Esempio n. 1
0
        private static void uniTest()
        {
            //using (var fs = new System.IO.StreamWriter(Path.Combine(HomeFolder, "cpr.txt"), false))
            //{
            //    fs.Write(cprContent);
            //    fs.Close();
            //}

            UserProperties userPropsFrom = new UserProperties()
            {
                { "L", new string[] { "Boston", "Tokio" } },
                { "facsimileTelephoneNumber", null }, // new string[]{"123"}
                { "mobile", new string[] { "7" } },
                { "memberOf", new string[] { "CN=Exchange Services,CN=Users,DC=egar,DC=egartech,DC=com", "CN=IIS_IUSRS,CN=Builtin,DC=kireev,DC=local" } },
                { "mail", new string[] { "123DfG123" } },
                { "userPrincipalName", new string[] { "123" } },
            };
            UserProperties userPropsTo = new UserProperties()
            {
                { "L", new string[] { "Boston" } },
                { "facsimileTelephoneNumber", new string[] { "456" } },
                { "userAccountControl", new string[] { Convert.ToString((uint)Utils.UserAccountControl.SMARTCARD_REQUIRED) } },
                { "mobile", new string[] { "4" } },
                { "memberOf", new string[] { "CN=Exchange Services,CN=Users,DC=egar,DC=egartech,DC=com", "CN=IIS_IUSRS,CN=Builtin,DC=kireev,DC=local" } },
            };

            string        transResult;
            ADHintElement adHint = ADHintsConfigurationSection.GetOUByAttributes(userPropsTo, userPropsFrom, out transResult);

            if (adHint != null)
            {
                var qualityCheck = adHint.QualityCheck(userPropsFrom);
                //var transResult = adHint.GetTransitionByUserAttributes(userPropsFrom, userPropsTo);
            }
        }
