Sponsoring a canon_user plugin for LDAP lookup

Dan White dwhite at olp.net
Mon Mar 12 10:43:16 EST 2007


Torsten,

Yes, I had some success last night. It took some time to pick up
the OpenLDAP proxy process.

Using both patches, the canonization works for me for both
sample-server and imapd, but not for pop3d when it opens the
mailbox, for some reason. I'm using Debian etch with the
following versions:

cyrus-imapd-2.2:        2.2.13-10
libsasl2:               2.1.22.dfsg1-8
slapd:                  2.3.30-4

I'm going to try version 2.3 of cyrus imap to see if pop3 works
any differently.

I added the following statements to the default slapd.conf
config:

========
sasl-regexp    
  "gidNumber=0\\\+uidNumber=0,cn=peercred,cn=external,cn=auth"
  cn=admin,dc=nodomain

authz-policy to

authz-regexp   
  "gidNumber=8\\\+uidNumber=104,cn=peercred,cn=external,cn=auth"
  cn=admin,dc=nodomain

authz-regexp uid=(.*),cn=external,cn=auth
    ldap:///ou=People,dc=nodomain??one?(cn=$1)
========

Where 104 is the UID of my local cyrus user in /etc/passwd.
The suffix is "dc=nodomain".

I added the following to my admin entry:
========
dn: cn=admin,dc=nodomain
changetype: modify
add: authzTo
authzTo: ldap:///ou=People,dc=nodomain??sub?(objectClass=posixAccount)
=========

I'm not sure this authzTo line is correct, but it worked during
testing.

My test user looks like:
=========
dn: uid=test3434,ou=People,dc=nodomain
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
uid: test3434
cn: test3434
cn: test3434 at olp.net
cn: dwhite
cn: dwhite at olp.net
uidNumber: 1001
gidNumber: 500
homeDirectory: /home/test3434
loginShell: /bin/bash
shadowMin: 0
shadowMax: 99999
shadowLastChange: 13581
userPassword: mysecret
==========

I added the following lines to /etc/imapd.conf:
========
sasl_pwcheck_method: auxprop
sasl_auxprop_plugin: ldapdb

sasl_canon_user_plugin: ldapdb
sasl_ldapdb_uri: ldapi://%2fvar%2frun%2fslapd%2fldapi/
sasl_ldapdb_mech: EXTERNAL
sasl_ldapdb_canon_attr: uid
========
(I added cyrus to the openldap group in /etc/group to
give it access to the ldapi socket)

Some tests (as the cyrus user):
=======
cyrus at test:~$ ldapwhoami -Y EXTERNAL
SASL/EXTERNAL authentication started
SASL username: gidNumber=8+uidNumber=104,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn:cn=admin,dc=nodomain
Result: Success (0)
cyrus at test:~$
=======

=======
cyrus at test:~$ ldapwhoami -Y EXTERNAL \
  -U gidNumber=8+uidNumber=104,cn=peercred,cn=external,cn=auth \
  -X u:dwhite SASL/EXTERNAL
authentication started
SASL username: u:dwhite
SASL SSF: 0
dn:uid=test3434,ou=people,dc=nodomain
Result: Success (0)
cyrus at test:~$
========

Here's an expect script you can use with the sample-server
and sample-client executables:
========
#!/usr/bin/expect

# Set environment variables:
#   SASL_PATH - to the location of the plugin modules
#   SASL_CONF_PATH - path to the sample.conf file

set username [lindex $argv 0]
set mech [lindex $argv 1]
spawn /usr/sbin/sasl-sample-server -s sample -m $mech
set saslserver $spawn_id
spawn /usr/bin/sasl-sample-client -s sample -a $username
set saslclient $spawn_id

while { 1!=2 } {

  expect {
    -i $saslserver -re "S: \[0-9a-zA-Z\=\]+" {
      set output $expect_out(0,string)
      send -i $saslclient "$output\r"
      send_user "==Sending $output to client.==\n";
    }
    -i $saslserver -re "recieved decoded.*client" {
      send_user "==got client recieved.==\n"
      break
    }
  }

  expect {
    -i $saslclient -re "C: \[0-9a-zA-Z\=\]+" {
      set output $expect_out(0,string)
      send -i $saslserver "$output\r"
      send_user "==Sending $output to server.==\n";
    }
    -i $saslclient -re "Password:" {
      expect_user -re "(.*)\n"
      send_user "\n"
      send -i $saslclient "$expect_out(1,string)\r"

      expect -i $saslclient -re "C: \[0-9a-zA-Z\=\]+"
      set output $expect_out(0,string)
      send -i $saslserver "$output\r"
      send_user "==Sending $output to server.==\n";
    }
  }
}

send_user "==Success==\n"
========

To use, create a .conf file somewhere (like in
/tmp/sample.conf) with the following contents:
========
pwcheck_method: auxprop
auxprop_plugin: ldapdb

ldapdb_uri: ldapi://%2fvar%2frun%2fslapd%2fldapi/
ldapdb_mech: EXTERNAL

canon_user_plugin: ldapdb
ldapdb_canon_attr: uid
========

Then do:
test:~# export SASL_CONF_PATH=/tmp
test:~# ./sasl.exp dwhite LOGIN
...
Password: mysecret
...
got 'dwhite'
...
Username: dwhite
...
Username: test3434
...
==Success==
test:~#
==========

Connecting via IMAP seems to work fine. I can authenticate
with either username (test3434 or dwhite) and I get
test3434's INBOX.

- Dan

