Back to index

openldap  2.4.31
add.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1998-2012 The OpenLDAP Foundation.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted only as authorized by the OpenLDAP
00009  * Public License.
00010  *
00011  * A copy of this license is available in the file LICENSE in the
00012  * top-level directory of the distribution or, alternatively, at
00013  * <http://www.OpenLDAP.org/license.html>.
00014  */
00015 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
00016  * All rights reserved.
00017  *
00018  * Redistribution and use in source and binary forms are permitted
00019  * provided that this notice is preserved and that due credit is given
00020  * to the University of Michigan at Ann Arbor. The name of the University
00021  * may not be used to endorse or promote products derived from this
00022  * software without specific prior written permission. This software
00023  * is provided ``as is'' without express or implied warranty.
00024  */
00025 
00026 #include "portable.h"
00027 
00028 #include <stdio.h>
00029 #include <ac/string.h>
00030 #include <ac/time.h>
00031 #include <ac/socket.h>
00032 
00033 #include "lutil.h"
00034 #include "slap.h"
00035 
00036 int
00037 do_add( Operation *op, SlapReply *rs )
00038 {
00039        BerElement    *ber = op->o_ber;
00040        char          *last;
00041        struct berval dn = BER_BVNULL;
00042        ber_len_t     len;
00043        ber_tag_t     tag;
00044        Modifications *modlist = NULL;
00045        Modifications **modtail = &modlist;
00046        Modifications tmp;
00047        char          textbuf[ SLAP_TEXT_BUFLEN ];
00048        size_t        textlen = sizeof( textbuf );
00049        int           rc = 0;
00050        int           freevals = 1;
00051        OpExtraDB oex;
00052 
00053        Debug( LDAP_DEBUG_TRACE, "%s do_add\n",
00054               op->o_log_prefix, 0, 0 );
00055 
00056        /*
00057         * Parse the add request.  It looks like this:
00058         *
00059         *     AddRequest := [APPLICATION 14] SEQUENCE {
00060         *            name   DistinguishedName,
00061         *            attrs  SEQUENCE OF SEQUENCE {
00062         *                   type   AttributeType,
00063         *                   values SET OF AttributeValue
00064         *            }
00065         *     }
00066         */
00067 
00068        /* get the name */
00069        if ( ber_scanf( ber, "{m", /*}*/ &dn ) == LBER_ERROR ) {
00070               Debug( LDAP_DEBUG_ANY, "%s do_add: ber_scanf failed\n",
00071                      op->o_log_prefix, 0, 0 );
00072               send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
00073               return SLAPD_DISCONNECT;
00074        }
00075 
00076        Debug( LDAP_DEBUG_ARGS, "%s do_add: dn (%s)\n",
00077               op->o_log_prefix, dn.bv_val, 0 );
00078 
00079        /* get the attrs */
00080        for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
00081            tag = ber_next_element( ber, &len, last ) )
00082        {
00083               Modifications *mod;
00084               ber_tag_t rtag;
00085 
00086               tmp.sml_nvalues = NULL;
00087 
00088               rtag = ber_scanf( ber, "{m{W}}", &tmp.sml_type, &tmp.sml_values );
00089 
00090               if ( rtag == LBER_ERROR ) {
00091                      Debug( LDAP_DEBUG_ANY, "%s do_add: decoding error\n",
00092                             op->o_log_prefix, 0, 0 );
00093                      send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
00094                      rs->sr_err = SLAPD_DISCONNECT;
00095                      goto done;
00096               }
00097 
00098               if ( tmp.sml_values == NULL ) {
00099                      Debug( LDAP_DEBUG_ANY, "%s do_add: no values for type %s\n",
00100                             op->o_log_prefix, tmp.sml_type.bv_val, 0 );
00101                      send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR,
00102                             "no values for attribute type" );
00103                      goto done;
00104               }
00105 
00106               mod  = (Modifications *) ch_malloc( sizeof(Modifications) );
00107               mod->sml_op = LDAP_MOD_ADD;
00108               mod->sml_flags = 0;
00109               mod->sml_next = NULL;
00110               mod->sml_desc = NULL;
00111               mod->sml_type = tmp.sml_type;
00112               mod->sml_values = tmp.sml_values;
00113               mod->sml_nvalues = NULL;
00114 
00115               *modtail = mod;
00116               modtail = &mod->sml_next;
00117        }
00118 
00119        if ( ber_scanf( ber, /*{*/ "}") == LBER_ERROR ) {
00120               Debug( LDAP_DEBUG_ANY, "%s do_add: ber_scanf failed\n",
00121                      op->o_log_prefix, 0, 0 );
00122               send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
00123               rs->sr_err = SLAPD_DISCONNECT;
00124               goto done;
00125        }
00126 
00127        if ( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
00128               Debug( LDAP_DEBUG_ANY, "%s do_add: get_ctrls failed\n",
00129                      op->o_log_prefix, 0, 0 );
00130               goto done;
00131        } 
00132 
00133        rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn,
00134               op->o_tmpmemctx );
00135 
00136        if ( rs->sr_err != LDAP_SUCCESS ) {
00137               Debug( LDAP_DEBUG_ANY, "%s do_add: invalid dn (%s)\n",
00138                      op->o_log_prefix, dn.bv_val, 0 );
00139               send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
00140               goto done;
00141        }
00142 
00143        op->ora_e = entry_alloc();
00144        ber_dupbv( &op->ora_e->e_name, &op->o_req_dn );
00145        ber_dupbv( &op->ora_e->e_nname, &op->o_req_ndn );
00146 
00147        Statslog( LDAP_DEBUG_STATS, "%s ADD dn=\"%s\"\n",
00148            op->o_log_prefix, op->o_req_dn.bv_val, 0, 0, 0 );
00149 
00150        if ( modlist == NULL ) {
00151               send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR,
00152                      "no attributes provided" );
00153               goto done;
00154        }
00155 
00156        if ( dn_match( &op->ora_e->e_nname, &slap_empty_bv ) ) {
00157               /* protocolError may be a more appropriate error */
00158               send_ldap_error( op, rs, LDAP_ALREADY_EXISTS,
00159                      "root DSE already exists" );
00160               goto done;
00161 
00162        } else if ( dn_match( &op->ora_e->e_nname, &frontendDB->be_schemandn ) ) {
00163               send_ldap_error( op, rs, LDAP_ALREADY_EXISTS,
00164                      "subschema subentry already exists" );
00165               goto done;
00166        }
00167 
00168        rs->sr_err = slap_mods_check( op, modlist, &rs->sr_text,
00169               textbuf, textlen, NULL );
00170 
00171        if ( rs->sr_err != LDAP_SUCCESS ) {
00172               send_ldap_result( op, rs );
00173               goto done;
00174        }
00175 
00176        /* temporary; remove if not invoking backend function */
00177        op->ora_modlist = modlist;
00178 
00179        /* call this so global overlays/SLAPI have access to ora_e */
00180        rs->sr_err = slap_mods2entry( op->ora_modlist, &op->ora_e,
00181               1, 0, &rs->sr_text, textbuf, textlen );
00182        if ( rs->sr_err != LDAP_SUCCESS ) {
00183               send_ldap_result( op, rs );
00184               goto done;
00185        }
00186 
00187        freevals = 0;
00188 
00189        oex.oe.oe_key = (void *)do_add;
00190        oex.oe_db = NULL;
00191        LDAP_SLIST_INSERT_HEAD(&op->o_extra, &oex.oe, oe_next);
00192 
00193        op->o_bd = frontendDB;
00194        rc = frontendDB->be_add( op, rs );
00195        LDAP_SLIST_REMOVE(&op->o_extra, &oex.oe, OpExtra, oe_next);
00196 
00197 #ifdef LDAP_X_TXN
00198        if ( rc == LDAP_X_TXN_SPECIFY_OKAY ) {
00199               /* skip cleanup */
00200               return rc;
00201        } else
00202 #endif
00203        if ( rc == 0 ) {
00204               if ( op->ora_e != NULL && oex.oe_db != NULL ) {
00205                      BackendDB     *bd = op->o_bd;
00206 
00207                      op->o_bd = oex.oe_db;
00208 
00209                      be_entry_release_w( op, op->ora_e );
00210 
00211                      op->ora_e = NULL;
00212                      op->o_bd = bd;
00213               }
00214        }
00215 
00216 done:;
00217        if ( modlist != NULL ) {
00218               /* in case of error, free the values as well */
00219               slap_mods_free( modlist, freevals );
00220        }
00221 
00222        if ( op->ora_e != NULL ) {
00223               entry_free( op->ora_e );
00224        }
00225        op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
00226        op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
00227 
00228        return rc;
00229 }
00230 
00231 int
00232 fe_op_add( Operation *op, SlapReply *rs )
00233 {
00234        Modifications **modtail = &op->ora_modlist;
00235        int           rc = 0;
00236        BackendDB     *op_be, *bd = op->o_bd;
00237        char          textbuf[ SLAP_TEXT_BUFLEN ];
00238        size_t        textlen = sizeof( textbuf );
00239 
00240        /*
00241         * We could be serving multiple database backends.  Select the
00242         * appropriate one, or send a referral to our "referral server"
00243         * if we don't hold it.
00244         */
00245        op->o_bd = select_backend( &op->ora_e->e_nname, 1 );
00246        if ( op->o_bd == NULL ) {
00247               op->o_bd = bd;
00248               rs->sr_ref = referral_rewrite( default_referral,
00249                      NULL, &op->ora_e->e_name, LDAP_SCOPE_DEFAULT );
00250               if ( !rs->sr_ref ) rs->sr_ref = default_referral;
00251               if ( rs->sr_ref ) {
00252                      rs->sr_err = LDAP_REFERRAL;
00253                      send_ldap_result( op, rs );
00254 
00255                      if ( rs->sr_ref != default_referral ) {
00256                             ber_bvarray_free( rs->sr_ref );
00257                      }
00258               } else {
00259                      send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
00260                             "no global superior knowledge" );
00261               }
00262               goto done;
00263        }
00264 
00265        /* If we've got a glued backend, check the real backend */
00266        op_be = op->o_bd;
00267        if ( SLAP_GLUE_INSTANCE( op->o_bd )) {
00268               op->o_bd = select_backend( &op->ora_e->e_nname, 0 );
00269        }
00270 
00271        /* check restrictions */
00272        if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) {
00273               send_ldap_result( op, rs );
00274               goto done;
00275        }
00276 
00277        /* check for referrals */
00278        if( backend_check_referrals( op, rs ) != LDAP_SUCCESS ) {
00279               goto done;
00280        }
00281 
00282        rs->sr_err = slap_mods_obsolete_check( op, op->ora_modlist,
00283               &rs->sr_text, textbuf, textlen );
00284 
00285        if ( rs->sr_err != LDAP_SUCCESS ) {
00286               send_ldap_result( op, rs );
00287               goto done;
00288        }
00289 
00290        /*
00291         * do the add if 1 && (2 || 3)
00292         * 1) there is an add function implemented in this backend;
00293         * 2) this backend is master for what it holds;
00294         * 3) it's a replica and the dn supplied is the updatedn.
00295         */
00296        if ( op->o_bd->be_add ) {
00297               /* do the update here */
00298               int repl_user = be_isupdate( op );
00299               if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user ) {
00300                      int           update = !BER_BVISEMPTY( &op->o_bd->be_update_ndn );
00301 
00302                      op->o_bd = op_be;
00303 
00304                      if ( !update ) {
00305                             rs->sr_err = slap_mods_no_user_mod_check( op, op->ora_modlist,
00306                                    &rs->sr_text, textbuf, textlen );
00307 
00308                             if ( rs->sr_err != LDAP_SUCCESS ) {
00309                                    send_ldap_result( op, rs );
00310                                    goto done;
00311                             }
00312                      }
00313 
00314                      if ( !repl_user ) {
00315                             /* go to the last mod */
00316                             for ( modtail = &op->ora_modlist;
00317                                           *modtail != NULL;
00318                                           modtail = &(*modtail)->sml_next )
00319                             {
00320                                    assert( (*modtail)->sml_op == LDAP_MOD_ADD );
00321                                    assert( (*modtail)->sml_desc != NULL );
00322                             }
00323 
00324 
00325                             /* check for unmodifiable attributes */
00326                             rs->sr_err = slap_mods_no_repl_user_mod_check( op,
00327                                    op->ora_modlist, &rs->sr_text, textbuf, textlen );
00328                             if ( rs->sr_err != LDAP_SUCCESS ) {
00329                                    send_ldap_result( op, rs );
00330                                    goto done;
00331                             }
00332                      }
00333 
00334                      rc = op->o_bd->be_add( op, rs );
00335                      if ( rc == LDAP_SUCCESS ) {
00336                             OpExtra *oex;
00337                             /* NOTE: be_entry_release_w() is
00338                              * called by do_add(), so that global
00339                              * overlays on the way back can
00340                              * at least read the entry */
00341                             LDAP_SLIST_FOREACH(oex, &op->o_extra, oe_next) {
00342                                    if ( oex->oe_key == (void *)do_add ) {
00343                                           ((OpExtraDB *)oex)->oe_db = op->o_bd;
00344                                           break;
00345                                    }
00346                             }
00347                      }
00348 
00349               } else {
00350                      BerVarray defref = NULL;
00351 
00352                      defref = op->o_bd->be_update_refs
00353                             ? op->o_bd->be_update_refs : default_referral;
00354 
00355                      if ( defref != NULL ) {
00356                             rs->sr_ref = referral_rewrite( defref,
00357                                    NULL, &op->ora_e->e_name, LDAP_SCOPE_DEFAULT );
00358                             if ( rs->sr_ref == NULL ) rs->sr_ref = defref;
00359                             rs->sr_err = LDAP_REFERRAL;
00360                             if (!rs->sr_ref) rs->sr_ref = default_referral;
00361                             send_ldap_result( op, rs );
00362 
00363                             if ( rs->sr_ref != default_referral ) {
00364                                    ber_bvarray_free( rs->sr_ref );
00365                             }
00366                      } else {
00367                             send_ldap_error( op, rs,
00368                                    LDAP_UNWILLING_TO_PERFORM,
00369                                    "shadow context; no update referral" );
00370                      }
00371               }
00372        } else {
00373               Debug( LDAP_DEBUG_ARGS, "do_add: no backend support\n", 0, 0, 0 );
00374               send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
00375                      "operation not supported within namingContext" );
00376        }
00377 
00378 done:;
00379        op->o_bd = bd;
00380        return rc;
00381 }
00382 
00383 int
00384 slap_mods2entry(
00385        Modifications *mods,
00386        Entry **e,
00387        int initial,
00388        int dup,
00389        const char **text,
00390        char *textbuf, size_t textlen )
00391 {
00392        Attribute **tail;
00393        int i;
00394 
00395        if ( initial ) {
00396               assert( (*e)->e_attrs == NULL );
00397        }
00398 
00399        for ( tail = &(*e)->e_attrs; *tail != NULL; tail = &(*tail)->a_next )
00400               ;
00401 
00402        *text = textbuf;
00403 
00404        for( ; mods != NULL; mods = mods->sml_next ) {
00405               Attribute *attr;
00406 
00407               assert( mods->sml_desc != NULL );
00408 
00409               attr = attr_find( (*e)->e_attrs, mods->sml_desc );
00410 
00411               if( attr != NULL ) {
00412 #define SLURPD_FRIENDLY
00413 #ifdef SLURPD_FRIENDLY
00414                      int j;
00415 
00416                      if ( !initial ) {
00417                             /*     
00418                              * This check allows overlays to override operational
00419                              * attributes by setting them directly in the entry.
00420                              * We assume slap_mods_no_user_mod_check() was called
00421                              * with the user modifications.
00422                              */
00423                             *text = NULL;
00424                             return LDAP_SUCCESS;
00425                      }
00426 
00427                      i = attr->a_numvals;
00428                      j = mods->sml_numvals;
00429                      attr->a_numvals += j;
00430                      j++;   /* NULL */
00431                      
00432                      attr->a_vals = ch_realloc( attr->a_vals,
00433                             sizeof( struct berval ) * (i+j) );
00434 
00435                      /* checked for duplicates in slap_mods_check */
00436 
00437                      if ( dup ) {
00438                             for ( j = 0; mods->sml_values[j].bv_val; j++ ) {
00439                                    ber_dupbv( &attr->a_vals[i+j], &mods->sml_values[j] );
00440                             }
00441                             BER_BVZERO( &attr->a_vals[i+j] );
00442                             j++;
00443                      } else {
00444                             AC_MEMCPY( &attr->a_vals[i], mods->sml_values,
00445                                    sizeof( struct berval ) * j );
00446                      }
00447 
00448                      if( mods->sml_nvalues ) {
00449                             attr->a_nvals = ch_realloc( attr->a_nvals,
00450                                    sizeof( struct berval ) * (i+j) );
00451                             if ( dup ) {
00452                                    for ( j = 0; mods->sml_nvalues[j].bv_val; j++ ) {
00453                                           ber_dupbv( &attr->a_nvals[i+j], &mods->sml_nvalues[j] );
00454                                    }
00455                                    BER_BVZERO( &attr->a_nvals[i+j] ); 
00456                             } else {
00457                                    AC_MEMCPY( &attr->a_nvals[i], mods->sml_nvalues,
00458                                           sizeof( struct berval ) * j );
00459                             }
00460                      } else {
00461                             attr->a_nvals = attr->a_vals;
00462                      }
00463 
00464                      continue;
00465 #else
00466                      snprintf( textbuf, textlen,
00467                             "attribute '%s' provided more than once",
00468                             mods->sml_desc->ad_cname.bv_val );
00469                      *text = textbuf;
00470                      return LDAP_TYPE_OR_VALUE_EXISTS;
00471 #endif
00472               }
00473 
00474               attr = attr_alloc( mods->sml_desc );
00475 
00476               /* move values to attr structure */
00477               i = mods->sml_numvals;
00478               attr->a_numvals = mods->sml_numvals;
00479               if ( dup ) { 
00480                      attr->a_vals = (BerVarray) ch_calloc( i+1, sizeof( BerValue ));
00481                      for ( i = 0; mods->sml_values[i].bv_val; i++ ) {
00482                             ber_dupbv( &attr->a_vals[i], &mods->sml_values[i] );
00483                      }
00484                      BER_BVZERO( &attr->a_vals[i] );
00485               } else {
00486                      attr->a_vals = mods->sml_values;
00487               }
00488 
00489               if ( mods->sml_nvalues ) {
00490                      if ( dup ) {
00491                             i = mods->sml_numvals;
00492                             attr->a_nvals = (BerVarray) ch_calloc( i+1, sizeof( BerValue ));
00493                             for ( i = 0; mods->sml_nvalues[i].bv_val; i++ ) {
00494                                    ber_dupbv( &attr->a_nvals[i], &mods->sml_nvalues[i] );
00495                             }
00496                             BER_BVZERO( &attr->a_nvals[i] );
00497                      } else {
00498                             attr->a_nvals = mods->sml_nvalues;
00499                      }
00500               } else {
00501                      attr->a_nvals = attr->a_vals;
00502               }
00503 
00504               *tail = attr;
00505               tail = &attr->a_next;
00506        }
00507 
00508        *text = NULL;
00509 
00510        return LDAP_SUCCESS;
00511 }
00512 
00513 int
00514 slap_entry2mods(
00515        Entry *e,
00516        Modifications **mods,
00517        const char **text,
00518        char *textbuf, size_t textlen )
00519 {
00520        Modifications *modhead = NULL;
00521        Modifications *mod;
00522        Modifications **modtail = &modhead;
00523        Attribute            *a_new;
00524        AttributeDescription *a_new_desc;
00525        int                         i, count;
00526 
00527        a_new = e->e_attrs;
00528 
00529        while ( a_new != NULL ) {
00530               a_new_desc = a_new->a_desc;
00531               mod = (Modifications *) ch_malloc( sizeof( Modifications ));
00532               
00533               mod->sml_op = LDAP_MOD_REPLACE;
00534               mod->sml_flags = 0;
00535 
00536               mod->sml_type = a_new_desc->ad_cname;
00537 
00538               count = a_new->a_numvals;
00539               mod->sml_numvals = a_new->a_numvals;
00540 
00541               mod->sml_values = (struct berval*) ch_malloc(
00542                      (count+1) * sizeof( struct berval) );
00543 
00544               /* see slap_mods_check() comments...
00545                * if a_vals == a_nvals, there is no normalizer.
00546                * in this case, mod->sml_nvalues must be left NULL.
00547                */
00548               if ( a_new->a_vals != a_new->a_nvals ) {
00549                      mod->sml_nvalues = (struct berval*) ch_malloc(
00550                             (count+1) * sizeof( struct berval) );
00551               } else {
00552                      mod->sml_nvalues = NULL;
00553               }
00554 
00555               for ( i = 0; i < count; i++ ) {
00556                      ber_dupbv(mod->sml_values+i, a_new->a_vals+i); 
00557                      if ( mod->sml_nvalues ) {
00558                             ber_dupbv( mod->sml_nvalues+i, a_new->a_nvals+i ); 
00559                      } 
00560               }
00561 
00562               mod->sml_values[count].bv_val = NULL; 
00563               mod->sml_values[count].bv_len = 0; 
00564 
00565               if ( mod->sml_nvalues ) {
00566                      mod->sml_nvalues[count].bv_val = NULL; 
00567                      mod->sml_nvalues[count].bv_len = 0; 
00568               }
00569 
00570               mod->sml_desc = a_new_desc;
00571               mod->sml_next =NULL;
00572               *modtail = mod;
00573               modtail = &mod->sml_next;
00574               a_new = a_new->a_next; 
00575        }
00576 
00577        *mods = modhead;
00578 
00579        return LDAP_SUCCESS;
00580 }
00581 
00582 int slap_add_opattrs(
00583        Operation *op,
00584        const char **text,
00585        char *textbuf,
00586        size_t textlen,
00587        int manage_ctxcsn )
00588 {
00589        struct berval name, timestamp, csn = BER_BVNULL;
00590        struct berval nname, tmp;
00591        char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
00592        char csnbuf[ LDAP_PVT_CSNSTR_BUFSIZE ];
00593        Attribute *a;
00594 
00595        if ( SLAP_LASTMOD( op->o_bd ) ) {
00596               char *ptr;
00597               int gotcsn = 0;
00598 
00599               timestamp.bv_val = timebuf;
00600               a = attr_find( op->ora_e->e_attrs, slap_schema.si_ad_entryCSN );
00601               if ( a ) {
00602                      gotcsn = 1;
00603                      csn = a->a_vals[0];
00604               }
00605               if ( BER_BVISEMPTY( &op->o_csn )) {
00606                      if ( !gotcsn ) {
00607                             csn.bv_val = csnbuf;
00608                             csn.bv_len = sizeof(csnbuf);
00609                             slap_get_csn( op, &csn, manage_ctxcsn );
00610                      } else {
00611                             if ( manage_ctxcsn )
00612                                    slap_queue_csn( op, &csn );
00613                      }
00614               } else {
00615                      csn = op->o_csn;
00616               }
00617               ptr = ber_bvchr( &csn, '#' );
00618               if ( ptr ) {
00619                      timestamp.bv_len = STRLENOF("YYYYMMDDHHMMSSZ");
00620                      AC_MEMCPY( timebuf, csn.bv_val, timestamp.bv_len );
00621                      timebuf[timestamp.bv_len-1] = 'Z';
00622                      timebuf[timestamp.bv_len] = '\0';
00623               } else {
00624                      time_t now = slap_get_time();
00625 
00626                      timestamp.bv_len = sizeof(timebuf);
00627 
00628                      slap_timestamp( &now, &timestamp );
00629               }
00630 
00631               if ( BER_BVISEMPTY( &op->o_dn ) ) {
00632                      BER_BVSTR( &name, SLAPD_ANONYMOUS );
00633                      nname = name;
00634               } else {
00635                      name = op->o_dn;
00636                      nname = op->o_ndn;
00637               }
00638 
00639               a = attr_find( op->ora_e->e_attrs,
00640                      slap_schema.si_ad_entryUUID );
00641               if ( !a ) {
00642                      char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
00643 
00644                      tmp.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
00645                      tmp.bv_val = uuidbuf;
00646                      
00647                      attr_merge_normalize_one( op->ora_e,
00648                             slap_schema.si_ad_entryUUID, &tmp, op->o_tmpmemctx );
00649               }
00650 
00651               a = attr_find( op->ora_e->e_attrs,
00652                      slap_schema.si_ad_creatorsName );
00653               if ( !a ) {
00654                      attr_merge_one( op->ora_e,
00655                             slap_schema.si_ad_creatorsName, &name, &nname );
00656               }
00657 
00658               a = attr_find( op->ora_e->e_attrs,
00659                      slap_schema.si_ad_createTimestamp );
00660               if ( !a ) {
00661                      attr_merge_one( op->ora_e,
00662                             slap_schema.si_ad_createTimestamp, &timestamp, NULL );
00663               }
00664 
00665               if ( !gotcsn ) {
00666                      attr_merge_one( op->ora_e,
00667                             slap_schema.si_ad_entryCSN, &csn, NULL );
00668               }
00669 
00670               a = attr_find( op->ora_e->e_attrs,
00671                      slap_schema.si_ad_modifiersName );
00672               if ( !a ) {
00673                      attr_merge_one( op->ora_e,
00674                             slap_schema.si_ad_modifiersName, &name, &nname );
00675               }
00676 
00677               a = attr_find( op->ora_e->e_attrs,
00678                      slap_schema.si_ad_modifyTimestamp );
00679               if ( !a ) {
00680                      attr_merge_one( op->ora_e,
00681                             slap_schema.si_ad_modifyTimestamp, &timestamp, NULL );
00682               }
00683        }
00684 
00685        return LDAP_SUCCESS;
00686 }