From 4a223061edb8a3fdb0bb1f5a721a42248ef5a486 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Tue, 19 Apr 2005 21:21:51 +0000 Subject: [PATCH] allow abandon/cancel for all tools --- clients/tools/common.c | 54 +++++++++++++++++++++++--- clients/tools/common.h | 1 + clients/tools/ldapcompare.c | 75 +++++++++++++++++++++++++++++++++---- clients/tools/ldapdelete.c | 26 ++++++++++--- clients/tools/ldapmodify.c | 36 +++++++++++++----- clients/tools/ldapmodrdn.c | 23 ++++++++++-- clients/tools/ldappasswd.c | 24 +++++++++--- clients/tools/ldapsearch.c | 27 ++----------- clients/tools/ldapwhoami.c | 62 ++++++++++++++++++++++++++---- doc/devel/args | 2 +- doc/man/man1/ldapsearch.1 | 9 ----- 11 files changed, 261 insertions(+), 78 deletions(-) diff --git a/clients/tools/common.c b/clients/tools/common.c index 49d2052cfd..f78e6b38a6 100644 --- a/clients/tools/common.c +++ b/clients/tools/common.c @@ -86,6 +86,15 @@ static int chainingResolve = -1; static int chainingContinuation = -1; #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ +static int gotintr; +static int abcan; + +RETSIGTYPE +do_sig( int sig ) +{ + gotintr = abcan; +} + /* Set in main() */ char *prog = NULL; @@ -119,18 +128,19 @@ N_(" -D binddn bind DN\n"), N_(" -e [!][=] general extensions (! indicates criticality)\n") N_(" [!]assert= (an RFC 2254 Filter)\n") N_(" [!]authzid= (\"dn:\" or \"u:\")\n") -N_(" [!]manageDSAit\n") -N_(" [!]noop\n") -#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST -N_(" ppolicy\n") -#endif #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR N_(" [!]chaining[=[/]]\n") N_(" one of \"chainingPreferred\", \"chainingRequired\",\n") N_(" \"referralsPreferred\", \"referralsRequired\"\n") #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ +N_(" [!]manageDSAit\n") +N_(" [!]noop\n") +#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST +N_(" ppolicy\n") +#endif N_(" [!]postread[=] (a comma-separated attribute list)\n") N_(" [!]preread[=] (a comma-separated attribute list)\n"), +N_(" abandon, cancel (SIGINT sends abandon/cancel (not really controls)\n") N_(" -f file read operations from `file'\n"), N_(" -h host LDAP server\n"), N_(" -H URI LDAP Uniform Resource Indentifier(s)\n"), @@ -354,6 +364,13 @@ tool_args( int argc, char **argv ) } #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ + /* this shouldn't go here, really; but it's a feature... */ + } else if ( strcasecmp( control, "abandon" ) == 0 ) { + abcan = LDAP_REQ_ABANDON; + + } else if ( strcasecmp( control, "cancel" ) == 0 ) { + abcan = LDAP_REQ_EXTENDED; + } else { fprintf( stderr, "Invalid general control name: %s\n", control ); @@ -756,6 +773,10 @@ tool_conn_setup( int not, void (*private_setup)( LDAP * ) ) (void) SIGNAL( SIGPIPE, SIG_IGN ); #endif + if ( abcan ) { + SIGNAL( SIGINT, do_sig ); + } + if ( !not ) { int rc; @@ -1135,3 +1156,26 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) exit( EXIT_FAILURE ); } } + +int +tool_check_abandon( LDAP *ld, int msgid ) +{ + int rc; + + switch ( gotintr ) { + case LDAP_REQ_EXTENDED: + rc = ldap_cancel_s( ld, msgid, NULL, NULL ); + fprintf( stderr, "got interrupt, cancel got %d: %s\n", + rc, ldap_err2string( rc ) ); + return -1; + + case LDAP_REQ_ABANDON: + rc = ldap_abandon( ld, msgid ); + fprintf( stderr, "got interrupt, abandon got %d: %s\n", + rc, ldap_err2string( rc ) ); + return -1; + } + + return 0; +} + diff --git a/clients/tools/common.h b/clients/tools/common.h index fc7632b6bc..dad3108c02 100644 --- a/clients/tools/common.h +++ b/clients/tools/common.h @@ -80,6 +80,7 @@ void tool_bind LDAP_P(( LDAP * )); void tool_unbind LDAP_P(( LDAP * )); void tool_destroy LDAP_P(( void )); void tool_server_controls LDAP_P(( LDAP *, LDAPControl *, int )); +int tool_check_abandon LDAP_P(( LDAP *ld, int msgid )); LDAP_END_DECL diff --git a/clients/tools/ldapcompare.c b/clients/tools/ldapcompare.c index ed128768cf..a7a20a4f14 100644 --- a/clients/tools/ldapcompare.c +++ b/clients/tools/ldapcompare.c @@ -232,27 +232,88 @@ static int docompare( LDAPControl **sctrls, LDAPControl **cctrls ) { - int rc; + int rc, msgid, code; + LDAPMessage *res; + char *matcheddn; + char *text; + char **refs; if ( not ) { return LDAP_SUCCESS; } - rc = ldap_compare_ext_s( ld, dn, attr, bvalue, - sctrls, cctrls ); + rc = ldap_compare_ext( ld, dn, attr, bvalue, + sctrls, cctrls, &msgid ); + if ( rc == -1 ) { + return( rc ); + } + + for ( ; ; ) { + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = 100000; + + if ( tool_check_abandon( ld, msgid ) ) { + return LDAP_CANCELLED; + } + + rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res ); + if ( rc < 0 ) { + ldap_perror( ld, "ldapcompare: ldap_result" ); + return rc; + } + + if ( rc != 0 ) { + break; + } + } + + rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 1 ); + + if( rc != LDAP_SUCCESS ) { + fprintf( stderr, "%s: ldap_parse_result: %s (%d)\n", + prog, ldap_err2string( rc ), rc ); + return rc; + } + + if ( !quiet && ( verbose || ( code != LDAP_SUCCESS && code != LDAP_COMPARE_TRUE && code != LDAP_COMPARE_FALSE )|| + (matcheddn && *matcheddn) || (text && *text) || (refs && *refs) ) ) + { + printf( _("Compare Result: %s (%d)\n"), + ldap_err2string( code ), code ); + + if( text && *text ) { + printf( _("Additional info: %s\n"), text ); + } + + if( matcheddn && *matcheddn ) { + printf( _("Matched DN: %s\n"), matcheddn ); + } + + if( refs ) { + int i; + for( i=0; refs[i]; i++ ) { + printf(_("Referral: %s\n"), refs[i] ); + } + } + } + + ber_memfree( text ); + ber_memfree( matcheddn ); + ber_memvfree( (void **) refs ); /* if we were told to be quiet, use the return value. */ if ( !quiet ) { - if ( rc == LDAP_COMPARE_TRUE ) { + if ( code == LDAP_COMPARE_TRUE ) { printf(_("TRUE\n")); - } else if ( rc == LDAP_COMPARE_FALSE ) { + } else if ( code == LDAP_COMPARE_FALSE ) { printf(_("FALSE\n")); } else { printf(_("UNDEFINED\n")); - ldap_perror( ld, "ldap_compare" ); } } - return( rc ); + return( code ); } diff --git a/clients/tools/ldapdelete.c b/clients/tools/ldapdelete.c index 101803a8b9..42730f1402 100644 --- a/clients/tools/ldapdelete.c +++ b/clients/tools/ldapdelete.c @@ -233,10 +233,25 @@ static int dodelete( return rc; } - rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res ); - if ( rc < 0 ) { - ldap_perror( ld, "ldapdelete: ldap_result" ); - return rc; + for ( ; ; ) { + struct timeval tv; + + if ( tool_check_abandon( ld, id ) ) { + return LDAP_CANCELLED; + } + + tv.tv_sec = 0; + tv.tv_usec = 100000; + + rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res ); + if ( rc < 0 ) { + ldap_perror( ld, "ldapdelete: ldap_result" ); + return rc; + } + + if ( rc != 0 ) { + break; + } } rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 1 ); @@ -250,7 +265,8 @@ static int dodelete( if( verbose || code != LDAP_SUCCESS || (matcheddn && *matcheddn) || (text && *text) || (refs && *refs) ) { - printf( _("Delete Result: %s (%d)\n"), ldap_err2string( code ), code ); + printf( _("Delete Result: %s (%d)\n"), + ldap_err2string( code ), code ); if( text && *text ) { printf( _("Additional info: %s\n"), text ); diff --git a/clients/tools/ldapmodify.c b/clients/tools/ldapmodify.c index 72d000020b..f4da605fb7 100644 --- a/clients/tools/ldapmodify.c +++ b/clients/tools/ldapmodify.c @@ -1010,7 +1010,7 @@ domodify( } if ( !not ) { - int msgid; + int msgid; if ( newentry ) { rc = ldap_add_ext( ld, dn, pmods, pctrls, NULL, &msgid ); } else { @@ -1114,21 +1114,37 @@ static int process_response( const char *opstr, const char *dn ) { - LDAPMessage *res; - int rc = LDAP_OTHER; + LDAPMessage *res; + int rc = LDAP_OTHER; + struct timeval tv = { 0 }; - if( ldap_result( ld, msgid, + for ( ; ; ) { + tv.tv_sec = 0; + tv.tv_usec = 100000; + + rc = ldap_result( ld, msgid, #ifdef LDAP_GROUP_TRANSACTION - txn ? 0 : 1, + txn ? 0 : 1, #else - 1, + 1, #endif - NULL, &res ) == -1 ) { - ldap_get_option( ld, LDAP_OPT_ERROR_NUMBER, &rc ); - return rc; + &tv, &res ); + if ( tool_check_abandon( ld, msgid ) ) { + return LDAP_CANCELLED; + } + + if ( rc == -1 ) { + ldap_get_option( ld, LDAP_OPT_ERROR_NUMBER, &rc ); + return rc; + } + + if ( rc != 0 ) { + break; + } } - if( ldap_msgtype( res ) != LDAP_RES_INTERMEDIATE ) { +done:; + if ( ldap_msgtype( res ) != LDAP_RES_INTERMEDIATE ) { rc = ldap_result2error( ld, res, 1 ); if( rc != LDAP_SUCCESS ) ldap_perror( ld, opstr ); return rc; diff --git a/clients/tools/ldapmodrdn.c b/clients/tools/ldapmodrdn.c index 188855b62b..dd3146cd06 100644 --- a/clients/tools/ldapmodrdn.c +++ b/clients/tools/ldapmodrdn.c @@ -263,10 +263,25 @@ static int domodrdn( return rc; } - rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res ); - if ( rc < 0 ) { - ldap_perror( ld, "ldapmodrdn: ldap_result" ); - return rc; + for ( ; ; ) { + struct timeval tv = { 0 }; + + if ( tool_check_abandon( ld, id ) ) { + return LDAP_CANCELLED; + } + + tv.tv_sec = 0; + tv.tv_usec = 100000; + + rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res ); + if ( rc < 0 ) { + ldap_perror( ld, "ldapmodrdn: ldap_result" ); + return rc; + } + + if ( rc != 0 ) { + break; + } } rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 1 ); diff --git a/clients/tools/ldappasswd.c b/clients/tools/ldappasswd.c index e3184bcc67..31556695c0 100644 --- a/clients/tools/ldappasswd.c +++ b/clients/tools/ldappasswd.c @@ -322,11 +322,25 @@ main( int argc, char *argv[] ) goto done; } - rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res ); - if ( rc < 0 ) { - ldap_perror( ld, "ldappasswd: ldap_result" ); - rc = EXIT_FAILURE; - goto done; + for ( ; ; ) { + struct timeval tv; + + if ( tool_check_abandon( ld, id ) ) { + return LDAP_CANCELLED; + } + + tv.tv_sec = 0; + tv.tv_usec = 100000; + + rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res ); + if ( rc < 0 ) { + ldap_perror( ld, "ldappasswd: ldap_result" ); + return rc; + } + + if ( rc != 0 ) { + break; + } } rc = ldap_parse_result( ld, res, diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c index 2de87f9d76..add14c38ae 100644 --- a/clients/tools/ldapsearch.c +++ b/clients/tools/ldapsearch.c @@ -553,14 +553,6 @@ private_conn_setup( LDAP *ld ) } } -static int gotintr; - -RETSIGTYPE -do_sig( int sig ) -{ - gotintr = contoper; -} - int main( int argc, char **argv ) { @@ -619,10 +611,6 @@ main( int argc, char **argv ) attrs = &argv[optind]; } - if ( contoper > 0 ) { - SIGNAL( SIGINT, do_sig ); - } - if ( infile != NULL ) { if ( infile[0] == '-' && infile[1] == '\0' ) { fp = stdin; @@ -1018,18 +1006,9 @@ static int dosearch( sortattr ? LDAP_MSG_ALL : LDAP_MSG_ONE, NULL, &res )) > 0 ) { - switch ( gotintr ) { - case 2: - rc = ldap_cancel_s( ld, msgid, NULL, NULL ); - fprintf( stderr, "got interrupt, cancel got %d: %s\n", - rc, ldap_err2string( rc ) ); - return -1; - - case 1: - rc = ldap_abandon( ld, msgid ); - fprintf( stderr, "got interrupt, abandon got %d: %s\n", - rc, ldap_err2string( rc ) ); - return -1; + rc = tool_check_abandon( ld, msgid ); + if ( rc ) { + return rc; } if( sortattr ) { diff --git a/clients/tools/ldapwhoami.c b/clients/tools/ldapwhoami.c index 82f187a55a..575e76a5d0 100644 --- a/clients/tools/ldapwhoami.c +++ b/clients/tools/ldapwhoami.c @@ -108,16 +108,18 @@ handle_private_option( int i ) int main( int argc, char *argv[] ) { - int rc; - char *user = NULL; + int rc; + char *user = NULL; - LDAP *ld = NULL; + LDAP *ld = NULL; - char *matcheddn = NULL, *text = NULL, **refs = NULL; - char *retoid = NULL; - struct berval *retdata = NULL; + char *matcheddn = NULL, *text = NULL, **refs = NULL; + char *retoid = NULL; + struct berval *retdata = NULL; + int id, code; + LDAPMessage *res; - tool_init(); + tool_init(); prog = lutil_progname( "ldapwhoami", argc, argv ); /* LDAPv3 only */ @@ -156,7 +158,51 @@ main( int argc, char *argv[] ) tool_server_controls( ld, NULL, 0 ); } - rc = ldap_whoami_s( ld, &retdata, NULL, NULL ); + rc = ldap_whoami( ld, NULL, NULL, &id ); + + if( rc != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_extended_operation" ); + rc = EXIT_FAILURE; + goto skip; + } + + for ( ; ; ) { + struct timeval tv; + + if ( tool_check_abandon( ld, id ) ) { + return LDAP_CANCELLED; + } + + tv.tv_sec = 0; + tv.tv_usec = 100000; + + rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res ); + if ( rc < 0 ) { + ldap_perror( ld, "ldapwhoami: ldap_result" ); + return rc; + } + + if ( rc != 0 ) { + break; + } + } + + rc = ldap_parse_result( ld, res, + &code, &matcheddn, &text, &refs, NULL, 0 ); + + if( rc != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_parse_result" ); + rc = EXIT_FAILURE; + goto skip; + } + + rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 ); + + if( rc != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_parse_result" ); + rc = EXIT_FAILURE; + goto skip; + } if( retdata != NULL ) { if( retdata->bv_len == 0 ) { diff --git a/doc/devel/args b/doc/devel/args index 5c637fc85e..cc7385bdc5 100644 --- a/doc/devel/args +++ b/doc/devel/args @@ -4,7 +4,7 @@ ldapdelete *CDE**HI*K M*OPQR UVWXYZ cdef*h**k *n*p* vwxy ldapmodify *CDE**HI*K M*OPQRS UVWXYZabcde *h**k *n*p*r t vwxy ldapmodrdn *CDE**HI*K M*OPQR UVWXYZ cdef*h**k *n*p*rs vwxy ldappasswd A*CDE**HI* *O QRS UVWXYZa def*h** * * * s vwxy -ldapsearch A*CDE**HI*KLM*OPQRSTUVWXYZabcdef*h**kl*n*p* stuvwxyz +ldapsearch A*CDE**HI*KLM*OPQRSTUVWXYZab def*h**kl*n*p* stuvwxyz ldapwhoami * DE**HI* *O QR UVWXYZ def*h** *n*p* vwxy diff --git a/doc/man/man1/ldapsearch.1 b/doc/man/man1/ldapsearch.1 index 1086110b01..cdb952bb67 100644 --- a/doc/man/man1/ldapsearch.1 +++ b/doc/man/man1/ldapsearch.1 @@ -9,8 +9,6 @@ ldapsearch \- LDAP search tool [\c .BR \-n ] [\c -.BR \-c ] -[\c .BR \-u ] [\c .BR \-v ] @@ -101,13 +99,6 @@ If no \fIattrs\fP are listed, all user attributes are returned. If only Show what would be done, but don't actually perform the search. Useful for debugging in conjunction with -v. .TP -.B \-c -Trap SIGINT and issue an -.B abandon -operation (if the switch appears once), or a -.B cancel -extended operation (if the switch appears twice). -.TP .B \-u Include the User Friendly Name form of the Distinguished Name (DN) in the output. -- 2.39.5