private int CreateNewLdapUsers(ITaskReporter reporter)
        {
            IList <PersonModel> persons = this.optigem.GetNewPersons().ToList();

            reporter.StartTask("Neue Personen in OPTIGEM vorbereiten", persons.Count);

            if (persons.Any())
            {
                int intranetUid = this.optigem.GetNextSyncUserId();

                foreach (var person in persons)
                {
                    string username = LdapBuilder.GetCn((person.Vorname?.Trim() + "." + person.Nachname?.Trim()).Trim('.')).ToLower(CultureInfo.CurrentCulture);

                    reporter.Progress(username);

                    person.Username   = username.Length > 50 ? username.Substring(0, 50) : username;
                    person.Password   = this.CalculatePassword();
                    person.SyncUserId = intranetUid++;

                    reporter.Log(person.Username + " mit Id " + person.SyncUserId + " angelegt.");
                }

                this.optigem.SetIntranetUserIds(persons);

                return(persons.Count);
            }

            return(0);
        }
Beispiel #2
0
        private void OnPasswordSetClicked(object sender, EventArgs e)
        {
            var optigem = new OptigemConnector(this.configuration.OptigemDatabasePath);

            IList <PersonModel> persons = optigem.GetAllPersons(this.txbAddUsername.Text?.Trim())
                                          .ToList();

            if (!persons.Any())
            {
                MessageBox.Show("Es konnte kein Benutzer mit dem angegebenen Benutzernamen gefunden werden.", "Fehler...", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else if (persons.Count() > 1)
            {
                MessageBox.Show("Es wurde mehr als ein Benutzer mit dem angegebenen Benutzernamen gefunden.", "Fehler...", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                var person = persons.First();

                var parser = new LdapConnectionStringParser {
                    ConnectionString = optigem.GetLdapConnectionString()
                };
                var ldap = new LdapConnector(parser.Server, parser.Port, AuthType.Basic, parser.User, parser.Password, 100, this.configuration.WhatIf);

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

                if (searchResult.Length == 0)
                {
                    MessageBox.Show("Der ausgewählte Benutzer ist in LDAP nicht vorhanden." + Environment.NewLine + "Das Passwort kann nicht gesetzt werden.", "Fehler...", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else if (searchResult.Length > 1)
                {
                    MessageBox.Show("Für den Benutzer ist mehr als ein Eintrag in LDAP vorhanden." + Environment.NewLine + "Das Passwort kann nicht gesetzt werden.", "Fehler...", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    var entry = searchResult.First();

                    var  password = new DirectoryAttribute("userpassword", LdapBuilder.GenerateSaltedSha1(person.Password));
                    bool result   = ldap.ModifyEntry(entry.DistinguishedName, new DirectoryAttributeModification[] { password.CreateModification(DirectoryAttributeOperation.Replace) });

                    if (result)
                    {
                        MessageBox.Show("Das Passwort für den Benutzer wurde zurück gesetzt (siehe Feld in OPTIGEM).", "Passwort zurückgesetzt...", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else
                    {
                        MessageBox.Show("Beim Zurücksetzen des Passworts is ein Fehler aufgetreten.", "Fehler...", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }
Beispiel #3
0
        public void SyncMetadata(ITaskReporter reporter)
        {
            this.categories = this.optigem.GetCategories().ToList();
            Log.Source.TraceEvent(TraceEventType.Verbose, 0, "Fetched {0} groups from Optigem.", categories.Count);

            this.zuordnungen = this.optigem.GetAllKategorieZuordnungen().ToList();

            reporter.StartTask("Personenkategorien abgleichen", categories.Count + 1);

            this.groups = this.GetLdapGroups();
            Log.Source.TraceEvent(TraceEventType.Verbose, 0, "Fetched {0} groups from LDAP.", this.groups.Count);

            var openGroups = groups.Where(g => g.SyncGroupSource == this.configuration.LdapSyncGroupSource).ToList();

            Log.Source.TraceEvent(TraceEventType.Verbose, 0, "{0} groups from LDAP have correct sync source ('{1}').", openGroups.Count, this.configuration.LdapSyncGroupSource);

            foreach (PersonenkategorieModel category in categories)
            {
                reporter.Progress(category.Name);

                var group = groups.FirstOrDefault(g => g.SyncGroupSource == this.configuration.LdapSyncGroupSource && g.SyncGroupId == category.Id);

                string name    = LdapBuilder.GetCn(category.Name);
                string groupDn = $"cn={name},{this.configuration.LdapGruppenBaseDn}";

                if (group != null)
                {
                    if (group.Name != name)
                    {
                        this.ldap.MoveEntry($"cn={group.Name},{this.configuration.LdapGruppenBaseDn}", this.configuration.LdapGruppenBaseDn, $"cn={name}");

                        Log.Source.TraceEvent(TraceEventType.Information, 0, "Updated group name from '{0}' to '{1}'.", group.Name, name);
                        reporter.Log($"Updated group name from '{group.Name}' to '{name}'.");

                        group.Name = name;
                    }

                    openGroups.Remove(group);
                }
                else
                {
                    // Add new group
                    this.ldap.AddEntry(
                        groupDn,
                        new[]
                    {
                        new DirectoryAttribute("cn", name),
                        new DirectoryAttribute("syncgroupsource", this.configuration.LdapSyncGroupSource),
                        new DirectoryAttribute("syncgroupid", category.Id.ToString()),
                        new DirectoryAttribute("objectclass", "top", "groupOfNames", "feggroup")
                    });

                    Log.Source.TraceEvent(TraceEventType.Information, 0, "Added new group '{0}'.", groupDn);
                    reporter.Log($"Added new group '{groupDn}'.");

                    if (this.configuration.LdapDefaultParentGroups != null)
                    {
                        foreach (string parentGroupDn in this.configuration.LdapDefaultParentGroups)
                        {
                            var addAttribute = new DirectoryAttributeModification {
                                Name = "member", Operation = DirectoryAttributeOperation.Add
                            };
                            addAttribute.Add(groupDn);

                            this.ldap.ModifyEntry(
                                parentGroupDn,
                                new[] { addAttribute });

                            Log.Source.TraceEvent(TraceEventType.Information, 0, "Added new group '{0}' to parent group '{1}'.", name, parentGroupDn);
                            reporter.Log($"Added new group '{name}' to parent group '{parentGroupDn}'.");
                        }
                    }

                    groups.Add(new LdapGroup {
                        Name = name, SyncGroupId = category.Id, SyncGroupSource = this.configuration.LdapSyncGroupSource
                    });
                }
            }

            reporter.Progress("Checking for obsolete groups...");

            // Remove obsolete groups
            foreach (var group in openGroups)
            {
                this.ldap.DeleteEntry($"cn={group.Name},{this.configuration.LdapGruppenBaseDn}");
                Log.Source.TraceEvent(TraceEventType.Information, 0, "Deleted obsolete group '{0}'.", group.Name);
                reporter.Log($"Deleted obsolete group '{group.Name}'.");
                groups.Remove(group);
            }
        }
        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);
                    }
                }
            }
        }