]> git.sur5r.net Git - openldap/blob - clients/tools/ldapexop.c
advertise known exops
[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-2009 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         fprintf( stderr, _("       %s [options] whoami\n"), prog);
47         fprintf( stderr, _("       %s [options] cancel <id>\n"), prog);
48         fprintf( stderr, _("       %s [options] refresh <DN> [<ttl>]\n"), prog);
49         tool_common_usage();
50         exit( EXIT_FAILURE );
51 }
52
53
54 const char options[] = ""
55         "d:D:e:h:H:InNO:o:p:QR:U:vVw:WxX:y:Y:Z";
56
57 int
58 handle_private_option( int i )
59 {
60         switch ( i ) {
61         default:
62                 return 0;
63         }
64         return 1;
65 }
66
67
68 int
69 main( int argc, char *argv[] )
70 {
71         int             rc;
72
73         LDAP            *ld = NULL;
74
75         char            *matcheddn = NULL, *text = NULL, **refs = NULL;
76         LDAPControl **ctrls = NULL;
77         int             id, code;
78         LDAPMessage     *res;
79
80         tool_init( TOOL_EXOP );
81         prog = lutil_progname( "ldapexop", argc, argv );
82
83         /* LDAPv3 only */
84         protocol = LDAP_VERSION3;
85
86         tool_args( argc, argv );
87
88         if ( argc - optind < 1 ) {
89                 usage();
90         }
91
92         if ( pw_file || want_bindpw ) {
93                 if ( pw_file ) {
94                         rc = lutil_get_filed_password( pw_file, &passwd );
95                         if( rc ) return EXIT_FAILURE;
96                 } else {
97                         passwd.bv_val = getpassphrase( _("Enter LDAP Password: ") );
98                         passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
99                 }
100         }
101
102         ld = tool_conn_setup( 0, 0 );
103
104         tool_bind( ld );
105
106         argv += optind;
107         argc -= optind;
108
109         if ( strcasecmp( argv[ 0 ], "whoami" ) == 0 ) {
110                 tool_server_controls( ld, NULL, 0 );
111
112                 rc = ldap_whoami( ld, NULL, NULL, &id ); 
113                 if ( rc != LDAP_SUCCESS ) {
114                         tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
115                         rc = EXIT_FAILURE;
116                         goto skip;
117                 }
118
119         } else if ( strcasecmp( argv[ 0 ], "cancel" ) == 0 ) {
120                 int             cancelid;
121
122                 switch ( argc ) {
123                 case 2:
124                          if ( lutil_atoi( &cancelid, argv[ 1 ] ) != 0 || cancelid < 0 ) {
125                                 fprintf( stderr, "invalid cancelid=%s\n\n", argv[ 1 ] );
126                                 usage();
127                         }
128                         break;
129
130                 default:
131                         fprintf( stderr, "need cancelid\n\n" );
132                         usage();
133                 }
134
135                 rc = ldap_cancel( ld, cancelid, NULL, NULL, &id );
136                 if ( rc != LDAP_SUCCESS ) {
137                         tool_perror( "ldap_cancel", rc, NULL, NULL, NULL, NULL );
138                         rc = EXIT_FAILURE;
139                         goto skip;
140                 }
141
142         } else if ( strcasecmp( argv[ 0 ], "passwd" ) == 0 ) {
143                 fprintf( stderr, "use ldappasswd(1) instead.\n\n", argv[ 0 ] );
144                 usage();
145                 /* TODO? */
146
147         } else if ( strcasecmp( argv[ 0 ], "refresh" ) == 0 ) {
148                 int             ttl = 3600;
149                 struct berval   dn;
150
151                 switch ( argc ) {
152                 case 3:
153                         ttl = atoi( argv[ 2 ] );
154
155                 case 2:
156                         dn.bv_val = argv[ 1 ];
157                         dn.bv_len = strlen( dn.bv_val );
158                         break;
159
160                 default:
161                         fprintf( stderr, _("need DN [ttl]\n\n") );
162                         usage();
163                 }
164                 
165                 tool_server_controls( ld, NULL, 0 );
166
167                 rc = ldap_refresh( ld, &dn, ttl, NULL, NULL, &id ); 
168                 if ( rc != LDAP_SUCCESS ) {
169                         tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
170                         rc = EXIT_FAILURE;
171                         goto skip;
172                 }
173
174         } else {
175                 char *p;
176
177                 if ( argc != 1 ) {
178                         usage();
179                 }
180
181                 p = strchr( argv[ 0 ], ':' );
182                 if ( p == argv[ 0 ] ) {
183                         usage();
184                 }
185
186                 if ( p != NULL )
187                         *p++ = '\0';
188
189                 if ( tool_is_oid( argv[ 0 ] ) ) {
190                         struct berval   reqdata;
191                         struct berval   type;
192                         struct berval   value;
193                         int             freeval;
194
195                         if ( p != NULL ) {
196                                 p[ -1 ] = ':';
197                                 ldif_parse_line2( argv[ 0 ], &type, &value, &freeval );
198                                 p[ -1 ] = '\0';
199
200                                 if ( freeval ) {
201                                         reqdata = value;
202                                 } else {
203                                         ber_dupbv( &reqdata, &value );
204                                 }
205                         }
206
207
208                         tool_server_controls( ld, NULL, 0 );
209
210                         rc = ldap_extended_operation( ld, argv[ 0 ], p ? &reqdata : NULL, NULL, NULL, &id );
211                         if ( rc != LDAP_SUCCESS ) {
212                                 tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
213                                 rc = EXIT_FAILURE;
214                                 goto skip;
215                         }
216                 } else {
217                         fprintf( stderr, "unknown exop \"%s\"\n\n", argv[ 0 ] );
218                         usage();
219                 }
220         }
221
222         for ( ; ; ) {
223                 struct timeval  tv;
224
225                 if ( tool_check_abandon( ld, id ) ) {
226                         return LDAP_CANCELLED;
227                 }
228
229                 tv.tv_sec = 0;
230                 tv.tv_usec = 100000;
231
232                 rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
233                 if ( rc < 0 ) {
234                         tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
235                         rc = EXIT_FAILURE;
236                         goto skip;
237                 }
238
239                 if ( rc != 0 ) {
240                         break;
241                 }
242         }
243
244         rc = ldap_parse_result( ld, res,
245                 &code, &matcheddn, &text, &refs, &ctrls, 0 );
246         if ( rc == LDAP_SUCCESS ) {
247                 rc = code;
248         }
249
250         if ( rc != LDAP_SUCCESS ) {
251                 tool_perror( "ldap_parse_result", rc, NULL, matcheddn, text, refs );
252                 rc = EXIT_FAILURE;
253                 goto skip;
254         }
255
256         if ( strcasecmp( argv[ 0 ], "whoami" ) == 0 ) {
257                 char            *retoid = NULL;
258                 struct berval   *retdata = NULL;
259
260                 rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
261
262                 if ( rc != LDAP_SUCCESS ) {
263                         tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
264                         rc = EXIT_FAILURE;
265                         goto skip;
266                 }
267
268                 if ( retdata != NULL ) {
269                         if ( retdata->bv_len == 0 ) {
270                                 printf(_("anonymous\n") );
271                         } else {
272                                 printf("%s\n", retdata->bv_val );
273                         }
274                 }
275
276                 ber_memfree( retoid );
277                 ber_bvfree( retdata );
278
279         } else if ( strcasecmp( argv[ 0 ], "cancel" ) == 0 ) {
280                 /* no extended response; returns specific errors */
281                 assert( 0 );
282
283         } else if ( strcasecmp( argv[ 0 ], "passwd" ) == 0 ) {
284                 /* TODO */
285
286         } else if ( strcasecmp( argv[ 0 ], "refresh" ) == 0 ) {
287                 int     newttl;
288
289                 rc = ldap_parse_refresh( ld, res, &newttl );
290
291                 if ( rc != LDAP_SUCCESS ) {
292                         tool_perror( "ldap_parse_refresh", rc, NULL, NULL, NULL, NULL );
293                         rc = EXIT_FAILURE;
294                         goto skip;
295                 }
296
297                 printf( "newttl=%d\n", newttl );
298
299         } else if ( tool_is_oid( argv[ 0 ] ) ) {
300                 char            *retoid = NULL;
301                 struct berval   *retdata = NULL;
302
303                 if( ldif < 2 ) {
304                         printf(_("# extended operation response\n"));
305                 }
306
307                 rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
308                 if ( rc != LDAP_SUCCESS ) {
309                         tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
310                         rc = EXIT_FAILURE;
311                         goto skip;
312                 }
313
314                 if ( ldif < 2 && retoid != NULL ) {
315                         tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
316                                 "oid", retoid, strlen(retoid) );
317                 }
318
319                 ber_memfree( retoid );
320
321                 if( retdata != NULL ) {
322                         if ( ldif < 2 ) {
323                                 tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
324                                         "data", retdata->bv_val, retdata->bv_len );
325                         }
326
327                         ber_bvfree( retdata );
328                 }
329         }
330
331         if( verbose || ( code != LDAP_SUCCESS ) || matcheddn || text || refs ) {
332                 printf( _("Result: %s (%d)\n"), ldap_err2string( code ), code );
333
334                 if( text && *text ) {
335                         printf( _("Additional info: %s\n"), text );
336                 }
337
338                 if( matcheddn && *matcheddn ) {
339                         printf( _("Matched DN: %s\n"), matcheddn );
340                 }
341
342                 if( refs ) {
343                         int i;
344                         for( i=0; refs[i]; i++ ) {
345                                 printf(_("Referral: %s\n"), refs[i] );
346                         }
347                 }
348         }
349
350     if (ctrls) {
351                 tool_print_ctrls( ld, ctrls );
352                 ldap_controls_free( ctrls );
353         }
354
355         ber_memfree( text );
356         ber_memfree( matcheddn );
357         ber_memvfree( (void **) refs );
358
359 skip:
360         /* disconnect from server */
361         tool_unbind( ld );
362         tool_destroy();
363
364         return code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
365 }