Пример #1
0
        public void SyncMembership(ITaskReporter reporter)
        {
            var filteredGroups = this.groups.Where(g => g.SyncGroupSource == this.configuration.LdapSyncGroupSource).ToList();

            reporter.StartTask("Gruppenmitgliedschaften abgleichen", filteredGroups.Count);

            // Refetch group members (might have been changed/renamed!).
            var newGroups = this.GetLdapGroups();

            foreach (var group in filteredGroups)
            {
                reporter.Progress(group.Name);

                // Set base for diff with new values.
                LdapGroup newGroup = newGroups.FirstOrDefault(g => g.SyncGroupId == group.SyncGroupId && g.SyncGroupSource == this.configuration.LdapSyncGroupSource);
                if (newGroup != null)
                {
                    group.SetOriginalMembers(newGroup.OrginalMembers);
                }

                DirectoryAttributeModification[] addedMembers = group.AddedMembers
                                                                .Select(m => new DirectoryAttribute("member", m).CreateModification(DirectoryAttributeOperation.Add))
                                                                .ToArray();

                DirectoryAttributeModification[] removedMembers = group.RemovedMembers
                                                                  .Where(m => !m.EndsWith(this.configuration.LdapGruppenBaseDn))
                                                                  .Select(m => new DirectoryAttribute("member", m).CreateModification(DirectoryAttributeOperation.Delete, forceValue: true))
                                                                  .ToArray();

                if (addedMembers.Any() || removedMembers.Any())
                {
                    string groupDn = $"cn={group.Name},{this.configuration.LdapGruppenBaseDn}";
                    DirectoryAttributeModification[] modifications = addedMembers.Concat(removedMembers).ToArray();

                    this.ldap.ModifyEntry(groupDn, modifications);

                    foreach (var item in modifications)
                    {
                        foreach (string name in item.GetValues <string>())
                        {
                            reporter.Log((item.Operation == DirectoryAttributeOperation.Add ? "Hinzugefügt" : "Entfernt") + ": " + name);
                        }
                    }

                    Log.Source.TraceEvent(TraceEventType.Information, 0, "Updated members of LDAP group '{0}': {1} added, {2} removed.", group.Name, addedMembers.Length, removedMembers.Length);
                    foreach (string modifiedPrint in modifications.SelectMany(Log.Print))
                    {
                        Log.Source.TraceEvent(TraceEventType.Verbose, 0, "Update to LDAP group '{0}': {1}.", group.Name, modifiedPrint);
                    }
                }
            }
        }
Пример #2
0
        public static LdapGroup FromEntry(Novell.Directory.Ldap.LdapEntry entry)
        {
            LdapGroup group = new LdapGroup();

            string[] attrs = new string[] { "cn", "sAMAccountName", "distinguishedName", "member" };

            System.Reflection.FieldInfo[] fis = typeof(LdapGroup).GetFields();

            foreach (System.Reflection.FieldInfo fi in fis)
            {
                string fieldName = fi.Name;

                int ind = System.Array.FindIndex(attrs, x => string.Equals(x, fieldName, System.StringComparison.InvariantCultureIgnoreCase));
                if (ind == -1)
                {
                    continue;
                }

                string attributeName = attrs[ind];
                Novell.Directory.Ldap.LdapAttribute att = entry.getAttribute(attributeName);

                if (att == null)
                {
                    continue;
                }

                if (fi.FieldType.IsGenericType)
                {
                    fi.FieldType.GetMethod("AddRange").Invoke(fi.GetValue(group), new object[] { att.StringValueArray });
                }
                else
                {
                    fi.SetValue(group, att.StringValue);
                }
            } // Next fi

            return(group);
        } // End Function FromEntry
 public static bool IsDivisionAdminForGroup(this ClaimsPrincipal user, LdapGroup group)
 {
     return(user.HasClaim(IsDivisionLgsClaim.ClaimType, group.DivisionId));
 }
