static int rdnval_op_rename( Operation *op, SlapReply *rs ) { Modifications *ml, **mlp; int numvals = 0; BerVarray vals = NULL, nvals = NULL; struct berval old; int rc; dnRdn( &op->o_req_dn, &old ); if ( dn_match( &old, &op->orr_newrdn ) ) { dnRdn( &op->o_req_ndn, &old ); if ( dn_match( &old, &op->orr_nnewrdn ) ) { return SLAP_CB_CONTINUE; } } rc = rdnval_rdn2vals( op, rs, &op->orr_newrdn, &op->orr_nnewrdn, &vals, &nvals, &numvals ); if ( rc != LDAP_SUCCESS ) { send_ldap_result( op, rs ); } ml = SLAP_CALLOC( sizeof( Modifications ), 1 ); ml->sml_values = vals; ml->sml_nvalues = nvals; ml->sml_numvals = numvals; ml->sml_op = LDAP_MOD_REPLACE; ml->sml_flags = SLAP_MOD_INTERNAL; ml->sml_desc = ad_rdnValue; ml->sml_type = ad_rdnValue->ad_cname; for ( mlp = &op->orr_modlist; *mlp != NULL; mlp = &(*mlp)->sml_next ) /* goto tail */ ; *mlp = ml; return SLAP_CB_CONTINUE; }
static int vernum_op_modify( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; vernum_t *vn = (vernum_t *)on->on_bi.bi_private; Modifications *ml, **mlp; struct berval val = BER_BVC( "1" ); int rc; unsigned got = 0; for ( ml = op->orm_modlist; ml != NULL; ml = ml->sml_next ) { if ( ml->sml_desc == vn->vn_vernum ) { /* already present - leave it alone * (or should we increment it anyway?) */ return SLAP_CB_CONTINUE; } if ( ml->sml_desc == vn->vn_attr ) { got = 1; } } if ( !got ) { return SLAP_CB_CONTINUE; } for ( mlp = &op->orm_modlist; *mlp != NULL; mlp = &(*mlp)->sml_next ) /* goto tail */ ; /* ITS#6561 */ #ifdef SLAP_MOD_ADD_IF_NOT_PRESENT /* the initial value is only added if the vernum attr is not present */ ml = SLAP_CALLOC( sizeof( Modifications ), 1 ); ml->sml_values = SLAP_CALLOC( sizeof( struct berval ) , 2 ); value_add_one( &ml->sml_values, &val_init ); ml->sml_nvalues = NULL; ml->sml_numvals = 1; ml->sml_op = SLAP_MOD_ADD_IF_NOT_PRESENT; ml->sml_flags = SLAP_MOD_INTERNAL; ml->sml_desc = vn->vn_vernum; ml->sml_type = vn->vn_vernum->ad_cname; *mlp = ml; mlp = &ml->sml_next; #endif /* SLAP_MOD_ADD_IF_NOT_PRESENT */ /* this increments by 1 the vernum attr */ ml = SLAP_CALLOC( sizeof( Modifications ), 1 ); ml->sml_values = SLAP_CALLOC( sizeof( struct berval ) , 2 ); value_add_one( &ml->sml_values, &val ); ml->sml_nvalues = NULL; ml->sml_numvals = 1; ml->sml_op = LDAP_MOD_INCREMENT; ml->sml_flags = SLAP_MOD_INTERNAL; ml->sml_desc = vn->vn_vernum; ml->sml_type = vn->vn_vernum->ad_cname; *mlp = ml; return SLAP_CB_CONTINUE; }
static int vc_exop( Operation *op, SlapReply *rs ) { int rc = LDAP_SUCCESS; ber_tag_t tag; ber_len_t len = -1; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; struct berval reqdata = BER_BVNULL; struct berval cookie = BER_BVNULL; struct berval bdn = BER_BVNULL; ber_tag_t authtag; struct berval cred = BER_BVNULL; struct berval ndn = BER_BVNULL; struct berval mechanism = BER_BVNULL; vc_conn_t *conn = NULL; vc_cb_t vc = { 0 }; slap_callback sc = { 0 }; SlapReply rs2 = { 0 }; if ( op->ore_reqdata == NULL || op->ore_reqdata->bv_len == 0 ) { rs->sr_text = "empty request data field in VerifyCredentials exop"; return LDAP_PROTOCOL_ERROR; } /* optimistic */ rs->sr_err = LDAP_SUCCESS; ber_dupbv_x( &reqdata, op->ore_reqdata, op->o_tmpmemctx ); /* ber_init2 uses reqdata directly, doesn't allocate new buffers */ ber_init2( ber, &reqdata, 0 ); tag = ber_scanf( ber, "{" /*}*/ ); if ( tag != LBER_SEQUENCE ) { rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } tag = ber_peek_tag( ber, &len ); if ( tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE ) { /* * cookie: the pointer to the connection * of this operation */ ber_scanf( ber, "m", &cookie ); if ( cookie.bv_len != sizeof(Connection *) ) { rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } } /* DN, authtag */ tag = ber_scanf( ber, "mt", &bdn, &authtag ); if ( tag == LBER_ERROR ) { rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } rc = dnNormalize( 0, NULL, NULL, &bdn, &ndn, op->o_tmpmemctx ); if ( rc != LDAP_SUCCESS ) { rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } switch ( authtag ) { case LDAP_AUTH_SIMPLE: /* cookie only makes sense for SASL bind (so far) */ if ( !BER_BVISNULL( &cookie ) ) { rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } tag = ber_scanf( ber, "m", &cred ); if ( tag == LBER_ERROR ) { rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } break; case LDAP_AUTH_SASL: tag = ber_scanf( ber, "{s" /*}*/ , &mechanism ); if ( tag == LBER_ERROR || BER_BVISNULL( &mechanism ) || BER_BVISEMPTY( &mechanism ) ) { rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } tag = ber_peek_tag( ber, &len ); if ( tag == LBER_OCTETSTRING ) { ber_scanf( ber, "m", &cred ); } tag = ber_scanf( ber, /*{*/ "}" ); break; default: rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } if ( !BER_BVISNULL( &cookie ) ) { vc_conn_t tmp = { 0 }; AC_MEMCPY( (char *)&tmp.conn, (const char *)cookie.bv_val, cookie.bv_len ); ldap_pvt_thread_mutex_lock( &vc_mutex ); conn = (vc_conn_t *)avl_find( vc_tree, (caddr_t)&tmp, vc_conn_cmp ); if ( conn == NULL || ( conn != NULL && conn->refcnt != 0 ) ) { conn = NULL; ldap_pvt_thread_mutex_unlock( &vc_mutex ); rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } conn->refcnt++; ldap_pvt_thread_mutex_unlock( &vc_mutex ); } else { void *thrctx; conn = (vc_conn_t *)SLAP_CALLOC( 1, sizeof( vc_conn_t ) ); conn->refcnt = 1; thrctx = ldap_pvt_thread_pool_context(); connection_fake_init2( &conn->connbuf, &conn->opbuf, thrctx, 0 ); conn->op = &conn->opbuf.ob_op; snprintf( conn->op->o_log_prefix, sizeof( conn->op->o_log_prefix ), "%s VERIFYCREDENTIALS", op->o_log_prefix ); } conn->op->o_tag = LDAP_REQ_BIND; memset( &conn->op->oq_bind, 0, sizeof( conn->op->oq_bind ) ); conn->op->o_req_dn = ndn; conn->op->o_req_ndn = ndn; conn->op->o_protocol = LDAP_VERSION3; conn->op->orb_method = authtag; conn->op->o_callback = ≻ /* TODO: controls */ tag = ber_peek_tag( ber, &len ); if ( tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS ) { conn->op->o_ber = ber; rc = get_ctrls2( conn->op, &rs2, 0, LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS ); if ( rc != LDAP_SUCCESS ) { rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } } tag = ber_skip_tag( ber, &len ); if ( len || tag != LBER_DEFAULT ) { rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } switch ( authtag ) { case LDAP_AUTH_SIMPLE: break; case LDAP_AUTH_SASL: conn->op->orb_mech = mechanism; break; } conn->op->orb_cred = cred; sc.sc_response = vc_cb; sc.sc_private = &vc; conn->op->o_bd = frontendDB; rs->sr_err = frontendDB->be_bind( conn->op, &rs2 ); if ( conn->op->o_conn->c_sasl_bind_in_progress ) { rc = vc_create_response( conn, rs2.sr_err, rs2.sr_text, !BER_BVISEMPTY( &vc.sasldata ) ? &vc.sasldata : NULL, NULL, vc.ctrls, &rs->sr_rspdata ); } else { rc = vc_create_response( NULL, rs2.sr_err, rs2.sr_text, NULL, &conn->op->o_conn->c_dn, vc.ctrls, &rs->sr_rspdata ); } if ( rc != 0 ) { rs->sr_err = LDAP_OTHER; goto done; } if ( !BER_BVISNULL( &conn->op->o_conn->c_dn ) && conn->op->o_conn->c_dn.bv_val != conn->op->o_conn->c_ndn.bv_val ) ber_memfree( conn->op->o_conn->c_dn.bv_val ); if ( !BER_BVISNULL( &conn->op->o_conn->c_ndn ) ) ber_memfree( conn->op->o_conn->c_ndn.bv_val ); done:; if ( conn ) { if ( conn->op->o_conn->c_sasl_bind_in_progress ) { if ( conn->conn == NULL ) { conn->conn = conn; conn->refcnt--; ldap_pvt_thread_mutex_lock( &vc_mutex ); rc = avl_insert( &vc_tree, (caddr_t)conn, vc_conn_cmp, vc_conn_dup ); ldap_pvt_thread_mutex_unlock( &vc_mutex ); assert( rc == 0 ); } else { ldap_pvt_thread_mutex_lock( &vc_mutex ); conn->refcnt--; ldap_pvt_thread_mutex_unlock( &vc_mutex ); } } else { if ( conn->conn != NULL ) { vc_conn_t *tmp; ldap_pvt_thread_mutex_lock( &vc_mutex ); tmp = avl_delete( &vc_tree, (caddr_t)conn, vc_conn_cmp ); ldap_pvt_thread_mutex_unlock( &vc_mutex ); } SLAP_FREE( conn ); } } if ( vc.ctrls ) { ldap_controls_free( vc.ctrls ); vc.ctrls = NULL; } if ( !BER_BVISNULL( &ndn ) ) { op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx ); BER_BVZERO( &ndn ); } op->o_tmpfree( reqdata.bv_val, op->o_tmpmemctx ); BER_BVZERO( &reqdata ); return rs->sr_err; }
int modify_delete_values( Entry *e, Modification *mod, int permissive, const char **text, char *textbuf, size_t textlen ) { int i, j, k, rc = LDAP_SUCCESS; Attribute *a; MatchingRule *mr = mod->sm_desc->ad_type->sat_equality; BerVarray nvals = NULL; char dummy = '\0'; /* * If permissive is set, then the non-existence of an * attribute is not treated as an error. */ /* delete the entire attribute */ if ( mod->sm_bvalues == NULL ) { rc = attr_delete( &e->e_attrs, mod->sm_desc ); if( permissive ) { rc = LDAP_SUCCESS; } else if( rc != LDAP_SUCCESS ) { *text = textbuf; snprintf( textbuf, textlen, "modify/delete: %s: no such attribute", mod->sm_desc->ad_cname.bv_val ); rc = LDAP_NO_SUCH_ATTRIBUTE; } return rc; } if( mr == NULL || !mr->smr_match ) { /* disallow specific attributes from being deleted if no equality rule */ *text = textbuf; snprintf( textbuf, textlen, "modify/delete: %s: no equality matching rule", mod->sm_desc->ad_cname.bv_val ); return LDAP_INAPPROPRIATE_MATCHING; } /* delete specific values - find the attribute first */ if ( (a = attr_find( e->e_attrs, mod->sm_desc )) == NULL ) { if( permissive ) { return LDAP_SUCCESS; } *text = textbuf; snprintf( textbuf, textlen, "modify/delete: %s: no such attribute", mod->sm_desc->ad_cname.bv_val ); return LDAP_NO_SUCH_ATTRIBUTE; } /* find each value to delete */ for ( j = 0; a->a_vals[ j ].bv_val != NULL; j++ ) /* count existing values */ ; nvals = (BerVarray)SLAP_CALLOC( j + 1, sizeof ( struct berval ) ); if( nvals == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "modify_delete_values: SLAP_CALLOC failed", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "modify_delete_values: SLAP_CALLOC failed", 0, 0, 0 ); #endif goto return_results; } /* normalize existing values */ for ( j = 0; a->a_vals[ j ].bv_val != NULL; j++ ) { rc = value_normalize( a->a_desc, SLAP_MR_EQUALITY, &a->a_vals[ j ], &nvals[ j ], text ); if ( rc != LDAP_SUCCESS ) { nvals[ j ].bv_val = NULL; goto return_results; } } for ( i = 0; mod->sm_bvalues[ i ].bv_val != NULL; i++ ) { struct berval asserted; int found = 0; /* normalize the value to be deleted */ rc = value_normalize( mod->sm_desc, SLAP_MR_EQUALITY, &mod->sm_bvalues[ i ], &asserted, text ); if( rc != LDAP_SUCCESS ) { goto return_results; } /* search it */ for ( j = 0; nvals[ j ].bv_val != NULL; j++ ) { int match; if ( nvals[ j ].bv_val == &dummy ) { continue; } rc = (*mr->smr_match)( &match, SLAP_MR_VALUE_SYNTAX_MATCH, a->a_desc->ad_type->sat_syntax, mr, &nvals[ j ], &asserted ); if ( rc != LDAP_SUCCESS ) { free( asserted.bv_val ); *text = textbuf; snprintf( textbuf, textlen, "%s: matching rule failed", mod->sm_desc->ad_cname.bv_val ); goto return_results; } if ( match != 0 ) { continue; } found = 1; /* delete value and mark it as dummy */ free( nvals[ j ].bv_val ); nvals[ j ].bv_val = &dummy; break; } free( asserted.bv_val ); if ( found == 0 ) { *text = textbuf; snprintf( textbuf, textlen, "modify/delete: %s: no such value", mod->sm_desc->ad_cname.bv_val ); rc = LDAP_NO_SUCH_ATTRIBUTE; goto return_results; } } /* compact array skipping dummies */ for ( k = 0, j = 0; nvals[ k ].bv_val != NULL; j++, k++ ) { /* delete and skip dummies */ ; for ( ; nvals[ k ].bv_val == &dummy; k++ ) { free( a->a_vals[ k ].bv_val ); } if ( j != k ) { a->a_vals[ j ] = a->a_vals[ k ]; } if ( a->a_vals[ k ].bv_val == NULL ) { break; } } a->a_vals[ j ].bv_val = NULL; assert( i == k - j ); /* if no values remain, delete the entire attribute */ if ( a->a_vals[0].bv_val == NULL ) { if ( attr_delete( &e->e_attrs, mod->sm_desc ) ) { *text = textbuf; snprintf( textbuf, textlen, "modify/delete: %s: no such attribute", mod->sm_desc->ad_cname.bv_val ); rc = LDAP_NO_SUCH_ATTRIBUTE; } } return_results:; if ( nvals ) { /* delete the remaining normalized values */ for ( j = 0; nvals[ j ].bv_val != NULL; j++ ) { if ( nvals[ j ].bv_val != &dummy ) { ber_memfree( nvals[ j ].bv_val ); } } ber_memfree( nvals ); } return rc; }
int modify_check_duplicates( AttributeDescription *ad, MatchingRule *mr, BerVarray vals, BerVarray mods, int permissive, const char **text, char *textbuf, size_t textlen ) { int i, j, numvals = 0, nummods, rc = LDAP_SUCCESS, matched; BerVarray nvals = NULL, nmods = NULL; /* * FIXME: better do the following * * - count the existing values * - count the new values * * - if the existing values are less than the new ones { * - normalize all the existing values * - for each new value { * - normalize * - check with existing * - cross-check with already normalized new vals * } * } else { * - for each new value { * - normalize * - cross-check with already normalized new vals * } * - for each existing value { * - normalize * - check with already normalized new values * } * } * * The first case is good when adding a lot of new values, * and significantly at first import of values (e.g. adding * a new group); the latter case seems to be quite important * as well, because it is likely to be the most frequently * used when administering the entry. The current * implementation will always normalize all the existing * values before checking. If there's no duplicate, the * performances should not change; they will in case of error. */ for ( nummods = 0; mods[ nummods ].bv_val != NULL; nummods++ ) /* count new values */ ; if ( vals ) { for ( numvals = 0; vals[ numvals ].bv_val != NULL; numvals++ ) /* count existing values */ ; if ( numvals < nummods ) { nvals = SLAP_CALLOC( numvals + 1, sizeof( struct berval ) ); if( nvals == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "modify_check_duplicates: SLAP_CALLOC failed", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "modify_check_duplicates: SLAP_CALLOC failed", 0, 0, 0 ); #endif goto return_results; } /* normalize the existing values first */ for ( j = 0; vals[ j ].bv_val != NULL; j++ ) { rc = value_normalize( ad, SLAP_MR_EQUALITY, &vals[ j ], &nvals[ j ], text ); /* existing attribute values must normalize */ assert( rc == LDAP_SUCCESS ); if ( rc != LDAP_SUCCESS ) { nvals[ j ].bv_val = NULL; goto return_results; } } nvals[ j ].bv_val = NULL; } } /* * If the existing values are less than the new values, * it is more convenient to normalize all the existing * values and test each new value against them first, * then to other already normalized values */ nmods = SLAP_CALLOC( nummods + 1, sizeof( struct berval ) ); if ( nmods == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "modify_check_duplicates: SLAP_CALLOC failed", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "modify_check_duplicates: SLAP_CALLOC failed", 0, 0, 0 ); #endif goto return_results; } for ( i = 0; mods[ i ].bv_val != NULL; i++ ) { rc = value_normalize( ad, SLAP_MR_EQUALITY, &mods[ i ], &nmods[ i ], text ); if ( rc != LDAP_SUCCESS ) { nmods[ i ].bv_val = NULL; goto return_results; } if ( numvals > 0 && numvals < nummods ) { for ( matched = 0, j = 0; nvals[ j ].bv_val; j++ ) { int match; rc = (*mr->smr_match)( &match, SLAP_MR_VALUE_SYNTAX_MATCH, ad->ad_type->sat_syntax, mr, &nmods[ i ], &nvals[ j ] ); if ( rc != LDAP_SUCCESS ) { nmods[ i + 1 ].bv_val = NULL; *text = textbuf; snprintf( textbuf, textlen, "%s: matching rule failed", ad->ad_cname.bv_val ); goto return_results; } if ( match == 0 ) { if ( permissive ) { matched++; continue; } *text = textbuf; snprintf( textbuf, textlen, "%s: value #%d provided more than once", ad->ad_cname.bv_val, i ); rc = LDAP_TYPE_OR_VALUE_EXISTS; nmods[ i + 1 ].bv_val = NULL; goto return_results; } } if ( permissive && matched == j ) { nmods[ i + 1 ].bv_val = NULL; rc = LDAP_TYPE_OR_VALUE_EXISTS; goto return_results; } } for ( matched = 0, j = 0; j < i; j++ ) { int match; rc = (*mr->smr_match)( &match, SLAP_MR_VALUE_SYNTAX_MATCH, ad->ad_type->sat_syntax, mr, &nmods[ i ], &nmods[ j ] ); if ( rc != LDAP_SUCCESS ) { nmods[ i + 1 ].bv_val = NULL; *text = textbuf; snprintf( textbuf, textlen, "%s: matching rule failed", ad->ad_cname.bv_val ); goto return_results; } if ( match == 0 ) { if ( permissive ) { matched++; continue; } *text = textbuf; snprintf( textbuf, textlen, "%s: value #%d provided more than once", ad->ad_cname.bv_val, j ); rc = LDAP_TYPE_OR_VALUE_EXISTS; nmods[ i + 1 ].bv_val = NULL; goto return_results; } } if ( permissive && matched == j ) { nmods[ i + 1 ].bv_val = NULL; rc = LDAP_TYPE_OR_VALUE_EXISTS; goto return_results; } } nmods[ i ].bv_val = NULL; /* * if new values are more than existing values, it is more * convenient to normalize and check all new values first, * then check each new value against existing values, which * can be normalized in place */ if ( numvals >= nummods ) { for ( j = 0; vals[ j ].bv_val; j++ ) { struct berval asserted; rc = value_normalize( ad, SLAP_MR_EQUALITY, &vals[ j ], &asserted, text ); if ( rc != LDAP_SUCCESS ) { goto return_results; } for ( matched = 0, i = 0; nmods[ i ].bv_val; i++ ) { int match; rc = (*mr->smr_match)( &match, SLAP_MR_VALUE_SYNTAX_MATCH, ad->ad_type->sat_syntax, mr, &nmods[ i ], &asserted ); if ( rc != LDAP_SUCCESS ) { *text = textbuf; snprintf( textbuf, textlen, "%s: matching rule failed", ad->ad_cname.bv_val ); free( asserted.bv_val ); goto return_results; } if ( match == 0 ) { if ( permissive ) { matched++; continue; } *text = textbuf; snprintf( textbuf, textlen, "%s: value #%d provided more than once", ad->ad_cname.bv_val, j ); rc = LDAP_TYPE_OR_VALUE_EXISTS; free( asserted.bv_val ); goto return_results; } } free( asserted.bv_val ); if ( permissive && matched == i ) { rc = LDAP_TYPE_OR_VALUE_EXISTS; goto return_results; } } } return_results:; if ( nvals ) { ber_bvarray_free( nvals ); } if ( nmods ) { ber_bvarray_free( nmods ); } return rc; }
static int cloak_cfgen( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)c->bi; cloak_info_t *ci = (cloak_info_t *)on->on_bi.bi_private; int rc = 0, i; if ( c->op == SLAP_CONFIG_EMIT ) { switch( c->type ) { case CLOAK_ATTR: for ( i = 0; ci; i++, ci = ci->ci_next ) { struct berval bv; int len; assert( ci->ci_ad != NULL ); if ( ci->ci_oc != NULL ) len = snprintf( c->cr_msg, sizeof( c->cr_msg ), SLAP_X_ORDERED_FMT "%s %s", i, ci->ci_ad->ad_cname.bv_val, ci->ci_oc->soc_cname.bv_val ); else len = snprintf( c->cr_msg, sizeof( c->cr_msg ), SLAP_X_ORDERED_FMT "%s", i, ci->ci_ad->ad_cname.bv_val ); bv.bv_val = c->cr_msg; bv.bv_len = len; value_add_one( &c->rvalue_vals, &bv ); } break; default: rc = 1; break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { cloak_info_t *ci_next; switch( c->type ) { case CLOAK_ATTR: for ( ci_next = ci, i = 0; ci_next, c->valx < 0 || i < c->valx; ci = ci_next, i++ ){ ci_next = ci->ci_next; ch_free ( ci->ci_ad ); if ( ci->ci_oc != NULL ) ch_free ( ci->ci_oc ); ch_free( ci ); } ci = (cloak_info_t *)on->on_bi.bi_private; break; default: rc = 1; break; } return rc; } switch( c->type ) { case CLOAK_ATTR: { ObjectClass *oc = NULL; AttributeDescription *ad = NULL; const char *text; cloak_info_t **cip = NULL; cloak_info_t *ci_next = NULL; if ( c->argc == 3 ) { oc = oc_find( c->argv[ 2 ] ); if ( oc == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), CLOAK_USAGE "unable to find ObjectClass \"%s\"", c->argv[ 2 ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } } rc = slap_str2ad( c->argv[ 1 ], &ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), CLOAK_USAGE "unable to find AttributeDescription \"%s\"", c->argv[ 1 ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } for ( i = 0, cip = (cloak_info_t **)&on->on_bi.bi_private; c->valx < 0 || i < c->valx, *cip; i++, cip = &(*cip)->ci_next ) { if ( c->valx >= 0 && *cip == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), CLOAK_USAGE "invalid index {%d}\n", c->valx ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } ci_next = *cip; } *cip = (cloak_info_t *)SLAP_CALLOC( 1, sizeof( cloak_info_t ) ); (*cip)->ci_oc = oc; (*cip)->ci_ad = ad; (*cip)->ci_next = ci_next; rc = 0; break; } default: rc = 1; break; } return rc; }
static int rdnval_rdn2vals( Operation *op, SlapReply *rs, struct berval *dn, struct berval *ndn, BerVarray *valsp, BerVarray *nvalsp, int *numvalsp ) { LDAPRDN rdn = NULL, nrdn = NULL; int nAVA, i; assert( *valsp == NULL ); assert( *nvalsp == NULL ); *numvalsp = 0; if ( ldap_bv2rdn_x( dn, &rdn, (char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ) ) { Debug( LDAP_DEBUG_TRACE, "%s rdnval: can't figure out " "type(s)/value(s) of rdn DN=\"%s\"\n", op->o_log_prefix, dn->bv_val, 0 ); rs->sr_err = LDAP_INVALID_DN_SYNTAX; rs->sr_text = "unknown type(s) used in RDN"; goto done; } if ( ldap_bv2rdn_x( ndn, &nrdn, (char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ) ) { Debug( LDAP_DEBUG_TRACE, "%s rdnval: can't figure out " "type(s)/value(s) of normalized rdn DN=\"%s\"\n", op->o_log_prefix, ndn->bv_val, 0 ); rs->sr_err = LDAP_INVALID_DN_SYNTAX; rs->sr_text = "unknown type(s) used in RDN"; goto done; } for ( nAVA = 0; rdn[ nAVA ]; nAVA++ ) /* count'em */ ; /* NOTE: we assume rdn and nrdn contain the same AVAs! */ *valsp = SLAP_CALLOC( sizeof( struct berval ), nAVA + 1 ); *nvalsp = SLAP_CALLOC( sizeof( struct berval ), nAVA + 1 ); /* Add new attribute values to the entry */ for ( i = 0; rdn[ i ]; i++ ) { AttributeDescription *desc = NULL; rs->sr_err = slap_bv2ad( &rdn[ i ]->la_attr, &desc, &rs->sr_text ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "%s rdnval: %s: %s\n", op->o_log_prefix, rs->sr_text, rdn[ i ]->la_attr.bv_val ); goto done; } if ( !rdnval_is_valid( desc, &rdn[ i ]->la_value ) ) { Debug( LDAP_DEBUG_TRACE, "%s rdnval: syntax of naming attribute '%s' " "not compatible with directoryString", op->o_log_prefix, rdn[ i ]->la_attr.bv_val, 0 ); continue; } if ( value_find_ex( desc, SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, *nvalsp, &nrdn[ i ]->la_value, op->o_tmpmemctx ) == LDAP_NO_SUCH_ATTRIBUTE ) { ber_dupbv( &(*valsp)[ *numvalsp ], &rdn[ i ]->la_value ); ber_dupbv( &(*nvalsp)[ *numvalsp ], &nrdn[ i ]->la_value ); (*numvalsp)++; } } if ( rdnval_unique_check( op, *valsp ) != LDAP_SUCCESS ) { rs->sr_err = LDAP_CONSTRAINT_VIOLATION; rs->sr_text = "rdnValue not unique within siblings"; goto done; } done:; if ( rdn != NULL ) { ldap_rdnfree_x( rdn, op->o_tmpmemctx ); } if ( nrdn != NULL ) { ldap_rdnfree_x( nrdn, op->o_tmpmemctx ); } if ( rs->sr_err != LDAP_SUCCESS ) { if ( *valsp != NULL ) { ber_bvarray_free( *valsp ); ber_bvarray_free( *nvalsp ); *valsp = NULL; *nvalsp = NULL; *numvalsp = 0; } } return rs->sr_err; }