1 /* ldapexop.c -- a tool for performing well-known extended operations */
2 /* $OpenLDAP: pkg/ldap/clients/tools/ldapexop.c,v 1.9.2.3 2008/02/11 23:26:38 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2005-2008 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
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>.
17 * This work was originally developed by Pierangelo Masarati for inclusion
18 * in OpenLDAP Software based, in part, on other client tools.
25 #include <ac/stdlib.h>
28 #include <ac/socket.h>
29 #include <ac/string.h>
31 #include <ac/unistd.h>
36 #include "lutil_ldap.h"
37 #include "ldap_defaults.h"
44 fprintf( stderr
, _("Issue LDAP extended operations\n\n"));
45 fprintf( stderr
, _("usage: %s [options] <oid|oid:data|oid::b64data>\n"), prog
);
51 const char options
[] = ""
52 "d:D:e:h:H:InO:o:p:QR:U:vVw:WxX:y:Y:Z";
55 handle_private_option( int i
)
66 main( int argc
, char *argv
[] )
72 char *matcheddn
= NULL
, *text
= NULL
, **refs
= NULL
;
73 LDAPControl
**ctrls
= NULL
;
77 tool_init( TOOL_EXOP
);
78 prog
= lutil_progname( "ldapexop", argc
, argv
);
81 protocol
= LDAP_VERSION3
;
83 tool_args( argc
, argv
);
85 if ( argc
- optind
< 1 ) {
89 if ( pw_file
|| want_bindpw
) {
91 rc
= lutil_get_filed_password( pw_file
, &passwd
);
92 if( rc
) return EXIT_FAILURE
;
94 passwd
.bv_val
= getpassphrase( _("Enter LDAP Password: ") );
95 passwd
.bv_len
= passwd
.bv_val
? strlen( passwd
.bv_val
) : 0;
99 ld
= tool_conn_setup( 0, 0 );
106 if ( strcasecmp( argv
[ 0 ], "whoami" ) == 0 ) {
107 tool_server_controls( ld
, NULL
, 0 );
109 rc
= ldap_whoami( ld
, NULL
, NULL
, &id
);
110 if ( rc
!= LDAP_SUCCESS
) {
111 tool_perror( "ldap_extended_operation", rc
, NULL
, NULL
, NULL
, NULL
);
116 } else if ( strcasecmp( argv
[ 0 ], "cancel" ) == 0 ) {
121 if ( lutil_atoi( &cancelid
, argv
[ 1 ] ) != 0 || cancelid
< 0 ) {
122 fprintf( stderr
, "invalid cancelid=%s\n\n", argv
[ 1 ] );
128 fprintf( stderr
, "need cancelid\n\n" );
132 rc
= ldap_cancel( ld
, cancelid
, NULL
, NULL
, &id
);
133 if ( rc
!= LDAP_SUCCESS
) {
134 tool_perror( "ldap_cancel", rc
, NULL
, NULL
, NULL
, NULL
);
139 } else if ( strcasecmp( argv
[ 0 ], "passwd" ) == 0 ) {
140 fprintf( stderr
, "use ldappasswd(1) instead.\n\n", argv
[ 0 ] );
144 } else if ( strcasecmp( argv
[ 0 ], "refresh" ) == 0 ) {
150 ttl
= atoi( argv
[ 2 ] );
153 dn
.bv_val
= argv
[ 1 ];
154 dn
.bv_len
= strlen( dn
.bv_val
);
160 fprintf( stderr
, _("need DN [ttl]\n\n") );
164 tool_server_controls( ld
, NULL
, 0 );
166 rc
= ldap_refresh( ld
, &dn
, ttl
, NULL
, NULL
, &id
);
167 if ( rc
!= LDAP_SUCCESS
) {
168 tool_perror( "ldap_extended_operation", rc
, NULL
, NULL
, NULL
, NULL
);
180 p
= strchr( argv
[ 0 ], ':' );
181 if ( p
== argv
[ 0 ] ) {
188 if ( tool_is_oid( argv
[ 0 ] ) ) {
189 struct berval reqdata
;
196 ldif_parse_line2( argv
[ 0 ], &type
, &value
, &freeval
);
202 ber_dupbv( &reqdata
, &value
);
207 tool_server_controls( ld
, NULL
, 0 );
209 rc
= ldap_extended_operation( ld
, argv
[ 0 ], p
? &reqdata
: NULL
, NULL
, NULL
, &id
);
210 if ( rc
!= LDAP_SUCCESS
) {
211 tool_perror( "ldap_extended_operation", rc
, NULL
, NULL
, NULL
, NULL
);
216 fprintf( stderr
, "unknown exop \"%s\"\n\n", argv
[ 0 ] );
224 if ( tool_check_abandon( ld
, id
) ) {
225 return LDAP_CANCELLED
;
231 rc
= ldap_result( ld
, LDAP_RES_ANY
, LDAP_MSG_ALL
, &tv
, &res
);
233 tool_perror( "ldap_result", rc
, NULL
, NULL
, NULL
, NULL
);
243 rc
= ldap_parse_result( ld
, res
,
244 &code
, &matcheddn
, &text
, &refs
, &ctrls
, 0 );
245 if ( rc
== LDAP_SUCCESS
) {
249 if ( rc
!= LDAP_SUCCESS
) {
250 tool_perror( "ldap_parse_result", rc
, NULL
, matcheddn
, text
, refs
);
255 if ( strcasecmp( argv
[ 0 ], "whoami" ) == 0 ) {
257 struct berval
*retdata
= NULL
;
259 rc
= ldap_parse_extended_result( ld
, res
, &retoid
, &retdata
, 1 );
261 if ( rc
!= LDAP_SUCCESS
) {
262 tool_perror( "ldap_parse_extended_result", rc
, NULL
, NULL
, NULL
, NULL
);
267 if ( retdata
!= NULL
) {
268 if ( retdata
->bv_len
== 0 ) {
269 printf(_("anonymous\n") );
271 printf("%s\n", retdata
->bv_val
);
275 ber_memfree( retoid
);
276 ber_bvfree( retdata
);
278 } else if ( strcasecmp( argv
[ 0 ], "cancel" ) == 0 ) {
279 /* no extended response; returns specific errors */
282 } else if ( strcasecmp( argv
[ 0 ], "passwd" ) == 0 ) {
285 } else if ( strcasecmp( argv
[ 0 ], "refresh" ) == 0 ) {
288 rc
= ldap_parse_refresh( ld
, res
, &newttl
);
290 if ( rc
!= LDAP_SUCCESS
) {
291 tool_perror( "ldap_parse_refresh", rc
, NULL
, NULL
, NULL
, NULL
);
296 printf( "newttl=%d\n", newttl
);
298 } else if ( tool_is_oid( argv
[ 0 ] ) ) {
300 struct berval
*retdata
= NULL
;
303 printf(_("# extended operation response\n"));
306 rc
= ldap_parse_extended_result( ld
, res
, &retoid
, &retdata
, 1 );
307 if ( rc
!= LDAP_SUCCESS
) {
308 tool_perror( "ldap_parse_extended_result", rc
, NULL
, NULL
, NULL
, NULL
);
313 if ( ldif
< 2 && retoid
!= NULL
) {
314 tool_write_ldif( ldif
? LDIF_PUT_COMMENT
: LDIF_PUT_VALUE
,
315 "oid", retoid
, strlen(retoid
) );
318 ber_memfree( retoid
);
320 if( retdata
!= NULL
) {
322 tool_write_ldif( ldif
? LDIF_PUT_COMMENT
: LDIF_PUT_BINARY
,
323 "data", retdata
->bv_val
, retdata
->bv_len
);
326 ber_bvfree( retdata
);
330 if( verbose
|| ( code
!= LDAP_SUCCESS
) || matcheddn
|| text
|| refs
) {
331 printf( _("Result: %s (%d)\n"), ldap_err2string( code
), code
);
333 if( text
&& *text
) {
334 printf( _("Additional info: %s\n"), text
);
337 if( matcheddn
&& *matcheddn
) {
338 printf( _("Matched DN: %s\n"), matcheddn
);
343 for( i
=0; refs
[i
]; i
++ ) {
344 printf(_("Referral: %s\n"), refs
[i
] );
350 tool_print_ctrls( ld
, ctrls
);
351 ldap_controls_free( ctrls
);
355 ber_memfree( matcheddn
);
356 ber_memvfree( (void **) refs
);
359 /* disconnect from server */
363 return code
== LDAP_SUCCESS
? EXIT_SUCCESS
: EXIT_FAILURE
;