+ if ( op.o_bd ) {
+ /* For rootdn, see if we can use the rootpw */
+ if ( be_isroot_dn( op.o_bd, &op.o_req_ndn ) &&
+ !BER_BVISEMPTY( &op.o_bd->be_rootpw )) {
+ struct berval cbv = BER_BVNULL;
+
+ /* If there's a recognized scheme, see if it's CLEARTEXT */
+ if ( lutil_passwd_scheme( op.o_bd->be_rootpw.bv_val )) {
+ if ( !strncasecmp( op.o_bd->be_rootpw.bv_val,
+ sc_cleartext.bv_val, sc_cleartext.bv_len )) {
+
+ /* If it's CLEARTEXT, skip past scheme spec */
+ cbv.bv_len = op.o_bd->be_rootpw.bv_len -
+ sc_cleartext.bv_len;
+ if ( cbv.bv_len ) {
+ cbv.bv_val = op.o_bd->be_rootpw.bv_val +
+ sc_cleartext.bv_len;
+ }
+ }
+ /* No scheme, use the whole value */
+ } else {
+ cbv = op.o_bd->be_rootpw;
+ }
+ if ( !BER_BVISEMPTY( &cbv )) {
+ for( i = 0; sl.list[i].name; i++ ) {
+ const char *name = sl.list[i].name;
+
+ if ( name[0] == '*' ) {
+ if ( flags & SASL_AUXPROP_AUTHZID ) continue;
+ name++;
+ } else if ( !(flags & SASL_AUXPROP_AUTHZID ) )
+ continue;
+
+ if ( !strcasecmp(name,"userPassword") ) {
+ sl.sparams->utils->prop_set( sl.sparams->propctx,
+ sl.list[i].name, cbv.bv_val, cbv.bv_len );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( op.o_bd->be_search ) {
+ SlapReply rs = {REP_RESULT};
+ op.o_hdr = conn->c_sasl_bindop->o_hdr;
+ op.o_tag = LDAP_REQ_SEARCH;
+ op.o_ndn = conn->c_ndn;
+ op.o_callback = &cb;
+ slap_op_time( &op.o_time, &op.o_tincr );
+ op.o_do_not_cache = 1;
+ op.o_is_auth_check = 1;
+ op.o_req_dn = op.o_req_ndn;
+ op.ors_scope = LDAP_SCOPE_BASE;
+ op.ors_deref = LDAP_DEREF_NEVER;
+ op.ors_tlimit = SLAP_NO_LIMIT;
+ op.ors_slimit = 1;
+ op.ors_filter = &generic_filter;
+ op.ors_filterstr = generic_filterstr;
+ /* FIXME: we want all attributes, right? */
+ op.ors_attrs = NULL;
+
+ op.o_bd->be_search( &op, &rs );
+ }
+ }
+ }
+}
+
+#if SASL_VERSION_FULL >= 0x020110
+static int
+slap_auxprop_store(
+ void *glob_context,
+ sasl_server_params_t *sparams,
+ struct propctx *prctx,
+ const char *user,
+ unsigned ulen)
+{
+ Operation op = {0};
+ SlapReply rs = {REP_RESULT};
+ int rc, i, j;
+ Connection *conn = NULL;
+ const struct propval *pr;
+ Modifications *modlist = NULL, **modtail = &modlist, *mod;
+ slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
+ char textbuf[SLAP_TEXT_BUFLEN];
+ const char *text;
+ size_t textlen = sizeof(textbuf);
+
+ /* just checking if we are enabled */
+ if (!prctx) return SASL_OK;
+
+ if (!sparams || !user) return SASL_BADPARAM;
+
+ pr = sparams->utils->prop_get( sparams->propctx );
+
+ /* Find our DN and conn first */
+ for( i = 0; pr[i].name; i++ ) {
+ if ( pr[i].name[0] == '*' ) {
+ if ( !strcmp( pr[i].name, slap_propnames[SLAP_SASL_PROP_CONN] ) ) {
+ if ( pr[i].values && pr[i].values[0] )
+ AC_MEMCPY( &conn, pr[i].values[0], sizeof( conn ) );
+ continue;
+ }
+ if ( !strcmp( pr[i].name, slap_propnames[SLAP_SASL_PROP_AUTHC] ) ) {
+ if ( pr[i].values && pr[i].values[0] ) {
+ AC_MEMCPY( &op.o_req_ndn, pr[i].values[0], sizeof( struct berval ) );
+ }
+ }
+ }
+ }
+ if (!conn || !op.o_req_ndn.bv_val) return SASL_BADPARAM;
+
+ op.o_bd = select_backend( &op.o_req_ndn, 0, 1 );
+
+ if ( !op.o_bd || !op.o_bd->be_modify ) return SASL_FAIL;
+
+ pr = sparams->utils->prop_get( prctx );
+ if (!pr) return SASL_BADPARAM;
+
+ for (i=0; pr[i].name; i++);
+ if (!i) return SASL_BADPARAM;
+
+ for (i=0; pr[i].name; i++) {
+ mod = (Modifications *)ch_malloc( sizeof(Modifications) );
+ mod->sml_op = LDAP_MOD_REPLACE;
+ mod->sml_flags = 0;
+ ber_str2bv( pr[i].name, 0, 0, &mod->sml_type );
+ mod->sml_values = (struct berval *)ch_malloc( (pr[i].nvalues + 1) *
+ sizeof(struct berval));
+ for (j=0; j<pr[i].nvalues; j++) {
+ ber_str2bv( pr[i].values[j], 0, 1, &mod->sml_values[j]);
+ }
+ BER_BVZERO( &mod->sml_values[j] );
+ mod->sml_nvalues = NULL;
+ mod->sml_desc = NULL;
+ *modtail = mod;
+ modtail = &mod->sml_next;
+ }
+ *modtail = NULL;
+
+ rc = slap_mods_check( modlist, &text, textbuf, textlen, NULL );
+
+ if ( rc == LDAP_SUCCESS ) {
+ rc = slap_mods_no_user_mod_check( &op, modlist,
+ &text, textbuf, textlen );
+
+ if ( rc == LDAP_SUCCESS ) {
+ op.o_hdr = conn->c_sasl_bindop->o_hdr;
+ op.o_tag = LDAP_REQ_MODIFY;
+ op.o_ndn = op.o_req_ndn;