]> git.sur5r.net Git - openldap/blob - servers/slapd/tools/slapadd.c
3c71859e832a8ac70eac77f6aa4f69d86ae12a4c
[openldap] / servers / slapd / tools / slapadd.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 #include "portable.h"
7
8 #include <stdio.h>
9
10 #include <ac/stdlib.h>
11
12 #include <ac/ctype.h>
13 #include <ac/string.h>
14 #include <ac/socket.h>
15 #include <ac/unistd.h>
16
17 #include <lber.h>
18 #include <ldif.h>
19
20 #include "slapcommon.h"
21
22 int
23 main( int argc, char **argv )
24 {
25         char            *buf = NULL;
26         int         lineno;
27         int         lmax;
28         int                     rc = EXIT_SUCCESS;
29
30         const char *text;
31         char textbuf[SLAP_TEXT_BUFLEN] = { '\0' };
32         size_t textlen = sizeof textbuf;
33
34         struct berval name, timestamp, csn;
35         char timebuf[22];
36         char csnbuf[64];
37
38 #ifdef NEW_LOGGING
39         lutil_log_initialize(argc, argv );
40 #endif
41         slap_tool_init( "slapadd", SLAPADD, argc, argv );
42
43         if( !be->be_entry_open ||
44                 !be->be_entry_close ||
45                 !be->be_entry_put )
46         {
47                 fprintf( stderr, "%s: database doesn't support necessary operations.\n",
48                         progname );
49                 exit( EXIT_FAILURE );
50         }
51
52         lmax = 0;
53         lineno = 0;
54
55         if( be->be_entry_open( be, 1 ) != 0 ) {
56                 fprintf( stderr, "%s: could not open database.\n",
57                         progname );
58                 exit( EXIT_FAILURE );
59         }
60
61         while( ldif_read_record( ldiffp, &lineno, &buf, &lmax ) ) {
62                 Entry *e = str2entry( buf );
63                 struct berval bvtext;
64
65                 bvtext.bv_len = textlen;
66                 bvtext.bv_val = textbuf;
67
68                 if( e == NULL ) {
69                         fprintf( stderr, "%s: could not parse entry (line=%d)\n",
70                                 progname, lineno );
71                         rc = EXIT_FAILURE;
72                         if( continuemode ) continue;
73                         break;
74                 }
75
76                 /* make sure the DN is not empty */
77                 if( !e->e_nname.bv_len ) {
78                         fprintf( stderr, "%s: empty dn=\"%s\" (line=%d)\n",
79                                 progname, e->e_dn, lineno );
80                         rc = EXIT_FAILURE;
81                         entry_free( e );
82                         if( continuemode ) continue;
83                         break;
84                 }
85
86                 /* check backend */
87                 if( select_backend( &e->e_nname, is_entry_referral(e), nosubordinates )
88                         != be )
89                 {
90                         fprintf( stderr, "%s: line %d: "
91                                 "database (%s) not configured to hold \"%s\"\n",
92                                 progname, lineno,
93                                 be ? be->be_suffix[0].bv_val : "<none>",
94                                 e->e_dn );
95                         fprintf( stderr, "%s: line %d: "
96                                 "database (%s) not configured to hold \"%s\"\n",
97                                 progname, lineno,
98                                 be ? be->be_nsuffix[0].bv_val : "<none>",
99                                 e->e_ndn );
100                         rc = EXIT_FAILURE;
101                         entry_free( e );
102                         if( continuemode ) continue;
103                         break;
104                 }
105
106                 {
107                         Attribute *sc = attr_find( e->e_attrs,
108                                 slap_schema.si_ad_structuralObjectClass );
109                         Attribute *oc = attr_find( e->e_attrs,
110                                 slap_schema.si_ad_objectClass );
111
112                         if( oc == NULL ) {
113                                 fprintf( stderr, "%s: dn=\"%s\" (line=%d): %s\n",
114                                         progname, e->e_dn, lineno,
115                                         "no objectClass attribute");
116                                 rc = EXIT_FAILURE;
117                                 entry_free( e );
118                                 if( continuemode ) continue;
119                                 break;
120                         }
121
122                         if( sc == NULL ) {
123                                 struct berval vals[2];
124
125                                 /* int ret = */ 
126                                         structural_class( oc->a_vals, vals,
127                                         NULL, &text, textbuf, textlen );
128
129                                 if( vals[0].bv_len == 0 ) {
130                                         fprintf( stderr, "%s: dn=\"%s\" (line=%d): %s\n",
131                                         progname, e->e_dn, lineno, text );
132                                         rc = EXIT_FAILURE;
133                                         entry_free( e );
134                                         if( continuemode ) continue;
135                                         break;
136                                 }
137
138                                 vals[1].bv_val = NULL;
139                                 attr_merge( e, slap_schema.si_ad_structuralObjectClass,
140                                         vals );
141                         }
142                 }
143
144                 if ( SLAP_LASTMOD(be) ) {
145                         struct tm *ltm;
146                         time_t now = slap_get_time();
147
148                         ltm = gmtime(&now);
149                         lutil_gentime( timebuf, sizeof(timebuf), ltm );
150
151                         csn.bv_len = lutil_csnstr( csnbuf, sizeof( csnbuf ), 0, 0 );
152                         csn.bv_val = csnbuf;
153
154                         timestamp.bv_val = timebuf;
155                         timestamp.bv_len = strlen(timebuf);
156
157                         if ( be->be_rootndn.bv_len == 0 ) {
158                                 name.bv_val = SLAPD_ANONYMOUS;
159                                 name.bv_len = sizeof(SLAPD_ANONYMOUS) - 1;
160                         } else {
161                                 name = be->be_rootndn;
162                         }
163                 }
164
165                 if( global_schemacheck ) {
166                         /* check schema */
167
168                         rc = entry_schema_check( be, e, NULL, &text, textbuf, textlen );
169
170                         if( rc != LDAP_SUCCESS ) {
171                                 fprintf( stderr, "%s: dn=\"%s\" (line=%d): %s\n",
172                                         progname, e->e_dn, lineno, text );
173                                 rc = EXIT_FAILURE;
174                                 entry_free( e );
175                                 if( continuemode ) continue;
176                                 break;
177                         }
178                 }
179
180                 if ( SLAP_LASTMOD(be) ) {
181                         char uuidbuf[40];
182                         struct berval vals[2];
183
184                         vals[0].bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
185                         vals[0].bv_val = uuidbuf;
186                         vals[1].bv_len = 0;
187                         vals[1].bv_val = NULL;
188                         attr_merge( e, slap_schema.si_ad_entryUUID, vals );
189
190                         ber_dupbv( &vals[0], &name );
191                         vals[1].bv_len = 0;
192                         vals[1].bv_val = NULL;
193                         attr_merge( e, slap_schema.si_ad_creatorsName, vals);
194
195                         ber_dupbv( &vals[0], &name );
196                         vals[1].bv_len = 0;
197                         vals[1].bv_val = NULL;
198                         attr_merge( e, slap_schema.si_ad_modifiersName, vals);
199
200                         ber_dupbv( &vals[0], &timestamp );
201                         vals[1].bv_len = 0;
202                         vals[1].bv_val = NULL;
203                         attr_merge( e, slap_schema.si_ad_createTimestamp, vals );
204
205                         ber_dupbv( &vals[0], &timestamp );
206                         vals[1].bv_len = 0;
207                         vals[1].bv_val = NULL;
208                         attr_merge( e, slap_schema.si_ad_modifyTimestamp, vals );
209
210                         ber_dupbv( &vals[0], &csn );
211                         vals[1].bv_len = 0;
212                         vals[1].bv_val = NULL;
213                         attr_merge( e, slap_schema.si_ad_entryCSN, vals );
214                 }
215
216                 if (!dryrun) {
217                         ID id = be->be_entry_put( be, e, &bvtext );
218                         if( id == NOID ) {
219                                 fprintf( stderr, "%s: could not add entry dn=\"%s\" (line=%d): %s\n",
220                                         progname, e->e_dn, lineno, bvtext.bv_val );
221                                 rc = EXIT_FAILURE;
222                                 entry_free( e );
223                                 if( continuemode ) continue;
224                                 break;
225                         }
226                 
227                         if ( verbose ) {
228                                 fprintf( stderr, "added: \"%s\" (%08lx)\n",
229                                         e->e_dn, (long) id );
230                         }
231                 } else {
232                         if ( verbose ) {
233                                 fprintf( stderr, "(dry) added: \"%s\"\n", e->e_dn );
234                         }
235                 }
236
237                 entry_free( e );
238         }
239
240         ch_free( buf );
241
242         be->be_entry_close( be );
243
244         if( be->be_sync ) {
245                 be->be_sync( be );
246         }
247
248         slap_tool_destroy();
249         return rc;
250 }