Пример #4
0
        private void SyncUser(ITaskReporter reporter, PersonModel model, SearchResultEntry entry, bool fullSync)
        {
            ICollection <PersonenkategorieModel> kategorien = this.groups.GetKategorien(model.Nr);
            // this.optigem.GetPersonenkategorien(model.Nr).ToList();

            bool disabled = this.IsDisabled(model, kategorien);

            string baseDn;
            string requiredBaseDn;

            string mitgliederBase = "ou=mitglieder," + this.configuration.LdapBenutzerBaseDn;
            string externBase     = "ou=extern," + this.configuration.LdapBenutzerBaseDn;

            if (disabled)
            {
                requiredBaseDn = this.configuration.LdapInaktiveBenutzerBaseDn;
                baseDn         = requiredBaseDn;
            }
            else
            {
                requiredBaseDn = this.configuration.LdapBenutzerBaseDn;
                baseDn         = kategorien.Any(k => k.Name == "Mitglied") ? mitgliederBase : externBase;
            }

            string cn = LdapBuilder.GetCn(model.Username);
            string dn = $"cn={cn},{baseDn}";

            if (disabled && model.EndDatum.HasValue && model.EndDatum.Value < DateTime.Today.AddYears(-2))
            {
                // More than two years inactive => delete in LDAP

                // No entry in LDAP => ok, NOP
                if (entry != null)
                {
                    try
                    {
                        reporter.Log($"Benutzer wird gelöscht (mehr als 2 Jahre inaktiv): {entry.DistinguishedName}");
                        this.ldap.DeleteEntry(entry.DistinguishedName);
                    }
                    catch (Exception exception)
                    {
                        reporter.Log($"Beim Versuch den Benutzer {cn} zu löschen ist ein Fehler aufgetreten: {exception.Message}");
                    }
                }

                return;
            }

            if (entry == null)
            {
                SearchResultEntry[] searchResult = this.ldap
                                                   .PagedSearch($"(&(objectClass=inetOrgPerson)(syncUserId={model.SyncUserId}))", this.configuration.LdapDirectoryBaseDn, LdapBuilder.AllAttributes)
                                                   .SelectMany(s => s.OfType <SearchResultEntry>())
                                                   .ToArray();

                if (searchResult.Length == 0)
                {
                    DirectoryAttribute[] attributes = LdapBuilder.GetAllAttributes(model, disabled).ToArray();

                    this.ldap.AddEntry(dn, attributes);
                    Log.Source.TraceEvent(TraceEventType.Information, 0, "Added new LDAP user '{0}'.", dn);
                    reporter.Log($"Neuer Benutzer hinzugefügt: {dn}");
                }
                else
                {
                    entry = searchResult.First();
                }
            }

            if (entry != null)
            {
                string oldDn     = entry.DistinguishedName;
                string oldBaseDn = oldDn.Split(new[] { ',' }, 2).Last();

                Log.Source.TraceEvent(TraceEventType.Verbose, 0, "Syncing LDAP user '{0}'.", oldDn);

                if (!oldDn.EndsWith(requiredBaseDn) ||
                    (oldBaseDn == externBase && baseDn == mitgliederBase) ||
                    (oldBaseDn == mitgliederBase && baseDn == externBase))
                {
                    this.ldap.MoveEntry(oldDn, baseDn, $"cn={cn}");
                    Log.Source.TraceEvent(TraceEventType.Information, 0, "Moved LDAP user from '{0}' to '{1}'.", oldDn, dn);
                    reporter.Log($"Benutzer von {oldDn} nach {dn} verschoben.");
                }
                else
                {
                    // User was not moved. Set baseDn to actual baseDn.
                    baseDn = oldBaseDn;
                    dn     = $"cn={cn},{baseDn}";

                    string oldCn = entry.Attributes["cn"][0]?.ToString();
                    if (oldCn != cn)
                    {
                        dn = $"cn={cn},{oldBaseDn}";
                        this.ldap.MoveEntry(oldDn, oldBaseDn, $"cn={cn}");
                        Log.Source.TraceEvent(TraceEventType.Information, 0, "Renamed LDAP user from '{0}' to '{1}'.", oldCn, cn);
                        reporter.Log($"Benutzer von {oldCn} nach {cn} umbenannt.");
                    }
                }

                DirectoryAttributeModification[] diffAttributes = null;

                if (fullSync)
                {
                    diffAttributes = LdapBuilder.GetDiff(
                        LdapBuilder.GetUpdateAttributes(model, disabled),
                        entry,
                        LdapBuilder.CreateAttributes.Union(new[] { "cn", "dn" }).ToArray())
                                     .ToArray();
                }
                else
                {
                    // only update disabled attribute
                    diffAttributes = LdapBuilder.GetDiff(
                        LdapBuilder.GetUpdateAttributes(model, disabled),
                        entry,
                        LdapBuilder.AllAttributes.Except(new[] { "typo3disabled" }).ToArray())
                                     .ToArray();
                }

                if (diffAttributes?.Any() ?? false)
                {
                    this.ldap.ModifyEntry(dn, diffAttributes);
                    Log.Source.TraceEvent(TraceEventType.Information, 0, "Updated LDAP user '{0}'.", dn);
                    foreach (var diff in diffAttributes)
                    {
                        var    oldAttr  = entry.Attributes.Values?.OfType <DirectoryAttribute>().FirstOrDefault(a => string.Equals(a.Name, diff.Name, StringComparison.InvariantCultureIgnoreCase));
                        string oldValue = oldAttr == null ? string.Empty : string.Join("', '", oldAttr.GetValues <string>());
                        Debug.Assert(oldValue != string.Join("', '", diff.GetValues <string>()));
                        reporter.Log($"{diff.Name} auf '{string.Join("', '", diff.GetValues<string>())}' gesetzt (alt: '{oldValue}').");
                    }

                    foreach (string attributeChange in diffAttributes.SelectMany(Log.Print))
                    {
                        Log.Source.TraceEvent(TraceEventType.Verbose, 0, "Updated LDAP user '{0}': {1}", cn, attributeChange);
                    }
                }
            }

            if (!disabled)
            {
                foreach (PersonenkategorieModel kategorie in kategorien)
                {
                    LdapGroup group = this.groups.Get(kategorie);

                    if (group == null)
                    {
                        Log.Source.TraceEvent(TraceEventType.Warning, 0, "LDAP group does not exist: '{0}'", kategorie.Name);
                    }
                    else
                    {
                        group.MemberList.Add(dn);
                    }
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Gets all groups found via LDAP
        /// </summary>
        /// <param name="ldapConfig">LDAP configuration</param>
        public LdapGroup[] GetGroups(LdapSettings ldapConfig)
        {
            List <LdapGroup> groups = new List <LdapGroup>();

            // Connect to group directory via LDAP
            string ldapStr = GetLdapStr(ldapConfig);

            using DirectoryEntry entry = Connect($"{ldapStr}/{ldapConfig.LdapGroupDN},{ldapConfig.LdapBaseDN}");

            // Apply search filter
            using DirectorySearcher searcher = new DirectorySearcher(entry);
            searcher.Filter = ldapConfig.LdapGroupFilter;

            // Return all found groups
            foreach (SearchResult result in searcher.FindAll())
            {
                using DirectoryEntry groupEntry = result?.GetDirectoryEntry();
                if (groupEntry == null)
                {
                    continue;
                }

                // Obtain attributes
                object guidData  = groupEntry.Properties[ldapConfig.LdapGroupGuidAttr]?.Value;
                string groupName = groupEntry.Properties[ldapConfig.LdapGroupNameAttr]?.Value?.ToString();

                if (guidData == null ||
                    !(guidData is byte[]) ||
                    string.IsNullOrWhiteSpace(groupName))
                {
                    continue;
                }

                string guid  = (new Guid((byte[])guidData)).ToString();
                var    group = new LdapGroup(guid, groupName);

                // Get all members
                object[] members = groupEntry.Properties[ldapConfig.LdapMember]?.Value as object[];
                if (members == null)
                {
                    continue;
                }
                // Add all found member to group
                foreach (object memberObj in members)
                {
                    string userDN = memberObj.ToString();
                    if (string.IsNullOrWhiteSpace(userDN) || !userDN.Contains(ldapConfig.LdapBaseDN, StringComparison.CurrentCultureIgnoreCase))
                    {
                        // Skip users not part of the LDAP service
                        continue;
                    }

                    // Get user entry
                    using DirectoryEntry user = Connect($"{ldapStr}/{userDN}");
                    if (user == null)
                    {
                        continue;
                    }

                    object userGuidData = user.Properties[ldapConfig.LdapUserGuidAttr]?.Value;
                    string userName     = user.Properties[ldapConfig.LdapUserNameAttr]?.Value?.ToString();
                    if (userGuidData == null ||
                        !(userGuidData is byte[]) ||
                        string.IsNullOrWhiteSpace(userName))
                    {
                        // Skip users without GUID or name
                        continue;
                    }

                    string userGuid = (new Guid((byte[])userGuidData)).ToString();

                    _logger.LogDebug("{0} (Guid: {1}) is in group: {2}", userName, userGuid, groupName);
                    group.UserGuids.Add(userGuid);
                }

                groups.Add(group);
            }

            return(groups.ToArray());
        }
Пример #6
0
 /// <summary>
 /// Creates a new role based on information from LDAP
 /// </summary>
 /// <param name="ldapGroup">LDAP group information</param>
 public static Role FromLDAP(LdapGroup ldapGroup) =>
 new Role(ldapGroup.Name)
 {
     Origin   = Origins.LDAP,
     LdapGuid = ldapGroup.LdapGuid
 };
Пример #7
0
 /// <summary>
 /// Reactivates a role (group)
 /// </summary>
 /// <param name="ldapGroup">LDAP group information</param>
 internal void Reactivate(LdapGroup ldapGroup)
 {
     IsDeleted = false;
     Name      = ldapGroup.Name;
 }
 /// <summary>
 /// Removes the Deleted-Mark from a role (group) again and rehydrates the information from LDAP
 /// </summary>
 /// <param name="roleManager"></param>
 /// <param name="role"></param>
 /// <param name="ldapGroup"></param>
 public static async Task <IdentityResult> ReactivateRoleAsync(this RoleManager <Role> roleManager, Role role, LdapGroup ldapGroup)
 {
     role.Reactivate(ldapGroup);
     return(await roleManager.UpdateAsync(role));
 }