Fuer den Fall, dass der alte Benutzer schon geloescht und der neue von Hand angelegt wurde - dann liegt nur noch das Verzeichnis herum. users.cfg bleibt unangetastet, es wandert allein das Verzeichnis. Geprueft wird vorher, dass der Zielbenutzer existiert und der alte nicht mehr; gibt es ihn noch, verweist das Script auf die normale Umbenennung. Hat das Ziel schon ein Verzeichnis mit Mails, bricht es ab - mit --force wird das bestehende als <name>.abgeloest-<zeitstempel> beiseitegeschoben statt geloescht. Die Zielpruefung arbeitet jetzt als Folge statt paarweise: bei der Uebernahme raeumt der erste Schritt das Ziel, das der zweite belegt. Eine isolierte Pruefung haette das als Konflikt gemeldet. Dazu die Kontaktkarte: .personal traegt Namen und Adresse des vorherigen Eigentuemers. Sie wird jetzt umgeschrieben statt entfernt - Kerio legt sie naemlich nicht neu an, wenn sie fehlt, weder beim Neustart noch bei einer Aenderung ueber die Admin-API. Das gilt auch fuer die normale Umbenennung, wo bisher die alte Adresse stehenblieb. Beides gegen den Testserver verifiziert: nach der Uebernahme sieht der Zielbenutzer alle Mails samt Unterordnern und Flags, die Kontaktkarte stimmt, users.cfg ist unveraendert und neue Mail wird zugestellt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
316 lines
13 KiB
Markdown
316 lines
13 KiB
Markdown
# kerio-connect-rename-user
|
|
|
|
Werkzeuge für Kerio Connect auf der Kommandozeile.
|
|
|
|
| Datei | Zweck |
|
|
| --- | --- |
|
|
| [`kerio_rename_user.py`](kerio_rename_user.py) | Benutzer umbenennen — Login-Name **und** Mailbox-Verzeichnis im Store |
|
|
| [`kerio_users_config.py`](kerio_users_config.py) | Lesen und Ändern von `users.cfg` |
|
|
| [`kerio_common.py`](kerio_common.py) | Gemeinsame Bausteine: Admin-API-Client, Dienststeuerung |
|
|
|
|
Das Script läuft **lokal auf dem Kerio-Server als root**, braucht nur die
|
|
Python-Standardbibliothek und bietet `--dry-run`.
|
|
|
|
## Getestet
|
|
|
|
Gegen **Kerio Connect 10.0.9 patch 2** auf Debian 12, mit lizenziertem Server
|
|
und laufendem IMAP. Ein Benutzer mit gefüllter Mailbox wurde umbenannt und
|
|
danach geprüft:
|
|
|
|
| Prüfung | Ergebnis |
|
|
| --- | --- |
|
|
| IMAP-Login mit dem neuen Namen | funktioniert |
|
|
| IMAP-Login mit dem alten Namen | wird abgewiesen |
|
|
| Alle Mails in INBOX und Unterordner | vollständig vorhanden |
|
|
| Flags (`\Seen`, `\Flagged`) | erhalten |
|
|
| Mail-Dateien (`.eml`), md5 vorher/nachher | bitgleich |
|
|
| Neue Mail an die neue Adresse | `Result: delivered` |
|
|
| Mail an die alte Adresse | `550 5.1.1 Mailbox does not exist` |
|
|
| Verwaistes Verzeichnis unter dem alten Namen | keines |
|
|
| GUID und Passwort-Hash des Benutzers | unverändert |
|
|
|
|
Und für `--adopt`, mit gelöschtem Altbenutzer und neu angelegtem Zielbenutzer:
|
|
|
|
| Prüfung | Ergebnis |
|
|
| --- | --- |
|
|
| Alle 7 Mails beim neuen Benutzer sichtbar | ja, inklusive Unterordner und Flags |
|
|
| Kontaktkarte `.personal` | auf neuen Namen und Adresse umgeschrieben |
|
|
| `users.cfg` | unverändert |
|
|
| Neue Mail an den Zielbenutzer | zugestellt |
|
|
| Verwaistes Verzeichnis | keines übrig |
|
|
|
|
Geändert haben sich nur Kerios eigene Index- und Statusdateien (`.journal.db`,
|
|
`status.fld`, `index.fld`) — die schreibt der Server bei jedem Zugriff neu.
|
|
|
|
Dazu Unit-Tests unter [tests/](tests/):
|
|
|
|
```bash
|
|
python3 tests/test_store.py
|
|
python3 tests/test_users_config.py
|
|
python3 tests/test_adopt.py
|
|
```
|
|
|
|
---
|
|
|
|
# Benutzer umbenennen
|
|
|
|
## Warum das nicht trivial ist
|
|
|
|
Kerio hält den Benutzernamen an zwei Stellen, die nichts voneinander wissen:
|
|
|
|
| Wo | Was |
|
|
| --- | --- |
|
|
| `users.cfg` | Der Login-Name, in **zwei** Listen: `User` und `UserAdditionalData` |
|
|
| Dateisystem | `<store>/mail/<domain>/<loginname>/` — die eigentliche Mailbox |
|
|
|
|
Ändert man nur den Login-Namen, sucht Kerio ab sofort im Verzeichnis mit dem
|
|
*neuen* Namen, findet keins, legt ein leeres an — und die alten Mails liegen
|
|
weiter unter dem alten Verzeichnisnamen. Typischer Anlass für eine Umbenennung:
|
|
Heirat oder ein anderer Namenswechsel.
|
|
|
|
## Warum nicht über die Administration API
|
|
|
|
**Die API kann das nicht.** `Users.set` nimmt ein Feld `loginName` entgegen und
|
|
ignoriert es stillschweigend — kein Fehler, keine Wirkung. Nachgeprüft gegen
|
|
Kerio Connect 10.0.9 mit vier Varianten (nur `loginName`, mit `domainId`, mit
|
|
leeren `emailAddresses`, vollständiges User-Objekt): alle wirkungslos, während
|
|
`fullName` im selben Aufruf sauber übernommen wird.
|
|
|
|
Deshalb arbeitet das Script direkt auf `users.cfg` — und braucht dadurch
|
|
**keine Admin-Zugangsdaten**.
|
|
|
|
## Ablauf
|
|
|
|
1. **Vorprüfungen**, bevor irgendetwas geschrieben wird:
|
|
- Domain und Benutzer in `users.cfg` vorhanden?
|
|
- Benutzer aus einem Verzeichnisdienst (`InternalDb=0`)? → Abbruch, denn
|
|
dann gehört der Name dem Verzeichnisdienst
|
|
- neuer Login-Name frei und zeichenmäßig zulässig?
|
|
- Zielverzeichnis unbelegt, Quelle und Ziel auf demselben Dateisystem?
|
|
- Dienst steuerbar?
|
|
2. Plan ausgeben. `--dry-run` endet hier, sonst Rückfrage (`--yes` überspringt).
|
|
3. Dienst stoppen.
|
|
4. `users.cfg` **neu einlesen**, Name in `User` und `UserAdditionalData` setzen,
|
|
atomar über eine temporäre Datei speichern.
|
|
5. Verzeichnisse verschieben (`mail/`, und `archive/` falls vorhanden).
|
|
6. Dienst starten und gegenlesen.
|
|
|
|
**Schritte 4 und 5 liegen bewusst in einem einzigen Stopp-Fenster.** Das ist
|
|
keine Bequemlichkeit: Läuft Kerio zwischendurch mit nur einer der beiden
|
|
Hälften, legt es die vermeintlich fehlende Mailbox sofort neu an, und man hat
|
|
ein verwaistes Verzeichnis mehr. Genau das ist beim Entwickeln passiert.
|
|
|
|
Schlägt etwas fehl, werden verschobene Verzeichnisse zurückgenommen und
|
|
`users.cfg` aus dem Backup wiederhergestellt.
|
|
|
|
## Benutzung
|
|
|
|
```bash
|
|
# Wer ist da? (kein root nötig)
|
|
./kerio_rename_user.py --list
|
|
|
|
# Erst ansehen:
|
|
./kerio_rename_user.py \
|
|
--domain firma.de \
|
|
--old-login anna.mueller \
|
|
--new-login anna.schmidt \
|
|
--full-name "Anna Schmidt" \
|
|
--dry-run
|
|
|
|
# Dann wirklich:
|
|
sudo ./kerio_rename_user.py \
|
|
--domain firma.de \
|
|
--old-login anna.mueller \
|
|
--new-login anna.schmidt \
|
|
--full-name "Anna Schmidt"
|
|
```
|
|
|
|
Nur den angezeigten Namen ändern, ohne Login und Verzeichnis anzufassen:
|
|
|
|
```bash
|
|
sudo ./kerio_rename_user.py --domain firma.de \
|
|
--old-login anna.mueller --full-name "Anna Schmidt"
|
|
```
|
|
|
|
## Verwaistes Verzeichnis übernehmen (`--adopt`)
|
|
|
|
Für den Fall, dass der alte Benutzer **schon gelöscht** und der neue **schon
|
|
angelegt** ist — dann liegt nur noch das Mailbox-Verzeichnis herum und soll dem
|
|
neuen Benutzer zugeordnet werden:
|
|
|
|
```bash
|
|
sudo ./kerio_rename_user.py --adopt \
|
|
--domain firma.de \
|
|
--old-login anna.mueller \
|
|
--new-login anna.schmidt
|
|
```
|
|
|
|
`--old-login` ist hier der Name des **verwaisten Verzeichnisses**, `--new-login`
|
|
der **bereits existierende** Zielbenutzer. `users.cfg` wird dabei nicht
|
|
angefasst — es wandert nur das Verzeichnis.
|
|
|
|
Geprüft wird vorher:
|
|
|
|
- Der Zielbenutzer existiert in `users.cfg` (sonst liefe die Mailbox ins Leere).
|
|
- Der alte Benutzer existiert **nicht** mehr. Gibt es ihn noch, bricht das
|
|
Script ab und verweist auf die normale Umbenennung, die auch `users.cfg`
|
|
mitzieht.
|
|
- Hat der Zielbenutzer schon ein Verzeichnis mit Mails darin, bricht das Script
|
|
ab. Mit `--force` wird das bestehende Verzeichnis als
|
|
`<name>.abgeloest-<zeitstempel>` beiseitegeschoben statt gelöscht — die Mails
|
|
bleiben also erhalten, werden aber **nicht** zusammengeführt.
|
|
|
|
Nach der Übernahme wird die Kontaktkarte des Benutzers (`.personal`) auf den
|
|
neuen Namen und die neue Adresse umgeschrieben, `stats.usr` beiseitegelegt —
|
|
die legt Kerio selbst neu an.
|
|
|
|
**Das Kennwort kommt nicht mit.** Der Zielbenutzer meldet sich weiterhin mit
|
|
seinem eigenen an; übernommen wird ausschließlich der Mailbestand.
|
|
|
|
## Optionen
|
|
|
|
| Option | Bedeutung |
|
|
| --- | --- |
|
|
| `--list` | Benutzer aus `users.cfg` auflisten |
|
|
| `--adopt` | Verwaistes Verzeichnis einem bestehenden Benutzer zuordnen |
|
|
| `--domain` | Mail-Domain, z. B. `firma.de` |
|
|
| `--old-login`, `--new-login` | Login-Namen ohne `@domain` |
|
|
| `--full-name` | Neuer angezeigter Name |
|
|
| `--install-dir` | Standard `/opt/kerio/mailserver` |
|
|
| `--store-dir` | Standard `/opt/kerio/mailserver/store` |
|
|
| `--service-name` | Dienstname, Standard `kerio-connect` |
|
|
| `--service-manager` | `auto`, `systemd`, `initd` oder `none` |
|
|
| `--service-wait` | Sekunden Wartezeit aufs Stoppen, Standard 90 |
|
|
| `--dry-run` | Nur anzeigen |
|
|
| `--yes` | Rückfrage überspringen |
|
|
| `--force` | Bei Verzeichnisdienst-Benutzern; mit `--adopt`: belegtes Ziel beiseiteschieben |
|
|
|
|
`--service-manager none` fasst den Dienst nicht an — dafür muss Kerio dann
|
|
selbst gestoppt sein, bevor das Script läuft.
|
|
|
|
## Die Kontaktkarte
|
|
|
|
`<mailbox>/.personal` ist die persönliche vCard des Benutzers und trägt seinen
|
|
Namen und seine Adresse. Das Script schreibt sie in beiden Modi auf den neuen
|
|
Stand um — Adresse, `FN:` und die Betreffzeile.
|
|
|
|
Löschen wäre keine Alternative: **Kerio legt die Datei nicht neu an**, wenn sie
|
|
fehlt. Weder beim Dienstneustart noch bei einer Änderung am Benutzer über die
|
|
Admin-API (geprüft gegen 10.0.9). Der Benutzer stünde dauerhaft ohne eigene
|
|
Kontaktkarte da.
|
|
|
|
## Was das Script bewusst nicht anfasst
|
|
|
|
Der alte Name bleibt an zwei Stellen stehen, die reine Anzeige betreffen und den
|
|
Mailbetrieb nicht stören:
|
|
|
|
- `#public/Contacts/` — der Eintrag in der globalen Adressliste
|
|
- `.caldav.db` / `.carddav.db` — die DAV-Datenbanken
|
|
|
|
Wer die sofort korrekt haben will, korrigiert den Kontakt in der
|
|
Administrationskonsole.
|
|
|
|
Kommt der alte Name in `users.cfg` außerhalb der Benutzerlisten vor (etwa in
|
|
einem Alias), meldet das Script das im Plan und ändert es **nicht** automatisch —
|
|
lieber ein Hinweis als eine kaputte Konfiguration.
|
|
|
|
Die alte Adresse nimmt nach der Umbenennung keine Mail mehr an. Wer das braucht,
|
|
legt anschließend in der Administrationskonsole einen Alias an.
|
|
|
|
## Hinweise
|
|
|
|
- **Vorher ein Backup des Stores anlegen.** Das Script verschiebt Verzeichnisse.
|
|
- Erst an einem Testbenutzer ausprobieren.
|
|
- Der Benutzer sollte während des Laufs nicht angemeldet sein.
|
|
- Nach der Umbenennung müssen sich alle Mail-Clients mit dem neuen Login neu
|
|
anmelden.
|
|
- Gruppenmitgliedschaften bleiben erhalten: Kerio referenziert Gruppen über
|
|
GUIDs, nicht über Namen.
|
|
|
|
---
|
|
|
|
# Testlizenz besorgen
|
|
|
|
Der Erstkonfigurationsassistent verlangt im Schritt „Registrierte Testaktivierung"
|
|
eine Testlizenznummer samt CAPTCHA. Der Link „Lizenznummer für Testversion
|
|
erhalten" im Assistenten zeigt noch auf die alte `kerio.com`-Adresse und läuft
|
|
ins Leere: GFI hat die Domain auf **`gfi.ai`** umgestellt.
|
|
|
|
Die funktionierende Adresse — dort die E-Mail-Adresse eintragen, die Nummer kommt
|
|
per Mail:
|
|
|
|
**<https://gfi.ai/products-and-solutions/email-and-messaging-solutions/kerioconnect/free-trial>**
|
|
|
|
Die alten Adressen `www.gfi.com/.../kerio-connect/download` und
|
|
`gfi.ai/.../kerio-connect/download` leiten inzwischen alle dorthin um.
|
|
|
|
Die Nummer lässt sich entweder im Assistenten eintragen oder später aus der
|
|
laufenden Instanz heraus: **Dashboard → „Become a registered trial user"**.
|
|
Beides braucht ausgehendes HTTPS auf Port 443.
|
|
|
|
## Für jeden Testlauf eine frische E-Mail-Adresse
|
|
|
|
**GFI gibt pro E-Mail-Adresse dauerhaft dieselbe Trial-Nummer zurück.** Wer sich
|
|
mit einer Adresse schon einmal registriert hat, bekommt bei jeder weiteren
|
|
Anfrage seinen alten Schlüssel — und wenn dessen 30 Tage abgelaufen sind, ist er
|
|
es auch beim Neuanfordern. Der Server quittiert das mit:
|
|
|
|
```
|
|
registration.cpp: License error: Unable to set license (License is expired).
|
|
```
|
|
|
|
Das sieht nach einem Server- oder Netzwerkproblem aus, ist aber keines: Der
|
|
Schlüssel ist schlicht der alte. Für einen neuen Testzeitraum braucht es eine
|
|
Adresse, mit der noch nie registriert wurde.
|
|
|
|
Wegwerfadressen (trashmail.com und ähnliche) funktionieren dafür, werden von der
|
|
Anmeldeseite aber teilweise blockiert — dann hilft nur ein anderer Anbieter.
|
|
|
|
## Ohne Lizenz geht kein Mailbetrieb
|
|
|
|
Der Schalter `ConfigWizardDone` in `mailserver.cfg` überspringt zwar den
|
|
Assistenten und gibt Administrationskonsole und Admin-API frei — er aktiviert
|
|
aber **keinen Testzeitraum**. Ohne Lizenzschlüssel weisen IMAP, POP3 und Webmail
|
|
jede Verbindung ab (`Server license expired` beim Client, `Product name does not
|
|
match` im Log), und `error.log` meldet beim Start `No license key found`. Eine
|
|
API zum Aktivieren gibt es nicht.
|
|
|
|
Wer den Assistenten neu durchlaufen will, setzt `ConfigWizardDone` zurück auf `0`
|
|
oder löscht `mailserver.cfg` ganz — Kerio legt beim nächsten Start eine frische
|
|
an. Achtung: die Domänendefinition steht in dieser Datei, die Benutzer in
|
|
`users.cfg` sind danach verwaist.
|
|
|
|
**`mailserver.cfg` und `users.cfg` dürfen nur bei gestopptem Dienst bearbeitet
|
|
werden.** Kerio schreibt seine Konfiguration beim Beenden aus dem Speicher
|
|
zurück und überschreibt sonst jede Änderung am laufenden Dienst.
|
|
|
|
## Wenn der Schlüssel abgelehnt wird
|
|
|
|
`store/logs/error.log` unterscheidet die Fälle — die Meldung sagt, ob der
|
|
Schlüssel *ungültig* oder *abgelaufen* ist. Bei `License is expired` zuerst die
|
|
E-Mail-Adresse prüfen (siehe oben), das ist die häufigste Ursache.
|
|
|
|
Erst danach lohnt die Netzwerkseite:
|
|
|
|
```bash
|
|
# Registrierungsserver erreichbar?
|
|
getent hosts secure.kerio.com # muss auflösen
|
|
getent hosts registration.kerio.com # löst NICHT mehr auf (normal)
|
|
|
|
# Uhr korrekt? Eine falsche Systemzeit lässt gültige Lizenzen ablaufen.
|
|
timedatectl
|
|
```
|
|
|
|
Der alte Host `registration.kerio.com` existiert nicht mehr; `secure.kerio.com`
|
|
ist der aktive Registrierungsserver.
|
|
|
|
---
|
|
|
|
## Referenzen
|
|
|
|
- [Administration API — Users](https://manuals.gfi.com/en/kerio/api/connect/admin/reference/interfacekerio_1_1jsonapi_1_1admin_1_1_users.html)
|
|
- [Sample communication (Session.login, X-Token)](https://manuals.gfi.com/en/kerio/api/connect/admin/reference/sample_communication.html)
|
|
- [Registering Kerio Connect (unregistered mode)](https://manuals.gfi.com/en/kerio/connect/content/registration-and-licenses/registering-kerio-connect-1134.html)
|
|
- [Kerio Connect Testversion (30 Tage)](https://gfi.ai/products-and-solutions/email-and-messaging-solutions/kerioconnect/free-trial)
|
|
- [Modifying the mailserver.cfg](https://support.kerioconnect.gfi.com/en-us/article/114788-modifying-the-mailserver-cfg)
|