int relay_back_db_open( Backend *be, ConfigReply *cr ) { relay_back_info *ri = (relay_back_info *)be->be_private; assert( ri != NULL ); if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) { ri->ri_bd = select_backend( &ri->ri_realsuffix, 1 ); /* must be there: it was during config! */ if ( ri->ri_bd == NULL ) { snprintf( cr->msg, sizeof( cr->msg), "cannot find database " "of relay dn \"%s\" " "in \"olcRelay <dn>\"\n", ri->ri_realsuffix.bv_val ); Log1( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "relay_back_db_open: %s.\n", cr->msg ); return 1; } /* inherit controls */ AC_MEMCPY( be->bd_self->be_ctrls, ri->ri_bd->be_ctrls, sizeof( be->be_ctrls ) ); } else { /* inherit all? */ AC_MEMCPY( be->bd_self->be_ctrls, frontendDB->be_ctrls, sizeof( be->be_ctrls ) ); } return 0; }
int relay_back_entry_release_rw( Operation *op, Entry *e, int rw ) { relay_back_info *ri = (relay_back_info *)op->o_bd->be_private; BackendDB *bd; int rc = 1; bd = ri->ri_bd; if ( bd == NULL) { bd = select_backend( &op->o_req_ndn, 1 ); if ( bd == NULL ) { return 1; } } if ( bd->be_release ) { BackendDB *be = op->o_bd; op->o_bd = bd; rc = bd->be_release( op, e, rw ); op->o_bd = be; } return rc; }
int relay_back_entry_get_rw( Operation *op, struct berval *ndn, ObjectClass *oc, AttributeDescription *at, int rw, Entry **e ) { relay_back_info *ri = (relay_back_info *)op->o_bd->be_private; BackendDB *bd; int rc = 1; bd = ri->ri_bd; if ( bd == NULL) { bd = select_backend( &op->o_req_ndn, 1 ); if ( bd == NULL ) { return 1; } } if ( bd->be_fetch ) { BackendDB *be = op->o_bd; op->o_bd = bd; rc = bd->be_fetch( op, ndn, oc, at, rw, e ); op->o_bd = be; } return rc; }
idattr_id_to_dn ( Operation *op, AttributeDescription *searchAttr, struct berval* searchID, struct berval* resultDN) { Operation nop = *op; char filter_str[128]; AttributeAssertion ava = { NULL, BER_BVNULL }; Filter filter = {LDAP_FILTER_EQUALITY}; SlapReply sreply = {REP_RESULT}; slap_callback cb = { NULL, idattr_id_to_dn_cb, NULL, NULL }; BackendDB *target_bd = NULL; idattr_id_to_dn_t dn_result = {0}; int rc = 0; target_bd = select_backend(&op->o_req_ndn, 0); if (!target_bd || !target_bd->be_search) return LDAP_NOT_SUPPORTED; sreply.sr_entry = NULL; sreply.sr_nentries = 0; nop.ors_filterstr.bv_len = snprintf(filter_str, sizeof(filter_str), "(%s=%s)",searchAttr->ad_cname.bv_val, searchID->bv_val); filter.f_ava = &ava; filter.f_av_desc = searchAttr; filter.f_av_value = *searchID; nop.o_tag = LDAP_REQ_SEARCH; nop.o_protocol = LDAP_VERSION3; nop.o_callback = &cb; nop.o_time = slap_get_time(); nop.o_do_not_cache = 0; nop.o_dn = target_bd->be_rootdn; nop.o_ndn = target_bd->be_rootndn; nop.o_bd = target_bd; nop.o_req_dn = target_bd->be_suffix[0]; nop.o_req_ndn = target_bd->be_nsuffix[0]; nop.ors_scope = LDAP_SCOPE_SUBTREE; nop.ors_deref = LDAP_DEREF_NEVER; nop.ors_slimit = SLAP_NO_LIMIT; nop.ors_tlimit = SLAP_NO_LIMIT; nop.ors_filter = &filter; nop.ors_filterstr.bv_val = filter_str; nop.ors_filterstr.bv_len = strlen(filter_str); nop.ors_attrs = NULL; nop.ors_attrsonly = 0; cb.sc_private = &dn_result; rc = nop.o_bd->be_search( &nop, &sreply ); if (dn_result.found) { ber_dupbv(resultDN, &dn_result.target_dn ); } return 0; }
static int slap_exop_refresh( Operation *op, SlapReply *rs ) { BackendDB *bd = op->o_bd; rs->sr_err = slap_parse_refresh( op->ore_reqdata, &op->o_req_ndn, NULL, &rs->sr_text, op->o_tmpmemctx ); if ( rs->sr_err != LDAP_SUCCESS ) { return rs->sr_err; } Log2( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO, "%s REFRESH dn=\"%s\"\n", op->o_log_prefix, op->o_req_ndn.bv_val ); op->o_req_dn = op->o_req_ndn; op->o_bd = select_backend( &op->o_req_ndn, 0 ); if ( op->o_bd == NULL ) { send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT, "no global superior knowledge" ); goto done; } if ( !SLAP_DYNAMIC( op->o_bd ) ) { send_ldap_error( op, rs, LDAP_UNAVAILABLE_CRITICAL_EXTENSION, "backend does not support dynamic directory services" ); goto done; } rs->sr_err = backend_check_restrictions( op, rs, (struct berval *)&slap_EXOP_REFRESH ); if ( rs->sr_err != LDAP_SUCCESS ) { goto done; } if ( op->o_bd->be_extended == NULL ) { send_ldap_error( op, rs, LDAP_UNAVAILABLE_CRITICAL_EXTENSION, "backend does not support extended operations" ); goto done; } op->o_bd->be_extended( op, rs ); done:; if ( !BER_BVISNULL( &op->o_req_ndn ) ) { op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); BER_BVZERO( &op->o_req_ndn ); BER_BVZERO( &op->o_req_dn ); } op->o_bd = bd; return rs->sr_err; }
/* * Called when controller got OP_OPEN * The controller passes the request to a chosen server */ void controller_open(int *backend_socket, int client_socket, struct op_hdr get_hdr) { int len = -1; int fd = -1; // FD int mode = -1; int name_len = 0; struct op_hdr put_hdr; int s_idx = -1; char path_buff[4096]; // init put_hdr = get_hdr; mode = get_hdr.p1; name_len = get_hdr.p2; // Size of file name printf("\tname_len: %d, mode: %d\n", name_len, mode); /* Read the actual data (name of the file) */ READ_ALL(len, client_socket, path_buff, name_len); path_buff[name_len] = '\0'; printf("\tfilename: %s\n", path_buff); // Open connection to the appropriate server if ((s_idx = select_backend(path_buff)) < 0) { printf("Requested file: %s not found\n", path_buff); put_hdr.op = ERR_OPEN; put_hdr.p1 = 0; WRITE_SOC(len, client_socket, &put_hdr, HDR_SIZE); return; } /* Connect to server */ if ((*backend_socket = connect_to_server(server_list[s_idx].name, server_port)) < 0) { perror("Connection to server failed"); put_hdr.op = ERR_OPEN; put_hdr.p1 = errno; WRITE_SOC(len, client_socket, &put_hdr, HDR_SIZE); return; } /* Open the requested file on the backend server */ fd = client_open(*backend_socket, path_buff, mode); /* Reply with the result */ put_hdr.op = OP_OPEN; put_hdr.p1 = fd; WRITE_SOC(len, client_socket, &put_hdr, HDR_SIZE); }
static int autoca_setlocal( Operation *op, struct berval *cert, struct berval *pkey ) { Modifications mod[2]; struct berval bvs[4]; slap_callback cb = {0}; SlapReply rs = {REP_RESULT}; const char *text; mod[0].sml_numvals = 1; mod[0].sml_values = bvs; mod[0].sml_nvalues = NULL; mod[0].sml_desc = NULL; if ( slap_str2ad( "olcTLSCertificate;binary", &mod[0].sml_desc, &text )) return -1; mod[0].sml_op = LDAP_MOD_REPLACE; mod[0].sml_flags = SLAP_MOD_INTERNAL; bvs[0] = *cert; BER_BVZERO( &bvs[1] ); mod[0].sml_next = &mod[1]; mod[1].sml_numvals = 1; mod[1].sml_values = &bvs[2]; mod[1].sml_nvalues = NULL; mod[1].sml_desc = NULL; if ( slap_str2ad( "olcTLSCertificateKey;binary", &mod[1].sml_desc, &text )) return -1; mod[1].sml_op = LDAP_MOD_REPLACE; mod[1].sml_flags = SLAP_MOD_INTERNAL; bvs[2] = *pkey; BER_BVZERO( &bvs[3] ); mod[1].sml_next = NULL; cb.sc_response = slap_null_cb; op->o_bd = select_backend( (struct berval *)&configDN, 0 ); if ( !op->o_bd ) return -1; op->o_tag = LDAP_REQ_MODIFY; op->o_callback = &cb; op->orm_modlist = mod; op->orm_no_opattrs = 1; op->o_req_dn = configDN; op->o_req_ndn = configDN; op->o_dn = op->o_bd->be_rootdn; op->o_ndn = op->o_bd->be_rootndn; op->o_bd->be_modify( op, &rs ); return rs.sr_err; }
static void slapi_int_set_operation_dn( Slapi_PBlock *pb ) { Backend *be; Operation *op = pb->pb_op; if ( BER_BVISNULL( &op->o_ndn ) ) { /* set to root DN */ be = select_backend( &op->o_req_ndn, 1 ); if ( be != NULL ) { ber_dupbv( &op->o_dn, &be->be_rootdn ); ber_dupbv( &op->o_ndn, &be->be_rootndn ); } } }
idattr_is_member ( Operation *op, struct berval* groupDN, AttributeDescription *searchAttr, struct berval* searchID, u_int32_t * result) { Operation nop = *op; AttributeAssertion ava = { NULL, BER_BVNULL }; SlapReply sreply = {REP_RESULT}; slap_callback cb = { NULL, idattr_is_member_cb, NULL, NULL }; BackendDB *target_bd = NULL; idattr_ismember_t ismember = {0}; int rc = 0; target_bd = select_backend(&op->o_req_ndn, 0); if (!target_bd || !target_bd->be_compare) return LDAP_NOT_SUPPORTED; sreply.sr_entry = NULL; sreply.sr_nentries = 0; nop.orc_ava = &ava; nop.orc_ava->aa_desc = searchAttr; nop.orc_ava->aa_value = *searchID; nop.o_tag = LDAP_REQ_COMPARE; nop.o_protocol = LDAP_VERSION3; nop.o_callback = &cb; nop.o_time = slap_get_time(); nop.o_do_not_cache = 0; nop.o_dn = target_bd->be_rootdn; nop.o_ndn = target_bd->be_rootndn; nop.o_bd = target_bd; nop.o_req_dn = *groupDN; nop.o_req_ndn = *groupDN; cb.sc_private = &ismember; rc = nop.o_bd->be_compare( &nop, &sreply ); Debug(LDAP_DEBUG_ACL, "idattr_is_member be_compare[%d] ismember[%d]\n", rc, ismember.found, 0); if (ismember.found) *result = 1; else *result = 0; return 0; }
/* must run as a pool thread to avoid cn=config deadlock */ static void * autoca_setca_task( void *ctx, void *arg ) { Connection conn = { 0 }; OperationBuffer opbuf; Operation *op; struct berval *cacert = arg; Modifications mod; struct berval bvs[2]; slap_callback cb = {0}; SlapReply rs = {REP_RESULT}; const char *text; connection_fake_init( &conn, &opbuf, ctx ); op = &opbuf.ob_op; mod.sml_numvals = 1; mod.sml_values = bvs; mod.sml_nvalues = NULL; mod.sml_desc = NULL; if ( slap_str2ad( "olcTLSCACertificate;binary", &mod.sml_desc, &text )) goto leave; mod.sml_op = LDAP_MOD_REPLACE; mod.sml_flags = SLAP_MOD_INTERNAL; bvs[0] = *cacert; BER_BVZERO( &bvs[1] ); mod.sml_next = NULL; cb.sc_response = slap_null_cb; op->o_bd = select_backend( (struct berval *)&configDN, 0 ); if ( !op->o_bd ) goto leave; op->o_tag = LDAP_REQ_MODIFY; op->o_callback = &cb; op->orm_modlist = &mod; op->orm_no_opattrs = 1; op->o_req_dn = configDN; op->o_req_ndn = configDN; op->o_dn = op->o_bd->be_rootdn; op->o_ndn = op->o_bd->be_rootndn; op->o_bd->be_modify( op, &rs ); leave: ch_free( arg ); return NULL; }
static int pblock_be_call( Slapi_PBlock *pb, int (*bep)(Operation *) ) { BackendDB *be_orig; Operation *op; int rc; PBLOCK_ASSERT_OP( pb, 0 ); op = pb->pb_op; be_orig = op->o_bd; op->o_bd = select_backend( &op->o_req_ndn, 0 ); rc = (*bep)( op ); op->o_bd = be_orig; return rc; }
static void send_page( Operation *op, SlapReply *rs, sort_op *so ) { TAvlnode *cur_node = so->so_tree; TAvlnode *next_node = NULL; BackendDB *be = op->o_bd; Entry *e; int rc; rs->sr_attrs = op->ors_attrs; while ( cur_node && rs->sr_nentries < so->so_page_size ) { sort_node *sn = cur_node->avl_data; if ( slapd_shutdown ) break; next_node = tavl_next( cur_node, TAVL_DIR_RIGHT ); op->o_bd = select_backend( &sn->sn_dn, 0 ); e = NULL; rc = be_entry_get_rw( op, &sn->sn_dn, NULL, NULL, 0, &e ); ch_free( cur_node->avl_data ); ber_memfree( cur_node ); cur_node = next_node; so->so_nentries--; if ( e && rc == LDAP_SUCCESS ) { rs->sr_entry = e; rs->sr_flags = REP_ENTRY_MUSTRELEASE; rs->sr_err = send_search_entry( op, rs ); if ( rs->sr_err == LDAP_UNAVAILABLE ) break; } } /* Set the first entry to send for the next page */ so->so_tree = next_node; if ( next_node ) next_node->avl_left = NULL; op->o_bd = be; }
static int fe_entry_release_rw( Operation *op, Entry *e, int rw ) { BackendDB *bd; int rc = LDAP_NO_SUCH_OBJECT; bd = op->o_bd; op->o_bd = select_backend( &e->e_nname, 0 ); if ( op->o_bd != NULL ) { if ( op->o_bd->be_release ) { rc = op->o_bd->be_release( op, e, rw ); } } op->o_bd = bd; return rc; }
static int fe_entry_get_rw( Operation *op, struct berval *ndn, ObjectClass *oc, AttributeDescription *at, int rw, Entry **e ) { BackendDB *bd; int rc = LDAP_NO_SUCH_OBJECT; bd = op->o_bd; op->o_bd = select_backend( ndn, 0 ); if ( op->o_bd != NULL ) { if ( op->o_bd->be_fetch ) { rc = op->o_bd->be_fetch( op, ndn, oc, at, rw, e ); } } op->o_bd = bd; return rc; }
int relay_back_db_open( Backend *be, ConfigReply *cr ) { relay_back_info *ri = (relay_back_info *)be->be_private; assert( ri != NULL ); if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) { ri->ri_bd = select_backend( &ri->ri_realsuffix, 1 ); /* must be there: it was during config! */ assert( ri->ri_bd != NULL ); /* inherit controls */ AC_MEMCPY( be->be_ctrls, ri->ri_bd->be_ctrls, sizeof( be->be_ctrls ) ); } else { /* inherit all? */ AC_MEMCPY( be->be_ctrls, frontendDB->be_ctrls, sizeof( be->be_ctrls ) ); } return 0; }
int fe_op_modrdn( Operation *op, SlapReply *rs ) { struct berval dest_ndn = BER_BVNULL, dest_pndn, pdn = BER_BVNULL; BackendDB *op_be, *bd = op->o_bd; ber_slen_t diff; if( op->o_req_ndn.bv_len == 0 ) { Debug( LDAP_DEBUG_ANY, "%s do_modrdn: root dse!\n", op->o_log_prefix, 0, 0 ); send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "cannot rename the root DSE" ); goto cleanup; } else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) { Debug( LDAP_DEBUG_ANY, "%s do_modrdn: subschema subentry: %s (%ld)\n", op->o_log_prefix, frontendDB->be_schemandn.bv_val, (long)frontendDB->be_schemandn.bv_len ); send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "cannot rename subschema subentry" ); goto cleanup; } if( op->orr_nnewSup ) { dest_pndn = *op->orr_nnewSup; } else { dnParent( &op->o_req_ndn, &dest_pndn ); } build_new_dn( &dest_ndn, &dest_pndn, &op->orr_nnewrdn, op->o_tmpmemctx ); diff = (ber_slen_t) dest_ndn.bv_len - (ber_slen_t) op->o_req_ndn.bv_len; if ( diff > 0 ? dnIsSuffix( &dest_ndn, &op->o_req_ndn ) : diff < 0 && dnIsSuffix( &op->o_req_ndn, &dest_ndn ) ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, diff > 0 ? "cannot place an entry below itself" : "cannot place an entry above itself" ); goto cleanup; } /* * We could be serving multiple database backends. Select the * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ op->o_bd = select_backend( &op->o_req_ndn, 1 ); if ( op->o_bd == NULL ) { op->o_bd = bd; rs->sr_ref = referral_rewrite( default_referral, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); if (!rs->sr_ref) rs->sr_ref = default_referral; if ( rs->sr_ref != NULL ) { rs->sr_err = LDAP_REFERRAL; send_ldap_result( op, rs ); if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref ); } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "no global superior knowledge" ); } goto cleanup; } /* If we've got a glued backend, check the real backend */ op_be = op->o_bd; if ( SLAP_GLUE_INSTANCE( op->o_bd )) { op->o_bd = select_backend( &op->o_req_ndn, 0 ); } /* check restrictions */ if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } /* check for referrals */ if ( backend_check_referrals( op, rs ) != LDAP_SUCCESS ) { goto cleanup; } /* check that destination DN is in the same backend as source DN */ if ( select_backend( &dest_ndn, 0 ) != op->o_bd ) { send_ldap_error( op, rs, LDAP_AFFECTS_MULTIPLE_DSAS, "cannot rename between DSAs" ); goto cleanup; } /* * do the modrdn if 1 && (2 || 3) * 1) there is a modrdn function implemented in this backend; * 2) this backend is master for what it holds; * 3) it's a replica and the dn supplied is the update_ndn. */ if ( op->o_bd->be_modrdn ) { /* do the update here */ int repl_user = be_isupdate( op ); if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user ) { op->o_bd = op_be; op->o_bd->be_modrdn( op, rs ); if ( op->o_bd->be_delete ) { struct berval org_req_dn = BER_BVNULL; struct berval org_req_ndn = BER_BVNULL; struct berval org_dn = BER_BVNULL; struct berval org_ndn = BER_BVNULL; int org_managedsait; org_req_dn = op->o_req_dn; org_req_ndn = op->o_req_ndn; org_dn = op->o_dn; org_ndn = op->o_ndn; org_managedsait = get_manageDSAit( op ); op->o_dn = op->o_bd->be_rootdn; op->o_ndn = op->o_bd->be_rootndn; op->o_managedsait = SLAP_CONTROL_NONCRITICAL; while ( rs->sr_err == LDAP_SUCCESS && op->o_delete_glue_parent ) { op->o_delete_glue_parent = 0; if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) { slap_callback cb = { NULL }; cb.sc_response = slap_null_cb; dnParent( &op->o_req_ndn, &pdn ); op->o_req_dn = pdn; op->o_req_ndn = pdn; op->o_callback = &cb; op->o_bd->be_delete( op, rs ); } else { break; } } op->o_managedsait = org_managedsait; op->o_dn = org_dn; op->o_ndn = org_ndn; op->o_req_dn = org_req_dn; op->o_req_ndn = org_req_ndn; op->o_delete_glue_parent = 0; } } else { BerVarray defref = op->o_bd->be_update_refs ? op->o_bd->be_update_refs : default_referral; if ( defref != NULL ) { rs->sr_ref = referral_rewrite( defref, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); if (!rs->sr_ref) rs->sr_ref = defref; rs->sr_err = LDAP_REFERRAL; send_ldap_result( op, rs ); if (rs->sr_ref != defref) ber_bvarray_free( rs->sr_ref ); } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "shadow context; no update referral" ); } } } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "operation not supported within namingContext" ); } cleanup:; if ( dest_ndn.bv_val != NULL ) ber_memfree_x( dest_ndn.bv_val, op->o_tmpmemctx ); op->o_bd = bd; return rs->sr_err; }
int fe_op_bind( Operation *op, SlapReply *rs ) { BackendDB *bd = op->o_bd; /* check for inappropriate controls */ if( get_manageDSAit( op ) == SLAP_CONTROL_CRITICAL ) { send_ldap_error( op, rs, LDAP_UNAVAILABLE_CRITICAL_EXTENSION, "manageDSAit control inappropriate" ); goto cleanup; } if ( op->orb_method == LDAP_AUTH_SASL ) { if ( op->o_protocol < LDAP_VERSION3 ) { Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%ld\n", (unsigned long)op->o_protocol ); send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "SASL bind requires LDAPv3" ); rs->sr_err = SLAPD_DISCONNECT; goto cleanup; } if( BER_BVISNULL( &op->orb_mech ) || BER_BVISEMPTY( &op->orb_mech ) ) { Debug( LDAP_DEBUG_ANY, "do_bind: no sasl mechanism provided\n" ); send_ldap_error( op, rs, LDAP_AUTH_METHOD_NOT_SUPPORTED, "no SASL mechanism provided" ); goto cleanup; } /* check restrictions */ if( backend_check_restrictions( op, rs, &op->orb_mech ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); if ( op->o_conn->c_sasl_bind_in_progress ) { if( !bvmatch( &op->o_conn->c_sasl_bind_mech, &op->orb_mech ) ) { /* mechanism changed between bind steps */ slap_sasl_reset(op->o_conn); } } else { ber_dupbv(&op->o_conn->c_sasl_bind_mech, &op->orb_mech); } /* Set the bindop for the benefit of in-directory SASL lookups */ op->o_conn->c_sasl_bindop = op; ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); rs->sr_err = slap_sasl_bind( op, rs ); goto cleanup; } else { /* Not SASL, cancel any in-progress bind */ ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); if ( !BER_BVISNULL( &op->o_conn->c_sasl_bind_mech ) ) { free( op->o_conn->c_sasl_bind_mech.bv_val ); BER_BVZERO( &op->o_conn->c_sasl_bind_mech ); } op->o_conn->c_sasl_bind_in_progress = 0; slap_sasl_reset( op->o_conn ); ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); } if ( op->orb_method == LDAP_AUTH_SIMPLE ) { BER_BVSTR( &op->orb_mech, "SIMPLE" ); /* accept "anonymous" binds */ if ( BER_BVISEMPTY( &op->orb_cred ) || BER_BVISEMPTY( &op->o_req_ndn ) ) { rs->sr_err = LDAP_SUCCESS; if( !BER_BVISEMPTY( &op->orb_cred ) && !( global_allows & SLAP_ALLOW_BIND_ANON_CRED )) { /* cred is not empty, disallow */ rs->sr_err = LDAP_INVALID_CREDENTIALS; } else if ( !BER_BVISEMPTY( &op->o_req_ndn ) && !( global_allows & SLAP_ALLOW_BIND_ANON_DN )) { /* DN is not empty, disallow */ rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "unauthenticated bind (DN with no password) disallowed"; } else if ( global_disallows & SLAP_DISALLOW_BIND_ANON ) { /* disallow */ rs->sr_err = LDAP_INAPPROPRIATE_AUTH; rs->sr_text = "anonymous bind disallowed"; } else { backend_check_restrictions( op, rs, &op->orb_mech ); } /* * we already forced connection to "anonymous", * just need to send success */ send_ldap_result( op, rs ); Debug( LDAP_DEBUG_TRACE, "do_bind: v%d anonymous bind\n", op->o_protocol ); goto cleanup; } else if ( global_disallows & SLAP_DISALLOW_BIND_SIMPLE ) { /* disallow simple authentication */ rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "unwilling to perform simple authentication"; send_ldap_result( op, rs ); Debug( LDAP_DEBUG_TRACE, "do_bind: v%d simple bind(%s) disallowed\n", op->o_protocol, op->o_req_ndn.bv_val ); goto cleanup; } } else { rs->sr_err = LDAP_AUTH_METHOD_NOT_SUPPORTED; rs->sr_text = "unknown authentication method"; send_ldap_result( op, rs ); Debug( LDAP_DEBUG_TRACE, "do_bind: v%d unknown authentication method (%d)\n", op->o_protocol, op->orb_method ); goto cleanup; } /* * We could be serving multiple database backends. Select the * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ if ( (op->o_bd = select_backend( &op->o_req_ndn, 0 )) == NULL ) { /* don't return referral for bind requests */ /* noSuchObject is not allowed to be returned by bind */ rs->sr_err = LDAP_INVALID_CREDENTIALS; op->o_bd = bd; send_ldap_result( op, rs ); goto cleanup; } /* check restrictions */ if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } if( op->o_bd->be_bind ) { op->o_conn->c_authz_cookie = NULL; rs->sr_err = (op->o_bd->be_bind)( op, rs ); if ( rs->sr_err == 0 ) { (void)fe_op_bind_success( op, rs ); } else if ( !BER_BVISNULL( &op->orb_edn ) ) { free( op->orb_edn.bv_val ); BER_BVZERO( &op->orb_edn ); } } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "operation not supported within naming context" ); } cleanup:; op->o_bd = bd; 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; }
int fe_op_delete( Operation *op, SlapReply *rs ) { struct berval pdn = BER_BVNULL; BackendDB *op_be, *bd = op->o_bd; /* * We could be serving multiple database backends. Select the * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ op->o_bd = select_backend( &op->o_req_ndn, 1 ); if ( op->o_bd == NULL ) { op->o_bd = bd; rs->sr_ref = referral_rewrite( default_referral, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); if (!rs->sr_ref) rs->sr_ref = default_referral; if ( rs->sr_ref != NULL ) { rs->sr_err = LDAP_REFERRAL; send_ldap_result( op, rs ); if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref ); } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "no global superior knowledge" ); } goto cleanup; } /* If we've got a glued backend, check the real backend */ op_be = op->o_bd; if ( SLAP_GLUE_INSTANCE( op->o_bd )) { op->o_bd = select_backend( &op->o_req_ndn, 0 ); } /* check restrictions */ if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } /* check for referrals */ if( backend_check_referrals( op, rs ) != LDAP_SUCCESS ) { goto cleanup; } /* * do the delete if 1 && (2 || 3) * 1) there is a delete function implemented in this backend; * 2) this backend is master for what it holds; * 3) it's a replica and the dn supplied is the update_ndn. */ if ( op->o_bd->be_delete ) { /* do the update here */ int repl_user = be_isupdate( op ); if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user ) { struct berval org_req_dn = BER_BVNULL; struct berval org_req_ndn = BER_BVNULL; struct berval org_dn = BER_BVNULL; struct berval org_ndn = BER_BVNULL; int org_managedsait; op->o_bd = op_be; op->o_bd->be_delete( op, rs ); org_req_dn = op->o_req_dn; org_req_ndn = op->o_req_ndn; org_dn = op->o_dn; org_ndn = op->o_ndn; org_managedsait = get_manageDSAit( op ); op->o_dn = op->o_bd->be_rootdn; op->o_ndn = op->o_bd->be_rootndn; op->o_managedsait = SLAP_CONTROL_NONCRITICAL; while ( rs->sr_err == LDAP_SUCCESS && op->o_delete_glue_parent ) { op->o_delete_glue_parent = 0; if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) { slap_callback cb = { NULL, NULL, NULL, NULL }; cb.sc_response = slap_null_cb; dnParent( &op->o_req_ndn, &pdn ); op->o_req_dn = pdn; op->o_req_ndn = pdn; op->o_callback = &cb; op->o_bd->be_delete( op, rs ); } else { break; } } op->o_managedsait = org_managedsait; op->o_dn = org_dn; op->o_ndn = org_ndn; op->o_req_dn = org_req_dn; op->o_req_ndn = org_req_ndn; op->o_delete_glue_parent = 0; } else { BerVarray defref = op->o_bd->be_update_refs ? op->o_bd->be_update_refs : default_referral; if ( defref != NULL ) { rs->sr_ref = referral_rewrite( defref, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); if (!rs->sr_ref) rs->sr_ref = defref; rs->sr_err = LDAP_REFERRAL; send_ldap_result( op, rs ); if (rs->sr_ref != defref) ber_bvarray_free( rs->sr_ref ); } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "shadow context; no update referral" ); } } } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "operation not supported within namingContext" ); } cleanup:; op->o_bd = bd; return rs->sr_err; }
int passwd_extop( Operation *op, SlapReply *rs ) { struct berval id = {0, NULL}, hash, *rsp = NULL; req_pwdexop_s *qpw = &op->oq_pwdexop; req_extended_s qext = op->oq_extended; Modifications *ml; slap_callback cb = { NULL, slap_null_cb, NULL, NULL }; int i, nhash; char **hashes, idNul; int rc; BackendDB *op_be; int freenewpw = 0; struct berval dn = BER_BVNULL, ndn = BER_BVNULL; assert( ber_bvcmp( &slap_EXOP_MODIFY_PASSWD, &op->ore_reqoid ) == 0 ); if( op->o_dn.bv_len == 0 ) { Statslog( LDAP_DEBUG_STATS, "%s PASSMOD\n", op->o_log_prefix, 0, 0, 0, 0 ); rs->sr_text = "only authenticated users may change passwords"; return LDAP_STRONG_AUTH_REQUIRED; } qpw->rs_old.bv_len = 0; qpw->rs_old.bv_val = NULL; qpw->rs_new.bv_len = 0; qpw->rs_new.bv_val = NULL; qpw->rs_mods = NULL; qpw->rs_modtail = NULL; rs->sr_err = slap_passwd_parse( op->ore_reqdata, &id, &qpw->rs_old, &qpw->rs_new, &rs->sr_text ); if ( !BER_BVISNULL( &id )) { idNul = id.bv_val[id.bv_len]; id.bv_val[id.bv_len] = '\0'; } if ( rs->sr_err == LDAP_SUCCESS && !BER_BVISEMPTY( &id ) ) { Statslog( LDAP_DEBUG_STATS, "%s PASSMOD id=\"%s\"%s%s\n", op->o_log_prefix, id.bv_val, qpw->rs_old.bv_val ? " old" : "", qpw->rs_new.bv_val ? " new" : "", 0 ); } else { Statslog( LDAP_DEBUG_STATS, "%s PASSMOD%s%s\n", op->o_log_prefix, qpw->rs_old.bv_val ? " old" : "", qpw->rs_new.bv_val ? " new" : "", 0, 0 ); } if ( rs->sr_err != LDAP_SUCCESS ) { if ( !BER_BVISNULL( &id )) id.bv_val[id.bv_len] = idNul; return rs->sr_err; } if ( !BER_BVISEMPTY( &id ) ) { rs->sr_err = dnPrettyNormal( NULL, &id, &dn, &ndn, op->o_tmpmemctx ); id.bv_val[id.bv_len] = idNul; if ( rs->sr_err != LDAP_SUCCESS ) { rs->sr_text = "Invalid DN"; rc = rs->sr_err; goto error_return; } op->o_req_dn = dn; op->o_req_ndn = ndn; op->o_bd = select_backend( &op->o_req_ndn, 1 ); } else { ber_dupbv_x( &dn, &op->o_dn, op->o_tmpmemctx ); ber_dupbv_x( &ndn, &op->o_ndn, op->o_tmpmemctx ); op->o_req_dn = dn; op->o_req_ndn = ndn; ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); op->o_bd = op->o_conn->c_authz_backend; ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); } if( op->o_bd == NULL ) { if ( qpw->rs_old.bv_val != NULL ) { rs->sr_text = "unwilling to verify old password"; rc = LDAP_UNWILLING_TO_PERFORM; goto error_return; } #ifdef HAVE_CYRUS_SASL rc = slap_sasl_setpass( op, rs ); #else rs->sr_text = "no authz backend"; rc = LDAP_OTHER; #endif goto error_return; } if ( op->o_req_ndn.bv_len == 0 ) { rs->sr_text = "no password is associated with the Root DSE"; rc = LDAP_UNWILLING_TO_PERFORM; goto error_return; } /* If we've got a glued backend, check the real backend */ op_be = op->o_bd; if ( SLAP_GLUE_INSTANCE( op->o_bd )) { op->o_bd = select_backend( &op->o_req_ndn, 0 ); } if (backend_check_restrictions( op, rs, (struct berval *)&slap_EXOP_MODIFY_PASSWD ) != LDAP_SUCCESS) { rc = rs->sr_err; goto error_return; } /* check for referrals */ if ( backend_check_referrals( op, rs ) != LDAP_SUCCESS ) { rc = rs->sr_err; goto error_return; } /* This does not apply to multi-master case */ if(!( !SLAP_SINGLE_SHADOW( op->o_bd ) || be_isupdate( op ))) { /* we SHOULD return a referral in this case */ BerVarray defref = op->o_bd->be_update_refs ? op->o_bd->be_update_refs : default_referral; if( defref != NULL ) { rs->sr_ref = referral_rewrite( op->o_bd->be_update_refs, NULL, NULL, LDAP_SCOPE_DEFAULT ); if(rs->sr_ref) { rs->sr_flags |= REP_REF_MUSTBEFREED; } else { rs->sr_ref = defref; } rc = LDAP_REFERRAL; goto error_return; } rs->sr_text = "shadow context; no update referral"; rc = LDAP_UNWILLING_TO_PERFORM; goto error_return; } /* generate a new password if none was provided */ if ( qpw->rs_new.bv_len == 0 ) { slap_passwd_generate( &qpw->rs_new ); if ( qpw->rs_new.bv_len ) { rsp = slap_passwd_return( &qpw->rs_new ); freenewpw = 1; } } if ( qpw->rs_new.bv_len == 0 ) { rs->sr_text = "password generation failed"; rc = LDAP_OTHER; goto error_return; } op->o_bd = op_be; /* Give the backend a chance to handle this itself */ if ( op->o_bd->be_extended ) { rs->sr_err = op->o_bd->be_extended( op, rs ); if ( rs->sr_err != LDAP_UNWILLING_TO_PERFORM && rs->sr_err != SLAP_CB_CONTINUE ) { rc = rs->sr_err; if ( rsp ) { rs->sr_rspdata = rsp; rsp = NULL; } goto error_return; } } /* The backend didn't handle it, so try it here */ if( op->o_bd && !op->o_bd->be_modify ) { rs->sr_text = "operation not supported for current user"; rc = LDAP_UNWILLING_TO_PERFORM; goto error_return; } if ( qpw->rs_old.bv_val != NULL ) { Entry *e = NULL; rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, slap_schema.si_ad_userPassword, 0, &e ); if ( rc == LDAP_SUCCESS && e ) { Attribute *a = attr_find( e->e_attrs, slap_schema.si_ad_userPassword ); if ( a ) rc = slap_passwd_check( op, e, a, &qpw->rs_old, &rs->sr_text ); else rc = 1; be_entry_release_r( op, e ); if ( rc == LDAP_SUCCESS ) goto old_good; } rs->sr_text = "unwilling to verify old password"; rc = LDAP_UNWILLING_TO_PERFORM; goto error_return; } old_good: ml = ch_malloc( sizeof(Modifications) ); if ( !qpw->rs_modtail ) qpw->rs_modtail = &ml->sml_next; if ( default_passwd_hash ) { for ( nhash = 0; default_passwd_hash[nhash]; nhash++ ); hashes = default_passwd_hash; } else { nhash = 1; hashes = (char **)defhash; } ml->sml_numvals = nhash; ml->sml_values = ch_malloc( (nhash+1)*sizeof(struct berval) ); for ( i=0; hashes[i]; i++ ) { slap_passwd_hash_type( &qpw->rs_new, &hash, hashes[i], &rs->sr_text ); if ( hash.bv_len == 0 ) { if ( !rs->sr_text ) { rs->sr_text = "password hash failed"; } break; } ml->sml_values[i] = hash; } ml->sml_values[i].bv_val = NULL; ml->sml_nvalues = NULL; ml->sml_desc = slap_schema.si_ad_userPassword; ml->sml_type = ml->sml_desc->ad_cname; ml->sml_op = LDAP_MOD_REPLACE; ml->sml_flags = 0; ml->sml_next = qpw->rs_mods; qpw->rs_mods = ml; if ( hashes[i] ) { rs->sr_err = LDAP_OTHER; } else { slap_callback *sc = op->o_callback; op->o_tag = LDAP_REQ_MODIFY; op->o_callback = &cb; op->orm_modlist = qpw->rs_mods; op->orm_no_opattrs = 0; cb.sc_private = qpw; /* let Modify know this was pwdMod, * if it cares... */ rs->sr_err = op->o_bd->be_modify( op, rs ); /* be_modify() might have shuffled modifications */ qpw->rs_mods = op->orm_modlist; if ( rs->sr_err == LDAP_SUCCESS ) { rs->sr_rspdata = rsp; } else if ( rsp ) { ber_bvfree( rsp ); rsp = NULL; } op->o_tag = LDAP_REQ_EXTENDED; op->o_callback = sc; } rc = rs->sr_err; op->oq_extended = qext; error_return:; if ( qpw->rs_mods ) { slap_mods_free( qpw->rs_mods, 1 ); } if ( freenewpw ) { free( qpw->rs_new.bv_val ); } if ( !BER_BVISNULL( &dn ) ) { op->o_tmpfree( dn.bv_val, op->o_tmpmemctx ); BER_BVZERO( &op->o_req_dn ); } if ( !BER_BVISNULL( &ndn ) ) { op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx ); BER_BVZERO( &op->o_req_ndn ); } return rc; }
static int pblock_get( Slapi_PBlock *pb, int param, void **value ) { int rc = PBLOCK_SUCCESS; pblock_lock( pb ); switch ( param ) { case SLAPI_OPERATION: *value = pb->pb_op; break; case SLAPI_OPINITIATED_TIME: PBLOCK_ASSERT_OP( pb, 0 ); *((long *)value) = pb->pb_op->o_time; break; case SLAPI_OPERATION_ID: PBLOCK_ASSERT_OP( pb, 0 ); *((long *)value) = pb->pb_op->o_opid; break; case SLAPI_OPERATION_TYPE: PBLOCK_ASSERT_OP( pb, 0 ); *((ber_tag_t *)value) = pb->pb_op->o_tag; break; case SLAPI_OPERATION_MSGID: PBLOCK_ASSERT_OP( pb, 0 ); *((long *)value) = pb->pb_op->o_msgid; break; case SLAPI_X_OPERATION_DELETE_GLUE_PARENT: PBLOCK_ASSERT_OP( pb, 0 ); *((int *)value) = pb->pb_op->o_delete_glue_parent; break; case SLAPI_X_OPERATION_NO_SCHEMA_CHECK: PBLOCK_ASSERT_OP( pb, 0 ); *((int *)value) = get_no_schema_check( pb->pb_op ); break; case SLAPI_X_ADD_STRUCTURAL_CLASS: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) { struct berval tmpval = BER_BVNULL; rc = mods_structural_class( pb->pb_op->ora_modlist, &tmpval, &pb->pb_rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ), pb->pb_op->o_tmpmemctx ); *((char **)value) = tmpval.bv_val; } else { rc = PBLOCK_ERROR; } break; case SLAPI_X_OPERATION_NO_SUBORDINATE_GLUE: PBLOCK_ASSERT_OP( pb, 0 ); *((int *)value) = pb->pb_op->o_no_subordinate_glue; break; case SLAPI_REQCONTROLS: PBLOCK_ASSERT_OP( pb, 0 ); *((LDAPControl ***)value) = pb->pb_op->o_ctrls; break; case SLAPI_REQUESTOR_DN: PBLOCK_ASSERT_OP( pb, 0 ); *((char **)value) = pb->pb_op->o_dn.bv_val; break; case SLAPI_MANAGEDSAIT: PBLOCK_ASSERT_OP( pb, 0 ); *((int *)value) = get_manageDSAit( pb->pb_op ); break; case SLAPI_X_RELAX: PBLOCK_ASSERT_OP( pb, 0 ); *((int *)value) = get_relax( pb->pb_op ); break; case SLAPI_BACKEND: PBLOCK_ASSERT_OP( pb, 0 ); *((BackendDB **)value) = select_backend( &pb->pb_op->o_req_ndn, 0 ); break; case SLAPI_BE_TYPE: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_bd != NULL ) *((char **)value) = pb->pb_op->o_bd->bd_info->bi_type; else *value = NULL; break; case SLAPI_CONNECTION: *value = pb->pb_conn; break; case SLAPI_X_CONN_SSF: PBLOCK_ASSERT_OP( pb, 0 ); *((slap_ssf_t *)value) = pb->pb_conn->c_ssf; break; case SLAPI_X_CONN_SASL_CONTEXT: PBLOCK_ASSERT_CONN( pb ); if ( pb->pb_conn->c_sasl_authctx != NULL ) *value = pb->pb_conn->c_sasl_authctx; else *value = pb->pb_conn->c_sasl_sockctx; break; case SLAPI_TARGET_DN: PBLOCK_ASSERT_OP( pb, 0 ); *((char **)value) = pb->pb_op->o_req_dn.bv_val; break; case SLAPI_REQUESTOR_ISROOT: *((int *)value) = pblock_be_call( pb, be_isroot ); break; case SLAPI_IS_REPLICATED_OPERATION: *((int *)value) = pblock_be_call( pb, be_slurp_update ); break; case SLAPI_CONN_AUTHTYPE: case SLAPI_CONN_AUTHMETHOD: /* XXX should return SASL mech */ PBLOCK_ASSERT_CONN( pb ); *((char **)value) = pblock_get_authtype( &pb->pb_conn->c_authz, #ifdef HAVE_TLS pb->pb_conn->c_is_tls #else 0 #endif ); break; case SLAPI_IS_INTERNAL_OPERATION: *((int *)value) = pb->pb_intop; break; case SLAPI_X_CONN_IS_UDP: PBLOCK_ASSERT_CONN( pb ); #ifdef LDAP_CONNECTIONLESS *((int *)value) = pb->pb_conn->c_is_udp; #else *((int *)value) = 0; #endif break; case SLAPI_CONN_ID: PBLOCK_ASSERT_CONN( pb ); *((long *)value) = pb->pb_conn->c_connid; break; case SLAPI_CONN_DN: PBLOCK_ASSERT_CONN( pb ); #if 0 /* This would be necessary to keep plugin compat after the fix in ITS#4158 */ if ( pb->pb_op->o_tag == LDAP_REQ_BIND && pb->pb_rs->sr_err == LDAP_SUCCESS ) *((char **)value) = pb->pb_op->orb_edn.bv_val; else #endif *((char **)value) = pb->pb_conn->c_dn.bv_val; break; case SLAPI_CONN_CLIENTIP: PBLOCK_ASSERT_CONN( pb ); if ( strncmp( pb->pb_conn->c_peer_name.bv_val, "IP=", 3 ) == 0 ) *((char **)value) = &pb->pb_conn->c_peer_name.bv_val[3]; else *value = NULL; break; case SLAPI_X_CONN_CLIENTPATH: PBLOCK_ASSERT_CONN( pb ); if ( strncmp( pb->pb_conn->c_peer_name.bv_val, "PATH=", 3 ) == 0 ) *((char **)value) = &pb->pb_conn->c_peer_name.bv_val[5]; else *value = NULL; break; case SLAPI_CONN_SERVERIP: PBLOCK_ASSERT_CONN( pb ); if ( strncmp( pb->pb_conn->c_sock_name.bv_val, "IP=", 3 ) == 0 ) *((char **)value) = &pb->pb_conn->c_sock_name.bv_val[3]; else *value = NULL; break; case SLAPI_X_CONN_SERVERPATH: PBLOCK_ASSERT_CONN( pb ); if ( strncmp( pb->pb_conn->c_sock_name.bv_val, "PATH=", 3 ) == 0 ) *((char **)value) = &pb->pb_conn->c_sock_name.bv_val[5]; else *value = NULL; break; case SLAPI_RESULT_CODE: case SLAPI_PLUGIN_INTOP_RESULT: PBLOCK_ASSERT_OP( pb, 0 ); *((int *)value) = pb->pb_rs->sr_err; break; case SLAPI_RESULT_TEXT: PBLOCK_ASSERT_OP( pb, 0 ); *((const char **)value) = pb->pb_rs->sr_text; break; case SLAPI_RESULT_MATCHED: PBLOCK_ASSERT_OP( pb, 0 ); *((const char **)value) = pb->pb_rs->sr_matched; break; case SLAPI_ADD_ENTRY: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) *((Slapi_Entry **)value) = pb->pb_op->ora_e; else *value = NULL; break; case SLAPI_MODIFY_MODS: { LDAPMod **mods = NULL; Modifications *ml = NULL; pblock_get_default( pb, param, (void **)&mods ); if ( mods == NULL && pb->pb_intop == 0 ) { switch ( pb->pb_op->o_tag ) { case LDAP_REQ_MODIFY: ml = pb->pb_op->orm_modlist; break; case LDAP_REQ_MODRDN: ml = pb->pb_op->orr_modlist; break; default: rc = PBLOCK_ERROR; break; } if ( rc != PBLOCK_ERROR ) { mods = slapi_int_modifications2ldapmods( ml ); pblock_set_default( pb, param, (void *)mods ); } } *((LDAPMod ***)value) = mods; break; } case SLAPI_MODRDN_NEWRDN: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) *((char **)value) = pb->pb_op->orr_newrdn.bv_val; else *value = NULL; break; case SLAPI_MODRDN_NEWSUPERIOR: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN && pb->pb_op->orr_newSup != NULL ) *((char **)value) = pb->pb_op->orr_newSup->bv_val; else *value = NULL; break; case SLAPI_MODRDN_DELOLDRDN: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) *((int *)value) = pb->pb_op->orr_deleteoldrdn; else *((int *)value) = 0; break; case SLAPI_SEARCH_SCOPE: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) *((int *)value) = pb->pb_op->ors_scope; else *((int *)value) = 0; break; case SLAPI_SEARCH_DEREF: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) *((int *)value) = pb->pb_op->ors_deref; else *((int *)value) = 0; break; case SLAPI_SEARCH_SIZELIMIT: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) *((int *)value) = pb->pb_op->ors_slimit; else *((int *)value) = 0; break; case SLAPI_SEARCH_TIMELIMIT: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) *((int *)value) = pb->pb_op->ors_tlimit; else *((int *)value) = 0; break; case SLAPI_SEARCH_FILTER: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) *((Slapi_Filter **)value) = pb->pb_op->ors_filter; else *((Slapi_Filter **)value) = NULL; break; case SLAPI_SEARCH_STRFILTER: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) *((char **)value) = pb->pb_op->ors_filterstr.bv_val; else *((char **)value) = NULL; break; case SLAPI_SEARCH_ATTRS: { char **attrs = NULL; PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag != LDAP_REQ_SEARCH ) { rc = PBLOCK_ERROR; break; } pblock_get_default( pb, param, (void **)&attrs ); if ( attrs == NULL && pb->pb_intop == 0 ) { attrs = anlist2charray_x( pb->pb_op->ors_attrs, 0, pb->pb_op->o_tmpmemctx ); pblock_set_default( pb, param, (void *)attrs ); } *((char ***)value) = attrs; break; } case SLAPI_SEARCH_ATTRSONLY: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) *((int *)value) = pb->pb_op->ors_attrsonly; else *((int *)value) = 0; break; case SLAPI_SEARCH_RESULT_ENTRY: PBLOCK_ASSERT_OP( pb, 0 ); *((Slapi_Entry **)value) = pb->pb_rs->sr_entry; break; case SLAPI_BIND_RET_SASLCREDS: PBLOCK_ASSERT_OP( pb, 0 ); *((struct berval **)value) = pb->pb_rs->sr_sasldata; break; case SLAPI_EXT_OP_REQ_OID: *((const char **)value) = pb->pb_op->ore_reqoid.bv_val; break; case SLAPI_EXT_OP_REQ_VALUE: *((struct berval **)value) = pb->pb_op->ore_reqdata; break; case SLAPI_EXT_OP_RET_OID: PBLOCK_ASSERT_OP( pb, 0 ); *((const char **)value) = pb->pb_rs->sr_rspoid; break; case SLAPI_EXT_OP_RET_VALUE: PBLOCK_ASSERT_OP( pb, 0 ); *((struct berval **)value) = pb->pb_rs->sr_rspdata; break; case SLAPI_BIND_METHOD: if ( pb->pb_op->o_tag == LDAP_REQ_BIND ) *((int *)value) = pb->pb_op->orb_method; else *((int *)value) = 0; break; case SLAPI_BIND_CREDENTIALS: if ( pb->pb_op->o_tag == LDAP_REQ_BIND ) *((struct berval **)value) = &pb->pb_op->orb_cred; else *value = NULL; break; case SLAPI_COMPARE_TYPE: if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE ) *((char **)value) = pb->pb_op->orc_ava->aa_desc->ad_cname.bv_val; else *value = NULL; break; case SLAPI_COMPARE_VALUE: if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE ) *((struct berval **)value) = &pb->pb_op->orc_ava->aa_value; else *value = NULL; break; case SLAPI_ABANDON_MSGID: if ( pb->pb_op->o_tag == LDAP_REQ_ABANDON ) *((int *)value) = pb->pb_op->orn_msgid; else *((int *)value) = 0; break; default: rc = pblock_get_default( pb, param, value ); break; } pblock_unlock( pb ); return rc; }
static int slapi_over_acl_group( Operation *op, Entry *target, struct berval *gr_ndn, struct berval *op_ndn, ObjectClass *group_oc, AttributeDescription *group_at ) { Slapi_Entry *e; int rc; Slapi_PBlock *pb; BackendDB *be = op->o_bd; GroupAssertion *g; SlapReply rs = { REP_RESULT }; op->o_bd = select_backend( gr_ndn, 0 ); for ( g = op->o_groups; g; g = g->ga_next ) { if ( g->ga_be != op->o_bd || g->ga_oc != group_oc || g->ga_at != group_at || g->ga_len != gr_ndn->bv_len ) { continue; } if ( strcmp( g->ga_ndn, gr_ndn->bv_val ) == 0 ) { break; } } if ( g != NULL ) { rc = g->ga_res; goto done; } if ( target != NULL && dn_match( &target->e_nname, gr_ndn ) ) { e = target; rc = 0; } else { rc = be_entry_get_rw( op, gr_ndn, group_oc, group_at, 0, &e ); } if ( e != NULL ) { int internal_op; slap_callback cb; internal_op = slapi_op_internal_p( op, &rs, &cb ); cb.sc_response = NULL; cb.sc_cleanup = NULL; pb = SLAPI_OPERATION_PBLOCK( op ); slapi_pblock_set( pb, SLAPI_X_GROUP_ENTRY, (void *)e ); slapi_pblock_set( pb, SLAPI_X_GROUP_OPERATION_DN, (void *)op_ndn->bv_val ); slapi_pblock_set( pb, SLAPI_X_GROUP_ATTRIBUTE, (void *)group_at->ad_cname.bv_val ); slapi_pblock_set( pb, SLAPI_X_GROUP_TARGET_ENTRY, (void *)target ); rc = slapi_over_call_plugins( pb, SLAPI_X_PLUGIN_PRE_GROUP_FN ); if ( rc >= 0 ) /* 1 means no plugins called */ rc = SLAP_CB_CONTINUE; else rc = pb->pb_rs->sr_err; slapi_pblock_delete_param( pb, SLAPI_X_GROUP_ENTRY ); slapi_pblock_delete_param( pb, SLAPI_X_GROUP_OPERATION_DN ); slapi_pblock_delete_param( pb, SLAPI_X_GROUP_ATTRIBUTE ); slapi_pblock_delete_param( pb, SLAPI_X_GROUP_TARGET_ENTRY ); if ( !internal_op ) slapi_pblock_destroy( pb ); if ( e != target ) { be_entry_release_r( op, e ); } op->o_callback = cb.sc_next; } else { rc = LDAP_NO_SUCH_OBJECT; /* return SLAP_CB_CONTINUE for correctness? */ } if ( op->o_tag != LDAP_REQ_BIND && !op->o_do_not_cache && rc != SLAP_CB_CONTINUE ) { g = op->o_tmpalloc( sizeof( GroupAssertion ) + gr_ndn->bv_len, op->o_tmpmemctx ); g->ga_be = op->o_bd; g->ga_oc = group_oc; g->ga_at = group_at; g->ga_res = rc; g->ga_len = gr_ndn->bv_len; strcpy( g->ga_ndn, gr_ndn->bv_val ); g->ga_next = op->o_groups; op->o_groups = g; } /* * XXX don't call POST_GROUP_FN, I have no idea what the point of * that plugin function was anyway */ done: op->o_bd = be; return rc; }
int fe_op_compare( Operation *op, SlapReply *rs ) { Entry *entry = NULL; AttributeAssertion *ava = op->orc_ava; BackendDB *bd = op->o_bd; if( strcasecmp( op->o_req_ndn.bv_val, LDAP_ROOT_DSE ) == 0 ) { if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } rs->sr_err = root_dse_info( op->o_conn, &entry, &rs->sr_text ); if( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } } else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) { if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); rs->sr_err = 0; goto cleanup; } rs->sr_err = schema_info( &entry, &rs->sr_text ); if( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); rs->sr_err = 0; goto cleanup; } } if( entry ) { rs->sr_err = slap_compare_entry( op, entry, ava ); entry_free( entry ); send_ldap_result( op, rs ); if( rs->sr_err == LDAP_COMPARE_TRUE || rs->sr_err == LDAP_COMPARE_FALSE ) { rs->sr_err = LDAP_SUCCESS; } goto cleanup; } /* * We could be serving multiple database backends. Select the * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ op->o_bd = select_backend( &op->o_req_ndn, 0 ); if ( op->o_bd == NULL ) { rs->sr_ref = referral_rewrite( default_referral, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); rs->sr_err = LDAP_REFERRAL; if (!rs->sr_ref) rs->sr_ref = default_referral; op->o_bd = bd; send_ldap_result( op, rs ); if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref ); rs->sr_err = 0; goto cleanup; } /* check restrictions */ if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } /* check for referrals */ if( backend_check_referrals( op, rs ) != LDAP_SUCCESS ) { goto cleanup; } if ( SLAP_SHADOW(op->o_bd) && get_dontUseCopy(op) ) { /* don't use shadow copy */ send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "copy not used" ); } else if ( ava->aa_desc == slap_schema.si_ad_entryDN ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "entryDN compare not supported" ); } else if ( ava->aa_desc == slap_schema.si_ad_subschemaSubentry ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "subschemaSubentry compare not supported" ); #ifndef SLAP_COMPARE_IN_FRONTEND } else if ( ava->aa_desc == slap_schema.si_ad_hasSubordinates && op->o_bd->be_has_subordinates ) { int rc, hasSubordinates = LDAP_SUCCESS; rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &entry ); if ( rc == 0 && entry ) { if ( ! access_allowed( op, entry, ava->aa_desc, &ava->aa_value, ACL_COMPARE, NULL ) ) { rc = rs->sr_err = LDAP_INSUFFICIENT_ACCESS; } else { rc = rs->sr_err = op->o_bd->be_has_subordinates( op, entry, &hasSubordinates ); be_entry_release_r( op, entry ); } } if ( rc == 0 ) { int asserted; asserted = bvmatch( &ava->aa_value, &slap_true_bv ) ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE; if ( hasSubordinates == asserted ) { rs->sr_err = LDAP_COMPARE_TRUE; } else { rs->sr_err = LDAP_COMPARE_FALSE; } } else { /* return error only if "disclose" * is granted on the object */ if ( backend_access( op, NULL, &op->o_req_ndn, slap_schema.si_ad_entry, NULL, ACL_DISCLOSE, NULL ) == LDAP_INSUFFICIENT_ACCESS ) { rs->sr_err = LDAP_NO_SUCH_OBJECT; } } send_ldap_result( op, rs ); if ( rc == 0 ) { rs->sr_err = LDAP_SUCCESS; } } else if ( op->o_bd->be_compare ) { rs->sr_err = op->o_bd->be_compare( op, rs ); #endif /* ! SLAP_COMPARE_IN_FRONTEND */ } else { rs->sr_err = SLAP_CB_CONTINUE; } if ( rs->sr_err == SLAP_CB_CONTINUE ) { /* do our best to compare that AVA * * NOTE: this code is used only * if SLAP_COMPARE_IN_FRONTEND * is #define'd (it's not by default) * or if op->o_bd->be_compare is NULL. * * FIXME: one potential issue is that * if SLAP_COMPARE_IN_FRONTEND overlays * are not executed for compare. */ BerVarray vals = NULL; int rc = LDAP_OTHER; rs->sr_err = backend_attribute( op, NULL, &op->o_req_ndn, ava->aa_desc, &vals, ACL_COMPARE ); switch ( rs->sr_err ) { default: /* return error only if "disclose" * is granted on the object */ if ( backend_access( op, NULL, &op->o_req_ndn, slap_schema.si_ad_entry, NULL, ACL_DISCLOSE, NULL ) == LDAP_INSUFFICIENT_ACCESS ) { rs->sr_err = LDAP_NO_SUCH_OBJECT; } break; case LDAP_SUCCESS: if ( value_find_ex( op->oq_compare.rs_ava->aa_desc, SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, vals, &ava->aa_value, op->o_tmpmemctx ) == 0 ) { rs->sr_err = LDAP_COMPARE_TRUE; break; } else { rs->sr_err = LDAP_COMPARE_FALSE; } rc = LDAP_SUCCESS; break; } send_ldap_result( op, rs ); if ( rc == 0 ) { rs->sr_err = LDAP_SUCCESS; } if ( vals ) { ber_bvarray_free_x( vals, op->o_tmpmemctx ); } } cleanup:; op->o_bd = bd; return rs->sr_err; }
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; }
int fe_op_modify( Operation *op, SlapReply *rs ) { BackendDB *op_be, *bd = op->o_bd; char textbuf[ SLAP_TEXT_BUFLEN ]; size_t textlen = sizeof( textbuf ); if ( BER_BVISEMPTY( &op->o_req_ndn ) ) { Debug( LDAP_DEBUG_ANY, "%s do_modify: root dse!\n", op->o_log_prefix, 0, 0 ); send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "modify upon the root DSE not supported" ); goto cleanup; } else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) { Debug( LDAP_DEBUG_ANY, "%s do_modify: subschema subentry!\n", op->o_log_prefix, 0, 0 ); send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "modification of subschema subentry not supported" ); goto cleanup; } /* * We could be serving multiple database backends. Select the * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ op->o_bd = select_backend( &op->o_req_ndn, 1 ); if ( op->o_bd == NULL ) { op->o_bd = bd; rs->sr_ref = referral_rewrite( default_referral, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); if ( !rs->sr_ref ) { rs->sr_ref = default_referral; } if ( rs->sr_ref != NULL ) { rs->sr_err = LDAP_REFERRAL; send_ldap_result( op, rs ); if ( rs->sr_ref != default_referral ) { ber_bvarray_free( rs->sr_ref ); } } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "no global superior knowledge" ); } goto cleanup; } /* If we've got a glued backend, check the real backend */ op_be = op->o_bd; if ( SLAP_GLUE_INSTANCE( op->o_bd )) { op->o_bd = select_backend( &op->o_req_ndn, 0 ); } /* check restrictions */ if ( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } /* check for referrals */ if ( backend_check_referrals( op, rs ) != LDAP_SUCCESS ) { goto cleanup; } rs->sr_err = slap_mods_obsolete_check( op, op->orm_modlist, &rs->sr_text, textbuf, textlen ); if ( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } /* check for modify/increment support */ if ( op->orm_increment && !SLAP_INCREMENT( op->o_bd ) ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "modify/increment not supported in context" ); goto cleanup; } /* * do the modify if 1 && (2 || 3) * 1) there is a modify function implemented in this backend; * 2) this backend is master for what it holds; * 3) it's a replica and the dn supplied is the update_ndn. */ if ( op->o_bd->be_modify ) { /* do the update here */ int repl_user = be_isupdate( op ); /* * Multimaster slapd does not have to check for replicator dn * because it accepts each modify request */ if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user ) { int update = !BER_BVISEMPTY( &op->o_bd->be_update_ndn ); op->o_bd = op_be; if ( !update ) { rs->sr_err = slap_mods_no_user_mod_check( op, op->orm_modlist, &rs->sr_text, textbuf, textlen ); if ( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } } op->o_bd->be_modify( op, rs ); } else { /* send a referral */ BerVarray defref = op->o_bd->be_update_refs ? op->o_bd->be_update_refs : default_referral; if ( defref != NULL ) { rs->sr_ref = referral_rewrite( defref, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); if ( rs->sr_ref == NULL ) { /* FIXME: must duplicate, because * overlays may muck with it */ rs->sr_ref = defref; } rs->sr_err = LDAP_REFERRAL; send_ldap_result( op, rs ); if ( rs->sr_ref != defref ) { ber_bvarray_free( rs->sr_ref ); } } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "shadow context; no update referral" ); } } } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "operation not supported within namingContext" ); } cleanup:; op->o_bd = bd; return rs->sr_err; }
static void process_read_frontend(struct conn_context *ctx) { int ep_fd, front_fd, end_fd; char *buf = ctx->buf; int events = ctx->events; struct epoll_event evt; struct sockaddr_in addr_in; int ret; int cpu_id = ctx->cpu_id; ep_fd = ctx->ep_fd; front_fd = ctx->fd; //FIXME: What else should I do. if (events & (EPOLLHUP | EPOLLERR)) { printf("process_read_frontend() with events HUP or ERR\n"); goto free_back; } print_d("Process read event[%02x] on front-end socket %d\n", events, front_fd); ret = read(front_fd, buf, MAX_BUFSIZE); if (ret < 0) { wdata[cpu_id].read_cnt++; perror("process_read_frontend() can't read client socket"); goto free_back; } ctx->data_len = ret; print_d("Read %d from front-end socket %d\n", ret, front_fd); //Remove interested read event for front-end socket evt.events = EPOLLHUP | EPOLLERR; evt.data.ptr = ctx; ret = epoll_ctl(ep_fd, EPOLL_CTL_MOD, front_fd, &evt); if (ret < 0) { perror("Unable to add client socket read event to epoll"); goto free_back; } int flags; ret = socket(AF_INET, SOCK_STREAM, 0); if (ret < 0) { perror("Unable to create new socket for backend"); goto free_back; } end_fd = ret; ctx->end_fd = end_fd; print_d("Create socket %d\n", ret); flags = fcntl(ret, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(ret, F_SETFL, flags); struct linger ling = {1, 0}; ret = setsockopt(end_fd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling)); if (ret < 0) { perror("Unable to set socket linger option"); goto free_back; } select_backend(&addr_in); ret = connect(end_fd, (struct sockaddr *)&addr_in, sizeof(struct sockaddr)); if (ret < 0) { if (errno != EINPROGRESS) { perror("Unable to connect to back end server"); goto free_back; } } ctx->handler = process_write_backend; ctx->flags |= PROXY_BACKEND_EVENT; evt.events = EPOLLOUT | EPOLLHUP | EPOLLERR; evt.data.ptr = ctx; ret = epoll_ctl(ep_fd, EPOLL_CTL_ADD, end_fd, &evt); if (ret < 0) { perror("Unable to add client socket read event to epoll"); goto free_back; } ctx->end_fd_added = 1; print_d("Add back-end socket %d to epoll\n", end_fd); goto back; free_back: print_d("cpu[%d] close socket %d\n", cpu_id, ctx->fd); process_close(ctx); free_context(ctx); back: return; }
static int relay_back_cf( ConfigArgs *c ) { relay_back_info *ri = ( relay_back_info * )c->be->be_private; int rc = 0; if ( c->op == SLAP_CONFIG_EMIT ) { if ( ri != NULL && !BER_BVISNULL( &ri->ri_realsuffix ) ) { value_add_one( &c->rvalue_vals, &ri->ri_realsuffix ); return 0; } return 1; } else if ( c->op == LDAP_MOD_DELETE ) { if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) { ch_free( ri->ri_realsuffix.bv_val ); BER_BVZERO( &ri->ri_realsuffix ); ri->ri_bd = NULL; return 0; } return 1; } else { BackendDB *bd; assert( ri != NULL ); assert( BER_BVISNULL( &ri->ri_realsuffix ) ); if ( c->be->be_nsuffix == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg), "\"relay\" directive " "must appear after \"suffix\"" ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); rc = 1; goto relay_done; } if ( !BER_BVISNULL( &c->be->be_nsuffix[ 1 ] ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg), "relaying of multiple suffix " "database not supported" ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); rc = 1; goto relay_done; } bd = select_backend( &c->value_ndn, 1 ); if ( bd == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg), "cannot find database " "of relay dn \"%s\" " "in \"olcRelay <dn>\"\n", c->value_dn.bv_val ); Log2( LDAP_DEBUG_CONFIG, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); } else if ( bd->be_private == c->be->be_private ) { snprintf( c->cr_msg, sizeof( c->cr_msg), "relay dn \"%s\" would call self " "in \"relay <dn>\" line\n", c->value_dn.bv_val ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); rc = 1; goto relay_done; } ri->ri_realsuffix = c->value_ndn; BER_BVZERO( &c->value_ndn ); relay_done:; ch_free( c->value_dn.bv_val ); ch_free( c->value_ndn.bv_val ); } return rc; }
static int dynlist_compare( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; dynlist_info_t *dli = (dynlist_info_t *)on->on_bi.bi_private; Operation o = *op; Entry *e = NULL; dynlist_map_t *dlm; BackendDB *be; for ( ; dli != NULL; dli = dli->dli_next ) { for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) if ( op->oq_compare.rs_ava->aa_desc == dlm->dlm_member_ad ) break; if ( dlm ) { /* This compare is for one of the attributes we're * interested in. We'll use slapd's existing dyngroup * evaluator to get the answer we want. */ BerVarray id = NULL, authz = NULL; o.o_do_not_cache = 1; if ( ad_dgIdentity && backend_attribute( &o, NULL, &o.o_req_ndn, ad_dgIdentity, &id, ACL_READ ) == LDAP_SUCCESS ) { /* if not rootdn and dgAuthz is present, * check if user can be authorized as dgIdentity */ if ( ad_dgAuthz && !BER_BVISEMPTY( id ) && !be_isroot( op ) && backend_attribute( &o, NULL, &o.o_req_ndn, ad_dgAuthz, &authz, ACL_READ ) == LDAP_SUCCESS ) { rs->sr_err = slap_sasl_matches( op, authz, &o.o_ndn, &o.o_ndn ); ber_bvarray_free_x( authz, op->o_tmpmemctx ); if ( rs->sr_err != LDAP_SUCCESS ) { goto done; } } o.o_dn = *id; o.o_ndn = *id; o.o_groups = NULL; /* authz changed, invalidate cached groups */ } rs->sr_err = backend_group( &o, NULL, &o.o_req_ndn, &o.oq_compare.rs_ava->aa_value, dli->dli_oc, dli->dli_ad ); switch ( rs->sr_err ) { case LDAP_SUCCESS: rs->sr_err = LDAP_COMPARE_TRUE; break; case LDAP_NO_SUCH_OBJECT: /* NOTE: backend_group() returns noSuchObject * if op_ndn does not exist; however, since * dynamic list expansion means that the * member attribute is virtually present, the * non-existence of the asserted value implies * the assertion is FALSE rather than * UNDEFINED */ rs->sr_err = LDAP_COMPARE_FALSE; break; } done:; if ( id ) ber_bvarray_free_x( id, o.o_tmpmemctx ); return SLAP_CB_CONTINUE; } } be = select_backend( &o.o_req_ndn, 1 ); if ( !be || !be->be_search ) { return SLAP_CB_CONTINUE; } if ( overlay_entry_get_ov( &o, &o.o_req_ndn, NULL, NULL, 0, &e, on ) != LDAP_SUCCESS || e == NULL ) { return SLAP_CB_CONTINUE; } /* check for dynlist objectClass; done if not found */ dli = (dynlist_info_t *)on->on_bi.bi_private; while ( dli != NULL && !is_entry_objectclass_or_sub( e, dli->dli_oc ) ) { dli = dli->dli_next; } if ( dli == NULL ) { goto release; } if ( ad_dgIdentity ) { Attribute *id = attrs_find( e->e_attrs, ad_dgIdentity ); if ( id ) { Attribute *authz; /* 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( e->e_attrs, ad_dgAuthz ) ) ) { if ( slap_sasl_matches( op, authz->a_nvals, &o.o_ndn, &o.o_ndn ) != LDAP_SUCCESS ) { goto release; } } o.o_dn = id->a_vals[0]; o.o_ndn = id->a_nvals[0]; o.o_groups = NULL; } } /* generate dynamic list with dynlist_response() and compare */ { SlapReply r = { REP_SEARCH }; dynlist_cc_t dc = { { 0, dynlist_sc_compare_entry, 0, 0 }, 0 }; AttributeName an[2]; dc.dc_ava = op->orc_ava; dc.dc_res = &rs->sr_err; o.o_callback = (slap_callback *) &dc; o.o_tag = LDAP_REQ_SEARCH; o.ors_limit = NULL; o.ors_tlimit = SLAP_NO_LIMIT; o.ors_slimit = SLAP_NO_LIMIT; o.ors_filterstr = *slap_filterstr_objectClass_pres; o.ors_filter = (Filter *) slap_filter_objectClass_pres; o.ors_scope = LDAP_SCOPE_BASE; o.ors_deref = LDAP_DEREF_NEVER; an[0].an_name = op->orc_ava->aa_desc->ad_cname; an[0].an_desc = op->orc_ava->aa_desc; BER_BVZERO( &an[1].an_name ); o.ors_attrs = an; o.ors_attrsonly = 0; o.o_acl_priv = ACL_COMPARE; o.o_bd = be; (void)be->be_search( &o, &r ); if ( o.o_dn.bv_val != op->o_dn.bv_val ) { slap_op_groups_free( &o ); } } release:; if ( e != NULL ) { overlay_entry_release_ov( &o, e, 0, on ); } return SLAP_CB_CONTINUE; }
int fe_op_search( Operation *op, SlapReply *rs ) { BackendDB *bd = op->o_bd; if ( op->ors_scope == LDAP_SCOPE_BASE ) { Entry *entry = NULL; if ( BER_BVISEMPTY( &op->o_req_ndn ) ) { #ifdef LDAP_CONNECTIONLESS /* Ignore LDAPv2 CLDAP Root DSE queries */ if (op->o_protocol == LDAP_VERSION2 && op->o_conn->c_is_udp) { goto return_results; } #endif /* check restrictions */ if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto return_results; } rs->sr_err = root_dse_info( op->o_conn, &entry, &rs->sr_text ); } else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) { /* check restrictions */ if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto return_results; } rs->sr_err = schema_info( &entry, &rs->sr_text ); } if( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto return_results; } else if ( entry != NULL ) { if ( get_assert( op ) && ( test_filter( op, entry, get_assertion( op )) != LDAP_COMPARE_TRUE )) { rs->sr_err = LDAP_ASSERTION_FAILED; goto fail1; } rs->sr_err = test_filter( op, entry, op->ors_filter ); if( rs->sr_err == LDAP_COMPARE_TRUE ) { /* note: we set no limits because either * no limit is specified, or at least 1 * is specified, and we're going to return * at most one entry */ op->ors_slimit = SLAP_NO_LIMIT; op->ors_tlimit = SLAP_NO_LIMIT; rs->sr_entry = entry; rs->sr_attrs = op->ors_attrs; rs->sr_operational_attrs = NULL; rs->sr_flags = 0; send_search_entry( op, rs ); rs->sr_entry = NULL; rs->sr_operational_attrs = NULL; } rs->sr_err = LDAP_SUCCESS; fail1: entry_free( entry ); send_ldap_result( op, rs ); goto return_results; } } if( BER_BVISEMPTY( &op->o_req_ndn ) && !BER_BVISEMPTY( &default_search_nbase ) ) { slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx ); slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx ); ber_dupbv_x( &op->o_req_dn, &default_search_base, op->o_tmpmemctx ); ber_dupbv_x( &op->o_req_ndn, &default_search_nbase, op->o_tmpmemctx ); } /* * We could be serving multiple database backends. Select the * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ op->o_bd = select_backend( &op->o_req_ndn, 1 ); if ( op->o_bd == NULL ) { rs->sr_ref = referral_rewrite( default_referral, NULL, &op->o_req_dn, op->ors_scope ); if (!rs->sr_ref) rs->sr_ref = default_referral; rs->sr_err = LDAP_REFERRAL; op->o_bd = bd; send_ldap_result( op, rs ); if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref ); rs->sr_ref = NULL; goto return_results; } /* check restrictions */ if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto return_results; } /* check for referrals */ if( backend_check_referrals( op, rs ) != LDAP_SUCCESS ) { goto return_results; } if ( SLAP_SHADOW(op->o_bd) && get_dontUseCopy(op) ) { /* don't use shadow copy */ BerVarray defref = op->o_bd->be_update_refs ? op->o_bd->be_update_refs : default_referral; if( defref != NULL ) { rs->sr_ref = referral_rewrite( defref, NULL, &op->o_req_dn, op->ors_scope ); if( !rs->sr_ref) rs->sr_ref = defref; rs->sr_err = LDAP_REFERRAL; send_ldap_result( op, rs ); if (rs->sr_ref != defref) ber_bvarray_free( rs->sr_ref ); } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "copy not used; no referral information available" ); } } else if ( op->o_bd->be_search ) { if ( limits_check( op, rs ) == 0 ) { /* actually do the search and send the result(s) */ (op->o_bd->be_search)( op, rs ); } /* else limits_check() sends error */ } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "operation not supported within namingContext" ); } return_results:; op->o_bd = bd; return rs->sr_err; }
static int idattr_dynacl_mask( void *priv, Operation *op, Entry *target, AttributeDescription *desc, struct berval *val, int nmatch, regmatch_t *matches, slap_access_t *grant, slap_access_t *deny ) { idattr_t *id = (idattr_t *)priv; Entry *user = NULL; int rc = LDAP_INSUFFICIENT_ACCESS; int user_rc = LDAP_INSUFFICIENT_ACCESS; int target_rc = LDAP_INSUFFICIENT_ACCESS; Backend *be = op->o_bd, *group_be = NULL, *user_be = NULL; AttributeDescription *searchAttr = NULL; ObjectClass *searchObject = NULL; struct berval *searchTarget = NULL; Entry *searchEntry = NULL; ACL_INVALIDATE( *deny ); Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: pat(%s) type(%d) op(%d)\n", id->idattr_pat.bv_val, id->idattr_type, id->idattr_ops ); Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: target(%s) op->o_ndn(%s)\n", target->e_nname.bv_val, op->o_ndn.bv_val, 0 ); if (id->idattr_ops && (id->idattr_ops != op->o_tag)) { Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: Operation Not Allowed - Ops allowed (%d), Requested Op (%d)\n", id->idattr_ops, op->o_tag, 0 ); // LDAP_INSUFFICIENT_ACCESS return 0; } if (!op->o_conn->c_authz.c_sai_krb5_auth_data_provisioned) { user_be = op->o_bd = select_backend( &op->o_ndn, 0); if ( op->o_bd == NULL ) { Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: op->o_bd == NULL \n", 0, 0, 0 ); op->o_bd = be; return 0; } } // check ACL TYPE Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: idattr_type(%d)\n", id->idattr_type, 0, 0 ); if (id->idattr_type == UUID_TYPE || id->idattr_type == OWNER_TYPE) { searchAttr = idattr_uuid; searchObject = idattr_extensible_object; searchTarget = &op->o_ndn; } else if (id->idattr_type == SID_TYPE) { searchAttr = idattr_sid; searchObject = idattr_extensible_object; searchTarget = &op->o_conn->c_authz.sai_ndn; } else if (id->idattr_type == SELFWRITE_TYPE) { searchAttr = id->idattr_selfattrDesc; searchObject = idattr_extensible_object; searchTarget = &op->o_ndn; } else if (id->idattr_type == USERS_TYPE) { if (BER_BVISEMPTY( &op->o_ndn )) { // LDAP_INSUFFICIENT_ACCESS op->o_bd = be; return 0; } else { // check for APPLYTO clause if (id->idattr_applyto) { rc = idattr_check_applyto(op, target, searchAttr, id); } else { rc = LDAP_SUCCESS; } goto assignaccess; } } else { Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: unknown idattr_type(%s)\n", id->idattr_type, 0, 0 ); // LDAP_INSUFFICIENT_ACCESS return 0; } if (op->o_conn->c_authz.c_sai_krb5_auth_data_provisioned) { user_rc = LDAP_SUCCESS; } else if (searchAttr) { // lookup user record user_rc = be_entry_get_rw( op, searchTarget, NULL, searchAttr, 0, &user ); Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: be_entry_get_rw user_rc(%d) user(%x) \n", user_rc, user, 0 ); if ( user_rc != LDAP_SUCCESS || user == NULL ) { op->o_bd = be; return 0; } } if ( user_rc == LDAP_SUCCESS || user != NULL ) { user_rc = idattr_check_isuser(op, user, searchAttr, id); if (user_rc == LDAP_SUCCESS) { switch ( id->idattr_type ) { case SELFWRITE_TYPE: user_rc = idattr_check_selfwrite(op, target, user, val, id); break; case OWNER_TYPE: user_rc = idattr_check_isowner(op, user, target, searchAttr, id); break; case UUID_TYPE: case SID_TYPE: user_rc = LDAP_SUCCESS; break; default: break; } if (user_rc == LDAP_SUCCESS) { if (id->idattr_applyto) { rc = idattr_check_applyto(op, target, searchAttr, id); } else { rc = LDAP_SUCCESS; } } } } else { rc = LDAP_NO_SUCH_OBJECT; } assignaccess: if ( rc == LDAP_SUCCESS ) { ACL_LVL_ASSIGN_WRITE( *grant ); } cleanup: if ( user != NULL) { op->o_bd = user_be; be_entry_release_r( op, user ); op->o_bd = be; } op->o_bd = be; return 0; }