示例#1
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));
            }
              }
        }
示例#2
0
文件: LDAP.cs 项目: gnomix/T.A.L.K.
        /// <summary>
        /// Search method
        /// </summary>
        /// <param name="dir">Search settings<seealso cref="DirectoryType"/></param>
        /// <returns>A dataset conform to the specified FieldFormatters<seealso cref="FieldFormatter"/></returns>
        public static DataSet Search(DirectoryType dir)
        {
            DataSet results = new DataSet();
            DataTable dt = results.Tables.Add();
            LdapDatasourceType ldt = (LdapDatasourceType)dir.Item;
            try
            {
                Init(ldt.server, ldt.authenticationType, ldt.user, ldt.userPassword, ldt.targetOU, ldt.ldapFilter, ldt.pageSize, ldt.nbPages);
                log.Debug("Search " + ldapFilter + " from " + targetOU + " on " + ldapServer);
                PageResultRequestControl prc = new PageResultRequestControl(pageSize);
                prc.IsCritical = false;
                PageResultResponseControl cookie;
                SearchResponse sr;

                SearchRequest request = new SearchRequest(targetOU, ldapFilter, SearchScope.Subtree,ldt.ldapAttributes);
                request.Controls.Add(prc);

                foreach (string attribut in ldt.ldapAttributes)
                {
                    dt.Columns.Add(attribut, typeof(string));
                }
                

                int pageCount = 0;
                int count;
                while (true)
                {
                    pageCount++;

                    sr = (SearchResponse)ldapConnection.SendRequest(request);
                    log.Debug("Page " + pageCount.ToString() + ": " + sr.Entries.Count + " entries");

                    count = 0;
                    foreach (SearchResultEntry entry in sr.Entries)
                    {
                        count++;
                        log.Debug("Entry " + count.ToString() + ": " + entry.DistinguishedName);
                        List<object> values = new List<object>();
                        
                        foreach (string attribut in ldt.ldapAttributes)
                        {
                            DirectoryAttribute da = entry.Attributes[attribut];
                            if (da != null && da.GetValues(typeof(string)).Length > 0)
                            {
                                values.Add((string)da.GetValues(typeof(string))[0]);
                            }
                            else
                            {
                                values.Add("");
                            }
                        }
                        dt.Rows.Add(values.ToArray());
                    }

                    if (sr.Controls.Length != 1 || !(sr.Controls[0] is PageResultResponseControl))
                    {
                        log.Debug("Weird response...");
                        ldapConnection.Dispose();
                        return results;
                    }

                    cookie = (PageResultResponseControl)sr.Controls[0];

                    if (cookie.Cookie.Length == 0) break;

                    prc.Cookie = cookie.Cookie;
                }

                ldapConnection.Dispose();
                log.Debug("Search ended");
                return results;
            }
            catch (Exception e)
            {
                log.Error(e.Message);
                return results;
            }
        }
        /// <summary>
        /// Retrieves current state of LDAP database and reflects it to the CMS.
        /// </summary>
        public void Synchronize()
        {
            try
            {
                var request = new SearchRequest(DefaultNamingContext, "(&(|(objectClass=user)(objectClass=group))(usnchanged>="+ (Dispatcher.HighestUsnChanged + 1) +"))", SearchScope.Subtree, null);
                request.Controls.Add(new ShowDeletedControl());

                // Page result
                var prc = new PageResultRequestControl(5);
                request.Controls.Add(prc);
                var soc = new SearchOptionsControl(System.DirectoryServices.Protocols.SearchOption.DomainScope);
                request.Controls.Add(soc);

                while (true)
                {
                    var searchResponse = (SearchResponse) Connection.SendRequest(request);

                    if (searchResponse != null)
                    {
                        // Find the returned page response control
                        foreach (DirectoryControl control in searchResponse.Controls)
                        {
                            if (control is PageResultResponseControl)
                            {
                                //update the cookie for next set
                                prc.Cookie = ((PageResultResponseControl) control).Cookie;
                                break;
                            }
                        }

                        Dispatcher.AddToQueue(searchResponse.Entries.Cast<SearchResultEntry>().Where(p =>LdapHelper.IsUser(p, PersonObjectCategory) || LdapHelper.IsGroup(p, GroupObjectCategory)).ToList());

                        if (prc.Cookie.Length == 0)
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                LogError("Full synchronization failed.", ex);
            }
        }
示例#4
0
        /// <summary>
        /// Performs LDAP Search and extracts attributes.
        /// </summary>
        /// <param name="logger">The logger.</param>
        /// <param name="CurrentTime">Locked program timestamp value</param>
        private void ExtractLDAPResults(LogHelper logger, DateTime CurrentTime)
        {
            List<string> AttributesToAdd = new List<string>();
            foreach (PropertyBase item in this.Properties)
                AttributesToAdd.Add(item.Mapping);

            string[] _attrs = AttributesToAdd.ToArray();

            String sFilter = SetQueryFilter(this.BatchAction, CurrentTime);

            SearchRequest searchRequest = new SearchRequest(this.SearchRoot, sFilter, SearchScope.Subtree, _attrs);

            PageResultRequestControl PageResponse = new PageResultRequestControl(this.PageSize);
            SearchOptionsControl SearchOptions = new SearchOptionsControl(System.DirectoryServices.Protocols.SearchOption.DomainScope);

            searchRequest.Controls.Add(PageResponse);
            searchRequest.Controls.Add(SearchOptions);

            logger.LogVerbose(string.Format("Establishing LDAP Connection to: {0}", this.ServerName));
            
            using(LdapConnection connection = CreateLDAPConnection())
            {
                logger.LogVerbose(string.Format("Performing a {0} operation with filter: {1}", this.BatchAction, sFilter));

                while (true)
                {
                    SearchResponse response = null;

                    try
                    {
                        response = connection.SendRequest(searchRequest) as SearchResponse;
                    }
                    catch(Exception ex)
                    {
                        throw new Exception("An error occurred whilst creating the SearchResponse", ex);
                    }

                    int ResponseCount = response.Entries.Count;
                    int CurrentBatchSize;

                    if (ResponseCount != this.PageSize)
                        CurrentBatchSize = ResponseCount;
                    else
                        CurrentBatchSize = this.PageSize;

                    string FilePath = CSVCreateFile(this.CSVDirectoryLocation, _TotalUsers, CurrentBatchSize);
                    

                    foreach (DirectoryControl control in response.Controls)
                    {
                        if (control is PageResultResponseControl)
                        {
                            PageResponse.Cookie = ((PageResultResponseControl)control).Cookie;
                            break;
                        }
                    }

                    // Create CSV file for current batch of users
                    using (CSVWriter BatchFile = new CSVWriter(FilePath))
                    {
                        // Create column headings for CSV file
                        CSVUserEntry heading = new CSVUserEntry();

                        // Iterate over attribute headings
                        foreach (PropertyBase item in this.Properties)
                            heading.Add(item.Name);

                        BatchFile.CSVWriteUser(heading, logger);

                        // Create new CSV row for each user
                        foreach (SearchResultEntry sre in response.Entries)
                        {
                            // Placeholder for CSV entry of current user
                            CSVUserEntry user = new CSVUserEntry();

                            // Exract each user attribute specified in XML file
                            foreach (PropertyBase item in this.Properties)
                            {
                                try
                                {
                                    DirectoryAttribute attr = sre.Attributes[item.Mapping];
                                    string value = string.Empty;
                                    if (null != attr && attr.Count > 0)
                                        value = attr[0].ToString();

                                    if (item.Index == this.UserNameIndex)
                                        user.Add(CreateUserAccountName(value, attr));
                                    else
                                        user.Add(value);
                                }
                                catch (Exception ex)
                                {
                                    if (logger != null)
                                    {
                                        logger.LogException(string.Empty, ex);
                                        _TotalFailures++;
                                    }
                                }
                            }

                            // Write current user to CSV file
                            BatchFile.CSVWriteUser(user, logger);

                            // Increment user count value
                            _TotalUsers++;
                        }
                    }

                    logger.LogVerbose(string.Format("Successfully extracted {0} users to {1} - the total user count is: {2}", CurrentBatchSize, FilePath, _TotalUsers));

                    if (PageResponse.Cookie.Length == 0)
                        break;
                }
            }           
        }
示例#5
0
        /// <summary>
        /// Searches the LDAP directory for entries that match the specified search filter.
        /// </summary>
        /// <param name="filter">The filter that defines the entries to find.</param>
        /// <param name="attributes">(Optional) The attributes that should be returned in each entry found. </param>
        /// <param name="baseDn">(Optional)The distinguished name of the base entry where the search will begin. (Typically an OU or the base DN of the directory.) If not supplied, the default values will be used. This base is used only for the duration of this search.</param>
        /// <param name="scope">(Optional) The scope to use while searching. Defaults to Subtree. (Typically Base, just the object with the DN specified; OneLevel, just the child objects of the base object; or Subtree, the base object and all child objects) This scope is used only for the duration of this search.</param>
        /// <param name="queryPageSize">(Optional) The query page size to specify when making large requests. Defaults to DEFAULT_QUERY_PAGE_SIZE.</param>
        /// <param name="chaseReferrals">(Optional) Whether the search should chase object referrals to other servers if necessary. Defaults to true;</param>
        /// <returns>A collection of search result entries found, or null if there was an error with the search.</returns>
        public List<SearchResultEntry> Search(string filter, List<string> attributes = null, string baseDn = null, SearchScope scope = SearchScope.Subtree, int queryPageSize = DEFAULT_QUERY_PAGE_SIZE, bool chaseReferrals = true)
        {
            // Set the search base and scope for the search if provided.
            string previousBase = searchBaseDN;
            SearchScope previousScope = searchScope;
            bool customBaseAndScope = false;
            if (!string.IsNullOrWhiteSpace(baseDn))
            {
                SetSearchBaseAndScope(baseDn, scope);
                customBaseAndScope = true;
            }

            SearchRequest request = null;

            // Check if attributes have been provided.
            if (attributes == null || attributes.Count == 0)
            {
                // No attributes were provided... get them all.
                request = new SearchRequest(searchBaseDN, filter, searchScope);
            }
            else
            {
                // Specific attributes were requested, limit the search to just them.
                request = new SearchRequest(searchBaseDN, filter, searchScope, attributes.ToArray());
            }

            // Add a directory control that makes the search use pages for returning large result sets.
            PageResultRequestControl pageResultRequestControl = new PageResultRequestControl(queryPageSize);
            request.Controls.Add(pageResultRequestControl);

            if (!chaseReferrals)
            {
                // Turn of referral chasing in the session.
                connection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
            }

            // Create a list to hold our results while we request all of the results in pages.
            List<SearchResultEntry> results = new List<SearchResultEntry>();
            try
            {
                while (true)
                {
                    // Add the page request control that manages the paged searched, and send the request for results.
                    SearchResponse response = (SearchResponse)connection.SendRequest(request);

                    // Check that we received a response.
                    if (response != null)
                    {
                        // A response was received.

                        // Get the paging response control to allow us to gather the results in batches.
                        foreach (DirectoryControl control in response.Controls)
                        {
                            if (control is PageResultResponseControl)
                            {
                                PageResultResponseControl pageResultResponseControl =
                                    (PageResultResponseControl) control;

                                // Update the cookie in the request control to gather the next page of the query.
                                pageResultRequestControl.Cookie = pageResultResponseControl.Cookie;

                                // Break out of the loop now that we've copied the cookie.
                                break;
                            }
                        }

                        if (response.ResultCode == ResultCode.Success)
                        {
                            // Add the results to the list.
                            foreach (SearchResultEntry entry in response.Entries)
                            {
                                results.Add(entry);
                            }
                        }
                        else
                        {
                            // There has been an error retrieving the results.

                            // Reset the search base and scope if necessary.
                            if (customBaseAndScope)
                            {
                                SetSearchBaseAndScope(previousBase, previousScope);
                            }

                            return null;
                        }

                        // Check whether the cookies is empty and all the results have been gathered.
                        if (pageResultRequestControl.Cookie.Length == 0)
                        {
                            // The cookie is empty. We're done gathing results.
                            break;
                        }
                    }
                    else
                    {
                        // No response was received.
                        return null;
                    }
                }
                // Return the results found.

                // Reset the search base and scope if necessary.
                if (customBaseAndScope)
                {
                    SetSearchBaseAndScope(previousBase, previousScope);
                }

                return results;
            }
            catch
            {
            }

            // Reset the search base and scope if necessary.
            if (customBaseAndScope)
            {
                SetSearchBaseAndScope(previousBase, previousScope);
            }

            return null;
        }
示例#6
0
        /// <summary>
        /// Lazy-loading pure IEnumerable with transparent paging
        /// </summary>
        /// <returns></returns>
        public virtual IEnumerable<SearchResultEntry> GetResults()
        {
            SearchRequest req = new SearchRequest
            {
                DistinguishedName = this.DistinguishedName,
                Filter = this.Filter,
                Scope = this.SearchScope
            };

            if (this.MaxSearchTimePerPage.TotalSeconds > 0)
                req.TimeLimit = this.MaxSearchTimePerPage;

            if (this.SizeLimit > 0)
                req.SizeLimit = this.SizeLimit;

            string alist = string.Empty;
            if (this.Attrs != null && this.Attrs.Length > 0)
            {
                alist = string.Join("!", this.Attrs);
                req.Attributes.AddRange(this.Attrs);
            }

            PageResultRequestControl prc = new PageResultRequestControl(this.PageSize);
            prc.IsCritical = false;

            logger.Trace("Initial pg of {0}, max pages {1}", this.PageSize, this.MaxPages);

            int currentPage = 0;

            while (!_abort && prc != null && (currentPage++ < this.MaxPages || this.MaxPages < 1))
            {
                if (this.PageSize > 0 && (this.PageSize < this.SizeLimit || this.SizeLimit == 0))
                {
                    if (currentPage > 1)
                        req.Controls.Clear();

                    req.Controls.Add(prc);
                }
                else
                {
                    logger.Trace("Unpaged search (pgsz {0}, sizelimit {1})", this.PageSize, this.SizeLimit);
                }

                foreach (var dc in this.UserControls)
                    req.Controls.Add(dc);

                string key = this.DistinguishedName + ";" + this.SearchScope.ToString()
                    + ";f=" + this.Filter + ";cp=" + currentPage + ";psz=" + this.PageSize
                    + ";szl=" + this.SizeLimit + ";att" + alist;

                SearchResponse resp;

                try
                {
                    resp = this.GetSearchResponse(key, req);

                    if (resp != null)
                        logger.Debug("{0} total results", resp.Entries.Count);
                }
                catch (LdapException lde)
                {
                    if (_abort && lde.ErrorCode == 88)
                    {
                        logger.Info("Canceled by user");
                        yield break;
                    }
                    else
                    {
                        logger.Error("Ldap server msg {0}, code {1}, ex msg {2}",
                            lde.ServerErrorMessage, lde.ErrorCode, lde.Message);
                        throw;
                    }
                }
                // Note that Directory(Operation)Exception is NOT a subclass of LdapException
                // nor vice versa... verified

                if (_abort || resp == null)
                    yield break;

                foreach (SearchResultEntry se in resp.Entries)
                {
                    if (_abort)
                    {
                        logger.Info("Request aborted in enum");
                        yield break;
                    }

                    yield return se;
                }

                prc = UpdatePrc(resp);
            }
        }
示例#7
0
        static void Main(string[] args)
        {
            Console.Error.WriteLine("ShowAdCerts v1.0, (c) 2012 Zetetic LLC");

            if (args.Length == 1 && args[0].EndsWith("?"))
            {
                Console.Error.WriteLine(@"Switches (all are optional):

            -h  host or domain name (default = default logon server)
            -f  ldap filter         (default = userCertificate=*   )
            -b  search base         (default = domain root NC      )
            -v  (turn on cert validation of non-expired certs      )
            -r  (dump raw cert data                                )
            ");

                System.Environment.ExitCode = 1;
                return;
            }

            string searchbase = null, filter = "(&(userCertificate=*))", host = "";
            bool validate = false, raw = false;

            try
            {
                for (int i = 0; i < args.Length; i++)
                {
                    switch (args[i])
                    {
                        case "-h":
                            host = args[++i];
                            break;

                        case "-r":
                            raw = true;
                            break;

                        case "-f":
                            filter = args[++i];
                            switch (filter.ToLowerInvariant())
                            {
                                case "computer":
                                    filter = "(&(userCertificate=*)(objectCategory=computer))";
                                    break;

                                case "user":
                                case "person":
                                    filter = "(&(userCertificate=*)(objectCategory=person))";
                                    break;
                            }
                            break;

                        case "-b":
                            searchbase = args[++i];
                            break;

                        case "-v":
                            validate = true;
                            break;

                        default:
                            Console.Error.WriteLine("Unknown argument {0}", args[i]);
                            break;
                    }
                }

                using (var conn = new LdapConnection(host))
                {
                    conn.SessionOptions.ProtocolVersion = 3;

                    if (string.IsNullOrEmpty(searchbase))
                    {
                        var e = ((SearchResponse)conn.SendRequest(new SearchRequest(
                            "",
                            "(&(objectClass=*))",
                            SearchScope.Base,
                            "defaultNamingContext"))).Entries[0];

                        searchbase = e.Attributes["defaultNamingContext"][0].ToString();
                    }

                    var srch = new SearchRequest(searchbase, filter, SearchScope.Subtree, "userCertificate");
                    var pager = new PageResultRequestControl();
                    srch.Controls.Add(pager);

                    int count = 0;

                    while (true)
                    {
                        var resp = (SearchResponse)conn.SendRequest(srch);

                        foreach (SearchResultEntry se in resp.Entries)
                        {
                            if (!se.Attributes.Contains("userCertificate"))
                            {
                                continue;
                            }

                            Console.WriteLine("# {0}", ++count);
                            Console.WriteLine("dn: {0}", se.DistinguishedName);

                            foreach (var o in se.Attributes["userCertificate"].GetValues(typeof(byte[])))
                            {
                                byte[] bytes = (byte[])o;

                                try
                                {
                                    X509Certificate2 cert = new X509Certificate2(bytes);

                                    Console.WriteLine("subject: {0}", string.IsNullOrEmpty(cert.Subject) ? cert.SubjectName.Name : cert.Subject);
                                    Console.WriteLine("issuer: {0}", cert.Issuer);
                                    Console.WriteLine("thumbprint: {0}", cert.Thumbprint);
                                    Console.WriteLine("serial: {0}", cert.SerialNumber);

                                    var estr = cert.GetExpirationDateString();
                                    var expired = false;

                                    if (!string.IsNullOrEmpty(estr))
                                    {
                                        Console.WriteLine("exp: {0}", estr);
                                        DateTime dt;

                                        if (DateTime.TryParse(estr, out dt) && dt < DateTime.Now)
                                        {
                                            Console.WriteLine("expired: TRUE");
                                            expired = true;
                                        }
                                    }

                                    if (validate && !expired)
                                    {
                                        Console.WriteLine("valid: {0}", cert.Verify().ToString().ToUpperInvariant());
                                    }
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine("exception: {0}, {1}", e.GetType(), e.Message);
                                }

                                if (raw)
                                {
                                    var s = Convert.ToBase64String(bytes);

                                    Console.WriteLine("-----BEGIN CERTIFICATE-----");

                                    for (int i = 0; i < s.Length; i += 78)
                                    {
                                        Console.WriteLine(s.Substring(i, Math.Min(78, s.Length - i)));
                                    }

                                    Console.WriteLine("-----END CERTIFICATE-----");
                                }

                                Console.WriteLine("-");
                            }
                            Console.WriteLine("");
                        }

                        var rc = resp.Controls.SingleOrDefault(t => t is PageResultResponseControl) as PageResultResponseControl;

                        if (rc == null || rc.Cookie == null || rc.Cookie.Length == 0)
                            break;

                        pager.Cookie = rc.Cookie;
                    }
                }
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Error type = {0}, message = {1}, stack = {2}", e.GetType(), e.Message, e.StackTrace);

                System.Environment.ExitCode = 2;
            }
        }
示例#8
0
文件: Account.cs 项目: vokac/F2B
        private IDictionary<string, AccountStatus> PagedSearch(string afilter)
        {
            // read data from LDAP
            PageResultRequestControl pageRequestControl = new PageResultRequestControl(5);
            // for some reason without setting this search option
            // paged search doesn't work for domain root base name
            // (probably caused by incompatible referral settings
            // so this is no longer necessary with "External" referral
            //SearchOptionsControl searchOptions =
            //    new SearchOptionsControl(System.DirectoryServices.Protocols.SearchOption.DomainScope);
            // with following option we could technically track also deleted
            // objects that are currently updated only by full search in AD,
            // but that requires special persmissions (administrator?) and
            // additional code to deal with history of objects with same name
            //ShowDeletedControl showDeleted = new ShowDeletedControl();

            SearchRequest request = new SearchRequest();
            request.Attributes.Add("cn");
            request.Attributes.Add("userAccountControl");
            //request.Attributes.Add("isDeleted");
            request.Controls.Add(pageRequestControl);
            //request.Controls.Add(searchOptions);
            //request.Controls.Add(showDeleted);
            request.DistinguishedName = sbase;
            request.Filter = afilter;
            request.Scope = System.DirectoryServices.Protocols.SearchScope.Subtree;

            Dictionary<string, AccountStatus> ret = new Dictionary<string, AccountStatus>();
            SearchResponse response;
            while (true)
            {
                response = (SearchResponse)con.SendRequest(request);

                foreach (SearchResultEntry entry in response.Entries)
                {
                    string user = (string)entry.Attributes["cn"][0];
                    Int32 uac = Int32.Parse((string)entry.Attributes["userAccountControl"][0]);

                    if (!CaseSensitive)
                        user = user.ToLower();

                    AccountStatus status = AccountStatus.EXISTS;
                    if ((uac & 0x00000010) == 0x00000010)
                    {
                        status |= AccountStatus.LOCKED;
                    }
                    if ((uac & 0x00000002) == 0x00000002)
                    {
                        status |= AccountStatus.DISABLED;
                    }
                    //if (entry.Attributes.Contains("isDeleted") && bool.Parse((string)entry.Attributes["isDeleted"][0]))
                    //{
                    //    status |= Account.DELETED;
                    //}

                    ret[user] = status;
                }

                //find the returned page response control
                foreach (DirectoryControl control in response.Controls)
                {
                    if (control is PageResultResponseControl)
                    {
                        //update the cookie for next set
                        pageRequestControl.Cookie = ((PageResultResponseControl)control).Cookie;
                        break;
                    }
                }

                if (pageRequestControl.Cookie.Length == 0)
                    break;
            }
            //con.SessionOptions.StopTransportLayerSecurity();

            return ret;
        }