X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fmodify.c;h=99e31fe033bec6a696287ce17a0da2fbde2dbb05;hb=b44cc963c2b021821ccac582054e2ffa04f4f1e1;hp=7f953276a14ef9b9d854670e72dd21382ce70ddb;hpb=ddb9755ba7557a1a456431bc8af0bd02b21579dc;p=openldap diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index 7f953276a1..99e31fe033 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -1,6 +1,6 @@ /* $OpenLDAP$ */ /* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ /* @@ -27,17 +27,12 @@ #include "slap.h" -#ifndef SLAPD_SCHEMA_NOT_COMPAT -static int add_modified_attrs( Operation *op, Modifications **modlist ); -#endif - int do_modify( Connection *conn, - Operation *op -) + Operation *op ) { - char *dn, *ndn; + char *dn, *ndn = NULL; char *last; ber_tag_t tag; ber_len_t len; @@ -49,6 +44,8 @@ do_modify( Modifications *mods = NULL; Backend *be; int rc; + const char *text; + int manageDSAit; Debug( LDAP_DEBUG_TRACE, "do_modify\n", 0, 0, 0 ); @@ -131,11 +128,6 @@ do_modify( } (*modtail)->ml_op = mop; - -#ifndef SLAPD_SCHEMA_NOT_COMPAT - attr_normalize( (*modtail)->ml_type ); -#endif - modtail = &(*modtail)->ml_next; } *modtail = NULL; @@ -154,6 +146,13 @@ do_modify( goto cleanup; } + if( ndn == '\0' ) { + Debug( LDAP_DEBUG_ANY, "do_modify: root dse!\n", 0, 0, 0 ); + send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM, + NULL, "modify upon the root DSE not supported", NULL, NULL ); + goto cleanup; + } + #ifdef LDAP_DEBUG Debug( LDAP_DEBUG_ARGS, "modifications:\n", 0, 0, 0 ); for ( tmp = modlist; tmp != NULL; tmp = tmp->ml_next ) { @@ -164,35 +163,33 @@ do_modify( } #endif - Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d MOD dn=\"%s\"\n", op->o_connid, op->o_opid, dn, 0, 0 ); + manageDSAit = get_manageDSAit( op ); + /* * 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 ( (be = select_backend( ndn )) == NULL ) { + if ( (be = select_backend( ndn, manageDSAit )) == NULL ) { send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL, default_referral, NULL ); goto cleanup; } - /* make sure this backend recongizes critical controls */ - rc = backend_check_controls( be, conn, op ) ; - + /* check restrictions */ + rc = backend_check_restrictions( be, conn, op, NULL, &text ) ; if( rc != LDAP_SUCCESS ) { send_ldap_result( conn, op, rc, - NULL, NULL, NULL, NULL ); + NULL, text, NULL, NULL ); goto cleanup; } - if ( global_readonly || be->be_readonly ) { - Debug( LDAP_DEBUG_ANY, "do_modify: database is read-only\n", - 0, 0, 0 ); - send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM, - NULL, "database is read-only", NULL, NULL ); + /* check for referrals */ + rc = backend_check_referrals( be, conn, op, dn, ndn ); + if ( rc != LDAP_SUCCESS ) { goto cleanup; } @@ -216,8 +213,7 @@ do_modify( #endif { int update = be->be_update_ndn != NULL; -#ifdef SLAPD_SCHEMA_NOT_COMPAT - char *text; + const char *text; rc = slap_modlist2mods( modlist, update, &mods, &text ); if( rc != LDAP_SUCCESS ) { @@ -225,20 +221,18 @@ do_modify( NULL, text, NULL, NULL ); goto cleanup; } -#else - mods = modlist; - modlist = NULL; -#endif if ( (be->be_lastmod == ON || (be->be_lastmod == UNDEFINED && global_lastmod == ON)) && !update ) { -#ifdef SLAPD_SCHEMA_NOT_COMPAT - rc = slap_mods_opattrs( op, &mods, &text ); -#else - char *text = "no-user-modification attribute type"; - rc = add_modified_attrs( op, &mods ); -#endif + Modifications **modstail; + for( modstail = &mods; + *modstail != NULL; + modstail = &(*modstail)->sml_next ) + { + /* empty */ + } + rc = slap_mods_opattrs( op, modstail, &text ); if( rc != LDAP_SUCCESS ) { send_ldap_result( conn, op, rc, @@ -268,12 +262,12 @@ do_modify( } } else { send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM, - NULL, "Function not implemented", NULL, NULL ); + NULL, "operation not supported within namingContext", NULL, NULL ); } cleanup: free( dn ); - free( ndn ); + if( ndn != NULL ) free( ndn ); if ( modlist != NULL ) slap_modlist_free( modlist ); if ( mods != NULL ) @@ -281,7 +275,6 @@ cleanup: return rc; } -#ifdef SLAPD_SCHEMA_NOT_COMPAT /* * convert a raw list of modifications to internal format * Do basic attribute type checking and syntax validation. @@ -290,30 +283,33 @@ int slap_modlist2mods( LDAPModList *ml, int update, Modifications **mods, - char **text ) + const char **text ) { int rc; Modifications **modtail = mods; for( ; ml != NULL; ml = ml->ml_next ) { Modifications *mod; - AttributeDescription *ad; + AttributeDescription *ad = NULL; mod = (Modifications *) ch_calloc( 1, sizeof(Modifications) ); - ad = mod->sml_desc; + /* copy the op */ + mod->sml_op = ml->ml_op; /* convert to attribute description */ - rc = slap_str2ad( ml->ml_type, &ad, text ); + rc = slap_str2ad( ml->ml_type, &mod->sml_desc, text ); if( rc != LDAP_SUCCESS ) { slap_mods_free( mod ); return rc; } - if((ad->ad_type->sat_syntax->ssyn_flags & SLAP_SYNTAX_BINARY) - && !( ad->ad_flags & SLAP_DESC_BINARY )) + ad = mod->sml_desc; + + if( slap_syntax_is_binary( ad->ad_type->sat_syntax ) + && !slap_ad_is_binary( ad )) { /* attribute requires binary transfer */ slap_mods_free( mod ); @@ -321,6 +317,15 @@ int slap_modlist2mods( return LDAP_UNDEFINED_TYPE; } + if( !slap_syntax_is_binary( ad->ad_type->sat_syntax ) + && slap_ad_is_binary( ad )) + { + /* attribute requires binary transfer */ + slap_mods_free( mod ); + *text = "attribute disallows ;binary transfer"; + return LDAP_UNDEFINED_TYPE; + } + if (!update && is_at_no_user_mod( ad->ad_type )) { /* user modification disallowed */ slap_mods_free( mod ); @@ -336,6 +341,15 @@ int slap_modlist2mods( slap_syntax_validate_func *validate = ad->ad_type->sat_syntax->ssyn_validate; + if( !validate ) { + Debug( LDAP_DEBUG_TRACE, + "modlist2mods: no validator for syntax %s\n", + ad->ad_type->sat_syntax->ssyn_oid, 0, 0 ); + slap_mods_free( mod ); + *text = "no validator for syntax"; + return LDAP_INVALID_SYNTAX; + } + /* * check that each value is valid per syntax */ @@ -353,7 +367,7 @@ int slap_modlist2mods( * a rough single value check... an additional check is needed * to catch add of single value to existing single valued attribute */ - if( ( ml->ml_op == LDAP_MOD_ADD || ml->ml_op == LDAP_MOD_REPLACE ) + if( ( mod->sml_op == LDAP_MOD_ADD || mod->sml_op == LDAP_MOD_REPLACE ) && nvals > 1 && is_at_single_value( ad->ad_type )) { slap_mods_free( mod ); @@ -375,19 +389,20 @@ int slap_modlist2mods( int slap_mods_opattrs( Operation *op, Modifications **modtail, - char **text ) + const char **text ) { - int rc; struct berval name, timestamp; time_t now = slap_get_time(); char timebuf[22]; struct tm *ltm; Modifications *mod; - AttributeDescription *ad; int mop = op->o_tag == LDAP_REQ_ADD ? LDAP_MOD_ADD : LDAP_MOD_REPLACE; + assert( modtail != NULL ); + assert( *modtail == NULL ); + ldap_pvt_thread_mutex_lock( &gmtime_mutex ); ltm = gmtime( &now ); strftime( timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", ltm ); @@ -396,57 +411,27 @@ int slap_mods_opattrs( timestamp.bv_len = strlen(timebuf); if( op->o_dn == NULL || op->o_dn[0] == '\0' ) { - name.bv_val = ""; - name.bv_len = sizeof("")-1; + name.bv_val = SLAPD_ANONYMOUS; + name.bv_len = sizeof(SLAPD_ANONYMOUS)-1; } else { name.bv_val = op->o_dn; name.bv_len = strlen( op->o_dn ); } if( op->o_tag == LDAP_REQ_ADD ) { - rc = slap_str2ad( "creatorsName", &ad, text ); - if( rc == LDAP_SUCCESS ) { - mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) ); - mod->sml_op = mop; - mod->sml_desc = ad; - mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) ); - mod->sml_bvalues[0] = ber_bvdup( &name ); - mod->sml_bvalues[1] = NULL; - - *modtail = mod; - modtail = &mod->sml_next; - } - - rc = slap_str2ad( "createTimeStamp", &ad, text ); - if( rc == LDAP_SUCCESS ) { - mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) ); - mod->sml_op = mop; - mod->sml_desc = ad; - mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) ); - mod->sml_bvalues[0] = ber_bvdup( ×tamp ); - mod->sml_bvalues[1] = NULL; - *modtail = mod; - modtail = &mod->sml_next; - } - } - - rc = slap_str2ad( "modifiersName", &ad, text ); - if( rc == LDAP_SUCCESS ) { mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) ); mod->sml_op = mop; - mod->sml_desc = ad; + mod->sml_desc = ad_dup( slap_schema.si_ad_creatorsName ); mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) ); mod->sml_bvalues[0] = ber_bvdup( &name ); mod->sml_bvalues[1] = NULL; + *modtail = mod; modtail = &mod->sml_next; - } - rc = slap_str2ad( "modifyTimeStamp", &ad, text ); - if( rc == LDAP_SUCCESS ) { mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) ); mod->sml_op = mop; - mod->sml_desc = ad; + mod->sml_desc = ad_dup( slap_schema.si_ad_createTimestamp ); mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) ); mod->sml_bvalues[0] = ber_bvdup( ×tamp ); mod->sml_bvalues[1] = NULL; @@ -454,64 +439,27 @@ int slap_mods_opattrs( modtail = &mod->sml_next; } - return LDAP_SUCCESS; -} - -#else -static int -add_modified_attrs( Operation *op, Modifications **modlist ) -{ - char buf[22]; - struct berval bv; - struct berval *bvals[2]; - Modifications *m; - struct tm *ltm; - time_t currenttime; - - bvals[0] = &bv; - bvals[1] = NULL; - - /* remove any attempts by the user to modify these attrs */ - for ( m = *modlist; m != NULL; m = m->ml_next ) { - if ( oc_check_op_no_usermod_attr( m->ml_type ) ) { - return LDAP_CONSTRAINT_VIOLATION; - } - } - - if ( op->o_dn == NULL || op->o_dn[0] == '\0' ) { - bv.bv_val = ""; - bv.bv_len = sizeof("")-1; - } else { - bv.bv_val = op->o_dn; - bv.bv_len = strlen( bv.bv_val ); - } - m = (Modifications *) ch_calloc( 1, sizeof(Modifications) ); - m->ml_type = ch_strdup( "modifiersname" ); - m->ml_op = LDAP_MOD_REPLACE; - m->ml_bvalues = (struct berval **) ch_calloc(2, sizeof(struct berval *)); - m->ml_bvalues[0] = ber_bvdup( &bv ); - m->ml_next = *modlist; - *modlist = m; - - currenttime = slap_get_time(); - ldap_pvt_thread_mutex_lock( &gmtime_mutex ); - ltm = gmtime( ¤ttime ); - strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm ); - ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); - - bv.bv_val = buf; - bv.bv_len = strlen( bv.bv_val ); - m = (Modifications *) ch_calloc( 1, sizeof(Modifications) ); - m->ml_type = ch_strdup( "modifytimestamp" ); - m->ml_op = LDAP_MOD_REPLACE; - m->ml_bvalues = (struct berval **) ch_calloc(2, sizeof(struct berval *)); - m->ml_bvalues[0] = ber_bvdup( &bv ); - m->ml_next = *modlist; - *modlist = m; + mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) ); + mod->sml_op = mop; + mod->sml_desc = ad_dup( slap_schema.si_ad_modifiersName ); + mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) ); + mod->sml_bvalues[0] = ber_bvdup( &name ); + mod->sml_bvalues[1] = NULL; + *modtail = mod; + modtail = &mod->sml_next; + + mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) ); + mod->sml_op = mop; + mod->sml_desc = ad_dup( slap_schema.si_ad_modifyTimestamp ); + mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) ); + mod->sml_bvalues[0] = ber_bvdup( ×tamp ); + mod->sml_bvalues[1] = NULL; + *modtail = mod; + modtail = &mod->sml_next; return LDAP_SUCCESS; } -#endif + void slap_mod_free( @@ -519,13 +467,7 @@ slap_mod_free( int freeit ) { -#ifdef SLAPD_SCHEMA_NOT_COMPAT ad_free( mod->sm_desc, 1 ); -#else - if (mod->sm_desc) { - free( mod->sm_desc ); - } -#endif if ( mod->sm_bvalues != NULL ) ber_bvecfree( mod->sm_bvalues );