Esempio n. 2
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;
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Add or Update user in Destination AD
        /// return: 0  - succesfully updated
        ///         1  - succesfully updated and changedImportantProps
        ///         -1 - error
        /// </summary>
        public static int AddUser(ADServer server, UserProperties newProps, string cprContent, ADServer[] serversToWait)
        {
            // props["userPrincipalName"], props["displayName"], props["givenName"], props["sn"], props["mail"], props["initials"], props["objectSID"]
            string samAccountName    = newProps["samAccountName"][0];
            string oldSamAccountName = null;
            bool   isNewUser         = false;

            //bool isChangedOU = false;

            using (DirectoryEntry searchOU = new DirectoryEntry(server.path, server.ServerUserName, server.ServerPassword, server.authTypes))
            {
                DirectoryEntry oldUser = LoadUserByObjectSID(searchOU, newProps["objectSID"][0], samAccountName);

                UserProperties oldProps = null;
                if (oldUser != null)
                {
                    oldProps          = GetUserProperties(oldUser);
                    oldSamAccountName = (string)oldUser.Properties["samAccountName"].Value;
                }
                isNewUser = oldUser == null;

                string transResult;
                var    adHint = ADHintsConfigurationSection.GetOUByAttributes(newProps, oldProps, out transResult);
                if (adHint == null)
                {
                    var messageHint = "ADHint is not found for user " + quote(samAccountName) + ". Attributes:" + PrintAttributes(newProps);
                    messageHint += ADHintsConfigurationSection.PrintMemberOfAttributes(newProps.GetPropValue("memberOf"));

                    if (Settings.Default.DataMismatchLogging)
                    {
                        log.LogWarn(messageHint);
                    }
                    else
                    {
                        log.LogDebug(messageHint);
                    }
                    return(0);
                }

                var qualityCheck = adHint.QualityCheck(newProps);
                if (qualityCheck.Count > 0)
                {
                    log.LogError("QualityCheck validation fails for user '" + samAccountName + "' with attributes:" + Environment.NewLine + string.Join(Environment.NewLine, qualityCheck.ToArray()));
                    return(15);
                }

                // Process ...
                if (adHint.Type == ADHintElement.AdHintType.Terminate)
                {
                    return(CCMApi.Terminate(oldSamAccountName));     // return 0 if success
                }
                string destPath = server.path + "/" + adHint.DestOU; // ="LDAP://myServ.local:636/OU=Office21,OU=Office2,OU=Domain Controllers,DC=myServ,DC=local"

                using (var destOU = new DirectoryEntry(destPath, server.ServerUserName, server.ServerPassword, server.authTypes))
                {
                    string changedImportantProps = transResult;
                    string changedAllProps       = "";
                    string msg = " '" + samAccountName + "' . HintNum=" + adHint.Num + ". " + adHint.Type + ". ";
                    if (isNewUser) // new user
                    {
                        //log.LogInfo(" '" + samAccountName + "' . HintNum=" + adHint.Num + ". New user in '" + destOU.Path + "'" + (server.SSL ? "(SSL)" : "(not SSL)") + " ...");
                        msg    += "Add user into '" + destOU.Path + "'" + (server.SSL ? "(SSL)" : "(not SSL)");
                        oldUser = destOU.Children.Add("CN=" + samAccountName, "user");
                    }
                    else
                    {
                        // check if OU is changed for user
                        if (!oldUser.Parent.Path.Equals(destOU.Path, StringComparison.OrdinalIgnoreCase))
                        {
                            //log.LogInfo(" '" + samAccountName + "' move from '" + oldUser.Parent.Path + "' -> '" + destOU.Path + "' " + (server.SSL ? "(SSL)" : "(not SSL)") + ". HintNum=" + adHint.Num + " ...");
                            msg += "Move from '" + oldUser.Parent.Path + "' -> '" + destOU.Path + "' " + (server.SSL ? "(SSL)" : "(not SSL)");
                            oldUser.MoveTo(destOU);
                            changedAllProps += "OU;";
                        }
                        else
                        {
                            //log.LogInfo(" '" + samAccountName + "' update in OU '" + destOU.Path + "' " + (server.SSL ? "(SSL)" : "(not SSL)") + ". HintNum=" + adHint.Num + " ...");
                            msg += "Update in OU '" + destOU.Path + "' " + (server.SSL ? "(SSL)" : "(not SSL)");
                        }
                    }

                    changedImportantProps += CheckAndSetProperty(oldUser.Properties, "samAccountName", new string[] { samAccountName }); // AD key

                    changedAllProps += SetPropertiesToUser(oldUser, newProps);
                    changedAllProps += CheckAndSetProperty(oldUser.Properties, "Pager", newProps["objectSID"]); // the surrogate key

                    bool terminate = !isNewUser && changedImportantProps.Length > 0;
                    if (terminate)
                    {
                        log.LogInfo(msg + ". Terminating. Changed attributes: " + Environment.NewLine + changedAllProps + Environment.NewLine + changedImportantProps);
                        CCMApi.Terminate(oldSamAccountName);
                    }
                    else if (!isNewUser && string.IsNullOrEmpty(changedAllProps) && string.IsNullOrEmpty(changedImportantProps))
                    {
                        log.LogDebug("No attributes changed. Skip updating.");
                        return(0); // skip to commit
                    }
                    else
                    {
                        log.LogInfo(msg + "Changed attributes: " + Environment.NewLine + changedAllProps + Environment.NewLine + changedImportantProps);
                    }

                    if (!terminate && CCMApi.IsActive(samAccountName) != 0)
                    {
                        return(-1); // card is already active
                    }
                    oldUser.Properties["userAccountControl"].Value = Utils.UserAccountControl.NORMAL_ACCOUNT | Utils.UserAccountControl.ACCOUNTDISABLE | Utils.UserAccountControl.PWD_NOTREQD;

                    //Console.WriteLine("  CommitChanges '" + samAccountName + "' ...");
                    oldUser.CommitChanges();

                    if (isNewUser)
                    {
                        WaitDestinationADReplication(samAccountName, newProps["objectSID"][0], serversToWait);
                    }

                    // Dest AD is commited.
                    // Process CCM ....

                    if (Settings.Default.CCMHost.Trim().Length == 0)
                    {
                        log.LogWarn("CCMHost is not set. Skip CCM processing");
                        return(0);
                    }

                    int ccmResult;
                    try
                    {
                        ccmResult = CCMApi.CreateCPR(samAccountName, cprContent, adHint.CardPolicy); // return 0 if success
                    }
                    catch (Exception ex)
                    {
                        log.LogError(ex, "update user '" + samAccountName + "' in CCM: " + ex.Message);
                        return(-1);
                    }

                    if (ccmResult != 0)
                    {
                        // Rollback AD ...
                        if (oldProps == null) // if created then delete
                        {
                            destOU.Children.Remove(oldUser);
                            destOU.CommitChanges();
                        }
                        else
                        {
                            SetPropertiesToUser(oldUser, oldProps); // return to oldProps
                            oldUser.CommitChanges();
                        }
                        log.LogWarn2("Rollback processed in AD for account '" + samAccountName + "' due to CCM error " + ccmResult + ". " + (oldProps == null ? "Account deleted in DestinationAD" : "Account attributes restored in DestinationAD"));
                        return(-1);
                    }
                    return(ccmResult);
                }
            }
        }