static void asyncmeta_search_last_result(a_metaconn_t *mc, bm_context_t *bc, int candidate, int sres) { a_metainfo_t *mi = mc->mc_info; Operation *op = bc->op; SlapReply *rs = &bc->rs; int i; SlapReply *candidates = bc->candidates; char *matched = NULL; if ( bc->candidate_match > 0 ) { struct berval pmatched = BER_BVNULL; /* we use the first one */ for ( i = 0; i < mi->mi_ntargets; i++ ) { if ( META_IS_CANDIDATE( &candidates[ i ] ) && candidates[ i ].sr_matched != NULL ) { struct berval bv, pbv; int rc; /* if we got success, and this target * returned noSuchObject, and its suffix * is a superior of the searchBase, * ignore the matchedDN */ if ( sres == LDAP_SUCCESS && candidates[ i ].sr_err == LDAP_NO_SUCH_OBJECT && op->o_req_ndn.bv_len > mi->mi_targets[ i ]->mt_nsuffix.bv_len ) { free( (char *)candidates[ i ].sr_matched ); candidates[ i ].sr_matched = NULL; continue; } ber_str2bv( candidates[ i ].sr_matched, 0, 0, &bv ); rc = dnPretty( NULL, &bv, &pbv, op->o_tmpmemctx ); if ( rc == LDAP_SUCCESS ) { /* NOTE: if they all are superiors * of the baseDN, the shorter is also * superior of the longer... */ if ( pbv.bv_len > pmatched.bv_len ) { if ( !BER_BVISNULL( &pmatched ) ) { op->o_tmpfree( pmatched.bv_val, op->o_tmpmemctx ); } pmatched = pbv; } else { op->o_tmpfree( pbv.bv_val, op->o_tmpmemctx ); } } if ( candidates[ i ].sr_matched != NULL ) { free( (char *)candidates[ i ].sr_matched ); candidates[ i ].sr_matched = NULL; } } } if ( !BER_BVISNULL( &pmatched ) ) { matched = pmatched.bv_val; } } else if ( sres == LDAP_NO_SUCH_OBJECT ) { matched = mi->mi_suffix.bv_val; } /* * In case we returned at least one entry, we return LDAP_SUCCESS * otherwise, the latter error code we got */ if ( sres == LDAP_SUCCESS ) { if ( rs->sr_v2ref ) { sres = LDAP_REFERRAL; } if ( META_BACK_ONERR_REPORT( mi ) ) { /* * Report errors, if any * * FIXME: we should handle error codes and return the more * important/reasonable */ for ( i = 0; i < mi->mi_ntargets; i++ ) { if ( !META_IS_CANDIDATE( &candidates[ i ] ) ) { continue; } if ( candidates[ i ].sr_err != LDAP_SUCCESS && candidates[ i ].sr_err != LDAP_NO_SUCH_OBJECT ) { sres = candidates[ i ].sr_err; break; } } } } Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_search_last_result(\"%d\"): " ".\n", op->o_log_prefix, candidate ); rs->sr_err = sres; rs->sr_matched = ( sres == LDAP_SUCCESS ? NULL : matched ); rs->sr_text = ( sres == LDAP_SUCCESS ? NULL : candidates[candidate].sr_text ); rs->sr_ref = ( sres == LDAP_REFERRAL ? rs->sr_v2ref : NULL ); asyncmeta_send_ldap_result(bc, op, rs); rs->sr_text = NULL; rs->sr_matched = NULL; rs->sr_ref = NULL; }
static int vernum_repair( BackendDB *be ) { slap_overinst *on = (slap_overinst *)be->bd_info; vernum_t *vn = (vernum_t *)on->on_bi.bi_private; void *ctx = ldap_pvt_thread_pool_context(); Connection conn = { 0 }; OperationBuffer opbuf; Operation *op; BackendDB db; slap_callback sc = { 0 }; vernum_repair_cb_t rcb = { 0 }; SlapReply rs = { REP_RESULT }; vernum_mod_t *rmod; int nrepaired = 0; connection_fake_init2( &conn, &opbuf, ctx, 0 ); op = &opbuf.ob_op; op->o_tag = LDAP_REQ_SEARCH; memset( &op->oq_search, 0, sizeof( op->oq_search ) ); assert( !BER_BVISNULL( &be->be_nsuffix[ 0 ] ) ); op->o_bd = select_backend( &be->be_nsuffix[ 0 ], 0 ); assert( op->o_bd != NULL ); assert( op->o_bd->be_nsuffix != NULL ); op->o_req_dn = op->o_bd->be_suffix[ 0 ]; op->o_req_ndn = op->o_bd->be_nsuffix[ 0 ]; op->o_dn = op->o_bd->be_rootdn; op->o_ndn = op->o_bd->be_rootndn; op->ors_scope = LDAP_SCOPE_SUBTREE; op->ors_tlimit = SLAP_NO_LIMIT; op->ors_slimit = SLAP_NO_LIMIT; op->ors_attrs = slap_anlist_no_attrs; op->ors_filterstr.bv_len = STRLENOF( "(&(=*)(!(=*)))" ) + vn->vn_attr->ad_cname.bv_len + vn->vn_vernum->ad_cname.bv_len; op->ors_filterstr.bv_val = op->o_tmpalloc( op->ors_filterstr.bv_len + 1, op->o_tmpmemctx ); snprintf( op->ors_filterstr.bv_val, op->ors_filterstr.bv_len + 1, "(&(%s=*)(!(%s=*)))", vn->vn_attr->ad_cname.bv_val, vn->vn_vernum->ad_cname.bv_val ); op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val ); if ( op->ors_filter == NULL ) { rs.sr_err = LDAP_OTHER; goto done_search; } op->o_callback = ≻ sc.sc_response = vernum_repair_cb; sc.sc_private = &rcb; rcb.bd = &db; db = *be; db.bd_info = (BackendInfo *)on; (void)op->o_bd->bd_info->bi_op_search( op, &rs ); op->o_tag = LDAP_REQ_MODIFY; sc.sc_response = slap_null_cb; sc.sc_private = NULL; memset( &op->oq_modify, 0, sizeof( req_modify_s ) ); for ( rmod = rcb.mods; rmod != NULL; ) { vernum_mod_t *rnext; Modifications mod; struct berval vals[2] = { BER_BVNULL }; SlapReply rs2 = { REP_RESULT }; mod.sml_flags = SLAP_MOD_INTERNAL; mod.sml_op = LDAP_MOD_REPLACE; mod.sml_desc = vn->vn_vernum; mod.sml_type = vn->vn_vernum->ad_cname; mod.sml_values = vals; mod.sml_values[0] = val_init; mod.sml_nvalues = NULL; mod.sml_numvals = 1; mod.sml_next = NULL; op->o_req_dn = rmod->ndn; op->o_req_ndn = rmod->ndn; op->orm_modlist = &mod; op->o_bd->be_modify( op, &rs2 ); slap_mods_free( op->orm_modlist->sml_next, 1 ); if ( rs2.sr_err == LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "%s: vernum_repair: entry DN=\"%s\" repaired\n", op->o_log_prefix, rmod->ndn.bv_val, 0 ); nrepaired++; } else { Debug( LDAP_DEBUG_ANY, "%s: vernum_repair: entry DN=\"%s\" repair failed (%d)\n", op->o_log_prefix, rmod->ndn.bv_val, rs2.sr_err ); } rnext = rmod->next; op->o_tmpfree( rmod, op->o_tmpmemctx ); rmod = rnext; } done_search:; op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx ); filter_free_x( op, op->ors_filter, 1 ); Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO, "vernum: repaired=%d\n", nrepaired ); return 0; }
void slapi_int_connection_done_pb( Slapi_PBlock *pb ) { Connection *conn; Operation *op; PBLOCK_ASSERT_INTOP( pb, 0 ); conn = pb->pb_conn; op = pb->pb_op; /* free allocated DNs */ if ( !BER_BVISNULL( &op->o_dn ) ) op->o_tmpfree( op->o_dn.bv_val, op->o_tmpmemctx ); if ( !BER_BVISNULL( &op->o_ndn ) ) op->o_tmpfree( op->o_ndn.bv_val, op->o_tmpmemctx ); if ( !BER_BVISNULL( &op->o_req_dn ) ) op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); if ( !BER_BVISNULL( &op->o_req_ndn ) ) op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); switch ( op->o_tag ) { case LDAP_REQ_MODRDN: if ( !BER_BVISNULL( &op->orr_newrdn )) op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx ); if ( !BER_BVISNULL( &op->orr_nnewrdn )) op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx ); if ( op->orr_newSup != NULL ) { assert( !BER_BVISNULL( op->orr_newSup ) ); op->o_tmpfree( op->orr_newSup->bv_val, op->o_tmpmemctx ); op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx ); } if ( op->orr_nnewSup != NULL ) { assert( !BER_BVISNULL( op->orr_nnewSup ) ); op->o_tmpfree( op->orr_nnewSup->bv_val, op->o_tmpmemctx ); op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx ); } slap_mods_free( op->orr_modlist, 1 ); break; case LDAP_REQ_ADD: slap_mods_free( op->ora_modlist, 0 ); break; case LDAP_REQ_MODIFY: slap_mods_free( op->orm_modlist, 1 ); break; case LDAP_REQ_SEARCH: if ( op->ors_attrs != NULL ) { op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx ); op->ors_attrs = NULL; } break; default: break; } slapi_ch_free_string( &conn->c_authmech.bv_val ); slapi_ch_free_string( &conn->c_dn.bv_val ); slapi_ch_free_string( &conn->c_ndn.bv_val ); slapi_ch_free_string( &conn->c_peer_domain.bv_val ); slapi_ch_free_string( &conn->c_peer_name.bv_val ); if ( conn->c_sb != NULL ) { ber_sockbuf_free( conn->c_sb ); } slapi_int_free_object_extensions( SLAPI_X_EXT_OPERATION, op ); slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION, conn ); slapi_ch_free( (void **)&pb->pb_op->o_callback ); slapi_ch_free( (void **)&pb->pb_op ); slapi_ch_free( (void **)&pb->pb_conn ); slapi_ch_free( (void **)&pb->pb_rs ); }
int asyncmeta_handle_common_result(LDAPMessage *msg, a_metaconn_t *mc, bm_context_t *bc, int candidate) { a_metainfo_t *mi; a_metatarget_t *mt; a_metasingleconn_t *msc; const char *save_text = NULL, *save_matched = NULL; BerVarray save_ref = NULL; LDAPControl **save_ctrls = NULL; void *matched_ctx = NULL; char *matched = NULL; char *text = NULL; char **refs = NULL; LDAPControl **ctrls = NULL; Operation *op; SlapReply *rs; int rc; mi = mc->mc_info; mt = mi->mi_targets[ candidate ]; msc = &mc->mc_conns[ candidate ]; op = bc->op; rs = &bc->rs; save_text = rs->sr_text, save_matched = rs->sr_matched; save_ref = rs->sr_ref; save_ctrls = rs->sr_ctrls; rs->sr_text = NULL; rs->sr_matched = NULL; rs->sr_ref = NULL; rs->sr_ctrls = NULL; /* only touch when activity actually took place... */ if ( mi->mi_idle_timeout != 0 ) { asyncmeta_set_msc_time(msc); } rc = ldap_parse_result( msc->msc_ldr, msg, &rs->sr_err, &matched, &text, &refs, &ctrls, 0 ); if ( rc == LDAP_SUCCESS ) { rs->sr_text = text; } else { rs->sr_err = rc; } rs->sr_err = slap_map_api2result( rs ); /* RFC 4511: referrals can only appear * if result code is LDAP_REFERRAL */ if ( refs != NULL && refs[ 0 ] != NULL && refs[ 0 ][ 0 ] != '\0' ) { if ( rs->sr_err != LDAP_REFERRAL ) { Debug( LDAP_DEBUG_ANY, "%s asyncmeta_handle_common_result[%d]: " "got referrals with err=%d\n", op->o_log_prefix, candidate, rs->sr_err ); } else { int i; for ( i = 0; refs[ i ] != NULL; i++ ) /* count */ ; rs->sr_ref = op->o_tmpalloc( sizeof( struct berval ) * ( i + 1 ), op->o_tmpmemctx ); for ( i = 0; refs[ i ] != NULL; i++ ) { ber_str2bv( refs[ i ], 0, 0, &rs->sr_ref[ i ] ); } BER_BVZERO( &rs->sr_ref[ i ] ); } } else if ( rs->sr_err == LDAP_REFERRAL ) { Debug( LDAP_DEBUG_ANY, "%s asyncmeta_handle_common_result[%d]: " "got err=%d with null " "or empty referrals\n", op->o_log_prefix, candidate, rs->sr_err ); rs->sr_err = LDAP_NO_SUCH_OBJECT; } if ( ctrls != NULL ) { rs->sr_ctrls = ctrls; } /* if the error in the reply structure is not * LDAP_SUCCESS, try to map it from client * to server error */ if ( !LDAP_ERR_OK( rs->sr_err ) ) { rs->sr_err = slap_map_api2result( rs ); /* internal ops ( op->o_conn == NULL ) * must not reply to client */ if ( op->o_conn && !op->o_do_not_cache && matched ) { /* record the (massaged) matched * DN into the reply structure */ rs->sr_matched = matched; } } if ( META_BACK_TGT_QUARANTINE( mt ) ) { asyncmeta_quarantine( op, mi, rs, candidate ); } if ( matched != NULL ) { struct berval dn, pdn; ber_str2bv( matched, 0, 0, &dn ); if ( dnPretty( NULL, &dn, &pdn, op->o_tmpmemctx ) == LDAP_SUCCESS ) { ldap_memfree( matched ); matched_ctx = op->o_tmpmemctx; matched = pdn.bv_val; } rs->sr_matched = matched; } if ( rs->sr_err == LDAP_UNAVAILABLE || rs->sr_err == LDAP_SERVER_DOWN ) { if ( rs->sr_text == NULL ) { rs->sr_text = "Target is unavailable"; } } ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); asyncmeta_drop_bc( mc, bc); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); if ( op->o_conn ) { asyncmeta_send_ldap_result(bc, op, rs); } if ( matched ) { op->o_tmpfree( (char *)rs->sr_matched, matched_ctx ); } if ( text ) { ldap_memfree( text ); } if ( rs->sr_ref ) { op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx ); rs->sr_ref = NULL; } if ( refs ) { ber_memvfree( (void **)refs ); } if ( ctrls ) { assert( rs->sr_ctrls != NULL ); ldap_controls_free( ctrls ); } rs->sr_text = save_text; rs->sr_matched = save_matched; rs->sr_ref = save_ref; rs->sr_ctrls = save_ctrls; rc = (LDAP_ERR_OK( rs->sr_err ) ? LDAP_SUCCESS : rs->sr_err); ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); asyncmeta_clear_bm_context(bc); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); return rc; }
int slapauth( int argc, char **argv ) { int rc = EXIT_SUCCESS; const char *progname = "slapauth"; Connection conn = {0}; OperationBuffer opbuf; Operation *op; slap_tool_init( progname, SLAPAUTH, argc, argv ); argv = &argv[ optind ]; argc -= optind; connection_fake_init( &conn, &opbuf, &conn ); op = &opbuf.ob_op; conn.c_sasl_bind_mech = mech; if ( !BER_BVISNULL( &authzID ) ) { struct berval authzdn; rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn, SLAP_GETDN_AUTHZID ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "authzID: <%s> check failed %d (%s)\n", authzID.bv_val, rc, ldap_err2string( rc ) ); rc = 1; BER_BVZERO( &authzID ); goto destroy; } authzID = authzdn; } if ( !BER_BVISNULL( &authcID ) ) { if ( !BER_BVISNULL( &authzID ) || argc == 0 ) { rc = do_check( &conn, op, &authcID ); goto destroy; } for ( ; argc--; argv++ ) { struct berval authzdn; ber_str2bv( argv[ 0 ], 0, 0, &authzID ); rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn, SLAP_GETDN_AUTHZID ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "authzID: <%s> check failed %d (%s)\n", authzID.bv_val, rc, ldap_err2string( rc ) ); rc = -1; BER_BVZERO( &authzID ); if ( !continuemode ) { goto destroy; } } authzID = authzdn; rc = do_check( &conn, op, &authcID ); op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx ); BER_BVZERO( &authzID ); if ( rc && !continuemode ) { goto destroy; } } goto destroy; } for ( ; argc--; argv++ ) { struct berval id; ber_str2bv( argv[ 0 ], 0, 0, &id ); rc = do_check( &conn, op, &id ); if ( rc && !continuemode ) { goto destroy; } } destroy: ; if ( !BER_BVISNULL( &authzID ) ) { op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx ); } if ( slap_tool_destroy()) rc = EXIT_FAILURE; return rc; }
static int autoca_db_open( BackendDB *be, ConfigReply *cr ) { slap_overinst *on = (slap_overinst *)be->bd_info; autoca_info *ai = on->on_bi.bi_private; Connection conn = { 0 }; OperationBuffer opbuf; Operation *op; void *thrctx; Entry *e; Attribute *a; int rc; if (slapMode & SLAP_TOOL_MODE) return 0; if ( ! *aca_attr2[0].ad ) { int i, code; const char *text; for ( i=0; aca_attr2[i].at; i++ ) { code = slap_str2ad( aca_attr2[i].at, aca_attr2[i].ad, &text ); if ( code ) return code; } /* Schema may not be loaded, ignore if missing */ slap_str2ad( "ipHostNumber", &ad_ipaddr, &text ); for ( i=0; aca_ocs[i].ot; i++ ) { code = register_oc( aca_ocs[i].ot, aca_ocs[i].oc, 0 ); if ( code ) return code; } } thrctx = ldap_pvt_thread_pool_context(); connection_fake_init2( &conn, &opbuf, thrctx, 0 ); op = &opbuf.ob_op; op->o_bd = be; op->o_dn = be->be_rootdn; op->o_ndn = be->be_rootndn; rc = overlay_entry_get_ov( op, be->be_nsuffix, NULL, NULL, 0, &e, on ); if ( e ) { int gotoc = 0, gotat = 0; if ( is_entry_objectclass( e, oc_caObj, 0 )) { gotoc = 1; a = attr_find( e->e_attrs, ad_caPkey ); if ( a ) { const unsigned char *pp; pp = (unsigned char *)a->a_vals[0].bv_val; ai->ai_pkey = d2i_AutoPrivateKey( NULL, &pp, a->a_vals[0].bv_len ); if ( ai->ai_pkey ) { a = attr_find( e->e_attrs, ad_caCert ); if ( a ) { pp = (unsigned char *)a->a_vals[0].bv_val; ai->ai_cert = d2i_X509( NULL, &pp, a->a_vals[0].bv_len ); /* If TLS wasn't configured yet, set this as our CA */ if ( !slap_tls_ctx ) autoca_setca( a->a_vals ); } } gotat = 1; } } overlay_entry_release_ov( op, e, 0, on ); /* generate attrs, store... */ if ( !gotat ) { genargs args; saveargs arg2; args.issuer_cert = NULL; args.issuer_pkey = NULL; args.subjectDN = &be->be_suffix[0]; args.cert_exts = CAexts; args.more_exts = NULL; args.keybits = ai->ai_cakeybits; args.days = ai->ai_cadays; rc = autoca_gencert( op, &args ); if ( rc ) return -1; ai->ai_cert = args.newcert; ai->ai_pkey = args.newpkey; arg2.dn = be->be_suffix; arg2.ndn = be->be_nsuffix; arg2.isca = 1; if ( !gotoc ) arg2.oc = oc_caObj; else arg2.oc = NULL; arg2.on = on; arg2.dercert = &args.dercert; arg2.derpkey = &args.derpkey; autoca_savecert( op, &arg2 ); /* If TLS wasn't configured yet, set this as our CA */ if ( !slap_tls_ctx ) autoca_setca( &args.dercert ); op->o_tmpfree( args.dercert.bv_val, op->o_tmpmemctx ); op->o_tmpfree( args.derpkey.bv_val, op->o_tmpmemctx ); } } return 0; }
/* ** Do a search for all the groups in the ** database, and add them to out internal list. */ static int autogroup_db_open( BackendDB *be, ConfigReply *cr ) { slap_overinst *on = (slap_overinst *) be->bd_info; autogroup_info_t *agi = on->on_bi.bi_private; autogroup_def_t *agd; autogroup_sc_t ags; Operation *op; SlapReply rs = { REP_RESULT }; slap_callback cb = { 0 }; void *thrctx = ldap_pvt_thread_pool_context(); Connection conn = { 0 }; OperationBuffer opbuf; Debug( LDAP_DEBUG_TRACE, "==> autogroup_db_open\n", 0, 0, 0); if ( agi == NULL ) { return 0; } connection_fake_init( &conn, &opbuf, thrctx ); op = &opbuf.ob_op; op->ors_attrsonly = 0; op->o_tag = LDAP_REQ_SEARCH; op->o_dn = be->be_rootdn; op->o_ndn = be->be_rootndn; op->o_req_dn = be->be_suffix[0]; op->o_req_ndn = be->be_nsuffix[0]; op->ors_scope = LDAP_SCOPE_SUBTREE; op->ors_deref = LDAP_DEREF_NEVER; op->ors_limit = NULL; op->ors_tlimit = SLAP_NO_LIMIT; op->ors_slimit = SLAP_NO_LIMIT; op->ors_attrs = slap_anlist_no_attrs; op->o_bd = be; op->o_bd->bd_info = (BackendInfo *)on->on_info; ags.ags_info = agi; cb.sc_private = &ags; cb.sc_response = autogroup_group_add_cb; cb.sc_cleanup = NULL; cb.sc_next = NULL; op->o_callback = &cb; for (agd = agi->agi_def ; agd ; agd = agd->agd_next) { autogroup_build_def_filter(agd, op); ags.ags_def = agd; op->o_bd->be_search( op, &rs ); filter_free_x( op, op->ors_filter, 1 ); op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx ); } return 0; }
static int pguid_repair( BackendDB *be ) { slap_overinst *on = (slap_overinst *)be->bd_info; void *ctx = ldap_pvt_thread_pool_context(); Connection conn = { 0 }; OperationBuffer opbuf; Operation *op; slap_callback sc = { 0 }; pguid_repair_cb_t pcb = { 0 }; SlapReply rs = { REP_RESULT }; pguid_mod_t *pmod; int nrepaired = 0; connection_fake_init2( &conn, &opbuf, ctx, 0 ); op = &opbuf.ob_op; op->o_tag = LDAP_REQ_SEARCH; memset( &op->oq_search, 0, sizeof( op->oq_search ) ); op->o_bd = select_backend( &be->be_nsuffix[ 0 ], 0 ); op->o_req_dn = op->o_bd->be_suffix[ 0 ]; op->o_req_ndn = op->o_bd->be_nsuffix[ 0 ]; op->o_dn = op->o_bd->be_rootdn; op->o_ndn = op->o_bd->be_rootndn; op->ors_scope = LDAP_SCOPE_SUBORDINATE; op->ors_tlimit = SLAP_NO_LIMIT; op->ors_slimit = SLAP_NO_LIMIT; op->ors_attrs = slap_anlist_no_attrs; op->ors_filterstr.bv_len = STRLENOF( "(!(=*))" ) + ad_parentUUID->ad_cname.bv_len; op->ors_filterstr.bv_val = op->o_tmpalloc( op->ors_filterstr.bv_len + 1, op->o_tmpmemctx ); snprintf( op->ors_filterstr.bv_val, op->ors_filterstr.bv_len + 1, "(!(%s=*))", ad_parentUUID->ad_cname.bv_val ); op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val ); if ( op->ors_filter == NULL ) { rs.sr_err = LDAP_OTHER; goto done_search; } op->o_callback = ≻ sc.sc_response = pguid_repair_cb; sc.sc_private = &pcb; pcb.on = on; (void)op->o_bd->bd_info->bi_op_search( op, &rs ); op->o_tag = LDAP_REQ_MODIFY; sc.sc_response = slap_null_cb; sc.sc_private = NULL; memset( &op->oq_modify, 0, sizeof( req_modify_s ) ); for ( pmod = pcb.mods; pmod != NULL; ) { pguid_mod_t *pnext; Modifications *mod; SlapReply rs2 = { REP_RESULT }; mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); mod->sml_flags = SLAP_MOD_INTERNAL; mod->sml_op = LDAP_MOD_REPLACE; mod->sml_desc = ad_parentUUID; mod->sml_type = ad_parentUUID->ad_cname; mod->sml_values = ch_malloc( sizeof( struct berval ) * 2 ); mod->sml_nvalues = NULL; mod->sml_numvals = 1; mod->sml_next = NULL; ber_dupbv( &mod->sml_values[0], &pmod->pguid ); BER_BVZERO( &mod->sml_values[1] ); op->o_req_dn = pmod->ndn; op->o_req_ndn = pmod->ndn; op->orm_modlist = mod; op->o_bd->be_modify( op, &rs2 ); slap_mods_free( op->orm_modlist, 1 ); if ( rs2.sr_err == LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "%s: pguid_repair: entry DN=\"%s\" repaired\n", op->o_log_prefix, pmod->ndn.bv_val, 0 ); nrepaired++; } else { Debug( LDAP_DEBUG_ANY, "%s: pguid_repair: entry DN=\"%s\" repair failed (%d)\n", op->o_log_prefix, pmod->ndn.bv_val, rs2.sr_err ); } pnext = pmod->next; op->o_tmpfree( pmod, op->o_tmpmemctx ); pmod = pnext; } done_search:; op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx ); filter_free_x( op, op->ors_filter, 1 ); Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO, "pguid: repaired=%d\n", nrepaired ); return rs.sr_err; }
static int #else static void #endif slap_auxprop_lookup( void *glob_context, sasl_server_params_t *sparams, unsigned flags, const char *user, unsigned ulen) { OperationBuffer opbuf = {{ NULL }}; Operation *op = (Operation *)&opbuf; int i, doit = 0; Connection *conn = NULL; lookup_info sl; int rc = LDAP_SUCCESS; #ifdef SLAP_AUXPROP_DONTUSECOPY int dontUseCopy = 0; BackendDB *dontUseCopy_bd = NULL; #endif /* SLAP_AUXPROP_DONTUSECOPY */ sl.list = sparams->utils->prop_get( sparams->propctx ); sl.sparams = sparams; sl.flags = flags; /* Find our DN and conn first */ for( i = 0; sl.list[i].name; i++ ) { if ( sl.list[i].name[0] == '*' ) { if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_CONN] ) ) { if ( sl.list[i].values && sl.list[i].values[0] ) AC_MEMCPY( &conn, sl.list[i].values[0], sizeof( conn ) ); continue; } if ( flags & SASL_AUXPROP_AUTHZID ) { if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHZLEN] )) { if ( sl.list[i].values && sl.list[i].values[0] ) AC_MEMCPY( &op->o_req_ndn.bv_len, sl.list[i].values[0], sizeof( op->o_req_ndn.bv_len ) ); } else if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHZ] )) { if ( sl.list[i].values ) op->o_req_ndn.bv_val = (char *)sl.list[i].values[0]; break; } } if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHCLEN] )) { if ( sl.list[i].values && sl.list[i].values[0] ) AC_MEMCPY( &op->o_req_ndn.bv_len, sl.list[i].values[0], sizeof( op->o_req_ndn.bv_len ) ); } else if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHC] ) ) { if ( sl.list[i].values ) { op->o_req_ndn.bv_val = (char *)sl.list[i].values[0]; if ( !(flags & SASL_AUXPROP_AUTHZID) ) break; } } #ifdef SLAP_AUXPROP_DONTUSECOPY if ( slap_dontUseCopy_propnames != NULL ) { int j; struct berval bv; ber_str2bv( &sl.list[i].name[1], 0, 1, &bv ); for ( j = 0; !BER_BVISNULL( &slap_dontUseCopy_propnames[ j ]); j++ ) { if ( bvmatch( &bv, &slap_dontUseCopy_propnames[ j ] ) ) { dontUseCopy = 1; break; } } } #endif /* SLAP_AUXPROP_DONTUSECOPY */ } } /* Now see what else needs to be fetched */ for( i = 0; sl.list[i].name; i++ ) { const char *name = sl.list[i].name; if ( name[0] == '*' ) { if ( flags & SASL_AUXPROP_AUTHZID ) continue; /* Skip our private properties */ if ( !strcmp( name, slap_propnames[0] )) { i += SLAP_SASL_PROP_COUNT - 1; continue; } name++; } else if ( !(flags & SASL_AUXPROP_AUTHZID ) ) continue; if ( sl.list[i].values ) { if ( !(flags & SASL_AUXPROP_OVERRIDE) ) continue; } doit = 1; break; } if (doit) { slap_callback cb = { NULL, sasl_ap_lookup, NULL, NULL }; cb.sc_private = &sl; op->o_bd = select_backend( &op->o_req_ndn, 1 ); 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; } } } } #ifdef SLAP_AUXPROP_DONTUSECOPY if ( SLAP_SHADOW( op->o_bd ) && dontUseCopy ) { dontUseCopy_bd = op->o_bd; op->o_bd = frontendDB; } retry_dontUseCopy:; #endif /* SLAP_AUXPROP_DONTUSECOPY */ if ( op->o_bd->be_search ) { SlapReply rs = {REP_RESULT}; #ifdef SLAP_AUXPROP_DONTUSECOPY LDAPControl **save_ctrls = NULL, c; int save_dontUseCopy; #endif /* SLAP_AUXPROP_DONTUSECOPY */ op->o_hdr = conn->c_sasl_bindop->o_hdr; op->o_controls = opbuf.ob_controls; op->o_tag = LDAP_REQ_SEARCH; op->o_dn = conn->c_ndn; 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; op->o_authz = conn->c_authz; /* FIXME: we want all attributes, right? */ op->ors_attrs = NULL; #ifdef SLAP_AUXPROP_DONTUSECOPY if ( dontUseCopy ) { save_dontUseCopy = op->o_dontUseCopy; if ( !op->o_dontUseCopy ) { int cnt = 0; save_ctrls = op->o_ctrls; if ( op->o_ctrls ) { for ( ; op->o_ctrls[ cnt ]; cnt++ ) ; } op->o_ctrls = op->o_tmpcalloc( sizeof(LDAPControl *), cnt + 2, op->o_tmpmemctx ); if ( cnt ) { for ( cnt = 0; save_ctrls[ cnt ]; cnt++ ) { op->o_ctrls[ cnt ] = save_ctrls[ cnt ]; } } c.ldctl_oid = LDAP_CONTROL_DONTUSECOPY; c.ldctl_iscritical = 1; BER_BVZERO( &c.ldctl_value ); op->o_ctrls[ cnt ] = &c; } op->o_dontUseCopy = SLAP_CONTROL_CRITICAL; } #endif /* SLAP_AUXPROP_DONTUSECOPY */ rc = op->o_bd->be_search( op, &rs ); #ifdef SLAP_AUXPROP_DONTUSECOPY if ( dontUseCopy ) { if ( save_ctrls != op->o_ctrls ) { op->o_tmpfree( op->o_ctrls, op->o_tmpmemctx ); op->o_ctrls = save_ctrls; op->o_dontUseCopy = save_dontUseCopy; } if ( rs.sr_err == LDAP_UNAVAILABLE && slap_dontUseCopy_ignore ) { op->o_bd = dontUseCopy_bd; dontUseCopy = 0; goto retry_dontUseCopy; } } #endif /* SLAP_AUXPROP_DONTUSECOPY */ } } } #if SASL_VERSION_FULL >= 0x020118 return rc != LDAP_SUCCESS ? SASL_FAIL : SASL_OK; #endif }
/* count dynamic objects existing in the database at startup */ static int dds_count( void *ctx, BackendDB *be ) { slap_overinst *on = (slap_overinst *)be->bd_info; dds_info_t *di = (dds_info_t *)on->on_bi.bi_private; Connection conn = { 0 }; OperationBuffer opbuf; Operation *op; slap_callback sc = { 0 }; SlapReply rs = { REP_RESULT }; int rc; char *extra = ""; connection_fake_init2( &conn, &opbuf, ctx, 0 ); op = &opbuf.ob_op; op->o_tag = LDAP_REQ_SEARCH; memset( &op->oq_search, 0, sizeof( op->oq_search ) ); op->o_bd = be; op->o_req_dn = op->o_bd->be_suffix[ 0 ]; op->o_req_ndn = op->o_bd->be_nsuffix[ 0 ]; op->o_dn = op->o_bd->be_rootdn; op->o_ndn = op->o_bd->be_rootndn; op->ors_scope = LDAP_SCOPE_SUBTREE; op->ors_tlimit = SLAP_NO_LIMIT; op->ors_slimit = SLAP_NO_LIMIT; op->ors_attrs = slap_anlist_no_attrs; op->ors_filterstr.bv_len = STRLENOF( "(objectClass=" ")" ) + slap_schema.si_oc_dynamicObject->soc_cname.bv_len; op->ors_filterstr.bv_val = op->o_tmpalloc( op->ors_filterstr.bv_len + 1, op->o_tmpmemctx ); snprintf( op->ors_filterstr.bv_val, op->ors_filterstr.bv_len + 1, "(objectClass=%s)", slap_schema.si_oc_dynamicObject->soc_cname.bv_val ); op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val ); if ( op->ors_filter == NULL ) { rs.sr_err = LDAP_OTHER; goto done_search; } op->o_callback = ≻ sc.sc_response = dds_count_cb; sc.sc_private = &di->di_num_dynamicObjects; di->di_num_dynamicObjects = 0; op->o_bd->bd_info = (BackendInfo *)on->on_info; (void)op->o_bd->bd_info->bi_op_search( op, &rs ); op->o_bd->bd_info = (BackendInfo *)on; done_search:; op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx ); filter_free_x( op, op->ors_filter, 1 ); rc = rs.sr_err; switch ( rs.sr_err ) { case LDAP_SUCCESS: Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO, "DDS non-expired=%d\n", di->di_num_dynamicObjects ); break; case LDAP_NO_SUCH_OBJECT: /* (ITS#5267) database not created yet? */ rs.sr_err = LDAP_SUCCESS; extra = " (ignored)"; /* fallthru */ default: Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "DDS non-expired objects lookup failed err=%d%s\n", rc, extra ); break; } return rs.sr_err; }
static int dds_expire( void *ctx, dds_info_t *di ) { Connection conn = { 0 }; OperationBuffer opbuf; Operation *op; slap_callback sc = { 0 }; dds_cb_t dc = { 0 }; dds_expire_t *de = NULL, **dep; SlapReply rs = { REP_RESULT }; time_t expire; char tsbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; struct berval ts; int ndeletes, ntotdeletes; int rc; char *extra = ""; connection_fake_init2( &conn, &opbuf, ctx, 0 ); op = &opbuf.ob_op; op->o_tag = LDAP_REQ_SEARCH; memset( &op->oq_search, 0, sizeof( op->oq_search ) ); op->o_bd = select_backend( &di->di_nsuffix[ 0 ], 0 ); op->o_req_dn = op->o_bd->be_suffix[ 0 ]; op->o_req_ndn = op->o_bd->be_nsuffix[ 0 ]; op->o_dn = op->o_bd->be_rootdn; op->o_ndn = op->o_bd->be_rootndn; op->ors_scope = LDAP_SCOPE_SUBTREE; op->ors_tlimit = DDS_INTERVAL( di )/2 + 1; op->ors_slimit = SLAP_NO_LIMIT; op->ors_attrs = slap_anlist_no_attrs; expire = slap_get_time() - di->di_tolerance; ts.bv_val = tsbuf; ts.bv_len = sizeof( tsbuf ); slap_timestamp( &expire, &ts ); op->ors_filterstr.bv_len = STRLENOF( "(&(objectClass=" ")(" "<=" "))" ) + slap_schema.si_oc_dynamicObject->soc_cname.bv_len + ad_entryExpireTimestamp->ad_cname.bv_len + ts.bv_len; op->ors_filterstr.bv_val = op->o_tmpalloc( op->ors_filterstr.bv_len + 1, op->o_tmpmemctx ); snprintf( op->ors_filterstr.bv_val, op->ors_filterstr.bv_len + 1, "(&(objectClass=%s)(%s<=%s))", slap_schema.si_oc_dynamicObject->soc_cname.bv_val, ad_entryExpireTimestamp->ad_cname.bv_val, ts.bv_val ); op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val ); if ( op->ors_filter == NULL ) { rs.sr_err = LDAP_OTHER; goto done_search; } op->o_callback = ≻ sc.sc_response = dds_expire_cb; sc.sc_private = &dc; (void)op->o_bd->bd_info->bi_op_search( op, &rs ); done_search:; op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx ); filter_free_x( op, op->ors_filter, 1 ); rc = rs.sr_err; switch ( rs.sr_err ) { case LDAP_SUCCESS: break; case LDAP_NO_SUCH_OBJECT: /* (ITS#5267) database not created yet? */ rs.sr_err = LDAP_SUCCESS; extra = " (ignored)"; /* fallthru */ default: Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "DDS expired objects lookup failed err=%d%s\n", rc, extra ); goto done; } op->o_tag = LDAP_REQ_DELETE; op->o_callback = ≻ sc.sc_response = slap_null_cb; sc.sc_private = NULL; slap_biglock_acquire(op->o_bd); for ( ntotdeletes = 0, ndeletes = 1; dc.dc_ndnlist != NULL && ndeletes > 0; ) { ndeletes = 0; for ( dep = &dc.dc_ndnlist; *dep != NULL; ) { de = *dep; op->o_req_dn = de->de_ndn; op->o_req_ndn = de->de_ndn; (void)op->o_bd->bd_info->bi_op_delete( op, &rs ); switch ( rs.sr_err ) { case LDAP_SUCCESS: Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO, "DDS dn=\"%s\" expired.\n", de->de_ndn.bv_val ); ndeletes++; break; case LDAP_NOT_ALLOWED_ON_NONLEAF: Log1( LDAP_DEBUG_ANY, LDAP_LEVEL_NOTICE, "DDS dn=\"%s\" is non-leaf; " "deferring.\n", de->de_ndn.bv_val ); dep = &de->de_next; de = NULL; break; default: Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_NOTICE, "DDS dn=\"%s\" err=%d; " "deferring.\n", de->de_ndn.bv_val, rs.sr_err ); break; } if ( de != NULL ) { *dep = de->de_next; op->o_tmpfree( de, op->o_tmpmemctx ); } } ntotdeletes += ndeletes; } slap_biglock_release(op->o_bd); rs.sr_err = LDAP_SUCCESS; Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO, "DDS expired=%d\n", ntotdeletes ); done:; return rs.sr_err; }