fix: LDAP leere BindPassword schlägt Login fehl + install.sh Passwort-Extraktion

- auth.Manager.Login: LDAP-Fallback überspringen wenn URL oder BindPassword leer
  (verhindert go-ldap ErrorEmptyPassword Code 206 bei fehlerhaftem LDAP-Config-Eintrag)
- install.sh: grep-Muster von variablenbreitem Lookbehind auf \K umgestellt
  (PCRE unterstützt keine variablen Lookbehinds — Passwörter wurden nie korrekt extrahiert)
- install.sh: Wartezeit auf Backend-Start erhöht (bis zu 15s statt 2s)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sysops
2026-03-20 01:47:48 +01:00
parent fd46f0de9a
commit b3074b303e
2 changed files with 11 additions and 6 deletions
+9 -4
View File
@@ -325,10 +325,15 @@ if [ -f "$INSTALL_DIR/update.sh" ]; then
info "Führe erstes Deployment durch (Build + Start)..." info "Führe erstes Deployment durch (Build + Start)..."
bash "$INSTALL_DIR/update.sh" bash "$INSTALL_DIR/update.sh"
# Echte Passwörter aus Journal lesen (Backend gibt sie beim ersten Start aus) # Echte Passwörter aus Journal lesen (Backend gibt sie beim ersten Start aus)
sleep 2 # Auf Backend warten (bis zu 15 Sekunden)
PW_SUPERADMIN=$(journalctl -u archivmail --no-pager -n 50 | grep -oP '(?<=superadmin\s+: )\S+' | tail -1) for _i in $(seq 1 15); do
PW_ADMIN=$(journalctl -u archivmail --no-pager -n 50 | grep -oP '(?<=admin\s+: )\S+' | tail -1) _pw=$(journalctl -u archivmail --no-pager -n 100 | grep 'admin' | grep -oP ':\s+\K[0-9a-f]{16,}' | tail -1)
PW_AUDITOR=$(journalctl -u archivmail --no-pager -n 50 | grep -oP '(?<=auditor\s+: )\S+' | tail -1) [[ -n "$_pw" ]] && break
sleep 1
done
PW_SUPERADMIN=$(journalctl -u archivmail --no-pager -n 100 | grep 'superadmin' | grep -oP ':\s+\K\S+' | tail -1)
PW_ADMIN=$(journalctl -u archivmail --no-pager -n 100 | grep ' admin ' | grep -v superadmin | grep -oP ':\s+\K\S+' | tail -1)
PW_AUDITOR=$(journalctl -u archivmail --no-pager -n 100 | grep 'auditor' | grep -oP ':\s+\K\S+' | tail -1)
[[ -n "$PW_ADMIN" ]] || PW_ADMIN="(nicht gefunden — siehe: journalctl -u archivmail | grep admin)" [[ -n "$PW_ADMIN" ]] || PW_ADMIN="(nicht gefunden — siehe: journalctl -u archivmail | grep admin)"
[[ -n "$PW_AUDITOR" ]] || PW_AUDITOR="(nicht gefunden — siehe: journalctl -u archivmail | grep auditor)" [[ -n "$PW_AUDITOR" ]] || PW_AUDITOR="(nicht gefunden — siehe: journalctl -u archivmail | grep auditor)"
[[ -n "$PW_SUPERADMIN" ]] || PW_SUPERADMIN="(nicht gefunden — siehe: journalctl -u archivmail | grep superadmin)" [[ -n "$PW_SUPERADMIN" ]] || PW_SUPERADMIN="(nicht gefunden — siehe: journalctl -u archivmail | grep superadmin)"
+2 -2
View File
@@ -91,7 +91,7 @@ func (m *Manager) Login(username, password string) (token string, user *userstor
tenantID, lookupErr := m.tenantLookup.GetTenantIDByDomain(ctx, domain) tenantID, lookupErr := m.tenantLookup.GetTenantIDByDomain(ctx, domain)
if lookupErr == nil && tenantID != nil { if lookupErr == nil && tenantID != nil {
tcfg, tErr := m.tenantLdapStore.GetWithPassword(ctx, *tenantID) tcfg, tErr := m.tenantLdapStore.GetWithPassword(ctx, *tenantID)
if tErr == nil && tcfg != nil && tcfg.Enabled { if tErr == nil && tcfg != nil && tcfg.Enabled && tcfg.URL != "" && tcfg.BindPassword != "" {
attrs, authErr := ldapauth.Authenticate(ldapauth.Config{ attrs, authErr := ldapauth.Authenticate(ldapauth.Config{
URL: tcfg.URL, URL: tcfg.URL,
BindDN: tcfg.BindDN, BindDN: tcfg.BindDN,
@@ -137,7 +137,7 @@ func (m *Manager) Login(username, password string) (token string, user *userstor
// 3. Global LDAP fallback — only reached if no matching tenant LDAP config found. // 3. Global LDAP fallback — only reached if no matching tenant LDAP config found.
if m.ldapStore != nil { if m.ldapStore != nil {
cfg, ldapErr := m.ldapStore.GetWithPassword(context.Background()) cfg, ldapErr := m.ldapStore.GetWithPassword(context.Background())
if ldapErr == nil && cfg != nil && cfg.Enabled { if ldapErr == nil && cfg != nil && cfg.Enabled && cfg.URL != "" && cfg.BindPassword != "" {
attrs, authErr := ldapauth.Authenticate(ldapauth.Config{ attrs, authErr := ldapauth.Authenticate(ldapauth.Config{
URL: cfg.URL, URL: cfg.URL,
BindDN: cfg.BindDN, BindDN: cfg.BindDN,