Script fix
This commit is contained in:
@@ -36,6 +36,14 @@ Existing `{MD5}` password hashes continue to work after the module is loaded —
|
|||||||
|
|
||||||
User activation and deactivation uses the OpenLDAP `ppolicy` overlay. When a user is marked inactive, `pwdAccountLockedTime` is set on their entry, which causes all LDAP binds to fail — including logins to Emby, Gitea, and any other LDAP-backed service.
|
User activation and deactivation uses the OpenLDAP `ppolicy` overlay. When a user is marked inactive, `pwdAccountLockedTime` is set on their entry, which causes all LDAP binds to fail — including logins to Emby, Gitea, and any other LDAP-backed service.
|
||||||
|
|
||||||
|
> **The easy way:** run [`ops/ldap-setup.sh`](ops/ldap-setup.sh) on the LDAP server. It is idempotent, auto-detects the correct user database, applies everything below (pw-sha2, ppolicy module/overlay/schema, custom schema, policy entry, SSO groups) and verifies ppolicy is active at the end:
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> sudo ./ops/ldap-setup.sh -p <admin-password>
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> If the app returns `503 OpenLDAP ppolicy overlay is not configured` on `PUT /api/user/<uid>/active`, run this script — it means the overlay is not attached to the database holding your users. The manual steps below are equivalent and kept for reference.
|
||||||
|
|
||||||
**1. Load the ppolicy module:**
|
**1. Load the ppolicy module:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -49,6 +57,13 @@ EOF
|
|||||||
|
|
||||||
**2. Add the overlay to your user database:**
|
**2. Add the overlay to your user database:**
|
||||||
|
|
||||||
|
> ⚠️ The database index below (`{1}mdb`) is **not** the same on every install. Confirm yours first — the overlay must go on the database whose `olcSuffix` is your base DN, or account locking silently won't apply to your users:
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> ldapsearch -Q -Y EXTERNAL -H ldapi:/// -b cn=config \
|
||||||
|
> '(&(objectClass=olcDatabaseConfig)(olcSuffix=dc=theta42,dc=com))' dn
|
||||||
|
> ```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ldapadd -Y EXTERNAL -H ldapi:/// << 'EOF'
|
ldapadd -Y EXTERNAL -H ldapi:/// << 'EOF'
|
||||||
dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
|
dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
|
||||||
|
|||||||
+52
-5
@@ -76,6 +76,25 @@ dir_add() {
|
|||||||
ok() { echo " [ok] $*"; }
|
ok() { echo " [ok] $*"; }
|
||||||
skip() { echo " [--] $* (already applied)"; }
|
skip() { echo " [--] $* (already applied)"; }
|
||||||
info() { echo; echo "==> $*"; }
|
info() { echo; echo "==> $*"; }
|
||||||
|
warn() { echo " [!!] $*" >&2; }
|
||||||
|
|
||||||
|
# ── Detect the database that serves BASE_DN ──────────────────────────────────
|
||||||
|
# The ppolicy overlay MUST be attached to the database that actually holds the
|
||||||
|
# user entries, otherwise pwdAccountLockedTime is never registered for them and
|
||||||
|
# the app's active/inactive toggle fails with "undefined attribute type".
|
||||||
|
# Do NOT hardcode olcDatabase={1}mdb — the index/backend varies per install.
|
||||||
|
info "locating user database for ${BASE_DN}"
|
||||||
|
|
||||||
|
DB_DN=$(config_search -b "cn=config" \
|
||||||
|
"(&(objectClass=olcDatabaseConfig)(olcSuffix=${BASE_DN}))" dn \
|
||||||
|
| awk '/^dn:/{sub(/^dn: /,""); print; exit}')
|
||||||
|
|
||||||
|
if [[ -z "$DB_DN" ]]; then
|
||||||
|
warn "Could not find a database with olcSuffix=${BASE_DN} under cn=config."
|
||||||
|
warn "Check the base DN (-b) and that slapd is running with a cn=config backend."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
ok "user database: ${DB_DN}"
|
||||||
|
|
||||||
# ── 1. pw-sha2 module (SSHA512 password hashing) ─────────────────────────────
|
# ── 1. pw-sha2 module (SSHA512 password hashing) ─────────────────────────────
|
||||||
info "pw-sha2 module"
|
info "pw-sha2 module"
|
||||||
@@ -106,17 +125,17 @@ fi
|
|||||||
# ── 3. ppolicy overlay ────────────────────────────────────────────────────────
|
# ── 3. ppolicy overlay ────────────────────────────────────────────────────────
|
||||||
info "ppolicy overlay"
|
info "ppolicy overlay"
|
||||||
|
|
||||||
if config_search -b "cn=config" "(olcOverlay=ppolicy)" | grep -q "ppolicy"; then
|
if config_search -b "$DB_DN" "(olcOverlay=*ppolicy*)" dn | grep -q "ppolicy"; then
|
||||||
skip "ppolicy overlay already configured"
|
skip "ppolicy overlay already configured on ${DB_DN}"
|
||||||
else
|
else
|
||||||
config_add "dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
|
config_add "dn: olcOverlay=ppolicy,${DB_DN}
|
||||||
objectClass: olcOverlayConfig
|
objectClass: olcOverlayConfig
|
||||||
objectClass: olcPPolicyConfig
|
objectClass: olcPPolicyConfig
|
||||||
olcOverlay: ppolicy
|
olcOverlay: ppolicy
|
||||||
olcPPolicyDefault: cn=ppolicy,${POLICY_BASE}
|
olcPPolicyDefault: cn=ppolicy,${POLICY_BASE}
|
||||||
olcPPolicyUseLockout: TRUE
|
olcPPolicyUseLockout: TRUE
|
||||||
olcPPolicyHashCleartext: FALSE"
|
olcPPolicyHashCleartext: FALSE"
|
||||||
ok "ppolicy overlay added"
|
ok "ppolicy overlay added to ${DB_DN}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── 4. ppolicy schema ─────────────────────────────────────────────────────────
|
# ── 4. ppolicy schema ─────────────────────────────────────────────────────────
|
||||||
@@ -225,6 +244,34 @@ member: ${BIND_DN}"
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# ── 9. Verify ppolicy is actually active on the user database ─────────────────
|
||||||
|
# This is the exact condition the app relies on: if the ppolicy overlay is not
|
||||||
|
# attached to the database holding the users, modifying pwdAccountLockedTime
|
||||||
|
# fails and User.setActive() returns a 503.
|
||||||
|
info "verifying ppolicy is active on ${DB_DN}"
|
||||||
|
|
||||||
|
VERIFY_FAILED=0
|
||||||
|
|
||||||
|
if config_search -b "$DB_DN" "(olcOverlay=*ppolicy*)" dn | grep -q "ppolicy"; then
|
||||||
|
ok "ppolicy overlay is attached to the user database"
|
||||||
|
else
|
||||||
|
warn "ppolicy overlay is NOT attached to ${DB_DN} — active/inactive toggle will fail"
|
||||||
|
VERIFY_FAILED=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if dir_search -b "cn=ppolicy,${POLICY_BASE}" -s base "(objectClass=*)" dn 2>/dev/null | grep -q "dn:"; then
|
||||||
|
ok "default password policy entry exists"
|
||||||
|
else
|
||||||
|
warn "default ppolicy entry missing at cn=ppolicy,${POLICY_BASE}"
|
||||||
|
VERIFY_FAILED=1
|
||||||
|
fi
|
||||||
|
|
||||||
# ── Done ──────────────────────────────────────────────────────────────────────
|
# ── Done ──────────────────────────────────────────────────────────────────────
|
||||||
echo
|
echo
|
||||||
echo "Setup complete."
|
if [[ "$VERIFY_FAILED" -eq 0 ]]; then
|
||||||
|
echo "Setup complete. ppolicy is active — user active/inactive toggle will work."
|
||||||
|
else
|
||||||
|
echo "Setup finished WITH WARNINGS — see [!!] lines above. The app's" >&2
|
||||||
|
echo "active/inactive feature will not work until they are resolved." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user