]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/sasl.c
Import ITS#2007 and ITS#2009 bug fixes from HEAD
[openldap] / servers / slapd / sasl.c
index ba1cdb0c2fae812807adca27485fa1e622506513..be7b1bb51368184bfe5dc8c897e53c0fa3d2ff77 100644 (file)
 
 static sasl_security_properties_t sasl_secprops;
 
+int slap_sasl_config( int cargc, char **cargv, char *line,
+       const char *fname, int lineno )
+{
+               /* set SASL proxy authorization policy */
+               if ( strcasecmp( cargv[0], "sasl-authz-policy" ) == 0 ) {
+                       if ( cargc != 2 ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, CRIT,
+                                          "%s: line %d: missing policy in \"sasl-authz-policy <policy>\" line\n",
+                                          fname, lineno, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY,
+           "%s: line %d: missing policy in \"sasl-authz-policy <policy>\" line\n",
+                                   fname, lineno, 0 );
+#endif
+
+                               return( 1 );
+                       }
+                       if ( slap_sasl_setpolicy( cargv[1] ) ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, CRIT,
+                                          "%s: line %d: unable "
+                                          "to parse value \"%s\" "
+                                          "in \"sasl-authz-policy "
+                                          "<policy>\" line.\n",
+                                          fname, lineno, cargv[1] );
+#else
+                               Debug( LDAP_DEBUG_ANY,
+                                       "%s: line %d: unable "
+                                       "to parse value \"%s\" "
+                                       "in \"sasl-authz-policy "
+                                       "<policy>\" line\n",
+                                       fname, lineno, cargv[1] );
+#endif
+                               return( 1 );
+                       }
+                       
+
+               /* set SASL host */
+               } else if ( strcasecmp( cargv[0], "sasl-host" ) == 0 ) {
+                       if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, CRIT,
+                                          "%s: line %d: missing host in \"sasl-host <host>\" line\n",
+                                          fname, lineno, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY,
+           "%s: line %d: missing host in \"sasl-host <host>\" line\n",
+                                   fname, lineno, 0 );
+#endif
+
+                               return( 1 );
+                       }
+
+                       if ( global_host != NULL ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, CRIT,
+                                          "%s: line %d: already set sasl-host!\n",
+                                          fname, lineno, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY,
+                                       "%s: line %d: already set sasl-host!\n",
+                                       fname, lineno, 0 );
+#endif
+
+                               return 1;
+
+                       } else {
+                               global_host = ch_strdup( cargv[1] );
+                       }
+
+               /* set SASL realm */
+               } else if ( strcasecmp( cargv[0], "sasl-realm" ) == 0 ) {
+                       if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, CRIT,
+                                          "%s: line %d: missing realm in \"sasl-realm <realm>\" line.\n",
+                                          fname, lineno, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY,
+           "%s: line %d: missing realm in \"sasl-realm <realm>\" line\n",
+                                   fname, lineno, 0 );
+#endif
+
+                               return( 1 );
+                       }
+
+                       if ( global_realm != NULL ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, CRIT,
+                                          "%s: line %d: already set sasl-realm!\n",
+                                          fname, lineno, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY,
+                                       "%s: line %d: already set sasl-realm!\n",
+                                       fname, lineno, 0 );
+#endif
+
+                               return 1;
+
+                       } else {
+                               global_realm = ch_strdup( cargv[1] );
+                       }
+
+               } else if ( !strcasecmp( cargv[0], "sasl-regexp" ) 
+                       || !strcasecmp( cargv[0], "saslregexp" ) )
+               {
+                       int rc;
+                       if ( cargc != 3 ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, CRIT,
+                                          "%s: line %d: need 2 args in "
+                                          "\"saslregexp <match> <replace>\"\n",
+                                          fname, lineno, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY, 
+                               "%s: line %d: need 2 args in \"saslregexp <match> <replace>\"\n",
+                                   fname, lineno, 0 );
+#endif
+
+                               return( 1 );
+                       }
+                       rc = slap_sasl_regexp_config( cargv[1], cargv[2] );
+                       if ( rc ) {
+                               return rc;
+                       }
+
+               /* SASL security properties */
+               } else if ( strcasecmp( cargv[0], "sasl-secprops" ) == 0 ) {
+                       char *txt;
+
+                       if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, CRIT,
+                                          "%s: line %d: missing flags in "
+                                          "\"sasl-secprops <properties>\" line\n",
+                                          fname, lineno, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY,
+           "%s: line %d: missing flags in \"sasl-secprops <properties>\" line\n",
+                                   fname, lineno, 0 );
+#endif
+
+                               return 1;
+                       }
+
+                       txt = slap_sasl_secprops( cargv[1] );
+                       if ( txt != NULL ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, CRIT,
+                                          "%s: line %d sasl-secprops: %s\n",
+                                          fname, lineno, txt );
+#else
+                               Debug( LDAP_DEBUG_ANY,
+           "%s: line %d: sasl-secprops: %s\n",
+                                   fname, lineno, txt );
+#endif
+
+                               return 1;
+                       }
+           }
+
+           return LDAP_SUCCESS;
+}
+
 static int
 slap_sasl_log(
        void *context,
@@ -111,10 +276,8 @@ slap_sasl_log(
        }
 
 #ifdef NEW_LOGGING
-       LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
-               "SASL [conn=%ld] %s: %s\n",
-               conn ? conn->c_connid : -1,
-               label, message ));
+       LDAP_LOG( TRANSPORT, ENTRY, 
+               "SASL [conn=%ld] %s: %s\n", conn ? conn->c_connid : -1, label, message);
 #else
        Debug( level, "SASL [conn=%ld] %s: %s\n",
                conn ? conn->c_connid: -1,
@@ -150,10 +313,9 @@ int slap_sasl_getdn( Connection *conn, char *id, int len,
        struct berval dn2;
 
 #ifdef NEW_LOGGING
-       LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
+       LDAP_LOG( TRANSPORT, ENTRY, 
                "slap_sasl_getdn: conn %d id=%s\n",
-               conn ? conn->c_connid : -1,
-               id ? (*id ? id : "<empty>") : "NULL" ));
+               conn ? conn->c_connid : -1, id ? (*id ? id : "<empty>") : "NULL", 0 );
 #else
        Debug( LDAP_DEBUG_ARGS, "slap_sasl_getdn: id=%s\n", 
       id?(*id?id:"<empty>"):"NULL",0,0 );
