static char *afs_realm_of_cell(afsconf_cell *cellconfig) { #ifdef NO_AFS return(0); #else char krbhst[MAX_HSTNM]=""; static char krbrlm[REALM_SZ+1]=""; #ifndef NO_KRB5 krb5_context ctx = 0; char ** realmlist=NULL; krb5_error_code r; #endif /* NO_KRB5 */ if (!cellconfig) return 0; #ifndef NO_KRB5 if ( pkrb5_init_context ) { r = pkrb5_init_context(&ctx); if ( !r ) r = pkrb5_get_host_realm(ctx, cellconfig->hostName[0], &realmlist); if ( !r && realmlist && realmlist[0] ) { strcpy(krbrlm, realmlist[0]); pkrb5_free_host_realm(ctx, realmlist); } if (ctx) pkrb5_free_context(ctx); } #endif /* NO_KRB5 */ if ( !krbrlm[0] ) { char *s = krbrlm; char *t = cellconfig->name; int c; while (c = *t++) { if (islower(c)) c=toupper(c); *s++ = c; } *s++ = 0; } return(krbrlm); #endif }
long Leash_convert524( krb5_context alt_ctx ) { #if defined(NO_KRB5) || defined(NO_KRB4) return(0); #else krb5_context ctx = 0; krb5_error_code code = 0; int icode = 0; krb5_principal me = 0; krb5_principal server = 0; krb5_creds *v5creds = 0; krb5_creds increds; krb5_ccache cc = 0; CREDENTIALS * v4creds = NULL; static int init_ets = 1; if (!pkrb5_init_context || !pkrb_in_tkt || !pkrb524_init_ets || !pkrb524_convert_creds_kdc) return 0; v4creds = (CREDENTIALS *) malloc(sizeof(CREDENTIALS)); memset((char *) v4creds, 0, sizeof(CREDENTIALS)); memset((char *) &increds, 0, sizeof(increds)); /* From this point on, we can goto cleanup because increds is initialized. */ if (alt_ctx) { ctx = alt_ctx; } else { code = pkrb5_init_context(&ctx); if (code) goto cleanup; } code = pkrb5_cc_default(ctx, &cc); if (code) goto cleanup; if ( init_ets ) { pkrb524_init_ets(ctx); init_ets = 0; } if (code = pkrb5_cc_get_principal(ctx, cc, &me)) goto cleanup; if ((code = pkrb5_build_principal(ctx, &server, krb5_princ_realm(ctx, me)->length, krb5_princ_realm(ctx, me)->data, "krbtgt", krb5_princ_realm(ctx, me)->data, NULL))) { goto cleanup; } increds.client = me; increds.server = server; increds.times.endtime = 0; increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; if ((code = pkrb5_get_credentials(ctx, 0, cc, &increds, &v5creds))) { goto cleanup; } if ((icode = pkrb524_convert_creds_kdc(ctx, v5creds, v4creds))) { goto cleanup; } /* initialize ticket cache */ if ((icode = pkrb_in_tkt(v4creds->pname, v4creds->pinst, v4creds->realm) != KSUCCESS)) { goto cleanup; } /* stash ticket, session key, etc. for future use */ if ((icode = pkrb_save_credentials(v4creds->service, v4creds->instance, v4creds->realm, v4creds->session, v4creds->lifetime, v4creds->kvno, &(v4creds->ticket_st), v4creds->issue_date))) { goto cleanup; } cleanup: memset(v4creds, 0, sizeof(v4creds)); free(v4creds); if (v5creds) { pkrb5_free_creds(ctx, v5creds); } if (increds.client == me) me = 0; if (increds.server == server) server = 0; pkrb5_free_cred_contents(ctx, &increds); if (server) { pkrb5_free_principal(ctx, server); } if (me) { pkrb5_free_principal(ctx, me); } pkrb5_cc_close(ctx, cc); if (ctx && (ctx != alt_ctx)) { pkrb5_free_context(ctx); } return !(code || icode); #endif /* NO_KRB5 */ }
int Leash_krb5_kinit( krb5_context alt_ctx, HWND hParent, char *principal_name, char *password, krb5_deltat lifetime, DWORD forwardable, DWORD proxiable, krb5_deltat renew_life, DWORD addressless, DWORD publicIP ) { #ifdef NO_KRB5 return(0); #else krb5_error_code code = 0; krb5_context ctx = 0; krb5_ccache cc = 0, defcache = 0; krb5_principal me = 0; char* name = 0; krb5_creds my_creds; krb5_get_init_creds_opt * options = NULL; krb5_address ** addrs = NULL; int i = 0, addr_count = 0; int cc_new = 0; const char * deftype = NULL; if (!pkrb5_init_context) return 0; memset(&my_creds, 0, sizeof(my_creds)); if (alt_ctx) { ctx = alt_ctx; } else { code = pkrb5_init_context(&ctx); if (code) goto cleanup; } code = pkrb5_get_init_creds_opt_alloc(ctx, &options); if (code) goto cleanup; code = pkrb5_cc_default(ctx, &defcache); if (code) goto cleanup; code = pkrb5_parse_name(ctx, principal_name, &me); if (code) goto cleanup; deftype = pkrb5_cc_get_type(ctx, defcache); if (me != NULL && pkrb5_cc_support_switch(ctx, deftype)) { /* Use an existing cache for the specified principal if we can. */ code = pkrb5_cc_cache_match(ctx, me, &cc); if (code != 0 && code != KRB5_CC_NOTFOUND) goto cleanup; if (code == KRB5_CC_NOTFOUND) { code = pkrb5_cc_new_unique(ctx, deftype, NULL, &cc); if (code) goto cleanup; cc_new = 1; } pkrb5_cc_close(ctx, defcache); } else { cc = defcache; } code = pkrb5_unparse_name(ctx, me, &name); if (code) goto cleanup; if (lifetime == 0) lifetime = Leash_get_default_lifetime(); else lifetime *= 5*60; if (renew_life > 0) renew_life *= 5*60; if (lifetime) pkrb5_get_init_creds_opt_set_tkt_life(options, lifetime); pkrb5_get_init_creds_opt_set_forwardable(options, forwardable ? 1 : 0); pkrb5_get_init_creds_opt_set_proxiable(options, proxiable ? 1 : 0); pkrb5_get_init_creds_opt_set_renew_life(options, renew_life); if (addressless) pkrb5_get_init_creds_opt_set_address_list(options,NULL); else { if (publicIP) { // we are going to add the public IP address specified by the user // to the list provided by the operating system krb5_address ** local_addrs=NULL; DWORD netIPAddr; pkrb5_os_localaddr(ctx, &local_addrs); while ( local_addrs[i++] ); addr_count = i + 1; addrs = (krb5_address **) malloc((addr_count+1) * sizeof(krb5_address *)); if ( !addrs ) { pkrb5_free_addresses(ctx, local_addrs); assert(0); } memset(addrs, 0, sizeof(krb5_address *) * (addr_count+1)); i = 0; while ( local_addrs[i] ) { addrs[i] = (krb5_address *)malloc(sizeof(krb5_address)); if (addrs[i] == NULL) { pkrb5_free_addresses(ctx, local_addrs); assert(0); } addrs[i]->magic = local_addrs[i]->magic; addrs[i]->addrtype = local_addrs[i]->addrtype; addrs[i]->length = local_addrs[i]->length; addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length); if (!addrs[i]->contents) { pkrb5_free_addresses(ctx, local_addrs); assert(0); } memcpy(addrs[i]->contents,local_addrs[i]->contents, local_addrs[i]->length); /* safe */ i++; } pkrb5_free_addresses(ctx, local_addrs); addrs[i] = (krb5_address *)malloc(sizeof(krb5_address)); if (addrs[i] == NULL) assert(0); addrs[i]->magic = KV5M_ADDRESS; addrs[i]->addrtype = AF_INET; addrs[i]->length = 4; addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length); if (!addrs[i]->contents) assert(0); netIPAddr = htonl(publicIP); memcpy(addrs[i]->contents,&netIPAddr,4); pkrb5_get_init_creds_opt_set_address_list(options,addrs); } } code = pkrb5_get_init_creds_opt_set_out_ccache(ctx, options, cc); if (code) goto cleanup; code = pkrb5_get_init_creds_password(ctx, &my_creds, me, password, // password leash_krb5_prompter, // prompter hParent, // prompter data 0, // start time 0, // service name options); // @TODO: make this an option if ((!code) && (cc != defcache)) { code = pkrb5_cc_switch(ctx, cc); if (!code) { const char *cctype = pkrb5_cc_get_type(ctx, cc); if (cctype != NULL) { char defname[20]; sprintf_s(defname, sizeof(defname), "%s:", cctype); pkrb5int_cc_user_set_default_name(ctx, defname); } } } cleanup: if (code && cc_new) { // don't leave newly-generated empty ccache lying around on failure pkrb5_cc_destroy(ctx, cc); cc = NULL; } if ( addrs ) { for ( i=0;i<addr_count;i++ ) { if ( addrs[i] ) { if ( addrs[i]->contents ) free(addrs[i]->contents); free(addrs[i]); } } } if (my_creds.client == me) my_creds.client = 0; pkrb5_free_cred_contents(ctx, &my_creds); if (name) pkrb5_free_unparsed_name(ctx, name); if (me) pkrb5_free_principal(ctx, me); if (cc) pkrb5_cc_close(ctx, cc); if (options) pkrb5_get_init_creds_opt_free(ctx, options); if (ctx && (ctx != alt_ctx)) pkrb5_free_context(ctx); return(code); #endif //!NO_KRB5 }
int LeashKRB5_renew(void) { #ifdef NO_KRB5 return(0); #else krb5_error_code code = 0; krb5_context ctx = 0; krb5_ccache cc = 0; krb5_principal me = 0; krb5_principal server = 0; krb5_creds my_creds; krb5_data *realm = 0; if ( !pkrb5_init_context ) goto cleanup; memset(&my_creds, 0, sizeof(krb5_creds)); code = pkrb5_init_context(&ctx); if (code) goto cleanup; code = pkrb5_cc_default(ctx, &cc); if (code) goto cleanup; code = pkrb5_cc_get_principal(ctx, cc, &me); if (code) goto cleanup; realm = krb5_princ_realm(ctx, me); code = pkrb5_build_principal_ext(ctx, &server, realm->length,realm->data, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, realm->length,realm->data, 0); if ( code ) goto cleanup; my_creds.client = me; my_creds.server = server; #ifdef KRB5_TC_NOTICKET pkrb5_cc_set_flags(ctx, cc, 0); #endif code = pkrb5_get_renewed_creds(ctx, &my_creds, me, cc, NULL); #ifdef KRB5_TC_NOTICKET pkrb5_cc_set_flags(ctx, cc, KRB5_TC_NOTICKET); #endif if (code) { if ( code != KRB5KDC_ERR_ETYPE_NOSUPP || code != KRB5_KDC_UNREACH) Leash_krb5_error(code, "krb5_get_renewed_creds()", 0, &ctx, &cc); goto cleanup; } code = pkrb5_cc_initialize(ctx, cc, me); if (code) goto cleanup; code = pkrb5_cc_store_cred(ctx, cc, &my_creds); if (code) goto cleanup; cleanup: if (my_creds.client == me) my_creds.client = 0; if (my_creds.server == server) my_creds.server = 0; pkrb5_free_cred_contents(ctx, &my_creds); if (me) pkrb5_free_principal(ctx, me); if (server) pkrb5_free_principal(ctx, server); if (cc) pkrb5_cc_close(ctx, cc); if (ctx) pkrb5_free_context(ctx); return(code); #endif /* NO_KRB5 */ }
BOOL Leash_ms2mit(BOOL save_creds) { #ifdef NO_KRB5 return(FALSE); #else /* NO_KRB5 */ krb5_context kcontext = 0; krb5_error_code code; krb5_ccache ccache=0; krb5_ccache mslsa_ccache=0; krb5_creds creds; krb5_cc_cursor cursor=0; krb5_principal princ = 0; BOOL rc = FALSE; if ( !pkrb5_init_context ) goto cleanup; if (code = pkrb5_init_context(&kcontext)) goto cleanup; if (code = pkrb5_cc_resolve(kcontext, "MSLSA:", &mslsa_ccache)) goto cleanup; if ( save_creds ) { if (code = pkrb5_cc_get_principal(kcontext, mslsa_ccache, &princ)) goto cleanup; if (code = pkrb5_cc_default(kcontext, &ccache)) goto cleanup; if (code = pkrb5_cc_initialize(kcontext, ccache, princ)) goto cleanup; if (code = pkrb5_cc_copy_creds(kcontext, mslsa_ccache, ccache)) goto cleanup; rc = TRUE; } else { /* Enumerate tickets from cache looking for an initial ticket */ if ((code = pkrb5_cc_start_seq_get(kcontext, mslsa_ccache, &cursor))) goto cleanup; while (!(code = pkrb5_cc_next_cred(kcontext, mslsa_ccache, &cursor, &creds))) { if ( creds.ticket_flags & TKT_FLG_INITIAL ) { rc = TRUE; pkrb5_free_cred_contents(kcontext, &creds); break; } pkrb5_free_cred_contents(kcontext, &creds); } pkrb5_cc_end_seq_get(kcontext, mslsa_ccache, &cursor); } cleanup: if (princ) pkrb5_free_principal(kcontext, princ); if (ccache) pkrb5_cc_close(kcontext, ccache); if (mslsa_ccache) pkrb5_cc_close(kcontext, mslsa_ccache); if (kcontext) pkrb5_free_context(kcontext); return(rc); #endif /* NO_KRB5 */ }