X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=clients%2Ftools%2Fldappasswd.c;h=a0265f4ebdc5fa9b8e7dbc0b48898c7fe9c20d0a;hb=626830b5adf4c048edc3ecd7c5cf48ab1fa8b495;hp=ad084ae8cf6f910525cf5a8083bd83da2cd8df9f;hpb=1a862732eee6c21cf97d9b58570a1e0e4587d5c4;p=openldap diff --git a/clients/tools/ldappasswd.c b/clients/tools/ldappasswd.c index ad084ae8cf..a0265f4ebd 100644 --- a/clients/tools/ldappasswd.c +++ b/clients/tools/ldappasswd.c @@ -1,6 +1,6 @@ /* $OpenLDAP$ */ /* - * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ @@ -11,250 +11,154 @@ #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, -"Change the password of an LDAP entry\n\n" -"usage: %s [options] dn\n" -" dn: the DN of the entry whose password must be changed\n" -"options:\n" -" -a secret\told password\n" -" -A\t\tprompt for old password\n" -" -d level\tdebugging level\n" -" -C\t\tchase referrals\n" -" -D binddn\tbind DN\n" -" -E\t\trequest SASL privacy (-EE to make it critical)\n" -" -h host\t\tLDAP server (default: localhost)\n" -" -I\t\trequest SASL integrity checking (-II to make it\n" -" \tcritical)\n" -" -n\t\tmake no modifications\n" -" -p port\t\tport on LDAP server\n" -" -S\t\tprompt for new password\n" -" -s secret\tnew password\n" -" -U user\t\tSASL authentication identity (username)\n" -" -v\t\tverbose mode\n" -" -w passwd\tbind password (for simple authentication)\n" -" -W\t\tprompt for bind password\n" -" -X id\t\tSASL authorization identity (\"dn:\" or \"u:\")\n" -" -Y mech\t\tSASL mechanism\n" -" -Z\t\tissue Start TLS request (-ZZ to require successful response)\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 -main( int argc, char *argv[] ) +handle_private_option( int i ) { - int rc; - char *ldaphost = NULL; - - char *dn = NULL; - char *binddn = NULL; - - struct berval passwd = { 0, NULL}; - char *newpw = NULL; - char *oldpw = NULL; - - int want_bindpw = 0; - int want_newpw = 0; - int want_oldpw = 0; - - int noupdates = 0; - int i; - int ldapport = 0; - int debug = 0; - int version = -1; - int authmethod = LDAP_AUTH_SIMPLE; -#ifdef HAVE_CYRUS_SASL - char *sasl_authc_id = NULL; - char *sasl_authz_id = NULL; - char *sasl_mech = NULL; - int sasl_integrity = 0; - int sasl_privacy = 0; -#endif - int use_tls = 0; - int referrals = 0; - LDAP *ld; - struct berval *bv = NULL; - - char *retoid; - struct berval *retdata; - - if (argc == 1) - usage (argv[0]); - - while( (i = getopt( argc, argv, - "Aa:CD:d:EIh:np:Ss:U:vWw:X:Y:Z" )) != EOF ) - { - switch (i) { - case 'A': /* prompt for oldr password */ - want_oldpw++; - break; - case 'a': /* old password (secret) */ - oldpw = strdup (optarg); - - { - char* p; - - for( p = optarg; *p == '\0'; p++ ) { - *p = '*'; - } - } - break; - case 'C': - referrals++; - break; - 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': /* prompt for user password */ - want_newpw++; - break; - - case 's': /* new password (secret) */ - newpw = strdup (optarg); - { - char* p; - - for( p = optarg; *p == '\0'; p++ ) { - *p = '*'; - } - } - break; - - case 'v': /* verbose */ - verbose++; - break; + 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 ); + } - case 'W': /* prompt for bind password */ - want_bindpw++; - break; + /* should be extended to support comma separated list of + * [!]key[=value] parameters, e.g. -E !foo,bar=567 + */ - case 'w': /* bind password */ - passwd.bv_val = strdup (optarg); - { - char* p; + crit = 0; + cvalue = NULL; + if( optarg[0] == '!' ) { + crit = 1; + optarg++; + } - for( p = optarg; *p == '\0'; p++ ) { - *p = '*'; - } - } - passwd.bv_len = strlen( passwd.bv_val ); - break; - - case 'I': -#ifdef HAVE_CYRUS_SASL - sasl_integrity++; - authmethod = LDAP_AUTH_SASL; -#else - fprintf( stderr, "%s was not compiled with SASL " - "support\n", argv[0] ); - return( EXIT_FAILURE ); -#endif - break; - case 'E': -#ifdef HAVE_CYRUS_SASL - sasl_privacy++; - authmethod = LDAP_AUTH_SASL; -#else - fprintf( stderr, "%s was not compiled with SASL " - "support\n", argv[0] ); - return( EXIT_FAILURE ); + control = strdup( optarg ); + if ( (cvalue = strchr( control, '=' )) != NULL ) { + *cvalue++ = '\0'; + } + fprintf( stderr, "Invalid passwd control name: %s\n", control ); + usage(); #endif - break; - case 'Y': -#ifdef HAVE_CYRUS_SASL - if ( strcasecmp( optarg, "any" ) && - strcmp( optarg, "*" ) ) { - sasl_mech = strdup( optarg ); + + case 'a': /* old password (secret) */ + oldpw = strdup (optarg); + + { + char* p; + for( p = optarg; *p != '\0'; p++ ) { + *p = '\0'; } - authmethod = LDAP_AUTH_SASL; -#else - fprintf( stderr, "%s was not compiled with SASL " - "support\n", argv[0] ); - return( EXIT_FAILURE ); -#endif - break; - case 'U': -#ifdef HAVE_CYRUS_SASL - sasl_authc_id = strdup( optarg ); - authmethod = LDAP_AUTH_SASL; -#else - fprintf( stderr, "%s was not compiled with SASL " - "support\n", argv[0] ); - return( EXIT_FAILURE ); -#endif - break; - case 'X': -#ifdef HAVE_CYRUS_SASL - sasl_authz_id = strdup( optarg ); - authmethod = LDAP_AUTH_SASL; -#else - fprintf( stderr, "%s was not compiled with SASL " - "support\n", argv[0] ); - return( EXIT_FAILURE ); -#endif - break; - case 'Z': -#ifdef HAVE_TLS - use_tls++; -#else - fprintf( stderr, "%s was not compiled with TLS " - "support\n", argv[0] ); - return( EXIT_FAILURE ); -#endif - break; + } + break; + + case 'A': /* prompt for old password */ + want_oldpw++; + break; - default: - usage (argv[0]); + 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 *user = NULL; + + LDAP *ld = NULL; + struct berval bv = {0, NULL}; + BerElement *ber = NULL; + + 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; - if( argc - optind != 1 ) { - usage( argv[0] ); - } + tool_args( argc, argv ); - dn = strdup( argv[optind] ); + if( argc - optind > 1 ) { + usage(); + } else if ( argc - optind == 1 ) { + user = strdup( argv[optind] ); + } else { + user = NULL; + } if( want_oldpw && oldpw == NULL ) { /* prompt for old password */ char *ckoldpw; - newpw = strdup(getpassphrase("Old password: ")); + oldpw = strdup(getpassphrase("Old password: ")); ckoldpw = getpassphrase("Re-enter old password: "); - if( newpw== NULL || ckoldpw == NULL || - strncmp( oldpw, ckoldpw, strlen(oldpw) )) + if( oldpw== NULL || ckoldpw == NULL || + strcmp( oldpw, ckoldpw )) { fprintf( stderr, "passwords do not match\n" ); return EXIT_FAILURE; @@ -268,127 +172,29 @@ main( int argc, char *argv[] ) cknewpw = getpassphrase("Re-enter new password: "); if( newpw== NULL || cknewpw == NULL || - strncmp( newpw, cknewpw, strlen(newpw) )) + strcmp( newpw, cknewpw )) { fprintf( stderr, "passwords do not match\n" ); return EXIT_FAILURE; } } - if( binddn == NULL && dn != NULL ) { - binddn = dn; - dn = NULL; - - if( passwd.bv_val == NULL ) { - passwd.bv_val = oldpw; - passwd.bv_len = oldpw == NULL ? 0 : strlen( oldpw ); - } - } - if (want_bindpw && passwd.bv_val == NULL ) { /* handle bind password */ - fprintf( stderr, "Bind DN: %s\n", binddn ); passwd.bv_val = strdup( getpassphrase("Enter bind password: ")); passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 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 ); - } - 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 ); - } - } - -#ifdef SIGPIPE - (void) SIGNAL( SIGPIPE, SIG_IGN ); -#endif + ld = tool_conn_setup( 0, 0 ); - /* connect to server */ - if ((ld = ldap_init( ldaphost, ldapport )) == NULL) { - perror("ldap_init"); - return EXIT_FAILURE; - } + tool_bind( ld ); - /* referrals */ - if (ldap_set_option( ld, LDAP_OPT_REFERRALS, - referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS ) - { - fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n", - referrals ? "on" : "off" ); - return EXIT_FAILURE; - } - - /* LDAPv3 only */ - version = 3; - rc = ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); - - if(rc != LDAP_OPT_SUCCESS ) { - fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version ); - return EXIT_FAILURE; - } + if ( authzid || manageDSAit || noop ) + tool_server_controls( ld, NULL, 0 ); - if ( use_tls && ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS ) { - if ( use_tls > 1 ) { - ldap_perror( ld, "ldap_start_tls" ); - return( EXIT_FAILURE ); - } - fprintf( stderr, "WARNING: could not start TLS\n" ); - } - - if ( authmethod == LDAP_AUTH_SASL ) { -#ifdef HAVE_CYRUS_SASL - int minssf = 0, maxssf = 0; - - if ( sasl_integrity > 0 ) - maxssf = 1; - if ( sasl_integrity > 1 ) - minssf = 1; - if ( sasl_privacy > 0 ) - maxssf = 100000; /* Something big value */ - if ( sasl_privacy > 1 ) - minssf = 56; - - if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF, - (void *)&minssf ) != LDAP_OPT_SUCCESS ) { - fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF" - "%d\n", minssf); - return( EXIT_FAILURE ); - } - if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF, - (void *)&maxssf ) != LDAP_OPT_SUCCESS ) { - fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MAXSSF" - "%d\n", maxssf); - return( EXIT_FAILURE ); - } - - rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id, - sasl_authz_id, sasl_mech, - passwd.bv_len ? &passwd : NULL, - NULL, NULL ); - - if( rc != LDAP_SUCCESS ) { - ldap_perror( ld, "ldap_negotiated_sasl_bind_s" ); - return( EXIT_FAILURE ); - } -#else - fprintf( stderr, "%s was not compiled with SASL support\n", - argv[0] ); - return( EXIT_FAILURE ); -#endif - } - else { - if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod ) - != LDAP_SUCCESS ) { - ldap_perror( ld, "ldap_bind" ); - return( EXIT_FAILURE ); - } - } - - if( dn != NULL || oldpw != NULL || newpw != NULL ) { + if( user != NULL || oldpw != NULL || newpw != NULL ) { /* build change password control */ - BerElement *ber = ber_alloc_t( LBER_USE_DER ); + ber = ber_alloc_t( LBER_USE_DER ); if( ber == NULL ) { perror( "ber_alloc_t" ); @@ -398,48 +204,76 @@ main( int argc, char *argv[] ) ber_printf( ber, "{" /*}*/ ); - if( dn != NULL ) { + if( user != NULL ) { ber_printf( ber, "ts", - LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID, dn ); - free(dn); + LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user ); + free(user); } if( oldpw != NULL ) { ber_printf( ber, "ts", - LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, oldpw ); + LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, oldpw ); free(oldpw); } if( newpw != NULL ) { ber_printf( ber, "ts", - LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw ); + LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, newpw ); free(newpw); } ber_printf( ber, /*{*/ "N}" ); - rc = ber_flatten( ber, &bv ); + rc = ber_flatten2( ber, &bv, 0 ); if( rc < 0 ) { - perror( "ber_flatten" ); + perror( "ber_flatten2" ); ldap_unbind( ld ); return EXIT_FAILURE; } + } - ber_free( ber, 1 ); + if ( not ) { + rc = LDAP_SUCCESS; + goto skip; + } + + rc = ldap_extended_operation( ld, + LDAP_EXOP_MODIFY_PASSWD, bv.bv_val ? &bv : NULL, + NULL, NULL, &id ); + + ber_free( ber, 1 ); + + if( rc != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_extended_operation" ); + ldap_unbind( ld ); + return EXIT_FAILURE; + } + + rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res ); + if ( rc < 0 ) { + ldap_perror( ld, "ldappasswd: ldap_result" ); + return rc; + } + + rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 0 ); + + if( rc != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_parse_result" ); + return rc; } - rc = ldap_extended_operation_s( ld, - LDAP_EXOP_X_MODIFY_PASSWD, bv, - NULL, NULL, - &retoid, &retdata ); + rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 ); - ber_bvfree( bv ); + if( rc != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_parse_result" ); + return rc; + } if( retdata != NULL ) { ber_tag_t tag; char *s; - BerElement *ber = ber_init( retdata ); + ber = ber_init( retdata ); if( ber == NULL ) { perror( "ber_init" ); @@ -460,17 +294,34 @@ main( int argc, char *argv[] ) ber_free( ber, 1 ); } - if ( rc != LDAP_SUCCESS ) { - ldap_perror( ld, "ldap_extended_operation" ); - ldap_unbind( ld ); - return EXIT_FAILURE; + if( verbose || code != LDAP_SUCCESS || matcheddn || text || refs ) { + printf( "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] ); + } + } } - 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; }