X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=clients%2Ftools%2Fldappasswd.c;h=a5cd3db7ae960a5a8113c11224ab93a6ea34606e;hb=4ecf780e48f3f73a62c8e61360d5b5e0548b3173;hp=c8337121baf0117809c358cd5f60a7d1e5c76c09;hpb=d5edb4bff62150cf35e8b9c59798017ff58febc0;p=openldap diff --git a/clients/tools/ldappasswd.c b/clients/tools/ldappasswd.c index c8337121ba..a5cd3db7ae 100644 --- a/clients/tools/ldappasswd.c +++ b/clients/tools/ldappasswd.c @@ -27,16 +27,29 @@ static void usage(const char *s) { fprintf(stderr, - "Usage: %s [options]\n" - " -D binddn\tbind dn\tREQUIRED\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" +"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" +" -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\trequest the use of TLS (-ZZ to make it critical)\n" , s ); exit( EXIT_FAILURE ); @@ -46,20 +59,35 @@ int main( int argc, char *argv[] ) { int rc; + char *ldaphost = NULL; + + char *dn = NULL; char *binddn = NULL; + char *bindpw = NULL; - char *ldaphost = NULL; char *newpw = NULL; + char *oldpw = NULL; + + int want_bindpw = 0; + int want_newpw = 0; + int want_oldpw = 0; + int noupdates = 0; - int i, j; + int i; int ldapport = 0; int debug = 0; int version = -1; - int want_bindpw = 0; + 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; LDAP *ld; - struct berval cred; struct berval *bv = NULL; - BerElement *ber; char *retoid; struct berval *retdata; @@ -68,9 +96,23 @@ main( int argc, char *argv[] ) usage (argv[0]); while( (i = getopt( argc, argv, - "D:d:h:np:s:vWw:" )) != EOF ) + "Aa:D: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 'D': /* bind distinguished name */ binddn = strdup (optarg); break; @@ -91,8 +133,20 @@ main( int argc, char *argv[] ) 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 */ @@ -105,6 +159,7 @@ main( int argc, char *argv[] ) case 'w': /* bind password */ bindpw = strdup (optarg); + { char* p; @@ -114,13 +169,93 @@ main( int argc, char *argv[] ) } 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 ); +#endif + break; + case 'Y': +#ifdef HAVE_CYRUS_SASL + if ( strcasecmp( optarg, "any" ) && + strcmp( optarg, "*" ) ) { + sasl_mech = 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 '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; default: usage (argv[0]); } } - if( newpw == NULL ) { + if( argc - optind != 1 ) { + usage( argv[0] ); + } + + dn = strdup( argv[optind] ); + + if( want_oldpw && oldpw == NULL ) { + /* prompt for old password */ + char *ckoldpw; + newpw = strdup(getpass("Old password: ")); + ckoldpw = getpass("Re-enter old password: "); + + if( strncmp( oldpw, ckoldpw, strlen(oldpw) )) { + fprintf( stderr, "passwords do not match\n" ); + return EXIT_FAILURE; + } + } + + if( want_newpw && newpw == NULL ) { /* prompt for new password */ char *cknewpw; newpw = strdup(getpass("New password: ")); @@ -132,13 +267,15 @@ main( int argc, char *argv[] ) } } - if( binddn == NULL ) { - fprintf( stderr, "no bind DN specified\n" ); - return EXIT_FAILURE; + if( binddn == NULL && dn != NULL ) { + binddn = dn; + dn = NULL; + + if( bindpw == NULL ) bindpw = oldpw; } - /* handle bind password */ - if (want_bindpw) { + if (want_bindpw && bindpw == NULL ) { + /* handle bind password */ fprintf( stderr, "Bind DN: %s\n", binddn ); bindpw = strdup( getpass("Enter bind password: ")); } @@ -165,6 +302,7 @@ main( int argc, char *argv[] ) /* don't chase referrals */ ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF ); + /* LDAPv3 only */ version = 3; rc = ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); @@ -172,36 +310,101 @@ main( int argc, char *argv[] ) fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version ); } - rc = ldap_bind_s( ld, binddn, bindpw, LDAP_AUTH_SIMPLE ); + if ( use_tls && ldap_start_tls( ld, NULL, NULL ) != LDAP_SUCCESS ) { + if ( use_tls > 1 ) { + ldap_perror( ld, "ldap_start_tls" ); + return( EXIT_FAILURE ); + } + } - if ( rc != LDAP_SUCCESS ) { - ldap_perror( ld, "ldap_bind" ); - ldap_unbind( ld ); - return EXIT_FAILURE; + 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 ); + } + + if ( ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id, + sasl_authz_id, sasl_mech, NULL, NULL, NULL ) + != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_sasl_bind" ); + 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, bindpw, authmethod ) + != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_bind" ); + return( EXIT_FAILURE ); + } } - /* build change password control */ - ber = ber_alloc_t( LBER_USE_DER ); + if( dn != NULL || oldpw != NULL || newpw != NULL ) { + /* build change password control */ + BerElement *ber = ber_alloc_t( LBER_USE_DER ); - if( ber == NULL ) { - perror( "ber_alloc_t" ); - ldap_unbind( ld ); - return EXIT_FAILURE; - } + if( ber == NULL ) { + perror( "ber_alloc_t" ); + ldap_unbind( ld ); + return EXIT_FAILURE; + } - ber_printf( ber, "{es}", - (ber_int_t) 0, - newpw ); + ber_printf( ber, "{" /*}*/ ); - rc = ber_flatten( ber, &bv ); + if( dn != NULL ) { + ber_printf( ber, "ts", + LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID, dn ); + free(dn); + } - if( rc < 0 ) { - perror( "ber_flatten" ); - ldap_unbind( ld ); - return EXIT_FAILURE; - } + if( oldpw != NULL ) { + ber_printf( ber, "ts", + LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, oldpw ); + free(oldpw); + } + + if( newpw != NULL ) { + ber_printf( ber, "ts", + LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw ); + free(newpw); + } + + ber_printf( ber, /*{*/ "}" ); + + rc = ber_flatten( ber, &bv ); + + if( rc < 0 ) { + perror( "ber_flatten" ); + ldap_unbind( ld ); + return EXIT_FAILURE; + } - ber_free( ber, 1 ); + ber_free( ber, 1 ); + } rc = ldap_extended_operation_s( ld, LDAP_EXOP_X_MODIFY_PASSWD, bv, @@ -210,6 +413,30 @@ main( int argc, char *argv[] ) ber_bvfree( bv ); + if( retdata != NULL ) { + ber_tag_t tag; + char *s; + BerElement *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 ); + } + if ( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_extended_operation" ); ldap_unbind( ld ); @@ -222,5 +449,5 @@ main( int argc, char *argv[] ) /* disconnect from server */ ldap_unbind (ld); - return ( EXIT_SUCCESS ); + return EXIT_SUCCESS; }