예제 #1
0
        /// <summary>
        /// Put to Destination and put to CCM
        /// </summary>
        /// <param name="servers"></param>
        /// <param name="usersProps"></param>
        /// <returns>count of successed users</returns>
        private static int PutToDestinationAD(ADServer[] servers, List <UserProperties> usersProps, bool initializeMode)
        {
            int updatedCnt = 0;

            foreach (var props in usersProps) // for each user
            {
                var samAccount = props["samAccountName"][0];
                var objectSID  = props["objectSID"][0];
                foreach (ADServer server in servers)
                {
                    try
                    {
                        var pollRes = PollAD.AddUser(server, props, cprContent, servers.Where(s => s.Name != server.Name).ToArray());
                        if (pollRes == 0)
                        {
                            updatedCnt++; // success
                            initializationFails.Remove(objectSID);
                        }
                        else if (pollRes != 15 && initializeMode) // 15 if qualityCheck fails
                        {
                            initializationFails.Add(objectSID, props);
                        }
                        break; // success
                    }
                    catch (Exception ex)
                    {
                        log.LogError(ex, "Save user '" + samAccount + "' to Destination AD Server: " + (server != null ? server.Name : "null" + ": " + ex.Message));
                        if (ex.HResult != -2147016646) //server is not operational
                        {
                            break;                     // no need to try another server if server is available
                        }
                    }
                    // try next server
                }
            }
            if (updatedCnt == usersProps.Count)
            {
                log.LogInfo("Updated " + updatedCnt + " user(s) of " + usersProps.Count);
            }
            else
            {
                log.LogError("Updated " + updatedCnt + " user(s) of " + usersProps.Count + ". See previouse log records for errors.");
            }

            return(updatedCnt); // == usersProps.Count;

            throw new Exception("Unable to connect to any Destination servers");
        }
예제 #2
0
 private static void CacheAllGroups()
 {
     foreach (var server in config.SourceADServers)
     {
         try
         {
             PollAD.GetGroupMembers(server, ADHintsConfigurationSection.GetAllGroupsFromConfig());
             return; // first available source AD
         }
         catch (Exception ex)
         {
             log.LogDebug("Failed to connect to " + server.ToString() + ": " + ex.Message);
         }
     }
     throw new Exception("No Source AD Servers available");
 }
예제 #3
0
        private static void BackgroundPoll()
        {
            bool logVerbose = config.LogVerbose;

            //var accountToMonitor = config.SamAccountsToMonitor;
            //if (accountToMonitor.Count > 0)
            //    log.LogDebug("Monitoring only " + accountToMonitor.Count + " accounts: " + string.Join(";", accountToMonitor));

            if (oUsToMonitor.Count > 0)
            {
                log.LogDebug("Monitoring only " + oUsToMonitor.Count + " OU(s): " + string.Join(";", oUsToMonitor));
            }
            if (oUsDNToMonitor.Count > 0)
            {
                log.LogDebug("Monitoring only " + oUsDNToMonitor.Count + " OU(s) DNs: " + string.Join(";", oUsDNToMonitor));
            }

            // get attributes for replicate:
            var allAtributes = ADHintsConfigurationSection.GetAllAttributeNames();

            PollAD.AddSourcePropNames(allAtributes);
            PollAD.AddDestinationPropNames(allAtributes);

            PollAD.Log             = log;
            CCMApi.log             = log;
            CCMApi.interCcmSpacing = config.interCcmSpacing;

#if DEBUG
            uniTest();
#endif
            InitializeAllAccounts();

            while (true)
            {
                try
                {
                    if (!canWork)
                    {
                        break;
                    }

                    if (File.Exists(Path.Combine(HomeFolder, config.CCMCPRFile)))
                    {
                        cprContent = SettingsConfiguration.LoadCPRFile(Path.Combine(HomeFolder, config.CCMCPRFile));
                    }
                    else
                    {
                        cprContent = SettingsConfiguration.CPRFileContent;
                    }

                    PollAD ad      = GetAvailableAD(config.SourceADServers, lastHighUSNs, false);
                    bool   success = false;

                    if (ad == null)
                    {
                        log.LogError("Unable to connect to any AD Servers");
                    }
                    else
                    {
                        if (ad.ChangedUsersProperties.Count == 0)
                        {
                            success = true; // no changes
                        }
                        else
                        {
                            int cnt = ad.ChangedUsersProperties.Count;
                            //log.LogInfo("Found update for " + cnt + " user(s) in Source AD. Current USN = " + ad.CurrentHighUSN + ". InvocationID=" + ad.GetInvocationID);

                            FilterAccounts(ad.ChangedUsersProperties, config.DestADServers.Select(s => s.ServerUserName), oUsToMonitor, oUsDNToMonitor);
                            if (cnt - ad.ChangedUsersProperties.Count > 0)
                            {
                                log.LogInfo("Filtered out " + (cnt - ad.ChangedUsersProperties.Count) + " accounts");
                            }

                            if (ad.ChangedUsersProperties.Count == 0)
                            {
                                success = true; // no changes
                            }
                            else if (0 != PutToDestinationAD(config.DestADServers, ad.ChangedUsersProperties, false))
                            {
                                success = true; // saved to Dest AD
                            }
                            //  if at least 1 user is succeeded then assume that whole iteration is succeeded
                            //  If all users are failed than seems to be CCM or AD is down and iteration should run again.
                        }

                        // if iteration is secceeded and highUSN is changed than save it to DB
                        if (success && (!lastHighUSNs.ContainsKey(ad.GetInvocationID) || lastHighUSNs[ad.GetInvocationID] != ad.CurrentHighUSN))
                        {
                            lastHighUSNs[ad.GetInvocationID] = ad.CurrentHighUSN;
                            // SaveCurrentHighUSN(ad.GetInvocationID, ad.CurrentHighUSN);
                        }
                    }
                    if (initializationFails.Count > 0)
                    {
                        log.LogInfo("Process " + initializationFails.Count + " accounts which failed on startup ...");
                        PutToDestinationAD(config.DestADServers, initializationFails.Values.ToList(), false);
                    }
                }
                catch (Exception ex)
                {
                    log.LogError(ex, "BackgroundPoll");
                }
                finally
                {
                    stopEvent.WaitOne(config.PoolsInterval * 1000); // each 2 sec
                }
            }
        }
