Back to index

openldap  2.4.31
ldapexop.c
Go to the documentation of this file.
00001 /* ldapexop.c -- a tool for performing well-known extended operations */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 2005-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 /* ACKNOWLEDGEMENTS:
00017  * This work was originally developed by Pierangelo Masarati for inclusion
00018  * in OpenLDAP Software based, in part, on other client tools.
00019  */
00020 
00021 #include "portable.h"
00022 
00023 #include <stdio.h>
00024 
00025 #include <ac/stdlib.h>
00026 
00027 #include <ac/ctype.h>
00028 #include <ac/socket.h>
00029 #include <ac/string.h>
00030 #include <ac/time.h>
00031 #include <ac/unistd.h>
00032 
00033 #include <ldap.h>
00034 #include "ldif.h"
00035 #include "lutil.h"
00036 #include "lutil_ldap.h"
00037 #include "ldap_defaults.h"
00038 
00039 #include "common.h"
00040 
00041 void
00042 usage( void )
00043 {
00044        fprintf( stderr, _("Issue LDAP extended operations\n\n"));
00045        fprintf( stderr, _("usage: %s [options] <oid|oid:data|oid::b64data>\n"), prog);
00046        fprintf( stderr, _("       %s [options] whoami\n"), prog);
00047        fprintf( stderr, _("       %s [options] cancel <id>\n"), prog);
00048        fprintf( stderr, _("       %s [options] refresh <DN> [<ttl>]\n"), prog);
00049        tool_common_usage();
00050        exit( EXIT_FAILURE );
00051 }
00052 
00053 
00054 const char options[] = ""
00055        "d:D:e:h:H:InNO:o:p:QR:U:vVw:WxX:y:Y:Z";
00056 
00057 int
00058 handle_private_option( int i )
00059 {
00060        switch ( i ) {
00061        default:
00062               return 0;
00063        }
00064        return 1;
00065 }
00066 
00067 
00068 int
00069 main( int argc, char *argv[] )
00070 {
00071        int           rc;
00072 
00073        LDAP          *ld = NULL;
00074 
00075        char          *matcheddn = NULL, *text = NULL, **refs = NULL;
00076        LDAPControl **ctrls = NULL;
00077        int           id, code;
00078        LDAPMessage   *res = NULL;
00079 
00080        tool_init( TOOL_EXOP );
00081        prog = lutil_progname( "ldapexop", argc, argv );
00082 
00083        /* LDAPv3 only */
00084        protocol = LDAP_VERSION3;
00085 
00086        tool_args( argc, argv );
00087 
00088        if ( argc - optind < 1 ) {
00089               usage();
00090        }
00091 
00092        ld = tool_conn_setup( 0, 0 );
00093 
00094        tool_bind( ld );
00095 
00096        argv += optind;
00097        argc -= optind;
00098 
00099        if ( strcasecmp( argv[ 0 ], "whoami" ) == 0 ) {
00100               tool_server_controls( ld, NULL, 0 );
00101 
00102               rc = ldap_whoami( ld, NULL, NULL, &id ); 
00103               if ( rc != LDAP_SUCCESS ) {
00104                      tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
00105                      rc = EXIT_FAILURE;
00106                      goto skip;
00107               }
00108 
00109        } else if ( strcasecmp( argv[ 0 ], "cancel" ) == 0 ) {
00110               int           cancelid;
00111 
00112               switch ( argc ) {
00113               case 2:
00114                       if ( lutil_atoi( &cancelid, argv[ 1 ] ) != 0 || cancelid < 0 ) {
00115                             fprintf( stderr, "invalid cancelid=%s\n\n", argv[ 1 ] );
00116                             usage();
00117                      }
00118                      break;
00119 
00120               default:
00121                      fprintf( stderr, "need cancelid\n\n" );
00122                      usage();
00123               }
00124 
00125               rc = ldap_cancel( ld, cancelid, NULL, NULL, &id );
00126               if ( rc != LDAP_SUCCESS ) {
00127                      tool_perror( "ldap_cancel", rc, NULL, NULL, NULL, NULL );
00128                      rc = EXIT_FAILURE;
00129                      goto skip;
00130               }
00131 
00132        } else if ( strcasecmp( argv[ 0 ], "passwd" ) == 0 ) {
00133               fprintf( stderr, "use ldappasswd(1) instead.\n\n", argv[ 0 ] );
00134               usage();
00135               /* TODO? */
00136 
00137        } else if ( strcasecmp( argv[ 0 ], "refresh" ) == 0 ) {
00138               int           ttl = 3600;
00139               struct berval dn;
00140 
00141               switch ( argc ) {
00142               case 3:
00143                      ttl = atoi( argv[ 2 ] );
00144 
00145               case 2:
00146                      dn.bv_val = argv[ 1 ];
00147                      dn.bv_len = strlen( dn.bv_val );
00148                      break;
00149 
00150               default:
00151                      fprintf( stderr, _("need DN [ttl]\n\n") );
00152                      usage();
00153               }
00154               
00155               tool_server_controls( ld, NULL, 0 );
00156 
00157               rc = ldap_refresh( ld, &dn, ttl, NULL, NULL, &id ); 
00158               if ( rc != LDAP_SUCCESS ) {
00159                      tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
00160                      rc = EXIT_FAILURE;
00161                      goto skip;
00162               }
00163 
00164        } else {
00165               char *p;
00166 
00167               if ( argc != 1 ) {
00168                      usage();
00169               }
00170 
00171               p = strchr( argv[ 0 ], ':' );
00172               if ( p == argv[ 0 ] ) {
00173                      usage();
00174               }
00175 
00176               if ( p != NULL )
00177                      *p++ = '\0';
00178 
00179               if ( tool_is_oid( argv[ 0 ] ) ) {
00180                      struct berval reqdata;
00181                      struct berval type;
00182                      struct berval value;
00183                      int           freeval;
00184 
00185                      if ( p != NULL ) {
00186                             p[ -1 ] = ':';
00187                             ldif_parse_line2( argv[ 0 ], &type, &value, &freeval );
00188                             p[ -1 ] = '\0';
00189 
00190                             if ( freeval ) {
00191                                    reqdata = value;
00192                             } else {
00193                                    ber_dupbv( &reqdata, &value );
00194                             }
00195                      }
00196 
00197 
00198                      tool_server_controls( ld, NULL, 0 );
00199 
00200                      rc = ldap_extended_operation( ld, argv[ 0 ], p ? &reqdata : NULL, NULL, NULL, &id );
00201                      if ( rc != LDAP_SUCCESS ) {
00202                             tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
00203                             rc = EXIT_FAILURE;
00204                             goto skip;
00205                      }
00206               } else {
00207                      fprintf( stderr, "unknown exop \"%s\"\n\n", argv[ 0 ] );
00208                      usage();
00209               }
00210        }
00211 
00212        for ( ; ; ) {
00213               struct timeval       tv;
00214 
00215               if ( tool_check_abandon( ld, id ) ) {
00216                      tool_exit( ld, LDAP_CANCELLED );
00217               }
00218 
00219               tv.tv_sec = 0;
00220               tv.tv_usec = 100000;
00221 
00222               rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
00223               if ( rc < 0 ) {
00224                      tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
00225                      rc = EXIT_FAILURE;
00226                      goto skip;
00227               }
00228 
00229               if ( rc != 0 ) {
00230                      break;
00231               }
00232        }
00233 
00234        rc = ldap_parse_result( ld, res,
00235               &code, &matcheddn, &text, &refs, &ctrls, 0 );
00236        if ( rc == LDAP_SUCCESS ) {
00237               rc = code;
00238        }
00239 
00240        if ( rc != LDAP_SUCCESS ) {
00241               tool_perror( "ldap_parse_result", rc, NULL, matcheddn, text, refs );
00242               rc = EXIT_FAILURE;
00243               goto skip;
00244        }
00245 
00246        if ( strcasecmp( argv[ 0 ], "whoami" ) == 0 ) {
00247               char          *retoid = NULL;
00248               struct berval *retdata = NULL;
00249 
00250               rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 0 );
00251 
00252               if ( rc != LDAP_SUCCESS ) {
00253                      tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
00254                      rc = EXIT_FAILURE;
00255                      goto skip;
00256               }
00257 
00258               if ( retdata != NULL ) {
00259                      if ( retdata->bv_len == 0 ) {
00260                             printf(_("anonymous\n") );
00261                      } else {
00262                             printf("%s\n", retdata->bv_val );
00263                      }
00264               }
00265 
00266               ber_memfree( retoid );
00267               ber_bvfree( retdata );
00268 
00269        } else if ( strcasecmp( argv[ 0 ], "cancel" ) == 0 ) {
00270               /* no extended response; returns specific errors */
00271               assert( 0 );
00272 
00273        } else if ( strcasecmp( argv[ 0 ], "passwd" ) == 0 ) {
00274               /* TODO */
00275 
00276        } else if ( strcasecmp( argv[ 0 ], "refresh" ) == 0 ) {
00277               int    newttl;
00278 
00279               rc = ldap_parse_refresh( ld, res, &newttl );
00280 
00281               if ( rc != LDAP_SUCCESS ) {
00282                      tool_perror( "ldap_parse_refresh", rc, NULL, NULL, NULL, NULL );
00283                      rc = EXIT_FAILURE;
00284                      goto skip;
00285               }
00286 
00287               printf( "newttl=%d\n", newttl );
00288 
00289        } else if ( tool_is_oid( argv[ 0 ] ) ) {
00290               char          *retoid = NULL;
00291               struct berval *retdata = NULL;
00292 
00293               if( ldif < 2 ) {
00294                      printf(_("# extended operation response\n"));
00295               }
00296 
00297               rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 0 );
00298               if ( rc != LDAP_SUCCESS ) {
00299                      tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
00300                      rc = EXIT_FAILURE;
00301                      goto skip;
00302               }
00303 
00304               if ( ldif < 2 && retoid != NULL ) {
00305                      tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
00306                             "oid", retoid, strlen(retoid) );
00307               }
00308 
00309               ber_memfree( retoid );
00310 
00311               if( retdata != NULL ) {
00312                      if ( ldif < 2 ) {
00313                             tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
00314                                    "data", retdata->bv_val, retdata->bv_len );
00315                      }
00316 
00317                      ber_bvfree( retdata );
00318               }
00319        }
00320 
00321        if( verbose || code != LDAP_SUCCESS ||
00322               ( matcheddn && *matcheddn ) || ( text && *text ) || refs ) {
00323               printf( _("Result: %s (%d)\n"), ldap_err2string( code ), code );
00324 
00325               if( text && *text ) {
00326                      printf( _("Additional info: %s\n"), text );
00327               }
00328 
00329               if( matcheddn && *matcheddn ) {
00330                      printf( _("Matched DN: %s\n"), matcheddn );
00331               }
00332 
00333               if( refs ) {
00334                      int i;
00335                      for( i=0; refs[i]; i++ ) {
00336                             printf(_("Referral: %s\n"), refs[i] );
00337                      }
00338               }
00339        }
00340 
00341     if (ctrls) {
00342               tool_print_ctrls( ld, ctrls );
00343               ldap_controls_free( ctrls );
00344        }
00345 
00346        ber_memfree( text );
00347        ber_memfree( matcheddn );
00348        ber_memvfree( (void **) refs );
00349 
00350 skip:
00351        /* disconnect from server */
00352        if ( res )
00353               ldap_msgfree( res );
00354        tool_exit( ld, code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE );
00355 }