X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=clients%2Ftools%2Fldappasswd.c;h=a0265f4ebdc5fa9b8e7dbc0b48898c7fe9c20d0a;hb=626830b5adf4c048edc3ecd7c5cf48ab1fa8b495;hp=5e9737347976ea81bb7e03cbe0fd4aa90e5e129e;hpb=354d0d5b508666af7fa4e3135c2b3a980b17c422;p=openldap diff --git a/clients/tools/ldappasswd.c b/clients/tools/ldappasswd.c index 5e97373479..a0265f4ebd 100644 --- a/clients/tools/ldappasswd.c +++ b/clients/tools/ldappasswd.c @@ -1,6 +1,6 @@ /* $OpenLDAP$ */ /* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ @@ -11,232 +11,317 @@ #include #include -#include #include #include #include #include #include - +#include "lutil.h" +#include "lutil_ldap.h" #include "ldap_defaults.h" -static int verbose = 0; +#include "common.h" + + +static char *newpw = NULL; +static char *oldpw = NULL; +static int want_newpw = 0; +static int want_oldpw = 0; -static void -usage(const char *s) + +void +usage( void ) { fprintf(stderr, - "Usage: %s [options] dn\n" - " -D binddn\tbind dn\n" - " -d level\tdebugging level\n" - " -h host\tldap server (default: localhost)\n" - " -n\t\tmake no modifications\n" - " -p port\tldap port\n" - " -s secret\tnew password\n" - " -v\t\tincrease verbosity\n" - " -W\t\tprompt for bind password\n" - " -w passwd\tbind password (for simple authentication)\n" - , s ); - +"Change password of an LDAP user\n\n" +"usage: %s [options] [user]\n" +" user: the autentication identity, commonly a DN\n" +"Password change options:\n" +" -a secret old password\n" +" -A prompt for old password\n" +" -s secret new password\n" +" -S prompt for new password\n" + , prog ); + tool_common_usage(); exit( EXIT_FAILURE ); } + +const char options[] = "a:As:S" + "Cd:D:e:h:H:InO:p:QR:U:vVw:WxX:Y:Z"; + +int +handle_private_option( int i ) +{ + switch ( i ) { +#if 0 + int crit; + char *control, *cvalue; + case 'E': /* passwd controls */ + if( protocol == LDAP_VERSION2 ) { + fprintf( stderr, "%s: -E incompatible with LDAPv%d\n", + prog, protocol ); + exit( EXIT_FAILURE ); + } + + /* should be extended to support comma separated list of + * [!]key[=value] parameters, e.g. -E !foo,bar=567 + */ + + crit = 0; + cvalue = NULL; + if( optarg[0] == '!' ) { + crit = 1; + optarg++; + } + + control = strdup( optarg ); + if ( (cvalue = strchr( control, '=' )) != NULL ) { + *cvalue++ = '\0'; + } + fprintf( stderr, "Invalid passwd control name: %s\n", control ); + usage(); +#endif + + case 'a': /* old password (secret) */ + oldpw = strdup (optarg); + + { + char* p; + for( p = optarg; *p != '\0'; p++ ) { + *p = '\0'; + } + } + break; + + case 'A': /* prompt for old password */ + want_oldpw++; + break; + + case 's': /* new password (secret) */ + newpw = strdup (optarg); + { + char* p; + for( p = optarg; *p != '\0'; p++ ) { + *p = '\0'; + } + } + break; + + case 'S': /* prompt for user password */ + want_newpw++; + break; + + default: + return 0; + } + return 1; +} + + int main( int argc, char *argv[] ) { int rc; - char *dn = NULL; - char *binddn = NULL; - char *bindpw = NULL; - char *ldaphost = NULL; - char *newpw = NULL; - int noupdates = 0; - int i; - int ldapport = 0; - int debug = 0; - int version = -1; - int want_bindpw = 0; - LDAP *ld; - struct berval *bv = NULL; - BerElement *ber; - - char *retoid; - struct berval *retdata; - - if (argc == 1) - usage (argv[0]); - - while( (i = getopt( argc, argv, - "D:d:h:np:s:vWw:" )) != EOF ) - { - switch (i) { - case 'D': /* bind distinguished name */ - binddn = strdup (optarg); - break; - - case 'd': /* debugging option */ - debug |= atoi (optarg); - break; - - case 'h': /* ldap host */ - ldaphost = strdup (optarg); - break; - - case 'n': /* don't update entry(s) */ - noupdates++; - break; - - case 'p': /* ldap port */ - ldapport = strtol( optarg, NULL, 10 ); - break; - - case 's': /* new password (secret) */ - newpw = strdup (optarg); - break; - - case 'v': /* verbose */ - verbose++; - break; - - case 'W': /* prompt for bind password */ - want_bindpw++; - break; - - case 'w': /* bind password */ - bindpw = strdup (optarg); - { - char* p; - - for( p = optarg; *p == '\0'; p++ ) { - *p = '*'; - } - } - break; + char *user = NULL; + LDAP *ld = NULL; + struct berval bv = {0, NULL}; + BerElement *ber = NULL; - default: - usage (argv[0]); - } + int id, code = LDAP_OTHER; + LDAPMessage *res; + char *matcheddn = NULL, *text = NULL, **refs = NULL; + char *retoid = NULL; + struct berval *retdata = NULL; + + prog = lutil_progname( "ldappasswd", argc, argv ); + + /* LDAPv3 only */ + protocol = LDAP_VERSION3; + + tool_args( argc, argv ); + + if( argc - optind > 1 ) { + usage(); + } else if ( argc - optind == 1 ) { + user = strdup( argv[optind] ); + } else { + user = NULL; } - if( argc - optind != 1 ) { - usage( argv[0] ); - } + if( want_oldpw && oldpw == NULL ) { + /* prompt for old password */ + char *ckoldpw; + oldpw = strdup(getpassphrase("Old password: ")); + ckoldpw = getpassphrase("Re-enter old password: "); - dn = strdup( argv[optind] ); + if( oldpw== NULL || ckoldpw == NULL || + strcmp( oldpw, ckoldpw )) + { + fprintf( stderr, "passwords do not match\n" ); + return EXIT_FAILURE; + } + } - if( newpw == NULL ) { + if( want_newpw && newpw == NULL ) { /* prompt for new password */ char *cknewpw; - newpw = strdup(getpass("New password: ")); - cknewpw = getpass("Re-enter new password: "); + newpw = strdup(getpassphrase("New password: ")); + cknewpw = getpassphrase("Re-enter new password: "); - if( strncmp( newpw, cknewpw, strlen(newpw) )) { + if( newpw== NULL || cknewpw == NULL || + strcmp( newpw, cknewpw )) + { fprintf( stderr, "passwords do not match\n" ); return EXIT_FAILURE; } } - if( binddn == NULL ) { - binddn = dn; - dn = NULL; + if (want_bindpw && passwd.bv_val == NULL ) { + /* handle bind password */ + passwd.bv_val = strdup( getpassphrase("Enter bind password: ")); + passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0; } - /* handle bind password */ - if (want_bindpw) { - fprintf( stderr, "Bind DN: %s\n", binddn ); - bindpw = strdup( getpass("Enter bind password: ")); - } + ld = tool_conn_setup( 0, 0 ); - if ( debug ) { - if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) { - fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug ); + tool_bind( ld ); + + if ( authzid || manageDSAit || noop ) + tool_server_controls( ld, NULL, 0 ); + + if( user != NULL || oldpw != NULL || newpw != NULL ) { + /* build change password control */ + ber = ber_alloc_t( LBER_USE_DER ); + + if( ber == NULL ) { + perror( "ber_alloc_t" ); + ldap_unbind( ld ); + return EXIT_FAILURE; } - if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) { - fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug ); + + ber_printf( ber, "{" /*}*/ ); + + if( user != NULL ) { + ber_printf( ber, "ts", + LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user ); + free(user); } - } -#ifdef SIGPIPE - (void) SIGNAL( SIGPIPE, SIG_IGN ); -#endif + if( oldpw != NULL ) { + ber_printf( ber, "ts", + LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, oldpw ); + free(oldpw); + } - /* connect to server */ - if ((ld = ldap_init( ldaphost, ldapport )) == NULL) { - perror("ldap_init"); - return EXIT_FAILURE; - } + if( newpw != NULL ) { + ber_printf( ber, "ts", + LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, newpw ); + free(newpw); + } - /* don't chase referrals */ - ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF ); + ber_printf( ber, /*{*/ "N}" ); - version = 3; - rc = ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); + rc = ber_flatten2( ber, &bv, 0 ); - if(rc != LDAP_OPT_SUCCESS ) { - fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version ); + if( rc < 0 ) { + perror( "ber_flatten2" ); + ldap_unbind( ld ); + return EXIT_FAILURE; + } } - rc = ldap_bind_s( ld, binddn, bindpw, LDAP_AUTH_SIMPLE ); - - if ( rc != LDAP_SUCCESS ) { - ldap_perror( ld, "ldap_bind" ); - ldap_unbind( ld ); - return EXIT_FAILURE; + if ( not ) { + rc = LDAP_SUCCESS; + goto skip; } - /* build change password control */ - ber = ber_alloc_t( LBER_USE_DER ); + rc = ldap_extended_operation( ld, + LDAP_EXOP_MODIFY_PASSWD, bv.bv_val ? &bv : NULL, + NULL, NULL, &id ); - if( ber == NULL ) { - perror( "ber_alloc_t" ); + ber_free( ber, 1 ); + + if( rc != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_extended_operation" ); ldap_unbind( ld ); return EXIT_FAILURE; } - if( dn != NULL ) { - ber_printf( ber, "{tsts}", - LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID, dn, - LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw ); + rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res ); + if ( rc < 0 ) { + ldap_perror( ld, "ldappasswd: ldap_result" ); + return rc; + } - free(dn); + rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 0 ); - } else { - ber_printf( ber, "{ts}", - LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw ); + if( rc != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_parse_result" ); + return rc; } - free(newpw); + rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 ); - rc = ber_flatten( ber, &bv ); + if( rc != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_parse_result" ); + return rc; + } - if( rc < 0 ) { - perror( "ber_flatten" ); - ldap_unbind( ld ); - return EXIT_FAILURE; + if( retdata != NULL ) { + ber_tag_t tag; + char *s; + ber = ber_init( retdata ); + + if( ber == NULL ) { + perror( "ber_init" ); + ldap_unbind( ld ); + return EXIT_FAILURE; + } + + /* we should check the tag */ + tag = ber_scanf( ber, "{a}", &s); + + if( tag == LBER_ERROR ) { + perror( "ber_scanf" ); + } else { + printf("New password: %s\n", s); + free( s ); + } + + ber_free( ber, 1 ); } - ber_free( ber, 1 ); + if( verbose || code != LDAP_SUCCESS || matcheddn || text || refs ) { + printf( "Result: %s (%d)\n", ldap_err2string( code ), code ); - rc = ldap_extended_operation_s( ld, - LDAP_EXOP_X_MODIFY_PASSWD, bv, - NULL, NULL, - &retoid, &retdata ); + if( text && *text ) { + printf( "Additional info: %s\n", text ); + } - ber_bvfree( bv ); + if( matcheddn && *matcheddn ) { + printf( "Matched DN: %s\n", matcheddn ); + } - if ( rc != LDAP_SUCCESS ) { - ldap_perror( ld, "ldap_extended_operation" ); - ldap_unbind( ld ); - return EXIT_FAILURE; + if( refs ) { + int i; + for( i=0; refs[i]; i++ ) { + printf("Referral: %s\n", refs[i] ); + } + } } - ldap_memfree( retoid ); + ber_memfree( text ); + ber_memfree( matcheddn ); + ber_memvfree( (void **) refs ); + ber_memfree( retoid ); ber_bvfree( retdata ); +skip: /* disconnect from server */ ldap_unbind (ld); - return ( EXIT_SUCCESS ); + return code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE; }