AFP548

OpenLDAP + Lion + password changes via System Preferences

So, I've got this OpenLDAP server with network home directories at home that all of my Mac machines authenticate to. Everybody can bounce around to whatever Mac is available. It works great. :D Anyway, with Snow Leopard, I was able to change user passwords via System Preferences. However, that got broken when I upgraded to Lion (amongst other things). Both Snow Leopard and Lion send exop's to the ldap server, but for whatever reason, the id is screwed up in Lion (or at least, it's screwed up on the two machines at home I tested this with). Instead of sending the user's DN, e.g. "uid=user,cn=users,ou=something,dc=somewhere,dc=com", the ldap server is only sent the uid, e.g. "user". The ldap server is expecting a DN here, so naturally, it fails with the error "Invalid DN". Bummer. So, to work around that, I had to patch OpenLDAP (version 2.4.26 in this case). Now, when my server can't resolve the id it's given during a password change, it will look at the bind DN, and if the id string is contained within the bind DN string, it will just use the bind DN as the entry to change. I figured this would still allow me to manually specify password changes via an admin account while still giving users the ability to change their own passwords without having to point them at a webpage (lame). I should point out that all my accounts have the uid as part of the DN... I guess if you were doing some kind of crazy SASL mappings, this might not work for you... Anyway, here's the patch in case anyone else is interested... If it works for you, great. If not, oh well. [code] -- passwd.c 2011-06-30 11:13:36.000000000 -0400 +++ passwd.lion_compatability.c 2012-02-13 22:48:54.213214617 -0500 @@ -18,4 +18,5 @@ #include +#include #include @@ -59,4 +60,5 @@ int freenewpw = 0; struct berval dn = BER_BVNULL, ndn = BER_BVNULL; + ber_int_t err; assert( ber_bvcmp( &slap_EXOP_MODIFY_PASSWD, &op->ore_reqoid ) == 0 ); @@ -102,11 +104,8 @@ if ( !BER_BVISEMPTY( &id ) ) { - rs->sr_err = dnPrettyNormal( NULL, &id, &dn, &ndn, op->o_tmpmemctx ); - id.bv_val[id.bv_len] = idNul; - if ( rs->sr_err != LDAP_SUCCESS ) { - rs->sr_text = "Invalid DN"; - rc = rs->sr_err; - goto error_return; - } + err = dnPrettyNormal( NULL, &id, &dn, &ndn, op->o_tmpmemctx ); + } + + if ( !BER_BVISEMPTY( &id ) && (err == LDAP_SUCCESS) ) { op->o_req_dn = dn; op->o_req_ndn = ndn; @@ -116,4 +115,16 @@ ber_dupbv_x( &dn, &op->o_dn, op->o_tmpmemctx ); ber_dupbv_x( &ndn, &op->o_ndn, op->o_tmpmemctx ); + if ( !BER_BVISEMPTY( &id ) ) { + /* See if the id matches the bind dn */ + if ( strstr( dn.bv_val, id.bv_val ) == NULL ) + { + rs->sr_err = err; /* From dnPrettyNormal */ + rs->sr_text = "Invalid DN"; + rc = rs->sr_err; + goto error_return; + } + Statslog( LDAP_DEBUG_STATS, "%s Invalid id (%s) specified; using bind DN (%s)\n", + op->o_log_prefix, id.bv_val, dn.bv_val, 0, 0 ); + } op->o_req_dn = dn; op->o_req_ndn = ndn; @@ -123,4 +134,8 @@ } + if ( !BER_BVISEMPTY( &id ) ) { + id.bv_val[id.bv_len] = idNul; + } + if( op->o_bd == NULL ) { if ( qpw->rs_old.bv_val != NULL ) { [/code]
Exit mobile version