Torsten Schlabach wrote:
> Hi Dan!
>
> Did you anywhere with that?
>
> Regards,
> Torsten
>
> -------- Original-Nachricht --------
> Betreff: [Fwd: Re: Sponsoring a canon_user plugin for LDAP lookup]
> Datum: Thu, 08 Mar 2007 18:51:36 +0100
> Von: Torsten Schlabach <tschlabach at gmx.net>
> An: dwhite at olp.net
>
> Hi Dan!
>
> This is the other one.
>
> So the process would probably be:
>
> - Check out the SASL library sources.
> - Apply the patched.
> - Configure with the apporiate option to build the libldapdb SASL plugin
> and built it.
> - Either install SASL from your patched sources or just transfer the
> libldapdb libs into your SASL installation coming from your packages.
> (Not sure what distro you're using.)
>
> That was not the problem.
>
> Then you need to configure both OpenLDAP (slapd.conf) as well as Cyrus
> IMAPd (imapd.conf) to use this properly and this is where I basically
> failed and gave up.
>
> Would be nice if you kept me in the look, please.
>
> Regards,
> Torsten
>
> -------- Original-Nachricht --------
> Betreff: Re: Sponsoring a canon_user plugin for LDAP lookup
> Datum: Mon, 19 Feb 2007 16:13:50 -0800
> Von: Howard Chu <hyc at highlandsun.com>
> An: Torsten Schlabach <tschlabach at gmx.net>
> Referenzen: <45A6179E.2040506 at gmx.net>
> <45A7C28A.8060602 at highlandsun.com> <45A7EDBD.6070700 at gmx.net>
> <45A7F356.5070806 at highlandsun.com> <45A80444.9090802 at gmx.net>
> <45A814D2.70903 at highlandsun.com> <45A818C4.40406 at gmx.net>
> <45A81C4E.2090003 at highlandsun.com> <45A81EA1.5090204 at gmx.net>
> <45A830BD.4080300 at highlandsun.com> <45DA148D.7000207 at gmx.net>
> <45DA1DC6.6060703 at highlandsun.com> <45DA20F1.3080700 at gmx.net>
>
> Torsten Schlabach wrote:
>> Hi!
>>
>> > +       out[len] = '\0';
>>
>> I had tried this myself, but the result I got was an empty string. So 
>> it seems that len == 0 for whatever reason.
>>
>> Bonus question, as I am going nuts about it: How do I add the authTo: 
>> attribute to the uid=root object?
>>
>> Regards,
>> Torsten
>>
>> Howard Chu schrieb:
>>> Hi. Try patching these two lines. I haven't tested this yet, 
>>> rebuilding my test directory at the moment and will know more in a 
>>> few minutes.
> The attachment contains the same patch for those two lines, plus a
> canonuser_client entry point. It's working for me, with these rules:
>
> authid-rewriteMap slapd alias2DN
> ldap:///dc=example,dc=com?mailAliasedName?sub?
> authid-rewriteRule uid=(.*)@(.*),cn=digest-md5,cn=auth
>
> ldap:///dc=example,dc=com??sub?(uid=%{alias2dn((&(mailalias=$1)(dc=$2)))}) 
>
> authz-regexp uid=(.*),cn=digest-md5,cn=auth
>      ldap:///dc=example,dc=com??sub?(uid=$1)
>
>
>
> ------------------------------------------------------------------------
>
> --- ldapdb.c.X	2007-01-12 16:55:58.000000000 -0800
> +++ ldapdb.c	2007-02-19 15:37:48.000000000 -0800
> @@ -311,7 +311,7 @@
>      if (!strncasecmp(ctx->canon.bv_val, rdn, ctx->canon.bv_len) &&
>      	rdn[ctx->canon.bv_len] == '=') {
>  	char *comma;
> -	rdn += ctx->canon.bv_len + 2;
> +	rdn += ctx->canon.bv_len + 1;
>  	comma = strchr(rdn, ',');
>  	if ( comma )
>  	    len = comma - rdn;
> @@ -320,6 +320,7 @@
>  	if ( len > out_max )
>  	    len = out_max;
>  	memcpy(out, rdn, len);
> +	out[len] = '\0';
>  	*out_ulen = len;
>  	ret = SASL_OK;
>  	ber_bvfree(cp.dn);
> @@ -361,6 +362,38 @@
>  }
>  
>  static int
> +ldapdb_canon_client(void *glob_context,
> +		    sasl_client_params_t *cparams,
> +		    const char *user,
> +		    unsigned ulen,
> +		    unsigned flags,
> +		    char *out,
> +		    unsigned out_max,
> +		    unsigned *out_ulen)
> +{
> +    if(!cparams || !user) return SASL_BADPARAM;
> +
> +    /* Trim whitespace */
> +    while(isspace(*(unsigned char *)user)) {
> +	user++;
> +	ulen--;
> +    }
> +    while(isspace((unsigned char)user[ulen-1])) {
> +    	ulen--;
> +    }
> +    
> +    if (!ulen) {
> +    	cparams->utils->seterror(cparams->utils->conn, 0,
> +	    "All-whitespace username.");
> +	return SASL_FAIL;
> +    }
> +    memcpy(out, user, ulen);
> +    out[ulen] = '\0';
> +    *out_ulen = ulen;
> +    return SASL_OK;
> +}
> +
> +static int
>  ldapdb_config(const sasl_utils_t *utils)
>  {
>      ldapctx *p = &ldapdb_ctx;
> @@ -446,7 +479,7 @@
>  	ldapdb,	/* name */
>  	NULL,	/* canon_user_free */
>  	ldapdb_canon_server,	/* canon_user_server */
> -	NULL,	/* canon_user_client */
> +	ldapdb_canon_client,	/* canon_user_client */
>  	NULL,
>  	NULL,
>  	NULL
>
>
>   



More information about the Cyrus-sasl mailing list