Hi,

there is an environment in which I have to use MS Active Directory for authentication and mail server user database, and I've run into a problem.



I. The problem

I want to retrieve the objectGUID attribute for the homedir path of the users. This attribute does never change, even when the username does or the account gets moved to another AD domain.

However, the objectGUID is returned as binary gibberish when using the following setting:

user_attrs = \
  =home=/var/vmail/example.com/%LT{ldap:objectGUID}, \

It results in

# doveadm user uTesting
field   value
user    utesting
home    /var/vmail/example.com/d ��n�aa_ o��
mail    maildir:~/mail

Can someone reproduce this or offer a workaround?

The only idea I had was hashing the value using =%M{ldap:objectGUID}. However, this approach would become problematic if the behavior changes and a proper string representation is returned, as expected, instead of the binary data. Therefore, I'm hesitant to use this method for now.

A better approach would be encoding it as Base64, but I was unsuccessful to identify a fitting modifier at <https://doc.dovecot.org/configuration_manual/config_file/config_variables/#modifiers>. Any ideas?



II. Additional info

Using other attributes for LDAP/Active Directory works as expected. E.g.

=home=/var/vmail/example.com/%LT{ldap:sAMAccountName}

results in

# doveadm user uTesting
field   value
user    utesting
home    /var/vmail/example.com/utesting
mail    maildir:~/mail

The objectGUID is indeed binary data, but IHMO, it should be handled differently when returned. E.g. there is a defined string representation, [MS-DTYP] section 2.3.4.3: <https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/222af2d3-5c00-4899-bc87-ed4c6515e80d> which links to:

curly braced GUID string: The string representation of a 128-bit
globally unique identifier (GUID) using the form
{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}, where X denotes a hexadecimal
digit. The string representation between the enclosing braces is the
standard representation of a GUID as described in [RFC4122] section 3.
Unlike a GUIDString, a curly braced GUID string includes enclosing braces.

Some libs simply decide to return the data Base64 encoded (which would be OK, too). E.g. openldap-clients / ldapsearch does so with objectGUID and objectSid:

$ ldapsearch [...]
[...]
# uTesting, common, user, managed, example.com
dn: CN=uTesting,OU=common,OU=user,OU=managed,DC=example,DC=com
[...]
name: uTesting
objectGUID:: RCDirQPvGU6KQUFfIE/i2Q==
[...]
objectSid:: AQUAAAAAAAUVAAAALenCqsullBUfFoubWQQAAA==
[...]
sAMAccountName: uTesting
[...]

Other software had comparable bugs or behavior , e.g.

sssd ("Properly handle AD's binary objectGUID"):
<https://bugzilla.redhat.com/show_bug.cgi?id=1205382>
<https://github.com/SSSD/sssd/issues/3629>

owncloud ("ensure that objectguid or guid really return binary data before converting it"): <https://github.com/owncloud/core/issues/8317>



III. Software versions, config

I can reproduce the issue on Fedora Server 38

# cat /etc/redhat-release Fedora release 38 (Thirty Eight)

# uname -r
6.4.15-200.fc38.x86_64

# dovecot --version
2.3.20 (80a5ac675d)

and CentOS 9 Stream:

# cat /etc/redhat-release CentOS Stream release 9

# uname -r
5.14.0-364.el9.x86_64

# dovecot --version
2.3.16 (7e2e900c1a)

I did not try a Debian-based distro yet.

The config itself works fine, relevant settings just for reference (as there are not many examples on the internet, maybe useful for somebody):

auth_username_format = %Lu

passdb {
  driver = ldap
  args = /etc/dovecot/dovecot-ldap.conf.ext
}
userdb {
  driver = ldap
  args = /etc/dovecot/dovecot-ldap-userdb.conf.ext
}

with the following options to exclude inactive accounts, search smtp proxy addresses and having a mandatory group membership in SERVICE_EmailUsers:

base = OU=common,OU=user,OU=managed,DC=example,DC=com
scope = subtree

user_filter = \
  (& \
    (objectClass=user) \
    (objectCategory=Person) \
    
(|(sAMAccountName=%{username})(mail=%{username})(proxyAddresses=smtp:%{username}@%{domain}))
 \
    (!(userAccountControl:1.2.840.113556.1.4.803:=2)) \
    (memberOf:1.2.840.113556.1.4.1941:=SERVICE_EmailUsers) \
  )
pass_filter = \
  (& \
    (objectClass=user) \
    (objectCategory=Person) \
    
(|(sAMAccountName=%{username})(mail=%{username})(proxyAddresses=smtp:%{username}@%{domain}))
 \
    (!(userAccountControl:1.2.840.113556.1.4.803:=2)) \
    (memberOf:1.2.840.113556.1.4.1941:=SERVICE_EmailUsers) \
  )


I will blog about the config in more detail at https://foundata.com/en/blog/ soon, especially when the objectGUID is solved (maybe hashing it really the way to go). :-)

Regards,
Andreas


--
foundata GmbH
Steinhäuserstr. 20
76135 Karlsruhe

Sitz der Gesellschaft: Karlsruhe
Registergericht: Amtsgericht Mannheim, HRB 714807
Geschäftsführer: Andreas Haerter
USt-IdNr.: DE284122682
_______________________________________________
dovecot mailing list -- dovecot@dovecot.org
To unsubscribe send an email to dovecot-le...@dovecot.org

Reply via email to