1

Topic: remoteauth.la

==== REQUIRED BASIC INFO OF YOUR IREDMAIL SERVER ====
- iRedMail version (check /etc/iredmail-release): 1.6.2 OPENLDAP edition.
- Deployed with iRedMail Easy or the downloadable installer? downloadable
- Linux/BSD distribution name and version: debian11
- Store mail accounts in which backend (LDAP/MySQL/PGSQL): ldap
- Web server (Apache or Nginx):
- Manage mail accounts with iRedAdmin-Pro? yes
- [IMPORTANT] Related original log or error message is required if you're experiencing an issue.
====
Hi, i m trying to authenticate my accounts against AD . I just speak about authentication, not identification or else. I try to use remoteauth in slapd but the backport version(2.5.13+dfsg-2~bpo11+1) of slapd has it, not the standard version (2.4.57+dfsg-3+deb11u1).

My questions are simple :
-can i use the backport version of openldap instead of the standard one  (will it breaks iredadminpro?)
-does it will work ? i mean can i delegate auth (and only auth ) to an AD (or something else that authenticate against my AD) ?

By the way how to transfert the license ? (it has been buy by a another society than mine).
Many thanks in advance

----

Spider Email Archiver: On-Premises, lightweight email archiving software developed by iRedMail team. Supports Amazon S3 compatible storage and custom branding.

2

Re: remoteauth.la

FYI for AD integration: https://docs.iredmail.org/active.directory.html

3

Re: remoteauth.la

ZhangHuangbin wrote:

FYI for AD integration: http()s://docs.iredmail.org/active.directory.html

I know, but in this case i can not use iredldapadminpro.
Moreover with this howto i can not have acces to mailgroup given by AD groups; especially ther is no 'one ldap request'  to obtain all groups a users belongs to (memberOf + primarygroup).

My goal is to have on one hand my ad with his structure in the other hand the structure that is used by your tools; but the authentication of iredadmin (the password part) is delegated to AD.

I m going to test, il will give you the results :-}

4

Re: remoteauth.la

This is a howto for using remoteauth (from the ldap in iredadminpro to authenticate in an AD)
This has been tested with debian 11 bullseye iredadminproldap5.4.1 and iredamin 1.6.2

A) in debian replace ldap2.4 with ldap2.5 from backports eg  "apt-get -t bullseye-backports install slapd"
even with iredadmin already installed upgrade works fine;

B) modify you slapd to user remoteauth
B1) in the part of slapd.conf where you find serveral "moduloads" add the line :

moduleload      remoteauth.la

B2) in databases section (at the end of slapd.conf) add (replace <..> with correct values):

overlay remoteauth
remoteauth_dn_attribute associatedName
# attribute used to resolve the domain
remoteauth_domain_attribute associatedDomain
# default domain if none is present in user entry
remoteauth_default_domain <NAME OF AD DOMAIN old style not FQDN> (eg DOMAIN\user -> DOMAIN) in lowercase
# domain mapping => [ list of hostnames or URIs]
# file europe.list contains a hostname or LDAP URI, one per line
# OpenLDAP tries to connect to first server, then if it fails or timeouts, to second server,...
#remoteauth_mapping europe file:///usr/local/openldap/etc/openldap/europe.list
# domain usa will use only one hostname
remoteauth_mapping <NAME OF AD DOMAIN old style not FQDN> <DNS_AD_SERVER_NMAE>
# fallback server to connect if no domain found in domain mapping
remoteauth_default_realm <NAME OF AD REALM : OR DNS NAME OF DOMAIN>
# number of retries attempted
remoteauth_retry_count 1
# store the password in case of successfull bind?
remoteauth_store off

okay that's the first part, for slapd

C) modify your slapd users accounts
C1) add objectClass extensibleObject to user accounts
C2) add 2 attributes to users records in ldap
C21) "associatedName"=> dn of user account in AD to authenticate against
C22) "associatedDomain" => Account in old NT style Form eg DOMAIN:user (seems that only DOMAIN: should work)

D) modify ZhangHuangbin code (do not blame me, i m not python-code-writer, so it is certainly awfull)
D1) in auth.py
comment the part
#~ if not conn:
        #~ _wrap = LDAPWrap()
        #~ conn = _wrap.conn

    #~ try:
        #~ qr = conn.search_s(dn,
                           #~ ldap.SCOPE_BASE,
                           #~ '(objectClass=*)',
                           #~ ['userPassword'])
        #~ if not qr:
            #~ # No such account.
            #~ return False, 'INVALID_CREDENTIALS'

        #~ _ldif = iredutils.bytes2str(qr[0][1])
        #~ pw = _ldif.get('userPassword', [''])[0]
        #~ if iredpwd.verify_password_hash(pw, password):
            #~ return True,
        #~ else:
            #~ return False, 'INVALID_CREDENTIALS'
    #~ except Exception as e:
        #~ return False, repr(e)
and add
    _wrap2 = LDAPWrap()
    conn_new = _wrap2.conn
    conn_new.unbind()
    try:
        qr=conn.bind_s(dn, password)
        if not qr:
            return False, 'INVALID_CREDENTIALS'
        else:
            return True,
    except Exception as e:
        return False, repr(e)
D2) in api_misc.py
comment :
#~ try:
            #~ _wrap = LDAPWrap()
            #~ conn = _wrap.conn

            #~ # Get password from LDAP
            #~ qr = conn.search_s(dn,
                               #~ ldap.SCOPE_BASE,
                               #~ "(objectClass=*)",
                               #~ ['userPassword'])

            #~ if not qr:
                #~ return api_render((False, 'NO_SUCH_ACCOUNT'))

            #~ _ldif = iredutils.bytes2str(qr[0][1])
            #~ # Compare first password
            #~ pw_in_ldap = _ldif.get('userPassword', [''])[0]
            #~ qr = iredpwd.verify_password_hash(pw_in_ldap, pw)
            #~ return api_render(qr)
        #~ except Exception as e:
            #~ return api_render((False, repr(e)))
and add :
        _wrap2 = LDAPWrap()
        conn_new = _wrap2.conn
        conn_new.unbind()
        try:
            _wrap2 = LDAPWrap()
            conn_new = _wrap2.conn
            conn_new.unbind()
            qr=conn.bind_s(dn, pw)
            if not qr:
                return False, 'INVALID_CREDENTIALS'
            else:
                return True,
        except Exception as e:
            return False, repr(e)


WARNING :
if in the ldap on iredamin a user has his userPassword field not empty it will use this field as password for the user;
if the field userPassword is empty the it fallback using remoteauth against AD.

5

Re: remoteauth.la

Thanks for sharing. smile