Пример #1
0
        private string CheckOUExists(ADServer server, string[] OUs, out bool success)
        {
            var    starTime = DateTime.Now;
            string errors   = "";

            success = false;
            foreach (var OU in OUs)
            {
                string destPath = server.path + "/" + OU;
                for (int trials = 0; trials < 6; trials++)
                {
                    if (DateTime.Now.Subtract(starTime).TotalSeconds > 60)
                    {
                        success = false;
                        return("Unable to connect to [" + server.ToString() + "]");
                    }
                    try
                    {
                        using (var destOU = new DirectoryEntry(destPath, server.ServerUserName, server.ServerPassword, server.authTypes))
                        {
                            var n = destOU.Name.ToString();
                            success = true;
                            log.LogDebug(" found OU: " + destPath);
                            break;
                        }
                    }
                    catch (Exception e)
                    {
                        var msg = "Fail to check OU [" + OU + "] in " + server.ToString(); // ""specified in config";
                        //                    if (e.HResult == -2147016661 || e.HResult == -2147016656) //0x8007202b. A referral was returned from the server
                        if (trials == 0)
                        {
                            errors += msg + ". " + e.Message;
                        }

                        if (e.HResult == -2147016656 || // object not found
                            e.HResult == -2147023570 || // user name or passw incorrect
                            e.HResult == -2147016672 || // An operations error occurred.
                            e.HResult == -2147016661    // 0x8007202b. A referral was returned from the server
                            )
                        {
                            break;
                        }
                        else
                        {
                            // if -2147016646 //server is not operational
                            // and other errors means that server is down or not responding
                            Thread.Sleep(10 * 1000);
                        }
                    }
                } // tries
            }
            return(errors);
        }
Пример #2
0
        public PollAD(ADServer server, IDictionary <string, string> prevHighUSNs, bool loadAll)
        {
            usersProperties = new List <UserProperties>();
            currentHighUSN  = null;
            string prevHighUSN;

            using (LdapConnection connection = server.getLapConnection)
            {
                var filter        = "(&(objectClass=*))";
                var searchRequest = new SearchRequest(null, filter, System.DirectoryServices.Protocols.SearchScope.Base, "highestCommittedUSN", "DnsHostName", "dsServiceName", "objectSID");
                var response      = connection.SendRequest(searchRequest) as SearchResponse;

                currentHighUSN = Convert.ToString(response.Entries[0].Attributes["highestcommittedusn"][0]);
                //Console.WriteLine(" currentHighUSN: " + currentHighUSN);

                // Get the name of the DC connected to.
                dnsHostName = Convert.ToString(response.Entries[0].Attributes["DnsHostName"][0]);
                //Console.WriteLine(" dns: " + dnsHostName);

                // Bind to the DC service object to get the invocationID.
                // The dsServiceName property of root DSE contains the distinguished
                // name of this DC service object.
                dsServiceName = Convert.ToString(response.Entries[0].Attributes["dsServiceName"][0]);
            }

            using (DirectoryEntry rootDSE = new DirectoryEntry(server.path, server.ServerUserName, server.ServerPassword, server.authTypes))
            {
                using (DirectoryEntry dcService = new DirectoryEntry(server.path + @"/" + dsServiceName, server.ServerUserName, server.ServerPassword, server.authTypes))
                {
                    // instanceID of AD database:
                    workInvocationID = BitConverter.ToString((byte[])dcService.Properties["invocationID"].Value);
                    //Console.WriteLine(" InvocationID = " + workInvocationID);
                    // Compare it to the DC name from the previous USN sync operation.
                    // Each invocationID has each own highestCommittedUSN !
                    if (loadAll || prevHighUSNs == null)
                    {
                        prevHighUSN = "0"; // initialize mode. Load All accounts.
                    }
                    else if (!prevHighUSNs.TryGetValue(workInvocationID, out prevHighUSN))
                    {
                        prevHighUSN = null; // AD server is polled first time.
                    }
#if DEBUG
                    //foreach (var prop in dcService.SchemaEntry.Properties)
                    //{
                    //    string propName = prop.ToString();
                    //    var propValue = dcService.SchemaEntry.Properties[propName].Value;
                    //    Console.WriteLine(propName + "=" + propValue);
                    //}
#endif
                }

                log.LogDebug(server.ToString() + ". currentUSN=" + currentHighUSN);

                if (String.IsNullOrEmpty(prevHighUSN))
                {
                    log.LogDebug("FIRST launch. Skip polling. Set currentUSN=" + currentHighUSN);
                    return; // first launch. Just set currentHighUSN and return.
                }

                if (Equals(prevHighUSN, currentHighUSN))
                {
                    return; // no changes since last update
                }
                if (prevHighUSN == "0")
                {
                    log.LogWarn("Load all users from [" + server.ToString() + "] ...");
                }

                LoadUsersByFilter(server, rootDSE, string.Format("(&(objectClass=user)(objectCategory=person)(uSNChanged>={0})(!(uSNChanged={0})))", prevHighUSN));

                if (prevHighUSN != "0") // only for realtime mode
                {
                    LoadUsersByGroups(server, rootDSE, prevHighUSN);
                }

                return;
            }
        }
