1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 #include <k5-platform.h>
7 #define TKTTIMELEFT 60*10 /* ten minutes */
9 static int verify_creds()
11 krb5_context kcontext;
15 kres = krb5_init_context(&kcontext);
18 kres = krb5_cc_default( kcontext, &ccache );
21 krb5_principal user_princ;
23 kres = krb5_cc_get_principal( kcontext, ccache, &user_princ );
25 krb5_free_principal( kcontext, user_princ );
26 krb5_cc_close( kcontext, ccache );
28 krb5_free_context(kcontext);
33 static void get_init_creds_opt_init( krb5_get_init_creds_opt *outOptions )
35 krb5_preauthtype preauth[] = { KRB5_PADATA_ENC_TIMESTAMP };
36 krb5_enctype etypes[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_CRC};
37 krb5_get_init_creds_opt_set_address_list(outOptions, NULL);
38 krb5_get_init_creds_opt_set_etype_list( outOptions, etypes, sizeof(etypes)/sizeof(krb5_enctype) );
39 krb5_get_init_creds_opt_set_preauth_list(outOptions, preauth, sizeof(preauth)/sizeof(krb5_preauthtype) );
42 typedef void * kbrccache_t;
43 #define CCACHE_PREFIX_DEFAULT "MEMORY:C_"
45 static kbrccache_t userinitcontext(
46 const char * user, const char * domain, const char * passwd, const char * cachename, int initialize,
49 krb5_context kcontext = 0;
50 krb5_ccache kcache = 0;
52 krb5_principal kme = 0;
54 char * pPass = strdup( passwd );
56 char * pCacheName = NULL;
59 memset( &kcreds, 0, sizeof(kcreds) );
60 kres = krb5_init_context( &kcontext );
64 kres = krb5_build_principal( kcontext, &kme, strlen(domain), domain, user, (char *) 0 );
66 kres = krb5_parse_name( kcontext, user, &kme );
69 krb5_unparse_name( kcontext, kme, &pName );
72 if (asprintf(&pCacheName, "%s%s", cachename, pName) < 0)
77 kres = krb5_cc_resolve( kcontext, pCacheName, &kcache );
80 kres = krb5_cc_resolve( kcontext, CCACHE_PREFIX_DEFAULT, &kcache );
82 pCacheName = strdup(CCACHE_PREFIX_DEFAULT);
87 kres = krb5_cc_default( kcontext, &kcache );
88 pCacheName = strdup( krb5_cc_get_name( kcontext, kcache ) );
92 krb5_free_context(kcontext);
96 krb5_cc_initialize( kcontext, kcache, kme );
97 if( kres == 0 && user && passwd )
99 long timeneeded = time(0L) +TKTTIMELEFT;
100 int have_credentials = 0;
101 krb5_cc_cursor cc_curs = NULL;
103 if( (kres=krb5_cc_start_seq_get(kcontext, kcache, &cc_curs)) >= 0 )
105 while( (kres=krb5_cc_next_cred(kcontext, kcache, &cc_curs, &kcreds))== 0)
108 if( krb5_principal_compare( kcontext, kme, kcreds.client ) )
110 if( kcreds.ticket_flags & TKT_FLG_INITIAL && kcreds.times.endtime>timeneeded )
111 have_credentials = 1;
113 krb5_free_cred_contents( kcontext, &kcreds );
114 if( have_credentials )
117 krb5_cc_end_seq_get( kcontext, kcache, &cc_curs );
121 const char * errmsg = error_message(kres);
122 fprintf( stderr, "%s user init(%s): %s\n", "setpass", pName, errmsg );
124 if( kres != 0 || have_credentials == 0 )
126 krb5_get_init_creds_opt *options = NULL;
127 kres = krb5_get_init_creds_opt_alloc(kcontext, &options);
130 get_init_creds_opt_init(options);
132 ** no valid credentials - get new ones
134 kres = krb5_get_init_creds_password( kcontext, &kcreds, kme, pPass,
138 0 /*in_tkt_service*/,
139 options /*options*/ );
144 kres = krb5_cc_initialize( kcontext, kcache, kme );
146 kres = krb5_cc_store_cred( kcontext, kcache, &kcreds );
148 have_credentials = 1;
150 krb5_get_init_creds_opt_free(kcontext, options);
153 if( have_credentials )
156 kres = gss_krb5_ccache_name( &mstat, pCacheName, NULL );
157 if( getenv( ENV_DEBUG_LDAPKERB ) )
158 fprintf( stderr, "gss credentials cache set to %s(%d)\n", pCacheName, kres );
161 krb5_cc_close( kcontext, kcache );
166 const char * errmsg = error_message(kres);
167 fprintf( stderr, "%s user init(%s): %s\n", "setpass", pName, errmsg );
169 krb5_free_principal( kcontext, kme );
170 krb5_free_cred_contents( kcontext, &kcreds );
174 krb5_free_context(kcontext);
190 static int init_creds()
193 char * password = NULL;
201 while( user[0] == 0 )
204 printf( "Username: ");
206 if( fgets( user, sizeof(user), stdin ) == NULL )
208 userlen = strlen( user);
211 user[userlen-1] = 0; /* get rid of the newline */
215 kbrccache_t usercontext;
216 password = getpass( "Password: ");
220 usercontext = userinitcontext( user, NULL, password, NULL, 1, &result );
228 int main( int argc, char ** argv )
231 char * new_password2;
232 krb5_context kcontext;
233 krb5_error_code kerr;
234 krb5_principal target_principal;
239 fprintf( stderr, "Usage: setpass user@REALM\n");
244 ** verify credentials -
250 fprintf( stderr, "No user credentials available\n");
254 ** check the principal name -
256 krb5_init_context(&kcontext);
257 kerr = krb5_parse_name( kcontext, argv[1], &target_principal );
261 kerr = krb5_unparse_name( kcontext, target_principal, &pname );
262 printf( "Changing password for %s:\n", pname);
267 ** get the new password -
271 new_password = getpass("Enter new password: ");
272 new_password2 = getpass("Verify new password: ");
273 if( strcmp( new_password, new_password2 ) == 0)
275 printf("Passwords do not match\n");
276 free( new_password );
277 free( new_password2 );
280 ** change the password -
285 krb5_data pw_res_string, res_string;
287 kerr = krb5_cc_default( kcontext, &ccache );
290 kerr = krb5_set_password_using_ccache(kcontext, ccache, new_password, target_principal,
291 &pw_result, &pw_res_string, &res_string );
293 fprintf( stderr, "Failed: %s\n", error_message(kerr) );
298 fprintf( stderr, "Failed(%d)", pw_result );
299 if( pw_res_string.length > 0 )
300 fprintf( stderr, ": %s", pw_res_string.data);
301 if( res_string.length > 0 )
302 fprintf( stderr, " %s", res_string.data);
303 fprintf( stderr, "\n");