예제 #4
0
        private static void InitializeAllAccounts()
        {
            CacheAllGroups();

            log.LogInfo("Initialize accounts ...");
            PollAD adSource = GetAvailableAD(config.SourceADServers, lastHighUSNs, true);
            PollAD adDest   = GetAvailableAD(config.DestADServers, lastHighUSNs, true);

            lastHighUSNs[adSource.GetInvocationID] = adSource.CurrentHighUSN;

            try
            {
                IDictionary <string, UserProperties> userByObjectSID  = new Dictionary <string, UserProperties>(adDest.ChangedUsersProperties.Count);
                IDictionary <string, UserProperties> userBySamAccount = new Dictionary <string, UserProperties>(adDest.ChangedUsersProperties.Count);
                log.LogInfo("Loaded " + adSource.ChangedUsersProperties.Count + " accounts from SourceAD " + adSource.DnsHostName + " and " + adDest.ChangedUsersProperties.Count + " accounts from Destination AD " + adDest.DnsHostName);
                foreach (var userProps in adDest.ChangedUsersProperties)
                {
                    userProps.Remove("ObjectSID");
                    if (userProps.ContainsKey("Pager") && userProps["Pager"] != null)
                    {
                        userByObjectSID[userProps["Pager"][0]] = userProps;
                    }
                    userBySamAccount[userProps["samAccountName"][0]] = userProps;
                }

                log.LogDebug("  " + userByObjectSID.Count + " users has initialized ObjectSID in DestAD");
                var changedUsers = new List <UserProperties>();

                var cnt = adSource.ChangedUsersProperties.Count;
                FilterAccounts(adSource.ChangedUsersProperties, config.DestADServers.Select(s => s.ServerUserName), oUsToMonitor, oUsDNToMonitor);
                if (cnt - adSource.ChangedUsersProperties.Count > 0)
                {
                    log.LogInfo("Filtered out " + (cnt - adSource.ChangedUsersProperties.Count) + " accounts");
                }

                // Compare Source and Destination users ...
                foreach (var userProps in adSource.ChangedUsersProperties)
                {
                    UserProperties destUser = null;
                    if (!userByObjectSID.TryGetValue(userProps["ObjectSID"][0], out destUser) || destUser == null)
                    {
                        userBySamAccount.TryGetValue(userProps["samAccountName"][0], out destUser);
                    }

                    if (destUser == null) // not found by SID nor samAccountName
                    {
                        log.LogDebug("  '" + userProps["samAccountName"][0] + "' is new user");
                        changedUsers.Add(userProps); // new user
                    }
                    else
                    {
                        ADHintElement adHint = null;
                        try
                        {
                            string notUsed;
                            adHint = ADHintsConfigurationSection.GetOUByAttributes(userProps, destUser, out notUsed);
                        }
                        catch (Exception)
                        {
                        }

                        // {[distinguishedName, CN=user3. sdfsdf,OU=Office31,OU=Office3,OU=Domain Controllers,DC=kireev,DC=local]}
                        // simple way to determine if OU is changed
                        if (adHint != null && destUser["distinguishedName"][0].IndexOf(adHint.DestOU, StringComparison.OrdinalIgnoreCase) < 0)
                        {
                            log.LogDebug("  '" + destUser["distinguishedName"][0] + "' need to move to " + adHint.DestOU);
                            changedUsers.Add(userProps); //  OU is changed
                        }
                        else
                        {
                            foreach (var prop in userProps)
                            {
                                string[] destPropVal;
                                if (!PollAD.propIgnoreDest.Contains(prop.Key) &&
                                    destUser.TryGetValue(prop.Key, out destPropVal) && prop.Value != null && !Utils.CheckEquals(prop.Value, destPropVal))
                                {
                                    log.LogDebug("  '" + userProps["samAccountName"][0] + "' changed [" + prop.Key + "]='" + Utils.PropVal(destPropVal) + "' -> '" + Utils.PropVal(prop.Value) + "'");
                                    changedUsers.Add(userProps);
                                    break;
                                }
                            }
                        }
                    }
                }

                if (changedUsers.Count == 0)
                {
                    log.LogInfo("Initialization complete. No differences between SourceAD and DestinationAD found.");
                }
                else
                {
                    log.LogInfo("Need to update " + changedUsers.Count + " accounts...");
                    var updatedCnt = PutToDestinationAD(config.DestADServers, changedUsers, true);
                    log.LogInfo("Initialization complete. Successfully updated " + updatedCnt + " of " + changedUsers.Count + " accounts.");
                }
            }
            catch (Exception ex)
            {
                log.LogError(ex, "Failed to Initialize: " + ex.Message);
                return;
            }
        }