📄 modrdn.c
字号:
LDAP_INSUFFICIENT_ACCESS, NULL, NULL, NULL, NULL ); goto return_results; } } } Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: wr to new parent's children OK\n", 0, 0 , 0 ); new_parent_dn = np_dn; } /* Build target dn and make sure target entry doesn't exist already. */ build_new_dn( &new_dn, e->e_dn, new_parent_dn, newrdn ); new_ndn = ch_strdup(new_dn); (void) dn_normalize( new_ndn ); Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: new ndn=%s\n", new_ndn, 0, 0 ); /* check for abandon */ ldap_pvt_thread_mutex_lock( &op->o_abandonmutex ); if ( op->o_abandon ) { ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex ); goto return_results; } ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex ); if ( ( rc_id = dn2id ( be, new_ndn, &id ) ) || id != NOID ) { /* if (rc_id) something bad happened to ldbm cache */ send_ldap_result( conn, op, rc_id ? LDAP_OPERATIONS_ERROR : LDAP_ALREADY_EXISTS, NULL, NULL, NULL, NULL ); goto return_results; } Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: new ndn=%s does not exist\n", new_ndn, 0, 0 ); /* Get attribute types and values of our new rdn, we will * need to add that to our new entry */ if ( rdn_attrs( newrdn, &new_rdn_types, &new_rdn_vals ) ) { Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: can't figure out type(s)/value(s) of newrdn\n", 0, 0, 0 ); send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, "unable to parse type(s)/value(s) used in RDN", NULL, NULL ); goto return_results; } Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: new_rdn_val=\"%s\", new_rdn_type=\"%s\"\n", new_rdn_vals[0], new_rdn_types[0], 0 ); /* Retrieve the old rdn from the entry's dn */ if ( (old_rdn = dn_rdn( be, dn )) == NULL ) { Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: can't figure out old_rdn from dn\n", 0, 0, 0 ); send_ldap_result( conn, op, LDAP_OTHER, NULL, "could not parse old DN", NULL, NULL ); goto return_results; } if ( rdn_attrs( old_rdn, &old_rdn_types, &old_rdn_vals ) ) { Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: can't figure out the old_rdn type(s)/value(s)\n", 0, 0, 0 ); send_ldap_result( conn, op, LDAP_OTHER, NULL, "unable to parse type(s)/value(s) used in RDN from old DN", NULL, NULL ); goto return_results; } if ( newSuperior == NULL && charray_strcasecmp( (const char **)old_rdn_types, (const char **)new_rdn_types ) != 0 ) { /* Not a big deal but we may say something */ Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: old_rdn_type=%s, new_rdn_type=%s!\n", old_rdn_types[0], new_rdn_types[0], 0 ); } Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: DN_X500\n", 0, 0, 0 ); mod = NULL; for ( a_cnt = 0; new_rdn_types[a_cnt]; a_cnt++ ) { int rc; Modifications *mod_tmp; struct berval val; mod_tmp = (Modifications *)ch_malloc( sizeof( Modifications ) ); mod_tmp->sml_desc = NULL; rc = slap_str2ad( new_rdn_types[a_cnt], &mod_tmp->sml_desc, &text ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: %s: %s (new)\n", text, new_rdn_types[a_cnt], 0 ); send_ldap_result( conn, op, rc, NULL, text, NULL, NULL ); goto return_results; } val.bv_val = new_rdn_vals[a_cnt]; val.bv_len = strlen( val.bv_val ); if ( ! access_allowed( be, conn, op, e, mod_tmp->sml_desc, &val, ACL_WRITE ) ) { Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: access not allowed " "to attr \"%s\"\n%s%s", new_rdn_types[a_cnt], "", "" ); send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, NULL, NULL, NULL, NULL ); goto return_results; } mod_tmp->sml_bvalues = (struct berval **)ch_malloc( 2 * sizeof(struct berval *) ); mod_tmp->sml_bvalues[0] = ber_bvstrdup( new_rdn_vals[a_cnt] ); mod_tmp->sml_bvalues[1] = NULL; mod_tmp->sml_op = SLAP_MOD_SOFTADD; mod_tmp->sml_next = mod; mod = mod_tmp; } /* Remove old rdn value if required */ if ( deleteoldrdn ) { /* Get value of old rdn */ if ( old_rdn_vals == NULL ) { Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: can't figure out oldRDN value(s) from old RDN\n", 0, 0, 0 ); send_ldap_result( conn, op, LDAP_OTHER, NULL, "could not parse value(s) from old RDN", NULL, NULL ); goto return_results; } for ( d_cnt = 0; old_rdn_types[d_cnt]; d_cnt++ ) { int rc; Modifications *mod_tmp; struct berval val; mod_tmp = (Modifications *)ch_malloc( sizeof( Modifications ) ); mod_tmp->sml_desc = NULL; rc = slap_str2ad( old_rdn_types[d_cnt], &mod_tmp->sml_desc, &text ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: %s: %s (old)\n", text, old_rdn_types[d_cnt], 0 ); send_ldap_result( conn, op, rc, NULL, text, NULL, NULL ); goto return_results; } val.bv_val = old_rdn_vals[d_cnt]; val.bv_len = strlen( val.bv_val ); if ( ! access_allowed( be, conn, op, e, mod_tmp->sml_desc, &val, ACL_WRITE ) ) { Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: access not allowed " "to attr \"%s\"\n%s%s", old_rdn_types[d_cnt], "", "" ); send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, NULL, NULL, NULL, NULL ); goto return_results; } /* Remove old value of rdn as an attribute. */ mod_tmp->sml_bvalues = (struct berval **)ch_malloc( 2 * sizeof(struct berval *) ); mod_tmp->sml_bvalues[0] = ber_bvstrdup( old_rdn_vals[d_cnt] ); mod_tmp->sml_bvalues[1] = NULL; mod_tmp->sml_op = LDAP_MOD_DELETE; mod_tmp->sml_next = mod; mod = mod_tmp; Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: removing old_rdn_val=%s\n", old_rdn_vals[0], 0, 0 ); } } /* check for abandon */ ldap_pvt_thread_mutex_lock( &op->o_abandonmutex ); if ( op->o_abandon ) { ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex ); goto return_results; } ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex ); /* delete old one */ if ( dn2id_delete( be, e->e_ndn, e->e_id ) != 0 ) { send_ldap_result( conn, op, LDAP_OTHER, NULL, "DN index delete fail", NULL, NULL ); goto return_results; } (void) cache_delete_entry( &li->li_cache, e ); rc = MUST_DESTROY; /* XXX: there is no going back! */ free( e->e_dn ); free( e->e_ndn ); e->e_dn = new_dn; e->e_ndn = new_ndn; new_dn = NULL; new_ndn = NULL; /* add new one */ if ( dn2id_add( be, e->e_ndn, e->e_id ) != 0 ) { send_ldap_result( conn, op, LDAP_OTHER, NULL, "DN index add failed", NULL, NULL ); goto return_results; } /* modify memory copy of entry */ rc = ldbm_modify_internal( be, conn, op, dn, &mod[0], e, &text, textbuf, textlen ); if( rc != LDAP_SUCCESS ) { if( rc != SLAPD_ABANDON ) { send_ldap_result( conn, op, rc, NULL, text, NULL, NULL ); } /* here we may try to delete the newly added dn */ if ( dn2id_delete( be, e->e_ndn, e->e_id ) != 0 ) { /* we already are in trouble ... */ ; } goto return_results; } (void) cache_update_entry( &li->li_cache, e ); /* NOTE: after this you must not free new_dn or new_ndn! * They are used by cache. */ /* id2entry index */ if ( id2entry_add( be, e ) != 0 ) { send_ldap_result( conn, op, LDAP_OTHER, NULL, "entry update failed", NULL, NULL ); goto return_results; } send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, NULL ); rc = 0; cache_entry_commit( e );return_results: if( new_dn != NULL ) free( new_dn ); if( new_ndn != NULL ) free( new_ndn ); if( p_dn != NULL ) free( p_dn ); if( p_ndn != NULL ) free( p_ndn ); /* LDAP v2 supporting correct attribute handling. */ if( new_rdn_types != NULL ) charray_free( new_rdn_types ); if( new_rdn_vals != NULL ) charray_free( new_rdn_vals ); if( old_rdn != NULL ) free(old_rdn); if( old_rdn_types != NULL ) charray_free( old_rdn_types ); if( old_rdn_vals != NULL ) charray_free( old_rdn_vals ); if ( mod != NULL ) { slap_mods_free( mod ); } /* LDAP v3 Support */ if ( np_dn != NULL ) free( np_dn ); if ( np_ndn != NULL ) free( np_ndn ); if( np != NULL ) { /* free new parent and writer lock */ cache_return_entry_w( &li->li_cache, np ); } if( p != NULL ) { /* free parent and writer lock */ cache_return_entry_w( &li->li_cache, p ); } if ( rootlock ) { /* release root writer lock */ ldap_pvt_thread_mutex_unlock(&li->li_root_mutex); } /* free entry and writer lock */ cache_return_entry_w( &li->li_cache, e ); if ( rc == MUST_DESTROY ) { /* if rc == MUST_DESTROY the entry is uncached * and its private data is destroyed; * the entry must be freed */ entry_free( e ); } return( rc );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -