Как я могу конвертировать из SID в имя учетной записи в C #

У меня есть приложение C #, которое сканирует каталог и собирает некоторую информацию. Я хотел бы отобразить имя учетной записи для каждого файла. Я могу сделать это в локальной системе, получив SID для объекта FileInfo, а затем выполнив:

string GetNameFromSID( SecurityIdentifier sid ) { NTAccount ntAccount = (NTAccount)sid.Translate( typeof( NTAccount ) ); return ntAccount.ToString(); } 

Однако это не работает для файлов в сети, по-видимому, потому, что функция Translate () работает только с локальными учетными записями пользователей. Я подумал, что, возможно, я мог бы найти LDAP-поиск в SID, поэтому я попробовал следующее:

 string GetNameFromSID( SecurityIdentifier sid ) { string str = "LDAP://"; DirectoryEntry dirEntry = new DirectoryEntry( str ); return dirEntry.Name; } 

Кажется, что это сработает, поскольку доступ к «dirEntry.Name» зависает в течение нескольких секунд, как будто он отключается и запрашивает сеть, но затем он выдает System.Runtime.InteropServices.COMException

Кто-нибудь знает, как я могу получить имя учетной записи произвольного файла или SID? Я мало знаю о сети или LDAP или что-то еще. Есть class под названием DirectorySearcher, который, возможно, я должен использовать, но он хочет имя домена, и я не знаю, как это получить – все, что у меня есть, – путь к каталогу, который я просматриваю.

Заранее спасибо.

    Метод переноса объекта SecurityReference работает с нелокальными SID, но только для учетных записей домена. Для локальных учетных записей на другом компьютере или в настройке, отличной от домена, вам необходимо выполнить PInvoke функцию LookupAccountSid, определяющую конкретное имя машины, на котором должен выполняться поиск.

    См. Здесь, чтобы получить хороший ответ:

    Лучший способ разрешить отображение имени пользователя по SID?

    Суть его в этом:

     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(); 

    Этот подход работает для меня для нелокальных SID по активному каталогу.

    System.DirectoryServices.AccountManagement.UserPrincipal class ( msdn link ) имеет статическую функцию FindByIdentity для преобразования SID в объект User. Он должен работать как с локальной машиной, так и с сервером 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(); 

    Ooh, тогда возможно, что вызов LDAP не работает, потому что вы, возможно, не находитесь в среде Active Directory. Если это так, то каждая из ваших машин несет ответственность за свой собственный хранилище. И ваш первый пример кода не работает по сети, потому что машина, на которой вы выполняете свой код, не знает, как разрешить SID, который имеет смысл только на удаленной машине.

    Вы действительно должны проверить, являются ли ваши машины частью Active Directory. Вы узнали бы это во время процесса входа в систему. Или вы можете проверить, щелкнув правой кнопкой мыши на «Мой компьютер», выберите «Свойства», вкладку «Имя компьютера», а затем посмотрите, является ли ваш компьютер частью домена.

    Отлично. Я скрепил код LookupAccountSid () отсюда:

    http://www.pinvoke.net/default.aspx/advapi32.LookupAccountSid

    И это сработало, хотя я сам должен был предоставить имя хоста. В случае UNC-пути я могу просто взять первый его компонент. Когда это сопоставленный диск, я использую этот код для преобразования пути к UNC:

    http://www.wiredprairie.us/blog/index.php/archives/22

    Кажется, что это работает, так вот как я это сделаю, если кто-то не столкнется с ситуацией, когда первый компонент UNC-пути не является именем хоста …

    Спасибо за вашу помощь.

    Вы также можете получить имя учетной записи специальных учетных записей, таких как «Все», с таким кодом, который будет работать независимо от настроек языка пользователя:

      SecurityIdentifier everyoneSid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); string everyone = everyoneSid.Translate(typeof(System.Security.Principal.NTAccount)).ToString(); 

    Это один из них. Вы находитесь в среде Active Directory правильно? Просто проверяю:)

    Во всяком случае, вместо привязки к sid.Value,

     string str = "LDAP://"; 

    Я бы попытался преобразовать массив байтов SID в строку Octet и связать с этим.

    Здесь есть приятный пример на странице 78. Это приблизит вас. Честно говоря, я раньше не пытался связываться с SID. Но у меня была успешная привязка к GUID пользователя, хотя 🙂

    Удачи и дайте мне знать, как это происходит.

    Получить текущий домен:

     System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain(); 

    Получить запись каталога из ldap и имя домена:

     DirectoryEntry de = new DirectoryEntry(string.Format("LDAP://{0}", domain)); 

    Получите sid из ActiveDirectoryMembershipProvider ActiveDirectoryMembershipUser:

     ActiveDirectoryMembershipUser user = (ActiveDirectoryMembershipUser)Membership.GetUser(); var sid = (SecurityIdentifier)user.ProviderUserKey; 

    Получите имя пользователя из SecurityIdentifier:

     (NTAccount)sid.Translate(typeof(NTAccount)); 

    Получить поиск каталога в активированном каталоге с записью каталога домена и именем пользователя:

     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 + ".
    "; } } }

    В зависимости от данных в вашем активном каталоге вы получите разнообразный ответ на выходе.

    Вот сайт, который имеет все необходимые мне свойства пользователя:

    Я уверен, что вы сможете использовать принятый ответ отсюда: Определите имя учетной записи LocalSystem, используя C #

    В принципе, вы можете перевести экземпляр classа SecurityIdentifier для ввода NTAccount, из которого вы можете получить имя пользователя. В коде:

     using System.Security.Principal; SecurityIdentifier sid = new SecurityIdentifier("S-1-5-18"); NTAccount acct = (NTAccount)sid.Translate(typeof(NTAccount)); Console.WriteLine(acct.Value); 
    Interesting Posts

    Использовать зарезервированное ключевое слово enum case

    Ошибка 0x80073cf9 при установке или обновлении приложений из магазина Windows

    C ++ 11 make_pair с указанными параметрами шаблона не компилируется

    Новый проект Asp.Net MVC5 создает бесконечный цикл для входа в систему

    добавить onclick-прослушиватель в предопределенную кнопку?

    Как удалить дочерний объект в NHibernate?

    Сбрасывайте метаданные из всех форматов с помощью FFmpeg

    Как предотвратить запуск моего приложения в фоновом режиме на iPhone

    Почему Windows думает, что моя беспроводная клавиатура является тостером?

    Можете ли вы использовать несколько дисплеев с дополнительной видеокартой?

    SSH для github с использованием CygWin не работает

    Какой тип указателя я использую, когда?

    cout << с char * аргумент печатает строку, а не значение указателя

    Каков самый элегантный способ удаления пути из переменной $ PATH в Bash?

    Использование SHA1 и RSA с java.security.Signature против MessageDigest и Cipher

    Давайте будем гением компьютера.