質問
ディレクトリをスキャンして情報を収集する C# アプリケーションがあります。ファイルごとにアカウント名を表示したいと思います。これをローカル システムで行うには、FileInfo オブジェクトの SID を取得し、次の操作を実行します。
string GetNameFromSID( SecurityIdentifier sid )
{
NTAccount ntAccount = (NTAccount)sid.Translate( typeof( NTAccount ) );
return ntAccount.ToString();
}
ただし、これはネットワーク上のファイルに対しては機能しません。これはおそらく、Translate() 関数がローカル ユーザー アカウントでのみ機能するためです。SID で LDAP ルックアップを実行できるかもしれないと考えたので、次のことを試しました。
string GetNameFromSID( SecurityIdentifier sid )
{
string str = "LDAP://<SID=" + sid.Value + ">";
DirectoryEntry dirEntry = new DirectoryEntry( str );
return dirEntry.Name;
}
これは、「dirEntry.Name」へのアクセスが数秒間ハングアップし、あたかもネットワークをクエリしているかのように動作するように見えますが、その後 System.Runtime.InteropServices.COMException をスローします。
任意のファイルまたは SID のアカウント名を取得する方法を知っている人はいますか?私はネットワークや LDAP などについてはあまり知りません。DirectorySearcher というクラスがあり、これを使用することになっているのですが、ドメイン名が必要で、その取得方法もわかりません。スキャンしているディレクトリへのパスしかありません。
前もって感謝します。
解決
SecurityReferenceオブジェクトのメソッドは、非ローカルのSIDにだけ、ドメインアカウントの作業を行い翻訳。別のマシンにローカルまたは非ドメインのセットアップにアカウントのためには、機能をのPInvokeする必要がありますルックアップを実行する必要のある特定のマシン名を指定してのLookupAccountSidます。
他のヒント
良い答えはここを参照してください。
それの要旨は、このビットは、次のとおりです。
string sid="S-1-5-21-789336058-507921405-854245398-9938";
string account = new System.Security.Principal.SecurityIdentifier(sid).Translate(typeof(System.Security.Principal.NTAccount)).ToString();
このアプローチは、Active Directory上の非ローカルSIDのために私のために動作します。
System.DirectoryServices.AccountManagement.UserPrincipal
クラス( MSDNリンクに)変換する静的関数FindByIdentity
を有しますユーザーオブジェクトにSID。ローカルマシンまたはLDAP / Active Directoryサーバに対しての両方を動作することができるはずです。私は唯一のアクティブディレクトリに対してそれを使用しています。
ここで私はIISで使用している例があります:
// Set the search context to a specific domain in active directory
var searchContext = new PrincipalContext(ContextType.Domain, "YOURDOMAIN", "OU=SomeOU,DC=YourCompany,DC=com");
// get the currently logged in user from IIS
MembershipUser aspUser = Membership.GetUser();
// get the SID of the user (stored in the SecurityIdentifier class)
var sid = aspUser.ProviderUserKey as System.Security.Principal.SecurityIdentifier;
// get the ActiveDirectory user object using the SID (sid.Value returns the SID in string form)
var adUser = UserPrincipal.FindByIdentity(searchContext, IdentityType.Sid, sid.Value);
// do stuff to user, look up group membership, etc.
C#では、ユーザーSIDを取得して文字列変数に代入します:
string strUser = System.Security.Principal.WindowsIdentity.GetCurrent().User.ToString();
ユーザー名に解決する能力は、文字列をサポートしているので、文字列を使用する必要があります。言い換えれば、VARのvarUserを使用すると、名前空間のエラーになります。
string strUserName = new System.Security.Principal.SecurityIdentifier(strUser).Translate(typeof(System.Security.Principal.NTAccount)).ToString();
ああ、Active Directory 環境にいない可能性があるため、LDAP 呼び出しが機能していない可能性があります。この場合、各マシンが独自のアイデンティティ ストアを担当します。また、最初のコード サンプルは、コードを実行しているマシンが、リモート マシン上でのみ意味をなす SID を解決する方法を知らないため、ネットワーク経由では機能しません。
マシンが Active Directory の一部であるかどうかを必ず確認する必要があります。これはログオン プロセス中にわかります。または、[マイ コンピュータ] を右クリックし、[プロパティ]、[コンピュータ名] タブの順に選択して、コンピュータがドメインに属しているかどうかを確認することもできます。
グレート。私はここからいくつかのLookupAccountSid()のコードをcribbedます:
http://www.pinvoke.net/default.aspx/advapi32.LookupAccountSid の
そして、私は、ホスト名を自分自身を提供する必要がありましたけれども、それは、働いていました。 UNCパスの場合、私はちょうどそれの最初の要素を取ることができます。それはマップされたドライブだとき、私はUNC 1へのパスを変換するには、このコードを使用します:
http://www.wiredprairie.us/blog/index.php /アーカイブ/ 22 の
それは、誰かが状況を思い付くしない限り、私はここでUNCパスの最初のコンポーネントがホスト名ではありません、それをやる方法ですので、動作しているようです...
あなたの助けすべてをありがとうございます。
また、ユーザーの言語設定に関係なく動作します。このようなコードで、「みんな」のような特別口座のアカウント名を取得することができます
SecurityIdentifier everyoneSid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
string everyone = everyoneSid.Translate(typeof(System.Security.Principal.NTAccount)).ToString();
この1はスタンパです。あなたは、Active Directory環境で、右ですか?ちょうどチェック:)
とにかく、代わりsid.Valueとの結合の、
string str = "LDAP://<SID=" + sid.Value + ">";
私はにSIDのバイト配列に変換しようとするだろうその代わりとオクテット文字列と結合します。
甘い例があります<のhref = "http://books.google.com/books?id=kGApqjobEfsC&pg=PA77&lpg=PA77&dq=sid+bind+octet+string&source=web&ots=p4pqWbUOPc&sig=8kkEOVD0_NHzkj00zjM98tjyPno&hl=en&ei=TqCESYyNFZHItQPzi -XODQ&SA =ここの78ページX&OI = book_result&resnum = 2&CT =結果#1 PPA78、M1" のrel = "nofollowをnoreferrer">これは近いあなたを取得します。正直に言うと、私は前にSIDとの結合を試みたいませんでした。しかし、私はしかし、ユーザーのGUIDとの結合の成功を収めてきました:)
幸運と私はそれが行く方法を知ってみましょう。
現在のドメインを取得します:
System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain();
LDAPからディレクトリエントリとドメイン名を取得します:
DirectoryEntry de = new DirectoryEntry(string.Format("LDAP://{0}", domain));
ActiveDirectoryMembershipProvider ActiveDirectoryMembershipUserからSIDを取得します:
ActiveDirectoryMembershipUser user = (ActiveDirectoryMembershipUser)Membership.GetUser();
var sid = (SecurityIdentifier)user.ProviderUserKey;
セキュリティ識別子からユーザ名を取得します:
(NTAccount)sid.Translate(typeof(NTAccount));
ディレクトリ検索は、ドメインのディレクトリエントリおよびユーザ名でのActiveDirectoryで行わなさいます:
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = string.Format("(SAMAccountName={0})", username);
search.PropertiesToLoad.Add("Name");
search.PropertiesToLoad.Add("displayName");
search.PropertiesToLoad.Add("company");
search.PropertiesToLoad.Add("homePhone");
search.PropertiesToLoad.Add("mail");
search.PropertiesToLoad.Add("givenName");
search.PropertiesToLoad.Add("lastLogon");
search.PropertiesToLoad.Add("userPrincipalName");
search.PropertiesToLoad.Add("st");
search.PropertiesToLoad.Add("sn");
search.PropertiesToLoad.Add("telephoneNumber");
search.PropertiesToLoad.Add("postalCode");
SearchResult result = search.FindOne();
if (result != null)
{
foreach (string key in result.Properties.PropertyNames)
{
// Each property contains a collection of its own
// that may contain multiple values
foreach (Object propValue in result.Properties[key])
{
outputString += key + " = " + propValue + ".<br/>";
}
}
}
あなたのアクティブ・ディレクトリ内のデータに応じて、出力に変化応答を取得します。
私はあなたがここから受け入れ答えを使用することができますかなり確信している:<のhref =「https://stackoverflow.com/questions/204942/determine-the-localsystem-account-name-using-c」 > C#のを使用してLocalSystemアカウント名を決定します。
基本的に、あなたはユーザ名を取得することができ、そこからNTAccountを入力するためのセキュリティ識別子クラスのインスタンスを、翻訳することができます。コードでます:
using System.Security.Principal;
SecurityIdentifier sid = new SecurityIdentifier("S-1-5-18");
NTAccount acct = (NTAccount)sid.Translate(typeof(NTAccount));
Console.WriteLine(acct.Value);