Opened 16 years ago

Last modified 15 years ago

#54 assigned enhancement

[PATCH] Auto-link multiple e-mail addresses from an LDAP authentication

Reported by: rjl Owned by: dmorton
Priority: low Milestone:
Component: PHP scripts Version: 1.0.0
Severity: normal Keywords: active directory ldap auto-link link multiple address authentication


LDAP accounts can contain more than one e-mail address, and when LDAP is used as the authentication method it would be nice to fetch all of the available e-mail addresses for the user and then auto-link them to his Maia account as secondary addresses. This would save him the trouble of having to do these additions manually.

Change History (9)

comment:1 Changed 16 years ago by dmorton

  • Owner changed from rjl to dmorton
  • Status changed from new to assigned

This is also possible for sql... basically, a more powerful but flexible authentication routine is needed...

comment:2 Changed 16 years ago by rjl

pbuonora@… added the suggestion of scanning the system's aliases file to automatically add supplemental addresses listed there.

comment:3 Changed 16 years ago by dmorton

Since these things could change, perhaps a routine could verify aliases and such during login, and present the user with a wizard if something new has been added...

comment:4 Changed 16 years ago by dmorton

  • Priority changed from normal to low

comment:5 Changed 15 years ago by dmorton

  • Milestone 1.0.0 deleted

comment:6 Changed 15 years ago by mw@…

  • Keywords active directory added
  • Version changed from 1.0.0 RC5 to 1.0.0

Attached are two patches and additioanl code which provide the feature of automatically adding all valid email addresses an active directory user has. for openldap it should be done in a similiar way. Ldap attributes which are hardcode for now (i.e. samaccountname) should be made configurable.

This work is not really ready for contribution but it is usable in special production environments and should be a good starting point (i hope) for migrating in future releases.

!! All patches/changes are against maia mailguard trunk svn checkout version 937

The code

sorry, some german comments and variable declarations still in

What does it?

  1. It gets all valid email addresse for the logged in user and compares them with the stored addresses in maia.
  1. If an address is in active directory but not in maia it gets linked to the maia user
  1. If an address is associated with the user which does not exist in active directory it will be deleted (unlinked) from the maia user

Todo: Everything happens unvisible for the user, no notice, no choice. Perhaps someone wants another behaviour, at least a popup which notifies the user of adding and/or removing aliases. On the other hand, in a straight customer environment where all addresses are managed by AD (or OpenLdap?), there is no need for a user to change anything in address assignments.

Like mentioned above, ldap attributes should not be hardcoded to make it work with openldap the same way.