Пример #3
0
        private void LoadUsersByFilter(ADServer server, DirectoryEntry rootDSE, string filter)
        {
            using (DirectorySearcher ds = new DirectorySearcher(rootDSE))
            {
                // if '>=' then we get last update twice
                // Note that the operators "<" and ">" are not supported. See "LDAP syntax filter clause"
                ds.Filter    = filter;
                ds.SizeLimit = 0; // unlimited
                ds.PageSize  = 1000;
                IList <string> propsToLoad = server.SourceDest.StartsWith("source", StringComparison.OrdinalIgnoreCase) ? propNamesSource : propNamesDestination;

                foreach (var p in propsToLoad)
                {
                    ds.PropertiesToLoad.Add(p);
                }

                using (SearchResultCollection results = ds.FindAll())
                {
                    var cnt = results.Count;
                    if (results != null && cnt > 0)
                    {
                        log.LogInfo("Reading " + cnt + " account(s) from " + server.ToString() + ". Current USN='" + CurrentHighUSN + "'. InvocationID='" + GetInvocationID + "'");
                        foreach (SearchResult user in results)
                        {
#if DEBUG
                            //foreach (var p in user.Properties)
                            //{
                            //    var prop = (ResultPropertyValueCollection)((System.Collections.DictionaryEntry)p).Value;
                            //    var propVal = (prop.Count > 0) ? Convert.ToString(prop[0]) : null;
                            //    Console.WriteLine(((System.Collections.DictionaryEntry)p).Key + "=" + propVal);
                            //}
#endif
                            //var user = r.GetDirectoryEntry();
                            var objectSID = user.Properties.Contains("objectSID") ? (new SecurityIdentifier(((byte[])user.Properties["objectSID"][0]), 0)).ToString() : string.Empty;
                            var dnProp    = user.Properties["distinguishedName"];
                            var dn        = (dnProp.Count > 0) ? Convert.ToString(dnProp[0]) : null;

                            // simbols '{}' are special for Format. So replace them in DN.
                            if (cnt <= 20)
                            {
                                log.LogInfo(" Read samAccountName='" + user.Properties["samAccountName"][0] + "', objectSID='" + objectSID + "', DN='" + dn.Replace('{', '(').Replace('}', ')') + "'");
                            }
                            UserProperties props = new UserProperties(propsToLoad.Count, StringComparer.OrdinalIgnoreCase);

                            //var groups = GetGroups(domainCtx, (string)user.Properties["samAccountName"][0]);

                            foreach (var p in propsToLoad)
                            {
                                var prop = user.Properties[p];
                                if ("objectSID".Equals(p, StringComparison.OrdinalIgnoreCase))
                                {
                                    props.Add(p, new string[] { objectSID });
                                }
                                else if (prop.Count > 0)// multi-value support  ("memberof".Equals(p, StringComparison.OrdinalIgnoreCase))
                                {
                                    var stringColl = ConvertToStrings(prop);
                                    props.Add(p, stringColl);
                                }
                                else
                                {
                                    props.Add(p, null); // property is set to null in AD
                                }
                            }

                            usersProperties.Add(props);
                        }
                    }
                }
            }
        }