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