Documentation
¶
Overview ¶
Package ldappw implements the RFC 2307 LDAP userPassword storage schemes used by OpenLDAP slapd, 389 Directory Server, Dovecot, and Atlassian Crowd: the {SHA}/{SSHA} family plus {MD5}/{SMD5} and the OpenLDAP pw-sha2 / Dovecot SHA-2 extensions ({SHA256}/{SSHA256}/{SHA384}/{SSHA384}/{SHA512}/{SSHA512}). It is an offline credential primitive: compute the storage string for a candidate password, or verify a candidate against a captured userPassword value (e.g. from a slapcat dump or a directory-server backup). It complements the credential toolkit — hash_identify recognises {SSHA}/{SHA}/{MD5} (hashcat modes 111 / 101 / 1001) and hash_crack attacks them, but neither could produce or check one. Pure offline compute from operator-supplied strings; no network or device.
Scheme construction ¶
Every scheme is the same shape with no key-stretching: the stored value is
{SCHEME}base64( H(password ‖ salt) ‖ salt )
where H is the named digest and the salt is empty for the unsalted variants ({SHA}, {MD5}, {SHA256}, …) and a trailing run of random bytes for the salted variants ({SSHA}, {SMD5}, {SSHA256}, …). Because the digest length is fixed per algorithm, verification splits the decoded blob at that boundary: the first digestLen bytes are the stored digest, the remainder is the salt, and the candidate is accepted iff H(password ‖ salt) equals the stored digest (constant-time). The salt length is therefore recovered from the blob, not assumed — slapd defaults to 4 bytes, Dovecot to longer, and both verify here.
Wrap-vs-native judgement ¶
Native. These schemes are a digest (crypto/{md5,sha1,sha256,sha512}) plus encoding/base64 — there is nothing to wrap; the only third-party option would be a cgo crypt(3) binding or an LDAP client library, neither warranted for a pure hash-and-encode. Consistent with internal/unixcrypt, internal/nthash, and internal/wpa, the crypto is owned in-tree.
Verifiable / no confidently-wrong output ¶
Strongest verification class — the construction is unambiguous (a single digest + base64, no rounds, no scrambling), so a wrong output cannot hide. {SHA} compute is gated byte-for-byte against the OpenLDAP `slappasswd -h {SHA}` oracle; {SSHA}/{SMD5} round-trip against slappasswd-produced values (variable-length salt recovered from the blob); the SHA-2 variants are gated against the definitional digest+base64 vectors (the exact pw-sha2 / Dovecot construction). Out of scope: {CRYPT} (RFC 2307 delegates it to crypt(3) — already covered by md5crypt / sha_crypt / bcrypt) and {CLEARTEXT}.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Compute ¶
Compute returns the {SCHEME}base64(...) userPassword string for the given password. For a salted scheme an explicit salt is used verbatim; if salt is empty a 4-byte random salt is generated (matching slappasswd's default). For an unsalted scheme a non-empty salt is rejected.