2013-08-12 10 views
9

Windowsでのユーザーのなりすましのニュアンスをマスターするための旅では、リモートデータベースへのなりすましに関する問題が最初に発生しましたが(this SO question参照)、私はそれを最後に考え出しました。私の次のハードルは、元に戻す/取り消す/元に戻す(お気に入りの動詞を選ぶ)偽装です。Windowsのなりすまし:軟膏の欠陥

結果は、両方のライブラリと同一である:

は私が私には確かなようですカップル異なる偽装ライブラリを試してみました。ベストプラクティスでは、リモートDB接続にLOGON32_LOGON_NEW_CREDENTIALSログオンタイプ(Windows API LogonUser functionを参照)を使用するよう指示されています。

// SCENARIO A 
BEGIN impersonation. 
Local user = MyDomain\MyUser 
DB reports: MyDomain\ImpersonatedUser 
END impersonation. 
Local user = MyDomain\MyUser 
DB reports: MyDomain\ImpersonatedUser << NOT EXPECTED HERE!! 

私が見つけた唯一の回避策はLOGON32_LOGON_INTERACTIVEログオンタイプを使用することですし、私はこの取得:の簡潔な説明から

// SCENARIO B 
BEGIN impersonation. 
Local user = MyDomain\ImpersonatedUser << EXPECTED, BUT NOT WANTED! 
DB reports: MyDomain\ImpersonatedUser 
END impersonation. 
Local user = MyDomain\MyUser 
DB reports: MyDomain\MyUser 

を私はここに私のサンプルコードが生成するものであることを行うとWindowsImpersonationContext.Undo方法はシナリオAで動作しているはずです。

LOGON32_LOGON_NEW_CREDENTIALSログオンタイプを使用して元に戻すことはできますか?

+0

データベースへの接続を閉じて再度開きます。偽装レベルを変更すると、データベースは通知を受け取りません。シナリオBでは、データベースクライアントが自動的に新しい接続を確立しているとしか推測できません。 –

+0

コメントありがとうございます、@ハリージョンストン;私は、実際にはSQL接続を閉じて新鮮なものを開始したと述べるべきでした。 –

+0

おそらく、データベースクライアントがSQL接続をキャッシュしているか、または潜在的なネットワーク接続(名前付きパイプ?)がキャッシュされている可能性があります。あなたの最善の選択肢はおそらくあなたのための偽装データベース接続を行うために(新しいトークンのコンテキストで)サブプロセスを起動することです。 –

答えて

6

Harry Johnston(質問に添付されたコメント)とPhil Harding(別の連絡先)からのおかげで、私はSQL Server connection poolingがここでの犯人であると判断できました。プーリングは接続文字列の一意性によって決定されるため、接続文字列を少し変更することで(たとえば、パラメータを逆順に並べたり、最後にスペースを追加するなど)、私は期待した動作を観察しました。

===== TEST WITH SAME CONN STRING: True 
BEGIN impersonation 
Local user: MyDomain\msorens 
DB reports: MyDomain\testuser 
END impersonation 
Local user: MyDomain\msorens 
DB reports: MyDomain\testuser <<<<< still impersonating !! 

===== TEST WITH SAME CONN STRING: False 
BEGIN impersonation 
Local user: MyDomain\msorens 
DB reports: MyDomain\testuser 
END impersonation 
Local user: MyDomain\msorens 
DB reports: MyDomain\msorens <<<<< this is what I wanted to get 
+0

他に何かが働いている必要があります。あなたが提供したそのリンクでは、「接続は接続文字列によってプールに分割され、統合セキュリティが使用されている場合はWindowsのIDによって分離されます」と記載されています。いくつかのコードを表示できますか? –

+1

私の解釈では、「Windows ID」は、System.Security.Principal.WindowsIdentity.GetCurrent()。Name'が返す値(上記の「ローカルユーザー」として報告するもの)を意味します。つまり、LOGON32_LOGON_NEW_CREDENTIALSを使用すると、ウィンドウのアイデンティティが変更されないため、同じプール内にディップします。同意しますか? –

+0

私はそれが事実だとは思わないが、私はいくつかのテストを行い、見つけ出すだろう。 SQLプロファイラで資格情報を見るのは簡単です。 –

5

私は、接続プールの内部に掘られ、それがWindows資格情報が全く接続プールキーの一部とみなされていないことが判明。 SQLログインのみが考慮されます。

したがって、ユーザーAの下で開かれた利用可能な接続があり、ユーザーBを偽装している場合は、依然としてユーザーBが使用され、SQLはユーザーAとしてユーザーに表示されます。

2人の異なるユーザーの接続文字列を少し変更する方法は問題ありません。 「通常の」ユーザーがいて、「昇格した」ユーザーに偽装する必要がある場合は、これを行うことができます。もちろん、の異なる文字列をアプリケーションのすべてのユーザーにしたくない場合は、接続プーリングを完全に無効にすることもできます。

接続文字列を調整するときは、偽装されたユーザー名をApplication NameまたはWorkstation IDのいずれかのフィールドに追加することを検討してください。これは、偽装されたユーザーごとに個別のプールを設定する利点があります。

関連する問題