+ /* XXX can we do both steps at once? */
+ rc = slap_sasl_getdn( conn, (char *)username, NULL, &dn,
+ FLAG_GETDN_AUTHCID | FLAG_GETDN_FINAL );
+ if ( rc != LDAP_SUCCESS ) {
+ sasl_seterror( sconn, 0, ldap_err2string( rc ) );
+ return SASL_NOUSER;
+ }
+
+ if ( dn.bv_len == 0 ) {
+ sasl_seterror( sconn, 0,
+ "No password is associated with the Root DSE" );
+ if ( dn.bv_val != NULL ) {
+ ch_free( dn.bv_val );
+ }
+ return SASL_NOUSER;
+ }
+
+ rc = backend_attribute( NULL, NULL, NULL, NULL, &dn,
+ slap_schema.si_ad_userPassword, &vals);
+ if ( rc != LDAP_SUCCESS ) {
+ ch_free( dn.bv_val );
+ sasl_seterror( sconn, 0, ldap_err2string( rc ) );
+ return SASL_NOVERIFY;
+ }
+
+ rc = SASL_NOVERIFY;
+
+ if ( vals != NULL ) {
+ for ( bv = vals; bv->bv_val != NULL; bv++ ) {
+ if ( !lutil_passwd( bv, &cred, NULL ) ) {
+ rc = SASL_OK;
+ break;
+ }
+ }
+ ber_bvarray_free( vals );
+ }
+
+ if ( rc != SASL_OK ) {
+ sasl_seterror( sconn, 0,
+ ldap_err2string( LDAP_INVALID_CREDENTIALS ) );
+ }
+
+ ch_free( dn.bv_val );
+
+ return rc;
+}
+
+static int
+slap_sasl_canonicalize(
+ sasl_conn_t *sconn,
+ void *context,
+ const char *in,
+ unsigned inlen,
+ unsigned flags,
+ const char *user_realm,
+ char *out,
+ unsigned out_max,
+ unsigned *out_len)
+{
+ Connection *conn = (Connection *)context;
+ struct berval dn;
+ int rc;
+
+ *out_len = 0;
+
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
+ "slap_sasl_canonicalize: conn %d %s=\"%s\"\n",
+ 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",
+ conn ? conn->c_connid : -1,
+ (flags == SASL_CU_AUTHID) ? "authcid" : "authzid",
+ in ? in : "<empty>" );
+#endif
+
+ rc = slap_sasl_getdn( conn, (char *)in, (char *)user_realm, &dn,
+ (flags == SASL_CU_AUTHID) ? FLAG_GETDN_AUTHCID : FLAG_GETDN_AUTHZID );
+ if ( rc != LDAP_SUCCESS ) {
+ sasl_seterror( sconn, 0, ldap_err2string( rc ) );
+ return SASL_NOAUTHZ;
+ }
+
+ if ( out_max < dn.bv_len ) {
+ return SASL_BUFOVER;
+ }
+
+ AC_MEMCPY( out, dn.bv_val, dn.bv_len );
+ out[dn.bv_len] = '\0';
+
+ *out_len = dn.bv_len;
+
+ ch_free( dn.bv_val );
+
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
+ "slap_sasl_canonicalize: conn %d %s=\"%s\"\n",
+ conn ? conn->c_connid : -1,
+ (flags == SASL_CU_AUTHID) ? "authcDN" : "authzDN",
+ out ));
+#else
+ Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: "
+ "%s=\"%s\"\n",
+ conn ? conn->c_connid : -1,
+ (flags == SASL_CU_AUTHID) ? "authcDN" : "authzDN",
+ out );
+#endif
+
+ return SASL_OK;
+}