X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fslapi%2Fslapi_ops.c;h=199fc8daf3142d5824d26a017e24edc70d8dc956;hb=35dc15ad6649d47749455d46e2bf186f035da62e;hp=0cc32804d445c99a8ff228f941191df532b04e82;hpb=a6a6946a67202271c2434067abd0d0d15168c667;p=openldap diff --git a/servers/slapd/slapi/slapi_ops.c b/servers/slapd/slapi/slapi_ops.c index 0cc32804d4..199fc8daf3 100644 --- a/servers/slapd/slapi/slapi_ops.c +++ b/servers/slapd/slapi/slapi_ops.c @@ -3,21 +3,26 @@ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ /* - * (C) Copyright IBM Corp. 1997,2002 - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and that due credit is - * given to IBM Corporation. This software is provided ``as is'' - * without express or implied warranty. + * Portions Copyright IBM Corp. 1997,2002-2003 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License, version 2.7 or later. */ /* * Portions (C) Copyright PADL Software Pty Ltd. 2003 - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and that due credit is - * given to PADL Software Pty Ltd. This software is provided ``as is'' - * without express or implied warranty. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that this notice is preserved + * and that due credit is given to PADL Software Pty Ltd. This software + * is provided ``as is'' without express or implied warranty. */ #include "portable.h" + +#include +#include +#include +#include + #include #include #include @@ -27,12 +32,10 @@ * so it can be used in ACLs */ static struct slap_listener slap_unknown_listener = { - BER_BVC("unknown"), /* FIXME: use a URI form? */ + BER_BVC("unknown"), /* FIXME: use a URI form? (e.g. slapi://) */ BER_BVC("UNKNOWN") }; -int bvptr2obj( struct berval **bvptr, struct berval **bvobj ); - static void internal_result_v3( Operation *op, @@ -54,12 +57,12 @@ internal_search_entry( Operation *op, SlapReply *rs ) { - char *ent2str = NULL; int nentries = 0, len = 0, i = 0; Slapi_Entry **head = NULL, **tp; - - ent2str = slapi_entry2str( rs->sr_entry, &len ); - if ( ent2str == NULL ) { + Slapi_Entry *entry; + + entry = slapi_entry_dup( rs->sr_entry ); + if ( entry == NULL ) { return 1; } @@ -72,24 +75,19 @@ internal_search_entry( if ( nentries == 0 ) { tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) ); if ( tp == NULL ) { + slapi_entry_free( entry ); return 1; } - tp[ 0 ] = (Slapi_Entry *)str2entry( ent2str ); - if ( tp[ 0 ] == NULL ) { - return 1; - } - + tp[ 0 ] = entry; } else { tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head, sizeof(Slapi_Entry *) * ( i + 1 ) ); if ( tp == NULL ) { + slapi_entry_free( entry ); return 1; } - tp[ i - 1 ] = (Slapi_Entry *)str2entry( ent2str ); - if ( tp[ i - 1 ] == NULL ) { - return 1; - } + tp[ i - 1 ] = entry; } tp[ i ] = NULL; @@ -168,7 +166,6 @@ slapiConnectionInit( c->c_dn.bv_len = 0; c->c_ndn.bv_val = NULL; c->c_ndn.bv_len = 0; - c->c_groups = NULL; c->c_listener = &slap_unknown_listener; ber_dupbv( &c->c_peer_domain, (struct berval *)&slap_unknown_bv ); @@ -178,7 +175,8 @@ slapiConnectionInit( c->c_sasl_bind_mech.bv_val = NULL; c->c_sasl_bind_mech.bv_len = 0; - c->c_sasl_context = NULL; + c->c_sasl_authctx = NULL; + c->c_sasl_sockctx = NULL; c->c_sasl_extra = NULL; c->c_sb = ber_sockbuf_alloc( ); @@ -256,9 +254,9 @@ static void slapiConnectionDestroy( Connection **pConn ) * the strings. */ static int -values2obj( +values2obj_copy( char **ppValue, - BerVarray *bvobj) + BerVarray *bvobj ) { int i; BerVarray tmpberval; @@ -276,8 +274,11 @@ values2obj( return LDAP_NO_MEMORY; } for ( i = 0; ppValue[i] != NULL; i++ ) { - tmpberval[i].bv_val = ppValue[i]; - tmpberval[i].bv_len = strlen( ppValue[i] ); + size_t len = strlen( ppValue[i] ); + + tmpberval[i].bv_val = slapi_ch_malloc( len + 1 ); + AC_MEMCPY( tmpberval[i].bv_val, ppValue[i], len + 1 ); + tmpberval[i].bv_len = len; } tmpberval[i].bv_val = NULL; tmpberval[i].bv_len = 0; @@ -287,23 +288,41 @@ values2obj( return LDAP_SUCCESS; } -static void -freeMods( Modifications *ml ) +static int +bvptr2obj_copy( + struct berval **bvptr, + BerVarray *bvobj ) { - /* - * Free a modification list whose values have been - * set with bvptr2obj() or values2obj() (ie. they - * do not own the pointer to the underlying values) - */ - Modifications *next; + int rc = LDAP_SUCCESS; + int i; + BerVarray tmpberval; - for ( ; ml != NULL; ml = next ) { - next = ml->sml_next; + if ( bvptr == NULL || *bvptr == NULL ) { + return LDAP_OTHER; + } - slapi_ch_free( (void **)&ml->sml_bvalues ); - slapi_ch_free( (void **)&ml->sml_nvalues ); - slapi_ch_free( (void **)&ml ); + for ( i = 0; bvptr != NULL && bvptr[i] != NULL; i++ ) { + ; /* EMPTY */ } + + tmpberval = (BerVarray)slapi_ch_malloc( (i + 1)*sizeof(struct berval)); + if ( tmpberval == NULL ) { + return LDAP_NO_MEMORY; + } + + for ( i = 0; bvptr[i] != NULL; i++ ) { + tmpberval[i].bv_val = slapi_ch_malloc( bvptr[i]->bv_len ); + tmpberval[i].bv_len = bvptr[i]->bv_len; + AC_MEMCPY( tmpberval[i].bv_val, bvptr[i]->bv_val, bvptr[i]->bv_len ); + } + tmpberval[i].bv_val = NULL; + tmpberval[i].bv_len = 0; + + if ( rc == LDAP_SUCCESS ) { + *bvobj = tmpberval; + } + + return rc; } /* @@ -336,7 +355,7 @@ LDAPModToEntry( op = (Operation *) slapi_ch_calloc(1, sizeof(Operation)); - if ( pEntry == NULL) { + if ( op == NULL) { rc = LDAP_NO_MEMORY; goto cleanup; } @@ -352,17 +371,25 @@ LDAPModToEntry( dn.bv_len = strlen(ldn); rc = dnPrettyNormal( NULL, &dn, &pEntry->e_name, &pEntry->e_nname, NULL ); - if ( rc != LDAP_SUCCESS ) + if ( rc != LDAP_SUCCESS ) { goto cleanup; + } if ( rc == LDAP_SUCCESS ) { - for ( i=0, pMod=mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod=mods[++i]) { + for ( i = 0, pMod = mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod = mods[++i]) { Modifications *mod; + if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) { - /* attr values are in berval format */ - /* convert an array of pointers to bervals to an array of bervals */ - rc = bvptr2obj(pMod->mod_bvalues, &bv); - if (rc != LDAP_SUCCESS) goto cleanup; + /* + * Convert an array of pointers to bervals to + * an array of bervals. Note that we need to copy the + * values too, as the slap_mods_check() will free the + * original values after prettying; the modifications + * being passed in may not have been allocated on the + * heap. + */ + rc = bvptr2obj_copy( pMod->mod_bvalues, &bv ); + if ( rc != LDAP_SUCCESS ) goto cleanup; tmp.sml_type.bv_val = pMod->mod_type; tmp.sml_type.bv_len = strlen( pMod->mod_type ); tmp.sml_bvalues = bv; @@ -386,8 +413,8 @@ LDAPModToEntry( if ( pMod->mod_values == NULL ) { rc = LDAP_OTHER; } else { - rc = values2obj( pMod->mod_values, &bv ); - if (rc != LDAP_SUCCESS) goto cleanup; + rc = values2obj_copy( pMod->mod_values, &bv ); + if ( rc != LDAP_SUCCESS ) goto cleanup; tmp.sml_type.bv_val = pMod->mod_type; tmp.sml_type.bv_len = strlen( pMod->mod_type ); tmp.sml_bvalues = bv; @@ -434,12 +461,8 @@ LDAPModToEntry( } } - /* - * FIXME: slap_mods2entry is declared static - * in servers/slapd/add.c - */ rc = slap_mods2entry( modlist, &pEntry, repl_user, - &text, textbuf, textlen ); + 0, &text, textbuf, textlen ); if (rc != LDAP_SUCCESS) { goto cleanup; } @@ -456,7 +479,7 @@ cleanup: if ( op ) slapi_ch_free( (void **)&op ); if ( modlist != NULL ) - freeMods( modlist ); + slap_mods_free( modlist ); if ( rc != LDAP_SUCCESS ) { if ( pEntry != NULL ) { slapi_entry_free( pEntry ); @@ -565,13 +588,13 @@ cleanup: #endif /* LDAP_SLAPI */ } -Slapi_PBlock * -slapi_add_entry_internal( - Slapi_Entry *e, +#ifdef LDAP_SLAPI +static Slapi_PBlock * +slapi_add_entry_internal_locked( + Slapi_Entry **e, LDAPControl **controls, int log_changes ) { -#ifdef LDAP_SLAPI Connection *pConn = NULL; Operation *op = NULL; Slapi_PBlock *pPB = NULL, *pSavePB = NULL; @@ -580,7 +603,7 @@ slapi_add_entry_internal( int isCritical; SlapReply rs = { REP_RESULT }; - if ( e == NULL ) { + if ( *e == NULL ) { rs.sr_err = LDAP_PARAM_ERROR; goto cleanup; } @@ -600,7 +623,7 @@ slapi_add_entry_internal( pPB = (Slapi_PBlock *)op->o_pb; op->o_ctrls = controls; - op->o_bd = select_backend( &e->e_nname, manageDsaIt, 0 ); + op->o_bd = select_backend( &((*e)->e_nname), manageDsaIt, 0 ); if ( op->o_bd == NULL ) { rs.sr_err = LDAP_PARTIAL_RESULTS; goto cleanup; @@ -608,15 +631,17 @@ slapi_add_entry_internal( op->o_dn = pConn->c_dn = op->o_bd->be_rootdn; op->o_ndn = pConn->c_ndn = op->o_bd->be_rootndn; - op->oq_add.rs_e = e; + op->oq_add.rs_e = *e; if ( op->o_bd->be_add ) { int repl_user = be_isupdate( op->o_bd, &op->o_ndn ); - if ( !op->o_bd->be_update_ndn.bv_len || repl_user ){ + if ( !op->o_bd->be_update_ndn.bv_len || repl_user ) { if ( (*op->o_bd->be_add)( op, &rs ) == 0 ) { if ( log_changes ) { replog( op ); } + be_entry_release_w( op, *e ); + *e = NULL; } } else { rs.sr_err = LDAP_REFERRAL; @@ -638,12 +663,34 @@ cleanup: slapiConnectionDestroy( &pConn ); return( pSavePB ); +} +#endif /* LDAP_SLAPI */ + +Slapi_PBlock * +slapi_add_entry_internal( + Slapi_Entry *e, + LDAPControl **controls, + int log_changes ) +{ +#ifdef LDAP_SLAPI + Slapi_PBlock *pb; + Slapi_Entry *entry; + + /* + * We make a copy to avoid an entry that may be freed later + * by the caller being placed in the cache. + */ + entry = slapi_entry_dup( e ); + pb = slapi_add_entry_internal_locked( &entry, controls, log_changes ); + if ( entry != NULL ) { + slapi_entry_free( entry ); + } + return pb; #else return NULL; -#endif /* LDAP_SLAPI */ +#endif } - Slapi_PBlock * slapi_add_internal( char *dn, @@ -671,7 +718,8 @@ slapi_add_internal( } if ( rc == LDAP_SUCCESS ) { - if((pEntry = LDAPModToEntry( dn, mods )) == NULL) { + pEntry = LDAPModToEntry( dn, mods ); + if ( pEntry == NULL ) { rc = LDAP_OTHER; } } @@ -680,10 +728,10 @@ slapi_add_internal( pb = slapi_pblock_new(); slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc ); } else { - pb = slapi_add_entry_internal( pEntry, controls, log_changes ); + pb = slapi_add_entry_internal_locked( &pEntry, controls, log_changes ); } - if ( pEntry ) { + if ( pEntry != NULL ) { slapi_entry_free(pEntry); } @@ -907,7 +955,7 @@ slapi_modify_internal( * convert an array of pointers to bervals * to an array of bervals */ - rs.sr_err = bvptr2obj( pMod->mod_bvalues, &bv ); + rs.sr_err = bvptr2obj_copy( pMod->mod_bvalues, &bv ); if ( rs.sr_err != LDAP_SUCCESS ) goto cleanup; tmp.sml_type.bv_val = pMod->mod_type; @@ -924,7 +972,7 @@ slapi_modify_internal( mod->sml_bvalues = tmp.sml_bvalues; mod->sml_nvalues = tmp.sml_nvalues; } else { - rs.sr_err = values2obj( pMod->mod_values, &bv ); + rs.sr_err = values2obj_copy( pMod->mod_values, &bv ); if ( rs.sr_err != LDAP_SUCCESS ) goto cleanup; tmp.sml_type.bv_val = pMod->mod_type; @@ -1015,7 +1063,7 @@ cleanup: slapi_ch_free( (void **)&dn.bv_val ); if ( modlist != NULL ) - freeMods( modlist ); + slap_mods_free( modlist ); if ( pConn != NULL ) { pSavePB = pPB; @@ -1066,8 +1114,10 @@ slapi_search_internal_bind( ptr = (Slapi_PBlock *)op->o_pb; op->o_ctrls = controls; - dn.bv_val = slapi_ch_strdup(ldn); - dn.bv_len = strlen(ldn); + if ( ldn != NULL ) { + dn.bv_val = slapi_ch_strdup(ldn); + dn.bv_len = strlen(ldn); + } rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn, NULL ); if ( rs.sr_err != LDAP_SUCCESS ) { @@ -1143,8 +1193,8 @@ slapi_search_internal_bind( } if ( !op->o_req_ndn.bv_len && default_search_nbase.bv_len ) { - slapi_ch_free( (void **)op->o_req_dn.bv_val ); - slapi_ch_free( (void **)op->o_req_ndn.bv_val ); + slapi_ch_free( (void **)&op->o_req_dn.bv_val ); + slapi_ch_free( (void **)&op->o_req_ndn.bv_val ); ber_dupbv( &op->o_req_dn, &default_search_base ); ber_dupbv( &op->o_req_ndn, &default_search_nbase );