@@ -238,29 +400,29 @@ int slap_sasl_getdn( Connection *conn, char *id, int len,
                /* Build the new dn */
                c1 = dn->bv_val;
                dn->bv_val = ch_malloc( len+1 );
-               p = slap_strcopy( dn->bv_val, "uid=" );
-               p = slap_strncopy( p, c1, dn->bv_len );
+               p = lutil_strcopy( dn->bv_val, "uid=" );
+               p = lutil_strncopy( p, c1, dn->bv_len );
 
                if( realm ) {
                        int rlen = dn->bv_len - ( realm - c1 );
-                       p = slap_strcopy( p, ",cn=" );
-                       p = slap_strncopy( p, realm, rlen );
+                       p = lutil_strcopy( p, ",cn=" );
+                       p = lutil_strncopy( p, realm, rlen );
                        realm[-1] = '@';
                } else if( user_realm && *user_realm ) {
-                       p = slap_strcopy( p, ",cn=" );
-                       p = slap_strcopy( p, user_realm );
+                       p = lutil_strcopy( p, ",cn=" );
+                       p = lutil_strcopy( p, user_realm );
                }
 
                if( conn->c_sasl_bind_mech.bv_len ) {
-                       p = slap_strcopy( p, ",cn=" );
-                       p = slap_strcopy( p, conn->c_sasl_bind_mech.bv_val );
+                       p = lutil_strcopy( p, ",cn=" );
+                       p = lutil_strcopy( p, conn->c_sasl_bind_mech.bv_val );
                }
-               p = slap_strcopy( p, ",cn=auth" );
+               p = lutil_strcopy( p, ",cn=auth" );
                dn->bv_len = p - dn->bv_val;
 
 #ifdef NEW_LOGGING
-               LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
-                       "slap_sasl_getdn: u:id converted to %s.\n", dn->bv_val ));
+               LDAP_LOG( TRANSPORT, ENTRY, 
+                       "slap_sasl_getdn: u:id converted to %s.\n", dn->bv_val, 0, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE, "getdn: u:id converted to %s\n", dn->bv_val,0,0 );
 #endif
