]> git.sur5r.net Git - openldap/blob - tests/progs/slapd-modify.c
ITS#5177 from HEAD
[openldap] / tests / progs / slapd-modify.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2007 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
11  * A copy of this license is available in file LICENSE in the
12  * top-level directory of the distribution or, alternatively, at
13  * <http://www.OpenLDAP.org/license.html>.
14  */
15
16 #include "portable.h"
17
18 #include <stdio.h>
19
20 #include <ac/stdlib.h>
21
22 #include <ac/ctype.h>
23 #include <ac/param.h>
24 #include <ac/socket.h>
25 #include <ac/string.h>
26 #include <ac/unistd.h>
27 #include <ac/wait.h>
28
29 #define LDAP_DEPRECATED 1
30 #include <ldap.h>
31 #include <lutil.h>
32
33 #define LOOPS   100
34 #define RETRIES 0
35
36 static void
37 do_modify( char *uri, char *host, int port, char *manager, char *passwd,
38                 char *entry, char *attr, char *value, int maxloop,
39                 int maxretries, int delay, int friendly );
40
41
42 static void
43 usage( char *name )
44 {
45         fprintf( stderr,
46                 "usage: %s "
47                 "-H <uri> | ([-h <host>] -p <port>) "
48                 "-D <manager> "
49                 "-w <passwd> "
50                 "-e <entry> "
51                 "[-l <loops>] "
52                 "[-r <maxretries>] "
53                 "[-t <delay>] "
54                 "[-F]\n",
55                         name );
56         exit( EXIT_FAILURE );
57 }
58
59 int
60 main( int argc, char **argv )
61 {
62         int             i;
63         char            *uri = NULL;
64         char            *host = "localhost";
65         int             port = -1;
66         char            *manager = NULL;
67         char            *passwd = NULL;
68         char            *entry = NULL;
69         char            *ava = NULL;
70         char            *value = NULL;
71         int             loops = LOOPS;
72         int             retries = RETRIES;
73         int             delay = 0;
74         int             friendly = 0;
75
76         while ( (i = getopt( argc, argv, "FH:h:p:D:w:e:a:l:r:t:" )) != EOF ) {
77                 switch( i ) {
78                 case 'F':
79                         friendly++;
80                         break;
81
82                 case 'H':               /* the server uri */
83                         uri = strdup( optarg );
84                         break;
85
86                 case 'h':               /* the servers host */
87                         host = strdup( optarg );
88                         break;
89
90                 case 'p':               /* the servers port */
91                         if ( lutil_atoi( &port, optarg ) != 0 ) {
92                                 usage( argv[0] );
93                         }
94                         break;
95
96                 case 'D':               /* the servers manager */
97                         manager = strdup( optarg );
98                         break;
99
100                 case 'w':               /* the server managers password */
101                         passwd = strdup( optarg );
102                         break;
103
104                 case 'e':               /* entry to modify */
105                         entry = strdup( optarg );
106                         break;
107
108                 case 'a':
109                         ava = strdup( optarg );
110                         break;
111
112                 case 'l':               /* the number of loops */
113                         if ( lutil_atoi( &loops, optarg ) != 0 ) {
114                                 usage( argv[0] );
115                         }
116                         break;
117
118                 case 'r':               /* number of retries */
119                         if ( lutil_atoi( &retries, optarg ) != 0 ) {
120                                 usage( argv[0] );
121                         }
122                         break;
123
124                 case 't':               /* delay in seconds */
125                         if ( lutil_atoi( &delay, optarg ) != 0 ) {
126                                 usage( argv[0] );
127                         }
128                         break;
129
130                 default:
131                         usage( argv[0] );
132                         break;
133                 }
134         }
135
136         if (( entry == NULL ) || ( ava == NULL ) || ( port == -1 && uri == NULL ))
137                 usage( argv[0] );
138
139         if ( *entry == '\0' ) {
140
141                 fprintf( stderr, "%s: invalid EMPTY entry DN.\n",
142                                 argv[0] );
143                 exit( EXIT_FAILURE );
144
145         }
146         if ( *ava  == '\0' ) {
147                 fprintf( stderr, "%s: invalid EMPTY AVA.\n",
148                                 argv[0] );
149                 exit( EXIT_FAILURE );
150         }
151         
152         if ( !( value = strchr( ava, ':' ))) {
153                 fprintf( stderr, "%s: invalid AVA.\n",
154                                 argv[0] );
155                 exit( EXIT_FAILURE );
156         }
157         *value++ = '\0'; 
158         while ( *value && isspace( (unsigned char) *value ))
159                 value++;
160
161         do_modify( uri, host, port, manager, passwd, entry, ava, value,
162                         loops, retries, delay, friendly );
163         exit( EXIT_SUCCESS );
164 }
165
166
167 static void
168 do_modify( char *uri, char *host, int port, char *manager,
169         char *passwd, char *entry, char* attr, char* value,
170         int maxloop, int maxretries, int delay, int friendly )
171 {
172         LDAP    *ld = NULL;
173         int     i = 0, do_retry = maxretries;
174         pid_t   pid;
175         int     rc = LDAP_SUCCESS;
176
177         struct ldapmod mod;
178         struct ldapmod *mods[2];
179         char *values[2];
180
181         pid = getpid();
182         
183         values[0] = value;
184         values[1] = NULL;
185         mod.mod_op = LDAP_MOD_ADD;
186         mod.mod_type = attr;
187         mod.mod_values = values;
188         mods[0] = &mod;
189         mods[1] = NULL;
190
191 retry:;
192         if ( uri ) {
193                 ldap_initialize( &ld, uri );
194         } else {
195                 ld = ldap_init( host, port );
196         }
197         if ( ld == NULL ) {
198                 perror( "ldap_init" );
199                 exit( EXIT_FAILURE );
200         }
201
202         {
203                 int version = LDAP_VERSION3;
204                 (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
205                         &version ); 
206         }
207
208         if ( do_retry == maxretries ) {
209                 fprintf( stderr, "PID=%ld - Modify(%d): entry=\"%s\".\n",
210                         (long) pid, maxloop, entry );
211         }
212
213         rc = ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE );
214         if ( rc != LDAP_SUCCESS ) {
215                 ldap_perror( ld, "ldap_bind" );
216                 switch ( rc ) {
217                 case LDAP_BUSY:
218                 case LDAP_UNAVAILABLE:
219                         if ( do_retry > 0 ) {
220                                 do_retry--;
221                                 if ( delay > 0 ) {
222                                     sleep( delay );
223                                 }
224                                 goto retry;
225                         }
226                 /* fallthru */
227                 default:
228                         break;
229                 }
230                 exit( EXIT_FAILURE );
231         }
232
233         for ( ; i < maxloop; i++ ) {
234                 mod.mod_op = LDAP_MOD_ADD;
235                 rc = ldap_modify_s( ld, entry, mods );
236                 if ( rc != LDAP_SUCCESS ) {
237                         ldap_perror( ld, "ldap_modify" );
238                         switch ( rc ) {
239                         case LDAP_TYPE_OR_VALUE_EXISTS:
240                                 /* NOTE: this likely means
241                                  * the second modify failed
242                                  * during the previous round... */
243                                 if ( !friendly ) {
244                                         goto done;
245                                 }
246                                 break;
247
248                         case LDAP_BUSY:
249                         case LDAP_UNAVAILABLE:
250                                 if ( do_retry > 0 ) {
251                                         do_retry--;
252                                         goto retry;
253                                 }
254                                 /* fall thru */
255
256                         default:
257                                 goto done;
258                         }
259                 }
260                 
261                 mod.mod_op = LDAP_MOD_DELETE;
262                 rc = ldap_modify_s( ld, entry, mods );
263                 if ( rc != LDAP_SUCCESS ) {
264                         ldap_perror( ld, "ldap_modify" );
265                         switch ( rc ) {
266                         case LDAP_NO_SUCH_ATTRIBUTE:
267                                 /* NOTE: this likely means
268                                  * the first modify failed
269                                  * during the previous round... */
270                                 if ( !friendly ) {
271                                         goto done;
272                                 }
273                                 break;
274
275                         case LDAP_BUSY:
276                         case LDAP_UNAVAILABLE:
277                                 if ( do_retry > 0 ) {
278                                         do_retry--;
279                                         goto retry;
280                                 }
281                                 /* fall thru */
282
283                         default:
284                                 goto done;
285                         }
286                 }
287
288         }
289
290 done:;
291         fprintf( stderr, " PID=%ld - Modify done (%d).\n", (long) pid, rc );
292
293         ldap_unbind( ld );
294 }
295
296