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