# vim:softtabstop=4:tabstop=8:expandtab:shiftwidth=4

    # equalize email adresses ldap<->maia
    # Function call in xlogin.php 
    # <> and <>

    require_once ("core.php");
    require_once ("DB.php");  // PEAR::DB
    require_once ("mailtools.php");
    require_once ("db.php");

     * vgl. auth_ldap() in auth.php

    # debugging calling with `php -f ilk_equalizer.php` 
    $ilk_equalize_debug = 0;
    if ($ilk_equalize_debug) ilk_equalize( "standard2", 6 );

    function ilk_equalize($user, $uid)
        global $dbh;
        global $lang;
        global $auth_ldap_server;
        global $auth_ldap_bind_dn;
        global $auth_ldap_base_dn;
        global $auth_ldap_password;
        global $auth_ldap_query;
        global $auth_ldap_attribute;
       global $auth_ldap_version;
       global $auth_ldap_opt_referrals;

        global $ilk_equalize_debug;

        $ldap_conn = ldap_connect($auth_ldap_server)
                         or die($lang['error_ldap_connect']);

       ldap_set_option($ldap_conn, LDAP_OPT_PROTOCOL_VERSION, $auth_ldap_version);
       ldap_set_option($ldap_conn, LDAP_OPT_REFERRALS, $auth_ldap_opt_referrals);

        ldap_bind($ldap_conn, $auth_ldap_bind_dn, $auth_ldap_password)
            or die($lang['error_ldap_bind']);

        # nach sAMAccountName filtern
        $my_auth_ldap_query = "(sAMAccountName=%%USER%%)";
        $filter = $my_auth_ldap_query;
        $filter = str_replace("%%USER%%", $user, $filter);

        $my_auth_ldap_attribute = "proxyAddresses";

        $sr = ldap_search($ldap_conn, $auth_ldap_base_dn, $filter,
                          #array($my_auth_ldap_attribute, "dn"));

        if (ldap_count_entries($ldap_conn, $sr) == 1) {
            $entries = ldap_get_entries($ldap_conn, $sr);
            #   debug_hash("entries", $entries);
            #   debug_hash("entries", $entries[0]["proxyaddresses"]);
            #   debug_hash("entries", $entries[0]["mail"]);

            ### proxyaddresses bei Bedarf anlegen       
            if ($data = $entries[0]["proxyaddresses"])
                foreach( $data as $key => $val )
                    $matches = array();
                    if (preg_match ("/^smtp:(.*)/i", $val, $matches) )
                        if ($ilk_equalize_debug) echo $matches[1]  . " wird angelegt..\n";
                        email_adresse_anlegen($uid, $matches[1]);

            ### email-adressen aus maia ueberpruefen, ob sie noch im ldap aktuell sind
            $select = "SELECT id, email FROM users WHERE maia_user_id = ?";
            $sth = $dbh->query($select, $uid);
            while ($row = $sth->fetchRow()) {
                 $maia_email = $row['email'];
                 $email_id = $row['id'];
                if ($ilk_equalize_debug) echo "pruefe maia-email $maia_email ($email_id).. ";

                $my_auth_ldap_query2 = "(proxyAddresses=smtp:$maia_email)";
                $my_auth_ldap_attribute2 = "mail";

                $sr = ldap_search($ldap_conn, $auth_ldap_base_dn, $my_auth_ldap_query2,

                if (ldap_count_entries($ldap_conn, $sr) == 1) {
                    if ($ilk_equalize_debug) echo "existiert.\n";
                    if ($ilk_equalize_debug) echo "wird geloescht..\n";
                    email_adresse_loeschen( $email_id );

     *  for debugging reasons

    function debug_hash( $name, $data )
    if ($data)
        foreach( $data as $key => $val )
            echo "$key: $val\n";

     *  legt email-adresse an, falls sie noch nicht existiert.
     *  falls sie unter einem anderen User existiert, wird sie umgezogen 
     *  vgl. settings.php

    function email_adresse_anlegen ( $euid, $email ) {
            $address_id = get_email_address_id($email);
            $old_owner = get_email_address_owner($address_id);
            if (!$old_owner) {
                add_email_address_to_user($euid, $email);
            } elseif ($old_owner != $euid) {
                transfer_email_address_to_user($old_owner, $euid, $email);

     *  loescht email-adresse, falls sie im ldap nicht mehr existiert.
     *  Code vgl. xadminusers.php

    function email_adresse_loeschen ( $email_id ) {
          // Find out who owns this e-mail address.
          $owner_id = get_email_address_owner($email_id);
          $primary_email_id = get_primary_email_id($owner_id);

          // Delete this email address, but only if it
          // is NOT the user's primary address.
          if ($email_id != $primary_email_id) {


Including the code within xlogin.php


--- trunk/php/xlogin.php        2006-01-17 00:36:42.000000000 +0000
+++ maia/php/xlogin.php 2006-01-31 10:25:23.000000000 +0000
@@ -188,6 +188,7 @@
    if ($authenticated === true)

        // See if this user has an entry in the users table yet
@@ -213,6 +214,13 @@
                                         trim($_POST["charset"]) :

+        # equalize email adresses ldap<->maia
+        # <> and <>
+       if (($auth_method == "imap") && ($auth_ldap_mail_equalizer)) {
+         require_once( "ilk_equalizer.php" );
+         ilk_equalize( $user_name, $uid );
+       }
        // If the $super variable was set, try to process the
        // (supposed) superuser's request.
        if ($super == "register") {

Make it a configure option in config.php.dist

There is another change which doesnt belong to the actual patch, its just concerning the mysql socket path in debian installs (ignore).


--- trunk/php/config.php.dist   2006-01-30 10:34:36.000000000 +0000
+++ maia/php/config.php.dist    2006-01-31 15:45:19.000000000 +0000
@@ -120,8 +120,8 @@

     //$maia_sql_dsn = "dbtype://dbuser:passwd@tcp(hostname:port)/maia";
-    $maia_sql_dsn = "mysql://amavis:passwd@tcp(localhost:3306)/maia";
-    //$maia_sql_dsn = "mysql://dbuser:passwd@unix(/var/tmp/mysql.sock)/maia";
+    //$maia_sql_dsn = "mysql://amavis:passwd@tcp(localhost:3306)/maia";
+    $maia_sql_dsn = "mysql://dbuser:passwd@unix(/var/run/mysqld/mysqld.sock)/maia";
     //$maia_sql_dsn = "mysql://dbuser:passwd/maia";

@@ -269,6 +269,10 @@
     // Active directory seems to need 0 (default is 1)
     $auth_ldap_opt_referrals = 1;

+    // If you want to have valid email addresses always
+    // addd automatically set this to True
+    $auth_ldap_equalizer = False;


comment:7 Changed 15 years ago by dmorton

That's funny, I was just working on something like this, and my code looks very similar.. :)

comment:8 Changed 15 years ago by anonymous

  • Summary changed from Auto-link multiple e-mail addresses from an LDAP authentication to [PATCH] Auto-link multiple e-mail addresses from an LDAP authentication

comment:9 Changed 15 years ago by rjl

  • patch set to 1
Note: See TracTickets for help on using tickets.