X-Git-Url: https://git.openafs.org/?p=openafs.git;a=blobdiff_plain;f=src%2FWINNT%2Fafsd%2Fafskfw.c;h=a7b78abe6a374e169addeea5238c2ff55a3ad1c2;hp=01ace95a8d3c372cc81bd07e31556cad0223ab59;hb=c4b1decf6caacb13db666f516ceaf9b65e4371ab;hpb=4cbee84b4c1d1eca5913a64a392e2b31779ca7b5 diff --git a/src/WINNT/afsd/afskfw.c b/src/WINNT/afsd/afskfw.c index 01ace95..a7b78ab 100644 --- a/src/WINNT/afsd/afskfw.c +++ b/src/WINNT/afsd/afskfw.c @@ -63,6 +63,9 @@ #include #include /* for life_to_time */ #include +#include + +#include /* * TIMING _____________________________________________________________________ @@ -99,6 +102,7 @@ DECL_FUNC_PTR(Leash_get_default_life_max); DECL_FUNC_PTR(Leash_get_default_renew_min); DECL_FUNC_PTR(Leash_get_default_renew_max); DECL_FUNC_PTR(Leash_get_default_renewable); +DECL_FUNC_PTR(Leash_get_default_mslsa_import); // krb5 functions DECL_FUNC_PTR(krb5_change_password); @@ -153,6 +157,7 @@ DECL_FUNC_PTR(krb5_get_renewed_creds); DECL_FUNC_PTR(krb5_get_default_config_files); DECL_FUNC_PTR(krb5_free_config_files); DECL_FUNC_PTR(krb5_get_default_realm); +DECL_FUNC_PTR(krb5_free_default_realm); DECL_FUNC_PTR(krb5_free_ticket); DECL_FUNC_PTR(krb5_decode_ticket); DECL_FUNC_PTR(krb5_get_host_realm); @@ -225,6 +230,11 @@ FUNC_INFO leash_fi[] = { END_FUNC_INFO }; +FUNC_INFO leash_opt_fi[] = { + MAKE_FUNC_INFO(Leash_get_default_mslsa_import), + END_FUNC_INFO +}; + FUNC_INFO k5_fi[] = { MAKE_FUNC_INFO(krb5_change_password), MAKE_FUNC_INFO(krb5_get_init_creds_opt_init), @@ -279,6 +289,7 @@ FUNC_INFO k5_fi[] = { MAKE_FUNC_INFO(krb5_get_default_config_files), MAKE_FUNC_INFO(krb5_free_config_files), MAKE_FUNC_INFO(krb5_get_default_realm), + MAKE_FUNC_INFO(krb5_free_default_realm), MAKE_FUNC_INFO(krb5_free_ticket), MAKE_FUNC_INFO(krb5_decode_ticket), MAKE_FUNC_INFO(krb5_get_host_realm), @@ -356,7 +367,9 @@ static int inited = 0; static int mid_cnt = 0; static struct textField * mid_tb = NULL; static HINSTANCE hKrb5 = 0; +#ifdef USE_KRB4 static HINSTANCE hKrb4 = 0; +#endif /* USE_KRB4 */ static HINSTANCE hKrb524 = 0; #ifdef USE_MS2MIT static HINSTANCE hSecur32 = 0; @@ -366,6 +379,7 @@ static HINSTANCE hComErr = 0; static HINSTANCE hService = 0; static HINSTANCE hProfile = 0; static HINSTANCE hLeash = 0; +static HINSTANCE hLeashOpt = 0; static HINSTANCE hCCAPI = 0; static struct principal_ccache_data * princ_cc_data = NULL; static struct cell_principal_map * cell_princ_map = NULL; @@ -402,6 +416,7 @@ KFW_initialize(void) LoadFuncs(PROFILE_DLL, profile_fi, &hProfile, 0, 1, 0, 0); LoadFuncs(LEASH_DLL, leash_fi, &hLeash, 0, 1, 0, 0); LoadFuncs(CCAPI_DLL, ccapi_fi, &hCCAPI, 0, 1, 0, 0); + LoadFuncs(LEASH_DLL, leash_opt_fi, &hLeashOpt, 0, 1, 0, 0); if ( KFW_is_available() ) { char rootcell[MAXCELLCHARS+1]; @@ -424,30 +439,32 @@ KFW_initialize(void) void KFW_cleanup(void) { - if (hKrb5) - FreeLibrary(hKrb5); - if (hKrb4) - FreeLibrary(hKrb4); - if (hProfile) - FreeLibrary(hProfile); - if (hComErr) - FreeLibrary(hComErr); - if (hService) - FreeLibrary(hService); + if (hLeashOpt) + FreeLibrary(hLeashOpt); + if (hCCAPI) + FreeLibrary(hCCAPI); + if (hLeash) + FreeLibrary(hLeash); + if (hKrb524) + FreeLibrary(hKrb524); #ifdef USE_MS2MIT if (hSecur32) FreeLibrary(hSecur32); #endif /* USE_MS2MIT */ - if (hKrb524) - FreeLibrary(hKrb524); - if (hLeash) - FreeLibrary(hLeash); - if (hCCAPI) - FreeLibrary(hCCAPI); + if (hService) + FreeLibrary(hService); + if (hComErr) + FreeLibrary(hComErr); + if (hProfile) + FreeLibrary(hProfile); +#ifdef USE_KRB4 + if (hKrb4) + FreeLibrary(hKrb4); +#endif /* USE_KRB4 */ + if (hKrb5) + FreeLibrary(hKrb5); } -static char OpenAFSConfigKeyName[] = "SOFTWARE\\OpenAFS\\Client"; - int KFW_use_krb524(void) { @@ -455,7 +472,7 @@ KFW_use_krb524(void) DWORD code, len; DWORD use524 = 0; - code = RegOpenKeyEx(HKEY_CURRENT_USER, OpenAFSConfigKeyName, + code = RegOpenKeyEx(HKEY_CURRENT_USER, AFSREG_USER_OPENAFS_SUBKEY, 0, KEY_QUERY_VALUE, &parmKey); if (code == ERROR_SUCCESS) { len = sizeof(use524); @@ -464,7 +481,7 @@ KFW_use_krb524(void) RegCloseKey(parmKey); } if (code != ERROR_SUCCESS) { - code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName, + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY, 0, KEY_QUERY_VALUE, &parmKey); if (code == ERROR_SUCCESS) { len = sizeof(use524); @@ -483,7 +500,7 @@ KFW_is_available(void) DWORD code, len; DWORD enableKFW = 1; - code = RegOpenKeyEx(HKEY_CURRENT_USER, OpenAFSConfigKeyName, + code = RegOpenKeyEx(HKEY_CURRENT_USER, AFSREG_USER_OPENAFS_SUBKEY, 0, KEY_QUERY_VALUE, &parmKey); if (code == ERROR_SUCCESS) { len = sizeof(enableKFW); @@ -493,7 +510,7 @@ KFW_is_available(void) } if (code != ERROR_SUCCESS) { - code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName, + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY, 0, KEY_QUERY_VALUE, &parmKey); if (code == ERROR_SUCCESS) { len = sizeof(enableKFW); @@ -900,8 +917,9 @@ KFW_import_windows_lsa(void) char * pname = NULL; krb5_data * princ_realm; krb5_error_code code; - char cell[128]="", realm[128]=""; + char cell[128]="", realm[128]="", *def_realm = 0; int i; + DWORD dwMsLsaImport; if (!pkrb5_init_context) return; @@ -922,6 +940,32 @@ KFW_import_windows_lsa(void) code = pkrb5_cc_get_principal(ctx, cc, &princ); if ( code ) goto cleanup; + dwMsLsaImport = pLeash_get_default_mslsa_import ? pLeash_get_default_mslsa_import() : 1; + switch ( dwMsLsaImport ) { + case 0: /* do not import */ + goto cleanup; + case 1: /* always import */ + break; + case 2: { /* matching realm */ + char ms_realm[128] = "", *r; + int i; + + for ( r=ms_realm, i=0; ilength; r++, i++ ) { + *r = krb5_princ_realm(ctx, princ)->data[i]; + } + *r = '\0'; + + if (code = pkrb5_get_default_realm(ctx, &def_realm)) + goto cleanup; + + if (strcmp(def_realm, ms_realm)) + goto cleanup; + break; + } + default: + break; + } + code = pkrb5_unparse_name(ctx,princ,&pname); if ( code ) goto cleanup; @@ -948,6 +992,8 @@ KFW_import_windows_lsa(void) pkrb5_free_unparsed_name(ctx,pname); if (princ) pkrb5_free_principal(ctx,princ); + if (def_realm) + pkrb5_free_default_realm(ctx, def_realm); if (cc) pkrb5_cc_close(ctx,cc); if (ctx) @@ -1034,7 +1080,7 @@ KFW_import_ccache_data(void) code = pkrb5_cc_close(ctx,cc); cc = 0; code = pkrb5_cc_close(ctx,oldcc); - cc = 0; + oldcc = 0; KRB5_error(code, "krb5_cc_copy_creds", 0, NULL, NULL); continue; } @@ -1165,8 +1211,7 @@ KFW_AFS_get_cred( char * username, { krb5_context ctx = 0; krb5_ccache cc = 0; - char * realm = 0; - char ** realmlist = 0; + char * realm = 0, * userrealm = 0; krb5_principal principal = 0; char * pname = 0; krb5_error_code code; @@ -1194,19 +1239,20 @@ KFW_AFS_get_cred( char * username, code = KFW_AFS_get_cellconfig( cell, (void*)&cellconfig, local_cell); if ( code ) goto cleanup; - realm = strchr(username,'@'); - if ( realm ) { + realm = afs_realm_of_cell(ctx, &cellconfig); // do not free + + userrealm = strchr(username,'@'); + if ( userrealm ) { pname = strdup(username); - realm = strchr(pname, '@'); - *realm = '\0'; + userrealm = strchr(pname, '@'); + *userrealm = '\0'; /* handle kerberos iv notation */ while ( dot = strchr(pname,'.') ) { *dot = '/'; } - *realm++ = '@'; + *userrealm++ = '@'; } else { - realm = afs_realm_of_cell(ctx, &cellconfig); // do not free pname = malloc(strlen(username) + strlen(realm) + 2); strcpy(pname, username); @@ -1219,7 +1265,6 @@ KFW_AFS_get_cred( char * username, strcat(pname,"@"); strcat(pname,realm); } - if ( IsDebuggerPresent() ) { OutputDebugString("Realm: "); OutputDebugString(realm); @@ -1325,7 +1370,7 @@ KFW_AFS_destroy_tickets_for_cell(char * cell) return 0; if ( IsDebuggerPresent() ) { - OutputDebugString("KFW_AFS_destroy_ticets_for_cell: "); + OutputDebugString("KFW_AFS_destroy_tickets_for_cell: "); OutputDebugString(cell); OutputDebugString("\n"); } @@ -1377,6 +1422,60 @@ KFW_AFS_destroy_tickets_for_cell(char * cell) return 0; } +int +KFW_AFS_destroy_tickets_for_principal(char * user) +{ + krb5_context ctx = 0; + krb5_error_code code; + int count; + char ** cells = NULL; + krb5_principal princ = 0; + krb5_ccache cc = 0; + + if (!pkrb5_init_context) + return 0; + + if ( IsDebuggerPresent() ) { + OutputDebugString("KFW_AFS_destroy_tickets_for_user: "); + OutputDebugString(user); + OutputDebugString("\n"); + } + + code = pkrb5_init_context(&ctx); + if (code) ctx = 0; + + code = pkrb5_parse_name(ctx, user, &princ); + if (code) goto loop_cleanup; + + code = KFW_get_ccache(ctx, princ, &cc); + if (code) goto loop_cleanup; + + code = pkrb5_cc_destroy(ctx, cc); + if (!code) cc = 0; + + loop_cleanup: + if ( cc ) { + pkrb5_cc_close(ctx, cc); + cc = 0; + } + if ( princ ) { + pkrb5_free_principal(ctx, princ); + princ = 0; + } + + count = KFW_AFS_find_cells_for_princ(ctx, user, &cells, TRUE); + if ( count >= 1 ) { + while ( count-- ) { + KFW_AFS_update_cell_princ_map(ctx, cells[count], user, FALSE); + free(cells[count]); + } + free(cells); + } + + pkrb5_free_context(ctx); + return 0; +} + int KFW_AFS_renew_expiring_tokens(void) { @@ -2429,7 +2528,9 @@ ViceIDToUsername(char *username, { static char lastcell[MAXCELLCHARS+1] = { 0 }; static char confname[512] = { 0 }; +#ifdef AFS_ID_TO_NAME char username_copy[BUFSIZ]; +#endif /* AFS_ID_TO_NAME */ long viceId; /* AFS uid of user */ int status = 0; #ifdef ALLOW_REGISTER @@ -2441,26 +2542,6 @@ ViceIDToUsername(char *username, confname[sizeof(confname) - 2] = '\0'; } - /* - * Talk about DUMB! It turns out that there is a bug in - * pr_Initialize -- even if you give a different cell name - * to it, it still uses a connection to a previous AFS server - * if one exists. The way to fix this is to change the - * _filename_ argument to pr_Initialize - that forces it to - * re-initialize the connection. We do this by adding and - * removing a "/" on the end of the configuration directory name. - */ - - if (lastcell[0] != '\0' && (strcmp(lastcell, aserver->cell) != 0)) { - int i = strlen(confname); - if (confname[i - 1] == '/') { - confname[i - 1] = '\0'; - } else { - confname[i] = '/'; - confname[i + 1] = '\0'; - } - } - strcpy(lastcell, aserver->cell); if (!pr_Initialize (0, confname, aserver->cell)) @@ -2501,15 +2582,7 @@ ViceIDToUsername(char *username, strncpy(aclient->cell, realm_of_user, MAXKTCREALMLEN - 1); if (status = ktc_SetToken(aserver, atoken, aclient, 0)) return status; - - /* - * In case you're wondering, we don't need to change the - * filename here because we're still connecting to the - * same cell -- we're just using a different authentication - * level - */ - - if (status = pr_Initialize(1L, confname, aserver->cell, 0)) + if (status = pr_Initialize(1L, confname, aserver->cell)) return status; if (status = pr_CreateUser(username, &id)) return status; @@ -2537,7 +2610,9 @@ KFW_AFS_klog( { long rc = 0; CREDENTIALS creds; +#ifdef USE_KRB4 KTEXT_ST ticket; +#endif /* USE_KRB4 */ struct ktc_principal aserver; struct ktc_principal aclient; char realm_of_user[REALM_SZ]; /* Kerberos realm of user */ @@ -2559,6 +2634,7 @@ KFW_AFS_klog( krb5_creds * k5creds = 0; krb5_error_code code; krb5_principal client_principal = 0; + krb5_data * k5data; int i, retry = 0; CurrentState = 0; @@ -2620,7 +2696,15 @@ KFW_AFS_klog( goto skip_krb5_init; } - if ( strchr(krb5_princ_component(ctx,client_principal,0),'.') != NULL ) + /* look for client principals which cannot be distinguished + * from Kerberos 4 multi-component principal names + */ + k5data = krb5_princ_component(ctx,client_principal,0); + for ( i=0; ilength; i++ ) { + if ( k5data->data[i] == '.' ) + break; + } + if (i != k5data->length) { OutputDebugString("Illegal Principal name contains dot in first component\n"); rc = KRB5KRB_ERR_GENERIC; @@ -3351,3 +3435,176 @@ BOOL KFW_probe_kdc(struct afsconf_cell * cellconfig) return serverReachable; } +BOOL +KFW_AFS_get_lsa_principal(char * szUser, DWORD *dwSize) +{ + krb5_context ctx = 0; + krb5_error_code code; + krb5_ccache mslsa_ccache=0; + krb5_principal princ = 0; + char * pname = 0; + BOOL success = 0; + + if (!KFW_is_available()) + return FALSE; + + if (code = pkrb5_init_context(&ctx)) + goto cleanup; + + if (code = pkrb5_cc_resolve(ctx, "MSLSA:", &mslsa_ccache)) + goto cleanup; + + if (code = pkrb5_cc_get_principal(ctx, mslsa_ccache, &princ)) + goto cleanup; + + if (code = pkrb5_unparse_name(ctx, princ, &pname)) + goto cleanup; + + if ( strlen(pname) < *dwSize ) { + strncpy(szUser, pname, *dwSize); + szUser[*dwSize-1] = '\0'; + success = 1; + } + *dwSize = strlen(pname); + + cleanup: + if (pname) + pkrb5_free_unparsed_name(ctx, pname); + + if (princ) + pkrb5_free_principal(ctx, princ); + + if (mslsa_ccache) + pkrb5_cc_close(ctx, mslsa_ccache); + + if (ctx) + pkrb5_free_context(ctx); + return success; +} + +void +KFW_AFS_copy_cache_to_system_file(char * user, char * szLogonId) +{ + char filename[256]; + DWORD count; + char cachename[264] = "FILE:"; + krb5_context ctx = 0; + krb5_error_code code; + krb5_principal princ = 0; + krb5_ccache cc = 0; + krb5_ccache ncc = 0; + + if (!pkrb5_init_context) + return; + + count = GetEnvironmentVariable("TEMP", filename, sizeof(filename)); + if ( count > sizeof(filename) || count == 0 ) { + GetWindowsDirectory(filename, sizeof(filename)); + } + + if ( strlen(filename) + strlen(szLogonId) + 2 > sizeof(filename) ) + return; + + strcat(filename, "\\"); + strcat(filename, szLogonId); + + strcat(cachename, filename); + + DeleteFile(filename); + + code = pkrb5_init_context(&ctx); + if (code) ctx = 0; + + code = pkrb5_parse_name(ctx, user, &princ); + if (code) goto cleanup; + + code = KFW_get_ccache(ctx, princ, &cc); + if (code) goto cleanup; + + code = pkrb5_cc_resolve(ctx, cachename, &ncc); + if (code) goto cleanup; + + code = pkrb5_cc_initialize(ctx, ncc, princ); + if (code) goto cleanup; + + code = pkrb5_cc_copy_creds(ctx,cc,ncc); + + cleanup: + if ( cc ) { + pkrb5_cc_close(ctx, cc); + cc = 0; + } + if ( ncc ) { + pkrb5_cc_close(ctx, ncc); + ncc = 0; + } + if ( princ ) { + pkrb5_free_principal(ctx, princ); + princ = 0; + } + + if (ctx) + pkrb5_free_context(ctx); +} + +int +KFW_AFS_copy_system_file_to_default_cache(char * filename) +{ + DWORD count; + char cachename[264] = "FILE:"; + HANDLE hFile; + krb5_context ctx = 0; + krb5_error_code code; + krb5_principal princ = 0; + krb5_ccache cc = 0; + krb5_ccache ncc = 0; + int retval = 1; + + if (!pkrb5_init_context) + return 1; + + if ( strlen(filename) + 6 > sizeof(cachename) ) + return 1; + + strcat(cachename, filename); + + code = pkrb5_init_context(&ctx); + if (code) ctx = 0; + + code = pkrb5_cc_resolve(ctx, cachename, &cc); + if (code) goto cleanup; + + code = pkrb5_cc_get_principal(ctx, cc, &princ); + + code = pkrb5_cc_default(ctx, &ncc); + if (!code) { + code = pkrb5_cc_initialize(ctx, ncc, princ); + + if (!code) + code = pkrb5_cc_copy_creds(ctx,cc,ncc); + } + if ( ncc ) { + pkrb5_cc_close(ctx, ncc); + ncc = 0; + } + + retval=0; /* success */ + + cleanup: + if ( cc ) { + pkrb5_cc_close(ctx, cc); + cc = 0; + } + + DeleteFile(filename); + + if ( princ ) { + pkrb5_free_principal(ctx, princ); + princ = 0; + } + + if (ctx) + pkrb5_free_context(ctx); + + return 0; +}