// domain, orgunit, container (folder) private void DeletePortalContainer(Node node) { try { AdLog.LogPortalObject("Deleting portal container (orgunit/domain/folder)", node.Path); if (Node.Exists(node.Path)) { // move all underlying users to deleted folder var users = Common.GetContainerUsers(node); // delete user nodes foreach (Node userNode in users) { DeletePortalUser(userNode); } // delete container node if allowed if (Common.GetContainerUsers(node).Count() == 0) { Node.DeletePhysical(node.Id); } else { AdLog.LogErrorPortalObject("Portal container cannot be deleted, it contains users!", node.Path); } } } catch (Exception ex) { AdLog.LogErrorADObject(ex.Message, node.Path); } }
// sync objects from AD to portal private void SyncObjectsFromAD(SyncTree syncTree, ADObjectType objType, SearchResultCollection allADObjects, Action <DirectoryEntry, string, Guid, SyncTree> CreateNewObject, Action <DirectoryEntry, Node, SyncTree> UpdateProperties) { foreach (SearchResult result in allADObjects) { try { string nodeADpath = result.Path; if (syncTree.IsADPathExcluded(nodeADpath)) { continue; } AdLog.LogOuterADObject("Syncing", result.Path); var guid = Common.GetADResultGuid(result, _config.GuidProp); if (!guid.HasValue) { // no AD guid present for object AdLog.LogErrorADObject("No AD GUID present", result.Path); continue; } // új objektumok (ou, user, group) felvétele, átmozgatások // - ha létezik az adott guid-ú objektum -> path ellenőrzés, átmozgatás // - ha nem létezik, létrehozás string nodePortalParentPath = syncTree.GetPortalParentPath(nodeADpath); if (!Node.Exists(nodePortalParentPath)) { // adpath: OU=OtherOrg,OU=ExampleOrg,DC=Nativ,DC=local // portalParentPath: "/Root/IMS/NATIV/ExampleOrg" EnsurePortalPath(syncTree, syncTree.GetADParentObjectPath(result.Path), RepositoryPath.GetParentPath(nodePortalParentPath)); } SyncOneADObject(result, null, (Guid)guid, objType, nodePortalParentPath, CreateNewObject, UpdateProperties, syncTree); } catch (Exception ex) { // syncing of one object of the current tree failed AdLog.LogException(ex); } } }
private void DeletePortalGroup(Node node) { try { AdLog.LogPortalObject("Deleting portal group", node.Path); node.Delete(); } catch (Exception ex) { AdLog.LogErrorADObject(ex.Message, node.Path); } }
public static void SetPortalObjectGuid(DirectoryEntry entry, Node node, string guidProp) { // get guid var guid = Common.GetADObjectGuid(entry, guidProp); if (guid.HasValue) { Common.UpdateLastSync(node, guid); //node.Save(); } else { AdLog.LogErrorADObject("Created AD object does not have a guid", entry.Path); } }
private void DeletePortalUser(Node node) { try { AdLog.LogPortalObject("Deleting (disabling) portal user", node.Path); ((IUser)node).Enabled = false; Common.DisablePortalUserCustomProperties(node, _propertyMappings); Common.UpdateLastSync(node, null); //node.Save(); - update lastsync already saves node Node.Move(node.Path, _deletedFromADPath); } catch (Exception ex) { AdLog.LogErrorADObject(ex.Message, node.Path); } }
// domain, orgunit, container (folder) private void CreateNewPortalContainer(DirectoryEntry entry, string parentPath, Guid guid, SyncTree syncTree) { switch (Common.GetADObjectType(entry, _config.NovellSupport)) { case ADObjectType.Organization: case ADObjectType.OrgUnit: CreateNewPortalOrgUnit(entry, parentPath, (Guid)guid, syncTree); break; case ADObjectType.Container: CreateNewPortalFolder(entry, parentPath, (Guid)guid, syncTree); break; case ADObjectType.Domain: CreateNewPortalDomain(entry, parentPath, (Guid)guid, syncTree); break; default: AdLog.LogErrorADObject("Unsupported AD object!", entry.Path); break; } }
public void DeleteADObject(string nodePath, Guid?guid) { IUser originalUser = User.Current; Common.ChangeToAdminAccount(); try { if (!IsSyncedObject(nodePath)) { return; } AdLog.LogPortalObject("Deleting AD object", nodePath); //var guid = Common.GetPortalObjectGuid(node); if (guid.HasValue) { SyncTreeADObject ADObject = GetADObjectByGuid((Guid)guid); using (DirectoryEntry entry = ADObject.entry) { if (entry != null) { // disable users under AD object and move them to specific folder var deletedPath = ADObject.syncTree.DeletedADObjectsPath; bool entryDeleted = false; using (DirectoryEntry deletedParent = ADObject.syncTree.ConnectToObject(deletedPath)) { using (SearchResultCollection resultColl = ADObject.syncTree.GetUsersUnderADObject(entry)) { foreach (SearchResult result in resultColl) { using (DirectoryEntry userEntry = result.GetDirectoryEntry()) { var userPath = userEntry.Path; // disable user and move to deleted folder if (deletedParent != null) { userEntry.MoveTo(deletedParent); } else { AdLog.LogError("Folder for deleted users could not be found on AD server!"); } Common.DisableUserAccount(userEntry); Common.DisableADObjectCustomProperties(userEntry, _propertyMappings, _config.ADNameMaxLength, _config.ADsAMAccountNameMaxLength); userEntry.CommitChanges(); // ha a parent objektum maga egy user volt, akkor őt később már nem kell törölni if (entry.Path == userPath) { entryDeleted = true; } } } } } // delete remaining entries under this entry including itself (if it has not been deleted yet) if (!entryDeleted) { // double check user containment: if it still contains users, raise an error! using (SearchResultCollection resultColl = ADObject.syncTree.GetUsersUnderADObject(entry)) { if (resultColl.Count == 0) { entry.DeleteTree(); } else { AdLog.LogErrorADObject("AD container cannot be deleted, it contains users!", entry.Path); } } } } else { AdLog.LogErrorPortalObject(string.Format("AD object with the given GUID ({0}) does not exist", guid.ToString()), nodePath); } } } else { AdLog.LogErrorPortalObject("Portal node does not have a syncguid", nodePath); } } catch (Exception ex) { AdLog.LogException(ex); throw new Exception(ex.Message, ex); } }
/* ==================================================================================== AD -> portal : Main algorithms */ // sync one object // két helyről hívhatjuk: // - SyncObjectsFromAD --> innen SearchResult objektumot kapunk // - SyncObjectsFromAD/EnsurePath --> innen Entryt kapunk // - utóbbiból helyes működésnél csak létre kell hozni új objektumot, de ha már létezik az objektum, akkor // moveoljuk, ne keletkezzen két azonos GUID-ú objektum a portálon private void SyncOneADObject(SearchResult result, DirectoryEntry ADentry, Guid guid, ADObjectType objType, string nodePortalParentPath, Action <DirectoryEntry, string, Guid, SyncTree> CreateNewObject, Action <DirectoryEntry, Node, SyncTree> UpdateProperties, SyncTree syncTree) { //bool validResult; //var node = GetNodeByGuid(guid, objType, out validResult); Node node = null; string guidStr = guid.ToString(); switch (objType) { case ADObjectType.AllContainers: node = (_portalContainers.ContainsKey(guidStr)) ? Node.LoadNode(_portalContainers[guidStr]) : null; break; case ADObjectType.User: node = (_portalUsers.ContainsKey(guidStr)) ? Node.LoadNode(_portalUsers[guidStr]) : null; break; case ADObjectType.Group: node = (_portalGroups.ContainsKey(guidStr)) ? Node.LoadNode(_portalGroups[guidStr]) : null; break; default: break; } if (node != null) { // existing portal object try { bool isNodeSynced = false; // check path, move object if necessary if (RepositoryPath.GetParentPath(node.Path) != nodePortalParentPath) { AdLog.LogADObject(string.Format("Moving object from {0} to {1}", node.Path, nodePortalParentPath), result.Path); Node.Move(node.Path, nodePortalParentPath); // reload node for further processing (set properties) node = Node.LoadNode(node.Id); isNodeSynced = true; } if (ADentry != null) { // ensurepath-ból jön, mindenképp szinkronizáljuk UpdateProperties(ADentry, node, syncTree); AdLog.LogADObject(String.Format("Saving synced portal object: {0}", node.Path), ADentry.Path); Common.UpdateLastSync(node, null); //node.Save(); - update lastsync already saves node } else { // syncobjectsből jövünk, csak resultunk van (entrynk nincs) // set properties and lastsync date - csak akkor szinkronizálunk, ha lastmod > x // (ha az objektum át lett mozgatva, a lastmod is változik AD-ben) if (_config.AlwaysSyncObjects || Common.IsPortalObjectInvalid(node, result, _config.NovellSupport)) { using (var entry = result.GetDirectoryEntry()) { UpdateProperties(entry, node, syncTree); isNodeSynced = true; } } if (isNodeSynced) { AdLog.LogADObject(String.Format("Saving synced portal object: {0}", node.Path), result.Path); Common.UpdateLastSync(node, null); //node.Save(); - update lastsync already saves node } } } catch (Exception ex) { AdLog.LogException(ex); // log: adott objektum szinkronizálása nem sikerült if (result != null) { AdLog.LogErrorADObject("Syncing of AD object not successful.", result.Path); } } } else { if (ADentry != null) { // ensurepath-ból jövünk CreateNewObject(ADentry, nodePortalParentPath, guid, syncTree); } else { // syncobjectsből jövünk, csak resultunk van // new portal object using (var entry = result.GetDirectoryEntry()) { CreateNewObject(entry, nodePortalParentPath, guid, syncTree); } } } }
private void SyncSingleObjectFromAD(string ldapPath) { SyncTree syncTree = null; DirectoryEntry entry = null; foreach (SyncTree sTree in _syncTrees) { if (sTree.ContainsADPath(ldapPath)) { entry = sTree.ConnectToObject(ldapPath); syncTree = sTree; } } if (syncTree == null) { AdLog.LogErrorADObject("Configured SyncTree could not be found for this path", ldapPath); return; } string nodePortalParentPath = syncTree.GetPortalParentPath(ldapPath); if (!Node.Exists(nodePortalParentPath)) { AdLog.LogErrorADObject(string.Format("Portal parent path ({0}) does not exist", nodePortalParentPath), ldapPath); return; } if (entry == null) { AdLog.LogErrorADObject("AD Entry is not found", ldapPath); return; } var guid = Common.GetADObjectGuid(entry, _config.GuidProp); if (!guid.HasValue) { AdLog.LogErrorADObject("AD Entry guid cannot be retrieved", ldapPath); return; } var adObjectType = Common.GetADObjectType(entry, false); Action <DirectoryEntry, string, Guid, SyncTree> CreateNewObject = null; Action <DirectoryEntry, Node, SyncTree> UpdateProperties = null; switch (adObjectType) { case ADObjectType.User: CreateNewObject = CreateNewPortalUser; UpdateProperties = UpdatePortalUserProperties; break; case ADObjectType.Group: CreateNewObject = CreateNewPortalGroup; UpdateProperties = UpdatePortalGroupProperties; break; case ADObjectType.Container: case ADObjectType.Organization: case ADObjectType.OrgUnit: CreateNewObject = CreateNewPortalContainer; UpdateProperties = UpdatePortalContainerProperties; break; default: AdLog.LogErrorADObject("Syncing of this type is not supported.", ldapPath); return; } // check if node already exists: var node = Common.GetPortalObjectByGuid(guid.Value); if (node == null) { if (!Node.Exists(nodePortalParentPath)) { EnsurePortalPath(syncTree, syncTree.GetADParentObjectPath(ldapPath), RepositoryPath.GetParentPath(nodePortalParentPath)); } CreateNewObject(entry, nodePortalParentPath, guid.Value, syncTree); } else { if (RepositoryPath.GetParentPath(node.Path) != nodePortalParentPath) { Node.Move(node.Path, nodePortalParentPath); // reload node for further processing (set properties) node = Node.LoadNode(node.Id); } UpdateProperties(entry, node, syncTree); Common.UpdateLastSync(node, null); } }
private void UpdatePortalGroupProperties(DirectoryEntry entry, Node node, SyncTree syncTree) { AdLog.LogObjects("Updating portal group properties", entry.Path, node.Path); node.Name = Common.GetADObjectName(entry.Name); // set members var group = (Group)node; var portalMembers = group.Members; var adMembers = GetADGroupMembers(entry, syncTree); var removeMembers = new List <Node>(); // add new members: foreach (Guid guid in adMembers.Keys) { try { //bool validResult; //Node portalNode = GetNodeByGuid(guid, adMembers[guid].objType, out validResult); //string adPath = adMembers[guid].Path; //var portalNodePath = syncTree.GetPortalPath(adPath); //portalNodePath = portalNodePath.Substring(0, portalNodePath.LastIndexOf('/')); //portalNodePath = RepositoryPath.Combine(portalNodePath, adMembers[guid].SamAccountName); //Node portalNode = Node.Load<Node>(portalNodePath); Node portalNode = null; string guidStr = guid.ToString(); if (_useOnTheFlyMemberQuery) { portalNode = Common.GetPortalObjectByGuid(guid); } else { switch (adMembers[guid].objType) { case ADObjectType.User: portalNode = (_portalUsers.ContainsKey(guidStr)) ? Node.LoadNode(_portalUsers[guidStr]) : null; break; case ADObjectType.Group: portalNode = (_portalGroups.ContainsKey(guidStr)) ? Node.LoadNode(_portalGroups[guidStr]) : null; break; default: break; } } if (portalNode != null) { if (!portalMembers.Any(n => n.Id == portalNode.Id)) { switch (adMembers[guid].objType) { case ADObjectType.Group: group.AddMember((IGroup)portalNode); break; case ADObjectType.User: group.AddMember((IUser)portalNode); break; default: // log: AD group membere se nem user, se nem group AdLog.LogErrorObjects("Member is neither a user nor a group", adMembers[guid].Path, portalNode.Path); break; } } } else { // log: a group a portálon nem létező user-t tartalmaz // a synctree-k elvileg tartalmazzák, mert a GetADGroupMembers csak synctree által tartalmazott objektumokat ad vissza AdLog.LogErrorADObject("Member does not exist in portal", adMembers[guid].Path); } } catch { AdLog.LogErrorADObject("Could not add member to group", adMembers[guid].Path); } } // remove old members // add nodes of portal group members to removeMembers list, // that have no corresponding AD objects in AD group foreach (Node member in portalMembers) { string guidStr = member["SyncGuid"] as string; if (guidStr != null) { if (!adMembers.Keys.Contains(new Guid(guidStr))) { removeMembers.Add(member); } } else { // log: a portál csoport szinkronizálatlan objektumot is tartalmaz AdLog.LogError(string.Format("Portal group contains unsynchronized object (group: {0}, object: {1}", group.Path, member.Path)); } } // remove members from portal group foreach (Node member in removeMembers) { var portalUser = member as IUser; if (portalUser != null) { group.RemoveMember(portalUser); } else { var portalGroup = member as IGroup; if (portalGroup != null) { group.RemoveMember(portalGroup); } } } // node.Save() nem kell, később mentődik }