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); } }
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; } }
/// <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); } } }