diff options
author | Sam Hartman <hartmans@mit.edu> | 2003-04-25 18:50:04 +0000 |
---|---|---|
committer | Sam Hartman <hartmans@mit.edu> | 2003-04-25 18:50:04 +0000 |
commit | ec50322c3076ab4517fb4fb5cc3a931f6adb4f20 (patch) | |
tree | d6819f6614b1530875d5d9b6ccc2ca64afe6e69f /src/clients | |
parent | dffb4a9da42dec49abe7ebae9501814ed493cf23 (diff) | |
download | krb5-ec50322c3076ab4517fb4fb5cc3a931f6adb4f20.tar.gz krb5-ec50322c3076ab4517fb4fb5cc3a931f6adb4f20.tar.xz krb5-ec50322c3076ab4517fb4fb5cc3a931f6adb4f20.zip |
Build ksetpw, a client for the Microsoft set password protocol. Not
of release quality yet, so don't actually install.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15374 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/clients')
-rw-r--r-- | src/clients/kpasswd/ChangeLog | 6 | ||||
-rw-r--r-- | src/clients/kpasswd/Makefile.in | 8 | ||||
-rw-r--r-- | src/clients/kpasswd/ksetpwd.c | 312 |
3 files changed, 324 insertions, 2 deletions
diff --git a/src/clients/kpasswd/ChangeLog b/src/clients/kpasswd/ChangeLog index 1019de41c..ac31dda99 100644 --- a/src/clients/kpasswd/ChangeLog +++ b/src/clients/kpasswd/ChangeLog @@ -1,3 +1,9 @@ +2003-04-25 Sam Hartman <hartmans@mit.edu> + + * Makefile.in : Add rule to build ksetpw, a set/change password + client for the Microsoft protocol. We do not install this program + by default because it is not of release quality yet. + 2003-02-25 Tom Yu <tlyu@mit.edu> * kpasswd.c (main): Don't pass a NULL pointer to printf(). diff --git a/src/clients/kpasswd/Makefile.in b/src/clients/kpasswd/Makefile.in index 89c134028..3f6394342 100644 --- a/src/clients/kpasswd/Makefile.in +++ b/src/clients/kpasswd/Makefile.in @@ -8,12 +8,16 @@ PROG_RPATH=$(KRB5_LIBDIR) kpasswd: kpasswd.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o kpasswd kpasswd.o $(KRB5_BASE_LIBS) +ksetpwd: ksetpwd.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o ksetpwd ksetpwd.o $(KRB5_BASE_LIBS) + kpasswd.o: $(srcdir)/kpasswd.c +ksetpwd.o: $(srcdir)/ksetpwd.c -all-unix:: kpasswd +all-unix:: kpasswd ksetpwd clean-unix:: - $(RM) kpasswd.o kpasswd + $(RM) kpasswd.o kpasswd ksetpwd.o ksetpwd install-all install-kdc install-server install-client install-unix:: $(INSTALL_PROGRAM) kpasswd $(DESTDIR)$(CLIENT_BINDIR)/`echo kpasswd|sed '$(transform)'` diff --git a/src/clients/kpasswd/ksetpwd.c b/src/clients/kpasswd/ksetpwd.c new file mode 100644 index 000000000..7b72b3659 --- /dev/null +++ b/src/clients/kpasswd/ksetpwd.c @@ -0,0 +1,312 @@ +#include <krb5.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> + +#define TKTTIMELEFT 60*10 /* ten minutes */ + +int verify_creds() +{ + krb5_context kcontext; + krb5_ccache ccache; + krb5_error_code kres; + + kres = krb5_init_context(&kcontext); + if( kres == 0 ) + { + kres = krb5_cc_default( kcontext, &ccache ); + if( kres == 0 ) + { + krb5_principal user_princ; + + kres = krb5_cc_get_principal( kcontext, ccache, &user_princ ); + if( kres == 0 ) + krb5_free_principal( kcontext, user_princ ); + krb5_cc_close( kcontext, ccache ); + } + krb5_free_context(kcontext); + } + return kres; +} + +void get_init_creds_opt_init( krb5_get_init_creds_opt *outOptions ) +{ + krb5_preauthtype preauth[] = { KRB5_PADATA_ENC_TIMESTAMP }; + krb5_enctype etypes[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_CRC}; + memset( outOptions, 0, sizeof(*outOptions) ); + krb5_get_init_creds_opt_init(outOptions); + krb5_get_init_creds_opt_set_address_list(outOptions, NULL); + krb5_get_init_creds_opt_set_etype_list( outOptions, etypes, sizeof(etypes)/sizeof(krb5_enctype) ); + krb5_get_init_creds_opt_set_preauth_list(outOptions, preauth, sizeof(preauth)/sizeof(krb5_preauthtype) ); +} + +typedef void * kbrccache_t; +#define CCACHE_PREFIX_DEFAULT "MEMORY:C_" + +kbrccache_t userinitcontext( + const char * user, const char * domain, const char * passwd, const char * cachename, int initialize, + int * outError ) +{ + krb5_context kcontext = 0; + krb5_ccache kcache = 0; + krb5_creds kcreds; + krb5_principal kme = 0; + krb5_error_code kres; + char * pPass = strdup( passwd ); + char * pName = NULL; + char * pCacheName = NULL; + int numCreds = 0; + + memset( &kcreds, 0, sizeof(kcreds) ); + kres = krb5_init_context( &kcontext ); + if( kres ) + goto return_error; + if( domain ) + kres = krb5_build_principal( kcontext, &kme, strlen(domain), domain, user, 0 ); + else + kres = krb5_parse_name( kcontext, user, &kme ); + if( kres ) + goto fail; + krb5_unparse_name( kcontext, kme, &pName ); + if( cachename ) + { + pCacheName = malloc( strlen( pName ) + strlen( cachename ) + 1 ); + if( pCacheName == NULL ) + { + kres = KRB5_CC_NOMEM; + goto fail; + } + strcpy( pCacheName, cachename ); + strcat( pCacheName, pName ); + kres = krb5_cc_resolve( kcontext, pCacheName, &kcache ); + if( kres ) + { + kres = krb5_cc_resolve( kcontext, CCACHE_PREFIX_DEFAULT, &kcache ); + if( kres == 0 ) + pCacheName = strdup(CCACHE_PREFIX_DEFAULT); + } + } + else + { + kres = krb5_cc_default( kcontext, &kcache ); + pCacheName = strdup( krb5_cc_get_name( kcontext, kcache ) ); + } + if( kres ) + { + krb5_free_context(kcontext); + goto return_error; + } + if( initialize ) + krb5_cc_initialize( kcontext, kcache, kme ); + if( kres == 0 && user && passwd ) + { + long timeneeded = time(0L) +TKTTIMELEFT; + int have_credentials = 0; + krb5_cc_cursor cc_curs = NULL; + numCreds = 0; + if( (kres=krb5_cc_start_seq_get(kcontext, kcache, &cc_curs)) >= 0 ) + { + while( (kres=krb5_cc_next_cred(kcontext, kcache, &cc_curs, &kcreds))== 0) + { + numCreds++; + if( krb5_principal_compare( kcontext, kme, kcreds.client ) ) + { + if( kcreds.ticket_flags & TKT_FLG_INITIAL && kcreds.times.endtime>timeneeded ) + have_credentials = 1; + } + krb5_free_cred_contents( kcontext, &kcreds ); + if( have_credentials ) + break; + } + krb5_cc_end_seq_get( kcontext, kcache, &cc_curs ); + } + else + { + const char * errmsg = error_message(kres); + fprintf( stderr, "%s user init(%s): %s\n", "setpass", pName, errmsg ); + } + if( kres != 0 || have_credentials == 0 ) + { + krb5_get_init_creds_opt options; + get_init_creds_opt_init(&options); +/* +** no valid credentials - get new ones +*/ + kres = krb5_get_init_creds_password( kcontext, &kcreds, kme, pPass, + NULL /*prompter*/, + NULL /*data*/, + 0 /*starttime*/, + 0 /*in_tkt_service*/, + &options /*options*/ ); + if( kres == 0 ) + { + if( numCreds <= 0 ) + kres = krb5_cc_initialize( kcontext, kcache, kme ); + if( kres == 0 ) + kres = krb5_cc_store_cred( kcontext, kcache, &kcreds ); + if( kres == 0 ) + have_credentials = 1; + } + } +#ifdef NOTUSED + if( have_credentials ) + { + int mstat; + kres = gss_krb5_ccache_name( &mstat, pCacheName, NULL ); + if( getenv( ENV_DEBUG_LDAPKERB ) ) + fprintf( stderr, "gss credentials cache set to %s(%d)\n", pCacheName, kres ); + } +#endif + krb5_cc_close( kcontext, kcache ); + } +fail: + if( kres ) + { + const char * errmsg = error_message(kres); + fprintf( stderr, "%s user init(%s): %s\n", "setpass", pName, errmsg ); + } + krb5_free_principal( kcontext, kme ); + krb5_free_cred_contents( kcontext, &kcreds ); + if( pName ) + free( pName ); + free(pPass); + krb5_free_context(kcontext); + +return_error: + if( kres ) + { + if( pCacheName ) + { + free(pCacheName); + pCacheName = NULL; + } + } + if( outError ) + *outError = kres; + return pCacheName; +} + +int init_creds() +{ + char user[512]; + char * password = NULL; + int result; + + user[0] = 0; + result = -1; + + for(;;) + { + while( user[0] == 0 ) + { + int userlen; + printf( "Username: "); + fflush(stdout); + if( fgets( user, sizeof(user), stdin ) == NULL ) + return -1; + userlen = strlen( user); + if( userlen < 2 ) + continue; + user[userlen-1] = 0; // get rid of the newline + break; + } + { + kbrccache_t usercontext; + password = getpass( "Password: "); + if( ! password ) + return -1; + result = 0; + usercontext = userinitcontext( user, NULL, password, NULL, 1, &result ); + if( usercontext ) + break; + } + } + return result; +} + +int main( int argc, char ** argv ) +{ + char * new_password = NULL; + char * new_password2; + krb5_context kcontext; + krb5_ccache ccache; + krb5_error_code kerr; + krb5_principal target_principal; + + + if( argc < 2 ) + { + fprintf( stderr, "Usage: setpass user@REALM\n"); + exit(1); + } + +/* +** verify credentials - +*/ + if( verify_creds() ) + init_creds(); + if( verify_creds() ) + { + fprintf( stderr, "No user credentials available\n"); + exit(1); + } +/* +** check the principal name - +*/ + krb5_init_context(&kcontext); + kerr = krb5_parse_name( kcontext, argv[1], &target_principal ); + + { + char * pname = NULL; + kerr = krb5_unparse_name( kcontext, target_principal, &pname ); + printf( "Changing password for %s:\n", pname); + fflush( stdout ); + free( pname ); + } +/* +** get the new password - +*/ + while( !new_password ) + { + new_password = getpass("Enter new password: "); + new_password2 = getpass("Verify new password: "); + if( strcmp( new_password, new_password2 ) ) + { + printf("Passwords do not match\n"); + free( new_password ); + free( new_password2 ); + continue; + } + } +/* +** change the password - +*/ + fprintf( stderr, "the password is %s\n", new_password ); + + { + int pw_result; + krb5_ccache ccache; + krb5_data pw_res_string, res_string; + + kerr = krb5_cc_default( kcontext, &ccache ); + if( kerr == 0 ) + { + kerr = krb5_set_password_using_ccache(kcontext, ccache, new_password, target_principal, + &pw_result, &pw_res_string, &res_string ); + if( kerr ) + fprintf( stderr, "Failed: %s\n", error_message(kerr) ); + else + { + if( pw_result ) + { + fprintf( stderr, "Failed(%d)", pw_result ); + if( pw_res_string.length > 0 ) + fprintf( stderr, ": %s", pw_res_string.data); + if( res_string.length > 0 ) + fprintf( stderr, " %s", res_string.data); + fprintf( stderr, "\n"); + } + } + } + } +} |