samba-tool user create rejected the cluster-generated trust_shared_password
with "0000052D: Constraint violation - check_password_restrictions: the
password does not meet the complexity criteria". The trust password is
high-entropy random bytes from init_kdc.sh and may not satisfy AD's
"3 of 4 character categories" rule.
Wrap the create + setpassword steps in a block that:
1. reads the current `samba-tool domain passwordsettings show` state
2. flips complexity off if it was on
3. does the user write
4. always: restores complexity to its prior on/off state
The restore is in an `always:` clause so a failure inside the write
block does not leave the domain policy weakened.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
samba-tool user create rejected the sAMAccountName "krbtgt/KNOE.LOCAL"
with "samldb: sAMAccountName contains invalid '/' character". AD/Samba
disallow "/" in sAMAccountName even though Kerberos principal names
require it (krbtgt/REMOTE@LOCAL).
Switch storage name to "krbtgt_KNOE.LOCAL" and add an ldbmodify pass
that sets the canonical Kerberos identity on the same object:
userPrincipalName = krbtgt/KNOE.LOCAL@PROLE.ORG
servicePrincipalName = krbtgt/KNOE.LOCAL
msDS-SupportedEncryptionTypes = 28 (RC4+AES128+AES256)
Samba KDC resolves principals by UPN/SPN, so a TGS-REQ for
krbtgt/KNOE.LOCAL@PROLE.ORG will hit this account.
Note: key-salt parity with the MIT side is NOT guaranteed yet. Samba's
default salt for AES keys is REALM+UPN; MIT's default for cross-realm
krbtgt is REALM+"krbtgt"+REMOTE. If kvno fails with "decrypt integrity
check failed" we'll add a keytab-export/import step in a follow-up
rather than try to coerce Samba's salt at creation time.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In --check mode the user-create step is skipped (it's mutating), so
the subsequent `samba-tool user show krbtgt/KNOE.LOCAL` probe fails
with rc=1 on a first dry-run because the user doesn't yet exist. Add
the same guarded failed_when used on the trust validate/show tasks
earlier: only fail when NOT (check_mode AND trust didn't pre-exist).
Real runs still fail hard on rc!=0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
samba-tool domain trust create --type=external only works against
another writeable AD-style DC; against an MIT KDC it fails with
"Failed to find a writeable DC for domain 'KNOE.LOCAL'". Our peer at
svc/auth in knoe-system is a plain Kerberos KDC, so we cannot use that
path.
Replace the trust create/validate/show steps with the supported
Samba-AD <-> MIT-KDC approach: create the inter-realm TGT principal as
an ordinary user account in Samba whose sAMAccountName is
"krbtgt/KNOE.LOCAL", with its password synced to the cluster Secret
knoe-system/knoe-kdc-secrets/trust_shared_password (which the MIT side
already keys against). Steps:
1. samba-tool user list (idempotency probe)
2. samba-tool user create krbtgt/KNOE.LOCAL ... (when missing)
3. samba-tool user setpassword krbtgt/KNOE.LOCAL (when present, to
re-sync after a cluster Secret rotation)
4. samba-tool user setexpiry --noexpiry
5. ldbmodify msDS-SupportedEncryptionTypes=28 (RC4+AES128+AES256
to match what init_kdc.sh sets on the MIT side)
6. samba-tool user show (smoke probe)
7. debug task prints the manual kvno smoke-test command
Cluster-secret lookups and krb5.conf [realms]/[domain_realm] edits are
unchanged - those parts were correct.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ansible --check mode auto-skips command/shell tasks unless they
explicitly opt in via check_mode:false. The two cluster-state lookups
(svc/auth ClusterIP and knoe-kdc-secrets/trust_shared_password) were
silently skipped during dry-run, leaving trust_kdc_ip empty and tripping
the assertion immediately.
Add check_mode:false to the five read-only tasks so a --check run can
still resolve cluster state and report what would change:
- Resolve trust_kdc_ip from cluster
- Resolve trust_shared_password from knoe-kdc-secrets
- samba-tool domain trust list (idempotency probe)
- samba-tool domain trust validate
- samba-tool domain trust show (smoke print)
The mutating create step (samba-tool domain trust create) keeps the
default behavior - skipped in check mode. validate/show gain a guarded
failed_when so a check-mode dry-run on a host where the trust does not
yet exist does not fail (the create was skipped, so a non-zero rc is
expected). Real runs still fail hard on rc!=0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The cross-realm trust playbook was written for the pre-rebrand realm name
PROLE.LOCAL, which no longer exists in the in-cluster KDC — the canonical
realm is now KNOE.LOCAL. The Samba AD trust was therefore never actually
established, leaving chrisfu@KNOE.LOCAL→chrisfu@PROLE.ORG service ticket
flows blocked (and blocking pg_oauth / db.prole.org Kerberos work).
Changes:
- Realm: PROLE.LOCAL → KNOE.LOCAL across all task names, vars, and the
krb5.conf [realms] / [domain_realm] blocks added on myrddin.
- samba_admin_password now resolves from the Ansible vault var
vault_samba_dns_admin_pass (group_vars/ad_dc/vault.yml) by default,
with SAMBA_ADMIN_PASSWORD env and -e overrides preserved for CI.
- trust_shared_password auto-resolves from the in-cluster Secret
knoe-system/knoe-kdc-secrets (key trust_shared_password) when not
passed explicitly — same Secret init_kdc.sh writes.
- Added [domain_realm] mapping for *.knoe.local → KNOE.LOCAL so Samba
can resolve in-cluster service principals.
- Added a final `samba-tool domain trust show` smoke step so a successful
run prints the visible trust state for log review.
Run:
ANSIBLE_VAULT_PASSWORD_FILE=$PWD/.vault_pass ansible-playbook infrastructure/playbooks/kerberos_trust_setup.yml
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>