How to check if a user with [UserName] and [Password] is not a domain administrator [DomainName] without impersonation?

Impersonation example

I can check if the user domain administrator is the following lines of code:

using (Impersonation im = new Impersonation(UserName, Domain, Password)) { System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent(); bool isDomainAdmin = identity.IsDomainAdmin(Domain, UserName, Password); if (!isDomainAdmin) { //deny access, for example } } 

where IsDomainAdmin is the extension method

 public static bool IsDomainAdmin(this WindowsIdentity identity, string domain, string userName, string password) { Domain d = Domain.GetDomain(new DirectoryContext(DirectoryContextType.Domain, domain, userName, password)); using (DirectoryEntry de = d.GetDirectoryEntry()) { byte[] domainSIdArray = (byte[])de.Properties["objectSid"].Value; SecurityIdentifier domainSId = new SecurityIdentifier(domainSIdArray, 0); SecurityIdentifier domainAdminsSId = new SecurityIdentifier(WellKnownSidType.AccountDomainAdminsSid, domainSId); WindowsPrincipal wp = new WindowsPrincipal(identity); return wp.IsInRole(domainAdminsSId); } } 

But when the IsDomainAdmin method is called, it tries to write some files to% LOCALAPPDATA% for the impersonated user, and if the program is not running as an administrator, it throws an exception

Failed to load file or assembly 'System.DirectoryServices, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a' or one of its dependencies. Either the required impersonation level was not or the provided impersonation level is invalid. (Exception from HRESULT: 0x80070542)

+4
source share
3 answers

You definitely do not need a user password to check if the user is a member of a group. So, why don't you just query AD straightforwardly using DirectoryEntry or DirectorySearcher ? If you also need to verify that the password you entered is correct, you can do this in an additional step using PrincipalContext.ValidateCredentials . (See Principle of PrincipalContext.ValidateCredentials (String, String) ).

 static void Main(string[] args) { string userDomain = "somedomain"; string userName = "username"; string password = "apassword"; if (IsDomainAdmin(userDomain, userName)) { string fullUserName = userDomain + @"\" + userName; PrincipalContext context = new PrincipalContext( ContextType.Domain, userDomain); if (context.ValidateCredentials(fullUserName, password)) { Console.WriteLine("Success!"); } } } public static bool IsDomainAdmin(string domain, string userName) { string adminDn = GetAdminDn(domain); SearchResult result = (new DirectorySearcher( new DirectoryEntry("LDAP://" + domain), "(&(objectCategory=user)(samAccountName=" + userName + "))", new[] { "memberOf" })).FindOne(); return result.Properties["memberOf"].Contains(adminDn); } public static string GetAdminDn(string domain) { return (string)(new DirectorySearcher( new DirectoryEntry("LDAP://" + domain), "(&(objectCategory=group)(cn=Domain Admins))") .FindOne().Properties["distinguishedname"][0]); } 
+3
source

We are modifying @ jmh_gr’s answer and seem to be independent of the name of the "Domain Admins" group.

 static string BuildOctetString(SecurityIdentifier sid) { byte[] items = new byte[sid.BinaryLength]; sid.GetBinaryForm(items, 0); StringBuilder sb = new StringBuilder(); foreach (byte b in items) { sb.Append(b.ToString("X2")); } return sb.ToString(); } public static bool IsDomainAdmin(string domain, string userName) { using (DirectoryEntry domainEntry = new DirectoryEntry(string.Format("LDAP://{0}", domain))) { byte[] domainSIdArray = (byte[])domainEntry.Properties["objectSid"].Value; SecurityIdentifier domainSId = new SecurityIdentifier(domainSIdArray, 0); SecurityIdentifier domainAdminsSId = new SecurityIdentifier(WellKnownSidType.AccountDomainAdminsSid, domainSId); using (DirectoryEntry groupEntry = new DirectoryEntry(string.Format("LDAP://<SID={0}>", BuildOctetString(domainAdminsSId)))) { string adminDn = groupEntry.Properties["distinguishedname"].Value as string; SearchResult result = (new DirectorySearcher(domainEntry, string.Format("(&(objectCategory=user)(samAccountName={0}))", userName), new[] { "memberOf" })).FindOne(); return result.Properties["memberOf"].Contains(adminDn); } } } 

Anyway, thanks @jmh_gr for the answer.

+2
source

Using this code @lluisfranco

 using System.DirectoryServices; using System.DirectoryServices.ActiveDirectory; using System.Net.NetworkInformation; using System.Security.Principal; namespace Alpha.Code { public static class SecurityExtensions { public static bool IsDomainAdmin (this WindowsIdentity identity) { Domain d = Domain.GetDomain(new DirectoryContext(DirectoryContextType.Domain, getDomainName())); using (DirectoryEntry de = d.GetDirectoryEntry()) { byte[] bdomSid = (byte[])de.Properties["objectSid"].Value; string sdomainSid = sIDtoString(bdomSid); WindowsPrincipal wp = new WindowsPrincipal(identity); SecurityIdentifier dsid = new SecurityIdentifier(sdomainSid); SecurityIdentifier dasid = new SecurityIdentifier( WellKnownSidType.AccountDomainAdminsSid, dsid); return wp.IsInRole(dasid); } } public static string getDomainName() { return IPGlobalProperties.GetIPGlobalProperties().DomainName; } public static string sIDtoString(byte[] sidBinary) { SecurityIdentifier sid = new SecurityIdentifier(sidBinary, 0); return sid.ToString(); } } } 

Usage example:

 if (WindowsIdentity.GetCurrent().IsDomainAdmin()) { //Actions to do if user is domain admin } 

A source:
http://geeks.ms/blogs/lfranco/archive/2009/11/25/how-to-191-como-saber-si-el-usuario-actual-es-administrador-del-dominio.aspx

0
source

Source: https://habr.com/ru/post/1401157/


All Articles