clayrisser / docker-openldap

openldap based on bitnami openldap with ppolicy, password hashing and support for ldif migrations
Apache License 2.0
9 stars 0 forks source link

Error: `ldap_bind: Invalid credentials (49)` #1

Open polarathene opened 1 year ago

polarathene commented 1 year ago

Problem

Migrating from an old unmaintained OpenLDAP image osixia/docker-openldap, users added via LDIF fail to authenticate with "Invalid credentials (49)".

Reproduction

ldapwhoami and ldapsearch commands within the same running container (docker exec -it ldap-test bash) are both sufficient at illustrating the problem.

# Default internal admin user is successful:
$ ldapwhoami -v -H 'ldap://ldap.example.test' -D 'cn=admin,dc=example,dc=test' -w adminpassword

ldap_initialize( ldap://ldap.example.test:389/??base )
dn:cn=admin,dc=example,dc=test
Result: Success (0)

# Custom user added is not:
$ ldapwhoami -v -H 'ldap://ldap.example.test' -D 'userid=john.doe,ou=people,dc=example,dc=test' -w secret

ldap_initialize( ldap://ldap.example.test:389/??base )
ldap_bind: Invalid credentials (49)

Admin user can query the LDIF record successfully:

$ ldapsearch -v -x -H 'ldap://ldap.example.test' -b 'ou=people,dc=example,dc=test' -D 'cn=admin,dc=example,dc=test' -w adminpassword  '(&(userid=john.doe)(mailEnabled=TRUE))'

ldap_initialize( ldap://ldap.example.test:389/??base )
filter: (&(userid=john.doe)(mailEnabled=TRUE))
requesting: All userApplication attributes
# extended LDIF
#
# LDAPv3
# base <ou=people,dc=example,dc=test> with scope subtree
# filter: (&(userid=john.doe)(mailEnabled=TRUE))
# requesting: ALL
#

# john.doe, people, example.test
dn: uid=john.doe,ou=people,dc=example,dc=test
objectClass: organizationalPerson
objectClass: person
objectClass: top
objectClass: PostfixBookMailAccount
objectClass: extensibleObject
cn: John Doe
givenName: John
sn: Doe
uid: john.doe
userPassword:: c2VjcmV0
mail: john.doe@example.test
mailEnabled: TRUE
mailUidNumber: 5000
mailGidNumber: 5000
mailAlias: postmaster@example.test
mailGroupMember: employees@example.test
mailHomeDirectory: /var/mail/example.test/john.doe/
mailStorageDirectory: maildir:/var/mail/example.test/john.doe/
mailQuota: 10240

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Where userPassword is base64 encoded in the response to c2VjcmV0 (aka secret).

Related log output from the `ldapsearch` command ``` 64dc88f8 conn=1008 fd=12 ACCEPT from IP=172.17.0.2:54138 (IP=0.0.0.0:389) 64dc88f8 conn=1008 op=0 BIND dn="cn=admin,dc=example,dc=test" method=128 64dc88f8 conn=1008 op=0 BIND dn="cn=admin,dc=example,dc=test" mech=SIMPLE ssf=0 64dc88f8 conn=1008 op=0 RESULT tag=97 err=0 text= 64dc88f8 conn=1008 op=1 SRCH base="ou=people,dc=example,dc=test" scope=2 deref=0 filter="(&(uid=john.doe)(mailEnabled=TRUE))" 64dc88f8 <= mdb_equality_candidates: (uid) not indexed 64dc88f8 <= mdb_equality_candidates: (mailEnabled) not indexed 64dc88f8 conn=1008 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text= 64dc88f8 conn=1008 op=2 UNBIND 64dc88f8 conn=1008 fd=12 closed ```

Whereas the equivalent for the custom user fails with:

$ ldapsearch -v -x -H 'ldap://ldap.example.test' -b 'ou=people,dc=example,dc=test' -D 'userid=john.doe,ou=people,dc=example,dc=test' -w secret  '(&(userid=john.doe)(mailEnabled=TRUE))'

ldap_initialize( ldap://ldap.example.test:389/??base )
ldap_bind: Invalid credentials (49)

# Related log output from container logs:
64dc8a08 conn=1010 fd=12 ACCEPT from IP=172.17.0.2:42226 (IP=0.0.0.0:389)
64dc8a08 conn=1010 op=0 BIND dn="uid=john.doe,ou=people,dc=example,dc=test" method=128
64dc8a08 conn=1010 op=0 RESULT tag=97 err=49 text=
64dc8a08 conn=1010 op=1 UNBIND
64dc8a08 conn=1010 fd=12 closed

docker run

docker run --rm --name ldap-test \
  --env LDAP_ROOT='dc=example,dc=test' \
  --env LDAP_HASH_PASSWORD='NONE' \
  --env LDAP_PORT_NUMBER=389 \
  --env BITNAMI_DEBUG=true \
  --volume '/tmp/ldif/:/migrations/:ro' \
  --hostname 'ldap.example.test' \
  registry.gitlab.com/bitspur/rock8s/docker-openldap
Log output during startup ``` rm: cannot remove '/opt/bitnami/openldap/ldifs': Permission denied 08:21:29.93 INFO ==> ** Starting LDAP setup ** 08:21:29.95 INFO ==> Validating settings in LDAP_* env vars 08:21:29.95 INFO ==> Initializing OpenLDAP... 08:21:29.95 DEBUG ==> Ensuring expected directories/files exist... 08:21:29.96 INFO ==> Creating LDAP online configuration 08:21:29.96 INFO ==> Creating slapd.ldif 08:21:29.98 INFO ==> Starting OpenLDAP server in background 64dc8709 @(#) $OpenLDAP: slapd 2.4.57+dfsg-3+deb11u1 (May 14 2022 18:32:57) $ Debian OpenLDAP Maintainers 64dc8709 slapd starting 08:21:30.99 INFO ==> Configure LDAP credentials for admin user SASL/EXTERNAL authentication started 64dc870a conn=1000 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870a conn=1000 op=0 BIND dn="" method=163 64dc870a conn=1000 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870a conn=1000 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870a conn=1000 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870a conn=1000 op=1 MOD dn="olcDatabase={2}mdb,cn=config" 64dc870a conn=1000 op=1 MOD attr=olcSuffix 64dc870a conn=1000 op=1 RESULT tag=103 err=0 text= 64dc870a conn=1000 op=2 MOD dn="olcDatabase={2}mdb,cn=config" 64dc870a conn=1000 op=2 MOD attr=olcRootDN 64dc870a conn=1000 op=2 RESULT tag=103 err=0 text= 64dc870a conn=1000 op=3 MOD dn="olcDatabase={2}mdb,cn=config" 64dc870a conn=1000 op=3 MOD attr=olcRootPW 64dc870a conn=1000 op=3 RESULT tag=103 err=0 text= 64dc870a conn=1000 op=4 MOD dn="olcDatabase={1}monitor,cn=config" 64dc870a conn=1000 op=4 MOD attr=olcAccess 64dc870a conn=1000 op=4 RESULT tag=103 err=0 text= 64dc870a conn=1000 op=5 UNBIND 64dc870a conn=1000 fd=12 closed modifying entry "olcDatabase={2}mdb,cn=config" modifying entry "olcDatabase={2}mdb,cn=config" modifying entry "olcDatabase={2}mdb,cn=config" modifying entry "olcDatabase={1}monitor,cn=config" 08:21:30.99 INFO ==> Adding LDAP extra schemas SASL/EXTERNAL authentication started 64dc870b conn=1001 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870b conn=1001 op=0 BIND dn="" method=163 64dc870b conn=1001 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870b conn=1001 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870b conn=1001 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870b conn=1001 op=1 ADD dn="cn=cosine,cn=schema,cn=config" 64dc870b conn=1001 op=1 RESULT tag=105 err=0 text= adding new entry "cn=cosine,cn=schema,cn=config" 64dc870b conn=1001 op=2 UNBIND 64dc870b conn=1001 fd=12 closed SASL/EXTERNAL authentication started 64dc870b conn=1002 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870b conn=1002 op=0 BIND dn="" method=163 64dc870b conn=1002 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870b conn=1002 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870b conn=1002 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870b conn=1002 op=1 ADD dn="cn=inetorgperson,cn=schema,cn=config" 64dc870b conn=1002 op=1 RESULT tag=105 err=0 text= adding new entry "cn=inetorgperson,cn=schema,cn=config" 64dc870b conn=1002 op=2 UNBIND 64dc870b conn=1002 fd=12 closed SASL/EXTERNAL authentication started 64dc870b conn=1003 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870b conn=1003 op=0 BIND dn="" method=163 64dc870b conn=1003 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870b conn=1003 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870b conn=1003 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870b conn=1003 op=1 ADD dn="cn=misc,cn=schema,cn=config" 64dc870b conn=1003 op=1 RESULT tag=105 err=0 text= adding new entry "cn=misc,cn=schema,cn=config" 64dc870b conn=1003 op=2 UNBIND 64dc870b conn=1003 fd=12 closed SASL/EXTERNAL authentication started 64dc870b conn=1004 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870b conn=1004 op=0 BIND dn="" method=163 64dc870b conn=1004 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870b conn=1004 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870b conn=1004 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870b conn=1004 op=1 ADD dn="cn=nis,cn=schema,cn=config" 64dc870b conn=1004 op=1 RESULT tag=105 err=0 text= 64dc870b conn=1004 op=2 UNBIND 64dc870b conn=1004 fd=12 closed adding new entry "cn=nis,cn=schema,cn=config" SASL/EXTERNAL authentication started 64dc870b conn=1005 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870b conn=1005 op=0 BIND dn="" method=163 64dc870b conn=1005 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870b conn=1005 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870b conn=1005 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870b conn=1005 op=1 ADD dn="cn=ppolicy,cn=schema,cn=config" 64dc870b conn=1005 op=1 RESULT tag=105 err=0 text= 64dc870b conn=1005 op=2 UNBIND 64dc870b conn=1005 fd=12 closed adding new entry "cn=ppolicy,cn=schema,cn=config" 08:21:31.02 INFO ==> Adding custom schemas : /opt/bitnami/openldap/schemas ... 64dc870b daemon: shutdown requested and initiated. 64dc870b slapd shutdown: waiting for 0 operations/tasks to finish 64dc870b slapd stopped. 08:21:32.21 INFO ==> Starting OpenLDAP server in background 64dc870c @(#) $OpenLDAP: slapd 2.4.57+dfsg-3+deb11u1 (May 14 2022 18:32:57) $ Debian OpenLDAP Maintainers 64dc870c slapd starting 08:21:33.22 INFO ==> Creating LDAP default tree 64dc870d conn=1000 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870d conn=1000 op=0 BIND dn="cn=admin,dc=example,dc=test" method=128 64dc870d conn=1000 op=0 BIND dn="cn=admin,dc=example,dc=test" mech=SIMPLE ssf=0 64dc870d conn=1000 op=0 RESULT tag=97 err=0 text= 64dc870d conn=1000 op=1 ADD dn="dc=example,dc=test" 64dc870d conn=1000 op=1 RESULT tag=105 err=0 text= 64dc870d conn=1000 op=2 ADD dn="ou=users,dc=example,dc=test" 64dc870d conn=1000 op=2 RESULT tag=105 err=0 text= 64dc870d conn=1000 op=3 ADD dn="cn=user01,ou=users,dc=example,dc=test" 64dc870d conn=1000 op=3 RESULT tag=105 err=0 text= 64dc870d conn=1000 op=4 ADD dn="cn=user02,ou=users,dc=example,dc=test" 64dc870d conn=1000 op=4 RESULT tag=105 err=0 text= 64dc870d conn=1000 op=5 ADD dn="cn=readers,ou=users,dc=example,dc=test" 64dc870d conn=1000 op=5 RESULT tag=105 err=0 text= 64dc870d conn=1000 op=6 UNBIND 64dc870d conn=1000 fd=12 closed adding new entry "dc=example,dc=test" adding new entry "ou=users,dc=example,dc=test" adding new entry "cn=user01,ou=users,dc=example,dc=test" adding new entry "cn=user02,ou=users,dc=example,dc=test" adding new entry "cn=readers,ou=users,dc=example,dc=test" 64dc870d daemon: shutdown requested and initiated. 64dc870d slapd shutdown: waiting for 0 operations/tasks to finish 64dc870d slapd stopped. 08:21:34.28 INFO ==> ** LDAP setup finished! ** 08:21:34.30 INFO ==> ** Starting slapd ** 64dc870e @(#) $OpenLDAP: slapd 2.4.57+dfsg-3+deb11u1 (May 14 2022 18:32:57) $ Debian OpenLDAP Maintainers 64dc870e slapd starting 64dc870e conn=1000 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870e conn=1000 op=0 BIND dn="" method=163 64dc870e conn=1000 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870e conn=1000 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870e conn=1000 op=0 RESULT tag=97 err=0 text= 64dc870e conn=1000 op=1 EXT oid=1.3.6.1.4.1.4203.1.11.3 64dc870e conn=1000 op=1 WHOAMI 64dc870e conn=1000 op=1 RESULT oid= err=0 text= dn:gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth 64dc870e conn=1000 op=2 UNBIND 64dc870e conn=1000 fd=12 closed ldapmodify -Y EXTERNAL -H ldapi:/// -f /opt/bitnami/openldap/migrations/00-access.ldif SASL/EXTERNAL authentication started 64dc870e conn=1001 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870e conn=1001 op=0 BIND dn="" method=163 64dc870e conn=1001 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870e conn=1001 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870e conn=1001 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870e conn=1001 op=1 MOD dn="olcDatabase={2}mdb,cn=config" 64dc870e conn=1001 op=1 MOD attr=olcAccess 64dc870e conn=1001 op=1 RESULT tag=103 err=0 text= modifying entry "olcDatabase={2}mdb,cn=config" 64dc870e conn=1001 op=2 UNBIND 64dc870e conn=1001 fd=12 closed ldapmodify -Y EXTERNAL -H ldapi:/// -f /opt/bitnami/openldap/migrations/01_mail-tree.ldif SASL/EXTERNAL authentication started 64dc870e conn=1002 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870e conn=1002 op=0 BIND dn="" method=163 64dc870e conn=1002 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870e conn=1002 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870e conn=1002 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870e conn=1002 op=1 ADD dn="ou=people,dc=example,dc=test" 64dc870e conn=1002 op=1 RESULT tag=105 err=0 text= 64dc870e conn=1002 op=2 UNBIND adding new entry "ou=people,dc=example,dc=test" 64dc870e conn=1002 fd=12 closed ldapmodify -Y EXTERNAL -H ldapi:/// -f /opt/bitnami/openldap/migrations/02_user-email.ldif SASL/EXTERNAL authentication started 64dc870e conn=1003 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870e conn=1003 op=0 BIND dn="" method=163 64dc870e conn=1003 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870e conn=1003 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870e conn=1003 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870e conn=1003 op=1 ADD dn="uid=john.doe,ou=people,dc=example,dc=test" 64dc870e conn=1003 op=1 RESULT tag=105 err=0 text= 64dc870e conn=1003 op=2 UNBIND 64dc870e conn=1003 fd=12 closed adding new entry "userid=john.doe,ou=people,dc=example,dc=test" ldapmodify -Y EXTERNAL -H ldapi:/// -f /opt/bitnami/openldap/migrations/auditlog.ldif SASL/EXTERNAL authentication started 64dc870e conn=1004 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870e conn=1004 op=0 BIND dn="" method=163 64dc870e conn=1004 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870e conn=1004 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870e conn=1004 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870e conn=1004 op=1 UNBIND 64dc870e conn=1004 fd=12 closed ldapmodify -Y EXTERNAL -H ldapi:/// -f /opt/bitnami/openldap/migrations/ppolicy.ldif SASL/EXTERNAL authentication started 64dc870e conn=1005 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870e conn=1005 op=0 BIND dn="" method=163 64dc870e conn=1005 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870e conn=1005 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870e conn=1005 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870e conn=1005 op=1 UNBIND 64dc870e conn=1005 fd=12 closed ldapmodify -Y EXTERNAL -H ldapi:/// -f /opt/bitnami/openldap/migrations/smbkrb5pwd.ldif SASL/EXTERNAL authentication started 64dc870e conn=1006 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870e conn=1006 op=0 BIND dn="" method=163 64dc870e conn=1006 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870e conn=1006 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870e conn=1006 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870e conn=1006 op=1 UNBIND 64dc870e conn=1006 fd=12 closed ldapmodify -Y EXTERNAL -H ldapi:/// -f /opt/bitnami/openldap/migrations/syncrepl.ldif SASL/EXTERNAL authentication started 64dc870e conn=1007 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870e conn=1007 op=0 BIND dn="" method=163 64dc870e conn=1007 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870e conn=1007 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870e conn=1007 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870e conn=1007 op=1 UNBIND 64dc870e conn=1007 fd=12 closed ```
Relevant snippet from above log (for the two custom LDIF files) ``` ldapmodify -Y EXTERNAL -H ldapi:/// -f /opt/bitnami/openldap/migrations/01_mail-tree.ldif SASL/EXTERNAL authentication started 64dc870e conn=1002 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870e conn=1002 op=0 BIND dn="" method=163 64dc870e conn=1002 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870e conn=1002 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870e conn=1002 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870e conn=1002 op=1 ADD dn="ou=people,dc=example,dc=test" 64dc870e conn=1002 op=1 RESULT tag=105 err=0 text= 64dc870e conn=1002 op=2 UNBIND adding new entry "ou=people,dc=example,dc=test" 64dc870e conn=1002 fd=12 closed ldapmodify -Y EXTERNAL -H ldapi:/// -f /opt/bitnami/openldap/migrations/02_user-email.ldif SASL/EXTERNAL authentication started 64dc870e conn=1003 fd=12 ACCEPT from PATH=/var/run/slapd/ldapi (PATH=/var/run/slapd/ldapi) 64dc870e conn=1003 op=0 BIND dn="" method=163 64dc870e conn=1003 op=0 BIND authcid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" authzid="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" 64dc870e conn=1003 op=0 BIND dn="gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth" mech=EXTERNAL sasl_ssf=0 ssf=71 64dc870e conn=1003 op=0 RESULT tag=97 err=0 text= SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth SASL SSF: 0 64dc870e conn=1003 op=1 ADD dn="uid=john.doe,ou=people,dc=example,dc=test" 64dc870e conn=1003 op=1 RESULT tag=105 err=0 text= 64dc870e conn=1003 op=2 UNBIND 64dc870e conn=1003 fd=12 closed adding new entry "userid=john.doe,ou=people,dc=example,dc=test" ```

Custom LDIF

Minimized to the two files below (2nd relies on the postfix-book.schema this image already provides). Creates a single mail user account to test against.

01_mail-tree.ldif:

dn: ou=people,dc=example,dc=test
changetype: add
objectClass: organizationalUnit
objectClass: top
ou: people

02_user-email.ldif:

# --------------------------------------------------------------------
# Create mail accounts
# --------------------------------------------------------------------
# John Doe
dn: userid=john.doe,ou=people,dc=example,dc=test
changetype: add
objectClass: organizationalPerson
objectClass: person
objectClass: top
objectClass: PostfixBookMailAccount
objectClass: extensibleObject
cn: John Doe
givenName: John
surname: Doe
userid: john.doe
userPassword: secret
mail: john.doe@example.test
# postfix-book.schema:
mailEnabled: TRUE
mailUidNumber: 5000
mailGidNumber: 5000
mailAlias: postmaster@example.test
mailGroupMember: employees@example.test
mailHomeDirectory: /var/mail/example.test/john.doe/
mailStorageDirectory: maildir:/var/mail/example.test/john.doe/
mailQuota: 10240

Background

Over the past two days (no LDAP experience), I've been trying to migrate the docker-mailserver LDAP test away from the osixia/docker-openldap image (we've used an old pinned version from many years ago, the latest just crashes).

That image was last maintained 2 years ago, and the bitnami openldap image seems to be one of the only actively maintained ones I came across that seemed suitable. However I ran into some compatibility issues there and my inexperience with LDAP... but this variant image with improvements is almost working, last roadblock is getting created users to successfully authenticate.

polarathene commented 1 year ago

FWIW, the goal is to integrate with the seperate docker-mailserver container using saslauthd to connect to the OpenLDAP container in our tests. I believe once this auth issue is resolved within the docker-openldap container it will work smoothly.

In the meantime, once the above ldapwhoami / ldapsearch commands work, the same running container can install, configure and test saslauthd with the following:

apt-get update && apt-get install sasl2-bin libsasl2-modules libsasl2-modules-ldap nano
nano /etc/saslauthd.conf

saslauthd.conf:

ldap_servers: ldap://ldap.example.test
ldap_auth_method: bind
ldap_bind_dn: cn=admin,dc=example,dc=test
ldap_bind_pw: adminpassword
ldap_search_base: ou=people,dc=example,dc=test
ldap_filter: (&(userid=%u)(mailEnabled=TRUE))
ldap_start_tls: no
ldap_tls_check_peer: no
ldap_referrals: yes
log_level: 10
# Run the saslauthd daemon with the config and LDAP plugin to auth against ldap:
saslauthd -d -a ldap -O /etc/saslauthd.conf

# In a separate terminal shell, verify everything is working:
testsaslauthd -u john.doe -p secret
polarathene commented 1 year ago

Resolved

I have identified a missing config was required for granting ACL to anonymous bind for auth (_references: slapd docs for olcAccess, OpenLDAP docs access 8.2.2 + 8.4_).

In the osixia/openldap image, this was configured via .ldif here (v1.1.6), while the current master of that image adds one more ACL rule that is similar to this projects (bitspur/rock8s/docker-openldap) image ACL (and the upstream bitnami image ACL)

This auth.ldif should carry that over by appending this rule? I've mounted it into /migrations. I'm not sure if the admin access is necessary, but could be templated as .tmpl instead of hard-coding the LDAP_ROOT.

dn: olcDatabase={2}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: to attrs=userPassword
  by self write
  by dn="cn=admin,dc=example,dc=test" write
  by anonymous auth
  by * none

NOTE: My user account .ldif files also did not need the changetype: add. I didn't create the original files or setup the original openldap docker image. Those now reside in /ldifs.

--env LDAP_HASH_PASSWORD='NONE' has no relevance to the userPassword value (at least for the .ldif account files I mount). The README description isn't quite clear to me where that applies. Perhaps it's the fallback if no scheme prefix exists in the stored value?


Verified

Verified with ldapwhoami:

$ ldapwhoami -v -x -H ldap://ldap.example.test -D 'uid=john.doe,ou=people,dc=example,dc=test' -w secret
ldap_initialize( ldap://ldap.example.test:389/??base )
dn:uid=john.doe,ou=people,dc=example,dc=test
Result: Success (0)

# Relevant container log output:
64ddb03c conn=1007 fd=12 ACCEPT from IP=172.17.0.2:42292 (IP=0.0.0.0:389)
64ddb03c conn=1007 op=0 BIND dn="uid=john.doe,ou=people,dc=example,dc=test" method=128
64ddb03c conn=1007 op=0 BIND dn="uid=john.doe,ou=people,dc=example,dc=test" mech=SIMPLE ssf=0
64ddb03c conn=1007 op=0 RESULT tag=97 err=0 text=
64ddb03c conn=1007 op=1 EXT oid=1.3.6.1.4.1.4203.1.11.3
64ddb03c conn=1007 op=1 WHOAMI
64ddb03c conn=1007 op=1 RESULT oid= err=0 text=
64ddb03c conn=1007 op=2 UNBIND
64ddb03c conn=1007 fd=12 closed

Verified with saslauthd setup described in previous comment:

$ testsaslauthd -u john.doe -p secret
0: OK "Success."

# Relevant container log output:
64ddb13a conn=1008 fd=12 ACCEPT from IP=172.17.0.2:41852 (IP=0.0.0.0:389)
64ddb13a conn=1008 op=0 BIND dn="cn=admin,dc=example,dc=test" method=128
64ddb13a conn=1008 op=0 BIND dn="cn=admin,dc=example,dc=test" mech=SIMPLE ssf=0
64ddb13a conn=1008 op=0 RESULT tag=97 err=0 text=
64ddb13a conn=1008 op=1 SRCH base="ou=people,dc=example,dc=test" scope=2 deref=0 filter="(&(uid=john.doe)(mailEnabled=TRUE))"
64ddb13a conn=1008 op=1 SRCH attr=dn
64ddb13a <= mdb_equality_candidates: (uid) not indexed
64ddb13a <= mdb_equality_candidates: (mailEnabled) not indexed
64ddb13a conn=1008 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
64ddb13a conn=1008 op=2 BIND anonymous mech=implicit ssf=0
64ddb13a conn=1008 op=2 BIND dn="uid=john.doe,ou=people,dc=example,dc=test" method=128
64ddb13a conn=1008 op=2 BIND dn="uid=john.doe,ou=people,dc=example,dc=test" mech=SIMPLE ssf=0
64ddb13a conn=1008 op=2 RESULT tag=97 err=0 text=

Here the testsaslauthd command sends the credentials to the saslauthd daemon, which connects to LDAP service with admin credentials (simple mechanism) and queries a user (dn attribute) with the search base and filter from saslauthd.conf settings. Afterwards it performs an anonymous bind (implicit mechanism?) presumably to retrieve the hashed userPassword value (granted by anonymous auth acl), performing auth for the actual user via bind dn (simple mechanism again, like ldapwhoami -x) which is successful.


If the anonymous auth acl is dropped, the ldapwhoami / ldapsearch commands likewise fail with "Invalid credentials (49)". Despite the container logs not mentioning any anonymous bind (Bind DN logged with mech=SIMPLE):

# Failure example when `anonymous auth` acl is not configured:
$ ldapwhoami -v -x -H ldap://ldap.example.test -D 'uid=john.doe,ou=people,dc=example,dc=test' -w secret
ldap_initialize( ldap://ldap.example.test:389/??base )
ldap_bind: Invalid credentials (49)

# Relevant container log output:
64ddb636 conn=1007 fd=12 ACCEPT from IP=172.17.0.2:59398 (IP=0.0.0.0:389)
64ddb636 conn=1007 op=0 BIND dn="uid=john.doe,ou=people,dc=example,dc=test" method=128
64ddb636 conn=1007 op=0 RESULT tag=97 err=49 text=
64ddb636 conn=1007 op=1 UNBIND
64ddb636 conn=1007 fd=12 closed

So the error message of "invalid credentials" was a bit misleading. It seems it was more of a problem retrieving userPassword due to lack of permissions?

polarathene commented 1 year ago

Since I managed to get bitnami/openldap working and no response to this report, I'm going to stick with that for the time being: https://github.com/docker-mailserver/docker-mailserver/pull/3494

I'll leave this issue open, as the bitnami/openldap image doesn't need the ACL migration, so that might be an unintended bug on your end, or should document the difference a bit more clearly as to why it was adjusted?


Off-topic: I recently noticed while looking through LDAP issues that you've previously engaged with docker-mailserver in the past, That was a nice surprise to recognize I had seen your name earlier when I landed here looking for an LDAP image replacement! 😁

clayrisser commented 11 months ago

@polarathene I actually made this image specifically for my use of docker-mailserver. I used to use osixia/docker-openldap as well.

I have a helm chart for this as well.

https://github.com/clayrisser/charts/tree/main/beta/openldap