@@ -288,8 +450,8 @@ int slap_sasl_getdn( Connection *conn, char *id, int len,
                ch_free( dn->bv_val );
                *dn = dn2;
 #ifdef NEW_LOGGING
-               LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
-                       "slap_sasl_getdn: dn:id converted to %s.\n", dn->bv_val ));
+               LDAP_LOG( TRANSPORT, ENTRY, 
+                       "slap_sasl_getdn: dn:id converted to %s.\n", dn->bv_val, 0, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE, "getdn: dn:id converted to %s\n",
                        dn->bv_val, 0, 0 );
@@ -358,8 +520,8 @@ slap_auxprop_lookup(
                rc = slap_str2ad( name, &ad, &text );
                if ( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG(( "sasl", LDAP_LEVEL_DETAIL1,
-                               "slap_auxprop: str2ad(%s): %s\n", name, text ));
+                       LDAP_LOG( TRANSPORT, DETAIL1, 
+                               "slap_auxprop: str2ad(%s): %s\n",  name, text, 0 );
 #else
                        Debug( LDAP_DEBUG_TRACE,
                                "slap_auxprop: str2ad(%s): %s\n", name, text, 0 );
@@ -499,11 +661,10 @@ slap_sasl_canonicalize(
        *out_len = 0;
 
 #ifdef NEW_LOGGING
-       LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
+       LDAP_LOG( TRANSPORT, ENTRY, 
                "slap_sasl_canonicalize: conn %d %s=\"%s\"\n",
-                       conn ? conn->c_connid : -1,
-                       (flags & SASL_CU_AUTHID) ? "authcid" : "authzid",
-                       in ? in : "<empty>" ));
+               conn ? conn->c_connid : -1,
+               (flags & SASL_CU_AUTHID) ? "authcid" : "authzid", in ? in : "<empty>");
 #else
        Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: "
                "%s=\"%s\"\n",
@@ -558,10 +719,9 @@ slap_sasl_canonicalize(
        prop_set( props, names[0], (char *)&dn, sizeof( dn ) );
                
 #ifdef NEW_LOGGING
-       LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
+       LDAP_LOG( TRANSPORT, ENTRY, 
                "slap_sasl_canonicalize: conn %d %s=\"%s\"\n",
-                       conn ? conn->c_connid : -1,
-                       names[0]+1, dn.bv_val ));
+               conn ? conn->c_connid : -1, names[0]+1, dn.bv_val );
 #else
        Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: "
                "%s=\"%s\"\n",
@@ -594,30 +754,39 @@ slap_sasl_authorize(
        int rc;
 
 #ifdef NEW_LOGGING
-       LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
+       LDAP_LOG( TRANSPORT, ENTRY, 
                "slap_sasl_authorize: conn %d authcid=\"%s\" authzid=\"%s\"\n",
-                       conn ? conn->c_connid : -1, auth_identity, requested_user));
+               conn ? conn->c_connid : -1, auth_identity, requested_user);
 #else
        Debug( LDAP_DEBUG_ARGS, "SASL Authorize [conn=%ld]: "
                "authcid=\"%s\" authzid=\"%s\"\n",
                conn ? conn->c_connid : -1, auth_identity, requested_user );
 #endif
+       if ( conn->c_sasl_dn.bv_val ) {
+               ch_free( conn->c_sasl_dn.bv_val );
+               conn->c_sasl_dn.bv_val = NULL;
+               conn->c_sasl_dn.bv_len = 0;
+       }
 
        prop_getnames( props, slap_propnames, auxvals );
        
+       AC_MEMCPY( &authcDN, auxvals[0].values[0], sizeof(authcDN) );
+
        /* Nothing to do if no authzID was given */
-       if ( !auxvals[1].name || !auxvals[1].values )
+       if ( !auxvals[1].name || !auxvals[1].values ) {
+               conn->c_sasl_dn = authcDN;
                return SASL_OK;
+       }
        
-       AC_MEMCPY( &authcDN, auxvals[0].values[0], sizeof(authcDN) );
        AC_MEMCPY( &authzDN, auxvals[1].values[0], sizeof(authzDN) );
 
