static int filter2ber( char *filter ) { int rc; struct berval bv = BER_BVNULL; BerElement *ber; printf( "Filter: %s\n", filter ); ber = ber_alloc_t( LBER_USE_DER ); if( ber == NULL ) { perror( "ber_alloc_t" ); return EXIT_FAILURE; } rc = ldap_pvt_put_filter( ber, filter ); if( rc < 0 ) { fprintf( stderr, "Filter error!\n"); return EXIT_FAILURE; } rc = ber_flatten2( ber, &bv, 0 ); if( rc < 0 ) { perror( "ber_flatten2" ); return EXIT_FAILURE; } printf( "BER encoding (len=%ld):\n", (long) bv.bv_len ); ber_bprint( bv.bv_val, bv.bv_len ); ber_free( ber, 1 ); return EXIT_SUCCESS; }
int slap_read_controls( Operation *op, SlapReply *rs, Entry *e, const struct berval *oid, LDAPControl **ctrl ) { int rc; struct berval bv; BerElementBuffer berbuf; BerElement *ber = (BerElement *) &berbuf; LDAPControl c; Operation myop; Debug( LDAP_DEBUG_ANY, "%s slap_read_controls: (%s) %s\n", op->o_log_prefix, oid->bv_val, e->e_dn ); rs->sr_entry = e; rs->sr_attrs = ( oid == &slap_pre_read_bv ) ? op->o_preread_attrs : op->o_postread_attrs; bv.bv_len = entry_flatsize( rs->sr_entry, 0 ); bv.bv_val = op->o_tmpalloc( bv.bv_len, op->o_tmpmemctx ); ber_init2( ber, &bv, LBER_USE_DER ); ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); /* create new operation */ myop = *op; /* FIXME: o_bd needed for ACL */ myop.o_bd = op->o_bd; myop.o_res_ber = ber; myop.o_callback = NULL; myop.ors_slimit = 1; myop.ors_attrsonly = 0; rc = slap_send_search_entry( &myop, rs ); if( rc ) return rc; rc = ber_flatten2( ber, &c.ldctl_value, 0 ); if( rc == -1 ) return LDAP_OTHER; c.ldctl_oid = oid->bv_val; c.ldctl_iscritical = 0; if ( *ctrl == NULL ) { /* first try */ *ctrl = (LDAPControl *) slap_sl_calloc( 1, sizeof(LDAPControl), NULL ); } else { /* retry: free previous try */ slap_sl_free( (*ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); } **ctrl = c; return LDAP_SUCCESS; }
int VmDirCreateRequestVoteCtrl( PVDIR_REQUEST_VOTE_CONTROL_VALUE pRequestVoteCtrlValue, LDAPControl* pRequestVoteCtrl ) { int retVal = LDAP_SUCCESS; BerElement* pBer = NULL; BerValue candidateIdBV = {0}; BerValue lastLogIndexBV = {0}; if (!pRequestVoteCtrlValue || !pRequestVoteCtrl) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_INVALID_PARAMETER); } if ((pBer = ber_alloc()) == NULL) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_NO_MEMORY); } candidateIdBV.bv_val = pRequestVoteCtrlValue->candidateId; candidateIdBV.bv_len = VmDirStringLenA(pRequestVoteCtrlValue->candidateId); retVal = VmDirAllocateStringPrintf(&lastLogIndexBV.bv_val, "%"PRIu64, pRequestVoteCtrlValue->lastLogIndex); BAIL_ON_VMDIR_ERROR( retVal ); lastLogIndexBV.bv_len = VmDirStringLenA(lastLogIndexBV.bv_val); if ( ber_printf( pBer, "{iOOi}", pRequestVoteCtrlValue->term, &candidateIdBV, &lastLogIndexBV, pRequestVoteCtrlValue->lastLogTerm) == -1) { VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: ber_printf failed.", __FUNCTION__ ); BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_NO_MEMORY); } memset( pRequestVoteCtrl, 0, sizeof( LDAPControl )); pRequestVoteCtrl->ldctl_oid = LDAP_REQUEST_VOTE_CONTROL; pRequestVoteCtrl->ldctl_iscritical = '1'; if (ber_flatten2(pBer, &pRequestVoteCtrl->ldctl_value, 1)) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_NO_MEMORY); } cleanup: VMDIR_SAFE_FREE_MEMORY(lastLogIndexBV.bv_val); if (pBer) { ber_free(pBer, 1); } return retVal; error: VmDirFreeCtrlContent(pRequestVoteCtrl); goto cleanup; }
static void send_paged_response( Operation *op, SlapReply *rs, ID *lastid, int tentries ) { LDAPControl *ctrls[2]; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; PagedResultsCookie respcookie; struct berval cookie; Debug(LDAP_DEBUG_ARGS, "send_paged_response: lastid=0x%08lx nentries=%d\n", lastid ? *lastid : 0, rs->sr_nentries, NULL ); ctrls[1] = NULL; ber_init2( ber, NULL, LBER_USE_DER ); if ( lastid ) { respcookie = ( PagedResultsCookie )(*lastid); cookie.bv_len = sizeof( respcookie ); cookie.bv_val = (char *)&respcookie; } else { respcookie = ( PagedResultsCookie )0; BER_BVSTR( &cookie, "" ); } op->o_conn->c_pagedresults_state.ps_cookie = respcookie; op->o_conn->c_pagedresults_state.ps_count = ((PagedResultsState *)op->o_pagedresults_state)->ps_count + rs->sr_nentries; /* return size of 0 -- no estimate */ ber_printf( ber, "{iO}", 0, &cookie ); ctrls[0] = op->o_tmpalloc( sizeof(LDAPControl), op->o_tmpmemctx ); if ( ber_flatten2( ber, &ctrls[0]->ldctl_value, 0 ) == -1 ) { goto done; } ctrls[0]->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS; ctrls[0]->ldctl_iscritical = 0; slap_add_ctrls( op, rs, ctrls ); rs->sr_err = LDAP_SUCCESS; send_ldap_result( op, rs ); done: (void) ber_free_buf( ber ); }
int ldap_create_page_control_value( LDAP *ld, ber_int_t pagesize, struct berval *cookie, struct berval *value ) { BerElement *ber = NULL; ber_tag_t tag; struct berval null_cookie = { 0, NULL }; if ( ld == NULL || value == NULL || pagesize < 1 || pagesize > LDAP_MAXINT ) { if ( ld ) ld->ld_errno = LDAP_PARAM_ERROR; return LDAP_PARAM_ERROR; } assert( LDAP_VALID( ld ) ); value->bv_val = NULL; value->bv_len = 0; ld->ld_errno = LDAP_SUCCESS; if ( cookie == NULL ) { cookie = &null_cookie; } ber = ldap_alloc_ber_with_options( ld ); if ( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } tag = ber_printf( ber, "{iO}", pagesize, cookie ); if ( tag == LBER_ERROR ) { ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } if ( ber_flatten2( ber, value, 1 ) == -1 ) { ld->ld_errno = LDAP_NO_MEMORY; } done: ; if ( ber != NULL ) { ber_free( ber, 1 ); } return ld->ld_errno; }
static int pack_pagedresult_response_control( Operation *op, SlapReply *rs, sort_op *so, LDAPControl **ctrlsp ) { LDAPControl *ctrl; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; PagedResultsCookie resp_cookie; struct berval cookie, bv; int rc; ber_init2( ber, NULL, LBER_USE_DER ); ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); if ( so->so_nentries > 0 ) { resp_cookie = ( PagedResultsCookie )so->so_tree; cookie.bv_len = sizeof( PagedResultsCookie ); cookie.bv_val = (char *)&resp_cookie; } else { resp_cookie = ( PagedResultsCookie )0; BER_BVZERO( &cookie ); } op->o_conn->c_pagedresults_state.ps_cookie = resp_cookie; op->o_conn->c_pagedresults_state.ps_count = ((PagedResultsState *)op->o_pagedresults_state)->ps_count + rs->sr_nentries; rc = ber_printf( ber, "{iO}", so->so_nentries, &cookie ); if ( rc != -1 ) { rc = ber_flatten2( ber, &bv, 0 ); } if ( rc != -1 ) { ctrl = (LDAPControl *)op->o_tmpalloc( sizeof(LDAPControl)+ bv.bv_len, op->o_tmpmemctx ); ctrl->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS; ctrl->ldctl_iscritical = 0; ctrl->ldctl_value.bv_val = (char *)(ctrl+1); ctrl->ldctl_value.bv_len = bv.bv_len; memcpy( ctrl->ldctl_value.bv_val, bv.bv_val, bv.bv_len ); ctrlsp[0] = ctrl; } else { ctrlsp[0] = NULL; rs->sr_err = LDAP_OTHER; } ber_free_buf( ber ); return rs->sr_err; }
/* Rewrite an LDAP DN in DER form * Input must be valid DN, therefore no error checking is done here. */ static int autoca_dnbv2der( Operation *op, struct berval *bv, struct berval *der ) { BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; LDAPDN dn; LDAPRDN rdn; LDAPAVA *ava; AttributeDescription *ad; int irdn, iava; ldap_bv2dn_x( bv, &dn, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ); ber_init2( ber, NULL, LBER_USE_DER ); ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); /* count RDNs, we need them in reverse order */ for (irdn = 0; dn[irdn]; irdn++); irdn--; /* DN is a SEQuence of RDNs */ ber_start_seq( ber, LBER_SEQUENCE ); for (; irdn >=0; irdn--) { /* RDN is a SET of AVAs */ ber_start_set( ber, LBER_SET ); rdn = dn[irdn]; for (iava = 0; rdn[iava]; iava++) { const char *text; char oid[1024]; struct berval bvo = { sizeof(oid), oid }; struct berval bva; /* AVA is a SEQuence of attr and value */ ber_start_seq( ber, LBER_SEQUENCE ); ava = rdn[iava]; ad = NULL; slap_bv2ad( &ava->la_attr, &ad, &text ); ber_str2bv( ad->ad_type->sat_oid, 0, 0, &bva ); ber_encode_oid( &bva, &bvo ); ber_put_berval( ber, &bvo, LBER_TAG_OID ); ber_put_berval( ber, &ava->la_value, LBER_TAG_UTF8 ); ber_put_seq( ber ); } ber_put_set( ber ); } ber_put_seq( ber ); ber_flatten2( ber, der, 0 ); ldap_dnfree_x( dn, op->o_tmpmemctx ); return 0; }
static int pack_vlv_response_control( Operation *op, SlapReply *rs, sort_op *so, LDAPControl **ctrlsp ) { LDAPControl *ctrl; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; struct berval cookie, bv; int rc; ber_init2( ber, NULL, LBER_USE_DER ); ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); rc = ber_printf( ber, "{iie", so->so_vlv_target, so->so_nentries, so->so_vlv_rc ); if ( rc != -1 && so->so_vcontext ) { cookie.bv_val = (char *)&so->so_vcontext; cookie.bv_len = sizeof(so->so_vcontext); rc = ber_printf( ber, "tO", LDAP_VLVCONTEXT_IDENTIFIER, &cookie ); } if ( rc != -1 ) { rc = ber_printf( ber, "}" ); } if ( rc != -1 ) { rc = ber_flatten2( ber, &bv, 0 ); } if ( rc != -1 ) { ctrl = (LDAPControl *)op->o_tmpalloc( sizeof(LDAPControl)+ bv.bv_len, op->o_tmpmemctx ); ctrl->ldctl_oid = LDAP_CONTROL_VLVRESPONSE; ctrl->ldctl_iscritical = 0; ctrl->ldctl_value.bv_val = (char *)(ctrl+1); ctrl->ldctl_value.bv_len = bv.bv_len; memcpy( ctrl->ldctl_value.bv_val, bv.bv_val, bv.bv_len ); ctrlsp[0] = ctrl; } else { ctrlsp[0] = NULL; rs->sr_err = LDAP_OTHER; } ber_free_buf( ber ); return rs->sr_err; }
int ldap_refresh( LDAP *ld, struct berval *dn, ber_int_t ttl, LDAPControl **sctrls, LDAPControl **cctrls, int *msgidp ) { struct berval bv = { 0, NULL }; BerElement *ber = NULL; int rc; assert( ld != NULL ); assert( LDAP_VALID( ld ) ); assert( dn != NULL ); assert( msgidp != NULL ); *msgidp = -1; ber = ber_alloc_t( LBER_USE_DER ); if ( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } ber_printf( ber, "{tOtiN}", LDAP_TAG_EXOP_REFRESH_REQ_DN, dn, LDAP_TAG_EXOP_REFRESH_REQ_TTL, ttl ); rc = ber_flatten2( ber, &bv, 0 ); if ( rc < 0 ) { rc = ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } rc = ldap_extended_operation( ld, LDAP_EXOP_REFRESH, &bv, sctrls, cctrls, msgidp ); done: ; ber_free( ber, 1 ); return rc; }
int ldap_create_assertion_control_value( LDAP *ld, char *assertion, struct berval *value ) { BerElement *ber = NULL; int err; if ( assertion == NULL || assertion[ 0 ] == '\0' ) { ld->ld_errno = LDAP_PARAM_ERROR; return ld->ld_errno; } if ( value == NULL ) { ld->ld_errno = LDAP_PARAM_ERROR; return ld->ld_errno; } BER_BVZERO( value ); ber = ldap_alloc_ber_with_options( ld ); if ( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } err = ldap_pvt_put_filter( ber, assertion ); if ( err < 0 ) { ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } err = ber_flatten2( ber, value, 1 ); if ( err < 0 ) { ld->ld_errno = LDAP_NO_MEMORY; goto done; } done:; if ( ber != NULL ) { ber_free( ber, 1 ); } return ld->ld_errno; }
static int dupent_response_done( Operation *op, SlapReply *rs ) { BerElementBuffer berbuf; BerElement *ber = (BerElement *) &berbuf; struct berval ctrlval; LDAPControl *ctrl, *ctrlsp[2]; ber_init2( ber, NULL, LBER_USE_DER ); /* DuplicateEntryResponseDone ::= SEQUENCE { resultCode, -- From [RFC2251] errorMessage [0] LDAPString OPTIONAL, attribute [1] AttributeDescription OPTIONAL } */ ber_printf( ber, "{i}", rs->sr_err ); if ( ber_flatten2( ber, &ctrlval, 0 ) == -1 ) { ber_free_buf( ber ); if ( op->o_dupent == SLAP_CONTROL_CRITICAL ) { return LDAP_CONSTRAINT_VIOLATION; } return SLAP_CB_CONTINUE; } ctrl = op->o_tmpcalloc( 1, sizeof( LDAPControl ) + ctrlval.bv_len + 1, op->o_tmpmemctx ); ctrl->ldctl_value.bv_val = (char *)&ctrl[ 1 ]; ctrl->ldctl_oid = LDAP_CONTROL_DUPENT_RESPONSE; ctrl->ldctl_iscritical = 0; ctrl->ldctl_value.bv_len = ctrlval.bv_len; AC_MEMCPY( ctrl->ldctl_value.bv_val, ctrlval.bv_val, ctrlval.bv_len ); ctrl->ldctl_value.bv_val[ ctrl->ldctl_value.bv_len ] = '\0'; ber_free_buf( ber ); ctrlsp[0] = ctrl; ctrlsp[1] = NULL; slap_add_ctrls( op, rs, ctrlsp ); return SLAP_CB_CONTINUE; }
static int send_ldap_controls( Operation *o, BerElement *ber, LDAPControl **c ) { int rc; if( c == NULL ) return 0; rc = ber_printf( ber, "t{"/*}*/, LDAP_TAG_CONTROLS ); if( rc == -1 ) return rc; for( ; *c != NULL; c++) { rc = send_ldap_control( ber, *c ); if( rc == -1 ) return rc; } #ifdef SLAP_CONTROL_X_SORTEDRESULTS /* this is a hack to avoid having to modify op->s_ctrls */ if( o->o_sortedresults ) { BerElementBuffer berbuf; BerElement *sber = (BerElement *) &berbuf; LDAPControl sorted; BER_BVZERO( &sorted.ldctl_value ); sorted.ldctl_oid = LDAP_CONTROL_SORTRESPONSE; sorted.ldctl_iscritical = 0; ber_init2( sber, NULL, LBER_USE_DER ); ber_printf( sber, "{e}", LDAP_UNWILLING_TO_PERFORM ); if( ber_flatten2( sber, &sorted.ldctl_value, 0 ) == -1 ) { return -1; } (void) ber_free_buf( sber ); rc = send_ldap_control( ber, &sorted ); if( rc == -1 ) return rc; } #endif rc = ber_printf( ber, /*{*/"N}" ); return rc; }
static int pack_sss_response_control( Operation *op, SlapReply *rs, LDAPControl **ctrlsp ) { LDAPControl *ctrl; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; struct berval bv; int rc; ber_init2( ber, NULL, LBER_USE_DER ); ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); /* Pack error code */ rc = ber_printf(ber, "{e}", rs->sr_err); if ( rc != -1) rc = ber_flatten2( ber, &bv, 0 ); if ( rc != -1 ) { ctrl = (LDAPControl *)op->o_tmpalloc( sizeof(LDAPControl)+ bv.bv_len, op->o_tmpmemctx ); ctrl->ldctl_oid = LDAP_CONTROL_SORTRESPONSE; ctrl->ldctl_iscritical = 0; ctrl->ldctl_value.bv_val = (char *)(ctrl+1); ctrl->ldctl_value.bv_len = bv.bv_len; memcpy( ctrl->ldctl_value.bv_val, bv.bv_val, bv.bv_len ); ctrlsp[0] = ctrl; } else { ctrlsp[0] = NULL; rs->sr_err = LDAP_OTHER; } ber_free_buf( ber ); return rs->sr_err; }
/* * Delete all the children of an entry recursively until leaf nodes are reached. */ static int deletechildren( LDAP *ld, const char *base, int subentries ) { LDAPMessage *res, *e; int entries; int rc = LDAP_SUCCESS, srch_rc; static char *attrs[] = { LDAP_NO_ATTRS, NULL }; LDAPControl c, *ctrls[2], **ctrlsp = NULL; BerElement *ber = NULL; if ( verbose ) printf ( _("deleting children of: %s\n"), base ); if ( subentries ) { /* * Do a one level search at base for subentry children. */ if ((ber = ber_alloc_t(LBER_USE_DER)) == NULL) { return EXIT_FAILURE; } rc = ber_printf( ber, "b", 1 ); if ( rc == -1 ) { ber_free( ber, 1 ); fprintf( stderr, _("Subentries control encoding error!\n")); return EXIT_FAILURE; } if ( ber_flatten2( ber, &c.ldctl_value, 0 ) == -1 ) { return EXIT_FAILURE; } c.ldctl_oid = LDAP_CONTROL_SUBENTRIES; c.ldctl_iscritical = 1; ctrls[0] = &c; ctrls[1] = NULL; ctrlsp = ctrls; } /* * Do a one level search at base for children. For each, delete its children. */ more:; srch_rc = ldap_search_ext_s( ld, base, LDAP_SCOPE_ONELEVEL, NULL, attrs, 1, ctrlsp, NULL, NULL, sizelimit, &res ); switch ( srch_rc ) { case LDAP_SUCCESS: case LDAP_SIZELIMIT_EXCEEDED: break; default: tool_perror( "ldap_search", srch_rc, NULL, NULL, NULL, NULL ); return( srch_rc ); } entries = ldap_count_entries( ld, res ); if ( entries > 0 ) { int i; for (e = ldap_first_entry( ld, res ), i = 0; e != NULL; e = ldap_next_entry( ld, e ), i++ ) { char *dn = ldap_get_dn( ld, e ); if( dn == NULL ) { ldap_get_option( ld, LDAP_OPT_RESULT_CODE, &rc ); tool_perror( "ldap_prune", rc, NULL, NULL, NULL, NULL ); ber_memfree( dn ); return rc; } rc = deletechildren( ld, dn, 0 ); if ( rc != LDAP_SUCCESS ) { tool_perror( "ldap_prune", rc, NULL, NULL, NULL, NULL ); ber_memfree( dn ); return rc; } if ( verbose ) { printf( _("\tremoving %s\n"), dn ); } rc = ldap_delete_ext_s( ld, dn, NULL, NULL ); if ( rc != LDAP_SUCCESS ) { tool_perror( "ldap_delete", rc, NULL, NULL, NULL, NULL ); ber_memfree( dn ); return rc; } if ( verbose ) { printf( _("\t%s removed\n"), dn ); } ber_memfree( dn ); } } ldap_msgfree( res ); if ( srch_rc == LDAP_SIZELIMIT_EXCEEDED ) { goto more; } return rc; }
int main( int argc, char *argv[] ) { int rc; char *user = NULL; LDAP *ld = NULL; struct berval bv = {0, NULL}; BerElement *ber = NULL; int id, code = LDAP_OTHER; LDAPMessage *res; char *matcheddn = NULL, *text = NULL, **refs = NULL; char *retoid = NULL; struct berval *retdata = NULL; LDAPControl **ctrls = NULL; tool_init( TOOL_PASSWD ); prog = lutil_progname( "ldappasswd", argc, argv ); /* LDAPv3 only */ protocol = LDAP_VERSION3; tool_args( argc, argv ); if( argc - optind > 1 ) { usage(); } else if ( argc - optind == 1 ) { user = strdup( argv[optind] ); } else { user = NULL; } if( oldpwfile ) { rc = lutil_get_filed_password( oldpwfile, &oldpw ); if( rc ) { rc = EXIT_FAILURE; goto done; } } if( want_oldpw && oldpw.bv_val == NULL ) { /* prompt for old password */ char *ckoldpw; oldpw.bv_val = strdup(getpassphrase(_("Old password: "******"Re-enter old password: "******"passwords do not match\n") ); rc = EXIT_FAILURE; goto done; } oldpw.bv_len = strlen( oldpw.bv_val ); } if( newpwfile ) { rc = lutil_get_filed_password( newpwfile, &newpw ); if( rc ) { rc = EXIT_FAILURE; goto done; } } if( want_newpw && newpw.bv_val == NULL ) { /* prompt for new password */ char *cknewpw; newpw.bv_val = strdup(getpassphrase(_("New password: "******"Re-enter new password: "******"passwords do not match\n") ); rc = EXIT_FAILURE; goto done; } newpw.bv_len = strlen( newpw.bv_val ); } ld = tool_conn_setup( 0, 0 ); tool_bind( ld ); if( user != NULL || oldpw.bv_val != NULL || newpw.bv_val != NULL ) { /* build the password modify request data */ ber = ber_alloc_t( LBER_USE_DER ); if( ber == NULL ) { perror( "ber_alloc_t" ); rc = EXIT_FAILURE; goto done; } ber_printf( ber, "{" /*}*/ ); if( user != NULL ) { ber_printf( ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user ); free(user); } if( oldpw.bv_val != NULL ) { ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, &oldpw ); free(oldpw.bv_val); } if( newpw.bv_val != NULL ) { ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, &newpw ); free(newpw.bv_val); } ber_printf( ber, /*{*/ "N}" ); rc = ber_flatten2( ber, &bv, 0 ); if( rc < 0 ) { perror( "ber_flatten2" ); rc = EXIT_FAILURE; goto done; } } if ( dont ) { rc = LDAP_SUCCESS; goto done; } tool_server_controls( ld, NULL, 0); rc = ldap_extended_operation( ld, LDAP_EXOP_MODIFY_PASSWD, bv.bv_val ? &bv : NULL, NULL, NULL, &id ); ber_free( ber, 1 ); if( rc != LDAP_SUCCESS ) { tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL ); rc = EXIT_FAILURE; goto done; } for ( ; ; ) { struct timeval tv; if ( tool_check_abandon( ld, id ) ) { tool_exit( ld, LDAP_CANCELLED ); } tv.tv_sec = 0; tv.tv_usec = 100000; rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res ); if ( rc < 0 ) { tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL ); tool_exit( ld, rc ); } if ( rc != 0 ) { break; } } rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, &ctrls, 0 ); if( rc != LDAP_SUCCESS ) { tool_perror( "ldap_parse_result", rc, NULL, NULL, NULL, NULL ); rc = EXIT_FAILURE; goto done; } rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 ); if( rc != LDAP_SUCCESS ) { tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL ); rc = EXIT_FAILURE; goto done; } if( retdata != NULL ) { ber_tag_t tag; char *s; ber = ber_init( retdata ); if( ber == NULL ) { perror( "ber_init" ); rc = EXIT_FAILURE; goto done; } /* we should check the tag */ tag = ber_scanf( ber, "{a}", &s); if( tag == LBER_ERROR ) { perror( "ber_scanf" ); } else { printf(_("New password: %s\n"), s); ber_memfree( s ); } ber_free( ber, 1 ); } else if ( code == LDAP_SUCCESS && newpw.bv_val == NULL ) { tool_perror( "ldap_parse_extended_result", LDAP_DECODING_ERROR, " new password expected", NULL, NULL, NULL ); } if( verbose || code != LDAP_SUCCESS || ( matcheddn && *matcheddn ) || ( text && *text ) || refs || ctrls ) { printf( _("Result: %s (%d)\n"), ldap_err2string( code ), code ); if( text && *text ) { printf( _("Additional info: %s\n"), text ); } if( matcheddn && *matcheddn ) { printf( _("Matched DN: %s\n"), matcheddn ); } if( refs ) { int i; for( i=0; refs[i]; i++ ) { printf(_("Referral: %s\n"), refs[i] ); } } if( ctrls ) { tool_print_ctrls( ld, ctrls ); ldap_controls_free( ctrls ); } } ber_memfree( text ); ber_memfree( matcheddn ); ber_memvfree( (void **) refs ); ber_memfree( retoid ); ber_bvfree( retdata ); rc = ( code == LDAP_SUCCESS ) ? EXIT_SUCCESS : EXIT_FAILURE; done: /* disconnect from server */ tool_exit( ld, rc ); }
static int vc_create_response( void *conn, int resultCode, const char *diagnosticMessage, struct berval *servercred, struct berval *authzid, LDAPControl **ctrls, struct berval **val ) { BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; struct berval bv; int rc; assert( val != NULL ); *val = NULL; ber_init2( ber, NULL, LBER_USE_DER ); (void)ber_printf( ber, "{is" /*}*/ , resultCode, diagnosticMessage ? diagnosticMessage : "" ); if ( conn ) { struct berval cookie; cookie.bv_len = sizeof( conn ); cookie.bv_val = (char *)&conn; (void)ber_printf( ber, "tO", 0, LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE, &cookie ); } if ( servercred ) { ber_printf( ber, "tO", LDAP_TAG_EXOP_VERIFY_CREDENTIALS_SCREDS, servercred ); } #if 0 if ( authzid ) { ber_printf( ber, "tO", LDAP_TAG_EXOP_VERIFY_CREDENTIALS_AUTHZID, authzid ); } #endif if ( ctrls ) { int c; rc = ber_printf( ber, "t{"/*}*/, LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS ); if ( rc == -1 ) goto done; for ( c = 0; ctrls[c] != NULL; c++ ) { rc = ber_printf( ber, "{s" /*}*/, ctrls[c]->ldctl_oid ); if ( ctrls[c]->ldctl_iscritical ) { rc = ber_printf( ber, "b", (ber_int_t)ctrls[c]->ldctl_iscritical ) ; if ( rc == -1 ) goto done; } if ( ctrls[c]->ldctl_value.bv_val != NULL ) { rc = ber_printf( ber, "O", &ctrls[c]->ldctl_value ); if( rc == -1 ) goto done; } rc = ber_printf( ber, /*{*/"N}" ); if ( rc == -1 ) goto done; } rc = ber_printf( ber, /*{*/"N}" ); if ( rc == -1 ) goto done; } ber_printf( ber, /*{*/ "}" ); rc = ber_flatten2( ber, &bv, 0 ); *val = ber_bvdup( &bv ); done:; ber_free_buf( ber ); return rc; }
int ldap_create_sort_control_value( LDAP *ld, LDAPSortKey **keyList, struct berval *value ) { int i; BerElement *ber = NULL; ber_tag_t tag; assert( ld != NULL ); assert( LDAP_VALID( ld ) ); if ( ld == NULL ) return LDAP_PARAM_ERROR; if ( keyList == NULL || value == NULL ) { ld->ld_errno = LDAP_PARAM_ERROR; return LDAP_PARAM_ERROR; } value->bv_val = NULL; value->bv_len = 0; ld->ld_errno = LDAP_SUCCESS; ber = ldap_alloc_ber_with_options( ld ); if ( ber == NULL) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } tag = ber_printf( ber, "{" /*}*/ ); if ( tag == LBER_ERROR ) { goto error_return; } for ( i = 0; keyList[i] != NULL; i++ ) { tag = ber_printf( ber, "{s" /*}*/, keyList[i]->attributeType ); if ( tag == LBER_ERROR ) { goto error_return; } if ( keyList[i]->orderingRule != NULL ) { tag = ber_printf( ber, "ts", LDAP_MATCHRULE_IDENTIFIER, keyList[i]->orderingRule ); if ( tag == LBER_ERROR ) { goto error_return; } } if ( keyList[i]->reverseOrder ) { tag = ber_printf( ber, "tb", LDAP_REVERSEORDER_IDENTIFIER, keyList[i]->reverseOrder ); if ( tag == LBER_ERROR ) { goto error_return; } } tag = ber_printf( ber, /*{*/ "N}" ); if ( tag == LBER_ERROR ) { goto error_return; } } tag = ber_printf( ber, /*{*/ "N}" ); if ( tag == LBER_ERROR ) { goto error_return; } if ( ber_flatten2( ber, value, 1 ) == -1 ) { ld->ld_errno = LDAP_NO_MEMORY; } if ( 0 ) { error_return:; ld->ld_errno = LDAP_ENCODING_ERROR; } if ( ber != NULL ) { ber_free( ber, 1 ); } return ld->ld_errno; }
int VmDirCreateSyncRequestControl( PCSTR pszInvocationId, USN lastLocalUsnProcessed, PCSTR pszUtdVector, LDAPControl * syncReqCtrl ) { int retVal = LDAP_SUCCESS; BerElement * ber = NULL; PSTR pszLastLocalUsnProcessed = NULL; if (syncReqCtrl == NULL) { retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_SIMPLE_LDAP_ERROR(retVal); } if ((ber = ber_alloc()) == NULL) { retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_SIMPLE_LDAP_ERROR(retVal); } if (VmDirAllocateStringPrintf(&pszLastLocalUsnProcessed, "%lld", lastLocalUsnProcessed)) { retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_SIMPLE_LDAP_ERROR(retVal); } if ( ber_printf( ber, "{i{sss}}", LDAP_SYNC_REFRESH_ONLY, pszInvocationId, pszLastLocalUsnProcessed, pszUtdVector ) == -1) { VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "VmDirCreateSyncRequestControl: ber_printf failed." ); retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_SIMPLE_LDAP_ERROR( retVal ); } memset( syncReqCtrl, 0, sizeof( LDAPControl )); syncReqCtrl->ldctl_oid = LDAP_CONTROL_SYNC; syncReqCtrl->ldctl_iscritical = '1'; if (ber_flatten2(ber, &syncReqCtrl->ldctl_value, 1)) { retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_SIMPLE_LDAP_ERROR(retVal); } cleanup: VMDIR_SAFE_FREE_STRINGA(pszLastLocalUsnProcessed); if (ber) { ber_free(ber, 1); } return retVal; ldaperror: ber_bvfree(&syncReqCtrl->ldctl_value); goto cleanup; }
int pam_pwmod(nssov_info *ni,TFILE *fp,Operation *op) { struct berval npw; int32_t tmpint32; char dnc[1024]; char uidc[32]; char opwc[256]; char npwc[256]; char svcc[256]; struct paminfo pi; int rc; READ_STRING(fp,uidc); pi.uid.bv_val = uidc; pi.uid.bv_len = tmpint32; READ_STRING(fp,dnc); pi.dn.bv_val = dnc; pi.dn.bv_len = tmpint32; READ_STRING(fp,svcc); pi.svc.bv_val = svcc; pi.svc.bv_len = tmpint32; READ_STRING(fp,opwc); pi.pwd.bv_val = opwc; pi.pwd.bv_len = tmpint32; READ_STRING(fp,npwc); npw.bv_val = npwc; npw.bv_len = tmpint32; Debug(LDAP_DEBUG_TRACE,"nssov_pam_pwmod(%s), %s\n", pi.dn.bv_val,pi.uid.bv_val,0); BER_BVZERO(&pi.msg); /* This is a prelim check */ if (BER_BVISEMPTY(&pi.dn)) { rc = pam_do_bind(ni,fp,op,&pi); if (rc == NSLCD_PAM_IGNORE) rc = NSLCD_PAM_SUCCESS; } else { BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; struct berval bv; SlapReply rs = {REP_RESULT}; slap_callback cb = {0}; ber_init_w_nullc(ber, LBER_USE_DER); ber_printf(ber, "{"); if (!BER_BVISEMPTY(&pi.pwd)) ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, &pi.pwd); if (!BER_BVISEMPTY(&npw)) ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, &npw); ber_printf(ber, "N}"); ber_flatten2(ber, &bv, 0); op->o_tag = LDAP_REQ_EXTENDED; op->ore_reqoid = slap_EXOP_MODIFY_PASSWD; op->ore_reqdata = &bv; op->o_dn = pi.dn; op->o_ndn = pi.dn; op->o_callback = &cb; op->o_conn->c_authz_backend = op->o_bd; cb.sc_response = slap_null_cb; op->o_bd = frontendDB; rc = op->o_bd->be_extended(op, &rs); if (rs.sr_text) ber_str2bv(rs.sr_text, 0, 0, &pi.msg); if (rc == LDAP_SUCCESS) rc = NSLCD_PAM_SUCCESS; else rc = NSLCD_PAM_PERM_DENIED; } WRITE_INT32(fp,NSLCD_VERSION); WRITE_INT32(fp,NSLCD_ACTION_PAM_PWMOD); WRITE_INT32(fp,NSLCD_RESULT_BEGIN); WRITE_BERVAL(fp,&pi.uid); WRITE_BERVAL(fp,&pi.dn); WRITE_INT32(fp,rc); WRITE_BERVAL(fp,&pi.msg); return 0; }
int ldap_verify_credentials(LDAP *ld, struct berval *cookie, LDAP_CONST char *dn, LDAP_CONST char *mechanism, struct berval *cred, LDAPControl **vcctrls, LDAPControl **sctrls, LDAPControl **cctrls, int *msgidp) { int rc; BerElement *ber; struct berval reqdata; assert(ld != NULL); assert(LDAP_VALID(ld)); assert(msgidp != NULL); ber = ber_alloc_t(LBER_USE_DER); if (dn == NULL) dn = ""; if (mechanism == LDAP_SASL_SIMPLE) { assert(!cookie); rc = ber_printf(ber, "{stO" /*"}"*/, dn, LDAP_AUTH_SIMPLE, cred); } else { if (!cred || BER_BVISNULL(cred)) { if (cookie) { rc = ber_printf(ber, "{tOst{sN}" /*"}"*/, LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE, cookie, dn, LDAP_AUTH_SASL, mechanism); } else { rc = ber_printf(ber, "{st{sN}N" /*"}"*/, dn, LDAP_AUTH_SASL, mechanism); } } else { if (cookie) { rc = ber_printf(ber, "{tOst{sON}" /*"}"*/, LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE, cookie, dn, LDAP_AUTH_SASL, mechanism, cred); } else { rc = ber_printf(ber, "{st{sON}" /*"}"*/, dn, LDAP_AUTH_SASL, mechanism, cred); } } } if (rc < 0) { rc = ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } if (vcctrls && *vcctrls) { LDAPControl *const *c; rc = ber_printf(ber, "t{" /*"}"*/, LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS); for (c=vcctrls; *c; c++) { rc = ldap_pvt_put_control(*c, ber); if (rc != LDAP_SUCCESS) { rc = ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } } rc = ber_printf(ber, /*"{{"*/ "}N}"); } else { rc = ber_printf(ber, /*"{"*/ "N}"); } if (rc < 0) { rc = ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } rc = ber_flatten2(ber, &reqdata, 0); if (rc < 0) { rc = ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } rc = ldap_extended_operation(ld, LDAP_EXOP_VERIFY_CREDENTIALS, &reqdata, sctrls, cctrls, msgidp); done: ber_free(ber, 1); return rc; }
int ldap_create_session_tracking_value( LDAP *ld, char *sessionSourceIp, char *sessionSourceName, char *formatOID, struct berval *sessionTrackingIdentifier, struct berval *value ) { BerElement *ber = NULL; ber_tag_t tag; struct berval ip, name, oid, id; if ( ld == NULL || formatOID == NULL || value == NULL ) { param_error:; if ( ld ) { ld->ld_errno = LDAP_PARAM_ERROR; } return LDAP_PARAM_ERROR; } assert( LDAP_VALID( ld ) ); ld->ld_errno = LDAP_SUCCESS; /* check sizes according to I.D. */ if ( sessionSourceIp == NULL ) { BER_BVSTR( &ip, "" ); } else { ber_str2bv( sessionSourceIp, 0, 0, &ip ); /* NOTE: we're strict because we don't want * to send out bad data */ if ( ip.bv_len > 128 ) goto param_error; } if ( sessionSourceName == NULL ) { BER_BVSTR( &name, "" ); } else { ber_str2bv( sessionSourceName, 0, 0, &name ); /* NOTE: we're strict because we don't want * to send out bad data */ if ( name.bv_len > 65536 ) goto param_error; } ber_str2bv( formatOID, 0, 0, &oid ); /* NOTE: we're strict because we don't want * to send out bad data */ if ( oid.bv_len > 1024 ) goto param_error; if ( sessionTrackingIdentifier == NULL || sessionTrackingIdentifier->bv_val == NULL ) { BER_BVSTR( &id, "" ); } else { id = *sessionTrackingIdentifier; } /* prepare value */ value->bv_val = NULL; value->bv_len = 0; ber = ldap_alloc_ber_with_options( ld ); if ( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } tag = ber_printf( ber, "{OOOO}", &ip, &name, &oid, &id ); if ( tag == LBER_ERROR ) { ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } if ( ber_flatten2( ber, value, 1 ) == -1 ) { ld->ld_errno = LDAP_NO_MEMORY; } done:; if ( ber != NULL ) { ber_free( ber, 1 ); } return ld->ld_errno; }
int main( int argc, char *argv[] ) { int rc; char *user = NULL; LDAP *ld = NULL; struct berval bv = {0, NULL}; BerElement *ber = NULL; int id, code = LDAP_OTHER; LDAPMessage *res; char *matcheddn = NULL, *text = NULL, **refs = NULL; char *retoid = NULL; struct berval *retdata = NULL; prog = lutil_progname( "ldappasswd", argc, argv ); /* LDAPv3 only */ protocol = LDAP_VERSION3; tool_args( argc, argv ); if( argc - optind > 1 ) { usage(); } else if ( argc - optind == 1 ) { user = strdup( argv[optind] ); } else { user = NULL; } if( oldpwfile ) { rc = lutil_get_filed_password( prog, &oldpw ); if( rc ) return EXIT_FAILURE; } if( want_oldpw && oldpw.bv_val == NULL ) { /* prompt for old password */ char *ckoldpw; oldpw.bv_val = strdup(getpassphrase("Old password: "******"Re-enter old password: "******"passwords do not match\n" ); return EXIT_FAILURE; } oldpw.bv_len = strlen( oldpw.bv_val ); } if( newpwfile ) { rc = lutil_get_filed_password( prog, &newpw ); if( rc ) return EXIT_FAILURE; } if( want_newpw && newpw.bv_val == NULL ) { /* prompt for new password */ char *cknewpw; newpw.bv_val = strdup(getpassphrase("New password: "******"Re-enter new password: "******"passwords do not match\n" ); return EXIT_FAILURE; } newpw.bv_len = strlen( newpw.bv_val ); } if( want_bindpw && passwd.bv_val == NULL ) { /* handle bind password */ if ( pw_file ) { rc = lutil_get_filed_password( pw_file, &passwd ); if( rc ) return EXIT_FAILURE; } else { passwd.bv_val = getpassphrase( "Enter LDAP Password: "******"ber_alloc_t" ); ldap_unbind( ld ); return EXIT_FAILURE; } ber_printf( ber, "{" /*}*/ ); if( user != NULL ) { ber_printf( ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user ); free(user); } if( oldpw.bv_val != NULL ) { ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, &oldpw ); free(oldpw.bv_val); } if( newpw.bv_val != NULL ) { ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, &newpw ); free(newpw.bv_val); } ber_printf( ber, /*{*/ "N}" ); rc = ber_flatten2( ber, &bv, 0 ); if( rc < 0 ) { perror( "ber_flatten2" ); ldap_unbind( ld ); return EXIT_FAILURE; } } if ( not ) { rc = LDAP_SUCCESS; goto skip; } rc = ldap_extended_operation( ld, LDAP_EXOP_MODIFY_PASSWD, bv.bv_val ? &bv : NULL, NULL, NULL, &id ); ber_free( ber, 1 ); if( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_extended_operation" ); ldap_unbind( ld ); return EXIT_FAILURE; } rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res ); if ( rc < 0 ) { ldap_perror( ld, "ldappasswd: ldap_result" ); return rc; } rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 0 ); if( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_parse_result" ); return rc; } rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 ); if( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_parse_result" ); return rc; } if( retdata != NULL ) { ber_tag_t tag; char *s; ber = ber_init( retdata ); if( ber == NULL ) { perror( "ber_init" ); ldap_unbind( ld ); return EXIT_FAILURE; } /* we should check the tag */ tag = ber_scanf( ber, "{a}", &s); if( tag == LBER_ERROR ) { perror( "ber_scanf" ); } else { printf("New password: %s\n", s); free( s ); } ber_free( ber, 1 ); } if( verbose || code != LDAP_SUCCESS || matcheddn || text || refs ) { printf( "Result: %s (%d)\n", ldap_err2string( code ), code ); if( text && *text ) { printf( "Additional info: %s\n", text ); } if( matcheddn && *matcheddn ) { printf( "Matched DN: %s\n", matcheddn ); } if( refs ) { int i; for( i=0; refs[i]; i++ ) { printf("Referral: %s\n", refs[i] ); } } } ber_memfree( text ); ber_memfree( matcheddn ); ber_memvfree( (void **) refs ); ber_memfree( retoid ); ber_bvfree( retdata ); skip: /* disconnect from server */ ldap_unbind (ld); return code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE; }
int ldap_create_vlv_control_value( LDAP *ld, LDAPVLVInfo *vlvinfop, struct berval *value ) { ber_tag_t tag; BerElement *ber; if ( ld == NULL || vlvinfop == NULL || value == NULL ) { if ( ld ) ld->ld_errno = LDAP_PARAM_ERROR; return LDAP_PARAM_ERROR; } assert( LDAP_VALID( ld ) ); value->bv_val = NULL; value->bv_len = 0; ld->ld_errno = LDAP_SUCCESS; ber = ldap_alloc_ber_with_options( ld ); if ( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } tag = ber_printf( ber, "{ii" /*}*/, vlvinfop->ldvlv_before_count, vlvinfop->ldvlv_after_count ); if ( tag == LBER_ERROR ) { goto error_return; } if ( vlvinfop->ldvlv_attrvalue == NULL ) { tag = ber_printf( ber, "t{iiN}", LDAP_VLVBYINDEX_IDENTIFIER, vlvinfop->ldvlv_offset, vlvinfop->ldvlv_count ); if ( tag == LBER_ERROR ) { goto error_return; } } else { tag = ber_printf( ber, "tO", LDAP_VLVBYVALUE_IDENTIFIER, vlvinfop->ldvlv_attrvalue ); if ( tag == LBER_ERROR ) { goto error_return; } } if ( vlvinfop->ldvlv_context ) { tag = ber_printf( ber, "tO", LDAP_VLVCONTEXT_IDENTIFIER, vlvinfop->ldvlv_context ); if ( tag == LBER_ERROR ) { goto error_return; } } tag = ber_printf( ber, /*{*/ "N}" ); if ( tag == LBER_ERROR ) { goto error_return; } if ( ber_flatten2( ber, value, 1 ) == -1 ) { ld->ld_errno = LDAP_NO_MEMORY; } if ( 0 ) { error_return:; ld->ld_errno = LDAP_ENCODING_ERROR; } if ( ber != NULL ) { ber_free( ber, 1 ); } return ld->ld_errno; }
static int null_back_respond( Operation *op, SlapReply *rs, int rc ) { LDAPControl ctrl[SLAP_MAX_RESPONSE_CONTROLS], *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; int c = 0; BerElementBuffer ps_berbuf; BerElement *ps_ber = NULL; LDAPControl **preread_ctrl = NULL, **postread_ctrl = NULL; rs->sr_err = LDAP_OTHER; /* this comes first, as in case of assertion failure * any further processing must stop */ if ( get_assert( op ) ) { rs->sr_err = LDAP_ASSERTION_FAILED; goto respond; } if ( op->o_preread ) { Entry e = { 0 }; switch ( op->o_tag ) { case LDAP_REQ_MODIFY: case LDAP_REQ_RENAME: case LDAP_REQ_DELETE: e.e_name = op->o_req_dn; e.e_nname = op->o_req_ndn; preread_ctrl = &ctrls[c]; *preread_ctrl = NULL; if ( slap_read_controls( op, rs, &e, &slap_pre_read_bv, preread_ctrl ) ) { preread_ctrl = NULL; Debug( LDAP_DEBUG_TRACE, "<=- null_back_respond: pre-read " "failed!\n", 0, 0, 0 ); if ( op->o_preread & SLAP_CONTROL_CRITICAL ) { /* FIXME: is it correct to abort * operation if control fails? */ goto respond; } } else { c++; } break; } } if ( op->o_postread ) { Entry e = { 0 }; switch ( op->o_tag ) { case LDAP_REQ_ADD: case LDAP_REQ_MODIFY: case LDAP_REQ_RENAME: if ( op->o_tag == LDAP_REQ_ADD ) { e.e_name = op->ora_e->e_name; e.e_nname = op->ora_e->e_nname; } else { e.e_name = op->o_req_dn; e.e_nname = op->o_req_ndn; } postread_ctrl = &ctrls[c]; *postread_ctrl = NULL; if ( slap_read_controls( op, rs, &e, &slap_post_read_bv, postread_ctrl ) ) { postread_ctrl = NULL; Debug( LDAP_DEBUG_TRACE, "<=- null_back_respond: post-read " "failed!\n", 0, 0, 0 ); if ( op->o_postread & SLAP_CONTROL_CRITICAL ) { /* FIXME: is it correct to abort * operation if control fails? */ goto respond; } } else { c++; } break; } } if ( op->o_noop ) { switch ( op->o_tag ) { case LDAP_REQ_ADD: case LDAP_REQ_MODIFY: case LDAP_REQ_RENAME: case LDAP_REQ_DELETE: case LDAP_REQ_EXTENDED: rc = LDAP_X_NO_OPERATION; break; } } if ( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ) { struct berval cookie = BER_BVC( "" ); /* should not be here... */ assert( op->o_tag == LDAP_REQ_SEARCH ); ctrl[c].ldctl_oid = LDAP_CONTROL_PAGEDRESULTS; ctrl[c].ldctl_iscritical = 0; ps_ber = (BerElement *)&ps_berbuf; ber_init2( ps_ber, NULL, LBER_USE_DER ); /* return size of 0 -- no estimate */ ber_printf( ps_ber, "{iO}", 0, &cookie ); if ( ber_flatten2( ps_ber, &ctrl[c].ldctl_value, 0 ) == -1 ) { goto done; } ctrls[c] = &ctrl[c]; c++; } /* terminate controls array */ ctrls[c] = NULL; rs->sr_ctrls = ctrls; rs->sr_err = rc; respond:; send_ldap_result( op, rs ); rs->sr_ctrls = NULL; done:; if ( ps_ber != NULL ) { (void) ber_free_buf( ps_ber ); } if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) { slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); slap_sl_free( *preread_ctrl, op->o_tmpmemctx ); } if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) { slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); slap_sl_free( *postread_ctrl, op->o_tmpmemctx ); } return rs->sr_err; }
static int deref_response( Operation *op, SlapReply *rs ) { int rc = SLAP_CB_CONTINUE; if ( rs->sr_type == REP_SEARCH ) { BerElementBuffer berbuf; BerElement *ber = (BerElement *) &berbuf; deref_cb_t *dc = (deref_cb_t *)op->o_callback->sc_private; DerefSpec *ds; DerefRes *dr, *drhead = NULL, **drp = &drhead; struct berval bv = BER_BVNULL; int nDerefRes = 0, nDerefVals = 0, nAttrs = 0, nVals = 0; struct berval ctrlval; LDAPControl *ctrl, *ctrlsp[2]; AccessControlState acl_state = ACL_STATE_INIT; static char dummy = '\0'; Entry *ebase; int i; rc = overlay_entry_get_ov( op, &rs->sr_entry->e_nname, NULL, NULL, 0, &ebase, dc->dc_on ); if ( rc != LDAP_SUCCESS || ebase == NULL ) { return SLAP_CB_CONTINUE; } for ( ds = dc->dc_ds; ds; ds = ds->ds_next ) { Attribute *a = attr_find( ebase->e_attrs, ds->ds_derefAttr ); if ( a != NULL ) { DerefVal *dv; BerVarray *bva; if ( !access_allowed( op, rs->sr_entry, a->a_desc, NULL, ACL_READ, &acl_state ) ) { continue; } dr = op->o_tmpcalloc( 1, sizeof( DerefRes ) + ( sizeof( DerefVal ) + sizeof( BerVarray * ) * ds->ds_nattrs ) * ( a->a_numvals + 1 ), op->o_tmpmemctx ); dr->dr_spec = *ds; dv = dr->dr_vals = (DerefVal *)&dr[ 1 ]; bva = (BerVarray *)&dv[ a->a_numvals + 1 ]; bv.bv_len += ds->ds_derefAttr->ad_cname.bv_len; nAttrs++; nDerefRes++; for ( i = 0; !BER_BVISNULL( &a->a_nvals[ i ] ); i++ ) { Entry *e = NULL; dv[ i ].dv_attrVals = bva; bva += ds->ds_nattrs; if ( !access_allowed( op, rs->sr_entry, a->a_desc, &a->a_nvals[ i ], ACL_READ, &acl_state ) ) { dv[ i ].dv_derefSpecVal.bv_val = &dummy; continue; } ber_dupbv_x( &dv[ i ].dv_derefSpecVal, &a->a_vals[ i ], op->o_tmpmemctx ); bv.bv_len += dv[ i ].dv_derefSpecVal.bv_len; nVals++; nDerefVals++; rc = overlay_entry_get_ov( op, &a->a_nvals[ i ], NULL, NULL, 0, &e, dc->dc_on ); if ( rc == LDAP_SUCCESS && e != NULL ) { int j; if ( access_allowed( op, e, slap_schema.si_ad_entry, NULL, ACL_READ, NULL ) ) { for ( j = 0; j < ds->ds_nattrs; j++ ) { Attribute *aa; if ( !access_allowed( op, e, ds->ds_attributes[ j ], NULL, ACL_READ, &acl_state ) ) { continue; } aa = attr_find( e->e_attrs, ds->ds_attributes[ j ] ); if ( aa != NULL ) { unsigned k, h, last = aa->a_numvals; ber_bvarray_dup_x( &dv[ i ].dv_attrVals[ j ], aa->a_vals, op->o_tmpmemctx ); bv.bv_len += ds->ds_attributes[ j ]->ad_cname.bv_len; for ( k = 0, h = 0; k < aa->a_numvals; k++ ) { if ( !access_allowed( op, e, aa->a_desc, &aa->a_nvals[ k ], ACL_READ, &acl_state ) ) { op->o_tmpfree( dv[ i ].dv_attrVals[ j ][ h ].bv_val, op->o_tmpmemctx ); dv[ i ].dv_attrVals[ j ][ h ] = dv[ i ].dv_attrVals[ j ][ --last ]; BER_BVZERO( &dv[ i ].dv_attrVals[ j ][ last ] ); continue; } bv.bv_len += dv[ i ].dv_attrVals[ j ][ h ].bv_len; nVals++; h++; } nAttrs++; } } } overlay_entry_release_ov( op, e, 0, dc->dc_on ); } } *drp = dr; drp = &dr->dr_next; } } overlay_entry_release_ov( op, ebase, 0, dc->dc_on ); if ( drhead == NULL ) { return SLAP_CB_CONTINUE; } /* cook the control value */ bv.bv_len += nVals * sizeof(struct berval) + nAttrs * sizeof(struct berval) + nDerefVals * sizeof(DerefVal) + nDerefRes * sizeof(DerefRes); bv.bv_val = op->o_tmpalloc( bv.bv_len, op->o_tmpmemctx ); ber_init2( ber, &bv, LBER_USE_DER ); ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); rc = ber_printf( ber, "{" /*}*/ ); for ( dr = drhead; dr != NULL; dr = dr->dr_next ) { for ( i = 0; !BER_BVISNULL( &dr->dr_vals[ i ].dv_derefSpecVal ); i++ ) { int j, first = 1; if ( dr->dr_vals[ i ].dv_derefSpecVal.bv_val == &dummy ) { continue; } rc = ber_printf( ber, "{OO" /*}*/, &dr->dr_spec.ds_derefAttr->ad_cname, &dr->dr_vals[ i ].dv_derefSpecVal ); op->o_tmpfree( dr->dr_vals[ i ].dv_derefSpecVal.bv_val, op->o_tmpmemctx ); for ( j = 0; j < dr->dr_spec.ds_nattrs; j++ ) { if ( dr->dr_vals[ i ].dv_attrVals[ j ] != NULL ) { if ( first ) { rc = ber_printf( ber, "t{" /*}*/, (LBER_CONSTRUCTED|LBER_CLASS_CONTEXT) ); first = 0; } rc = ber_printf( ber, "{O[W]}", &dr->dr_spec.ds_attributes[ j ]->ad_cname, dr->dr_vals[ i ].dv_attrVals[ j ] ); op->o_tmpfree( dr->dr_vals[ i ].dv_attrVals[ j ], op->o_tmpmemctx ); } } if ( !first ) { rc = ber_printf( ber, /*{{*/ "}N}" ); } else { rc = ber_printf( ber, /*{*/ "}" ); } } } rc = ber_printf( ber, /*{*/ "}" ); if ( ber_flatten2( ber, &ctrlval, 0 ) == -1 ) { if ( op->o_deref == SLAP_CONTROL_CRITICAL ) { rc = LDAP_CONSTRAINT_VIOLATION; } else { rc = SLAP_CB_CONTINUE; } goto cleanup; } ctrl = op->o_tmpcalloc( 1, sizeof( LDAPControl ) + ctrlval.bv_len + 1, op->o_tmpmemctx ); ctrl->ldctl_value.bv_val = (char *)&ctrl[ 1 ]; ctrl->ldctl_oid = LDAP_CONTROL_X_DEREF; ctrl->ldctl_iscritical = 0; ctrl->ldctl_value.bv_len = ctrlval.bv_len; memcpy( ctrl->ldctl_value.bv_val, ctrlval.bv_val, ctrlval.bv_len ); ctrl->ldctl_value.bv_val[ ctrl->ldctl_value.bv_len ] = '\0'; ber_free_buf( ber ); ctrlsp[0] = ctrl; ctrlsp[1] = NULL; slap_add_ctrls( op, rs, ctrlsp ); rc = SLAP_CB_CONTINUE; cleanup:; /* release all */ for ( ; drhead != NULL; ) { DerefRes *drnext = drhead->dr_next; op->o_tmpfree( drhead, op->o_tmpmemctx ); drhead = drnext; } } else if ( rs->sr_type == REP_RESULT ) { rc = deref_cleanup( op, rs ); } return rc; }
int ldap_create_deref_control_value( LDAP *ld, LDAPDerefSpec *ds, struct berval *value ) { BerElement *ber = NULL; ber_tag_t tag; int i; if ( ld == NULL || value == NULL || ds == NULL ) { if ( ld ) ld->ld_errno = LDAP_PARAM_ERROR; return LDAP_PARAM_ERROR; } assert( LDAP_VALID( ld ) ); value->bv_val = NULL; value->bv_len = 0; ld->ld_errno = LDAP_SUCCESS; ber = ldap_alloc_ber_with_options( ld ); if ( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } tag = ber_printf( ber, "{" /*}*/ ); if ( tag == LBER_ERROR ) { ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } for ( i = 0; ds[i].derefAttr != NULL; i++ ) { int j; tag = ber_printf( ber, "{s{" /*}}*/ , ds[i].derefAttr ); if ( tag == LBER_ERROR ) { ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } for ( j = 0; ds[i].attributes[j] != NULL; j++ ) { tag = ber_printf( ber, "s", ds[i].attributes[ j ] ); if ( tag == LBER_ERROR ) { ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } } tag = ber_printf( ber, /*{{*/ "}N}" ); if ( tag == LBER_ERROR ) { ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } } tag = ber_printf( ber, /*{*/ "}" ); if ( tag == LBER_ERROR ) { ld->ld_errno = LDAP_ENCODING_ERROR; goto done; } if ( ber_flatten2( ber, value, 1 ) == -1 ) { ld->ld_errno = LDAP_NO_MEMORY; } done:; if ( ber != NULL ) { ber_free( ber, 1 ); } return ld->ld_errno; }
/* * initialize the sync */ int ldap_sync_init( ldap_sync_t *ls, int mode ) { LDAPControl ctrl = { 0 }, *ctrls[ 2 ]; BerElement *ber = NULL; int rc; struct timeval tv = { 0 }, *tvp = NULL; LDAPMessage *res = NULL; #ifdef LDAP_SYNC_TRACE fprintf( stderr, "ldap_sync_init(%s)...\n", mode == LDAP_SYNC_REFRESH_AND_PERSIST ? "LDAP_SYNC_REFRESH_AND_PERSIST" : ( mode == LDAP_SYNC_REFRESH_ONLY ? "LDAP_SYNC_REFRESH_ONLY" : "unknown" ) ); #endif /* LDAP_SYNC_TRACE */ assert( ls != NULL ); assert( ls->ls_ld != NULL ); /* support both refreshOnly and refreshAndPersist */ switch ( mode ) { case LDAP_SYNC_REFRESH_AND_PERSIST: case LDAP_SYNC_REFRESH_ONLY: break; default: fprintf( stderr, "ldap_sync_init: unknown mode=%d\n", mode ); return LDAP_PARAM_ERROR; } /* check consistency of cookie and reloadHint at initial refresh */ if ( ls->ls_cookie.bv_val == NULL && ls->ls_reloadHint != 0 ) { fprintf( stderr, "ldap_sync_init: inconsistent cookie/rhint\n" ); return LDAP_PARAM_ERROR; } ctrls[ 0 ] = &ctrl; ctrls[ 1 ] = NULL; /* prepare the Sync Request control */ ber = ber_alloc_t( LBER_USE_DER ); #ifdef LDAP_SYNC_TRACE fprintf( stderr, "%sber_alloc_t() %s= NULL\n", ber == NULL ? "!!! " : "", ber == NULL ? "=" : "!" ); #endif /* LDAP_SYNC_TRACE */ if ( ber == NULL ) { rc = LDAP_NO_MEMORY; goto done; } ls->ls_refreshPhase = LDAP_SYNC_CAPI_NONE; if ( ls->ls_cookie.bv_val != NULL ) { ber_printf( ber, "{eOb}", mode, &ls->ls_cookie, ls->ls_reloadHint ); } else { ber_printf( ber, "{eb}", mode, ls->ls_reloadHint ); } rc = ber_flatten2( ber, &ctrl.ldctl_value, 0 ); #ifdef LDAP_SYNC_TRACE fprintf( stderr, "%sber_flatten2() == %d\n", rc ? "!!! " : "", rc ); #endif /* LDAP_SYNC_TRACE */ if ( rc < 0 ) { rc = LDAP_OTHER; goto done; } /* make the control critical, as we cannot proceed without */ ctrl.ldctl_oid = LDAP_CONTROL_SYNC; ctrl.ldctl_iscritical = 1; /* timelimit? */ if ( ls->ls_timelimit ) { tv.tv_sec = ls->ls_timelimit; tvp = &tv; } /* actually run the search */ rc = ldap_search_ext( ls->ls_ld, ls->ls_base, ls->ls_scope, ls->ls_filter, ls->ls_attrs, 0, ctrls, NULL, tvp, ls->ls_sizelimit, &ls->ls_msgid ); #ifdef LDAP_SYNC_TRACE fprintf( stderr, "%sldap_search_ext(\"%s\", %d, \"%s\") == %d\n", rc ? "!!! " : "", ls->ls_base, ls->ls_scope, ls->ls_filter, rc ); #endif /* LDAP_SYNC_TRACE */ if ( rc != LDAP_SUCCESS ) { goto done; } /* initial content/content update phase */ for ( ; ; ) { LDAPMessage *msg = NULL; /* NOTE: this very short timeout is just to let * ldap_result() yield long enough to get something */ tv.tv_sec = 0; tv.tv_usec = 100000; rc = ldap_result( ls->ls_ld, ls->ls_msgid, LDAP_MSG_RECEIVED, &tv, &res ); #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t%sldap_result(%d) == %d\n", rc == -1 ? "!!! " : "", ls->ls_msgid, rc ); #endif /* LDAP_SYNC_TRACE */ switch ( rc ) { case 0: /* * timeout * * TODO: can do something else in the meanwhile) */ break; case -1: /* smtg bad! */ goto done; default: for ( msg = ldap_first_message( ls->ls_ld, res ); msg != NULL; msg = ldap_next_message( ls->ls_ld, msg ) ) { int refreshDone; switch ( ldap_msgtype( msg ) ) { case LDAP_RES_SEARCH_ENTRY: rc = ldap_sync_search_entry( ls, res ); break; case LDAP_RES_SEARCH_REFERENCE: rc = ldap_sync_search_reference( ls, res ); break; case LDAP_RES_SEARCH_RESULT: rc = ldap_sync_search_result( ls, res ); goto done_search; case LDAP_RES_INTERMEDIATE: rc = ldap_sync_search_intermediate( ls, res, &refreshDone ); if ( rc != LDAP_SUCCESS || refreshDone ) { goto done_search; } break; default: #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\tgot something unexpected...\n" ); #endif /* LDAP_SYNC_TRACE */ ldap_msgfree( res ); rc = LDAP_OTHER; goto done; } } ldap_msgfree( res ); res = NULL; break; } } done_search:; ldap_msgfree( res ); done:; if ( ber != NULL ) { ber_free( ber, 1 ); } return rc; }
int ldap_passwd( LDAP *ld, struct berval *user, struct berval *oldpw, struct berval *newpw, LDAPControl **sctrls, LDAPControl **cctrls, int *msgidp ) { int rc; struct berval bv = BER_BVNULL; BerElement *ber = NULL; assert( ld != NULL ); assert( LDAP_VALID( ld ) ); assert( msgidp != NULL ); if( user != NULL || oldpw != NULL || newpw != NULL ) { /* build change password control */ ber = ber_alloc_t( LBER_USE_DER ); if( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } ber_printf( ber, "{" /*}*/ ); if( user != NULL ) { ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user ); } if( oldpw != NULL ) { ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, oldpw ); } if( newpw != NULL ) { ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, newpw ); } ber_printf( ber, /*{*/ "N}" ); rc = ber_flatten2( ber, &bv, 0 ); if( rc < 0 ) { ld->ld_errno = LDAP_ENCODING_ERROR; return ld->ld_errno; } } rc = ldap_extended_operation( ld, LDAP_EXOP_MODIFY_PASSWD, bv.bv_val ? &bv : NULL, sctrls, cctrls, msgidp ); ber_free( ber, 1 ); return rc; }
meta_search_candidate_t asyncmeta_back_search_start( Operation *op, SlapReply *rs, a_metaconn_t *mc, bm_context_t *bc, int candidate, struct berval *prcookie, ber_int_t prsize ) { SlapReply *candidates = bc->candidates; a_metainfo_t *mi = ( a_metainfo_t * )mc->mc_info; a_metatarget_t *mt = mi->mi_targets[ candidate ]; a_metasingleconn_t *msc = &mc->mc_conns[ candidate ]; a_dncookie dc; struct berval realbase = op->o_req_dn; int realscope = op->ors_scope; struct berval mbase = BER_BVNULL; struct berval mfilter = BER_BVNULL; char **mapped_attrs = NULL; int rc; meta_search_candidate_t retcode; int timelimit; int nretries = 1; LDAPControl **ctrls = NULL; BerElement *ber; ber_int_t msgid; #ifdef SLAPD_META_CLIENT_PR LDAPControl **save_ctrls = NULL; #endif /* SLAPD_META_CLIENT_PR */ /* this should not happen; just in case... */ if ( msc->msc_ld == NULL ) { Debug( LDAP_DEBUG_ANY, "%s: asyncmeta_back_search_start candidate=%d ld=NULL%s.\n", op->o_log_prefix, candidate, META_BACK_ONERR_STOP( mi ) ? "" : " (ignored)" ); candidates[ candidate ].sr_err = LDAP_OTHER; if ( META_BACK_ONERR_STOP( mi ) ) { return META_SEARCH_ERR; } candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; return META_SEARCH_NOT_CANDIDATE; } Debug( LDAP_DEBUG_TRACE, "%s >>> asyncmeta_back_search_start[%d]\n", op->o_log_prefix, candidate, 0 ); /* * modifies the base according to the scope, if required */ if ( mt->mt_nsuffix.bv_len > op->o_req_ndn.bv_len ) { switch ( op->ors_scope ) { case LDAP_SCOPE_SUBTREE: /* * make the target suffix the new base * FIXME: this is very forgiving, because * "illegal" searchBases may be turned * into the suffix of the target; however, * the requested searchBase already passed * thru the candidate analyzer... */ if ( dnIsSuffix( &mt->mt_nsuffix, &op->o_req_ndn ) ) { realbase = mt->mt_nsuffix; if ( mt->mt_scope == LDAP_SCOPE_SUBORDINATE ) { realscope = LDAP_SCOPE_SUBORDINATE; } } else { /* * this target is no longer candidate */ retcode = META_SEARCH_NOT_CANDIDATE; goto doreturn; } break; case LDAP_SCOPE_SUBORDINATE: case LDAP_SCOPE_ONELEVEL: { struct berval rdn = mt->mt_nsuffix; rdn.bv_len -= op->o_req_ndn.bv_len + STRLENOF( "," ); if ( dnIsOneLevelRDN( &rdn ) && dnIsSuffix( &mt->mt_nsuffix, &op->o_req_ndn ) ) { /* * if there is exactly one level, * make the target suffix the new * base, and make scope "base" */ realbase = mt->mt_nsuffix; if ( op->ors_scope == LDAP_SCOPE_SUBORDINATE ) { if ( mt->mt_scope == LDAP_SCOPE_SUBORDINATE ) { realscope = LDAP_SCOPE_SUBORDINATE; } else { realscope = LDAP_SCOPE_SUBTREE; } } else { realscope = LDAP_SCOPE_BASE; } break; } /* else continue with the next case */ } case LDAP_SCOPE_BASE: /* * this target is no longer candidate */ retcode = META_SEARCH_NOT_CANDIDATE; goto doreturn; } } /* check filter expression */ if ( mt->mt_filter ) { metafilter_t *mf; for ( mf = mt->mt_filter; mf; mf = mf->mf_next ) { if ( regexec( &mf->mf_regex, op->ors_filterstr.bv_val, 0, NULL, 0 ) == 0 ) break; } /* nothing matched, this target is no longer a candidate */ if ( !mf ) { retcode = META_SEARCH_NOT_CANDIDATE; goto doreturn; } } /* * Rewrite the search base, if required */ dc.target = mt; dc.ctx = "searchBase"; dc.conn = op->o_conn; dc.rs = rs; switch ( asyncmeta_dn_massage( &dc, &realbase, &mbase ) ) { case LDAP_SUCCESS: break; case LDAP_UNWILLING_TO_PERFORM: rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "Operation not allowed"; retcode = META_SEARCH_ERR; goto doreturn; default: /* * this target is no longer candidate */ retcode = META_SEARCH_NOT_CANDIDATE; goto doreturn; } /* * Maps filter */ rc = asyncmeta_filter_map_rewrite( &dc, op->ors_filter, &mfilter, BACKLDAP_MAP, NULL ); switch ( rc ) { case LDAP_SUCCESS: break; case LDAP_COMPARE_FALSE: default: /* * this target is no longer candidate */ retcode = META_SEARCH_NOT_CANDIDATE; goto done; } /* * Maps required attributes */ rc = asyncmeta_map_attrs( op, &mt->mt_rwmap.rwm_at, op->ors_attrs, BACKLDAP_MAP, &mapped_attrs ); if ( rc != LDAP_SUCCESS ) { /* * this target is no longer candidate */ retcode = META_SEARCH_NOT_CANDIDATE; goto done; } if ( op->ors_tlimit != SLAP_NO_LIMIT ) { timelimit = op->ors_tlimit > 0 ? op->ors_tlimit : 1; } else { timelimit = -1; /* no limit */ } #ifdef SLAPD_META_CLIENT_PR save_ctrls = op->o_ctrls; { LDAPControl *pr_c = NULL; int i = 0, nc = 0; if ( save_ctrls ) { for ( ; save_ctrls[i] != NULL; i++ ); nc = i; pr_c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, save_ctrls, NULL ); } if ( pr_c != NULL ) nc--; if ( mt->mt_ps > 0 || prcookie != NULL ) nc++; if ( mt->mt_ps > 0 || prcookie != NULL || pr_c != NULL ) { int src = 0, dst = 0; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; struct berval val = BER_BVNULL; ber_len_t len; len = sizeof( LDAPControl * )*( nc + 1 ) + sizeof( LDAPControl ); if ( mt->mt_ps > 0 || prcookie != NULL ) { struct berval nullcookie = BER_BVNULL; ber_tag_t tag; if ( prsize == 0 && mt->mt_ps > 0 ) prsize = mt->mt_ps; if ( prcookie == NULL ) prcookie = &nullcookie; ber_init2( ber, NULL, LBER_USE_DER ); tag = ber_printf( ber, "{iO}", prsize, prcookie ); if ( tag == LBER_ERROR ) { /* error */ (void) ber_free_buf( ber ); goto done_pr; } tag = ber_flatten2( ber, &val, 0 ); if ( tag == LBER_ERROR ) { /* error */ (void) ber_free_buf( ber ); goto done_pr; } len += val.bv_len + 1; } op->o_ctrls = op->o_tmpalloc( len, op->o_tmpmemctx ); if ( save_ctrls ) { for ( ; save_ctrls[ src ] != NULL; src++ ) { if ( save_ctrls[ src ] != pr_c ) { op->o_ctrls[ dst ] = save_ctrls[ src ]; dst++; } } } if ( mt->mt_ps > 0 || prcookie != NULL ) { op->o_ctrls[ dst ] = (LDAPControl *)&op->o_ctrls[ nc + 1 ]; op->o_ctrls[ dst ]->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS; op->o_ctrls[ dst ]->ldctl_iscritical = 1; op->o_ctrls[ dst ]->ldctl_value.bv_val = (char *)&op->o_ctrls[ dst ][ 1 ]; AC_MEMCPY( op->o_ctrls[ dst ]->ldctl_value.bv_val, val.bv_val, val.bv_len + 1 ); op->o_ctrls[ dst ]->ldctl_value.bv_len = val.bv_len; dst++; (void)ber_free_buf( ber ); } op->o_ctrls[ dst ] = NULL; } done_pr:; } #endif /* SLAPD_META_CLIENT_PR */ retry:; asyncmeta_set_msc_time(msc); ctrls = op->o_ctrls; if (nretries == 0) { if (rc != LDAP_SUCCESS) { rs->sr_err = LDAP_BUSY; retcode = META_SEARCH_ERR; candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; goto done; } } if ( asyncmeta_controls_add( op, rs, mc, candidate, &ctrls ) != LDAP_SUCCESS ) { candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; retcode = META_SEARCH_NOT_CANDIDATE; goto done; } /* * Starts the search */ ber = ldap_build_search_req( msc->msc_ld, mbase.bv_val, realscope, mfilter.bv_val, mapped_attrs, op->ors_attrsonly, ctrls, NULL, timelimit, op->ors_slimit, op->ors_deref, &msgid ); if (ber) { candidates[ candidate ].sr_msgid = msgid; rc = ldap_send_initial_request( msc->msc_ld, LDAP_REQ_SEARCH, mbase.bv_val, ber, msgid ); if (rc == msgid) rc = LDAP_SUCCESS; else rc = LDAP_SERVER_DOWN; switch ( rc ) { case LDAP_SUCCESS: retcode = META_SEARCH_CANDIDATE; asyncmeta_set_msc_time(msc); break; case LDAP_SERVER_DOWN: ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex); if (mc->mc_active < 1) { asyncmeta_clear_one_msc(NULL, mc, candidate); } ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex); if ( nretries && asyncmeta_retry( op, rs, &mc, candidate, LDAP_BACK_DONTSEND ) ) { nretries = 0; /* if the identity changed, there might be need to re-authz */ (void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls ); goto retry; } rs->sr_err = LDAP_UNAVAILABLE; retcode = META_SEARCH_ERR; break; default: candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; retcode = META_SEARCH_NOT_CANDIDATE; } } done:; (void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls ); #ifdef SLAPD_META_CLIENT_PR if ( save_ctrls != op->o_ctrls ) { op->o_tmpfree( op->o_ctrls, op->o_tmpmemctx ); op->o_ctrls = save_ctrls; } #endif /* SLAPD_META_CLIENT_PR */ if ( mapped_attrs ) { ber_memfree_x( mapped_attrs, op->o_tmpmemctx ); } if ( mfilter.bv_val != op->ors_filterstr.bv_val ) { ber_memfree_x( mfilter.bv_val, NULL ); } if ( mbase.bv_val != realbase.bv_val ) { free( mbase.bv_val ); } doreturn:; Debug( LDAP_DEBUG_TRACE, "%s <<< asyncmeta_back_search_start[%p]=%d\n", op->o_log_prefix, msc, candidates[candidate].sr_msgid ); return retcode; }
int VmDirCreateAppendEntriesCtrl( PVDIR_APPEND_ENTRIES_CONTROL_VALUE pAppendEntriesCtrlValue, LDAPControl* pAppendEntriesCtrl ) { int retVal = LDAP_SUCCESS; BerElement* pBer = NULL; BerValue leaderBV = {0}; BerValue preLogIndexBV = {0}; BerValue leaderCommitBV = {0}; BerValue entriesBV = {0}; if (!pAppendEntriesCtrlValue || !pAppendEntriesCtrl) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_INVALID_PARAMETER); } if ((pBer = ber_alloc()) == NULL) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_NO_MEMORY); } leaderBV.bv_val = (char*)pAppendEntriesCtrlValue->leader; leaderBV.bv_len = VmDirStringLenA(pAppendEntriesCtrlValue->leader); retVal = VmDirAllocateStringPrintf(&preLogIndexBV.bv_val, "%"PRIu64, pAppendEntriesCtrlValue->preLogIndex); BAIL_ON_VMDIR_ERROR( retVal ); preLogIndexBV.bv_len = VmDirStringLenA(preLogIndexBV.bv_val); retVal = VmDirAllocateStringPrintf(&leaderCommitBV.bv_val, "%"PRIu64, pAppendEntriesCtrlValue->leaderCommit); BAIL_ON_VMDIR_ERROR( retVal ); leaderCommitBV.bv_len = VmDirStringLenA( leaderCommitBV.bv_val); entriesBV.bv_val = pAppendEntriesCtrlValue->entries.lberbv.bv_val; entriesBV.bv_len = pAppendEntriesCtrlValue->entries.lberbv.bv_len; if ( ber_printf( pBer, "{iOOiOO}", pAppendEntriesCtrlValue->term, &leaderBV, &preLogIndexBV, pAppendEntriesCtrlValue->preLogTerm, &leaderCommitBV, &entriesBV) == -1) { VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: ber_printf failed.", __FUNCTION__ ); BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_NO_MEMORY); } memset( pAppendEntriesCtrl, 0, sizeof( LDAPControl )); pAppendEntriesCtrl->ldctl_oid = LDAP_APPEND_ENTRIES_CONTROL; pAppendEntriesCtrl->ldctl_iscritical = '1'; if (ber_flatten2(pBer, &pAppendEntriesCtrl->ldctl_value, 1)) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_NO_MEMORY); } cleanup: VMDIR_SAFE_FREE_MEMORY(preLogIndexBV.bv_val); VMDIR_SAFE_FREE_MEMORY(leaderCommitBV.bv_val); if (pBer) { ber_free(pBer, 1); } return retVal; error: VmDirFreeCtrlContent(pAppendEntriesCtrl); goto cleanup; }