]> git.sur5r.net Git - openldap/blob - clients/tools/ldapexop.c
allow continuous mode
[openldap] / clients / tools / ldapexop.c
1 /* ldapexop.c -- a tool for performing well-known extended operations */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2005-2006 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /* ACKNOWLEDGEMENTS:
17  * This work was originally developed by Pierangelo Masarati for inclusion
18  * in OpenLDAP Software based, in part, on other client tools.
19  */
20
21 #include "portable.h"
22
23 #include <stdio.h>
24
25 #include <ac/stdlib.h>
26
27 #include <ac/ctype.h>
28 #include <ac/socket.h>
29 #include <ac/string.h>
30 #include <ac/time.h>
31 #include <ac/unistd.h>
32
33 #include <ldap.h>
34 #include "ldif.h"
35 #include "lutil.h"
36 #include "lutil_ldap.h"
37 #include "ldap_defaults.h"
38
39 #include "common.h"
40
41 void
42 usage( void )
43 {
44         fprintf( stderr, _("Issue LDAP extended operations\n\n"));
45         fprintf( stderr, _("usage: %s [options] <oid|oid:data|oid::b64data>\n"), prog);
46         tool_common_usage();
47         exit( EXIT_FAILURE );
48 }
49
50
51 const char options[] = ""
52         "d:D:e:h:H:InO:p:QR:U:vVw:WxX:y:Y:Z";
53
54 int
55 handle_private_option( int i )
56 {
57         switch ( i ) {
58         default:
59                 return 0;
60         }
61         return 1;
62 }
63
64
65 int
66 main( int argc, char *argv[] )
67 {
68         int             rc;
69         char            *user = NULL;
70
71         LDAP            *ld = NULL;
72
73         char            *matcheddn = NULL, *text = NULL, **refs = NULL;
74         int             id, code;
75         LDAPMessage     *res;
76
77         tool_init( TOOL_EXOP );
78         prog = lutil_progname( "ldapexop", argc, argv );
79
80         /* LDAPv3 only */
81         protocol = LDAP_VERSION3;
82
83         tool_args( argc, argv );
84
85         if ( argc - optind < 1 ) {
86                 usage();
87         }
88
89         if ( pw_file || want_bindpw ) {
90                 if ( pw_file ) {
91                         rc = lutil_get_filed_password( pw_file, &passwd );
92                         if( rc ) return EXIT_FAILURE;
93                 } else {
94                         passwd.bv_val = getpassphrase( _("Enter LDAP Password: ") );
95                         passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
96                 }
97         }
98
99         ld = tool_conn_setup( 0, 0 );
100
101         tool_bind( ld );
102
103         argv += optind;
104         argc -= optind;
105
106         if ( strcasecmp( argv[ 0 ], "whoami" ) == 0 ) {
107                 switch ( argc ) {
108                 case 2:
109                         user = argv[ 1 ];
110
111                 case 1:
112                         break;
113
114                 default:
115                         fprintf( stderr, "need [user]\n\n" );
116                         usage();
117                 }
118
119                 tool_server_controls( ld, NULL, 0 );
120
121                 rc = ldap_whoami( ld, NULL, NULL, &id ); 
122                 if ( rc != LDAP_SUCCESS ) {
123                         tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
124                         rc = EXIT_FAILURE;
125                         goto skip;
126                 }
127
128         } else if ( strcasecmp( argv[ 0 ], "cancel" ) == 0 ) {
129                 int             cancelid;
130
131                 switch ( argc ) {
132                 case 2:
133                          if ( lutil_atoi( &cancelid, argv[ 1 ] ) != 0 || cancelid < 0 ) {
134                                 fprintf( stderr, "invalid cancelid=%s\n\n", argv[ 1 ] );
135                                 usage();
136                         }
137                         break;
138
139                 default:
140                         fprintf( stderr, "need cancelid\n\n" );
141                         usage();
142                 }
143
144                 rc = ldap_cancel( ld, cancelid, NULL, NULL, &id );
145                 if ( rc != LDAP_SUCCESS ) {
146                         tool_perror( "ldap_cancel", rc, NULL, NULL, NULL, NULL );
147                         rc = EXIT_FAILURE;
148                         goto skip;
149                 }
150
151         } else if ( strcasecmp( argv[ 0 ], "passwd" ) == 0 ) {
152                 fprintf( stderr, "use ldappasswd(1) instead.\n\n", argv[ 0 ] );
153                 usage();
154                 /* TODO? */
155
156         } else if ( strcasecmp( argv[ 0 ], "refresh" ) == 0 ) {
157                 int             ttl = 3600;
158                 struct berval   dn;
159
160                 switch ( argc ) {
161                 case 3:
162                         ttl = atoi( argv[ 2 ] );
163
164                 case 2:
165                         dn.bv_val = argv[ 1 ];
166                         dn.bv_len = strlen( dn.bv_val );
167
168                 case 1:
169                         break;
170
171                 default:
172                         fprintf( stderr, _("need DN [ttl]\n\n") );
173                         usage();
174                 }
175                 
176                 tool_server_controls( ld, NULL, 0 );
177
178                 rc = ldap_refresh( ld, &dn, ttl, NULL, NULL, &id ); 
179                 if ( rc != LDAP_SUCCESS ) {
180                         tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
181                         rc = EXIT_FAILURE;
182                         goto skip;
183                 }
184
185         } else {
186                 char *p;
187
188                 if ( argc != 1 ) {
189                         usage();
190                 }
191
192                 p = strchr( argv[ 0 ], ':' );
193                 if ( p == argv[ 0 ] ) {
194                         usage();
195                 }
196
197                 if ( p != NULL )
198                         *p++ = '\0';
199
200                 if ( tool_is_oid( argv[ 0 ] ) ) {
201                         struct berval   reqdata;
202                         struct berval   type;
203                         struct berval   value;
204                         int             freeval;
205
206                         if ( p != NULL ) {
207                                 p[ -1 ] = ':';
208                                 ldif_parse_line2( argv[ 0 ], &type, &value, &freeval );
209                                 p[ -1 ] = '\0';
210
211                                 if ( freeval ) {
212                                         reqdata = value;
213                                 } else {
214                                         ber_dupbv( &reqdata, &value );
215                                 }
216                         }
217
218
219                         tool_server_controls( ld, NULL, 0 );
220
221                         rc = ldap_extended_operation( ld, argv[ 0 ], p ? &reqdata : NULL, NULL, NULL, &id );
222                         if ( rc != LDAP_SUCCESS ) {
223                                 tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
224                                 rc = EXIT_FAILURE;
225                                 goto skip;
226                         }
227                 } else {
228                         fprintf( stderr, "unknown exop \"%s\"\n\n", argv[ 0 ] );
229                         usage();
230                 }
231         }
232
233         for ( ; ; ) {
234                 struct timeval  tv;
235
236                 if ( tool_check_abandon( ld, id ) ) {
237                         return LDAP_CANCELLED;
238                 }
239
240                 tv.tv_sec = 0;
241                 tv.tv_usec = 100000;
242
243                 rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
244                 if ( rc < 0 ) {
245                         tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
246                         rc = EXIT_FAILURE;
247                         goto skip;
248                 }
249
250                 if ( rc != 0 ) {
251                         break;
252                 }
253         }
254
255         rc = ldap_parse_result( ld, res,
256                 &code, &matcheddn, &text, &refs, NULL, 0 );
257         if ( rc == LDAP_SUCCESS ) {
258                 rc = code;
259         }
260
261         if ( rc != LDAP_SUCCESS ) {
262                 tool_perror( "ldap_parse_result", rc, NULL, matcheddn, text, refs );
263                 rc = EXIT_FAILURE;
264                 goto skip;
265         }
266
267         if ( strcasecmp( argv[ 0 ], "whoami" ) == 0 ) {
268                 char            *retoid = NULL;
269                 struct berval   *retdata = NULL;
270
271                 rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
272
273                 if ( rc != LDAP_SUCCESS ) {
274                         tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
275                         rc = EXIT_FAILURE;
276                         goto skip;
277                 }
278
279                 if ( retdata != NULL ) {
280                         if ( retdata->bv_len == 0 ) {
281                                 printf(_("anonymous\n") );
282                         } else {
283                                 printf("%s\n", retdata->bv_val );
284                         }
285                 }
286
287                 ber_memfree( retoid );
288                 ber_bvfree( retdata );
289
290         } else if ( strcasecmp( argv[ 0 ], "cancel" ) == 0 ) {
291                 /* no extended response; returns specific errors */
292                 assert( 0 );
293
294         } else if ( strcasecmp( argv[ 0 ], "passwd" ) == 0 ) {
295                 /* TODO */
296
297         } else if ( strcasecmp( argv[ 0 ], "refresh" ) == 0 ) {
298                 int     newttl;
299
300                 rc = ldap_parse_refresh( ld, res, &newttl );
301
302                 if ( rc != LDAP_SUCCESS ) {
303                         tool_perror( "ldap_parse_refresh", rc, NULL, NULL, NULL, NULL );
304                         rc = EXIT_FAILURE;
305                         goto skip;
306                 }
307
308                 printf( "newttl=%d\n", newttl );
309
310         } else if ( tool_is_oid( argv[ 0 ] ) ) {
311                 char            *retoid = NULL;
312                 struct berval   *retdata = NULL;
313
314                 if( ldif < 2 ) {
315                         printf(_("# extended operation response\n"));
316                 }
317
318                 rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
319                 if ( rc != LDAP_SUCCESS ) {
320                         tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
321                         rc = EXIT_FAILURE;
322                         goto skip;
323                 }
324
325                 if ( ldif < 2 && retoid != NULL ) {
326                         tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
327                                 "oid", retoid, strlen(retoid) );
328                 }
329
330                 ber_memfree( retoid );
331
332                 if( retdata != NULL ) {
333                         if ( ldif < 2 ) {
334                                 tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
335                                         "data", retdata->bv_val, retdata->bv_len );
336                         }
337
338                         ber_bvfree( retdata );
339                 }
340         }
341
342         if( verbose || ( code != LDAP_SUCCESS ) || matcheddn || text || refs ) {
343                 printf( _("Result: %s (%d)\n"), ldap_err2string( code ), code );
344
345                 if( text && *text ) {
346                         printf( _("Additional info: %s\n"), text );
347                 }
348
349                 if( matcheddn && *matcheddn ) {
350                         printf( _("Matched DN: %s\n"), matcheddn );
351                 }
352
353                 if( refs ) {
354                         int i;
355                         for( i=0; refs[i]; i++ ) {
356                                 printf(_("Referral: %s\n"), refs[i] );
357                         }
358                 }
359         }
360
361         ber_memfree( text );
362         ber_memfree( matcheddn );
363         ber_memvfree( (void **) refs );
364
365 skip:
366         /* disconnect from server */
367         tool_unbind( ld );
368         tool_destroy();
369
370         return code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
371 }