-       rc = slap_sasl_authorized( &authcDN, &authzDN );
+       rc = slap_sasl_authorized( conn, &authcDN, &authzDN );
+       ch_free( authcDN.bv_val );
        if ( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
-               LDAP_LOG(( "sasl", LDAP_LEVEL_INFO,
-                          "slap_sasl_authorize: conn %ld  authorization disallowed (%d)\n",
-                          (long)(conn ? conn->c_connid : -1), rc ));
+               LDAP_LOG( TRANSPORT, INFO, 
+                       "slap_sasl_authorize: conn %ld  authorization disallowed (%d)\n",
+                       (long)(conn ? conn->c_connid : -1), rc, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE, "SASL Authorize [conn=%ld]: "
                        " authorization disallowed (%d)\n",
@@ -625,13 +794,16 @@ slap_sasl_authorize(
 #endif
 
                sasl_seterror( sconn, 0, "not authorized" );
+               ch_free( authzDN.bv_val );
                return SASL_NOAUTHZ;
        }
 
+       conn->c_sasl_dn = authzDN;
+
 #ifdef NEW_LOGGING
-       LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
-                  "slap_sasl_authorize: conn %d authorization allowed\n",
-                  (long)(conn ? conn->c_connid : -1 ) ));
+       LDAP_LOG( TRANSPORT, ENTRY, 
+               "slap_sasl_authorize: conn %d authorization allowed\n",
+               (long)(conn ? conn->c_connid : -1), 0, 0 );
 #else
        Debug( LDAP_DEBUG_TRACE, "SASL Authorize [conn=%ld]: "
                " authorization allowed\n",
@@ -654,13 +826,17 @@ slap_sasl_authorize(
        char *realm;
 
        *user = NULL;
+       if ( conn->c_sasl_dn.bv_val ) {
+               ch_free( conn->c_sasl_dn.bv_val );
+               conn->c_sasl_dn.bv_val = NULL;
+               conn->c_sasl_dn.bv_len = 0;
+       }
 
 #ifdef NEW_LOGGING
-       LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
-                  "slap_sasl_authorize: conn %d         authcid=\"%s\" authzid=\"%s\"\n",
-                  conn ? conn->c_connid : -1,
-                  authcid ? authcid : "<empty>",
-                  authzid ? authzid : "<empty>" ));
+       LDAP_LOG( TRANSPORT, ENTRY, 
+               "slap_sasl_authorize: conn %d    authcid=\"%s\" authzid=\"%s\"\n",
+               conn ? conn->c_connid : -1, authcid ? authcid : "<empty>",
+               authzid ? authzid : "<empty>" );
 #else
        Debug( LDAP_DEBUG_ARGS, "SASL Authorize [conn=%ld]: "
                "authcid=\"%s\" authzid=\"%s\"\n",
@@ -673,8 +849,8 @@ slap_sasl_authorize(
        rc = sasl_getprop( conn->c_sasl_context, SASL_REALM, (void **)&realm );
        if( rc != SASL_OK && rc != SASL_NOTDONE ) {
 #ifdef NEW_LOGGING
-               LDAP_LOG(( "sasl", LDAP_LEVEL_ERR,
-                       "slap_sasl_authorize: getprop(REALM) failed.\n" ));
+               LDAP_LOG( TRANSPORT, ERR,
+                       "slap_sasl_authorize: getprop(REALM) failed.\n", 0, 0, 0 );
 #else
                Debug(LDAP_DEBUG_TRACE,
                        "authorize: getprop(REALM) failed!\n", 0,0,0);
@@ -692,15 +868,15 @@ slap_sasl_authorize(
        }
        if( ( authzid == NULL ) || !strcmp( authcid,authzid ) ) {
 #ifdef NEW_LOGGING
-               LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
-                          "slap_sasl_authorize: conn %d  Using authcDN=%s\n",
-                          conn ? conn->c_connid : -1, authcDN.bv_val ));
+               LDAP_LOG( TRANSPORT, ENTRY, 
+                       "slap_sasl_authorize: conn %d  Using authcDN=%s\n",
+                       conn ? conn->c_connid : -1, authcDN.bv_val, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE, "SASL Authorize [conn=%ld]: "
                 "Using authcDN=%s\n", (long) (conn ? conn->c_connid : -1), authcDN.bv_val,0 );
 #endif
 
-               *user = authcDN.bv_val;
+               conn->c_sasl_dn = authcDN;
                *errstr = NULL;
                return SASL_OK;
        }
@@ -711,12 +887,13 @@ slap_sasl_authorize(
                return SASL_NOAUTHZ;
        }
 
-       rc = slap_sasl_authorized( &authcDN, &authzDN );
+       rc = slap_sasl_authorized(conn, &authcDN, &authzDN );
+       ch_free( authcDN.bv_val );
        if( rc ) {
 #ifdef NEW_LOGGING
-               LDAP_LOG(( "sasl", LDAP_LEVEL_INFO,
-                          "slap_sasl_authorize: conn %ld  authorization disallowed (%d)\n",
-                          (long)(conn ? conn->c_connid : -1), rc ));
+               LDAP_LOG( TRANSPORT, INFO, 
+                       "slap_sasl_authorize: conn %ld  authorization disallowed (%d)\n",
+                       (long)(conn ? conn->c_connid : -1), rc, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE, "SASL Authorize [conn=%ld]: "
                        " authorization disallowed (%d)\n",
@@ -724,24 +901,21 @@ slap_sasl_authorize(
 #endif
 
                *errstr = "not authorized";
-               ch_free( authcDN.bv_val );
                ch_free( authzDN.bv_val );
                return SASL_NOAUTHZ;
        }
 
 #ifdef NEW_LOGGING
-       LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
-                  "slap_sasl_authorize: conn %d authorization allowed\n",
-                  (long)(conn ? conn->c_connid : -1 ) ));
+       LDAP_LOG( TRANSPORT, RESULTS, 
+               "slap_sasl_authorize: conn %d authorization allowed\n",
+          (long)(conn ? conn->c_connid : -1 ), 0, 0 );
 #else
        Debug( LDAP_DEBUG_TRACE, "SASL Authorize [conn=%ld]: "
                " authorization allowed\n",
                (long) (conn ? conn->c_connid : -1), 0, 0 );
 #endif
 
-
-       ch_free( authcDN.bv_val );
-       *user = authzDN.bv_val;
+       conn->c_sasl_dn = authzDN;
        *errstr = NULL;
        return SASL_OK;
 }
