slapmodify.c revision 1.1 1 1.1 christos /* $NetBSD: slapmodify.c,v 1.1 2021/08/14 16:05:21 christos Exp $ */
2 1.1 christos
3 1.1 christos /* $OpenLDAP$ */
4 1.1 christos /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 1.1 christos *
6 1.1 christos * Copyright 1998-2021 The OpenLDAP Foundation.
7 1.1 christos * Portions Copyright 1998-2003 Kurt D. Zeilenga.
8 1.1 christos * Portions Copyright 2003 IBM Corporation.
9 1.1 christos * All rights reserved.
10 1.1 christos *
11 1.1 christos * Redistribution and use in source and binary forms, with or without
12 1.1 christos * modification, are permitted only as authorized by the OpenLDAP
13 1.1 christos * Public License.
14 1.1 christos *
15 1.1 christos * A copy of this license is available in file LICENSE in the
16 1.1 christos * top-level directory of the distribution or, alternatively, at
17 1.1 christos * <http://www.OpenLDAP.org/license.html>.
18 1.1 christos */
19 1.1 christos /* ACKNOWLEDGEMENTS:
20 1.1 christos * This work was initially developed by Pierangelo Masarati for inclusion
21 1.1 christos * in OpenLDAP Software.
22 1.1 christos */
23 1.1 christos
24 1.1 christos #include <sys/cdefs.h>
25 1.1 christos __RCSID("$NetBSD: slapmodify.c,v 1.1 2021/08/14 16:05:21 christos Exp $");
26 1.1 christos
27 1.1 christos #include "portable.h"
28 1.1 christos
29 1.1 christos #include <stdio.h>
30 1.1 christos
31 1.1 christos #include "ac/stdlib.h"
32 1.1 christos
33 1.1 christos #include "ac/ctype.h"
34 1.1 christos #include "ac/string.h"
35 1.1 christos #include "ac/socket.h"
36 1.1 christos #include "ac/unistd.h"
37 1.1 christos
38 1.1 christos #include "lber.h"
39 1.1 christos #include "ldif.h"
40 1.1 christos #include "lutil.h"
41 1.1 christos #include "lutil_meter.h"
42 1.1 christos #include <sys/stat.h>
43 1.1 christos
44 1.1 christos #include "slapcommon.h"
45 1.1 christos
46 1.1 christos extern int slap_DN_strict; /* dn.c */
47 1.1 christos
48 1.1 christos static char csnbuf[ LDAP_PVT_CSNSTR_BUFSIZE ];
49 1.1 christos
50 1.1 christos int
51 1.1 christos slapmodify( int argc, char **argv )
52 1.1 christos {
53 1.1 christos char *buf = NULL;
54 1.1 christos const char *text;
55 1.1 christos char textbuf[SLAP_TEXT_BUFLEN] = { '\0' };
56 1.1 christos size_t textlen = sizeof textbuf;
57 1.1 christos const char *progname = "slapmodify";
58 1.1 christos
59 1.1 christos struct berval csn;
60 1.1 christos unsigned long sid;
61 1.1 christos struct berval bvtext;
62 1.1 christos ID id;
63 1.1 christos OperationBuffer opbuf;
64 1.1 christos Operation *op;
65 1.1 christos
66 1.1 christos int checkvals, ldifrc;
67 1.1 christos unsigned long lineno, nextline;
68 1.1 christos int lmax;
69 1.1 christos int rc = EXIT_SUCCESS;
70 1.1 christos
71 1.1 christos int enable_meter = 0;
72 1.1 christos lutil_meter_t meter;
73 1.1 christos struct stat stat_buf;
74 1.1 christos
75 1.1 christos /* default "000" */
76 1.1 christos csnsid = 0;
77 1.1 christos
78 1.1 christos if ( isatty (2) ) enable_meter = 1;
79 1.1 christos slap_tool_init( progname, SLAPMODIFY, argc, argv );
80 1.1 christos
81 1.1 christos memset( &opbuf, 0, sizeof(opbuf) );
82 1.1 christos op = &opbuf.ob_op;
83 1.1 christos op->o_hdr = &opbuf.ob_hdr;
84 1.1 christos op->o_bd = be;
85 1.1 christos
86 1.1 christos if ( !be->be_entry_open ||
87 1.1 christos !be->be_entry_close ||
88 1.1 christos !be->be_entry_put ||
89 1.1 christos !be->be_dn2id_get ||
90 1.1 christos !be->be_entry_get ||
91 1.1 christos !be->be_entry_modify )
92 1.1 christos {
93 1.1 christos fprintf( stderr, "%s: database doesn't support necessary operations.\n",
94 1.1 christos progname );
95 1.1 christos if ( dryrun ) {
96 1.1 christos fprintf( stderr, "\t(dry) continuing...\n" );
97 1.1 christos
98 1.1 christos } else {
99 1.1 christos exit( EXIT_FAILURE );
100 1.1 christos }
101 1.1 christos }
102 1.1 christos
103 1.1 christos checkvals = (slapMode & SLAP_TOOL_QUICK) ? 0 : 1;
104 1.1 christos
105 1.1 christos lmax = 0;
106 1.1 christos nextline = 0;
107 1.1 christos
108 1.1 christos /* enforce schema checking unless not disabled and allow unknown
109 1.1 christos * attributes otherwise */
110 1.1 christos if ( (slapMode & SLAP_TOOL_NO_SCHEMA_CHECK) == 0) {
111 1.1 christos SLAP_DBFLAGS(be) &= ~(SLAP_DBFLAG_NO_SCHEMA_CHECK);
112 1.1 christos } else {
113 1.1 christos slap_DN_strict = 0;
114 1.1 christos }
115 1.1 christos
116 1.1 christos if( !dryrun && be->be_entry_open( be, 1 ) != 0 ) {
117 1.1 christos fprintf( stderr, "%s: could not open database.\n",
118 1.1 christos progname );
119 1.1 christos exit( EXIT_FAILURE );
120 1.1 christos }
121 1.1 christos
122 1.1 christos (void)slap_tool_update_ctxcsn_init();
123 1.1 christos
124 1.1 christos if ( enable_meter
125 1.1 christos #ifdef LDAP_DEBUG
126 1.1 christos /* tools default to "none" */
127 1.1 christos && slap_debug == LDAP_DEBUG_NONE
128 1.1 christos #endif
129 1.1 christos && !fstat ( fileno ( ldiffp->fp ), &stat_buf )
130 1.1 christos && S_ISREG(stat_buf.st_mode) ) {
131 1.1 christos enable_meter = !lutil_meter_open(
132 1.1 christos &meter,
133 1.1 christos &lutil_meter_text_display,
134 1.1 christos &lutil_meter_linear_estimator,
135 1.1 christos stat_buf.st_size);
136 1.1 christos } else {
137 1.1 christos enable_meter = 0;
138 1.1 christos }
139 1.1 christos
140 1.1 christos /* nextline is the line number of the end of the current entry */
141 1.1 christos for( lineno=1; ( ldifrc = ldif_read_record( ldiffp, &nextline, &buf, &lmax )) > 0;
142 1.1 christos lineno=nextline+1 )
143 1.1 christos {
144 1.1 christos BackendDB *bd;
145 1.1 christos Entry *e_orig = NULL, *e = NULL;
146 1.1 christos struct berval rbuf;
147 1.1 christos LDIFRecord lr;
148 1.1 christos struct berval ndn = BER_BVNULL;
149 1.1 christos int n;
150 1.1 christos int is_oc = 0;
151 1.1 christos int local_rc;
152 1.1 christos int mod_err = 0;
153 1.1 christos char *request = "(unknown)";
154 1.1 christos
155 1.1 christos ber_str2bv( buf, 0, 0, &rbuf );
156 1.1 christos
157 1.1 christos if ( lineno < jumpline )
158 1.1 christos continue;
159 1.1 christos
160 1.1 christos if ( enable_meter )
161 1.1 christos lutil_meter_update( &meter,
162 1.1 christos ftell( ldiffp->fp ),
163 1.1 christos 0);
164 1.1 christos
165 1.1 christos /*
166 1.1 christos * Initialize text buffer
167 1.1 christos */
168 1.1 christos bvtext.bv_len = textlen;
169 1.1 christos bvtext.bv_val = textbuf;
170 1.1 christos bvtext.bv_val[0] = '\0';
171 1.1 christos
172 1.1 christos local_rc = ldap_parse_ldif_record( &rbuf, lineno, &lr,
173 1.1 christos "slapmodify", LDIF_NO_CONTROLS );
174 1.1 christos
175 1.1 christos if ( local_rc != LDAP_SUCCESS ) {
176 1.1 christos fprintf( stderr, "%s: could not parse entry (line=%lu)\n",
177 1.1 christos progname, lineno );
178 1.1 christos rc = EXIT_FAILURE;
179 1.1 christos if( continuemode ) continue;
180 1.1 christos break;
181 1.1 christos }
182 1.1 christos
183 1.1 christos switch ( lr.lr_op ) {
184 1.1 christos case LDAP_REQ_ADD:
185 1.1 christos request = "add";
186 1.1 christos break;
187 1.1 christos
188 1.1 christos case LDAP_REQ_MODIFY:
189 1.1 christos request = "modify";
190 1.1 christos break;
191 1.1 christos
192 1.1 christos case LDAP_REQ_DELETE:
193 1.1 christos if ( be->be_entry_delete )
194 1.1 christos {
195 1.1 christos request = "delete";
196 1.1 christos break;
197 1.1 christos }
198 1.1 christos /* backend does not support delete, fallthru */
199 1.1 christos
200 1.1 christos case LDAP_REQ_MODRDN:
201 1.1 christos fprintf( stderr, "%s: request 0x%lx not supported (line=%lu)\n",
202 1.1 christos progname, (unsigned long)lr.lr_op, lineno );
203 1.1 christos rc = EXIT_FAILURE;
204 1.1 christos goto cleanup;
205 1.1 christos
206 1.1 christos default:
207 1.1 christos /* record skipped e.g. version: or comment or something we don't handle yet */
208 1.1 christos goto cleanup;
209 1.1 christos }
210 1.1 christos
211 1.1 christos local_rc = dnNormalize( 0, NULL, NULL, &lr.lr_dn, &ndn, NULL );
212 1.1 christos if ( local_rc != LDAP_SUCCESS ) {
213 1.1 christos fprintf( stderr, "%s: DN=\"%s\" normalization failed (line=%lu)\n",
214 1.1 christos progname, lr.lr_dn.bv_val, lineno );
215 1.1 christos rc = EXIT_FAILURE;
216 1.1 christos goto cleanup;
217 1.1 christos }
218 1.1 christos
219 1.1 christos /* make sure the DN is not empty */
220 1.1 christos if( BER_BVISEMPTY( &ndn ) &&
221 1.1 christos !BER_BVISEMPTY( be->be_nsuffix ))
222 1.1 christos {
223 1.1 christos fprintf( stderr, "%s: line %lu: "
224 1.1 christos "%s entry with empty dn=\"\"",
225 1.1 christos progname, lineno, request );
226 1.1 christos bd = select_backend( &ndn, nosubordinates );
227 1.1 christos if ( bd ) {
228 1.1 christos BackendDB *bdtmp;
229 1.1 christos int dbidx = 0;
230 1.1 christos LDAP_STAILQ_FOREACH( bdtmp, &backendDB, be_next ) {
231 1.1 christos if ( bdtmp == bd ) break;
232 1.1 christos dbidx++;
233 1.1 christos }
234 1.1 christos
235 1.1 christos assert( bdtmp != NULL );
236 1.1 christos
237 1.1 christos fprintf( stderr, "; did you mean to use database #%d (%s)?",
238 1.1 christos dbidx,
239 1.1 christos bd->be_suffix[0].bv_val );
240 1.1 christos
241 1.1 christos }
242 1.1 christos fprintf( stderr, "\n" );
243 1.1 christos rc = EXIT_FAILURE;
244 1.1 christos goto cleanup;
245 1.1 christos }
246 1.1 christos
247 1.1 christos /* check backend */
248 1.1 christos bd = select_backend( &ndn, nosubordinates );
249 1.1 christos if ( bd != be ) {
250 1.1 christos fprintf( stderr, "%s: line %lu: "
251 1.1 christos "database #%d (%s) not configured to hold \"%s\"",
252 1.1 christos progname, lineno,
253 1.1 christos dbnum,
254 1.1 christos be->be_suffix[0].bv_val,
255 1.1 christos lr.lr_dn.bv_val );
256 1.1 christos if ( bd ) {
257 1.1 christos BackendDB *bdtmp;
258 1.1 christos int dbidx = 0;
259 1.1 christos LDAP_STAILQ_FOREACH( bdtmp, &backendDB, be_next ) {
260 1.1 christos if ( bdtmp == bd ) break;
261 1.1 christos dbidx++;
262 1.1 christos }
263 1.1 christos
264 1.1 christos assert( bdtmp != NULL );
265 1.1 christos
266 1.1 christos fprintf( stderr, "; did you mean to use database #%d (%s)?",
267 1.1 christos dbidx,
268 1.1 christos bd->be_suffix[0].bv_val );
269 1.1 christos
270 1.1 christos } else {
271 1.1 christos fprintf( stderr, "; no database configured for that naming context" );
272 1.1 christos }
273 1.1 christos fprintf( stderr, "\n" );
274 1.1 christos rc = EXIT_FAILURE;
275 1.1 christos goto cleanup;
276 1.1 christos }
277 1.1 christos
278 1.1 christos /* get id and/or entry */
279 1.1 christos switch ( lr.lr_op ) {
280 1.1 christos case LDAP_REQ_ADD:
281 1.1 christos e = entry_alloc();
282 1.1 christos ber_dupbv( &e->e_name, &lr.lr_dn );
283 1.1 christos ber_dupbv( &e->e_nname, &ndn );
284 1.1 christos break;
285 1.1 christos
286 1.1 christos //case LDAP_REQ_MODRDN:
287 1.1 christos case LDAP_REQ_DELETE:
288 1.1 christos case LDAP_REQ_MODIFY:
289 1.1 christos id = be->be_dn2id_get( be, &ndn );
290 1.1 christos rc = (id == NOID);
291 1.1 christos if ( rc == LDAP_SUCCESS && lr.lr_op != LDAP_REQ_DELETE ) {
292 1.1 christos e_orig = be->be_entry_get( be, id );
293 1.1 christos if ( e_orig )
294 1.1 christos e = entry_dup( e_orig );
295 1.1 christos rc = (e == NULL);
296 1.1 christos }
297 1.1 christos break;
298 1.1 christos }
299 1.1 christos
300 1.1 christos if ( rc != LDAP_SUCCESS ) {
301 1.1 christos fprintf( stderr, "%s: no such entry \"%s\" in database (lineno=%lu)\n",
302 1.1 christos progname, ndn.bv_val, lineno );
303 1.1 christos rc = EXIT_FAILURE;
304 1.1 christos goto cleanup;
305 1.1 christos }
306 1.1 christos
307 1.1 christos if ( lr.lrop_mods ) {
308 1.1 christos for ( n = 0; lr.lrop_mods && lr.lrop_mods[ n ] != NULL; n++ ) {
309 1.1 christos LDAPMod *mod = lr.lrop_mods[ n ];
310 1.1 christos Modification mods = { 0 };
311 1.1 christos unsigned i = 0;
312 1.1 christos int bin = (mod->mod_op & LDAP_MOD_BVALUES);
313 1.1 christos int pretty = 0;
314 1.1 christos int normalize = 0;
315 1.1 christos
316 1.1 christos local_rc = slap_str2ad( mod->mod_type, &mods.sm_desc, &text );
317 1.1 christos /*
318 1.1 christos * Usually this would be a bad idea (way too dangerous, risks
319 1.1 christos * corrupting the DB), but ITS#7786 documents this as a last
320 1.1 christos * resort to fix cn=config and missing attributes are one of
321 1.1 christos * the possible issues we might encounter.
322 1.1 christos */
323 1.1 christos if ( local_rc == LDAP_UNDEFINED_TYPE &&
324 1.1 christos (slapMode & SLAP_TOOL_NO_SCHEMA_CHECK) ) {
325 1.1 christos local_rc = slap_str2undef_ad( mod->mod_type, &mods.sm_desc, &text, 0 );
326 1.1 christos }
327 1.1 christos if ( local_rc != LDAP_SUCCESS ) {
328 1.1 christos fprintf( stderr, "%s: slap_str2ad(\"%s\") failed for entry \"%s\" (%d: %s, lineno=%lu)\n",
329 1.1 christos progname, mod->mod_type, lr.lr_dn.bv_val, local_rc, text, lineno );
330 1.1 christos rc = EXIT_FAILURE;
331 1.1 christos goto cleanup;
332 1.1 christos }
333 1.1 christos
334 1.1 christos mods.sm_type = mods.sm_desc->ad_cname;
335 1.1 christos
336 1.1 christos if ( mods.sm_desc->ad_type->sat_syntax->ssyn_pretty ) {
337 1.1 christos pretty = 1;
338 1.1 christos
339 1.1 christos } else {
340 1.1 christos assert( mods.sm_desc->ad_type->sat_syntax->ssyn_validate != NULL );
341 1.1 christos }
342 1.1 christos
343 1.1 christos if ( mods.sm_desc->ad_type->sat_equality &&
344 1.1 christos mods.sm_desc->ad_type->sat_equality->smr_normalize )
345 1.1 christos {
346 1.1 christos normalize = 1;
347 1.1 christos }
348 1.1 christos
349 1.1 christos if ( bin && mod->mod_bvalues ) {
350 1.1 christos for ( i = 0; mod->mod_bvalues[ i ] != NULL; i++ )
351 1.1 christos ;
352 1.1 christos
353 1.1 christos } else if ( !bin && mod->mod_values ) {
354 1.1 christos for ( i = 0; mod->mod_values[ i ] != NULL; i++ )
355 1.1 christos ;
356 1.1 christos }
357 1.1 christos
358 1.1 christos if ( i != 0 )
359 1.1 christos {
360 1.1 christos mods.sm_values = ch_calloc( sizeof( struct berval ), i + 1 );
361 1.1 christos if ( normalize ) {
362 1.1 christos mods.sm_nvalues = ch_calloc( sizeof( struct berval ), i + 1 );
363 1.1 christos } else {
364 1.1 christos mods.sm_nvalues = NULL;
365 1.1 christos }
366 1.1 christos }
367 1.1 christos mods.sm_numvals = i;
368 1.1 christos
369 1.1 christos for ( i = 0; i < mods.sm_numvals; i++ ) {
370 1.1 christos struct berval bv;
371 1.1 christos
372 1.1 christos if ( bin ) {
373 1.1 christos bv = *mod->mod_bvalues[ i ];
374 1.1 christos } else {
375 1.1 christos ber_str2bv( mod->mod_values[ i ], 0, 0, &bv );
376 1.1 christos }
377 1.1 christos
378 1.1 christos if ( pretty ) {
379 1.1 christos local_rc = ordered_value_pretty( mods.sm_desc,
380 1.1 christos &bv, &mods.sm_values[i], NULL );
381 1.1 christos
382 1.1 christos } else {
383 1.1 christos local_rc = ordered_value_validate( mods.sm_desc,
384 1.1 christos &bv, 0 );
385 1.1 christos }
386 1.1 christos
387 1.1 christos if ( local_rc != LDAP_SUCCESS ) {
388 1.1 christos fprintf( stderr, "%s: DN=\"%s\": unable to %s attr=%s value #%d\n",
389 1.1 christos progname, e->e_dn, pretty ? "prettify" : "validate",
390 1.1 christos mods.sm_desc->ad_cname.bv_val, i );
391 1.1 christos /* handle error */
392 1.1 christos rc = EXIT_FAILURE;
393 1.1 christos ber_bvarray_free( mods.sm_values );
394 1.1 christos ber_bvarray_free( mods.sm_nvalues );
395 1.1 christos goto cleanup;
396 1.1 christos }
397 1.1 christos
398 1.1 christos if ( !pretty ) {
399 1.1 christos ber_dupbv( &mods.sm_values[i], &bv );
400 1.1 christos }
401 1.1 christos
402 1.1 christos if ( normalize ) {
403 1.1 christos local_rc = ordered_value_normalize(
404 1.1 christos SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
405 1.1 christos mods.sm_desc,
406 1.1 christos mods.sm_desc->ad_type->sat_equality,
407 1.1 christos &mods.sm_values[i], &mods.sm_nvalues[i],
408 1.1 christos NULL );
409 1.1 christos if ( local_rc != LDAP_SUCCESS ) {
410 1.1 christos fprintf( stderr, "%s: DN=\"%s\": unable to normalize attr=%s value #%d\n",
411 1.1 christos progname, e->e_dn, mods.sm_desc->ad_cname.bv_val, i );
412 1.1 christos /* handle error */
413 1.1 christos rc = EXIT_FAILURE;
414 1.1 christos ber_bvarray_free( mods.sm_values );
415 1.1 christos ber_bvarray_free( mods.sm_nvalues );
416 1.1 christos goto cleanup;
417 1.1 christos }
418 1.1 christos }
419 1.1 christos }
420 1.1 christos
421 1.1 christos mods.sm_op = (mod->mod_op & ~LDAP_MOD_BVALUES);
422 1.1 christos mods.sm_flags = 0;
423 1.1 christos
424 1.1 christos if ( mods.sm_desc == slap_schema.si_ad_objectClass ) {
425 1.1 christos is_oc = 1;
426 1.1 christos }
427 1.1 christos
428 1.1 christos switch ( mods.sm_op ) {
429 1.1 christos case LDAP_MOD_ADD:
430 1.1 christos local_rc = modify_add_values( e, &mods,
431 1.1 christos 0, &text, textbuf, textlen );
432 1.1 christos break;
433 1.1 christos
434 1.1 christos case LDAP_MOD_DELETE:
435 1.1 christos local_rc = modify_delete_values( e, &mods,
436 1.1 christos 0, &text, textbuf, textlen );
437 1.1 christos break;
438 1.1 christos
439 1.1 christos case LDAP_MOD_REPLACE:
440 1.1 christos local_rc = modify_replace_values( e, &mods,
441 1.1 christos 0, &text, textbuf, textlen );
442 1.1 christos break;
443 1.1 christos
444 1.1 christos case LDAP_MOD_INCREMENT:
445 1.1 christos local_rc = modify_increment_values( e, &mods,
446 1.1 christos 0, &text, textbuf, textlen );
447 1.1 christos break;
448 1.1 christos }
449 1.1 christos
450 1.1 christos ber_bvarray_free( mods.sm_values );
451 1.1 christos ber_bvarray_free( mods.sm_nvalues );
452 1.1 christos
453 1.1 christos if ( local_rc != LDAP_SUCCESS ) {
454 1.1 christos fprintf( stderr, "%s: DN=\"%s\": unable to modify attr=%s\n",
455 1.1 christos progname, e->e_dn, mods.sm_desc->ad_cname.bv_val );
456 1.1 christos rc = EXIT_FAILURE;
457 1.1 christos goto cleanup;
458 1.1 christos }
459 1.1 christos }
460 1.1 christos
461 1.1 christos rc = slap_tool_entry_check( progname, op, e, lineno, &text, textbuf, textlen );
462 1.1 christos if ( rc != LDAP_SUCCESS ) {
463 1.1 christos rc = EXIT_FAILURE;
464 1.1 christos goto cleanup;
465 1.1 christos }
466 1.1 christos }
467 1.1 christos
468 1.1 christos if ( SLAP_LASTMOD(be) && e != NULL ) {
469 1.1 christos time_t now = slap_get_time();
470 1.1 christos char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
471 1.1 christos struct berval vals[ 2 ];
472 1.1 christos
473 1.1 christos struct berval name, timestamp;
474 1.1 christos
475 1.1 christos struct berval nvals[ 2 ];
476 1.1 christos struct berval nname;
477 1.1 christos char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
478 1.1 christos
479 1.1 christos Attribute *a;
480 1.1 christos
481 1.1 christos vals[1].bv_len = 0;
482 1.1 christos vals[1].bv_val = NULL;
483 1.1 christos
484 1.1 christos nvals[1].bv_len = 0;
485 1.1 christos nvals[1].bv_val = NULL;
486 1.1 christos
487 1.1 christos csn.bv_len = ldap_pvt_csnstr( csnbuf, sizeof( csnbuf ), csnsid, 0 );
488 1.1 christos csn.bv_val = csnbuf;
489 1.1 christos
490 1.1 christos timestamp.bv_val = timebuf;
491 1.1 christos timestamp.bv_len = sizeof(timebuf);
492 1.1 christos
493 1.1 christos slap_timestamp( &now, ×tamp );
494 1.1 christos
495 1.1 christos if ( BER_BVISEMPTY( &be->be_rootndn ) ) {
496 1.1 christos BER_BVSTR( &name, SLAPD_ANONYMOUS );
497 1.1 christos nname = name;
498 1.1 christos } else {
499 1.1 christos name = be->be_rootdn;
500 1.1 christos nname = be->be_rootndn;
501 1.1 christos }
502 1.1 christos
503 1.1 christos a = attr_find( e->e_attrs, slap_schema.si_ad_entryUUID );
504 1.1 christos if ( a != NULL ) {
505 1.1 christos if ( a->a_vals != a->a_nvals ) {
506 1.1 christos SLAP_FREE( a->a_nvals[0].bv_val );
507 1.1 christos SLAP_FREE( a->a_nvals );
508 1.1 christos }
509 1.1 christos SLAP_FREE( a->a_vals[0].bv_val );
510 1.1 christos SLAP_FREE( a->a_vals );
511 1.1 christos a->a_vals = NULL;
512 1.1 christos a->a_nvals = NULL;
513 1.1 christos a->a_numvals = 0;
514 1.1 christos }
515 1.1 christos vals[0].bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
516 1.1 christos vals[0].bv_val = uuidbuf;
517 1.1 christos attr_merge_normalize_one( e, slap_schema.si_ad_entryUUID, vals, NULL );
518 1.1 christos
519 1.1 christos a = attr_find( e->e_attrs, slap_schema.si_ad_creatorsName );
520 1.1 christos if ( a == NULL ) {
521 1.1 christos vals[0] = name;
522 1.1 christos nvals[0] = nname;
523 1.1 christos attr_merge( e, slap_schema.si_ad_creatorsName, vals, nvals );
524 1.1 christos
525 1.1 christos } else {
526 1.1 christos ber_bvreplace( &a->a_vals[0], &name );
527 1.1 christos ber_bvreplace( &a->a_nvals[0], &nname );
528 1.1 christos }
529 1.1 christos
530 1.1 christos a = attr_find( e->e_attrs, slap_schema.si_ad_createTimestamp );
531 1.1 christos if ( a == NULL ) {
532 1.1 christos vals[0] = timestamp;
533 1.1 christos attr_merge( e, slap_schema.si_ad_createTimestamp, vals, NULL );
534 1.1 christos
535 1.1 christos } else {
536 1.1 christos ber_bvreplace( &a->a_vals[0], ×tamp );
537 1.1 christos }
538 1.1 christos
539 1.1 christos a = attr_find( e->e_attrs, slap_schema.si_ad_entryCSN );
540 1.1 christos if ( a == NULL ) {
541 1.1 christos vals[0] = csn;
542 1.1 christos attr_merge( e, slap_schema.si_ad_entryCSN, vals, NULL );
543 1.1 christos
544 1.1 christos } else {
545 1.1 christos ber_bvreplace( &a->a_vals[0], &csn );
546 1.1 christos }
547 1.1 christos
548 1.1 christos a = attr_find( e->e_attrs, slap_schema.si_ad_modifiersName );
549 1.1 christos if ( a == NULL ) {
550 1.1 christos vals[0] = name;
551 1.1 christos nvals[0] = nname;
552 1.1 christos attr_merge( e, slap_schema.si_ad_modifiersName, vals, nvals );
553 1.1 christos
554 1.1 christos } else {
555 1.1 christos ber_bvreplace( &a->a_vals[0], &name );
556 1.1 christos ber_bvreplace( &a->a_nvals[0], &nname );
557 1.1 christos }
558 1.1 christos
559 1.1 christos a = attr_find( e->e_attrs, slap_schema.si_ad_modifyTimestamp );
560 1.1 christos if ( a == NULL ) {
561 1.1 christos vals[0] = timestamp;
562 1.1 christos attr_merge( e, slap_schema.si_ad_modifyTimestamp, vals, NULL );
563 1.1 christos
564 1.1 christos } else {
565 1.1 christos ber_bvreplace( &a->a_vals[0], ×tamp );
566 1.1 christos }
567 1.1 christos }
568 1.1 christos
569 1.1 christos /* check schema, objectClass etc */
570 1.1 christos
571 1.1 christos if ( !dryrun ) {
572 1.1 christos switch ( lr.lr_op ) {
573 1.1 christos case LDAP_REQ_ADD:
574 1.1 christos id = be->be_entry_put( be, e, &bvtext );
575 1.1 christos rc = (id == NOID);
576 1.1 christos break;
577 1.1 christos
578 1.1 christos case LDAP_REQ_MODIFY:
579 1.1 christos id = be->be_entry_modify( be, e, &bvtext );
580 1.1 christos rc = (id == NOID);
581 1.1 christos break;
582 1.1 christos
583 1.1 christos case LDAP_REQ_DELETE:
584 1.1 christos rc = be->be_entry_delete( be, &ndn, &bvtext );
585 1.1 christos break;
586 1.1 christos
587 1.1 christos }
588 1.1 christos
589 1.1 christos if( rc != LDAP_SUCCESS ) {
590 1.1 christos fprintf( stderr, "%s: could not %s entry dn=\"%s\" "
591 1.1 christos "(line=%lu): %s\n", progname, request, ndn.bv_val,
592 1.1 christos lineno, bvtext.bv_val );
593 1.1 christos rc = EXIT_FAILURE;
594 1.1 christos goto cleanup;
595 1.1 christos }
596 1.1 christos
597 1.1 christos sid = slap_tool_update_ctxcsn_check( progname, e );
598 1.1 christos
599 1.1 christos if ( verbose )
600 1.1 christos fprintf( stderr, "%s: \"%s\" (%08lx)\n",
601 1.1 christos request, ndn.bv_val, (long) id );
602 1.1 christos } else {
603 1.1 christos if ( verbose )
604 1.1 christos fprintf( stderr, "%s: \"%s\"\n",
605 1.1 christos request, ndn.bv_val );
606 1.1 christos }
607 1.1 christos
608 1.1 christos cleanup:;
609 1.1 christos ldap_ldif_record_done( &lr );
610 1.1 christos SLAP_FREE( ndn.bv_val );
611 1.1 christos if ( e ) entry_free( e );
612 1.1 christos if ( e_orig ) be_entry_release_w( op, e_orig );
613 1.1 christos if ( rc != LDAP_SUCCESS && !continuemode ) break;
614 1.1 christos }
615 1.1 christos
616 1.1 christos if ( ldifrc < 0 )
617 1.1 christos rc = EXIT_FAILURE;
618 1.1 christos
619 1.1 christos bvtext.bv_len = textlen;
620 1.1 christos bvtext.bv_val = textbuf;
621 1.1 christos bvtext.bv_val[0] = '\0';
622 1.1 christos
623 1.1 christos if ( enable_meter ) {
624 1.1 christos lutil_meter_update( &meter, ftell( ldiffp->fp ), 1);
625 1.1 christos lutil_meter_close( &meter );
626 1.1 christos }
627 1.1 christos
628 1.1 christos if ( rc == EXIT_SUCCESS ) {
629 1.1 christos rc = slap_tool_update_ctxcsn( progname, sid, &bvtext );
630 1.1 christos }
631 1.1 christos
632 1.1 christos ch_free( buf );
633 1.1 christos
634 1.1 christos if ( !dryrun ) {
635 1.1 christos if ( enable_meter ) {
636 1.1 christos fprintf( stderr, "Closing DB..." );
637 1.1 christos }
638 1.1 christos if( be->be_entry_close( be ) ) {
639 1.1 christos rc = EXIT_FAILURE;
640 1.1 christos }
641 1.1 christos
642 1.1 christos if( be->be_sync ) {
643 1.1 christos be->be_sync( be );
644 1.1 christos }
645 1.1 christos if ( enable_meter ) {
646 1.1 christos fprintf( stderr, "\n" );
647 1.1 christos }
648 1.1 christos }
649 1.1 christos
650 1.1 christos if ( slap_tool_destroy())
651 1.1 christos rc = EXIT_FAILURE;
652 1.1 christos
653 1.1 christos return rc;
654 1.1 christos }
655 1.1 christos
656