int nssov_uid2dn(Operation *op,nssov_info *ni,struct berval *uid,struct berval *dn) { nssov_mapinfo *mi = &ni->ni_maps[NM_passwd]; char fbuf[1024]; struct berval filter = {sizeof(fbuf),fbuf}; slap_callback cb = {0}; SlapReply rs = {REP_RESULT}; Operation op2; int rc; /* if it isn't a valid username, just bail out now */ if (!isvalidusername(uid)) return 0; /* we have to look up the entry */ nssov_filter_byid(mi,UID_KEY,uid,&filter); BER_BVZERO(dn); cb.sc_private = dn; cb.sc_response = nssov_name2dn_cb; op2 = *op; op2.o_callback = &cb; op2.o_req_dn = mi->mi_base; op2.o_req_ndn = mi->mi_base; op2.ors_scope = mi->mi_scope; op2.ors_filterstr = filter; op2.ors_filter = str2filter_x( op, filter.bv_val ); op2.ors_attrs = slap_anlist_no_attrs; op2.ors_tlimit = SLAP_NO_LIMIT; op2.ors_slimit = SLAP_NO_LIMIT; rc = op2.o_bd->be_search( &op2, &rs ); filter_free_x( op, op2.ors_filter, 1 ); return rc == LDAP_SUCCESS && !BER_BVISNULL(dn); }
static int retcode_op_internal( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; Operation op2 = *op; BackendDB db = *op->o_bd; slap_callback sc = { 0 }; retcode_cb_t rdc; int rc; op2.o_tag = LDAP_REQ_SEARCH; op2.ors_scope = LDAP_SCOPE_BASE; op2.ors_deref = LDAP_DEREF_NEVER; op2.ors_tlimit = SLAP_NO_LIMIT; op2.ors_slimit = SLAP_NO_LIMIT; op2.ors_limit = NULL; op2.ors_attrsonly = 0; op2.ors_attrs = slap_anlist_all_attributes; ber_str2bv_x( "(objectClass=errAbsObject)", STRLENOF( "(objectClass=errAbsObject)" ), 1, &op2.ors_filterstr, op2.o_tmpmemctx ); op2.ors_filter = str2filter_x( &op2, op2.ors_filterstr.bv_val ); /* errAbsObject is defined by this overlay! */ assert( op2.ors_filter != NULL ); db.bd_info = on->on_info->oi_orig; op2.o_bd = &db; rdc.rdc_info = on->on_info->oi_orig; rdc.rdc_flags = RETCODE_FINDIR; if ( op->o_tag == LDAP_REQ_SEARCH ) { rdc.rdc_attrs = op->ors_attrs; } rdc.rdc_tag = op->o_tag; sc.sc_response = retcode_cb_response; sc.sc_private = &rdc; op2.o_callback = ≻ rc = op2.o_bd->be_search( &op2, rs ); op->o_abandon = op2.o_abandon; filter_free_x( &op2, op2.ors_filter, 1 ); ber_memfree_x( op2.ors_filterstr.bv_val, op2.o_tmpmemctx ); if ( rdc.rdc_flags == SLAP_CB_CONTINUE ) { return SLAP_CB_CONTINUE; } return rc; }
int do_search( Operation *op, /* info about the op to which we're responding */ SlapReply *rs /* all the response data we'll send */ ) { struct berval base = BER_BVNULL; ber_len_t siz, off, i; Debug( LDAP_DEBUG_TRACE, "%s do_search\n", op->o_log_prefix, 0, 0 ); /* * Parse the search request. It looks like this: * * SearchRequest := [APPLICATION 3] SEQUENCE { * baseObject DistinguishedName, * scope ENUMERATED { * baseObject (0), * singleLevel (1), * wholeSubtree (2), * subordinate (3) -- OpenLDAP extension * }, * derefAliases ENUMERATED { * neverDerefaliases (0), * derefInSearching (1), * derefFindingBaseObj (2), * alwaysDerefAliases (3) * }, * sizelimit INTEGER (0 .. 65535), * timelimit INTEGER (0 .. 65535), * attrsOnly BOOLEAN, * filter Filter, * attributes SEQUENCE OF AttributeType * } */ /* baseObject, scope, derefAliases, sizelimit, timelimit, attrsOnly */ if ( ber_scanf( op->o_ber, "{miiiib" /*}*/, &base, &op->ors_scope, &op->ors_deref, &op->ors_slimit, &op->ors_tlimit, &op->ors_attrsonly ) == LBER_ERROR ) { send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" ); rs->sr_err = SLAPD_DISCONNECT; goto return_results; } if ( op->ors_tlimit < 0 || op->ors_tlimit > SLAP_MAX_LIMIT ) { send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid time limit" ); goto return_results; } if ( op->ors_slimit < 0 || op->ors_slimit > SLAP_MAX_LIMIT ) { send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid size limit" ); goto return_results; } switch( op->ors_scope ) { case LDAP_SCOPE_BASE: case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBORDINATE: break; default: send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid scope" ); goto return_results; } switch( op->ors_deref ) { case LDAP_DEREF_NEVER: case LDAP_DEREF_FINDING: case LDAP_DEREF_SEARCHING: case LDAP_DEREF_ALWAYS: break; default: send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid deref" ); goto return_results; } rs->sr_err = dnPrettyNormal( NULL, &base, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); if( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s do_search: invalid dn: \"%s\"\n", op->o_log_prefix, base.bv_val, 0 ); send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" ); goto return_results; } Debug( LDAP_DEBUG_ARGS, "SRCH \"%s\" %d %d", base.bv_val, op->ors_scope, op->ors_deref ); Debug( LDAP_DEBUG_ARGS, " %d %d %d\n", op->ors_slimit, op->ors_tlimit, op->ors_attrsonly); /* filter - returns a "normalized" version */ rs->sr_err = get_filter( op, op->o_ber, &op->ors_filter, &rs->sr_text ); if( rs->sr_err != LDAP_SUCCESS ) { if( rs->sr_err == SLAPD_DISCONNECT ) { rs->sr_err = LDAP_PROTOCOL_ERROR; send_ldap_disconnect( op, rs ); rs->sr_err = SLAPD_DISCONNECT; } else { send_ldap_result( op, rs ); } goto return_results; } filter2bv_x( op, op->ors_filter, &op->ors_filterstr ); Debug( LDAP_DEBUG_ARGS, " filter: %s\n", !BER_BVISEMPTY( &op->ors_filterstr ) ? op->ors_filterstr.bv_val : "empty", 0, 0 ); /* attributes */ siz = sizeof(AttributeName); off = offsetof(AttributeName,an_name); if ( ber_scanf( op->o_ber, "{M}}", &op->ors_attrs, &siz, off ) == LBER_ERROR ) { send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding attrs error" ); rs->sr_err = SLAPD_DISCONNECT; goto return_results; } for ( i=0; i<siz; i++ ) { const char *dummy; /* ignore msgs from bv2ad */ op->ors_attrs[i].an_desc = NULL; op->ors_attrs[i].an_oc = NULL; op->ors_attrs[i].an_flags = 0; if ( slap_bv2ad( &op->ors_attrs[i].an_name, &op->ors_attrs[i].an_desc, &dummy ) != LDAP_SUCCESS ) { if ( slap_bv2undef_ad( &op->ors_attrs[i].an_name, &op->ors_attrs[i].an_desc, &dummy, SLAP_AD_PROXIED|SLAP_AD_NOINSERT ) ) { struct berval *bv = &op->ors_attrs[i].an_name; /* RFC 4511 LDAPv3: All User Attributes */ if ( bvmatch( bv, slap_bv_all_user_attrs ) ) { continue; } /* RFC 3673 LDAPv3: All Operational Attributes */ if ( bvmatch( bv, slap_bv_all_operational_attrs ) ) { continue; } /* RFC 4529 LDAP: Requesting Attributes by Object Class */ if ( bv->bv_len > 1 && bv->bv_val[0] == '@' ) { /* FIXME: check if remaining is valid oc name? */ continue; } /* add more "exceptions" to RFC 4511 4.5.1.8. */ /* invalid attribute description? remove */ if ( ad_keystring( bv ) ) { /* NOTE: parsed in-place, don't modify; * rather add "1.1", which must be ignored */ BER_BVSTR( &op->ors_attrs[i].an_name, LDAP_NO_ATTRS ); } /* otherwise leave in place... */ } } } if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s do_search: get_ctrls failed\n", op->o_log_prefix, 0, 0 ); goto return_results; } Debug( LDAP_DEBUG_ARGS, " attrs:", 0, 0, 0 ); if ( siz != 0 ) { for ( i = 0; i<siz; i++ ) { Debug( LDAP_DEBUG_ARGS, " %s", op->ors_attrs[i].an_name.bv_val, 0, 0 ); } } Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 ); if ( StatslogTest( LDAP_DEBUG_STATS ) ) { char abuf[BUFSIZ/2], *ptr = abuf; unsigned len = 0, alen; sprintf(abuf, "scope=%d deref=%d", op->ors_scope, op->ors_deref); Statslog( LDAP_DEBUG_STATS, "%s SRCH base=\"%s\" %s filter=\"%s\"\n", op->o_log_prefix, op->o_req_dn.bv_val, abuf, op->ors_filterstr.bv_val, 0 ); for ( i = 0; i<siz; i++ ) { alen = op->ors_attrs[i].an_name.bv_len; if (alen >= sizeof(abuf)) { alen = sizeof(abuf)-1; } if (len && (len + 1 + alen >= sizeof(abuf))) { Statslog( LDAP_DEBUG_STATS, "%s SRCH attr=%s\n", op->o_log_prefix, abuf, 0, 0, 0 ); len = 0; ptr = abuf; } if (len) { *ptr++ = ' '; len++; } ptr = lutil_strncopy(ptr, op->ors_attrs[i].an_name.bv_val, alen); len += alen; *ptr = '\0'; } if (len) { Statslog( LDAP_DEBUG_STATS, "%s SRCH attr=%s\n", op->o_log_prefix, abuf, 0, 0, 0 ); } } op->o_bd = frontendDB; rs->sr_err = frontendDB->be_search( op, rs ); return_results:; if ( !BER_BVISNULL( &op->o_req_dn ) ) { slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx ); } if ( !BER_BVISNULL( &op->o_req_ndn ) ) { slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx ); } if ( !BER_BVISNULL( &op->ors_filterstr ) ) { op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx ); } if ( op->ors_filter != NULL) { filter_free_x( op, op->ors_filter, 1 ); } if ( op->ors_attrs != NULL ) { op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx ); } return rs->sr_err; }
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; }
static int dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli ) { Attribute *a, *id = NULL; slap_callback cb = { 0 }; Operation o = *op; struct berval *url; Entry *e; int opattrs, userattrs; dynlist_sc_t dlc = { 0 }; dynlist_map_t *dlm; a = attrs_find( rs->sr_entry->e_attrs, dli->dli_ad ); if ( a == NULL ) { /* FIXME: error? */ return SLAP_CB_CONTINUE; } opattrs = SLAP_OPATTRS( rs->sr_attr_flags ); userattrs = SLAP_USERATTRS( rs->sr_attr_flags ); /* Don't generate member list if it wasn't requested */ for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) { AttributeDescription *ad = dlm->dlm_mapped_ad ? dlm->dlm_mapped_ad : dlm->dlm_member_ad; if ( userattrs || ad_inlist( ad, rs->sr_attrs ) ) break; } if ( dli->dli_dlm && !dlm ) return SLAP_CB_CONTINUE; if ( ad_dgIdentity && ( id = attrs_find( rs->sr_entry->e_attrs, ad_dgIdentity ))) { Attribute *authz = NULL; /* if not rootdn and dgAuthz is present, * check if user can be authorized as dgIdentity */ if ( ad_dgAuthz && !BER_BVISEMPTY( &id->a_nvals[0] ) && !be_isroot( op ) && ( authz = attrs_find( rs->sr_entry->e_attrs, ad_dgAuthz ) ) ) { if ( slap_sasl_matches( op, authz->a_nvals, &o.o_ndn, &o.o_ndn ) != LDAP_SUCCESS ) { return SLAP_CB_CONTINUE; } } o.o_dn = id->a_vals[0]; o.o_ndn = id->a_nvals[0]; o.o_groups = NULL; } e = rs->sr_entry; /* ensure e is modifiable, but do not replace * sr_entry yet since we have pointers into it */ if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) { e = entry_dup( rs->sr_entry ); } dlc.dlc_e = e; dlc.dlc_dli = dli; cb.sc_private = &dlc; cb.sc_response = dynlist_sc_update; o.o_callback = &cb; o.ors_deref = LDAP_DEREF_NEVER; o.ors_limit = NULL; o.ors_tlimit = SLAP_NO_LIMIT; o.ors_slimit = SLAP_NO_LIMIT; for ( url = a->a_nvals; !BER_BVISNULL( url ); url++ ) { LDAPURLDesc *lud = NULL; int i, j; struct berval dn; int rc; BER_BVZERO( &o.o_req_dn ); BER_BVZERO( &o.o_req_ndn ); o.ors_filter = NULL; o.ors_attrs = NULL; BER_BVZERO( &o.ors_filterstr ); if ( ldap_url_parse( url->bv_val, &lud ) != LDAP_URL_SUCCESS ) { /* FIXME: error? */ continue; } if ( lud->lud_host != NULL ) { /* FIXME: host not allowed; reject as illegal? */ Debug( LDAP_DEBUG_ANY, "dynlist_prepare_entry(\"%s\"): " "illegal URI \"%s\"\n", e->e_name.bv_val, url->bv_val, 0 ); goto cleanup; } if ( lud->lud_dn == NULL ) { /* note that an empty base is not honored in terms * of defaultSearchBase, because select_backend() * is not aware of the defaultSearchBase option; * this can be useful in case of a database serving * the empty suffix */ BER_BVSTR( &dn, "" ); } else { ber_str2bv( lud->lud_dn, 0, 0, &dn ); } rc = dnPrettyNormal( NULL, &dn, &o.o_req_dn, &o.o_req_ndn, op->o_tmpmemctx ); if ( rc != LDAP_SUCCESS ) { /* FIXME: error? */ goto cleanup; } o.ors_scope = lud->lud_scope; for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) { if ( dlm->dlm_mapped_ad != NULL ) { break; } } if ( dli->dli_dlm && !dlm ) { /* if ( lud->lud_attrs != NULL ), * the URL should be ignored */ o.ors_attrs = slap_anlist_no_attrs; } else if ( lud->lud_attrs == NULL ) { o.ors_attrs = rs->sr_attrs; } else { for ( i = 0; lud->lud_attrs[i]; i++) /* just count */ ; o.ors_attrs = op->o_tmpcalloc( i + 1, sizeof( AttributeName ), op->o_tmpmemctx ); for ( i = 0, j = 0; lud->lud_attrs[i]; i++) { const char *text = NULL; ber_str2bv( lud->lud_attrs[i], 0, 0, &o.ors_attrs[j].an_name ); o.ors_attrs[j].an_desc = NULL; (void)slap_bv2ad( &o.ors_attrs[j].an_name, &o.ors_attrs[j].an_desc, &text ); /* FIXME: ignore errors... */ if ( rs->sr_attrs == NULL ) { if ( o.ors_attrs[j].an_desc != NULL && is_at_operational( o.ors_attrs[j].an_desc->ad_type ) ) { continue; } } else { if ( o.ors_attrs[j].an_desc != NULL && is_at_operational( o.ors_attrs[j].an_desc->ad_type ) ) { if ( !opattrs ) { continue; } if ( !ad_inlist( o.ors_attrs[j].an_desc, rs->sr_attrs ) ) { /* lookup if mapped -- linear search, * not very efficient unless list * is very short */ for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) { if ( dlm->dlm_member_ad == o.ors_attrs[j].an_desc ) { break; } } if ( dlm == NULL ) { continue; } } } else { if ( !userattrs && o.ors_attrs[j].an_desc != NULL && !ad_inlist( o.ors_attrs[j].an_desc, rs->sr_attrs ) ) { /* lookup if mapped -- linear search, * not very efficient unless list * is very short */ for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) { if ( dlm->dlm_member_ad == o.ors_attrs[j].an_desc ) { break; } } if ( dlm == NULL ) { continue; } } } } j++; } if ( j == 0 ) { goto cleanup; } BER_BVZERO( &o.ors_attrs[j].an_name ); } if ( lud->lud_filter == NULL ) { ber_dupbv_x( &o.ors_filterstr, &dli->dli_default_filter, op->o_tmpmemctx ); } else { struct berval flt; ber_str2bv( lud->lud_filter, 0, 0, &flt ); if ( dynlist_make_filter( op, rs->sr_entry, url->bv_val, &flt, &o.ors_filterstr ) ) { /* error */ goto cleanup; } } o.ors_filter = str2filter_x( op, o.ors_filterstr.bv_val ); if ( o.ors_filter == NULL ) { goto cleanup; } o.o_bd = select_backend( &o.o_req_ndn, 1 ); if ( o.o_bd && o.o_bd->be_search ) { SlapReply r = { REP_SEARCH }; r.sr_attr_flags = slap_attr_flags( o.ors_attrs ); (void)o.o_bd->be_search( &o, &r ); } cleanup:; if ( id ) { slap_op_groups_free( &o ); } if ( o.ors_filter ) { filter_free_x( &o, o.ors_filter, 1 ); } if ( o.ors_attrs && o.ors_attrs != rs->sr_attrs && o.ors_attrs != slap_anlist_no_attrs ) { op->o_tmpfree( o.ors_attrs, op->o_tmpmemctx ); } if ( !BER_BVISNULL( &o.o_req_dn ) ) { op->o_tmpfree( o.o_req_dn.bv_val, op->o_tmpmemctx ); } if ( !BER_BVISNULL( &o.o_req_ndn ) ) { op->o_tmpfree( o.o_req_ndn.bv_val, op->o_tmpmemctx ); } assert( BER_BVISNULL( &o.ors_filterstr ) || o.ors_filterstr.bv_val != lud->lud_filter ); op->o_tmpfree( o.ors_filterstr.bv_val, op->o_tmpmemctx ); ldap_free_urldesc( lud ); } if ( e != rs->sr_entry ) { rs_replace_entry( op, rs, (slap_overinst *)op->o_bd->bd_info, e ); rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED; } return SLAP_CB_CONTINUE; }
static int rwm_int_filter_map_rewrite( Operation *op, dncookie *dc, Filter *f, struct berval *fstr ) { int i; Filter *p; AttributeDescription *ad; struct berval atmp, vtmp, *tmp; static struct berval /* better than nothing... */ ber_bvfalse = BER_BVC( "(!(objectClass=*))" ), ber_bvtf_false = BER_BVC( "(|)" ), /* better than nothing... */ ber_bvtrue = BER_BVC( "(objectClass=*)" ), ber_bvtf_true = BER_BVC( "(&)" ), #if 0 /* no longer needed; preserved for completeness */ ber_bvundefined = BER_BVC( "(?=undefined)" ), #endif ber_bverror = BER_BVC( "(?=error)" ), ber_bvunknown = BER_BVC( "(?=unknown)" ), ber_bvnone = BER_BVC( "(?=none)" ); ber_len_t len; assert( fstr != NULL ); BER_BVZERO( fstr ); if ( f == NULL ) { ber_dupbv_x( fstr, &ber_bvnone, op->o_tmpmemctx ); return LDAP_OTHER; } #if 0 /* ITS#6814: give the caller a chance to use undefined filters */ if ( f->f_choice & SLAPD_FILTER_UNDEFINED ) { goto computed; } #endif switch ( f->f_choice & SLAPD_FILTER_MASK ) { case LDAP_FILTER_EQUALITY: ad = f->f_av_desc; if ( map_attr_value( dc, &ad, &atmp, &f->f_av_value, &vtmp, RWM_MAP, op->o_tmpmemctx ) ) { goto computed; } fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(=)" ); fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)", atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" ); op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx ); break; case LDAP_FILTER_GE: ad = f->f_av_desc; if ( map_attr_value( dc, &ad, &atmp, &f->f_av_value, &vtmp, RWM_MAP, op->o_tmpmemctx ) ) { goto computed; } fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(>=)" ); fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)", atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" ); op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx ); break; case LDAP_FILTER_LE: ad = f->f_av_desc; if ( map_attr_value( dc, &ad, &atmp, &f->f_av_value, &vtmp, RWM_MAP, op->o_tmpmemctx ) ) { goto computed; } fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(<=)" ); fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)", atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" ); op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx ); break; case LDAP_FILTER_APPROX: ad = f->f_av_desc; if ( map_attr_value( dc, &ad, &atmp, &f->f_av_value, &vtmp, RWM_MAP, op->o_tmpmemctx ) ) { goto computed; } fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(~=)" ); fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)", atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" ); op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx ); break; case LDAP_FILTER_SUBSTRINGS: ad = f->f_sub_desc; if ( map_attr_value( dc, &ad, &atmp, NULL, NULL, RWM_MAP, op->o_tmpmemctx ) ) { goto computed; } /* cannot be a DN ... */ fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" ); fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)", atmp.bv_val ); if ( !BER_BVISNULL( &f->f_sub_initial ) ) { len = fstr->bv_len; filter_escape_value_x( &f->f_sub_initial, &vtmp, op->o_tmpmemctx ); fstr->bv_len += vtmp.bv_len; fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( &fstr->bv_val[len - 2], vtmp.bv_len + 3, /* "(attr=" */ "%s*)", vtmp.bv_len ? vtmp.bv_val : "" ); op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx ); } if ( f->f_sub_any != NULL ) { for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ ) { len = fstr->bv_len; filter_escape_value_x( &f->f_sub_any[i], &vtmp, op->o_tmpmemctx ); fstr->bv_len += vtmp.bv_len + 1; fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3, /* "(attr=[init]*[any*]" */ "%s*)", vtmp.bv_len ? vtmp.bv_val : "" ); op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx ); } } if ( !BER_BVISNULL( &f->f_sub_final ) ) { len = fstr->bv_len; filter_escape_value_x( &f->f_sub_final, &vtmp, op->o_tmpmemctx ); fstr->bv_len += vtmp.bv_len; fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3, /* "(attr=[init*][any*]" */ "%s)", vtmp.bv_len ? vtmp.bv_val : "" ); op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx ); } break; case LDAP_FILTER_PRESENT: ad = f->f_desc; if ( map_attr_value( dc, &ad, &atmp, NULL, NULL, RWM_MAP, op->o_tmpmemctx ) ) { goto computed; } fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" ); fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)", atmp.bv_val ); break; case LDAP_FILTER_AND: case LDAP_FILTER_OR: case LDAP_FILTER_NOT: fstr->bv_len = STRLENOF( "(%)" ); fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)", f->f_choice == LDAP_FILTER_AND ? '&' : f->f_choice == LDAP_FILTER_OR ? '|' : '!' ); for ( p = f->f_list; p != NULL; p = p->f_next ) { int rc; len = fstr->bv_len; rc = rwm_int_filter_map_rewrite( op, dc, p, &vtmp ); if ( rc != LDAP_SUCCESS ) { return rc; } fstr->bv_len += vtmp.bv_len; fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( &fstr->bv_val[len-1], vtmp.bv_len + 2, /*"("*/ "%s)", vtmp.bv_len ? vtmp.bv_val : "" ); op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx ); } break; case LDAP_FILTER_EXT: { if ( f->f_mr_desc ) { ad = f->f_mr_desc; if ( map_attr_value( dc, &ad, &atmp, &f->f_mr_value, &vtmp, RWM_MAP, op->o_tmpmemctx ) ) { goto computed; } } else { BER_BVSTR( &atmp, "" ); filter_escape_value_x( &f->f_mr_value, &vtmp, op->o_tmpmemctx ); } fstr->bv_len = atmp.bv_len + ( f->f_mr_dnattrs ? STRLENOF( ":dn" ) : 0 ) + ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len + 1 : 0 ) + vtmp.bv_len + STRLENOF( "(:=)" ); fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)", atmp.bv_val, f->f_mr_dnattrs ? ":dn" : "", !BER_BVISEMPTY( &f->f_mr_rule_text ) ? ":" : "", !BER_BVISEMPTY( &f->f_mr_rule_text ) ? f->f_mr_rule_text.bv_val : "", vtmp.bv_len ? vtmp.bv_val : "" ); op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx ); break; } case -1: computed:; filter_free_x( op, f, 0 ); f->f_choice = SLAPD_FILTER_COMPUTED; f->f_result = SLAPD_COMPARE_UNDEFINED; /* fallthru */ case SLAPD_FILTER_COMPUTED: switch ( f->f_result ) { case LDAP_COMPARE_FALSE: /* FIXME: treat UNDEFINED as FALSE */ case SLAPD_COMPARE_UNDEFINED: if ( dc->rwmap->rwm_flags & RWM_F_SUPPORT_T_F ) { tmp = &ber_bvtf_false; break; } tmp = &ber_bvfalse; break; case LDAP_COMPARE_TRUE: if ( dc->rwmap->rwm_flags & RWM_F_SUPPORT_T_F ) { tmp = &ber_bvtf_true; break; } tmp = &ber_bvtrue; break; default: tmp = &ber_bverror; break; } ber_dupbv_x( fstr, tmp, op->o_tmpmemctx ); break; default: ber_dupbv_x( fstr, &ber_bvunknown, op->o_tmpmemctx ); break; } return LDAP_SUCCESS; }
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; }
/* ** 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; }
int pam_authz(nssov_info *ni,TFILE *fp,Operation *op) { struct berval dn, uid, svc, ruser, rhost, tty; struct berval authzmsg = BER_BVNULL; int32_t tmpint32; char dnc[1024]; char uidc[32]; char svcc[256]; char ruserc[32]; char rhostc[256]; char ttyc[256]; int rc; Entry *e = NULL; Attribute *a; slap_callback cb = {0}; READ_STRING(fp,uidc); uid.bv_val = uidc; uid.bv_len = tmpint32; READ_STRING(fp,dnc); dn.bv_val = dnc; dn.bv_len = tmpint32; READ_STRING(fp,svcc); svc.bv_val = svcc; svc.bv_len = tmpint32; READ_STRING(fp,ruserc); ruser.bv_val = ruserc; ruser.bv_len = tmpint32; READ_STRING(fp,rhostc); rhost.bv_val = rhostc; rhost.bv_len = tmpint32; READ_STRING(fp,ttyc); tty.bv_val = ttyc; tty.bv_len = tmpint32; Debug(LDAP_DEBUG_TRACE,"nssov_pam_authz(%s)\n",dn.bv_val,0,0); /* If we didn't do authc, we don't have a DN yet */ if (BER_BVISEMPTY(&dn)) { struct paminfo pi; pi.uid = uid; pi.svc = svc; rc = pam_uid2dn(ni, op, &pi); if (rc) goto finish; dn = pi.dn; } /* See if they have access to the host and service */ if ((ni->ni_pam_opts & NI_PAM_HOSTSVC) && nssov_pam_svc_ad) { AttributeAssertion ava = ATTRIBUTEASSERTION_INIT; struct berval hostdn = BER_BVNULL; struct berval odn = op->o_ndn; SlapReply rs = {REP_RESULT}; op->o_dn = dn; op->o_ndn = dn; { nssov_mapinfo *mi = &ni->ni_maps[NM_host]; char fbuf[1024]; struct berval filter = {sizeof(fbuf),fbuf}; SlapReply rs2 = {REP_RESULT}; /* Lookup the host entry */ nssov_filter_byname(mi,0,&global_host_bv,&filter); cb.sc_private = &hostdn; cb.sc_response = nssov_name2dn_cb; op->o_callback = &cb; op->o_req_dn = mi->mi_base; op->o_req_ndn = mi->mi_base; op->ors_scope = mi->mi_scope; op->ors_filterstr = filter; op->ors_filter = str2filter_x(op, filter.bv_val); op->ors_attrs = slap_anlist_no_attrs; op->ors_tlimit = SLAP_NO_LIMIT; op->ors_slimit = 2; rc = op->o_bd->be_search(op, &rs2); filter_free_x(op, op->ors_filter, 1); if (BER_BVISEMPTY(&hostdn) && !BER_BVISEMPTY(&ni->ni_pam_defhost)) { filter.bv_len = sizeof(fbuf); filter.bv_val = fbuf; rs_reinit(&rs2, REP_RESULT); nssov_filter_byname(mi,0,&ni->ni_pam_defhost,&filter); op->ors_filterstr = filter; op->ors_filter = str2filter_x(op, filter.bv_val); rc = op->o_bd->be_search(op, &rs2); filter_free_x(op, op->ors_filter, 1); } /* no host entry, no default host -> deny */ if (BER_BVISEMPTY(&hostdn)) { rc = NSLCD_PAM_PERM_DENIED; authzmsg = hostmsg; goto finish; } } cb.sc_response = pam_compare_cb; cb.sc_private = NULL; op->o_tag = LDAP_REQ_COMPARE; op->o_req_dn = hostdn; op->o_req_ndn = hostdn; ava.aa_desc = nssov_pam_svc_ad; ava.aa_value = svc; op->orc_ava = &ava; rc = op->o_bd->be_compare( op, &rs ); if ( cb.sc_private == NULL ) { authzmsg = svcmsg; rc = NSLCD_PAM_PERM_DENIED; goto finish; } op->o_dn = odn; op->o_ndn = odn; } /* See if they're a member of the group */ if ((ni->ni_pam_opts & NI_PAM_USERGRP) && !BER_BVISEMPTY(&ni->ni_pam_group_dn) && ni->ni_pam_group_ad) { AttributeAssertion ava = ATTRIBUTEASSERTION_INIT; SlapReply rs = {REP_RESULT}; op->o_callback = &cb; cb.sc_response = slap_null_cb; op->o_tag = LDAP_REQ_COMPARE; op->o_req_dn = ni->ni_pam_group_dn; op->o_req_ndn = ni->ni_pam_group_dn; ava.aa_desc = ni->ni_pam_group_ad; ava.aa_value = dn; op->orc_ava = &ava; rc = op->o_bd->be_compare( op, &rs ); if ( rs.sr_err != LDAP_COMPARE_TRUE ) { authzmsg = grpmsg; rc = NSLCD_PAM_PERM_DENIED; goto finish; } } /* We need to check the user's entry for these bits */ if ((ni->ni_pam_opts & (NI_PAM_USERHOST|NI_PAM_USERSVC)) || ni->ni_pam_template_ad || ni->ni_pam_min_uid || ni->ni_pam_max_uid ) { rc = be_entry_get_rw( op, &dn, NULL, NULL, 0, &e ); if (rc != LDAP_SUCCESS) { rc = NSLCD_PAM_USER_UNKNOWN; goto finish; } } if ((ni->ni_pam_opts & NI_PAM_USERHOST) && nssov_pam_host_ad) { a = attr_find(e->e_attrs, nssov_pam_host_ad); if (!a || attr_valfind( a, SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | SLAP_MR_VALUE_OF_SYNTAX, &global_host_bv, NULL, op->o_tmpmemctx )) { rc = NSLCD_PAM_PERM_DENIED; authzmsg = hostmsg; goto finish; } } if ((ni->ni_pam_opts & NI_PAM_USERSVC) && nssov_pam_svc_ad) { a = attr_find(e->e_attrs, nssov_pam_svc_ad); if (!a || attr_valfind( a, SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | SLAP_MR_VALUE_OF_SYNTAX, &svc, NULL, op->o_tmpmemctx )) { rc = NSLCD_PAM_PERM_DENIED; authzmsg = svcmsg; goto finish; } } /* from passwd.c */ #define UIDN_KEY 2 if (ni->ni_pam_min_uid || ni->ni_pam_max_uid) { int id; char *tmp; nssov_mapinfo *mi = &ni->ni_maps[NM_passwd]; a = attr_find(e->e_attrs, mi->mi_attrs[UIDN_KEY].an_desc); if (!a) { rc = NSLCD_PAM_PERM_DENIED; authzmsg = uidmsg; goto finish; } id = (int)strtol(a->a_vals[0].bv_val,&tmp,0); if (a->a_vals[0].bv_val[0] == '\0' || *tmp != '\0') { rc = NSLCD_PAM_PERM_DENIED; authzmsg = uidmsg; goto finish; } if ((ni->ni_pam_min_uid && id < ni->ni_pam_min_uid) || (ni->ni_pam_max_uid && id > ni->ni_pam_max_uid)) { rc = NSLCD_PAM_PERM_DENIED; authzmsg = uidmsg; goto finish; } } if (ni->ni_pam_template_ad) { a = attr_find(e->e_attrs, ni->ni_pam_template_ad); if (a) uid = a->a_vals[0]; else if (!BER_BVISEMPTY(&ni->ni_pam_template)) uid = ni->ni_pam_template; } rc = NSLCD_PAM_SUCCESS; finish: WRITE_INT32(fp,NSLCD_VERSION); WRITE_INT32(fp,NSLCD_ACTION_PAM_AUTHZ); WRITE_INT32(fp,NSLCD_RESULT_BEGIN); WRITE_BERVAL(fp,&uid); WRITE_BERVAL(fp,&dn); WRITE_INT32(fp,rc); WRITE_BERVAL(fp,&authzmsg); if (e) { be_entry_release_r(op, e); } return 0; }
static int rdnval_unique_check( Operation *op, BerVarray vals ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; BackendDB db = *op->o_bd; Operation op2 = *op; SlapReply rs2 = { 0 }; int i; BerVarray fvals; char *ptr; int gotit = 0; slap_callback cb = { 0 }; /* short-circuit attempts to add suffix entry */ if ( op->o_tag == LDAP_REQ_ADD && be_issuffix( op->o_bd, &op->o_req_ndn ) ) { return LDAP_SUCCESS; } op2.o_bd = &db; op2.o_bd->bd_info = (BackendInfo *)on->on_info; op2.o_tag = LDAP_REQ_SEARCH; op2.o_dn = op->o_bd->be_rootdn; op2.o_ndn = op->o_bd->be_rootndn; op2.o_callback = &cb; cb.sc_response = rdnval_unique_check_cb; cb.sc_private = (void *)&gotit; dnParent( &op->o_req_ndn, &op2.o_req_dn ); op2.o_req_ndn = op2.o_req_dn; op2.ors_limit = NULL; op2.ors_slimit = 1; op2.ors_tlimit = SLAP_NO_LIMIT; op2.ors_attrs = slap_anlist_no_attrs; op2.ors_attrsonly = 1; op2.ors_deref = LDAP_DEREF_NEVER; op2.ors_scope = LDAP_SCOPE_ONELEVEL; for ( i = 0; !BER_BVISNULL( &vals[ i ] ); i++ ) /* just count */ ; fvals = op->o_tmpcalloc( sizeof( struct berval ), i + 1, op->o_tmpmemctx ); op2.ors_filterstr.bv_len = 0; if ( i > 1 ) { op2.ors_filterstr.bv_len = STRLENOF( "(&)" ); } for ( i = 0; !BER_BVISNULL( &vals[ i ] ); i++ ) { ldap_bv2escaped_filter_value_x( &vals[ i ], &fvals[ i ], 1, op->o_tmpmemctx ); op2.ors_filterstr.bv_len += ad_rdnValue->ad_cname.bv_len + fvals[ i ].bv_len + STRLENOF( "(=)" ); } op2.ors_filterstr.bv_val = op->o_tmpalloc( op2.ors_filterstr.bv_len + 1, op->o_tmpmemctx ); ptr = op2.ors_filterstr.bv_val; if ( i > 1 ) { ptr = lutil_strcopy( ptr, "(&" ); } for ( i = 0; !BER_BVISNULL( &vals[ i ] ); i++ ) { *ptr++ = '('; ptr = lutil_strncopy( ptr, ad_rdnValue->ad_cname.bv_val, ad_rdnValue->ad_cname.bv_len ); *ptr++ = '='; ptr = lutil_strncopy( ptr, fvals[ i ].bv_val, fvals[ i ].bv_len ); *ptr++ = ')'; } if ( i > 1 ) { *ptr++ = ')'; } *ptr = '\0'; assert( ptr == op2.ors_filterstr.bv_val + op2.ors_filterstr.bv_len ); op2.ors_filter = str2filter_x( op, op2.ors_filterstr.bv_val ); assert( op2.ors_filter != NULL ); (void)op2.o_bd->be_search( &op2, &rs2 ); filter_free_x( op, op2.ors_filter, 1 ); op->o_tmpfree( op2.ors_filterstr.bv_val, op->o_tmpmemctx ); for ( i = 0; !BER_BVISNULL( &vals[ i ] ); i++ ) { if ( vals[ i ].bv_val != fvals[ i ].bv_val ) { op->o_tmpfree( fvals[ i ].bv_val, op->o_tmpmemctx ); } } op->o_tmpfree( fvals, op->o_tmpmemctx ); if ( rs2.sr_err != LDAP_SUCCESS || gotit > 0 ) { return LDAP_CONSTRAINT_VIOLATION; } return LDAP_SUCCESS; }
/* 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; }
static adremap_dnv *adremap_filter( Operation *op, adremap_info *ai ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; Filter *f = op->ors_filter, *fn = NULL; adremap_dnv *ad = NULL; struct berval bv; int fextra = 0; /* Do we need to munge the filter? First see if it's of * the form (objectClass=<mapgrp>) * or form (&(objectClass=<mapgrp>)...) * or form (&(&(objectClass=<mapgrp>)...)...) */ if (f->f_choice == LDAP_FILTER_AND && f->f_and) { fextra = 1; f = f->f_and; fn = f->f_next; } if (f->f_choice == LDAP_FILTER_AND && f->f_and) { fextra = 2; f = f->f_and; } if (f->f_choice == LDAP_FILTER_EQUALITY && f->f_av_desc == slap_schema.si_ad_objectClass) { struct berval bv = f->f_av_value; for (ad = ai->ai_dnv; ad; ad = ad->ad_next) { if (!ber_bvstrcasecmp( &bv, &ad->ad_mapgrp->soc_cname )) { /* Now check to see if next element is (<newattr>=foo) */ Filter *fnew; if (fn && fn->f_choice == LDAP_FILTER_EQUALITY && fn->f_av_desc == ad->ad_newattr) { Filter fr[3]; AttributeAssertion aa[2] = {0}; Operation op2; slap_callback cb = {0}; SlapReply rs = {REP_RESULT}; struct berval dn = BER_BVNULL; /* It's a match, setup a search with filter * (&(objectclass=<refgrp>)(<deref>=foo)) */ fr[0].f_choice = LDAP_FILTER_AND; fr[0].f_and = &fr[1]; fr[0].f_next = NULL; fr[1].f_choice = LDAP_FILTER_EQUALITY; fr[1].f_ava = &aa[0]; fr[1].f_av_desc = slap_schema.si_ad_objectClass; fr[1].f_av_value = ad->ad_refgrp->soc_cname; fr[1].f_next = &fr[2]; fr[2].f_choice = LDAP_FILTER_EQUALITY; fr[2].f_ava = &aa[1]; fr[2].f_av_desc = ad->ad_deref; fr[2].f_av_value = fn->f_av_value; fr[2].f_next = NULL; /* Search with this filter to retrieve target DN */ op2 = *op; op2.o_callback = &cb; cb.sc_response = adremap_refsearch; cb.sc_private = &dn; op2.o_req_dn = ad->ad_refbase; op2.o_req_ndn = ad->ad_refbase; op2.ors_filter = fr; filter2bv_x(op, fr, &op2.ors_filterstr); op2.ors_deref = LDAP_DEREF_NEVER; op2.ors_slimit = 1; op2.ors_tlimit = SLAP_NO_LIMIT; op2.ors_attrs = slap_anlist_no_attrs; op2.ors_attrsonly = 1; op2.o_no_schema_check = 1; op2.o_bd->bd_info = (BackendInfo *)on->on_info; op2.o_bd->be_search(&op2, &rs); op2.o_bd->bd_info = (BackendInfo *)on; op->o_tmpfree(op2.ors_filterstr.bv_val, op->o_tmpmemctx); if (!dn.bv_len) { /* no match was found */ ad = NULL; break; } if (rs.sr_err) { /* sizelimit exceeded, etc.: invalid name */ op->o_tmpfree(dn.bv_val, op->o_tmpmemctx); ad = NULL; break; } /* Build a new filter of form * (&(objectclass=<group>)(<dnattr>=foo-DN)...) */ f = op->o_tmpalloc(sizeof(Filter), op->o_tmpmemctx); f->f_choice = LDAP_FILTER_AND; fnew = f; f->f_next = NULL; f->f_and = op->o_tmpalloc(sizeof(Filter), op->o_tmpmemctx); f = f->f_and; f->f_choice = LDAP_FILTER_EQUALITY; f->f_ava = op->o_tmpcalloc(1, sizeof(AttributeAssertion), op->o_tmpmemctx); f->f_av_desc = slap_schema.si_ad_objectClass; ber_dupbv_x(&f->f_av_value, &ad->ad_group->soc_cname, op->o_tmpmemctx); f->f_next = op->o_tmpalloc(sizeof(Filter), op->o_tmpmemctx); f = f->f_next; f->f_choice = LDAP_FILTER_EQUALITY; f->f_ava = op->o_tmpcalloc(1, sizeof(AttributeAssertion), op->o_tmpmemctx); f->f_av_desc = ad->ad_dnattr; f->f_av_value = dn; f->f_next = fn->f_next; fn->f_next = NULL; } else { /* Build a new filter of form * (objectclass=<group>) */ f->f_next = NULL; /* disconnect old chain */ f = op->o_tmpalloc(sizeof(Filter), op->o_tmpmemctx); f->f_choice = LDAP_FILTER_EQUALITY; f->f_ava = op->o_tmpcalloc(1, sizeof(AttributeAssertion), op->o_tmpmemctx); f->f_av_desc = slap_schema.si_ad_objectClass; ber_dupbv_x(&f->f_av_value, &ad->ad_group->soc_cname, op->o_tmpmemctx); /* If there was a wrapping (&), attach it. */ if (fextra) { fnew = op->o_tmpalloc(sizeof(Filter), op->o_tmpmemctx); fnew->f_choice = LDAP_FILTER_AND; fnew->f_and = f; fnew->f_next = NULL; f->f_next = fn; } else { fnew = f; f->f_next = NULL; } } if (fextra > 1) { f = op->o_tmpalloc(sizeof(Filter), op->o_tmpmemctx); f->f_choice = LDAP_FILTER_AND; f->f_and = fnew->f_and; f->f_next = f->f_and->f_next; f->f_and->f_next = op->ors_filter->f_and->f_and->f_next; op->ors_filter->f_and->f_and->f_next = NULL; fnew->f_and = f; } filter_free_x(op, op->ors_filter, 1); op->o_tmpfree(op->ors_filterstr.bv_val, op->o_tmpmemctx); op->ors_filter = fnew; filter2bv_x(op, op->ors_filter, &op->ors_filterstr); break; } } } return ad; }