@@ -815,8 +989,7 @@ int slap_sasl_init( void )
 
        if( rc != SASL_OK ) {
 #ifdef NEW_LOGGING
-               LDAP_LOG(( "sasl", LDAP_LEVEL_INFO,
-                          "slap_sasl_init: init failed.\n" ));
+               LDAP_LOG( TRANSPORT, INFO, "slap_sasl_init: init failed.\n", 0, 0, 0 );
 #else
                Debug( LDAP_DEBUG_ANY, "sasl_server_init failed\n",
                        0, 0, 0 );
@@ -826,8 +999,7 @@ int slap_sasl_init( void )
        }
 
 #ifdef NEW_LOGGING
-       LDAP_LOG(( "sasl", LDAP_LEVEL_INFO,
-                  "slap_sasl_init: initialized!\n"));
+       LDAP_LOG( TRANSPORT, INFO, "slap_sasl_init: initialized!\n", 0, 0, 0 );
 #else
        Debug( LDAP_DEBUG_TRACE, "slap_sasl_init: initialized!\n",
                0, 0, 0 );
@@ -949,8 +1121,8 @@ int slap_sasl_open( Connection *conn )
 
        if( sc != SASL_OK ) {
 #ifdef NEW_LOGGING
-               LDAP_LOG(( "sasl", LDAP_LEVEL_ERR,
-                          "slap_sasl_open: sasl_server_new failed: %d\n", sc ));
+               LDAP_LOG( TRANSPORT, ERR, 
+                       "slap_sasl_open: sasl_server_new failed: %d\n", sc, 0, 0 );
 #else
                Debug( LDAP_DEBUG_ANY, "sasl_server_new failed: %d\n",
                        sc, 0, 0 );
@@ -967,8 +1139,8 @@ int slap_sasl_open( Connection *conn )
 
                if( sc != SASL_OK ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG(( "sasl", LDAP_LEVEL_ERR,
-                                  "slap_sasl_open: sasl_setprop failed: %d \n", sc ));
+                       LDAP_LOG( TRANSPORT, ERR, 
+                               "slap_sasl_open: sasl_setprop failed: %d \n", sc, 0, 0 );
 #else
                        Debug( LDAP_DEBUG_ANY, "sasl_setprop failed: %d\n",
                                sc, 0, 0 );
@@ -1062,8 +1234,8 @@ char ** slap_sasl_mechs( Connection *conn )
 
                if( sc != SASL_OK ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG(( "sasl", LDAP_LEVEL_ERR,
-                               "slap_sasl_mechs: sasl_listmech failed: %d\n", sc ));
+                       LDAP_LOG( TRANSPORT, ERR, 
+                               "slap_sasl_mechs: sasl_listmech failed: %d\n", sc, 0, 0 );
 #else
                        Debug( LDAP_DEBUG_ANY, "slap_sasl_listmech failed: %d\n",
                                sc, 0, 0 );
@@ -1120,12 +1292,12 @@ int slap_sasl_bind(
        int sc;
 
 #ifdef NEW_LOGGING
-       LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
-               "sasl_bind: conn %ld dn=\"%s\" mech=%s datalen=%ld\n",
-               conn->c_connid,
+       LDAP_LOG( TRANSPORT, ENTRY, 
+               "sasl_bind: dn=\"%s\" mech=%s datalen=%ld\n",
                dn->bv_len ? dn->bv_val : "",
-               conn->c_sasl_bind_in_progress ? "<continuing>" : conn->c_sasl_bind_mech.bv_val,
-               cred ? cred->bv_len : 0 ));
+               conn->c_sasl_bind_in_progress ? "<continuing>" : 
+               conn->c_sasl_bind_mech.bv_val,
+               cred ? cred->bv_len : 0 );
 #else
        Debug(LDAP_DEBUG_ARGS,
                "==> sasl_bind: dn=\"%s\" mech=%s datalen=%ld\n",
@@ -1169,18 +1341,11 @@ int slap_sasl_bind(
        response.bv_len = reslen;
 
        if ( sc == SASL_OK ) {
-#if SASL_VERSION_MAJOR >= 2
-               struct propctx *props = sasl_auxprop_getctx( ctx );
-               struct propval vals[3];
                sasl_ssf_t *ssf = NULL;
 
-               prop_getnames( props, slap_propnames, vals );
-
-               AC_MEMCPY( edn, vals[0].values[0], sizeof(*edn) );
-               if ( vals[1].name && vals[1].values ) {
-                       ch_free( edn->bv_val );
-                       AC_MEMCPY( edn, vals[1].values[0], sizeof(*edn) );
-               }
+               *edn = conn->c_sasl_dn;
+               conn->c_sasl_dn.bv_val = NULL;
+               conn->c_sasl_dn.bv_len = 0;
 
                rc = LDAP_SUCCESS;
 
@@ -1196,46 +1361,6 @@ int slap_sasl_bind(
                send_ldap_sasl( conn, op, rc,
                        NULL, NULL, NULL, NULL,
                        response.bv_len ? &response : NULL );
-#else
-               char *username = NULL;
-
-               sc = sasl_getprop( ctx,
-                       SASL_USERNAME, (SASL_CONST void **)&username );
-
-               if ( sc != SASL_OK ) {
-#ifdef NEW_LOGGING
-                       LDAP_LOG(( "sasl", LDAP_LEVEL_ERR,
-                               "slap_sasl_bind: getprop(USERNAME) failed: %d\n", sc ));
-#else
-                       Debug(LDAP_DEBUG_TRACE,
-                               "slap_sasl_bind: getprop(USERNAME) failed!\n",
-                               0, 0, 0);
-#endif
-
-
-                       send_ldap_result( conn, op, rc = slap_sasl_err2ldap( sc ),
-                               NULL, "no SASL username", NULL, NULL );
-
-               } else {
-                       sasl_ssf_t *ssf = NULL;
-
-                       rc = LDAP_SUCCESS;
-                       ber_str2bv( username, 0, 1, edn );
-
-                       (void) sasl_getprop( ctx, SASL_SSF, (void *)&ssf );
-                       *ssfp = ssf ? *ssf : 0;
-
-                       if( *ssfp ) {
-                               ldap_pvt_thread_mutex_lock( &conn->c_mutex );
-                               conn->c_sasl_layers++;
-                               ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
-                       }
-
-                       send_ldap_sasl( conn, op, rc,
-                               NULL, NULL, NULL, NULL,
-                               response.bv_len ? &response : NULL );
-               }
-#endif
 
        } else if ( sc == SASL_CONTINUE ) {
                send_ldap_sasl( conn, op, rc = LDAP_SASL_BIND_IN_PROGRESS,
@@ -1256,8 +1381,7 @@ int slap_sasl_bind(
 #endif
 
 #ifdef NEW_LOGGING
-       LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
-               "slap_sasl_bind: rc=%d\n", rc ));
+       LDAP_LOG( TRANSPORT, RESULTS, "slap_sasl_bind: rc=%d\n", rc, 0, 0 );
 #else
        Debug(LDAP_DEBUG_TRACE, "<== slap_sasl_bind: rc=%d\n", rc, 0, 0);
 #endif
@@ -1281,3 +1405,90 @@ char* slap_sasl_secprops( const char *in )
        return "SASL not supported";
 #endif
 }
+
+#ifdef HAVE_CYRUS_SASL
+int
+slap_sasl_setpass(
+       Connection      *conn,
+       Operation       *op,
+       const char      *reqoid,
+       struct berval   *reqdata,
+       char            **rspoid,
+       struct berval   **rspdata,
+       LDAPControl     *** rspctrls,
+       const char      **text )
+{
+       int rc;
+       struct berval id = { 0, NULL }; /* needs to come from connection */
+       struct berval new = { 0, NULL };
+       struct berval old = { 0, NULL };
+
+       assert( reqoid != NULL );
+       assert( strcmp( LDAP_EXOP_MODIFY_PASSWD, reqoid ) == 0 );
+
+       rc = sasl_getprop( conn->c_sasl_context, SASL_USERNAME,
+               (SASL_CONST void **)&id.bv_val );
+
+       if( rc != SASL_OK ) {
+               *text = "unable to retrieve SASL username";
+               rc = LDAP_OTHER;
+               goto done;
+       }
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( BACKEND, ENTRY,
+               "slap_sasl_setpass: \"%s\"\n",
+               id.bv_val ? id.bv_val : "", 0, 0);
+#else
+       Debug( LDAP_DEBUG_ARGS, "==> slap_sasl_setpass: \"%s\"\n",
+               id.bv_val ? id.bv_val : "", 0, 0 );
+#endif
+
+       rc = slap_passwd_parse( reqdata,
+               NULL, &old, &new, text );
+
+       if( rc != LDAP_SUCCESS ) {
+               goto done;
+       }
+
+       if( new.bv_len == 0 ) {
+               slap_passwd_generate(&new);
+
+               if( new.bv_len == 0 ) {
+                       *text = "password generation failed.";
+                       rc = LDAP_OTHER;
+                       goto done;
+               }
+               
+               *rspdata = slap_passwd_return( &new );
+       }
+
+#if SASL_VERSION_MAJOR < 2
+       rc = sasl_setpass( conn->c_sasl_context,
+               id.bv_val, new.bv_val, new.bv_len, 0, text );
+#else
+       rc = sasl_setpass( conn->c_sasl_context, id.bv_val,
+               new.bv_val, new.bv_len, old.bv_val, old.bv_len, 0 );
+       if( rc != SASL_OK ) {
+               *text = sasl_errdetail( conn->c_sasl_context );
+       }
+#endif
+       switch(rc) {
+               case SASL_OK:
+                       rc = LDAP_SUCCESS;
+                       break;
+
+               case SASL_NOCHANGE:
+               case SASL_NOMECH:
+               case SASL_DISABLED:
+               case SASL_PWLOCK:
+               case SASL_FAIL:
+               case SASL_BADPARAM:
+               default:
+                       rc = LDAP_OTHER;
+       }
+
+done:
+       return rc;
+}
+#endif