summaryrefslogtreecommitdiffstats
path: root/src/windows/identity/plugins
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2007-06-20 01:19:59 +0000
committerKen Raeburn <raeburn@mit.edu>2007-06-20 01:19:59 +0000
commit78ec90d925e1f672639762e6c9fa674bf7ff0a64 (patch)
tree3aad3df3133e6e0f2922f575b9da94630543f433 /src/windows/identity/plugins
parentd275e06d0cb0f248aa54a6f134a59f84aa563e14 (diff)
set svn:eol-style to native for *.[ch]
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19596 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/windows/identity/plugins')
-rw-r--r--src/windows/identity/plugins/common/dynimport.c954
-rw-r--r--src/windows/identity/plugins/common/dynimport.h722
-rw-r--r--src/windows/identity/plugins/common/krb5common.c902
-rw-r--r--src/windows/identity/plugins/common/krb5common.h112
-rw-r--r--src/windows/identity/plugins/krb4/errorfuncs.c452
-rw-r--r--src/windows/identity/plugins/krb4/errorfuncs.h130
-rw-r--r--src/windows/identity/plugins/krb4/krb4configdlg.c1078
-rw-r--r--src/windows/identity/plugins/krb4/krb4funcs.c1794
-rw-r--r--src/windows/identity/plugins/krb4/krb4funcs.h264
-rw-r--r--src/windows/identity/plugins/krb4/krb4main.c314
-rw-r--r--src/windows/identity/plugins/krb4/krb4newcreds.c1746
-rw-r--r--src/windows/identity/plugins/krb4/krb4plugin.c594
-rw-r--r--src/windows/identity/plugins/krb4/krbcred.h272
-rw-r--r--src/windows/identity/plugins/krb4/langres.h98
-rw-r--r--src/windows/identity/plugins/krb5/datarep.c814
-rw-r--r--src/windows/identity/plugins/krb5/datarep.h152
-rw-r--r--src/windows/identity/plugins/krb5/errorfuncs.c594
-rw-r--r--src/windows/identity/plugins/krb5/errorfuncs.h150
-rw-r--r--src/windows/identity/plugins/krb5/krb5configcc.c1142
-rw-r--r--src/windows/identity/plugins/krb5/krb5configid.c710
-rw-r--r--src/windows/identity/plugins/krb5/krb5configids.c540
-rw-r--r--src/windows/identity/plugins/krb5/krb5funcs.c6974
-rw-r--r--src/windows/identity/plugins/krb5/krb5funcs.h434
-rw-r--r--src/windows/identity/plugins/krb5/krb5identpro.c3762
-rw-r--r--src/windows/identity/plugins/krb5/krb5main.c994
-rw-r--r--src/windows/identity/plugins/krb5/krb5newcreds.c5494
-rw-r--r--src/windows/identity/plugins/krb5/krb5plugin.c530
-rw-r--r--src/windows/identity/plugins/krb5/krb5props.c352
-rw-r--r--src/windows/identity/plugins/krb5/krbcred.h488
-rw-r--r--src/windows/identity/plugins/krb5/langres.h432
30 files changed, 16497 insertions, 16497 deletions
diff --git a/src/windows/identity/plugins/common/dynimport.c b/src/windows/identity/plugins/common/dynimport.c
index f49987ca7..24fa1a551 100644
--- a/src/windows/identity/plugins/common/dynimport.c
+++ b/src/windows/identity/plugins/common/dynimport.c
@@ -1,477 +1,477 @@
-/*
-* Copyright (c) 2005 Massachusetts Institute of Technology
-* Copyright (c) 2007 Secure Endpoints Inc.
-*
-* Permission is hereby granted, free of charge, to any person
-* obtaining a copy of this software and associated documentation
-* files (the "Software"), to deal in the Software without
-* restriction, including without limitation the rights to use, copy,
-* modify, merge, publish, distribute, sublicense, and/or sell copies
-* of the Software, and to permit persons to whom the Software is
-* furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be
-* included in all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-* SOFTWARE.
-*/
-
-/* $Id$ */
-
-#include<windows.h>
-#include<netidmgr.h>
-#include<dynimport.h>
-
-HINSTANCE hKrb4 = 0;
-HINSTANCE hKrb5 = 0;
-HINSTANCE hKrb524 = 0;
-HINSTANCE hSecur32 = 0;
-HINSTANCE hComErr = 0;
-HINSTANCE hService = 0;
-HINSTANCE hProfile = 0;
-HINSTANCE hPsapi = 0;
-HINSTANCE hToolHelp32 = 0;
-HINSTANCE hCCAPI = 0;
-
-DWORD AfsAvailable = 0;
-
-// CCAPI
-DECL_FUNC_PTR(cc_initialize);
-DECL_FUNC_PTR(cc_shutdown);
-DECL_FUNC_PTR(cc_get_NC_info);
-DECL_FUNC_PTR(cc_free_NC_info);
-
-// krb4 functions
-DECL_FUNC_PTR(get_krb_err_txt_entry);
-DECL_FUNC_PTR(k_isinst);
-DECL_FUNC_PTR(k_isname);
-DECL_FUNC_PTR(k_isrealm);
-DECL_FUNC_PTR(kadm_change_your_password);
-DECL_FUNC_PTR(kname_parse);
-DECL_FUNC_PTR(krb_get_cred);
-DECL_FUNC_PTR(krb_get_krbhst);
-DECL_FUNC_PTR(krb_get_lrealm);
-DECL_FUNC_PTR(krb_get_pw_in_tkt);
-DECL_FUNC_PTR(krb_get_tf_realm);
-DECL_FUNC_PTR(krb_mk_req);
-DECL_FUNC_PTR(krb_realmofhost);
-DECL_FUNC_PTR(tf_init);
-DECL_FUNC_PTR(tf_close);
-DECL_FUNC_PTR(tf_get_cred);
-DECL_FUNC_PTR(tf_get_pname);
-DECL_FUNC_PTR(tf_get_pinst);
-DECL_FUNC_PTR(LocalHostAddr);
-DECL_FUNC_PTR(tkt_string);
-DECL_FUNC_PTR(krb_set_tkt_string);
-DECL_FUNC_PTR(initialize_krb_error_func);
-DECL_FUNC_PTR(initialize_kadm_error_table);
-DECL_FUNC_PTR(dest_tkt);
-DECL_FUNC_PTR(krb_in_tkt);
-DECL_FUNC_PTR(krb_save_credentials);
-DECL_FUNC_PTR(krb_get_krbconf2);
-DECL_FUNC_PTR(krb_get_krbrealm2);
-DECL_FUNC_PTR(krb_life_to_time);
-
-// krb5 functions
-DECL_FUNC_PTR(krb5_change_password);
-DECL_FUNC_PTR(krb5_get_init_creds_opt_init);
-DECL_FUNC_PTR(krb5_get_init_creds_opt_set_tkt_life);
-DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life);
-DECL_FUNC_PTR(krb5_get_init_creds_opt_set_forwardable);
-DECL_FUNC_PTR(krb5_get_init_creds_opt_set_proxiable);
-DECL_FUNC_PTR(krb5_get_init_creds_opt_set_address_list);
-DECL_FUNC_PTR(krb5_get_init_creds_opt_set_change_password_prompt);
-DECL_FUNC_PTR(krb5_get_init_creds_password);
-DECL_FUNC_PTR(krb5_get_prompt_types);
-DECL_FUNC_PTR(krb5_build_principal_ext);
-DECL_FUNC_PTR(krb5_cc_get_name);
-DECL_FUNC_PTR(krb5_cc_get_type);
-DECL_FUNC_PTR(krb5_cc_resolve);
-DECL_FUNC_PTR(krb5_cc_default);
-DECL_FUNC_PTR(krb5_cc_default_name);
-DECL_FUNC_PTR(krb5_cc_set_default_name);
-DECL_FUNC_PTR(krb5_cc_initialize);
-DECL_FUNC_PTR(krb5_cc_destroy);
-DECL_FUNC_PTR(krb5_cc_close);
-DECL_FUNC_PTR(krb5_cc_store_cred);
-DECL_FUNC_PTR(krb5_cc_copy_creds);
-DECL_FUNC_PTR(krb5_cc_retrieve_cred);
-DECL_FUNC_PTR(krb5_cc_get_principal);
-DECL_FUNC_PTR(krb5_cc_start_seq_get);
-DECL_FUNC_PTR(krb5_cc_next_cred);
-DECL_FUNC_PTR(krb5_cc_end_seq_get);
-DECL_FUNC_PTR(krb5_cc_remove_cred);
-DECL_FUNC_PTR(krb5_cc_set_flags);
-// DECL_FUNC_PTR(krb5_cc_get_type);
-DECL_FUNC_PTR(krb5_free_context);
-DECL_FUNC_PTR(krb5_free_cred_contents);
-DECL_FUNC_PTR(krb5_free_principal);
-DECL_FUNC_PTR(krb5_get_in_tkt_with_password);
-DECL_FUNC_PTR(krb5_init_context);
-DECL_FUNC_PTR(krb5_parse_name);
-DECL_FUNC_PTR(krb5_timeofday);
-DECL_FUNC_PTR(krb5_timestamp_to_sfstring);
-DECL_FUNC_PTR(krb5_unparse_name);
-DECL_FUNC_PTR(krb5_get_credentials);
-DECL_FUNC_PTR(krb5_mk_req);
-DECL_FUNC_PTR(krb5_sname_to_principal);
-DECL_FUNC_PTR(krb5_get_credentials_renew);
-DECL_FUNC_PTR(krb5_free_data);
-DECL_FUNC_PTR(krb5_free_data_contents);
-// DECL_FUNC_PTR(krb5_get_realm_domain);
-DECL_FUNC_PTR(krb5_free_unparsed_name);
-DECL_FUNC_PTR(krb5_os_localaddr);
-DECL_FUNC_PTR(krb5_copy_keyblock_contents);
-DECL_FUNC_PTR(krb5_copy_data);
-DECL_FUNC_PTR(krb5_free_creds);
-DECL_FUNC_PTR(krb5_build_principal);
-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_set_default_realm);
-DECL_FUNC_PTR(krb5_free_ticket);
-DECL_FUNC_PTR(krb5_decode_ticket);
-DECL_FUNC_PTR(krb5_get_host_realm);
-DECL_FUNC_PTR(krb5_free_host_realm);
-DECL_FUNC_PTR(krb5_c_random_make_octets);
-DECL_FUNC_PTR(krb5_free_addresses);
-DECL_FUNC_PTR(krb5_free_default_realm);
-DECL_FUNC_PTR(krb5_string_to_deltat);
-
-// Krb524 functions
-DECL_FUNC_PTR(krb524_init_ets);
-DECL_FUNC_PTR(krb524_convert_creds_kdc);
-
-// ComErr functions
-DECL_FUNC_PTR(com_err);
-DECL_FUNC_PTR(error_message);
-
-// Profile functions
-DECL_FUNC_PTR(profile_init);
-DECL_FUNC_PTR(profile_flush);
-DECL_FUNC_PTR(profile_release);
-DECL_FUNC_PTR(profile_get_subsection_names);
-DECL_FUNC_PTR(profile_free_list);
-DECL_FUNC_PTR(profile_get_string);
-DECL_FUNC_PTR(profile_get_integer);
-DECL_FUNC_PTR(profile_get_values);
-DECL_FUNC_PTR(profile_get_relation_names);
-DECL_FUNC_PTR(profile_clear_relation);
-DECL_FUNC_PTR(profile_add_relation);
-DECL_FUNC_PTR(profile_update_relation);
-DECL_FUNC_PTR(profile_release_string);
-DECL_FUNC_PTR(profile_rename_section);
-
-// Service functions
-DECL_FUNC_PTR(OpenSCManagerA);
-DECL_FUNC_PTR(OpenServiceA);
-DECL_FUNC_PTR(QueryServiceStatus);
-DECL_FUNC_PTR(CloseServiceHandle);
-DECL_FUNC_PTR(LsaNtStatusToWinError);
-
-// LSA Functions
-DECL_FUNC_PTR(LsaConnectUntrusted);
-DECL_FUNC_PTR(LsaLookupAuthenticationPackage);
-DECL_FUNC_PTR(LsaCallAuthenticationPackage);
-DECL_FUNC_PTR(LsaFreeReturnBuffer);
-DECL_FUNC_PTR(LsaGetLogonSessionData);
-
-// CCAPI
-FUNC_INFO ccapi_fi[] = {
- MAKE_FUNC_INFO(cc_initialize),
- MAKE_FUNC_INFO(cc_shutdown),
- MAKE_FUNC_INFO(cc_get_NC_info),
- MAKE_FUNC_INFO(cc_free_NC_info),
- END_FUNC_INFO
-};
-
-FUNC_INFO k4_fi[] = {
- MAKE_FUNC_INFO(get_krb_err_txt_entry),
- MAKE_FUNC_INFO(k_isinst),
- MAKE_FUNC_INFO(k_isname),
- MAKE_FUNC_INFO(k_isrealm),
- MAKE_FUNC_INFO(kadm_change_your_password),
- MAKE_FUNC_INFO(kname_parse),
- MAKE_FUNC_INFO(krb_get_cred),
- MAKE_FUNC_INFO(krb_get_krbhst),
- MAKE_FUNC_INFO(krb_get_lrealm),
- MAKE_FUNC_INFO(krb_get_pw_in_tkt),
- MAKE_FUNC_INFO(krb_get_tf_realm),
- MAKE_FUNC_INFO(krb_mk_req),
- MAKE_FUNC_INFO(krb_realmofhost),
- MAKE_FUNC_INFO(tf_init),
- MAKE_FUNC_INFO(tf_close),
- MAKE_FUNC_INFO(tf_get_cred),
- MAKE_FUNC_INFO(tf_get_pname),
- MAKE_FUNC_INFO(tf_get_pinst),
- MAKE_FUNC_INFO(LocalHostAddr),
- MAKE_FUNC_INFO(tkt_string),
- MAKE_FUNC_INFO(krb_set_tkt_string),
- MAKE_FUNC_INFO(initialize_krb_error_func),
- MAKE_FUNC_INFO(initialize_kadm_error_table),
- MAKE_FUNC_INFO(dest_tkt),
- /* MAKE_FUNC_INFO(lsh_LoadKrb4LeashErrorTables), */// XXX
- MAKE_FUNC_INFO(krb_in_tkt),
- MAKE_FUNC_INFO(krb_save_credentials),
- MAKE_FUNC_INFO(krb_get_krbconf2),
- MAKE_FUNC_INFO(krb_get_krbrealm2),
- MAKE_FUNC_INFO(krb_life_to_time),
- END_FUNC_INFO
-};
-
-FUNC_INFO k5_fi[] = {
- MAKE_FUNC_INFO(krb5_change_password),
- MAKE_FUNC_INFO(krb5_get_init_creds_opt_init),
- MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_tkt_life),
- MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_renew_life),
- MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_forwardable),
- MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_proxiable),
- MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_address_list),
- MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_change_password_prompt),
- MAKE_FUNC_INFO(krb5_get_init_creds_password),
- MAKE_FUNC_INFO(krb5_get_prompt_types),
- MAKE_FUNC_INFO(krb5_build_principal_ext),
- MAKE_FUNC_INFO(krb5_cc_get_name),
- MAKE_FUNC_INFO(krb5_cc_get_type),
- MAKE_FUNC_INFO(krb5_cc_resolve),
- MAKE_FUNC_INFO(krb5_cc_default),
- MAKE_FUNC_INFO(krb5_cc_default_name),
- MAKE_FUNC_INFO(krb5_cc_set_default_name),
- MAKE_FUNC_INFO(krb5_cc_initialize),
- MAKE_FUNC_INFO(krb5_cc_destroy),
- MAKE_FUNC_INFO(krb5_cc_close),
- MAKE_FUNC_INFO(krb5_cc_copy_creds),
- MAKE_FUNC_INFO(krb5_cc_store_cred),
- MAKE_FUNC_INFO(krb5_cc_retrieve_cred),
- MAKE_FUNC_INFO(krb5_cc_get_principal),
- MAKE_FUNC_INFO(krb5_cc_start_seq_get),
- MAKE_FUNC_INFO(krb5_cc_next_cred),
- MAKE_FUNC_INFO(krb5_cc_end_seq_get),
- MAKE_FUNC_INFO(krb5_cc_remove_cred),
- MAKE_FUNC_INFO(krb5_cc_set_flags),
- // MAKE_FUNC_INFO(krb5_cc_get_type),
- MAKE_FUNC_INFO(krb5_free_context),
- MAKE_FUNC_INFO(krb5_free_cred_contents),
- MAKE_FUNC_INFO(krb5_free_principal),
- MAKE_FUNC_INFO(krb5_get_in_tkt_with_password),
- MAKE_FUNC_INFO(krb5_init_context),
- MAKE_FUNC_INFO(krb5_parse_name),
- MAKE_FUNC_INFO(krb5_timeofday),
- MAKE_FUNC_INFO(krb5_timestamp_to_sfstring),
- MAKE_FUNC_INFO(krb5_unparse_name),
- MAKE_FUNC_INFO(krb5_get_credentials),
- MAKE_FUNC_INFO(krb5_mk_req),
- MAKE_FUNC_INFO(krb5_sname_to_principal),
- MAKE_FUNC_INFO(krb5_get_credentials_renew),
- MAKE_FUNC_INFO(krb5_free_data),
- MAKE_FUNC_INFO(krb5_free_data_contents),
- // MAKE_FUNC_INFO(krb5_get_realm_domain),
- MAKE_FUNC_INFO(krb5_free_unparsed_name),
- MAKE_FUNC_INFO(krb5_os_localaddr),
- MAKE_FUNC_INFO(krb5_copy_keyblock_contents),
- MAKE_FUNC_INFO(krb5_copy_data),
- MAKE_FUNC_INFO(krb5_free_creds),
- MAKE_FUNC_INFO(krb5_build_principal),
- MAKE_FUNC_INFO(krb5_get_renewed_creds),
- MAKE_FUNC_INFO(krb5_free_addresses),
- 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_set_default_realm),
- MAKE_FUNC_INFO(krb5_free_ticket),
- MAKE_FUNC_INFO(krb5_decode_ticket),
- MAKE_FUNC_INFO(krb5_get_host_realm),
- MAKE_FUNC_INFO(krb5_free_host_realm),
- MAKE_FUNC_INFO(krb5_c_random_make_octets),
- MAKE_FUNC_INFO(krb5_free_default_realm),
- MAKE_FUNC_INFO(krb5_string_to_deltat),
- END_FUNC_INFO
-};
-
-FUNC_INFO k524_fi[] = {
- MAKE_FUNC_INFO(krb524_init_ets),
- MAKE_FUNC_INFO(krb524_convert_creds_kdc),
- END_FUNC_INFO
-};
-
-FUNC_INFO profile_fi[] = {
- MAKE_FUNC_INFO(profile_init),
- MAKE_FUNC_INFO(profile_flush),
- MAKE_FUNC_INFO(profile_release),
- MAKE_FUNC_INFO(profile_get_subsection_names),
- MAKE_FUNC_INFO(profile_free_list),
- MAKE_FUNC_INFO(profile_get_string),
- MAKE_FUNC_INFO(profile_get_integer),
- MAKE_FUNC_INFO(profile_get_values),
- MAKE_FUNC_INFO(profile_get_relation_names),
- MAKE_FUNC_INFO(profile_clear_relation),
- MAKE_FUNC_INFO(profile_add_relation),
- MAKE_FUNC_INFO(profile_update_relation),
- MAKE_FUNC_INFO(profile_release_string),
- MAKE_FUNC_INFO(profile_rename_section),
- END_FUNC_INFO
-};
-
-FUNC_INFO ce_fi[] = {
- MAKE_FUNC_INFO(com_err),
- MAKE_FUNC_INFO(error_message),
- END_FUNC_INFO
-};
-
-FUNC_INFO service_fi[] = {
- MAKE_FUNC_INFO(OpenSCManagerA),
- MAKE_FUNC_INFO(OpenServiceA),
- MAKE_FUNC_INFO(QueryServiceStatus),
- MAKE_FUNC_INFO(CloseServiceHandle),
- MAKE_FUNC_INFO(LsaNtStatusToWinError),
- END_FUNC_INFO
-};
-
-FUNC_INFO lsa_fi[] = {
- MAKE_FUNC_INFO(LsaConnectUntrusted),
- MAKE_FUNC_INFO(LsaLookupAuthenticationPackage),
- MAKE_FUNC_INFO(LsaCallAuthenticationPackage),
- MAKE_FUNC_INFO(LsaFreeReturnBuffer),
- MAKE_FUNC_INFO(LsaGetLogonSessionData),
- END_FUNC_INFO
-};
-
-// psapi functions
-DECL_FUNC_PTR(GetModuleFileNameExA);
-DECL_FUNC_PTR(EnumProcessModules);
-
-FUNC_INFO psapi_fi[] = {
- MAKE_FUNC_INFO(GetModuleFileNameExA),
- MAKE_FUNC_INFO(EnumProcessModules),
- END_FUNC_INFO
-};
-
-// toolhelp functions
-DECL_FUNC_PTR(CreateToolhelp32Snapshot);
-DECL_FUNC_PTR(Module32First);
-DECL_FUNC_PTR(Module32Next);
-
-FUNC_INFO toolhelp_fi[] = {
- MAKE_FUNC_INFO(CreateToolhelp32Snapshot),
- MAKE_FUNC_INFO(Module32First),
- MAKE_FUNC_INFO(Module32Next),
- END_FUNC_INFO
-};
-
-khm_int32 init_imports(void) {
- OSVERSIONINFO osvi;
- int imp_rv = 1;
-
-#define CKRV(m) \
- do { \
- if(!imp_rv) { \
- _reportf(L"Can't locate all required exports from module [%S]", (m)); \
- goto _err_ret; \
- } \
- } while (FALSE)
-
-#ifndef _WIN64
- imp_rv = LoadFuncs(KRB4_DLL, k4_fi, &hKrb4, 0, 1, 0, 0);
- CKRV(KRB4_DLL);
-#endif
-
- imp_rv = LoadFuncs(KRB5_DLL, k5_fi, &hKrb5, 0, 1, 0, 0);
- CKRV(KRB5_DLL);
-
- imp_rv = LoadFuncs(COMERR_DLL, ce_fi, &hComErr, 0, 0, 1, 0);
- CKRV(COMERR_DLL);
-
- imp_rv = LoadFuncs(SERVICE_DLL, service_fi, &hService, 0, 1, 0, 0);
- CKRV(SERVICE_DLL);
-
- imp_rv = LoadFuncs(SECUR32_DLL, lsa_fi, &hSecur32, 0, 1, 1, 1);
- CKRV(SECUR32_DLL);
-
- imp_rv = LoadFuncs(KRB524_DLL, k524_fi, &hKrb524, 0, 1, 1, 1);
- CKRV(KRB524_DLL);
-
- imp_rv = LoadFuncs(PROFILE_DLL, profile_fi, &hProfile, 0, 1, 0, 0);
- CKRV(PROFILE_DLL);
-
- imp_rv = LoadFuncs(CCAPI_DLL, ccapi_fi, &hCCAPI, 0, 1, 0, 0);
- /* CCAPI_DLL is optional. No error check. */
-
- memset(&osvi, 0, sizeof(OSVERSIONINFO));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&osvi);
-
- // XXX: We should really use feature testing, first
- // checking for CreateToolhelp32Snapshot. If that's
- // not around, we try the psapi stuff.
- //
- // Only load LSA functions if on NT/2000/XP
- if(osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
- {
- // Windows 9x
- imp_rv = LoadFuncs(TOOLHELPDLL, toolhelp_fi, &hToolHelp32, 0, 1, 0, 0);
- CKRV(TOOLHELPDLL);
-
- hPsapi = 0;
- }
- else if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
- {
- // Windows NT
- imp_rv = LoadFuncs(PSAPIDLL, psapi_fi, &hPsapi, 0, 1, 0, 0);
- CKRV(PSAPIDLL);
-
- hToolHelp32 = 0;
- }
-
- AfsAvailable = TRUE; //afscompat_init();
-
- return KHM_ERROR_SUCCESS;
-
- _err_ret:
- return KHM_ERROR_NOT_FOUND;
-}
-
-khm_int32 exit_imports(void) {
- //afscompat_close();
-
- if (hKrb4)
- FreeLibrary(hKrb4);
- if (hKrb5)
- FreeLibrary(hKrb5);
- if (hProfile)
- FreeLibrary(hProfile);
- if (hComErr)
- FreeLibrary(hComErr);
- if (hService)
- FreeLibrary(hService);
- if (hSecur32)
- FreeLibrary(hSecur32);
- if (hKrb524)
- FreeLibrary(hKrb524);
- if (hPsapi)
- FreeLibrary(hPsapi);
- if (hToolHelp32)
- FreeLibrary(hToolHelp32);
-
- return KHM_ERROR_SUCCESS;
-}
-
-int (*Lcom_err)(LPSTR,long,LPSTR,...);
-LPSTR (*Lerror_message)(long);
-LPSTR (*Lerror_table_name)(long);
-
-void Leash_load_com_err_callback(FARPROC ce,
- FARPROC em,
- FARPROC etn)
-{
- (FARPROC)Lcom_err=ce;
- (FARPROC)Lerror_message=em;
- (FARPROC)Lerror_table_name=etn;
-}
+/*
+* Copyright (c) 2005 Massachusetts Institute of Technology
+* Copyright (c) 2007 Secure Endpoints Inc.
+*
+* Permission is hereby granted, free of charge, to any person
+* obtaining a copy of this software and associated documentation
+* files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy,
+* modify, merge, publish, distribute, sublicense, and/or sell copies
+* of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*/
+
+/* $Id$ */
+
+#include<windows.h>
+#include<netidmgr.h>
+#include<dynimport.h>
+
+HINSTANCE hKrb4 = 0;
+HINSTANCE hKrb5 = 0;
+HINSTANCE hKrb524 = 0;
+HINSTANCE hSecur32 = 0;
+HINSTANCE hComErr = 0;
+HINSTANCE hService = 0;
+HINSTANCE hProfile = 0;
+HINSTANCE hPsapi = 0;
+HINSTANCE hToolHelp32 = 0;
+HINSTANCE hCCAPI = 0;
+
+DWORD AfsAvailable = 0;
+
+// CCAPI
+DECL_FUNC_PTR(cc_initialize);
+DECL_FUNC_PTR(cc_shutdown);
+DECL_FUNC_PTR(cc_get_NC_info);
+DECL_FUNC_PTR(cc_free_NC_info);
+
+// krb4 functions
+DECL_FUNC_PTR(get_krb_err_txt_entry);
+DECL_FUNC_PTR(k_isinst);
+DECL_FUNC_PTR(k_isname);
+DECL_FUNC_PTR(k_isrealm);
+DECL_FUNC_PTR(kadm_change_your_password);
+DECL_FUNC_PTR(kname_parse);
+DECL_FUNC_PTR(krb_get_cred);
+DECL_FUNC_PTR(krb_get_krbhst);
+DECL_FUNC_PTR(krb_get_lrealm);
+DECL_FUNC_PTR(krb_get_pw_in_tkt);
+DECL_FUNC_PTR(krb_get_tf_realm);
+DECL_FUNC_PTR(krb_mk_req);
+DECL_FUNC_PTR(krb_realmofhost);
+DECL_FUNC_PTR(tf_init);
+DECL_FUNC_PTR(tf_close);
+DECL_FUNC_PTR(tf_get_cred);
+DECL_FUNC_PTR(tf_get_pname);
+DECL_FUNC_PTR(tf_get_pinst);
+DECL_FUNC_PTR(LocalHostAddr);
+DECL_FUNC_PTR(tkt_string);
+DECL_FUNC_PTR(krb_set_tkt_string);
+DECL_FUNC_PTR(initialize_krb_error_func);
+DECL_FUNC_PTR(initialize_kadm_error_table);
+DECL_FUNC_PTR(dest_tkt);
+DECL_FUNC_PTR(krb_in_tkt);
+DECL_FUNC_PTR(krb_save_credentials);
+DECL_FUNC_PTR(krb_get_krbconf2);
+DECL_FUNC_PTR(krb_get_krbrealm2);
+DECL_FUNC_PTR(krb_life_to_time);
+
+// krb5 functions
+DECL_FUNC_PTR(krb5_change_password);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_init);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_set_tkt_life);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_set_forwardable);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_set_proxiable);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_set_address_list);
+DECL_FUNC_PTR(krb5_get_init_creds_opt_set_change_password_prompt);
+DECL_FUNC_PTR(krb5_get_init_creds_password);
+DECL_FUNC_PTR(krb5_get_prompt_types);
+DECL_FUNC_PTR(krb5_build_principal_ext);
+DECL_FUNC_PTR(krb5_cc_get_name);
+DECL_FUNC_PTR(krb5_cc_get_type);
+DECL_FUNC_PTR(krb5_cc_resolve);
+DECL_FUNC_PTR(krb5_cc_default);
+DECL_FUNC_PTR(krb5_cc_default_name);
+DECL_FUNC_PTR(krb5_cc_set_default_name);
+DECL_FUNC_PTR(krb5_cc_initialize);
+DECL_FUNC_PTR(krb5_cc_destroy);
+DECL_FUNC_PTR(krb5_cc_close);
+DECL_FUNC_PTR(krb5_cc_store_cred);
+DECL_FUNC_PTR(krb5_cc_copy_creds);
+DECL_FUNC_PTR(krb5_cc_retrieve_cred);
+DECL_FUNC_PTR(krb5_cc_get_principal);
+DECL_FUNC_PTR(krb5_cc_start_seq_get);
+DECL_FUNC_PTR(krb5_cc_next_cred);
+DECL_FUNC_PTR(krb5_cc_end_seq_get);
+DECL_FUNC_PTR(krb5_cc_remove_cred);
+DECL_FUNC_PTR(krb5_cc_set_flags);
+// DECL_FUNC_PTR(krb5_cc_get_type);
+DECL_FUNC_PTR(krb5_free_context);
+DECL_FUNC_PTR(krb5_free_cred_contents);
+DECL_FUNC_PTR(krb5_free_principal);
+DECL_FUNC_PTR(krb5_get_in_tkt_with_password);
+DECL_FUNC_PTR(krb5_init_context);
+DECL_FUNC_PTR(krb5_parse_name);
+DECL_FUNC_PTR(krb5_timeofday);
+DECL_FUNC_PTR(krb5_timestamp_to_sfstring);
+DECL_FUNC_PTR(krb5_unparse_name);
+DECL_FUNC_PTR(krb5_get_credentials);
+DECL_FUNC_PTR(krb5_mk_req);
+DECL_FUNC_PTR(krb5_sname_to_principal);
+DECL_FUNC_PTR(krb5_get_credentials_renew);
+DECL_FUNC_PTR(krb5_free_data);
+DECL_FUNC_PTR(krb5_free_data_contents);
+// DECL_FUNC_PTR(krb5_get_realm_domain);
+DECL_FUNC_PTR(krb5_free_unparsed_name);
+DECL_FUNC_PTR(krb5_os_localaddr);
+DECL_FUNC_PTR(krb5_copy_keyblock_contents);
+DECL_FUNC_PTR(krb5_copy_data);
+DECL_FUNC_PTR(krb5_free_creds);
+DECL_FUNC_PTR(krb5_build_principal);
+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_set_default_realm);
+DECL_FUNC_PTR(krb5_free_ticket);
+DECL_FUNC_PTR(krb5_decode_ticket);
+DECL_FUNC_PTR(krb5_get_host_realm);
+DECL_FUNC_PTR(krb5_free_host_realm);
+DECL_FUNC_PTR(krb5_c_random_make_octets);
+DECL_FUNC_PTR(krb5_free_addresses);
+DECL_FUNC_PTR(krb5_free_default_realm);
+DECL_FUNC_PTR(krb5_string_to_deltat);
+
+// Krb524 functions
+DECL_FUNC_PTR(krb524_init_ets);
+DECL_FUNC_PTR(krb524_convert_creds_kdc);
+
+// ComErr functions
+DECL_FUNC_PTR(com_err);
+DECL_FUNC_PTR(error_message);
+
+// Profile functions
+DECL_FUNC_PTR(profile_init);
+DECL_FUNC_PTR(profile_flush);
+DECL_FUNC_PTR(profile_release);
+DECL_FUNC_PTR(profile_get_subsection_names);
+DECL_FUNC_PTR(profile_free_list);
+DECL_FUNC_PTR(profile_get_string);
+DECL_FUNC_PTR(profile_get_integer);
+DECL_FUNC_PTR(profile_get_values);
+DECL_FUNC_PTR(profile_get_relation_names);
+DECL_FUNC_PTR(profile_clear_relation);
+DECL_FUNC_PTR(profile_add_relation);
+DECL_FUNC_PTR(profile_update_relation);
+DECL_FUNC_PTR(profile_release_string);
+DECL_FUNC_PTR(profile_rename_section);
+
+// Service functions
+DECL_FUNC_PTR(OpenSCManagerA);
+DECL_FUNC_PTR(OpenServiceA);
+DECL_FUNC_PTR(QueryServiceStatus);
+DECL_FUNC_PTR(CloseServiceHandle);
+DECL_FUNC_PTR(LsaNtStatusToWinError);
+
+// LSA Functions
+DECL_FUNC_PTR(LsaConnectUntrusted);
+DECL_FUNC_PTR(LsaLookupAuthenticationPackage);
+DECL_FUNC_PTR(LsaCallAuthenticationPackage);
+DECL_FUNC_PTR(LsaFreeReturnBuffer);
+DECL_FUNC_PTR(LsaGetLogonSessionData);
+
+// CCAPI
+FUNC_INFO ccapi_fi[] = {
+ MAKE_FUNC_INFO(cc_initialize),
+ MAKE_FUNC_INFO(cc_shutdown),
+ MAKE_FUNC_INFO(cc_get_NC_info),
+ MAKE_FUNC_INFO(cc_free_NC_info),
+ END_FUNC_INFO
+};
+
+FUNC_INFO k4_fi[] = {
+ MAKE_FUNC_INFO(get_krb_err_txt_entry),
+ MAKE_FUNC_INFO(k_isinst),
+ MAKE_FUNC_INFO(k_isname),
+ MAKE_FUNC_INFO(k_isrealm),
+ MAKE_FUNC_INFO(kadm_change_your_password),
+ MAKE_FUNC_INFO(kname_parse),
+ MAKE_FUNC_INFO(krb_get_cred),
+ MAKE_FUNC_INFO(krb_get_krbhst),
+ MAKE_FUNC_INFO(krb_get_lrealm),
+ MAKE_FUNC_INFO(krb_get_pw_in_tkt),
+ MAKE_FUNC_INFO(krb_get_tf_realm),
+ MAKE_FUNC_INFO(krb_mk_req),
+ MAKE_FUNC_INFO(krb_realmofhost),
+ MAKE_FUNC_INFO(tf_init),
+ MAKE_FUNC_INFO(tf_close),
+ MAKE_FUNC_INFO(tf_get_cred),
+ MAKE_FUNC_INFO(tf_get_pname),
+ MAKE_FUNC_INFO(tf_get_pinst),
+ MAKE_FUNC_INFO(LocalHostAddr),
+ MAKE_FUNC_INFO(tkt_string),
+ MAKE_FUNC_INFO(krb_set_tkt_string),
+ MAKE_FUNC_INFO(initialize_krb_error_func),
+ MAKE_FUNC_INFO(initialize_kadm_error_table),
+ MAKE_FUNC_INFO(dest_tkt),
+ /* MAKE_FUNC_INFO(lsh_LoadKrb4LeashErrorTables), */// XXX
+ MAKE_FUNC_INFO(krb_in_tkt),
+ MAKE_FUNC_INFO(krb_save_credentials),
+ MAKE_FUNC_INFO(krb_get_krbconf2),
+ MAKE_FUNC_INFO(krb_get_krbrealm2),
+ MAKE_FUNC_INFO(krb_life_to_time),
+ END_FUNC_INFO
+};
+
+FUNC_INFO k5_fi[] = {
+ MAKE_FUNC_INFO(krb5_change_password),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_init),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_tkt_life),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_renew_life),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_forwardable),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_proxiable),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_address_list),
+ MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_change_password_prompt),
+ MAKE_FUNC_INFO(krb5_get_init_creds_password),
+ MAKE_FUNC_INFO(krb5_get_prompt_types),
+ MAKE_FUNC_INFO(krb5_build_principal_ext),
+ MAKE_FUNC_INFO(krb5_cc_get_name),
+ MAKE_FUNC_INFO(krb5_cc_get_type),
+ MAKE_FUNC_INFO(krb5_cc_resolve),
+ MAKE_FUNC_INFO(krb5_cc_default),
+ MAKE_FUNC_INFO(krb5_cc_default_name),
+ MAKE_FUNC_INFO(krb5_cc_set_default_name),
+ MAKE_FUNC_INFO(krb5_cc_initialize),
+ MAKE_FUNC_INFO(krb5_cc_destroy),
+ MAKE_FUNC_INFO(krb5_cc_close),
+ MAKE_FUNC_INFO(krb5_cc_copy_creds),
+ MAKE_FUNC_INFO(krb5_cc_store_cred),
+ MAKE_FUNC_INFO(krb5_cc_retrieve_cred),
+ MAKE_FUNC_INFO(krb5_cc_get_principal),
+ MAKE_FUNC_INFO(krb5_cc_start_seq_get),
+ MAKE_FUNC_INFO(krb5_cc_next_cred),
+ MAKE_FUNC_INFO(krb5_cc_end_seq_get),
+ MAKE_FUNC_INFO(krb5_cc_remove_cred),
+ MAKE_FUNC_INFO(krb5_cc_set_flags),
+ // MAKE_FUNC_INFO(krb5_cc_get_type),
+ MAKE_FUNC_INFO(krb5_free_context),
+ MAKE_FUNC_INFO(krb5_free_cred_contents),
+ MAKE_FUNC_INFO(krb5_free_principal),
+ MAKE_FUNC_INFO(krb5_get_in_tkt_with_password),
+ MAKE_FUNC_INFO(krb5_init_context),
+ MAKE_FUNC_INFO(krb5_parse_name),
+ MAKE_FUNC_INFO(krb5_timeofday),
+ MAKE_FUNC_INFO(krb5_timestamp_to_sfstring),
+ MAKE_FUNC_INFO(krb5_unparse_name),
+ MAKE_FUNC_INFO(krb5_get_credentials),
+ MAKE_FUNC_INFO(krb5_mk_req),
+ MAKE_FUNC_INFO(krb5_sname_to_principal),
+ MAKE_FUNC_INFO(krb5_get_credentials_renew),
+ MAKE_FUNC_INFO(krb5_free_data),
+ MAKE_FUNC_INFO(krb5_free_data_contents),
+ // MAKE_FUNC_INFO(krb5_get_realm_domain),
+ MAKE_FUNC_INFO(krb5_free_unparsed_name),
+ MAKE_FUNC_INFO(krb5_os_localaddr),
+ MAKE_FUNC_INFO(krb5_copy_keyblock_contents),
+ MAKE_FUNC_INFO(krb5_copy_data),
+ MAKE_FUNC_INFO(krb5_free_creds),
+ MAKE_FUNC_INFO(krb5_build_principal),
+ MAKE_FUNC_INFO(krb5_get_renewed_creds),
+ MAKE_FUNC_INFO(krb5_free_addresses),
+ 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_set_default_realm),
+ MAKE_FUNC_INFO(krb5_free_ticket),
+ MAKE_FUNC_INFO(krb5_decode_ticket),
+ MAKE_FUNC_INFO(krb5_get_host_realm),
+ MAKE_FUNC_INFO(krb5_free_host_realm),
+ MAKE_FUNC_INFO(krb5_c_random_make_octets),
+ MAKE_FUNC_INFO(krb5_free_default_realm),
+ MAKE_FUNC_INFO(krb5_string_to_deltat),
+ END_FUNC_INFO
+};
+
+FUNC_INFO k524_fi[] = {
+ MAKE_FUNC_INFO(krb524_init_ets),
+ MAKE_FUNC_INFO(krb524_convert_creds_kdc),
+ END_FUNC_INFO
+};
+
+FUNC_INFO profile_fi[] = {
+ MAKE_FUNC_INFO(profile_init),
+ MAKE_FUNC_INFO(profile_flush),
+ MAKE_FUNC_INFO(profile_release),
+ MAKE_FUNC_INFO(profile_get_subsection_names),
+ MAKE_FUNC_INFO(profile_free_list),
+ MAKE_FUNC_INFO(profile_get_string),
+ MAKE_FUNC_INFO(profile_get_integer),
+ MAKE_FUNC_INFO(profile_get_values),
+ MAKE_FUNC_INFO(profile_get_relation_names),
+ MAKE_FUNC_INFO(profile_clear_relation),
+ MAKE_FUNC_INFO(profile_add_relation),
+ MAKE_FUNC_INFO(profile_update_relation),
+ MAKE_FUNC_INFO(profile_release_string),
+ MAKE_FUNC_INFO(profile_rename_section),
+ END_FUNC_INFO
+};
+
+FUNC_INFO ce_fi[] = {
+ MAKE_FUNC_INFO(com_err),
+ MAKE_FUNC_INFO(error_message),
+ END_FUNC_INFO
+};
+
+FUNC_INFO service_fi[] = {
+ MAKE_FUNC_INFO(OpenSCManagerA),
+ MAKE_FUNC_INFO(OpenServiceA),
+ MAKE_FUNC_INFO(QueryServiceStatus),
+ MAKE_FUNC_INFO(CloseServiceHandle),
+ MAKE_FUNC_INFO(LsaNtStatusToWinError),
+ END_FUNC_INFO
+};
+
+FUNC_INFO lsa_fi[] = {
+ MAKE_FUNC_INFO(LsaConnectUntrusted),
+ MAKE_FUNC_INFO(LsaLookupAuthenticationPackage),
+ MAKE_FUNC_INFO(LsaCallAuthenticationPackage),
+ MAKE_FUNC_INFO(LsaFreeReturnBuffer),
+ MAKE_FUNC_INFO(LsaGetLogonSessionData),
+ END_FUNC_INFO
+};
+
+// psapi functions
+DECL_FUNC_PTR(GetModuleFileNameExA);
+DECL_FUNC_PTR(EnumProcessModules);
+
+FUNC_INFO psapi_fi[] = {
+ MAKE_FUNC_INFO(GetModuleFileNameExA),
+ MAKE_FUNC_INFO(EnumProcessModules),
+ END_FUNC_INFO
+};
+
+// toolhelp functions
+DECL_FUNC_PTR(CreateToolhelp32Snapshot);
+DECL_FUNC_PTR(Module32First);
+DECL_FUNC_PTR(Module32Next);
+
+FUNC_INFO toolhelp_fi[] = {
+ MAKE_FUNC_INFO(CreateToolhelp32Snapshot),
+ MAKE_FUNC_INFO(Module32First),
+ MAKE_FUNC_INFO(Module32Next),
+ END_FUNC_INFO
+};
+
+khm_int32 init_imports(void) {
+ OSVERSIONINFO osvi;
+ int imp_rv = 1;
+
+#define CKRV(m) \
+ do { \
+ if(!imp_rv) { \
+ _reportf(L"Can't locate all required exports from module [%S]", (m)); \
+ goto _err_ret; \
+ } \
+ } while (FALSE)
+
+#ifndef _WIN64
+ imp_rv = LoadFuncs(KRB4_DLL, k4_fi, &hKrb4, 0, 1, 0, 0);
+ CKRV(KRB4_DLL);
+#endif
+
+ imp_rv = LoadFuncs(KRB5_DLL, k5_fi, &hKrb5, 0, 1, 0, 0);
+ CKRV(KRB5_DLL);
+
+ imp_rv = LoadFuncs(COMERR_DLL, ce_fi, &hComErr, 0, 0, 1, 0);
+ CKRV(COMERR_DLL);
+
+ imp_rv = LoadFuncs(SERVICE_DLL, service_fi, &hService, 0, 1, 0, 0);
+ CKRV(SERVICE_DLL);
+
+ imp_rv = LoadFuncs(SECUR32_DLL, lsa_fi, &hSecur32, 0, 1, 1, 1);
+ CKRV(SECUR32_DLL);
+
+ imp_rv = LoadFuncs(KRB524_DLL, k524_fi, &hKrb524, 0, 1, 1, 1);
+ CKRV(KRB524_DLL);
+
+ imp_rv = LoadFuncs(PROFILE_DLL, profile_fi, &hProfile, 0, 1, 0, 0);
+ CKRV(PROFILE_DLL);
+
+ imp_rv = LoadFuncs(CCAPI_DLL, ccapi_fi, &hCCAPI, 0, 1, 0, 0);
+ /* CCAPI_DLL is optional. No error check. */
+
+ memset(&osvi, 0, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osvi);
+
+ // XXX: We should really use feature testing, first
+ // checking for CreateToolhelp32Snapshot. If that's
+ // not around, we try the psapi stuff.
+ //
+ // Only load LSA functions if on NT/2000/XP
+ if(osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+ {
+ // Windows 9x
+ imp_rv = LoadFuncs(TOOLHELPDLL, toolhelp_fi, &hToolHelp32, 0, 1, 0, 0);
+ CKRV(TOOLHELPDLL);
+
+ hPsapi = 0;
+ }
+ else if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
+ {
+ // Windows NT
+ imp_rv = LoadFuncs(PSAPIDLL, psapi_fi, &hPsapi, 0, 1, 0, 0);
+ CKRV(PSAPIDLL);
+
+ hToolHelp32 = 0;
+ }
+
+ AfsAvailable = TRUE; //afscompat_init();
+
+ return KHM_ERROR_SUCCESS;
+
+ _err_ret:
+ return KHM_ERROR_NOT_FOUND;
+}
+
+khm_int32 exit_imports(void) {
+ //afscompat_close();
+
+ if (hKrb4)
+ FreeLibrary(hKrb4);
+ if (hKrb5)
+ FreeLibrary(hKrb5);
+ if (hProfile)
+ FreeLibrary(hProfile);
+ if (hComErr)
+ FreeLibrary(hComErr);
+ if (hService)
+ FreeLibrary(hService);
+ if (hSecur32)
+ FreeLibrary(hSecur32);
+ if (hKrb524)
+ FreeLibrary(hKrb524);
+ if (hPsapi)
+ FreeLibrary(hPsapi);
+ if (hToolHelp32)
+ FreeLibrary(hToolHelp32);
+
+ return KHM_ERROR_SUCCESS;
+}
+
+int (*Lcom_err)(LPSTR,long,LPSTR,...);
+LPSTR (*Lerror_message)(long);
+LPSTR (*Lerror_table_name)(long);
+
+void Leash_load_com_err_callback(FARPROC ce,
+ FARPROC em,
+ FARPROC etn)
+{
+ (FARPROC)Lcom_err=ce;
+ (FARPROC)Lerror_message=em;
+ (FARPROC)Lerror_table_name=etn;
+}
diff --git a/src/windows/identity/plugins/common/dynimport.h b/src/windows/identity/plugins/common/dynimport.h
index 7f3f598b0..850d96e5f 100644
--- a/src/windows/identity/plugins/common/dynimport.h
+++ b/src/windows/identity/plugins/common/dynimport.h
@@ -1,361 +1,361 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef __KHIMAIRA_DYNIMPORT_H
-#define __KHIMAIRA_DYNIMPORT_H
-
-/* Dynamic imports */
-#include<khdefs.h>
-#include<tlhelp32.h>
-
-#if _WIN32_WINNT < 0x0501
-#define KHM_SAVE_WIN32_WINNT _WIN32_WINNT
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-#include<ntsecapi.h>
-#ifdef KHM_SAVE_WIN32_WINNT
-#undef _WIN32_WINNT
-#define _WIN32_WINNT KHM_SAVE_WIN32_WINNT
-#undef KHM_SAVE_WIN32_WINNT
-#endif
-
-extern HINSTANCE hKrb4;
-extern HINSTANCE hKrb5;
-extern HINSTANCE hProfile;
-
-///////////////////////////////////////////////////////////////////////////////
-
-#define CCAPI_DLL "krbcc32.dll"
-#define KRBCC32_DLL "krbcc32.dll"
-#define SERVICE_DLL "advapi32.dll"
-#define SECUR32_DLL "secur32.dll"
-#define PROFILE_DLL "xpprof32.dll"
-
-//////////////////////////////////////////////////////////////////////////////
-
-#include <loadfuncs-com_err.h>
-#include <loadfuncs-krb5.h>
-#include <loadfuncs-profile.h>
-#include <loadfuncs-krb.h>
-#include <loadfuncs-krb524.h>
-#include <loadfuncs-lsa.h>
-
-//// CCAPI
-/* In order to avoid including the private CCAPI headers */
-typedef int cc_int32;
-
-#define CC_API_VER_1 1
-#define CC_API_VER_2 2
-
-#define CCACHE_API cc_int32
-
-/*
-** The Official Error Codes
-*/
-#define CC_NOERROR 0
-#define CC_BADNAME 1
-#define CC_NOTFOUND 2
-#define CC_END 3
-#define CC_IO 4
-#define CC_WRITE 5
-#define CC_NOMEM 6
-#define CC_FORMAT 7
-#define CC_LOCKED 8
-#define CC_BAD_API_VERSION 9
-#define CC_NO_EXIST 10
-#define CC_NOT_SUPP 11
-#define CC_BAD_PARM 12
-#define CC_ERR_CACHE_ATTACH 13
-#define CC_ERR_CACHE_RELEASE 14
-#define CC_ERR_CACHE_FULL 15
-#define CC_ERR_CRED_VERSION 16
-
-enum {
- CC_CRED_VUNKNOWN = 0, // For validation
- CC_CRED_V4 = 1,
- CC_CRED_V5 = 2,
- CC_CRED_VMAX = 3 // For validation
-};
-
-typedef struct opaque_dll_control_block_type* apiCB;
-typedef struct _infoNC {
- char* name;
- char* principal;
- cc_int32 vers;
-} infoNC;
-
-TYPEDEF_FUNC(
-CCACHE_API,
-CALLCONV_C,
-cc_initialize,
- (
- apiCB** cc_ctx, // < DLL's primary control structure.
- // returned here, passed everywhere else
- cc_int32 api_version, // > ver supported by caller (use CC_API_VER_1)
- cc_int32* api_supported, // < if ~NULL, max ver supported by DLL
- const char** vendor // < if ~NULL, vendor name in read only C string
- )
-);
-
-TYPEDEF_FUNC(
-CCACHE_API,
-CALLCONV_C,
-cc_shutdown,
- (
- apiCB** cc_ctx // <> DLL's primary control structure. NULL after
- )
-);
-
-TYPEDEF_FUNC(
-CCACHE_API,
-CALLCONV_C,
-cc_get_NC_info,
- (
- apiCB* cc_ctx, // > DLL's primary control structure
- struct _infoNC*** ppNCi // < (NULL before call) null terminated,
- // list of a structs (free via cc_free_infoNC())
- )
-);
-
-TYPEDEF_FUNC(
-CCACHE_API,
-CALLCONV_C,
-cc_free_NC_info,
- (
- apiCB* cc_ctx,
- struct _infoNC*** ppNCi // < free list of structs returned by
- // cc_get_cache_names(). set to NULL on return
- )
-);
-//// \CCAPI
-
-extern DWORD AfsAvailable;
-
-// service definitions
-typedef SC_HANDLE (WINAPI *FP_OpenSCManagerA)(char *, char *, DWORD);
-typedef SC_HANDLE (WINAPI *FP_OpenServiceA)(SC_HANDLE, char *, DWORD);
-typedef BOOL (WINAPI *FP_QueryServiceStatus)(SC_HANDLE, LPSERVICE_STATUS);
-typedef BOOL (WINAPI *FP_CloseServiceHandle)(SC_HANDLE);
-
-//////////////////////////////////////////////////////////////////////////////
-
-// CCAPI
-extern DECL_FUNC_PTR(cc_initialize);
-extern DECL_FUNC_PTR(cc_shutdown);
-extern DECL_FUNC_PTR(cc_get_NC_info);
-extern DECL_FUNC_PTR(cc_free_NC_info);
-
-// krb4 functions
-extern DECL_FUNC_PTR(get_krb_err_txt_entry);
-extern DECL_FUNC_PTR(k_isinst);
-extern DECL_FUNC_PTR(k_isname);
-extern DECL_FUNC_PTR(k_isrealm);
-extern DECL_FUNC_PTR(kadm_change_your_password);
-extern DECL_FUNC_PTR(kname_parse);
-extern DECL_FUNC_PTR(krb_get_cred);
-extern DECL_FUNC_PTR(krb_get_krbhst);
-extern DECL_FUNC_PTR(krb_get_lrealm);
-extern DECL_FUNC_PTR(krb_get_pw_in_tkt);
-extern DECL_FUNC_PTR(krb_get_tf_realm);
-extern DECL_FUNC_PTR(krb_mk_req);
-extern DECL_FUNC_PTR(krb_realmofhost);
-extern DECL_FUNC_PTR(tf_init);
-extern DECL_FUNC_PTR(tf_close);
-extern DECL_FUNC_PTR(tf_get_cred);
-extern DECL_FUNC_PTR(tf_get_pname);
-extern DECL_FUNC_PTR(tf_get_pinst);
-extern DECL_FUNC_PTR(LocalHostAddr);
-extern DECL_FUNC_PTR(tkt_string);
-extern DECL_FUNC_PTR(krb_set_tkt_string);
-extern DECL_FUNC_PTR(initialize_krb_error_func);
-extern DECL_FUNC_PTR(initialize_kadm_error_table);
-extern DECL_FUNC_PTR(dest_tkt);
-extern DECL_FUNC_PTR(lsh_LoadKrb4LeashErrorTables); // XXX
-extern DECL_FUNC_PTR(krb_in_tkt);
-extern DECL_FUNC_PTR(krb_save_credentials);
-extern DECL_FUNC_PTR(krb_get_krbconf2);
-extern DECL_FUNC_PTR(krb_get_krbrealm2);
-extern DECL_FUNC_PTR(krb_life_to_time);
-
-// krb5 functions
-extern DECL_FUNC_PTR(krb5_change_password);
-extern DECL_FUNC_PTR(krb5_get_init_creds_opt_init);
-extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_tkt_life);
-extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life);
-extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_forwardable);
-extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_proxiable);
-extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life);
-extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_address_list);
-extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_change_password_prompt);
-extern DECL_FUNC_PTR(krb5_get_init_creds_password);
-extern DECL_FUNC_PTR(krb5_get_prompt_types);
-extern DECL_FUNC_PTR(krb5_build_principal_ext);
-extern DECL_FUNC_PTR(krb5_cc_get_name);
-extern DECL_FUNC_PTR(krb5_cc_get_type);
-extern DECL_FUNC_PTR(krb5_cc_resolve);
-extern DECL_FUNC_PTR(krb5_cc_default);
-extern DECL_FUNC_PTR(krb5_cc_default_name);
-extern DECL_FUNC_PTR(krb5_cc_set_default_name);
-extern DECL_FUNC_PTR(krb5_cc_initialize);
-extern DECL_FUNC_PTR(krb5_cc_destroy);
-extern DECL_FUNC_PTR(krb5_cc_close);
-extern DECL_FUNC_PTR(krb5_cc_copy_creds);
-extern DECL_FUNC_PTR(krb5_cc_store_cred);
-extern DECL_FUNC_PTR(krb5_cc_retrieve_cred);
-extern DECL_FUNC_PTR(krb5_cc_get_principal);
-extern DECL_FUNC_PTR(krb5_cc_start_seq_get);
-extern DECL_FUNC_PTR(krb5_cc_next_cred);
-extern DECL_FUNC_PTR(krb5_cc_end_seq_get);
-extern DECL_FUNC_PTR(krb5_cc_remove_cred);
-extern DECL_FUNC_PTR(krb5_cc_set_flags);
-// extern DECL_FUNC_PTR(krb5_cc_get_type);
-extern DECL_FUNC_PTR(krb5_free_context);
-extern DECL_FUNC_PTR(krb5_free_cred_contents);
-extern DECL_FUNC_PTR(krb5_free_principal);
-extern DECL_FUNC_PTR(krb5_get_in_tkt_with_password);
-extern DECL_FUNC_PTR(krb5_init_context);
-extern DECL_FUNC_PTR(krb5_parse_name);
-extern DECL_FUNC_PTR(krb5_timeofday);
-extern DECL_FUNC_PTR(krb5_timestamp_to_sfstring);
-extern DECL_FUNC_PTR(krb5_unparse_name);
-extern DECL_FUNC_PTR(krb5_get_credentials);
-extern DECL_FUNC_PTR(krb5_mk_req);
-extern DECL_FUNC_PTR(krb5_sname_to_principal);
-extern DECL_FUNC_PTR(krb5_get_credentials_renew);
-extern DECL_FUNC_PTR(krb5_free_data);
-extern DECL_FUNC_PTR(krb5_free_data_contents);
-// extern DECL_FUNC_PTR(krb5_get_realm_domain);
-extern DECL_FUNC_PTR(krb5_free_unparsed_name);
-extern DECL_FUNC_PTR(krb5_os_localaddr);
-extern DECL_FUNC_PTR(krb5_copy_keyblock_contents);
-extern DECL_FUNC_PTR(krb5_copy_data);
-extern DECL_FUNC_PTR(krb5_free_creds);
-extern DECL_FUNC_PTR(krb5_build_principal);
-extern DECL_FUNC_PTR(krb5_get_renewed_creds);
-extern DECL_FUNC_PTR(krb5_free_addresses);
-extern DECL_FUNC_PTR(krb5_get_default_config_files);
-extern DECL_FUNC_PTR(krb5_free_config_files);
-extern DECL_FUNC_PTR(krb5_get_default_realm);
-extern DECL_FUNC_PTR(krb5_set_default_realm);
-extern DECL_FUNC_PTR(krb5_free_ticket);
-extern DECL_FUNC_PTR(krb5_decode_ticket);
-extern DECL_FUNC_PTR(krb5_get_host_realm);
-extern DECL_FUNC_PTR(krb5_free_host_realm);
-extern DECL_FUNC_PTR(krb5_c_random_make_octets);
-extern DECL_FUNC_PTR(krb5_free_default_realm);
-extern DECL_FUNC_PTR(krb5_string_to_deltat);
-
-// Krb524 functions
-extern DECL_FUNC_PTR(krb524_init_ets);
-extern DECL_FUNC_PTR(krb524_convert_creds_kdc);
-
-// ComErr functions
-extern DECL_FUNC_PTR(com_err);
-extern DECL_FUNC_PTR(error_message);
-
-// Profile functions
-extern DECL_FUNC_PTR(profile_init);
-extern DECL_FUNC_PTR(profile_flush);
-extern DECL_FUNC_PTR(profile_release);
-extern DECL_FUNC_PTR(profile_get_subsection_names);
-extern DECL_FUNC_PTR(profile_free_list);
-extern DECL_FUNC_PTR(profile_get_string);
-extern DECL_FUNC_PTR(profile_get_integer);
-extern DECL_FUNC_PTR(profile_get_values);
-extern DECL_FUNC_PTR(profile_get_relation_names);
-extern DECL_FUNC_PTR(profile_clear_relation);
-extern DECL_FUNC_PTR(profile_add_relation);
-extern DECL_FUNC_PTR(profile_update_relation);
-extern DECL_FUNC_PTR(profile_release_string);
-extern DECL_FUNC_PTR(profile_rename_section);
-
-// Service functions
-extern DECL_FUNC_PTR(OpenSCManagerA);
-extern DECL_FUNC_PTR(OpenServiceA);
-extern DECL_FUNC_PTR(QueryServiceStatus);
-extern DECL_FUNC_PTR(CloseServiceHandle);
-extern DECL_FUNC_PTR(LsaNtStatusToWinError);
-
-// LSA Functions
-extern DECL_FUNC_PTR(LsaConnectUntrusted);
-extern DECL_FUNC_PTR(LsaLookupAuthenticationPackage);
-extern DECL_FUNC_PTR(LsaCallAuthenticationPackage);
-extern DECL_FUNC_PTR(LsaFreeReturnBuffer);
-extern DECL_FUNC_PTR(LsaGetLogonSessionData);
-
-// toolhelp functions
-TYPEDEF_FUNC(
- HANDLE,
- WINAPI,
- CreateToolhelp32Snapshot,
- (DWORD, DWORD)
- );
-TYPEDEF_FUNC(
- BOOL,
- WINAPI,
- Module32First,
- (HANDLE, LPMODULEENTRY32)
- );
-TYPEDEF_FUNC(
- BOOL,
- WINAPI,
- Module32Next,
- (HANDLE, LPMODULEENTRY32)
- );
-
-// psapi functions
-TYPEDEF_FUNC(
- DWORD,
- WINAPI,
- GetModuleFileNameExA,
- (HANDLE, HMODULE, LPSTR, DWORD)
- );
-
-TYPEDEF_FUNC(
- BOOL,
- WINAPI,
- EnumProcessModules,
- (HANDLE, HMODULE*, DWORD, LPDWORD)
- );
-
-#define pGetModuleFileNameEx pGetModuleFileNameExA
-#define TOOLHELPDLL "kernel32.dll"
-#define PSAPIDLL "psapi.dll"
-
-// psapi functions
-extern DECL_FUNC_PTR(GetModuleFileNameExA);
-extern DECL_FUNC_PTR(EnumProcessModules);
-
-// toolhelp functions
-extern DECL_FUNC_PTR(CreateToolhelp32Snapshot);
-extern DECL_FUNC_PTR(Module32First);
-extern DECL_FUNC_PTR(Module32Next);
-
-khm_int32 init_imports(void);
-khm_int32 exit_imports(void);
-
-#endif
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef __KHIMAIRA_DYNIMPORT_H
+#define __KHIMAIRA_DYNIMPORT_H
+
+/* Dynamic imports */
+#include<khdefs.h>
+#include<tlhelp32.h>
+
+#if _WIN32_WINNT < 0x0501
+#define KHM_SAVE_WIN32_WINNT _WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
+#include<ntsecapi.h>
+#ifdef KHM_SAVE_WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT KHM_SAVE_WIN32_WINNT
+#undef KHM_SAVE_WIN32_WINNT
+#endif
+
+extern HINSTANCE hKrb4;
+extern HINSTANCE hKrb5;
+extern HINSTANCE hProfile;
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define CCAPI_DLL "krbcc32.dll"
+#define KRBCC32_DLL "krbcc32.dll"
+#define SERVICE_DLL "advapi32.dll"
+#define SECUR32_DLL "secur32.dll"
+#define PROFILE_DLL "xpprof32.dll"
+
+//////////////////////////////////////////////////////////////////////////////
+
+#include <loadfuncs-com_err.h>
+#include <loadfuncs-krb5.h>
+#include <loadfuncs-profile.h>
+#include <loadfuncs-krb.h>
+#include <loadfuncs-krb524.h>
+#include <loadfuncs-lsa.h>
+
+//// CCAPI
+/* In order to avoid including the private CCAPI headers */
+typedef int cc_int32;
+
+#define CC_API_VER_1 1
+#define CC_API_VER_2 2
+
+#define CCACHE_API cc_int32
+
+/*
+** The Official Error Codes
+*/
+#define CC_NOERROR 0
+#define CC_BADNAME 1
+#define CC_NOTFOUND 2
+#define CC_END 3
+#define CC_IO 4
+#define CC_WRITE 5
+#define CC_NOMEM 6
+#define CC_FORMAT 7
+#define CC_LOCKED 8
+#define CC_BAD_API_VERSION 9
+#define CC_NO_EXIST 10
+#define CC_NOT_SUPP 11
+#define CC_BAD_PARM 12
+#define CC_ERR_CACHE_ATTACH 13
+#define CC_ERR_CACHE_RELEASE 14
+#define CC_ERR_CACHE_FULL 15
+#define CC_ERR_CRED_VERSION 16
+
+enum {
+ CC_CRED_VUNKNOWN = 0, // For validation
+ CC_CRED_V4 = 1,
+ CC_CRED_V5 = 2,
+ CC_CRED_VMAX = 3 // For validation
+};
+
+typedef struct opaque_dll_control_block_type* apiCB;
+typedef struct _infoNC {
+ char* name;
+ char* principal;
+ cc_int32 vers;
+} infoNC;
+
+TYPEDEF_FUNC(
+CCACHE_API,
+CALLCONV_C,
+cc_initialize,
+ (
+ apiCB** cc_ctx, // < DLL's primary control structure.
+ // returned here, passed everywhere else
+ cc_int32 api_version, // > ver supported by caller (use CC_API_VER_1)
+ cc_int32* api_supported, // < if ~NULL, max ver supported by DLL
+ const char** vendor // < if ~NULL, vendor name in read only C string
+ )
+);
+
+TYPEDEF_FUNC(
+CCACHE_API,
+CALLCONV_C,
+cc_shutdown,
+ (
+ apiCB** cc_ctx // <> DLL's primary control structure. NULL after
+ )
+);
+
+TYPEDEF_FUNC(
+CCACHE_API,
+CALLCONV_C,
+cc_get_NC_info,
+ (
+ apiCB* cc_ctx, // > DLL's primary control structure
+ struct _infoNC*** ppNCi // < (NULL before call) null terminated,
+ // list of a structs (free via cc_free_infoNC())
+ )
+);
+
+TYPEDEF_FUNC(
+CCACHE_API,
+CALLCONV_C,
+cc_free_NC_info,
+ (
+ apiCB* cc_ctx,
+ struct _infoNC*** ppNCi // < free list of structs returned by
+ // cc_get_cache_names(). set to NULL on return
+ )
+);
+//// \CCAPI
+
+extern DWORD AfsAvailable;
+
+// service definitions
+typedef SC_HANDLE (WINAPI *FP_OpenSCManagerA)(char *, char *, DWORD);
+typedef SC_HANDLE (WINAPI *FP_OpenServiceA)(SC_HANDLE, char *, DWORD);
+typedef BOOL (WINAPI *FP_QueryServiceStatus)(SC_HANDLE, LPSERVICE_STATUS);
+typedef BOOL (WINAPI *FP_CloseServiceHandle)(SC_HANDLE);
+
+//////////////////////////////////////////////////////////////////////////////
+
+// CCAPI
+extern DECL_FUNC_PTR(cc_initialize);
+extern DECL_FUNC_PTR(cc_shutdown);
+extern DECL_FUNC_PTR(cc_get_NC_info);
+extern DECL_FUNC_PTR(cc_free_NC_info);
+
+// krb4 functions
+extern DECL_FUNC_PTR(get_krb_err_txt_entry);
+extern DECL_FUNC_PTR(k_isinst);
+extern DECL_FUNC_PTR(k_isname);
+extern DECL_FUNC_PTR(k_isrealm);
+extern DECL_FUNC_PTR(kadm_change_your_password);
+extern DECL_FUNC_PTR(kname_parse);
+extern DECL_FUNC_PTR(krb_get_cred);
+extern DECL_FUNC_PTR(krb_get_krbhst);
+extern DECL_FUNC_PTR(krb_get_lrealm);
+extern DECL_FUNC_PTR(krb_get_pw_in_tkt);
+extern DECL_FUNC_PTR(krb_get_tf_realm);
+extern DECL_FUNC_PTR(krb_mk_req);
+extern DECL_FUNC_PTR(krb_realmofhost);
+extern DECL_FUNC_PTR(tf_init);
+extern DECL_FUNC_PTR(tf_close);
+extern DECL_FUNC_PTR(tf_get_cred);
+extern DECL_FUNC_PTR(tf_get_pname);
+extern DECL_FUNC_PTR(tf_get_pinst);
+extern DECL_FUNC_PTR(LocalHostAddr);
+extern DECL_FUNC_PTR(tkt_string);
+extern DECL_FUNC_PTR(krb_set_tkt_string);
+extern DECL_FUNC_PTR(initialize_krb_error_func);
+extern DECL_FUNC_PTR(initialize_kadm_error_table);
+extern DECL_FUNC_PTR(dest_tkt);
+extern DECL_FUNC_PTR(lsh_LoadKrb4LeashErrorTables); // XXX
+extern DECL_FUNC_PTR(krb_in_tkt);
+extern DECL_FUNC_PTR(krb_save_credentials);
+extern DECL_FUNC_PTR(krb_get_krbconf2);
+extern DECL_FUNC_PTR(krb_get_krbrealm2);
+extern DECL_FUNC_PTR(krb_life_to_time);
+
+// krb5 functions
+extern DECL_FUNC_PTR(krb5_change_password);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_init);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_tkt_life);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_forwardable);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_proxiable);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_address_list);
+extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_change_password_prompt);
+extern DECL_FUNC_PTR(krb5_get_init_creds_password);
+extern DECL_FUNC_PTR(krb5_get_prompt_types);
+extern DECL_FUNC_PTR(krb5_build_principal_ext);
+extern DECL_FUNC_PTR(krb5_cc_get_name);
+extern DECL_FUNC_PTR(krb5_cc_get_type);
+extern DECL_FUNC_PTR(krb5_cc_resolve);
+extern DECL_FUNC_PTR(krb5_cc_default);
+extern DECL_FUNC_PTR(krb5_cc_default_name);
+extern DECL_FUNC_PTR(krb5_cc_set_default_name);
+extern DECL_FUNC_PTR(krb5_cc_initialize);
+extern DECL_FUNC_PTR(krb5_cc_destroy);
+extern DECL_FUNC_PTR(krb5_cc_close);
+extern DECL_FUNC_PTR(krb5_cc_copy_creds);
+extern DECL_FUNC_PTR(krb5_cc_store_cred);
+extern DECL_FUNC_PTR(krb5_cc_retrieve_cred);
+extern DECL_FUNC_PTR(krb5_cc_get_principal);
+extern DECL_FUNC_PTR(krb5_cc_start_seq_get);
+extern DECL_FUNC_PTR(krb5_cc_next_cred);
+extern DECL_FUNC_PTR(krb5_cc_end_seq_get);
+extern DECL_FUNC_PTR(krb5_cc_remove_cred);
+extern DECL_FUNC_PTR(krb5_cc_set_flags);
+// extern DECL_FUNC_PTR(krb5_cc_get_type);
+extern DECL_FUNC_PTR(krb5_free_context);
+extern DECL_FUNC_PTR(krb5_free_cred_contents);
+extern DECL_FUNC_PTR(krb5_free_principal);
+extern DECL_FUNC_PTR(krb5_get_in_tkt_with_password);
+extern DECL_FUNC_PTR(krb5_init_context);
+extern DECL_FUNC_PTR(krb5_parse_name);
+extern DECL_FUNC_PTR(krb5_timeofday);
+extern DECL_FUNC_PTR(krb5_timestamp_to_sfstring);
+extern DECL_FUNC_PTR(krb5_unparse_name);
+extern DECL_FUNC_PTR(krb5_get_credentials);
+extern DECL_FUNC_PTR(krb5_mk_req);
+extern DECL_FUNC_PTR(krb5_sname_to_principal);
+extern DECL_FUNC_PTR(krb5_get_credentials_renew);
+extern DECL_FUNC_PTR(krb5_free_data);
+extern DECL_FUNC_PTR(krb5_free_data_contents);
+// extern DECL_FUNC_PTR(krb5_get_realm_domain);
+extern DECL_FUNC_PTR(krb5_free_unparsed_name);
+extern DECL_FUNC_PTR(krb5_os_localaddr);
+extern DECL_FUNC_PTR(krb5_copy_keyblock_contents);
+extern DECL_FUNC_PTR(krb5_copy_data);
+extern DECL_FUNC_PTR(krb5_free_creds);
+extern DECL_FUNC_PTR(krb5_build_principal);
+extern DECL_FUNC_PTR(krb5_get_renewed_creds);
+extern DECL_FUNC_PTR(krb5_free_addresses);
+extern DECL_FUNC_PTR(krb5_get_default_config_files);
+extern DECL_FUNC_PTR(krb5_free_config_files);
+extern DECL_FUNC_PTR(krb5_get_default_realm);
+extern DECL_FUNC_PTR(krb5_set_default_realm);
+extern DECL_FUNC_PTR(krb5_free_ticket);
+extern DECL_FUNC_PTR(krb5_decode_ticket);
+extern DECL_FUNC_PTR(krb5_get_host_realm);
+extern DECL_FUNC_PTR(krb5_free_host_realm);
+extern DECL_FUNC_PTR(krb5_c_random_make_octets);
+extern DECL_FUNC_PTR(krb5_free_default_realm);
+extern DECL_FUNC_PTR(krb5_string_to_deltat);
+
+// Krb524 functions
+extern DECL_FUNC_PTR(krb524_init_ets);
+extern DECL_FUNC_PTR(krb524_convert_creds_kdc);
+
+// ComErr functions
+extern DECL_FUNC_PTR(com_err);
+extern DECL_FUNC_PTR(error_message);
+
+// Profile functions
+extern DECL_FUNC_PTR(profile_init);
+extern DECL_FUNC_PTR(profile_flush);
+extern DECL_FUNC_PTR(profile_release);
+extern DECL_FUNC_PTR(profile_get_subsection_names);
+extern DECL_FUNC_PTR(profile_free_list);
+extern DECL_FUNC_PTR(profile_get_string);
+extern DECL_FUNC_PTR(profile_get_integer);
+extern DECL_FUNC_PTR(profile_get_values);
+extern DECL_FUNC_PTR(profile_get_relation_names);
+extern DECL_FUNC_PTR(profile_clear_relation);
+extern DECL_FUNC_PTR(profile_add_relation);
+extern DECL_FUNC_PTR(profile_update_relation);
+extern DECL_FUNC_PTR(profile_release_string);
+extern DECL_FUNC_PTR(profile_rename_section);
+
+// Service functions
+extern DECL_FUNC_PTR(OpenSCManagerA);
+extern DECL_FUNC_PTR(OpenServiceA);
+extern DECL_FUNC_PTR(QueryServiceStatus);
+extern DECL_FUNC_PTR(CloseServiceHandle);
+extern DECL_FUNC_PTR(LsaNtStatusToWinError);
+
+// LSA Functions
+extern DECL_FUNC_PTR(LsaConnectUntrusted);
+extern DECL_FUNC_PTR(LsaLookupAuthenticationPackage);
+extern DECL_FUNC_PTR(LsaCallAuthenticationPackage);
+extern DECL_FUNC_PTR(LsaFreeReturnBuffer);
+extern DECL_FUNC_PTR(LsaGetLogonSessionData);
+
+// toolhelp functions
+TYPEDEF_FUNC(
+ HANDLE,
+ WINAPI,
+ CreateToolhelp32Snapshot,
+ (DWORD, DWORD)
+ );
+TYPEDEF_FUNC(
+ BOOL,
+ WINAPI,
+ Module32First,
+ (HANDLE, LPMODULEENTRY32)
+ );
+TYPEDEF_FUNC(
+ BOOL,
+ WINAPI,
+ Module32Next,
+ (HANDLE, LPMODULEENTRY32)
+ );
+
+// psapi functions
+TYPEDEF_FUNC(
+ DWORD,
+ WINAPI,
+ GetModuleFileNameExA,
+ (HANDLE, HMODULE, LPSTR, DWORD)
+ );
+
+TYPEDEF_FUNC(
+ BOOL,
+ WINAPI,
+ EnumProcessModules,
+ (HANDLE, HMODULE*, DWORD, LPDWORD)
+ );
+
+#define pGetModuleFileNameEx pGetModuleFileNameExA
+#define TOOLHELPDLL "kernel32.dll"
+#define PSAPIDLL "psapi.dll"
+
+// psapi functions
+extern DECL_FUNC_PTR(GetModuleFileNameExA);
+extern DECL_FUNC_PTR(EnumProcessModules);
+
+// toolhelp functions
+extern DECL_FUNC_PTR(CreateToolhelp32Snapshot);
+extern DECL_FUNC_PTR(Module32First);
+extern DECL_FUNC_PTR(Module32Next);
+
+khm_int32 init_imports(void);
+khm_int32 exit_imports(void);
+
+#endif
diff --git a/src/windows/identity/plugins/common/krb5common.c b/src/windows/identity/plugins/common/krb5common.c
index 6c3958694..1278fbcfa 100644
--- a/src/windows/identity/plugins/common/krb5common.c
+++ b/src/windows/identity/plugins/common/krb5common.c
@@ -1,451 +1,451 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<windows.h>
-#include<netidmgr.h>
-#include<dynimport.h>
-#include<krb5common.h>
-#ifdef DEBUG
-#include<assert.h>
-#endif
-#include<strsafe.h>
-
-/**************************************/
-/* khm_krb5_error(): */
-/**************************************/
-int
-khm_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName,
- int FreeContextFlag, krb5_context * ctx,
- krb5_ccache * cache)
-{
-#ifdef NO_KRB5
- return 0;
-#else
-
-#ifdef SHOW_MESSAGE_IN_AN_ANNOYING_WAY
- char message[256];
- const char *errText;
- int krb5Error = ((int)(rc & 255));
-
- errText = perror_message(rc);
- _snprintf(message, sizeof(message),
- "%s\n(Kerberos error %ld)\n\n%s failed",
- errText,
- krb5Error,
- FailedFunctionName);
-
- MessageBoxA(NULL, message, "Kerberos Five", MB_OK | MB_ICONERROR |
- MB_TASKMODAL |
- MB_SETFOREGROUND);
-#endif
-
- if (FreeContextFlag == 1)
- {
- if (*ctx != NULL)
- {
- if (*cache != NULL) {
- pkrb5_cc_close(*ctx, *cache);
- *cache = NULL;
- }
-
- pkrb5_free_context(*ctx);
- *ctx = NULL;
- }
- }
-
- return rc;
-
-#endif //!NO_KRB5
-}
-
-int
-khm_krb5_initialize(khm_handle ident,
- krb5_context *ctx,
- krb5_ccache *cache)
-{
-#ifdef NO_KRB5
- return(0);
-#else
-
- LPCSTR functionName = NULL;
- int freeContextFlag = 0;
- krb5_error_code rc = 0;
- krb5_flags flags = 0;
-
- if (pkrb5_init_context == NULL)
- return 1;
-
- if (*ctx == 0 && (rc = (*pkrb5_init_context)(ctx))) {
- functionName = "krb5_init_context()";
- freeContextFlag = 0;
- goto on_error;
- }
-
- if(*cache == 0) {
- wchar_t wccname[MAX_PATH];
- khm_size cbwccname;
-
- if(ident != NULL) {
- cbwccname = sizeof(wccname);
- do {
- char ccname[256];
-
- if(KHM_FAILED(kcdb_identity_get_attrib(ident, L"Krb5CCName",
- NULL, wccname,
- &cbwccname))) {
- cbwccname = sizeof(wccname);
- if (KHM_FAILED
- (khm_krb5_find_ccache_for_identity(ident,
- ctx,
- wccname,
- &cbwccname))) {
-#ifdef DEBUG_LIKE_A_MADMAN
- assert(FALSE);
-#endif
- break;
- }
- }
-
- if(UnicodeStrToAnsi(ccname, sizeof(ccname), wccname) == 0)
- break;
-
- if((*pkrb5_cc_resolve)(*ctx, ccname, cache)) {
- functionName = "krb5_cc_resolve()";
- freeContextFlag = 1;
- goto on_error;
- }
- } while(FALSE);
- }
-
-#ifndef FAILOVER_TO_DEFAULT_CCACHE
- rc = 1;
-#endif
- if (*cache == 0
-#ifdef FAILOVER_TO_DEFAULT_CCACHE
- && (rc = (*pkrb5_cc_default)(*ctx, cache))
-#endif
- ) {
- functionName = "krb5_cc_default()";
- freeContextFlag = 1;
- goto on_error;
- }
- }
-
-#ifdef KRB5_TC_NOTICKET
- flags = KRB5_TC_NOTICKET;
-#endif
-
- if ((rc = (*pkrb5_cc_set_flags)(*ctx, *cache, flags)))
- {
- if (rc != KRB5_FCC_NOFILE && rc != KRB5_CC_NOTFOUND)
- khm_krb5_error(rc, "krb5_cc_set_flags()", 0, ctx,
- cache);
- else if ((rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) && *ctx != NULL) {
- if (*cache != NULL) {
- (*pkrb5_cc_close)(*ctx, *cache);
- *cache = NULL;
- }
- }
- return rc;
- }
- return 0;
-
-on_error:
- return khm_krb5_error(rc, functionName, freeContextFlag, ctx, cache);
-#endif //!NO_KRB5
-}
-
-#define TIMET_TOLERANCE (60*5)
-
-khm_int32 KHMAPI
-khm_get_identity_expiration_time(krb5_context ctx, krb5_ccache cc,
- khm_handle ident,
- krb5_timestamp * pexpiration)
-{
- krb5_principal principal = 0;
- char * princ_name = NULL;
- krb5_creds creds;
- krb5_error_code code;
- krb5_error_code cc_code;
- krb5_cc_cursor cur;
- krb5_timestamp now, expiration = 0;
-
- wchar_t w_ident_name[KCDB_IDENT_MAXCCH_NAME];
- char ident_name[KCDB_IDENT_MAXCCH_NAME];
- khm_size cb;
-
- khm_int32 rv = KHM_ERROR_NOT_FOUND;
-
- if (!ctx || !cc || !ident || !pexpiration)
- return KHM_ERROR_GENERAL;
-
- code = pkrb5_cc_get_principal(ctx, cc, &principal);
-
- if ( code )
- return KHM_ERROR_INVALID_PARAM;
-
- cb = sizeof(w_ident_name);
- kcdb_identity_get_name(ident, w_ident_name, &cb);
- UnicodeStrToAnsi(ident_name, sizeof(ident_name), w_ident_name);
-
- code = pkrb5_unparse_name(ctx, principal, &princ_name);
-
- /* compare principal to ident. */
-
- if ( code || !princ_name ||
- strcmp(princ_name, ident_name) ) {
- if (princ_name)
- pkrb5_free_unparsed_name(ctx, princ_name);
- pkrb5_free_principal(ctx, principal);
- return KHM_ERROR_UNKNOWN;
- }
-
- pkrb5_free_unparsed_name(ctx, princ_name);
- pkrb5_free_principal(ctx, principal);
-
- code = pkrb5_timeofday(ctx, &now);
-
- if (code)
- return KHM_ERROR_UNKNOWN;
-
- cc_code = pkrb5_cc_start_seq_get(ctx, cc, &cur);
-
- while (!(cc_code = pkrb5_cc_next_cred(ctx, cc, &cur, &creds))) {
- krb5_data * c0 = krb5_princ_name(ctx, creds.server);
- krb5_data * c1 = krb5_princ_component(ctx, creds.server, 1);
- krb5_data * r = krb5_princ_realm(ctx, creds.server);
-
- if ( c0 && c1 && r && c1->length == r->length &&
- !strncmp(c1->data,r->data,r->length) &&
- !strncmp("krbtgt",c0->data,c0->length) ) {
-
- /* we have a TGT, check for the expiration time.
- * if it is valid and renewable, use the renew time
- */
-
- if (!(creds.ticket_flags & TKT_FLG_INVALID) &&
- creds.times.starttime < (now + TIMET_TOLERANCE) &&
- (creds.times.endtime + TIMET_TOLERANCE) > now) {
- expiration = creds.times.endtime;
-
- if ((creds.ticket_flags & TKT_FLG_RENEWABLE) &&
- (creds.times.renew_till > creds.times.endtime)) {
- expiration = creds.times.renew_till;
- }
- }
- }
- }
-
- if (cc_code == KRB5_CC_END) {
- cc_code = pkrb5_cc_end_seq_get(ctx, cc, &cur);
- rv = KHM_ERROR_SUCCESS;
- *pexpiration = expiration;
- }
-
- return rv;
-}
-
-khm_int32 KHMAPI
-khm_krb5_find_ccache_for_identity(khm_handle ident, krb5_context *pctx,
- void * buffer, khm_size * pcbbuf)
-{
- krb5_context ctx = 0;
- krb5_ccache cache = 0;
- krb5_error_code code;
- apiCB * cc_ctx = 0;
- struct _infoNC ** pNCi = NULL;
- int i;
- khm_int32 t;
- wchar_t * ms = NULL;
- khm_size cb;
- krb5_timestamp expiration = 0;
- krb5_timestamp best_match_expiration = 0;
- char best_match_ccname[256] = "";
- khm_handle csp_params = NULL;
- khm_handle csp_plugins = NULL;
-
- if (!buffer || !pcbbuf)
- return KHM_ERROR_GENERAL;
-
- ctx = *pctx;
-
- if (!pcc_initialize ||
- !pcc_get_NC_info ||
- !pcc_free_NC_info ||
- !pcc_shutdown)
- goto _skip_cc_iter;
-
- code = pcc_initialize(&cc_ctx, CC_API_VER_2, NULL, NULL);
- if (code)
- goto _exit;
-
- code = pcc_get_NC_info(cc_ctx, &pNCi);
-
- if (code)
- goto _exit;
-
- for(i=0; pNCi[i]; i++) {
- if (pNCi[i]->vers != CC_CRED_V5)
- continue;
-
- code = (*pkrb5_cc_resolve)(ctx, pNCi[i]->name, &cache);
- if (code)
- continue;
-
- /* need a function to check the cache for the identity
- * and determine if it has valid tickets. If it has
- * the right identity and valid tickets, store the
- * expiration time and the cache name. If it has the
- * right identity but no valid tickets, store the ccache
- * name and an expiration time of zero. if it does not
- * have the right identity don't save the name.
- *
- * Keep searching to find the best cache available.
- */
-
- if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache,
- ident,
- &expiration))) {
- if ( expiration > best_match_expiration ) {
- best_match_expiration = expiration;
- StringCbCopyA(best_match_ccname,
- sizeof(best_match_ccname),
- "API:");
- StringCbCatA(best_match_ccname,
- sizeof(best_match_ccname),
- pNCi[i]->name);
- expiration = 0;
- }
- }
-
- if(ctx != NULL && cache != NULL)
- (*pkrb5_cc_close)(ctx, cache);
- cache = 0;
- }
-
- _skip_cc_iter:
-
- if (KHM_SUCCEEDED(kmm_get_plugins_config(0, &csp_plugins))) {
- khc_open_space(csp_plugins, L"Krb5Cred\\Parameters", 0, &csp_params);
- khc_close_space(csp_plugins);
- csp_plugins = NULL;
- }
-
-#ifdef DEBUG
- if (csp_params == NULL) {
- assert(FALSE);
- }
-#endif
-
- if (csp_params &&
- KHM_SUCCEEDED(khc_read_int32(csp_params, L"MsLsaList", &t)) && t) {
- code = (*pkrb5_cc_resolve)(ctx, "MSLSA:", &cache);
- if (code == 0 && cache) {
- if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache,
- ident,
- &expiration))) {
- if ( expiration > best_match_expiration ) {
- best_match_expiration = expiration;
- StringCbCopyA(best_match_ccname, sizeof(best_match_ccname),
- "MSLSA:");
- expiration = 0;
- }
- }
- }
-
- if (ctx != NULL && cache != NULL)
- (*pkrb5_cc_close)(ctx, cache);
-
- cache = 0;
- }
-
- if (csp_params &&
- khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
- == KHM_ERROR_TOO_LONG &&
- cb > sizeof(wchar_t) * 2) {
-
- wchar_t * t;
- char ccname[MAX_PATH + 6];
-
- ms = PMALLOC(cb);
-
-#ifdef DEBUG
- assert(ms);
-#endif
-
- khc_read_multi_string(csp_params, L"FileCCList", ms, &cb);
- for(t = ms; t && *t; t = multi_string_next(t)) {
- StringCchPrintfA(ccname, ARRAYLENGTH(ccname),
- "FILE:%S", t);
-
- code = (*pkrb5_cc_resolve)(ctx, ccname, &cache);
- if (code)
- continue;
-
- if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache,
- ident,
- &expiration))) {
- if ( expiration > best_match_expiration ) {
- best_match_expiration = expiration;
- StringCbCopyA(best_match_ccname,
- sizeof(best_match_ccname),
- ccname);
- expiration = 0;
- }
- }
-
- if (ctx != NULL && cache != NULL)
- (*pkrb5_cc_close)(ctx, cache);
- cache = 0;
- }
-
- PFREE(ms);
- }
- _exit:
- if (csp_params)
- khc_close_space(csp_params);
-
- if (pNCi)
- (*pcc_free_NC_info)(cc_ctx, &pNCi);
-
- if (cc_ctx)
- (*pcc_shutdown)(&cc_ctx);
-
- if (best_match_ccname[0]) {
-
- if (*pcbbuf = AnsiStrToUnicode((wchar_t *)buffer,
- *pcbbuf,
- best_match_ccname)) {
-
- *pcbbuf = (*pcbbuf + 1) * sizeof(wchar_t);
-
- return KHM_ERROR_SUCCESS;
- }
-
- }
-
- return KHM_ERROR_GENERAL;
-}
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<windows.h>
+#include<netidmgr.h>
+#include<dynimport.h>
+#include<krb5common.h>
+#ifdef DEBUG
+#include<assert.h>
+#endif
+#include<strsafe.h>
+
+/**************************************/
+/* khm_krb5_error(): */
+/**************************************/
+int
+khm_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName,
+ int FreeContextFlag, krb5_context * ctx,
+ krb5_ccache * cache)
+{
+#ifdef NO_KRB5
+ return 0;
+#else
+
+#ifdef SHOW_MESSAGE_IN_AN_ANNOYING_WAY
+ char message[256];
+ const char *errText;
+ int krb5Error = ((int)(rc & 255));
+
+ errText = perror_message(rc);
+ _snprintf(message, sizeof(message),
+ "%s\n(Kerberos error %ld)\n\n%s failed",
+ errText,
+ krb5Error,
+ FailedFunctionName);
+
+ MessageBoxA(NULL, message, "Kerberos Five", MB_OK | MB_ICONERROR |
+ MB_TASKMODAL |
+ MB_SETFOREGROUND);
+#endif
+
+ if (FreeContextFlag == 1)
+ {
+ if (*ctx != NULL)
+ {
+ if (*cache != NULL) {
+ pkrb5_cc_close(*ctx, *cache);
+ *cache = NULL;
+ }
+
+ pkrb5_free_context(*ctx);
+ *ctx = NULL;
+ }
+ }
+
+ return rc;
+
+#endif //!NO_KRB5
+}
+
+int
+khm_krb5_initialize(khm_handle ident,
+ krb5_context *ctx,
+ krb5_ccache *cache)
+{
+#ifdef NO_KRB5
+ return(0);
+#else
+
+ LPCSTR functionName = NULL;
+ int freeContextFlag = 0;
+ krb5_error_code rc = 0;
+ krb5_flags flags = 0;
+
+ if (pkrb5_init_context == NULL)
+ return 1;
+
+ if (*ctx == 0 && (rc = (*pkrb5_init_context)(ctx))) {
+ functionName = "krb5_init_context()";
+ freeContextFlag = 0;
+ goto on_error;
+ }
+
+ if(*cache == 0) {
+ wchar_t wccname[MAX_PATH];
+ khm_size cbwccname;
+
+ if(ident != NULL) {
+ cbwccname = sizeof(wccname);
+ do {
+ char ccname[256];
+
+ if(KHM_FAILED(kcdb_identity_get_attrib(ident, L"Krb5CCName",
+ NULL, wccname,
+ &cbwccname))) {
+ cbwccname = sizeof(wccname);
+ if (KHM_FAILED
+ (khm_krb5_find_ccache_for_identity(ident,
+ ctx,
+ wccname,
+ &cbwccname))) {
+#ifdef DEBUG_LIKE_A_MADMAN
+ assert(FALSE);
+#endif
+ break;
+ }
+ }
+
+ if(UnicodeStrToAnsi(ccname, sizeof(ccname), wccname) == 0)
+ break;
+
+ if((*pkrb5_cc_resolve)(*ctx, ccname, cache)) {
+ functionName = "krb5_cc_resolve()";
+ freeContextFlag = 1;
+ goto on_error;
+ }
+ } while(FALSE);
+ }
+
+#ifndef FAILOVER_TO_DEFAULT_CCACHE
+ rc = 1;
+#endif
+ if (*cache == 0
+#ifdef FAILOVER_TO_DEFAULT_CCACHE
+ && (rc = (*pkrb5_cc_default)(*ctx, cache))
+#endif
+ ) {
+ functionName = "krb5_cc_default()";
+ freeContextFlag = 1;
+ goto on_error;
+ }
+ }
+
+#ifdef KRB5_TC_NOTICKET
+ flags = KRB5_TC_NOTICKET;
+#endif
+
+ if ((rc = (*pkrb5_cc_set_flags)(*ctx, *cache, flags)))
+ {
+ if (rc != KRB5_FCC_NOFILE && rc != KRB5_CC_NOTFOUND)
+ khm_krb5_error(rc, "krb5_cc_set_flags()", 0, ctx,
+ cache);
+ else if ((rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) && *ctx != NULL) {
+ if (*cache != NULL) {
+ (*pkrb5_cc_close)(*ctx, *cache);
+ *cache = NULL;
+ }
+ }
+ return rc;
+ }
+ return 0;
+
+on_error:
+ return khm_krb5_error(rc, functionName, freeContextFlag, ctx, cache);
+#endif //!NO_KRB5
+}
+
+#define TIMET_TOLERANCE (60*5)
+
+khm_int32 KHMAPI
+khm_get_identity_expiration_time(krb5_context ctx, krb5_ccache cc,
+ khm_handle ident,
+ krb5_timestamp * pexpiration)
+{
+ krb5_principal principal = 0;
+ char * princ_name = NULL;
+ krb5_creds creds;
+ krb5_error_code code;
+ krb5_error_code cc_code;
+ krb5_cc_cursor cur;
+ krb5_timestamp now, expiration = 0;
+
+ wchar_t w_ident_name[KCDB_IDENT_MAXCCH_NAME];
+ char ident_name[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb;
+
+ khm_int32 rv = KHM_ERROR_NOT_FOUND;
+
+ if (!ctx || !cc || !ident || !pexpiration)
+ return KHM_ERROR_GENERAL;
+
+ code = pkrb5_cc_get_principal(ctx, cc, &principal);
+
+ if ( code )
+ return KHM_ERROR_INVALID_PARAM;
+
+ cb = sizeof(w_ident_name);
+ kcdb_identity_get_name(ident, w_ident_name, &cb);
+ UnicodeStrToAnsi(ident_name, sizeof(ident_name), w_ident_name);
+
+ code = pkrb5_unparse_name(ctx, principal, &princ_name);
+
+ /* compare principal to ident. */
+
+ if ( code || !princ_name ||
+ strcmp(princ_name, ident_name) ) {
+ if (princ_name)
+ pkrb5_free_unparsed_name(ctx, princ_name);
+ pkrb5_free_principal(ctx, principal);
+ return KHM_ERROR_UNKNOWN;
+ }
+
+ pkrb5_free_unparsed_name(ctx, princ_name);
+ pkrb5_free_principal(ctx, principal);
+
+ code = pkrb5_timeofday(ctx, &now);
+
+ if (code)
+ return KHM_ERROR_UNKNOWN;
+
+ cc_code = pkrb5_cc_start_seq_get(ctx, cc, &cur);
+
+ while (!(cc_code = pkrb5_cc_next_cred(ctx, cc, &cur, &creds))) {
+ krb5_data * c0 = krb5_princ_name(ctx, creds.server);
+ krb5_data * c1 = krb5_princ_component(ctx, creds.server, 1);
+ krb5_data * r = krb5_princ_realm(ctx, creds.server);
+
+ if ( c0 && c1 && r && c1->length == r->length &&
+ !strncmp(c1->data,r->data,r->length) &&
+ !strncmp("krbtgt",c0->data,c0->length) ) {
+
+ /* we have a TGT, check for the expiration time.
+ * if it is valid and renewable, use the renew time
+ */
+
+ if (!(creds.ticket_flags & TKT_FLG_INVALID) &&
+ creds.times.starttime < (now + TIMET_TOLERANCE) &&
+ (creds.times.endtime + TIMET_TOLERANCE) > now) {
+ expiration = creds.times.endtime;
+
+ if ((creds.ticket_flags & TKT_FLG_RENEWABLE) &&
+ (creds.times.renew_till > creds.times.endtime)) {
+ expiration = creds.times.renew_till;
+ }
+ }
+ }
+ }
+
+ if (cc_code == KRB5_CC_END) {
+ cc_code = pkrb5_cc_end_seq_get(ctx, cc, &cur);
+ rv = KHM_ERROR_SUCCESS;
+ *pexpiration = expiration;
+ }
+
+ return rv;
+}
+
+khm_int32 KHMAPI
+khm_krb5_find_ccache_for_identity(khm_handle ident, krb5_context *pctx,
+ void * buffer, khm_size * pcbbuf)
+{
+ krb5_context ctx = 0;
+ krb5_ccache cache = 0;
+ krb5_error_code code;
+ apiCB * cc_ctx = 0;
+ struct _infoNC ** pNCi = NULL;
+ int i;
+ khm_int32 t;
+ wchar_t * ms = NULL;
+ khm_size cb;
+ krb5_timestamp expiration = 0;
+ krb5_timestamp best_match_expiration = 0;
+ char best_match_ccname[256] = "";
+ khm_handle csp_params = NULL;
+ khm_handle csp_plugins = NULL;
+
+ if (!buffer || !pcbbuf)
+ return KHM_ERROR_GENERAL;
+
+ ctx = *pctx;
+
+ if (!pcc_initialize ||
+ !pcc_get_NC_info ||
+ !pcc_free_NC_info ||
+ !pcc_shutdown)
+ goto _skip_cc_iter;
+
+ code = pcc_initialize(&cc_ctx, CC_API_VER_2, NULL, NULL);
+ if (code)
+ goto _exit;
+
+ code = pcc_get_NC_info(cc_ctx, &pNCi);
+
+ if (code)
+ goto _exit;
+
+ for(i=0; pNCi[i]; i++) {
+ if (pNCi[i]->vers != CC_CRED_V5)
+ continue;
+
+ code = (*pkrb5_cc_resolve)(ctx, pNCi[i]->name, &cache);
+ if (code)
+ continue;
+
+ /* need a function to check the cache for the identity
+ * and determine if it has valid tickets. If it has
+ * the right identity and valid tickets, store the
+ * expiration time and the cache name. If it has the
+ * right identity but no valid tickets, store the ccache
+ * name and an expiration time of zero. if it does not
+ * have the right identity don't save the name.
+ *
+ * Keep searching to find the best cache available.
+ */
+
+ if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache,
+ ident,
+ &expiration))) {
+ if ( expiration > best_match_expiration ) {
+ best_match_expiration = expiration;
+ StringCbCopyA(best_match_ccname,
+ sizeof(best_match_ccname),
+ "API:");
+ StringCbCatA(best_match_ccname,
+ sizeof(best_match_ccname),
+ pNCi[i]->name);
+ expiration = 0;
+ }
+ }
+
+ if(ctx != NULL && cache != NULL)
+ (*pkrb5_cc_close)(ctx, cache);
+ cache = 0;
+ }
+
+ _skip_cc_iter:
+
+ if (KHM_SUCCEEDED(kmm_get_plugins_config(0, &csp_plugins))) {
+ khc_open_space(csp_plugins, L"Krb5Cred\\Parameters", 0, &csp_params);
+ khc_close_space(csp_plugins);
+ csp_plugins = NULL;
+ }
+
+#ifdef DEBUG
+ if (csp_params == NULL) {
+ assert(FALSE);
+ }
+#endif
+
+ if (csp_params &&
+ KHM_SUCCEEDED(khc_read_int32(csp_params, L"MsLsaList", &t)) && t) {
+ code = (*pkrb5_cc_resolve)(ctx, "MSLSA:", &cache);
+ if (code == 0 && cache) {
+ if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache,
+ ident,
+ &expiration))) {
+ if ( expiration > best_match_expiration ) {
+ best_match_expiration = expiration;
+ StringCbCopyA(best_match_ccname, sizeof(best_match_ccname),
+ "MSLSA:");
+ expiration = 0;
+ }
+ }
+ }
+
+ if (ctx != NULL && cache != NULL)
+ (*pkrb5_cc_close)(ctx, cache);
+
+ cache = 0;
+ }
+
+ if (csp_params &&
+ khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
+ == KHM_ERROR_TOO_LONG &&
+ cb > sizeof(wchar_t) * 2) {
+
+ wchar_t * t;
+ char ccname[MAX_PATH + 6];
+
+ ms = PMALLOC(cb);
+
+#ifdef DEBUG
+ assert(ms);
+#endif
+
+ khc_read_multi_string(csp_params, L"FileCCList", ms, &cb);
+ for(t = ms; t && *t; t = multi_string_next(t)) {
+ StringCchPrintfA(ccname, ARRAYLENGTH(ccname),
+ "FILE:%S", t);
+
+ code = (*pkrb5_cc_resolve)(ctx, ccname, &cache);
+ if (code)
+ continue;
+
+ if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache,
+ ident,
+ &expiration))) {
+ if ( expiration > best_match_expiration ) {
+ best_match_expiration = expiration;
+ StringCbCopyA(best_match_ccname,
+ sizeof(best_match_ccname),
+ ccname);
+ expiration = 0;
+ }
+ }
+
+ if (ctx != NULL && cache != NULL)
+ (*pkrb5_cc_close)(ctx, cache);
+ cache = 0;
+ }
+
+ PFREE(ms);
+ }
+ _exit:
+ if (csp_params)
+ khc_close_space(csp_params);
+
+ if (pNCi)
+ (*pcc_free_NC_info)(cc_ctx, &pNCi);
+
+ if (cc_ctx)
+ (*pcc_shutdown)(&cc_ctx);
+
+ if (best_match_ccname[0]) {
+
+ if (*pcbbuf = AnsiStrToUnicode((wchar_t *)buffer,
+ *pcbbuf,
+ best_match_ccname)) {
+
+ *pcbbuf = (*pcbbuf + 1) * sizeof(wchar_t);
+
+ return KHM_ERROR_SUCCESS;
+ }
+
+ }
+
+ return KHM_ERROR_GENERAL;
+}
diff --git a/src/windows/identity/plugins/common/krb5common.h b/src/windows/identity/plugins/common/krb5common.h
index df3db93ae..29cae71ee 100644
--- a/src/windows/identity/plugins/common/krb5common.h
+++ b/src/windows/identity/plugins/common/krb5common.h
@@ -1,56 +1,56 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Adapted from multiple Leash header files */
-
-#ifndef __KHIMAIRA_KRB5COMMON_H
-#define __KHIMAIRA_KRB5COMMON_H
-
-#include<krb5.h>
-
-#ifndef NO_KRB5
-int khm_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName,
- int FreeContextFlag, krb5_context *ctx,
- krb5_ccache *cache);
-
-int
-khm_krb5_get_error_string(krb5_error_code rc,
- wchar_t * buffer,
- khm_size cb_buffer);
-
-int khm_krb5_initialize(khm_handle ident, krb5_context *, krb5_ccache *);
-
-khm_int32 KHMAPI
-khm_krb5_find_ccache_for_identity(khm_handle ident, krb5_context *pctx,
- void * buffer, khm_size * pcbbuf);
-
-khm_int32 KHMAPI
-khm_get_identity_expiration_time(krb5_context ctx, krb5_ccache cc,
- khm_handle ident,
- krb5_timestamp * pexpiration);
-#endif /* NO_KRB5 */
-
-#endif
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+/* Adapted from multiple Leash header files */
+
+#ifndef __KHIMAIRA_KRB5COMMON_H
+#define __KHIMAIRA_KRB5COMMON_H
+
+#include<krb5.h>
+
+#ifndef NO_KRB5
+int khm_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName,
+ int FreeContextFlag, krb5_context *ctx,
+ krb5_ccache *cache);
+
+int
+khm_krb5_get_error_string(krb5_error_code rc,
+ wchar_t * buffer,
+ khm_size cb_buffer);
+
+int khm_krb5_initialize(khm_handle ident, krb5_context *, krb5_ccache *);
+
+khm_int32 KHMAPI
+khm_krb5_find_ccache_for_identity(khm_handle ident, krb5_context *pctx,
+ void * buffer, khm_size * pcbbuf);
+
+khm_int32 KHMAPI
+khm_get_identity_expiration_time(krb5_context ctx, krb5_ccache cc,
+ khm_handle ident,
+ krb5_timestamp * pexpiration);
+#endif /* NO_KRB5 */
+
+#endif
diff --git a/src/windows/identity/plugins/krb4/errorfuncs.c b/src/windows/identity/plugins/krb4/errorfuncs.c
index f1aa63d88..f436a40a7 100644
--- a/src/windows/identity/plugins/krb4/errorfuncs.c
+++ b/src/windows/identity/plugins/krb4/errorfuncs.c
@@ -1,226 +1,226 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<kherror.h>
-
-#include<strsafe.h>
-
-extern void (__cdecl *pinitialize_krb_error_func)();
-extern void (__cdecl *pinitialize_kadm_error_table)();
-
-
-khm_int32 init_error_funcs()
-{
-
-#if 0
- /*TODO: Do something about this */
- if (plsh_LoadKrb4LeashErrorTables)
- plsh_LoadKrb4LeashErrorTables(hLeashInst, 0);
-#endif
- return KHM_ERROR_SUCCESS;
-}
-
-khm_int32 exit_error_funcs()
-{
- return KHM_ERROR_SUCCESS;
-}
-
-// Global Variables.
-static long lsh_errno;
-static char *err_context; /* error context */
-extern int (*Lcom_err)(LPSTR,long,LPSTR,...);
-extern LPSTR (*Lerror_message)(long);
-extern LPSTR (*Lerror_table_name)(long);
-
-#ifdef WIN16
-#define UNDERSCORE "_"
-#else
-#define UNDERSCORE
-#endif
-
-HWND GetRootParent (HWND Child)
-{
- HWND Last = NULL;
- while (Child)
- {
- Last = Child;
- Child = GetParent (Child);
- }
- return Last;
-}
-
-
-LPSTR err_describe(LPSTR buf, size_t len, long code)
-{
- LPSTR cp, com_err_msg;
- int offset;
- long table_num;
- char *etype;
-
- offset = (int) (code & 255);
- table_num = code - offset;
- com_err_msg = Lerror_message(code);
-
- switch(table_num)
- {
- case krb_err_base:
- case kadm_err_base:
- break;
- default:
- StringCbCopyA(buf, len, com_err_msg);
- return buf;
- }
-
- cp = buf;
- if (table_num == krb_err_base)
- switch(offset)
- {
- case KDC_NAME_EXP: /* 001 Principal expired */
- case KDC_SERVICE_EXP: /* 002 Service expired */
- case KDC_AUTH_EXP: /* 003 Auth expired */
- case KDC_PKT_VER: /* 004 Protocol version unknown */
- case KDC_P_MKEY_VER: /* 005 Wrong master key version */
- case KDC_S_MKEY_VER: /* 006 Wrong master key version */
- case KDC_BYTE_ORDER: /* 007 Byte order unknown */
- case KDC_PR_N_UNIQUE: /* 009 Principal not unique */
- case KDC_NULL_KEY: /* 010 Principal has null key */
- case KDC_GEN_ERR: /* 011 Generic error from KDC */
- case INTK_W_NOTALL : /* 061 Not ALL tickets returned */
- case INTK_PROT : /* 063 Protocol Error */
- case INTK_ERR : /* 070 Other error */
- com_err_msg = "Something weird happened... try again, and if Leash"
- " continues to fail, contact Network Services as listed in the "
- "About box.";
- break;
- case KDC_PR_UNKNOWN: /* 008 Principal unknown */
- com_err_msg = "You have entered an unknown username/instance/realm"
- " combination.";
- break;
- case GC_TKFIL : /* 021 Can't read ticket file */
- case GC_NOTKT : /* 022 Can't find ticket or TGT */
- com_err_msg = "Something is wrong with the memory where your "
- "tickets are stored. Try exiting Windows and restarting your "
- "computer.";
- break;
- case MK_AP_TGTEXP : /* 026 TGT Expired */
- /* no extra error msg */
- break;
- case RD_AP_TIME : /* 037 delta_t too big */
- com_err_msg = "Your computer's clock is out of sync with the "
- "Kerberos server. Please see the help file about correcting "
- "your clock.";
- break;
-
- case RD_AP_UNDEC : /* 031 Can't decode authenticator */
- case RD_AP_EXP : /* 032 Ticket expired */
- case RD_AP_NYV : /* 033 Ticket not yet valid */
- case RD_AP_REPEAT : /* 034 Repeated request */
- case RD_AP_NOT_US : /* 035 The ticket isn't for us */
- case RD_AP_INCON : /* 036 Request is inconsistent */
- case RD_AP_BADD : /* 038 Incorrect net address */
- case RD_AP_VERSION : /* 039 protocol version mismatch */
- case RD_AP_MSG_TYPE : /* 040 invalid msg type */
- case RD_AP_MODIFIED : /* 041 message stream modified */
- case RD_AP_ORDER : /* 042 message out of order */
- case RD_AP_UNAUTHOR : /* 043 unauthorized request */
- /* no extra error msg */
- break;
- case GT_PW_NULL: /* 51 Current PW is null */
- case GT_PW_BADPW: /* 52 Incorrect current password */
- case GT_PW_PROT: /* 53 Protocol Error */
- case GT_PW_KDCERR: /* 54 Error returned by KDC */
- case GT_PW_NULLTKT: /* 55 Null tkt returned by KDC */
- /* no error msg yet */
- break;
-
- /* Values returned by send_to_kdc */
- case SKDC_RETRY : /* 56 Retry count exceeded */
- case SKDC_CANT : /* 57 Can't send request */
- com_err_msg = "Cannot contact the kerberos server for the selected realm.";
- break;
- /* no error message on purpose: */
- case INTK_BADPW : /* 062 Incorrect password */
- break;
- default:
- /* no extra error msg */
- break;
- }
- else
- switch(code)
- {
- case KADM_INSECURE_PW:
- /* if( kadm_info != NULL ){
- * wsprintf(buf, "%s\n%s", com_err_msg, kadm_info);
- * } else {
- * wsprintf(buf, "%s\nPlease see the help file for information "
- * "about secure passwords.", com_err_msg);
- * }
- * com_err_msg = buf;
- */
-
- /* The above code would be preferred since it allows site specific
- * information to be delivered from the Kerberos server. However the
- * message box is too small for VGA screens.
- * It does work well if we only have to support 1024x768
- */
-
- com_err_msg = "You have entered an insecure or weak password.";
-
- default:
- /* no extra error msg */
- break;
- }
- if(com_err_msg != buf) {
- StringCbCopyA(buf, len, com_err_msg);
- }
- cp = buf + strlen(buf);
- *cp++ = '\n';
- switch(table_num) {
- case krb_err_base:
- etype = "Kerberos";
- break;
- case kadm_err_base:
- etype = "Kerberos supplemental";
- break;
- default:
- etype = Lerror_table_name(table_num);
- break;
- }
- StringCbPrintfA((LPSTR) cp, len - (cp-buf), (LPSTR) "(%s error %d"
-#ifdef DEBUG_COM_ERR
- " (absolute error %ld)"
-#endif
- ")", etype, offset
- //")\nPress F1 for help on this error.", etype, offset
-#ifdef DEBUG_COM_ERR
- , code
-#endif
- );
-
- return (LPSTR)buf;
-}
-
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<kherror.h>
+
+#include<strsafe.h>
+
+extern void (__cdecl *pinitialize_krb_error_func)();
+extern void (__cdecl *pinitialize_kadm_error_table)();
+
+
+khm_int32 init_error_funcs()
+{
+
+#if 0
+ /*TODO: Do something about this */
+ if (plsh_LoadKrb4LeashErrorTables)
+ plsh_LoadKrb4LeashErrorTables(hLeashInst, 0);
+#endif
+ return KHM_ERROR_SUCCESS;
+}
+
+khm_int32 exit_error_funcs()
+{
+ return KHM_ERROR_SUCCESS;
+}
+
+// Global Variables.
+static long lsh_errno;
+static char *err_context; /* error context */
+extern int (*Lcom_err)(LPSTR,long,LPSTR,...);
+extern LPSTR (*Lerror_message)(long);
+extern LPSTR (*Lerror_table_name)(long);
+
+#ifdef WIN16
+#define UNDERSCORE "_"
+#else
+#define UNDERSCORE
+#endif
+
+HWND GetRootParent (HWND Child)
+{
+ HWND Last = NULL;
+ while (Child)
+ {
+ Last = Child;
+ Child = GetParent (Child);
+ }
+ return Last;
+}
+
+
+LPSTR err_describe(LPSTR buf, size_t len, long code)
+{
+ LPSTR cp, com_err_msg;
+ int offset;
+ long table_num;
+ char *etype;
+
+ offset = (int) (code & 255);
+ table_num = code - offset;
+ com_err_msg = Lerror_message(code);
+
+ switch(table_num)
+ {
+ case krb_err_base:
+ case kadm_err_base:
+ break;
+ default:
+ StringCbCopyA(buf, len, com_err_msg);
+ return buf;
+ }
+
+ cp = buf;
+ if (table_num == krb_err_base)
+ switch(offset)
+ {
+ case KDC_NAME_EXP: /* 001 Principal expired */
+ case KDC_SERVICE_EXP: /* 002 Service expired */
+ case KDC_AUTH_EXP: /* 003 Auth expired */
+ case KDC_PKT_VER: /* 004 Protocol version unknown */
+ case KDC_P_MKEY_VER: /* 005 Wrong master key version */
+ case KDC_S_MKEY_VER: /* 006 Wrong master key version */
+ case KDC_BYTE_ORDER: /* 007 Byte order unknown */
+ case KDC_PR_N_UNIQUE: /* 009 Principal not unique */
+ case KDC_NULL_KEY: /* 010 Principal has null key */
+ case KDC_GEN_ERR: /* 011 Generic error from KDC */
+ case INTK_W_NOTALL : /* 061 Not ALL tickets returned */
+ case INTK_PROT : /* 063 Protocol Error */
+ case INTK_ERR : /* 070 Other error */
+ com_err_msg = "Something weird happened... try again, and if Leash"
+ " continues to fail, contact Network Services as listed in the "
+ "About box.";
+ break;
+ case KDC_PR_UNKNOWN: /* 008 Principal unknown */
+ com_err_msg = "You have entered an unknown username/instance/realm"
+ " combination.";
+ break;
+ case GC_TKFIL : /* 021 Can't read ticket file */
+ case GC_NOTKT : /* 022 Can't find ticket or TGT */
+ com_err_msg = "Something is wrong with the memory where your "
+ "tickets are stored. Try exiting Windows and restarting your "
+ "computer.";
+ break;
+ case MK_AP_TGTEXP : /* 026 TGT Expired */
+ /* no extra error msg */
+ break;
+ case RD_AP_TIME : /* 037 delta_t too big */
+ com_err_msg = "Your computer's clock is out of sync with the "
+ "Kerberos server. Please see the help file about correcting "
+ "your clock.";
+ break;
+
+ case RD_AP_UNDEC : /* 031 Can't decode authenticator */
+ case RD_AP_EXP : /* 032 Ticket expired */
+ case RD_AP_NYV : /* 033 Ticket not yet valid */
+ case RD_AP_REPEAT : /* 034 Repeated request */
+ case RD_AP_NOT_US : /* 035 The ticket isn't for us */
+ case RD_AP_INCON : /* 036 Request is inconsistent */
+ case RD_AP_BADD : /* 038 Incorrect net address */
+ case RD_AP_VERSION : /* 039 protocol version mismatch */
+ case RD_AP_MSG_TYPE : /* 040 invalid msg type */
+ case RD_AP_MODIFIED : /* 041 message stream modified */
+ case RD_AP_ORDER : /* 042 message out of order */
+ case RD_AP_UNAUTHOR : /* 043 unauthorized request */
+ /* no extra error msg */
+ break;
+ case GT_PW_NULL: /* 51 Current PW is null */
+ case GT_PW_BADPW: /* 52 Incorrect current password */
+ case GT_PW_PROT: /* 53 Protocol Error */
+ case GT_PW_KDCERR: /* 54 Error returned by KDC */
+ case GT_PW_NULLTKT: /* 55 Null tkt returned by KDC */
+ /* no error msg yet */
+ break;
+
+ /* Values returned by send_to_kdc */
+ case SKDC_RETRY : /* 56 Retry count exceeded */
+ case SKDC_CANT : /* 57 Can't send request */
+ com_err_msg = "Cannot contact the kerberos server for the selected realm.";
+ break;
+ /* no error message on purpose: */
+ case INTK_BADPW : /* 062 Incorrect password */
+ break;
+ default:
+ /* no extra error msg */
+ break;
+ }
+ else
+ switch(code)
+ {
+ case KADM_INSECURE_PW:
+ /* if( kadm_info != NULL ){
+ * wsprintf(buf, "%s\n%s", com_err_msg, kadm_info);
+ * } else {
+ * wsprintf(buf, "%s\nPlease see the help file for information "
+ * "about secure passwords.", com_err_msg);
+ * }
+ * com_err_msg = buf;
+ */
+
+ /* The above code would be preferred since it allows site specific
+ * information to be delivered from the Kerberos server. However the
+ * message box is too small for VGA screens.
+ * It does work well if we only have to support 1024x768
+ */
+
+ com_err_msg = "You have entered an insecure or weak password.";
+
+ default:
+ /* no extra error msg */
+ break;
+ }
+ if(com_err_msg != buf) {
+ StringCbCopyA(buf, len, com_err_msg);
+ }
+ cp = buf + strlen(buf);
+ *cp++ = '\n';
+ switch(table_num) {
+ case krb_err_base:
+ etype = "Kerberos";
+ break;
+ case kadm_err_base:
+ etype = "Kerberos supplemental";
+ break;
+ default:
+ etype = Lerror_table_name(table_num);
+ break;
+ }
+ StringCbPrintfA((LPSTR) cp, len - (cp-buf), (LPSTR) "(%s error %d"
+#ifdef DEBUG_COM_ERR
+ " (absolute error %ld)"
+#endif
+ ")", etype, offset
+ //")\nPress F1 for help on this error.", etype, offset
+#ifdef DEBUG_COM_ERR
+ , code
+#endif
+ );
+
+ return (LPSTR)buf;
+}
+
diff --git a/src/windows/identity/plugins/krb4/errorfuncs.h b/src/windows/identity/plugins/krb4/errorfuncs.h
index e339eca4f..d760c6259 100644
--- a/src/windows/identity/plugins/krb4/errorfuncs.h
+++ b/src/windows/identity/plugins/krb4/errorfuncs.h
@@ -1,65 +1,65 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef __KHIMAIRA_ERR_H
-#define __KHIMAIRA_ERR_H
-
-/* All error handling and reporting related functions for the krb4/5
- and AFS plugins */
-
-#include <errno.h>
-#include <com_err.h>
-/*
- * This is a hack needed because the real com_err.h does
- * not define err_func. We need it in the case where
- * we pull in the real com_err instead of the krb4
- * impostor.
- */
-#ifndef _DCNS_MIT_COM_ERR_H
-typedef LPSTR (*err_func)(int, long);
-#endif
-
-#include <krberr.h>
-#include <kadm_err.h>
-
-#define kadm_err_base ERROR_TABLE_BASE_kadm
-
-#include <stdarg.h>
-
-#ifndef KRBERR
-#define KRBERR(code) (code + krb_err_base)
-#endif
-
-LPSTR err_describe(LPSTR buf, size_t len, long code);
-
-
-/* */
-khm_int32 init_error_funcs();
-
-khm_int32 exit_error_funcs();
-
-
-#endif
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef __KHIMAIRA_ERR_H
+#define __KHIMAIRA_ERR_H
+
+/* All error handling and reporting related functions for the krb4/5
+ and AFS plugins */
+
+#include <errno.h>
+#include <com_err.h>
+/*
+ * This is a hack needed because the real com_err.h does
+ * not define err_func. We need it in the case where
+ * we pull in the real com_err instead of the krb4
+ * impostor.
+ */
+#ifndef _DCNS_MIT_COM_ERR_H
+typedef LPSTR (*err_func)(int, long);
+#endif
+
+#include <krberr.h>
+#include <kadm_err.h>
+
+#define kadm_err_base ERROR_TABLE_BASE_kadm
+
+#include <stdarg.h>
+
+#ifndef KRBERR
+#define KRBERR(code) (code + krb_err_base)
+#endif
+
+LPSTR err_describe(LPSTR buf, size_t len, long code);
+
+
+/* */
+khm_int32 init_error_funcs();
+
+khm_int32 exit_error_funcs();
+
+
+#endif
diff --git a/src/windows/identity/plugins/krb4/krb4configdlg.c b/src/windows/identity/plugins/krb4/krb4configdlg.c
index 523fbac5e..338cf7fa8 100644
--- a/src/windows/identity/plugins/krb4/krb4configdlg.c
+++ b/src/windows/identity/plugins/krb4/krb4configdlg.c
@@ -1,539 +1,539 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<kherror.h>
-#include<khuidefs.h>
-#include<strsafe.h>
-#include<assert.h>
-
-typedef struct tag_k4_ids_data {
- khui_config_init_data cfg;
-
- khm_int32 get_tix;
-} k4_ids_data;
-
-static void
-k4_ids_read_params(k4_ids_data * d) {
- khm_int32 t;
-#ifdef DEBUG
- assert(csp_params);
-#endif
-
- t = 1;
- khc_read_int32(csp_params, L"Krb4NewCreds", &t);
- d->get_tix = !!t;
-}
-
-static void
-k4_ids_write_params(HWND hw, k4_ids_data * d) {
- khm_int32 nv;
- khm_boolean applied = FALSE;
-
- if (IsDlgButtonChecked(hw, IDC_CFG_GETTIX) == BST_CHECKED)
- nv = TRUE;
- else
- nv = FALSE;
-
- if (!!nv != !!d->get_tix) {
- d->get_tix = !!nv;
- khc_write_int32(csp_params, L"Krb4NewCreds", d->get_tix);
- applied = TRUE;
- }
-
- khui_cfg_set_flags_inst(&d->cfg,
- (applied)?KHUI_CNFLAG_APPLIED:0,
- KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED);
-}
-
-static void
-k4_ids_check_mod(HWND hw, k4_ids_data * d) {
- khm_int32 nv;
-
- if (IsDlgButtonChecked(hw, IDC_CFG_GETTIX) == BST_CHECKED)
- nv = TRUE;
- else
- nv = FALSE;
-
- khui_cfg_set_flags_inst(&d->cfg,
- (!!nv != !!d->get_tix)? KHUI_CNFLAG_MODIFIED: 0,
- KHUI_CNFLAG_MODIFIED);
-}
-
-INT_PTR CALLBACK
-krb4_ids_config_proc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
- k4_ids_data * d;
-
- switch(uMsg) {
- case WM_INITDIALOG:
- d = PMALLOC(sizeof(*d));
- ZeroMemory(d, sizeof(*d));
-
- d->cfg = *((khui_config_init_data *) lParam);
-
-#pragma warning(push)
-#pragma warning(disable: 4244)
- SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
-#pragma warning(pop)
-
- k4_ids_read_params(d);
-
- CheckDlgButton(hwnd, IDC_CFG_GETTIX,
- (d->get_tix)? BST_CHECKED: BST_UNCHECKED);
-
- break;
-
- case WM_COMMAND:
- d = (k4_ids_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (HIWORD(wParam) == BN_CLICKED) {
- k4_ids_check_mod(hwnd, d);
- }
- break;
-
- case KHUI_WM_CFG_NOTIFY:
- d = (k4_ids_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (HIWORD(wParam) == WMCFG_APPLY) {
- k4_ids_write_params(hwnd, d);
- }
- break;
-
- case WM_DESTROY:
- d = (k4_ids_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- PFREE(d);
- break;
- }
-
- return FALSE;
-}
-
-typedef struct tag_k4_id_data {
- khui_config_init_data cfg;
- khm_int32 gettix; /* get tickets? */
- khm_boolean is_default_ident;
-} k4_id_data;
-
-void
-k4_id_read_params(k4_id_data * d) {
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- khm_size cb;
- khm_handle ident = NULL;
- khm_handle csp_ident = NULL;
- khm_handle csp_idk4 = NULL;
- khm_int32 flags = 0;
- khm_int32 t;
-
- khc_read_int32(csp_params, L"Krb4NewCreds", &d->gettix);
-
- *idname = 0;
- cb = sizeof(idname);
- khui_cfg_get_name(d->cfg.ctx_node, idname, &cb);
-
- kcdb_identity_create(idname, 0, &ident);
-
- if (ident == NULL) {
- d->gettix = 0;
- goto done;
- }
-
- kcdb_identity_get_flags(ident, &flags);
-
- if (!(flags & KCDB_IDENT_FLAG_DEFAULT)) {
- d->gettix = 0;
- goto done;
- }
-
- d->is_default_ident = TRUE;
-
- if (d->gettix == 0)
- goto done;
-
- if (KHM_FAILED(kcdb_identity_get_config(ident, 0, &csp_ident)))
- goto done;
-
- if (KHM_FAILED(khc_open_space(csp_ident, CSNAME_KRB4CRED,
- 0, &csp_idk4)))
- goto close_config;
-
- if (KHM_SUCCEEDED(khc_read_int32(csp_idk4, L"Krb4NewCreds", &t)) &&
- !t)
- d->gettix = 1;
-
- close_config:
- if (csp_ident)
- khc_close_space(csp_ident);
-
- if (csp_idk4)
- khc_close_space(csp_idk4);
-
- done:
- if (ident)
- kcdb_identity_release(ident);
-
- return;
-}
-
-khm_boolean
-k4_id_write_params(HWND hwnd, k4_id_data * d) {
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- khm_size cb_idname = sizeof(idname);
- khm_handle ident = NULL;
- khm_int32 flags = 0;
- khm_handle csp_ident = NULL;
- khm_handle csp_idk4 = NULL;
- khm_int32 gettix = 0;
- khm_boolean applied = FALSE;
-
- khui_cfg_get_name(d->cfg.ctx_node, idname, &cb_idname);
-
- kcdb_identity_create(idname, 0, &ident);
-
- if (ident == NULL)
- return FALSE;
-
- kcdb_identity_get_flags(ident, &flags);
-
- if (!(flags & KCDB_IDENT_FLAG_DEFAULT))
- goto done_apply;
-
- if (IsDlgButtonChecked(hwnd, IDC_CFG_GETTIX) == BST_CHECKED)
- gettix = TRUE;
-
- if (KHM_FAILED(kcdb_identity_get_config(ident, KHM_FLAG_CREATE,
- &csp_ident)))
- goto done_apply;
-
- if (KHM_FAILED(khc_open_space(csp_ident, CSNAME_KRB4CRED,
- KHM_FLAG_CREATE | KCONF_FLAG_WRITEIFMOD,
- &csp_idk4)))
- goto done_apply;
-
- khc_write_int32(csp_idk4, L"Krb4NewCreds", gettix);
-
- applied = TRUE;
-
- done_apply:
- if (ident)
- kcdb_identity_release(ident);
-
- if (csp_ident)
- khc_close_space(csp_ident);
-
- if (csp_idk4)
- khc_close_space(csp_idk4);
-
- return applied;
-}
-
-INT_PTR CALLBACK
-krb4_id_config_proc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
- switch(uMsg) {
- case WM_INITDIALOG:
- {
- k4_id_data * d;
-
- d = PMALLOC(sizeof(k4_id_data));
-
- if (!d)
- break;
-
- ZeroMemory(d, sizeof(*d));
-
- d->cfg = *((khui_config_init_data *) lParam);
-
-#pragma warning(push)
-#pragma warning(disable: 4244)
- SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
-#pragma warning(pop)
-
- k4_id_read_params(d);
-
- CheckDlgButton(hwnd, IDC_CFG_GETTIX,
- (d->gettix)?BST_CHECKED: BST_UNCHECKED);
- EnableWindow(GetDlgItem(hwnd, IDC_CFG_GETTIX),
- d->is_default_ident);
-
- }
- break;
-
- case WM_COMMAND:
- {
- k4_id_data * d;
-
- d = (k4_id_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (wParam == MAKEWPARAM(IDC_CFG_GETTIX,
- BN_CLICKED)) {
- int gettix = 0;
- int modified = 0;
-
- gettix = (IsDlgButtonChecked(hwnd, IDC_CFG_GETTIX) ==
- BST_CHECKED);
-
- modified = (!!gettix != !!d->gettix);
-
- khui_cfg_set_flags_inst(&d->cfg,
- ((modified)?KHUI_CNFLAG_MODIFIED: 0),
- KHUI_CNFLAG_MODIFIED);
- }
- }
- break;
-
- case KHUI_WM_CFG_NOTIFY:
- {
- k4_id_data * d;
-
- d = (k4_id_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (!d)
- break;
-
- if (HIWORD(wParam) == WMCFG_APPLY) {
- khm_int32 applied;
-
- applied = k4_id_write_params(hwnd, d);
-
- khui_cfg_set_flags_inst(&d->cfg,
- ((applied)? KHUI_CNFLAG_APPLIED: 0),
- (KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED));
- }
- }
- break;
-
- case WM_DESTROY:
- {
- k4_id_data * d;
-
- d = (k4_id_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (!d)
- break;
-
- PFREE(d);
- }
- break;
- }
-
- return FALSE;
-}
-
-typedef struct tag_k4_config_dlg_data {
- khui_config_node node;
- char krb_path[MAX_PATH];
- char krbrealm_path[MAX_PATH];
- char tkt_string[MAX_PATH];
-} k4_config_dlg_data;
-
-INT_PTR CALLBACK
-krb4_confg_proc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
-
- static BOOL in_init = FALSE;
- k4_config_dlg_data * d;
-
- switch(uMsg) {
- case WM_INITDIALOG:
- {
- wchar_t wbuf[MAX_PATH];
- CHAR krb_path[MAX_PATH];
- CHAR krbrealm_path[MAX_PATH];
- CHAR ticketName[MAX_PATH];
- char * pticketName;
- unsigned int krb_path_sz = sizeof(krb_path);
- unsigned int krbrealm_path_sz = sizeof(krbrealm_path);
- khm_size cbsize;
-
- d = PMALLOC(sizeof(*d));
- ZeroMemory(d, sizeof(*d));
-
-#pragma warning(push)
-#pragma warning(disable: 4244)
- SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
-#pragma warning(pop)
-
- d->node = (khui_config_node) lParam;
-
- in_init = TRUE;
-
- // Set KRB.CON
- memset(krb_path, '\0', sizeof(krb_path));
- if (!pkrb_get_krbconf2(krb_path, &krb_path_sz)) {
- // Error has happened
- } else { // normal find
- AnsiStrToUnicode(wbuf, sizeof(wbuf), krb_path);
- SetDlgItemText(hwnd, IDC_CFG_CFGPATH, wbuf);
- StringCbCopyA(d->krb_path, sizeof(d->krb_path), krb_path);
- }
-
- // Set KRBREALM.CON
- memset(krbrealm_path, '\0', sizeof(krbrealm_path));
- if (!pkrb_get_krbrealm2(krbrealm_path, &krbrealm_path_sz)) {
- // Error has happened
- } else {
- AnsiStrToUnicode(wbuf, sizeof(wbuf), krbrealm_path);
- SetDlgItemText(hwnd, IDC_CFG_RLMPATH, wbuf);
- StringCbCopyA(d->krbrealm_path, sizeof(d->krbrealm_path),
- krbrealm_path);
- }
-
- cbsize = sizeof(wbuf);
- if (KHM_SUCCEEDED(khc_read_string(csp_params, L"TktString",
- wbuf, &cbsize)) &&
- wbuf[0] != L'\0') {
-
- UnicodeStrToAnsi(ticketName, sizeof(ticketName), wbuf);
-
- } else {
-
- // Set TICKET.KRB file Editbox
- *ticketName = 0;
- pkrb_set_tkt_string(0);
-
- pticketName = ptkt_string();
- if (pticketName)
- StringCbCopyA(ticketName, sizeof(ticketName), pticketName);
-
- }
-
- if (!*ticketName) {
- // error
- } else {
- AnsiStrToUnicode(wbuf, sizeof(wbuf), ticketName);
- SetDlgItemText(hwnd, IDC_CFG_CACHE, wbuf);
- StringCbCopyA(d->tkt_string, sizeof(d->tkt_string),
- ticketName);
- }
-
- in_init = FALSE;
-
- }
- break;
-
- case WM_COMMAND:
- if (MAKEWPARAM(IDC_CFG_CACHE, EN_CHANGE)) {
- char tkt_string[MAX_PATH];
- wchar_t wtkt_string[MAX_PATH];
-
- if (in_init) {
- return TRUE;
- }
-
- d = (k4_config_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (d == NULL)
- return TRUE;
-
- tkt_string[0] = 0;
- wtkt_string[0] = 0;
-
- GetDlgItemText(hwnd, IDC_CFG_CACHE,
- wtkt_string, ARRAYLENGTH(wtkt_string));
- UnicodeStrToAnsi(tkt_string, sizeof(tkt_string),
- wtkt_string);
-
- if (_stricmp(tkt_string, d->tkt_string)) {
- khui_cfg_set_flags(d->node,
- KHUI_CNFLAG_MODIFIED,
- KHUI_CNFLAG_MODIFIED);
- } else {
- khui_cfg_set_flags(d->node,
- 0,
- KHUI_CNFLAG_MODIFIED);
- }
-
- return TRUE;
- }
- break;
-
- case KHUI_WM_CFG_NOTIFY:
- if (HIWORD(wParam) == WMCFG_APPLY) {
- wchar_t wtkt_string[MAX_PATH];
- char tkt_string[MAX_PATH];
- int t;
-
- d = (k4_config_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (d == NULL)
- return TRUE;
-
- t = GetDlgItemText(hwnd, IDC_CFG_CACHE,
- wtkt_string, ARRAYLENGTH(wtkt_string));
- if (t == 0)
- return TRUE;
-
- UnicodeStrToAnsi(tkt_string, sizeof(tkt_string), wtkt_string);
-
- if (_stricmp(tkt_string, d->tkt_string)) {
-
- pkrb_set_tkt_string(tkt_string);
-
- khc_write_string(csp_params, L"TktString", wtkt_string);
-
- khui_cfg_set_flags(d->node,
- KHUI_CNFLAG_APPLIED,
- KHUI_CNFLAG_APPLIED |
- KHUI_CNFLAG_MODIFIED);
- khm_krb4_list_tickets();
- } else {
- khui_cfg_set_flags(d->node,
- 0,
- KHUI_CNFLAG_MODIFIED);
- }
-
- return TRUE;
- }
- break;
-
- case WM_DESTROY:
- d = (k4_config_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (d) {
- PFREE(d);
- }
-
- break;
- }
- return FALSE;
-}
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<kherror.h>
+#include<khuidefs.h>
+#include<strsafe.h>
+#include<assert.h>
+
+typedef struct tag_k4_ids_data {
+ khui_config_init_data cfg;
+
+ khm_int32 get_tix;
+} k4_ids_data;
+
+static void
+k4_ids_read_params(k4_ids_data * d) {
+ khm_int32 t;
+#ifdef DEBUG
+ assert(csp_params);
+#endif
+
+ t = 1;
+ khc_read_int32(csp_params, L"Krb4NewCreds", &t);
+ d->get_tix = !!t;
+}
+
+static void
+k4_ids_write_params(HWND hw, k4_ids_data * d) {
+ khm_int32 nv;
+ khm_boolean applied = FALSE;
+
+ if (IsDlgButtonChecked(hw, IDC_CFG_GETTIX) == BST_CHECKED)
+ nv = TRUE;
+ else
+ nv = FALSE;
+
+ if (!!nv != !!d->get_tix) {
+ d->get_tix = !!nv;
+ khc_write_int32(csp_params, L"Krb4NewCreds", d->get_tix);
+ applied = TRUE;
+ }
+
+ khui_cfg_set_flags_inst(&d->cfg,
+ (applied)?KHUI_CNFLAG_APPLIED:0,
+ KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED);
+}
+
+static void
+k4_ids_check_mod(HWND hw, k4_ids_data * d) {
+ khm_int32 nv;
+
+ if (IsDlgButtonChecked(hw, IDC_CFG_GETTIX) == BST_CHECKED)
+ nv = TRUE;
+ else
+ nv = FALSE;
+
+ khui_cfg_set_flags_inst(&d->cfg,
+ (!!nv != !!d->get_tix)? KHUI_CNFLAG_MODIFIED: 0,
+ KHUI_CNFLAG_MODIFIED);
+}
+
+INT_PTR CALLBACK
+krb4_ids_config_proc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+ k4_ids_data * d;
+
+ switch(uMsg) {
+ case WM_INITDIALOG:
+ d = PMALLOC(sizeof(*d));
+ ZeroMemory(d, sizeof(*d));
+
+ d->cfg = *((khui_config_init_data *) lParam);
+
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
+#pragma warning(pop)
+
+ k4_ids_read_params(d);
+
+ CheckDlgButton(hwnd, IDC_CFG_GETTIX,
+ (d->get_tix)? BST_CHECKED: BST_UNCHECKED);
+
+ break;
+
+ case WM_COMMAND:
+ d = (k4_ids_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (HIWORD(wParam) == BN_CLICKED) {
+ k4_ids_check_mod(hwnd, d);
+ }
+ break;
+
+ case KHUI_WM_CFG_NOTIFY:
+ d = (k4_ids_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (HIWORD(wParam) == WMCFG_APPLY) {
+ k4_ids_write_params(hwnd, d);
+ }
+ break;
+
+ case WM_DESTROY:
+ d = (k4_ids_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ PFREE(d);
+ break;
+ }
+
+ return FALSE;
+}
+
+typedef struct tag_k4_id_data {
+ khui_config_init_data cfg;
+ khm_int32 gettix; /* get tickets? */
+ khm_boolean is_default_ident;
+} k4_id_data;
+
+void
+k4_id_read_params(k4_id_data * d) {
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb;
+ khm_handle ident = NULL;
+ khm_handle csp_ident = NULL;
+ khm_handle csp_idk4 = NULL;
+ khm_int32 flags = 0;
+ khm_int32 t;
+
+ khc_read_int32(csp_params, L"Krb4NewCreds", &d->gettix);
+
+ *idname = 0;
+ cb = sizeof(idname);
+ khui_cfg_get_name(d->cfg.ctx_node, idname, &cb);
+
+ kcdb_identity_create(idname, 0, &ident);
+
+ if (ident == NULL) {
+ d->gettix = 0;
+ goto done;
+ }
+
+ kcdb_identity_get_flags(ident, &flags);
+
+ if (!(flags & KCDB_IDENT_FLAG_DEFAULT)) {
+ d->gettix = 0;
+ goto done;
+ }
+
+ d->is_default_ident = TRUE;
+
+ if (d->gettix == 0)
+ goto done;
+
+ if (KHM_FAILED(kcdb_identity_get_config(ident, 0, &csp_ident)))
+ goto done;
+
+ if (KHM_FAILED(khc_open_space(csp_ident, CSNAME_KRB4CRED,
+ 0, &csp_idk4)))
+ goto close_config;
+
+ if (KHM_SUCCEEDED(khc_read_int32(csp_idk4, L"Krb4NewCreds", &t)) &&
+ !t)
+ d->gettix = 1;
+
+ close_config:
+ if (csp_ident)
+ khc_close_space(csp_ident);
+
+ if (csp_idk4)
+ khc_close_space(csp_idk4);
+
+ done:
+ if (ident)
+ kcdb_identity_release(ident);
+
+ return;
+}
+
+khm_boolean
+k4_id_write_params(HWND hwnd, k4_id_data * d) {
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb_idname = sizeof(idname);
+ khm_handle ident = NULL;
+ khm_int32 flags = 0;
+ khm_handle csp_ident = NULL;
+ khm_handle csp_idk4 = NULL;
+ khm_int32 gettix = 0;
+ khm_boolean applied = FALSE;
+
+ khui_cfg_get_name(d->cfg.ctx_node, idname, &cb_idname);
+
+ kcdb_identity_create(idname, 0, &ident);
+
+ if (ident == NULL)
+ return FALSE;
+
+ kcdb_identity_get_flags(ident, &flags);
+
+ if (!(flags & KCDB_IDENT_FLAG_DEFAULT))
+ goto done_apply;
+
+ if (IsDlgButtonChecked(hwnd, IDC_CFG_GETTIX) == BST_CHECKED)
+ gettix = TRUE;
+
+ if (KHM_FAILED(kcdb_identity_get_config(ident, KHM_FLAG_CREATE,
+ &csp_ident)))
+ goto done_apply;
+
+ if (KHM_FAILED(khc_open_space(csp_ident, CSNAME_KRB4CRED,
+ KHM_FLAG_CREATE | KCONF_FLAG_WRITEIFMOD,
+ &csp_idk4)))
+ goto done_apply;
+
+ khc_write_int32(csp_idk4, L"Krb4NewCreds", gettix);
+
+ applied = TRUE;
+
+ done_apply:
+ if (ident)
+ kcdb_identity_release(ident);
+
+ if (csp_ident)
+ khc_close_space(csp_ident);
+
+ if (csp_idk4)
+ khc_close_space(csp_idk4);
+
+ return applied;
+}
+
+INT_PTR CALLBACK
+krb4_id_config_proc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+ switch(uMsg) {
+ case WM_INITDIALOG:
+ {
+ k4_id_data * d;
+
+ d = PMALLOC(sizeof(k4_id_data));
+
+ if (!d)
+ break;
+
+ ZeroMemory(d, sizeof(*d));
+
+ d->cfg = *((khui_config_init_data *) lParam);
+
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
+#pragma warning(pop)
+
+ k4_id_read_params(d);
+
+ CheckDlgButton(hwnd, IDC_CFG_GETTIX,
+ (d->gettix)?BST_CHECKED: BST_UNCHECKED);
+ EnableWindow(GetDlgItem(hwnd, IDC_CFG_GETTIX),
+ d->is_default_ident);
+
+ }
+ break;
+
+ case WM_COMMAND:
+ {
+ k4_id_data * d;
+
+ d = (k4_id_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (wParam == MAKEWPARAM(IDC_CFG_GETTIX,
+ BN_CLICKED)) {
+ int gettix = 0;
+ int modified = 0;
+
+ gettix = (IsDlgButtonChecked(hwnd, IDC_CFG_GETTIX) ==
+ BST_CHECKED);
+
+ modified = (!!gettix != !!d->gettix);
+
+ khui_cfg_set_flags_inst(&d->cfg,
+ ((modified)?KHUI_CNFLAG_MODIFIED: 0),
+ KHUI_CNFLAG_MODIFIED);
+ }
+ }
+ break;
+
+ case KHUI_WM_CFG_NOTIFY:
+ {
+ k4_id_data * d;
+
+ d = (k4_id_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (!d)
+ break;
+
+ if (HIWORD(wParam) == WMCFG_APPLY) {
+ khm_int32 applied;
+
+ applied = k4_id_write_params(hwnd, d);
+
+ khui_cfg_set_flags_inst(&d->cfg,
+ ((applied)? KHUI_CNFLAG_APPLIED: 0),
+ (KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED));
+ }
+ }
+ break;
+
+ case WM_DESTROY:
+ {
+ k4_id_data * d;
+
+ d = (k4_id_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (!d)
+ break;
+
+ PFREE(d);
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+typedef struct tag_k4_config_dlg_data {
+ khui_config_node node;
+ char krb_path[MAX_PATH];
+ char krbrealm_path[MAX_PATH];
+ char tkt_string[MAX_PATH];
+} k4_config_dlg_data;
+
+INT_PTR CALLBACK
+krb4_confg_proc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+
+ static BOOL in_init = FALSE;
+ k4_config_dlg_data * d;
+
+ switch(uMsg) {
+ case WM_INITDIALOG:
+ {
+ wchar_t wbuf[MAX_PATH];
+ CHAR krb_path[MAX_PATH];
+ CHAR krbrealm_path[MAX_PATH];
+ CHAR ticketName[MAX_PATH];
+ char * pticketName;
+ unsigned int krb_path_sz = sizeof(krb_path);
+ unsigned int krbrealm_path_sz = sizeof(krbrealm_path);
+ khm_size cbsize;
+
+ d = PMALLOC(sizeof(*d));
+ ZeroMemory(d, sizeof(*d));
+
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
+#pragma warning(pop)
+
+ d->node = (khui_config_node) lParam;
+
+ in_init = TRUE;
+
+ // Set KRB.CON
+ memset(krb_path, '\0', sizeof(krb_path));
+ if (!pkrb_get_krbconf2(krb_path, &krb_path_sz)) {
+ // Error has happened
+ } else { // normal find
+ AnsiStrToUnicode(wbuf, sizeof(wbuf), krb_path);
+ SetDlgItemText(hwnd, IDC_CFG_CFGPATH, wbuf);
+ StringCbCopyA(d->krb_path, sizeof(d->krb_path), krb_path);
+ }
+
+ // Set KRBREALM.CON
+ memset(krbrealm_path, '\0', sizeof(krbrealm_path));
+ if (!pkrb_get_krbrealm2(krbrealm_path, &krbrealm_path_sz)) {
+ // Error has happened
+ } else {
+ AnsiStrToUnicode(wbuf, sizeof(wbuf), krbrealm_path);
+ SetDlgItemText(hwnd, IDC_CFG_RLMPATH, wbuf);
+ StringCbCopyA(d->krbrealm_path, sizeof(d->krbrealm_path),
+ krbrealm_path);
+ }
+
+ cbsize = sizeof(wbuf);
+ if (KHM_SUCCEEDED(khc_read_string(csp_params, L"TktString",
+ wbuf, &cbsize)) &&
+ wbuf[0] != L'\0') {
+
+ UnicodeStrToAnsi(ticketName, sizeof(ticketName), wbuf);
+
+ } else {
+
+ // Set TICKET.KRB file Editbox
+ *ticketName = 0;
+ pkrb_set_tkt_string(0);
+
+ pticketName = ptkt_string();
+ if (pticketName)
+ StringCbCopyA(ticketName, sizeof(ticketName), pticketName);
+
+ }
+
+ if (!*ticketName) {
+ // error
+ } else {
+ AnsiStrToUnicode(wbuf, sizeof(wbuf), ticketName);
+ SetDlgItemText(hwnd, IDC_CFG_CACHE, wbuf);
+ StringCbCopyA(d->tkt_string, sizeof(d->tkt_string),
+ ticketName);
+ }
+
+ in_init = FALSE;
+
+ }
+ break;
+
+ case WM_COMMAND:
+ if (MAKEWPARAM(IDC_CFG_CACHE, EN_CHANGE)) {
+ char tkt_string[MAX_PATH];
+ wchar_t wtkt_string[MAX_PATH];
+
+ if (in_init) {
+ return TRUE;
+ }
+
+ d = (k4_config_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (d == NULL)
+ return TRUE;
+
+ tkt_string[0] = 0;
+ wtkt_string[0] = 0;
+
+ GetDlgItemText(hwnd, IDC_CFG_CACHE,
+ wtkt_string, ARRAYLENGTH(wtkt_string));
+ UnicodeStrToAnsi(tkt_string, sizeof(tkt_string),
+ wtkt_string);
+
+ if (_stricmp(tkt_string, d->tkt_string)) {
+ khui_cfg_set_flags(d->node,
+ KHUI_CNFLAG_MODIFIED,
+ KHUI_CNFLAG_MODIFIED);
+ } else {
+ khui_cfg_set_flags(d->node,
+ 0,
+ KHUI_CNFLAG_MODIFIED);
+ }
+
+ return TRUE;
+ }
+ break;
+
+ case KHUI_WM_CFG_NOTIFY:
+ if (HIWORD(wParam) == WMCFG_APPLY) {
+ wchar_t wtkt_string[MAX_PATH];
+ char tkt_string[MAX_PATH];
+ int t;
+
+ d = (k4_config_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (d == NULL)
+ return TRUE;
+
+ t = GetDlgItemText(hwnd, IDC_CFG_CACHE,
+ wtkt_string, ARRAYLENGTH(wtkt_string));
+ if (t == 0)
+ return TRUE;
+
+ UnicodeStrToAnsi(tkt_string, sizeof(tkt_string), wtkt_string);
+
+ if (_stricmp(tkt_string, d->tkt_string)) {
+
+ pkrb_set_tkt_string(tkt_string);
+
+ khc_write_string(csp_params, L"TktString", wtkt_string);
+
+ khui_cfg_set_flags(d->node,
+ KHUI_CNFLAG_APPLIED,
+ KHUI_CNFLAG_APPLIED |
+ KHUI_CNFLAG_MODIFIED);
+ khm_krb4_list_tickets();
+ } else {
+ khui_cfg_set_flags(d->node,
+ 0,
+ KHUI_CNFLAG_MODIFIED);
+ }
+
+ return TRUE;
+ }
+ break;
+
+ case WM_DESTROY:
+ d = (k4_config_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (d) {
+ PFREE(d);
+ }
+
+ break;
+ }
+ return FALSE;
+}
diff --git a/src/windows/identity/plugins/krb4/krb4funcs.c b/src/windows/identity/plugins/krb4/krb4funcs.c
index b2b5fef4e..9e9ba42d2 100644
--- a/src/windows/identity/plugins/krb4/krb4funcs.c
+++ b/src/windows/identity/plugins/krb4/krb4funcs.c
@@ -1,897 +1,897 @@
-/*
-* Copyright (c) 2005 Massachusetts Institute of Technology
-*
-* Permission is hereby granted, free of charge, to any person
-* obtaining a copy of this software and associated documentation
-* files (the "Software"), to deal in the Software without
-* restriction, including without limitation the rights to use, copy,
-* modify, merge, publish, distribute, sublicense, and/or sell copies
-* of the Software, and to permit persons to whom the Software is
-* furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be
-* included in all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-* SOFTWARE.
-*/
-
-/* $Id$ */
-
-/* Originally this was krb5routines.c in Leash sources. Subsequently
-modified and adapted for NetIDMgr */
-
-#include<krbcred.h>
-#include<kherror.h>
-
-#define SECURITY_WIN32
-#include <security.h>
-
-#include <string.h>
-#include <time.h>
-#include <assert.h>
-#include <strsafe.h>
-
-
-
-int com_addr(void)
-{
- long ipAddr;
- char loc_addr[ADDR_SZ];
- CREDENTIALS cred;
- char service[40];
- char instance[40];
- // char addr[40];
- char realm[40];
- struct in_addr LocAddr;
- int k_errno;
-
- if (pkrb_get_cred == NULL)
- return(KSUCCESS);
-
- k_errno = (*pkrb_get_cred)(service,instance,realm,&cred);
- if (k_errno)
- return KRBERR(k_errno);
-
- while(1) {
- ipAddr = (*pLocalHostAddr)();
- LocAddr.s_addr = ipAddr;
- StringCbCopyA(loc_addr, sizeof(loc_addr), inet_ntoa(LocAddr));
- if ( strcmp(cred.address,loc_addr) != 0) {
- /* TODO: do something about this */
- //Leash_kdestroy ();
- break;
- }
- break;
- } // while()
- return 0;
-}
-
-
-long
-khm_krb4_list_tickets(void)
-{
- char ptktname[MAX_PATH + 5];
- char pname[ANAME_SZ];
- char pinst[INST_SZ];
- char prealm[REALM_SZ];
- wchar_t wbuf[256];
- int k_errno = 0;
- CREDENTIALS c;
- int newtickets = 0;
- int open = 0;
- khm_handle ident = NULL;
- khm_handle cred = NULL;
- time_t tt;
- FILETIME ft;
-
- kcdb_credset_flush(krb4_credset);
-
- // Since krb_get_tf_realm will return a ticket_file error,
- // we will call tf_init and tf_close first to filter out
- // things like no ticket file. Otherwise, the error that
- // the user would see would be
- // klist: can't find realm of ticket file: No ticket file (tf_util)
- // instead of klist: No ticket file (tf_util)
- if (ptf_init == NULL)
- goto collect;
-
- com_addr();
-
- // Open ticket file
- if ((k_errno = (*ptf_init)((*ptkt_string)(), R_TKT_FIL)))
- {
- goto cleanup;
- }
- // Close ticket file
- (void) (*ptf_close)();
-
- // We must find the realm of the ticket file here before calling
- // tf_init because since the realm of the ticket file is not
- // really stored in the principal section of the file, the
- // routine we use must itself call tf_init and tf_close.
-
- if ((k_errno = (*pkrb_get_tf_realm)((*ptkt_string)(), prealm)) != KSUCCESS)
- {
- goto cleanup;
- }
-
- // Open ticket file
- if (k_errno = (*ptf_init)((*ptkt_string)(), R_TKT_FIL))
- {
- goto cleanup;
- }
-
- StringCchCopyA(ptktname, ARRAYLENGTH(ptktname), (*ptkt_string)());
-
- open = 1;
-
- // Get principal name and instance
- if ((k_errno = (*ptf_get_pname)(pname)) || (k_errno = (*ptf_get_pinst)(pinst)))
- {
- goto cleanup;
- }
-
- // You may think that this is the obvious place to get the
- // realm of the ticket file, but it can't be done here as the
- // routine to do this must open the ticket file. This is why
- // it was done before tf_init.
- StringCbPrintf(wbuf, sizeof(wbuf), L"%S%S%S%S%S", (LPSTR)pname,
- (LPSTR)(pinst[0] ? "." : ""), (LPSTR)pinst,
- (LPSTR)(prealm[0] ? "@" : ""), (LPSTR)prealm);
-
- if(KHM_FAILED(kcdb_identity_create(wbuf, KCDB_IDENT_FLAG_CREATE, &ident)))
- {
- goto cleanup;
- }
-
- // Get KRB4 tickets
- while ((k_errno = (*ptf_get_cred)(&c)) == KSUCCESS)
- {
- StringCbPrintf(wbuf, sizeof(wbuf), L"%S%S%S%S%S",
- c.service,
- (c.instance[0] ? "." : ""),
- c.instance,
- (c.realm[0] ? "@" : ""),
- c.realm);
-
- if(KHM_FAILED(kcdb_cred_create(wbuf, ident, credtype_id_krb4, &cred)))
- continue;
-
- tt = c.issue_date + c.lifetime * 5L * 60L;
- TimetToFileTime(tt, &ft);
- kcdb_cred_set_attr(cred, KCDB_ATTR_EXPIRE, &ft, sizeof(ft));
-
- tt = c.issue_date;
- TimetToFileTime(tt, &ft);
- kcdb_cred_set_attr(cred, KCDB_ATTR_ISSUE, &ft, sizeof(ft));
-
- tt = c.lifetime * 5L * 60L;
- TimetToFileTimeInterval(tt, &ft);
- kcdb_cred_set_attr(cred, KCDB_ATTR_LIFETIME, &ft, sizeof(ft));
-
- AnsiStrToUnicode(wbuf, sizeof(wbuf), ptktname);
- kcdb_cred_set_attr(cred, KCDB_ATTR_LOCATION, wbuf, KCDB_CBSIZE_AUTO);
-
- kcdb_credset_add_cred(krb4_credset, cred, -1);
-
- kcdb_cred_release(cred);
- } // while
-
- cleanup:
- if (ptf_close == NULL)
- return(KSUCCESS);
-
- if (open)
- (*ptf_close)(); //close ticket file
-
- if (k_errno == EOF)
- k_errno = 0;
-
- // XXX the if statement directly below was inserted to eliminate
- // an error NO_TKT_FIL on Leash startup. The error occurs from an
- // error number thrown from krb_get_tf_realm. We believe this
- // change does not eliminate other errors, but it may.
-
- if (k_errno == NO_TKT_FIL)
- k_errno = 0;
-
- if(ident)
- kcdb_identity_release(ident);
-
-#if 0
- /*TODO: Handle errors here */
- if (k_errno)
- {
- CHAR message[256];
- CHAR errBuf[256];
- LPCSTR errText;
-
- if (!Lerror_message)
- return -1;
-
- errText = err_describe(errBuf, KRBERR(k_errno));
-
- sprintf(message, "%s\n\n%s failed", errText, functionName);
- MessageBox(NULL, message, "Kerberos Four",
- MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND);
- }
-#endif
-
- collect:
- kcdb_credset_collect(NULL, krb4_credset, ident, credtype_id_krb4, NULL);
-
- return k_errno;
-}
-
-#define KRB_FILE "KRB.CON"
-#define KRBREALM_FILE "KRBREALM.CON"
-#define KRB5_FILE "KRB5.INI"
-
-BOOL
-khm_krb5_get_profile_file(LPSTR confname, UINT szConfname)
-{
- char **configFile = NULL;
- if (pkrb5_get_default_config_files(&configFile))
- {
- GetWindowsDirectoryA(confname,szConfname);
- confname[szConfname-1] = '\0';
-
- StringCchCatA(confname, szConfname, "\\");
- StringCchCatA(confname, szConfname, KRB5_FILE);
-
- return FALSE;
- }
-
- *confname = 0;
-
- if (configFile)
- {
- StringCchCopyA(confname, szConfname, *configFile);
- pkrb5_free_config_files(configFile);
- }
-
- if (!*confname)
- {
- GetWindowsDirectoryA(confname,szConfname);
- confname[szConfname-1] = '\0';
-
- StringCchCatA(confname, szConfname, "\\");
- StringCchCatA(confname, szConfname, KRB5_FILE);
- }
-
- return FALSE;
-}
-
-BOOL
-khm_get_krb4_con_file(LPSTR confname, UINT szConfname)
-{
- if (hKrb5 && !hKrb4) {
- // hold krb.con where krb5.ini is located
- CHAR krbConFile[MAX_PATH]="";
- LPSTR pFind;
-
- if (khm_krb5_get_profile_file(krbConFile, sizeof(krbConFile))) {
- GetWindowsDirectoryA(krbConFile,sizeof(krbConFile));
- krbConFile[MAX_PATH-1] = '\0';
-
- StringCbCatA(krbConFile, sizeof(krbConFile), "\\");
- }
-
- pFind = strrchr(krbConFile, '\\');
-
- if (pFind) {
- *pFind = '\0';
-
- StringCbCatA(krbConFile, sizeof(krbConFile), "\\");
- StringCbCatA(krbConFile, sizeof(krbConFile), KRB_FILE);
- } else {
- krbConFile[0] = '\0';
- }
-
- StringCchCopyA(confname, szConfname, krbConFile);
- } else if (hKrb4) {
- unsigned int size = szConfname;
- memset(confname, '\0', szConfname);
- if (!pkrb_get_krbconf2(confname, &size)) {
- GetWindowsDirectoryA(confname,szConfname);
- confname[szConfname-1] = '\0';
- StringCchCatA(confname, szConfname, "\\");
- StringCchCatA(confname, szConfname, KRB_FILE);
- }
- }
-
- return FALSE;
-}
-
-int
-readstring(FILE * file, char * buf, int len)
-{
- int c,i;
- memset(buf, '\0', sizeof(buf));
- for (i=0, c=fgetc(file); c != EOF ; c=fgetc(file), i++)
- {
- if (i < sizeof(buf)) {
- if (c == '\n') {
- buf[i] = '\0';
- return i;
- } else {
- buf[i] = c;
- }
- } else {
- if (c == '\n') {
- buf[len-1] = '\0';
- return(i);
- }
- }
- }
- if (c == EOF) {
- if (i > 0 && i < len) {
- buf[i] = '\0';
- return(i);
- } else {
- buf[len-1] = '\0';
- return(-1);
- }
- }
- return(-1);
-}
-
-/*! \internal
- \brief Return a list of configured realms
-
- The string that is returned is a set of null terminated unicode strings,
- each of which denotes one realm. The set is terminated by a zero length
- null terminated string.
-
- The caller should free the returned string using free()
-
- \return The string with the list of realms or NULL if the operation fails.
-*/
-wchar_t * khm_krb5_get_realm_list(void)
-{
- wchar_t * rlist = NULL;
-
- if (pprofile_get_subsection_names && pprofile_free_list) {
- const char* rootSection[] = {"realms", NULL};
- const char** rootsec = rootSection;
- char **sections = NULL, **cpp = NULL, *value = NULL;
-
- char krb5_conf[MAX_PATH+1];
-
- if (!khm_krb5_get_profile_file(krb5_conf,sizeof(krb5_conf))) {
- profile_t profile;
- long retval;
- const char *filenames[2];
- wchar_t * d;
- size_t cbsize;
- size_t t;
-
- filenames[0] = krb5_conf;
- filenames[1] = NULL;
- retval = pprofile_init(filenames, &profile);
- if (!retval) {
- retval = pprofile_get_subsection_names(profile, rootsec, &sections);
-
- if (!retval)
- {
- /* first figure out how much space to allocate */
- cbsize = 0;
- for (cpp = sections; *cpp; cpp++)
- {
- cbsize += sizeof(wchar_t) * (strlen(*cpp) + 1);
- }
- cbsize += sizeof(wchar_t); /* double null terminated */
-
- rlist = PMALLOC(cbsize);
- d = rlist;
- for (cpp = sections; *cpp; cpp++)
- {
- AnsiStrToUnicode(d, cbsize, *cpp);
- t = wcslen(d) + 1;
- d += t;
- cbsize -= sizeof(wchar_t) * t;
- }
- *d = L'\0';
- }
-
- pprofile_free_list(sections);
-
-#if 0
- retval = pprofile_get_string(profile, "libdefaults","noaddresses", 0, "true", &value);
- if ( value ) {
- disable_noaddresses = config_boolean_to_int(value);
- pprofile_release_string(value);
- }
-#endif
- pprofile_release(profile);
- }
- }
- } else {
- FILE * file;
- char krb_conf[MAX_PATH+1];
- char * p;
- size_t cbsize, t;
- wchar_t * d;
-
- if (!khm_get_krb4_con_file(krb_conf,sizeof(krb_conf)) &&
-#if _MSC_VER >= 1400
- !fopen_s(&file, krb_conf, "rt")
-#else
- (file = fopen(krb_conf, "rt"))
-#endif
- )
- {
- char lineBuf[256];
-
- /*TODO: compute the actual required buffer size instead of hardcoding */
- cbsize = 16384; // arbitrary
- rlist = PMALLOC(cbsize);
- d = rlist;
-
- // Skip the default realm
- readstring(file,lineBuf,sizeof(lineBuf));
-
- // Read the defined realms
- while (TRUE)
- {
- if (readstring(file,lineBuf,sizeof(lineBuf)) < 0)
- break;
-
- if (*(lineBuf + strlen(lineBuf) - 1) == '\r')
- *(lineBuf + strlen(lineBuf) - 1) = 0;
-
- for (p=lineBuf; *p ; p++)
- {
- if (isspace(*p)) {
- *p = 0;
- break;
- }
- }
-
- if ( strncmp(".KERBEROS.OPTION.",lineBuf,17) ) {
- t = strlen(lineBuf) + 1;
- if(cbsize > (1 + t*sizeof(wchar_t))) {
- AnsiStrToUnicode(d, cbsize, lineBuf);
- d += t;
- cbsize -= t * sizeof(wchar_t);
- } else
- break;
- }
- }
-
- *d = L'\0';
-
- fclose(file);
- }
- }
-
- return rlist;
-}
-
-/*! \internal
- \brief Get the default realm
-
- A string will be returned that specifies the default realm. The caller
- should free the string using free().
-
- Returns NULL if the operation fails.
-*/
-wchar_t * khm_krb5_get_default_realm(void)
-{
- wchar_t * realm;
- size_t cch;
- krb5_context ctx=0;
- char * def = 0;
-
- pkrb5_init_context(&ctx);
- pkrb5_get_default_realm(ctx,&def);
-
- if (def) {
- cch = strlen(def) + 1;
- realm = PMALLOC(sizeof(wchar_t) * cch);
- AnsiStrToUnicode(realm, sizeof(wchar_t) * cch, def);
- pkrb5_free_default_realm(ctx, def);
- } else
- realm = NULL;
-
- pkrb5_free_context(ctx);
-
- return realm;
-}
-
-static
-char *
-make_postfix(const char * base,
- const char * postfix,
- char ** rcopy)
-{
- size_t base_size;
- size_t ret_size;
- char * copy = 0;
- char * ret = 0;
- size_t t;
-
- if (FAILED(StringCbLengthA(base, STRSAFE_MAX_CCH * sizeof(char), &t)))
- goto cleanup;
-
- base_size = t + 1;
-
- if (FAILED(StringCbLengthA(postfix, STRSAFE_MAX_CCH * sizeof(char), &t)))
- goto cleanup;
-
- ret_size = base_size + t + 1;
-
- copy = malloc(base_size);
- ret = malloc(ret_size);
-
- if (!copy || !ret)
- goto cleanup;
-
- StringCbCopyNA(copy, base_size, base, base_size);
- StringCbCopyNA(ret, ret_size, base, base_size);
- StringCbCopyNA(ret + (base_size - 1), ret_size - (base_size - 1),
- postfix, ret_size - (base_size - 1));
-
- cleanup:
- if (!copy || !ret) {
- if (copy)
- free(copy);
- if (ret)
- free(ret);
- copy = ret = 0;
- }
- // INVARIANT: (ret ==> copy) && (copy ==> ret)
- *rcopy = copy;
- return ret;
-}
-
-void
-khm_krb4_set_def_tkt_string(void) {
- wchar_t wtkt_string[MAX_PATH];
- char tkt_string[MAX_PATH];
- khm_size cb;
-
- cb = sizeof(wtkt_string);
-
- if (KHM_FAILED(khc_read_string(csp_params, L"TktString",
- wtkt_string, &cb)) ||
- wtkt_string[0] == L'\0') {
-
- pkrb_set_tkt_string(0);
-
- } else {
-
- UnicodeStrToAnsi(tkt_string, sizeof(tkt_string),
- wtkt_string);
- pkrb_set_tkt_string(tkt_string);
- }
-}
-
-
-static
-long
-make_temp_cache_v4(const char * postfix)
-{
- static char * old_cache = 0;
-
- if (!pkrb_set_tkt_string || !ptkt_string || !pdest_tkt)
- return 0; // XXX - is this appropriate?
-
- if (old_cache) {
- pdest_tkt();
- pkrb_set_tkt_string(old_cache);
- free(old_cache);
- old_cache = 0;
- }
-
- if (postfix)
- {
- char * tmp_cache = make_postfix(ptkt_string(), postfix, &old_cache);
-
- if (!tmp_cache)
- return KFAILURE;
-
- pkrb_set_tkt_string(tmp_cache);
- free(tmp_cache);
- }
- return 0;
-}
-
-long
-khm_krb4_changepwd(char * principal,
- char * password,
- char * newpassword,
- char** error_str)
-{
- long k_errno;
-
- if (!pkrb_set_tkt_string || !ptkt_string || !pkadm_change_your_password ||
- !pdest_tkt)
- return KFAILURE;
-
- k_errno = make_temp_cache_v4("_chgpwd");
- if (k_errno) return k_errno;
- k_errno = pkadm_change_your_password(principal, password, newpassword,
- error_str);
- make_temp_cache_v4(0);
- return k_errno;
-}
-
-struct tgt_filter_data {
- khm_handle identity;
- wchar_t realm[KCDB_IDENT_MAXCCH_NAME];
-};
-
-khm_int32 KHMAPI
-krb4_tgt_filter(khm_handle cred, khm_int32 flags, void * rock) {
- struct tgt_filter_data * pdata;
- wchar_t credname[KCDB_MAXCCH_NAME];
- wchar_t * t;
- khm_size cb;
- khm_int32 ctype;
-
- pdata = (struct tgt_filter_data *) rock;
- cb = sizeof(credname);
-
- if (KHM_FAILED(kcdb_cred_get_type(cred, &ctype)) ||
- ctype != credtype_id_krb4)
- return 0;
-
- if (KHM_FAILED(kcdb_cred_get_name(cred, credname, &cb)))
- return 0;
-
- if (wcsncmp(credname, L"krbtgt.", 7))
- return 0;
-
- t = wcsrchr(credname, L'@');
- if (t == NULL)
- return 0;
-
- if (wcscmp(t+1, pdata->realm))
- return 0;
-
- return 1;
-}
-
-khm_handle
-khm_krb4_find_tgt(khm_handle credset, khm_handle identity) {
- khm_handle result = NULL;
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- wchar_t * t;
- khm_size cb;
- struct tgt_filter_data filter_data;
-
- cb = sizeof(idname);
-
- if (KHM_FAILED(kcdb_identity_get_name(identity,
- idname,
- &cb)))
- return NULL;
-
- t = wcsrchr(idname, L'@');
- if (t == NULL)
- return NULL;
-
- StringCbCopy(filter_data.realm, sizeof(filter_data.realm),
- t + 1);
- filter_data.identity = identity;
-
- if (KHM_FAILED(kcdb_credset_find_filtered(credset,
- -1,
- krb4_tgt_filter,
- &filter_data,
- &result,
- NULL)))
- return NULL;
- else
- return result;
-}
-
-long
-khm_convert524(khm_handle identity)
-{
-#ifdef NO_KRB5
- 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.
- */
-
- code = khm_krb5_initialize(identity, &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;
-
- if (ctx)
- pkrb5_free_cred_contents(ctx, &increds);
-
- if (server) {
- pkrb5_free_principal(ctx, server);
- }
-
- if (me) {
- pkrb5_free_principal(ctx, me);
- }
-
- if (ctx && cc)
- pkrb5_cc_close(ctx, cc);
-
- if (ctx) {
- pkrb5_free_context(ctx);
- }
-
- return (code || icode);
-#endif /* NO_KRB5 */
-}
-
-long
-khm_krb4_kinit(char * aname,
- char * inst,
- char * realm,
- long lifetime,
- char * password) {
-
- wchar_t * functionName = NULL;
- wchar_t * err_context = NULL;
- int rc4 = 0;
- int msg = 0;
-
- if (pkname_parse == NULL) {
- goto cleanup;
- }
-
- err_context = L"getting realm";
- if (!*realm && (rc4 = (int)(*pkrb_get_lrealm)(realm, 1))) {
- functionName = L"krb_get_lrealm()";
- msg = IDS_ERR_REALM;
- goto cleanup;
- }
-
- err_context = L"checking principal";
- if ((!*aname) || (!(rc4 = (int)(*pk_isname)(aname)))) {
- functionName = L"krb_get_lrealm()";
- msg = IDS_ERR_PRINCIPAL;
- goto cleanup;
- }
-
- /* optional instance */
- if (!(rc4 = (int)(*pk_isinst)(inst))) {
- functionName = L"k_isinst()";
- msg = IDS_ERR_INVINST;
- goto cleanup;
- }
-
- if (!(rc4 = (int)(*pk_isrealm)(realm))) {
- functionName = L"k_isrealm()";
- msg = IDS_ERR_REALM;
- goto cleanup;
- }
-
- khm_krb4_set_def_tkt_string();
-
- err_context = L"fetching ticket";
- rc4 = (*pkrb_get_pw_in_tkt)(aname, inst, realm, "krbtgt", realm,
- lifetime, password);
-
- if (rc4) /* XXX: do we want: && (rc != NO_TKT_FIL) as well? */ {
- functionName = L"krb_get_pw_in_tkt()";
- msg = IDS_ERR_PWINTKT;
- goto cleanup;
- }
-
- return 0;
-
- cleanup:
- {
- _report_sr0(KHERR_ERROR, msg);
- _location(functionName);
- }
- return rc4;
-}
-
-
-int khm_krb4_kdestroy(void) {
- int k_errno = 0;
-
- if (pdest_tkt != NULL)
- {
- k_errno = (*pdest_tkt)();
- if (k_errno && (k_errno != RET_TKFIL))
- return KRBERR(k_errno);
- }
-
- return k_errno;
-}
+/*
+* Copyright (c) 2005 Massachusetts Institute of Technology
+*
+* Permission is hereby granted, free of charge, to any person
+* obtaining a copy of this software and associated documentation
+* files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy,
+* modify, merge, publish, distribute, sublicense, and/or sell copies
+* of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*/
+
+/* $Id$ */
+
+/* Originally this was krb5routines.c in Leash sources. Subsequently
+modified and adapted for NetIDMgr */
+
+#include<krbcred.h>
+#include<kherror.h>
+
+#define SECURITY_WIN32
+#include <security.h>
+
+#include <string.h>
+#include <time.h>
+#include <assert.h>
+#include <strsafe.h>
+
+
+
+int com_addr(void)
+{
+ long ipAddr;
+ char loc_addr[ADDR_SZ];
+ CREDENTIALS cred;
+ char service[40];
+ char instance[40];
+ // char addr[40];
+ char realm[40];
+ struct in_addr LocAddr;
+ int k_errno;
+
+ if (pkrb_get_cred == NULL)
+ return(KSUCCESS);
+
+ k_errno = (*pkrb_get_cred)(service,instance,realm,&cred);
+ if (k_errno)
+ return KRBERR(k_errno);
+
+ while(1) {
+ ipAddr = (*pLocalHostAddr)();
+ LocAddr.s_addr = ipAddr;
+ StringCbCopyA(loc_addr, sizeof(loc_addr), inet_ntoa(LocAddr));
+ if ( strcmp(cred.address,loc_addr) != 0) {
+ /* TODO: do something about this */
+ //Leash_kdestroy ();
+ break;
+ }
+ break;
+ } // while()
+ return 0;
+}
+
+
+long
+khm_krb4_list_tickets(void)
+{
+ char ptktname[MAX_PATH + 5];
+ char pname[ANAME_SZ];
+ char pinst[INST_SZ];
+ char prealm[REALM_SZ];
+ wchar_t wbuf[256];
+ int k_errno = 0;
+ CREDENTIALS c;
+ int newtickets = 0;
+ int open = 0;
+ khm_handle ident = NULL;
+ khm_handle cred = NULL;
+ time_t tt;
+ FILETIME ft;
+
+ kcdb_credset_flush(krb4_credset);
+
+ // Since krb_get_tf_realm will return a ticket_file error,
+ // we will call tf_init and tf_close first to filter out
+ // things like no ticket file. Otherwise, the error that
+ // the user would see would be
+ // klist: can't find realm of ticket file: No ticket file (tf_util)
+ // instead of klist: No ticket file (tf_util)
+ if (ptf_init == NULL)
+ goto collect;
+
+ com_addr();
+
+ // Open ticket file
+ if ((k_errno = (*ptf_init)((*ptkt_string)(), R_TKT_FIL)))
+ {
+ goto cleanup;
+ }
+ // Close ticket file
+ (void) (*ptf_close)();
+
+ // We must find the realm of the ticket file here before calling
+ // tf_init because since the realm of the ticket file is not
+ // really stored in the principal section of the file, the
+ // routine we use must itself call tf_init and tf_close.
+
+ if ((k_errno = (*pkrb_get_tf_realm)((*ptkt_string)(), prealm)) != KSUCCESS)
+ {
+ goto cleanup;
+ }
+
+ // Open ticket file
+ if (k_errno = (*ptf_init)((*ptkt_string)(), R_TKT_FIL))
+ {
+ goto cleanup;
+ }
+
+ StringCchCopyA(ptktname, ARRAYLENGTH(ptktname), (*ptkt_string)());
+
+ open = 1;
+
+ // Get principal name and instance
+ if ((k_errno = (*ptf_get_pname)(pname)) || (k_errno = (*ptf_get_pinst)(pinst)))
+ {
+ goto cleanup;
+ }
+
+ // You may think that this is the obvious place to get the
+ // realm of the ticket file, but it can't be done here as the
+ // routine to do this must open the ticket file. This is why
+ // it was done before tf_init.
+ StringCbPrintf(wbuf, sizeof(wbuf), L"%S%S%S%S%S", (LPSTR)pname,
+ (LPSTR)(pinst[0] ? "." : ""), (LPSTR)pinst,
+ (LPSTR)(prealm[0] ? "@" : ""), (LPSTR)prealm);
+
+ if(KHM_FAILED(kcdb_identity_create(wbuf, KCDB_IDENT_FLAG_CREATE, &ident)))
+ {
+ goto cleanup;
+ }
+
+ // Get KRB4 tickets
+ while ((k_errno = (*ptf_get_cred)(&c)) == KSUCCESS)
+ {
+ StringCbPrintf(wbuf, sizeof(wbuf), L"%S%S%S%S%S",
+ c.service,
+ (c.instance[0] ? "." : ""),
+ c.instance,
+ (c.realm[0] ? "@" : ""),
+ c.realm);
+
+ if(KHM_FAILED(kcdb_cred_create(wbuf, ident, credtype_id_krb4, &cred)))
+ continue;
+
+ tt = c.issue_date + c.lifetime * 5L * 60L;
+ TimetToFileTime(tt, &ft);
+ kcdb_cred_set_attr(cred, KCDB_ATTR_EXPIRE, &ft, sizeof(ft));
+
+ tt = c.issue_date;
+ TimetToFileTime(tt, &ft);
+ kcdb_cred_set_attr(cred, KCDB_ATTR_ISSUE, &ft, sizeof(ft));
+
+ tt = c.lifetime * 5L * 60L;
+ TimetToFileTimeInterval(tt, &ft);
+ kcdb_cred_set_attr(cred, KCDB_ATTR_LIFETIME, &ft, sizeof(ft));
+
+ AnsiStrToUnicode(wbuf, sizeof(wbuf), ptktname);
+ kcdb_cred_set_attr(cred, KCDB_ATTR_LOCATION, wbuf, KCDB_CBSIZE_AUTO);
+
+ kcdb_credset_add_cred(krb4_credset, cred, -1);
+
+ kcdb_cred_release(cred);
+ } // while
+
+ cleanup:
+ if (ptf_close == NULL)
+ return(KSUCCESS);
+
+ if (open)
+ (*ptf_close)(); //close ticket file
+
+ if (k_errno == EOF)
+ k_errno = 0;
+
+ // XXX the if statement directly below was inserted to eliminate
+ // an error NO_TKT_FIL on Leash startup. The error occurs from an
+ // error number thrown from krb_get_tf_realm. We believe this
+ // change does not eliminate other errors, but it may.
+
+ if (k_errno == NO_TKT_FIL)
+ k_errno = 0;
+
+ if(ident)
+ kcdb_identity_release(ident);
+
+#if 0
+ /*TODO: Handle errors here */
+ if (k_errno)
+ {
+ CHAR message[256];
+ CHAR errBuf[256];
+ LPCSTR errText;
+
+ if (!Lerror_message)
+ return -1;
+
+ errText = err_describe(errBuf, KRBERR(k_errno));
+
+ sprintf(message, "%s\n\n%s failed", errText, functionName);
+ MessageBox(NULL, message, "Kerberos Four",
+ MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND);
+ }
+#endif
+
+ collect:
+ kcdb_credset_collect(NULL, krb4_credset, ident, credtype_id_krb4, NULL);
+
+ return k_errno;
+}
+
+#define KRB_FILE "KRB.CON"
+#define KRBREALM_FILE "KRBREALM.CON"
+#define KRB5_FILE "KRB5.INI"
+
+BOOL
+khm_krb5_get_profile_file(LPSTR confname, UINT szConfname)
+{
+ char **configFile = NULL;
+ if (pkrb5_get_default_config_files(&configFile))
+ {
+ GetWindowsDirectoryA(confname,szConfname);
+ confname[szConfname-1] = '\0';
+
+ StringCchCatA(confname, szConfname, "\\");
+ StringCchCatA(confname, szConfname, KRB5_FILE);
+
+ return FALSE;
+ }
+
+ *confname = 0;
+
+ if (configFile)
+ {
+ StringCchCopyA(confname, szConfname, *configFile);
+ pkrb5_free_config_files(configFile);
+ }
+
+ if (!*confname)
+ {
+ GetWindowsDirectoryA(confname,szConfname);
+ confname[szConfname-1] = '\0';
+
+ StringCchCatA(confname, szConfname, "\\");
+ StringCchCatA(confname, szConfname, KRB5_FILE);
+ }
+
+ return FALSE;
+}
+
+BOOL
+khm_get_krb4_con_file(LPSTR confname, UINT szConfname)
+{
+ if (hKrb5 && !hKrb4) {
+ // hold krb.con where krb5.ini is located
+ CHAR krbConFile[MAX_PATH]="";
+ LPSTR pFind;
+
+ if (khm_krb5_get_profile_file(krbConFile, sizeof(krbConFile))) {
+ GetWindowsDirectoryA(krbConFile,sizeof(krbConFile));
+ krbConFile[MAX_PATH-1] = '\0';
+
+ StringCbCatA(krbConFile, sizeof(krbConFile), "\\");
+ }
+
+ pFind = strrchr(krbConFile, '\\');
+
+ if (pFind) {
+ *pFind = '\0';
+
+ StringCbCatA(krbConFile, sizeof(krbConFile), "\\");
+ StringCbCatA(krbConFile, sizeof(krbConFile), KRB_FILE);
+ } else {
+ krbConFile[0] = '\0';
+ }
+
+ StringCchCopyA(confname, szConfname, krbConFile);
+ } else if (hKrb4) {
+ unsigned int size = szConfname;
+ memset(confname, '\0', szConfname);
+ if (!pkrb_get_krbconf2(confname, &size)) {
+ GetWindowsDirectoryA(confname,szConfname);
+ confname[szConfname-1] = '\0';
+ StringCchCatA(confname, szConfname, "\\");
+ StringCchCatA(confname, szConfname, KRB_FILE);
+ }
+ }
+
+ return FALSE;
+}
+
+int
+readstring(FILE * file, char * buf, int len)
+{
+ int c,i;
+ memset(buf, '\0', sizeof(buf));
+ for (i=0, c=fgetc(file); c != EOF ; c=fgetc(file), i++)
+ {
+ if (i < sizeof(buf)) {
+ if (c == '\n') {
+ buf[i] = '\0';
+ return i;
+ } else {
+ buf[i] = c;
+ }
+ } else {
+ if (c == '\n') {
+ buf[len-1] = '\0';
+ return(i);
+ }
+ }
+ }
+ if (c == EOF) {
+ if (i > 0 && i < len) {
+ buf[i] = '\0';
+ return(i);
+ } else {
+ buf[len-1] = '\0';
+ return(-1);
+ }
+ }
+ return(-1);
+}
+
+/*! \internal
+ \brief Return a list of configured realms
+
+ The string that is returned is a set of null terminated unicode strings,
+ each of which denotes one realm. The set is terminated by a zero length
+ null terminated string.
+
+ The caller should free the returned string using free()
+
+ \return The string with the list of realms or NULL if the operation fails.
+*/
+wchar_t * khm_krb5_get_realm_list(void)
+{
+ wchar_t * rlist = NULL;
+
+ if (pprofile_get_subsection_names && pprofile_free_list) {
+ const char* rootSection[] = {"realms", NULL};
+ const char** rootsec = rootSection;
+ char **sections = NULL, **cpp = NULL, *value = NULL;
+
+ char krb5_conf[MAX_PATH+1];
+
+ if (!khm_krb5_get_profile_file(krb5_conf,sizeof(krb5_conf))) {
+ profile_t profile;
+ long retval;
+ const char *filenames[2];
+ wchar_t * d;
+ size_t cbsize;
+ size_t t;
+
+ filenames[0] = krb5_conf;
+ filenames[1] = NULL;
+ retval = pprofile_init(filenames, &profile);
+ if (!retval) {
+ retval = pprofile_get_subsection_names(profile, rootsec, &sections);
+
+ if (!retval)
+ {
+ /* first figure out how much space to allocate */
+ cbsize = 0;
+ for (cpp = sections; *cpp; cpp++)
+ {
+ cbsize += sizeof(wchar_t) * (strlen(*cpp) + 1);
+ }
+ cbsize += sizeof(wchar_t); /* double null terminated */
+
+ rlist = PMALLOC(cbsize);
+ d = rlist;
+ for (cpp = sections; *cpp; cpp++)
+ {
+ AnsiStrToUnicode(d, cbsize, *cpp);
+ t = wcslen(d) + 1;
+ d += t;
+ cbsize -= sizeof(wchar_t) * t;
+ }
+ *d = L'\0';
+ }
+
+ pprofile_free_list(sections);
+
+#if 0
+ retval = pprofile_get_string(profile, "libdefaults","noaddresses", 0, "true", &value);
+ if ( value ) {
+ disable_noaddresses = config_boolean_to_int(value);
+ pprofile_release_string(value);
+ }
+#endif
+ pprofile_release(profile);
+ }
+ }
+ } else {
+ FILE * file;
+ char krb_conf[MAX_PATH+1];
+ char * p;
+ size_t cbsize, t;
+ wchar_t * d;
+
+ if (!khm_get_krb4_con_file(krb_conf,sizeof(krb_conf)) &&
+#if _MSC_VER >= 1400
+ !fopen_s(&file, krb_conf, "rt")
+#else
+ (file = fopen(krb_conf, "rt"))
+#endif
+ )
+ {
+ char lineBuf[256];
+
+ /*TODO: compute the actual required buffer size instead of hardcoding */
+ cbsize = 16384; // arbitrary
+ rlist = PMALLOC(cbsize);
+ d = rlist;
+
+ // Skip the default realm
+ readstring(file,lineBuf,sizeof(lineBuf));
+
+ // Read the defined realms
+ while (TRUE)
+ {
+ if (readstring(file,lineBuf,sizeof(lineBuf)) < 0)
+ break;
+
+ if (*(lineBuf + strlen(lineBuf) - 1) == '\r')
+ *(lineBuf + strlen(lineBuf) - 1) = 0;
+
+ for (p=lineBuf; *p ; p++)
+ {
+ if (isspace(*p)) {
+ *p = 0;
+ break;
+ }
+ }
+
+ if ( strncmp(".KERBEROS.OPTION.",lineBuf,17) ) {
+ t = strlen(lineBuf) + 1;
+ if(cbsize > (1 + t*sizeof(wchar_t))) {
+ AnsiStrToUnicode(d, cbsize, lineBuf);
+ d += t;
+ cbsize -= t * sizeof(wchar_t);
+ } else
+ break;
+ }
+ }
+
+ *d = L'\0';
+
+ fclose(file);
+ }
+ }
+
+ return rlist;
+}
+
+/*! \internal
+ \brief Get the default realm
+
+ A string will be returned that specifies the default realm. The caller
+ should free the string using free().
+
+ Returns NULL if the operation fails.
+*/
+wchar_t * khm_krb5_get_default_realm(void)
+{
+ wchar_t * realm;
+ size_t cch;
+ krb5_context ctx=0;
+ char * def = 0;
+
+ pkrb5_init_context(&ctx);
+ pkrb5_get_default_realm(ctx,&def);
+
+ if (def) {
+ cch = strlen(def) + 1;
+ realm = PMALLOC(sizeof(wchar_t) * cch);
+ AnsiStrToUnicode(realm, sizeof(wchar_t) * cch, def);
+ pkrb5_free_default_realm(ctx, def);
+ } else
+ realm = NULL;
+
+ pkrb5_free_context(ctx);
+
+ return realm;
+}
+
+static
+char *
+make_postfix(const char * base,
+ const char * postfix,
+ char ** rcopy)
+{
+ size_t base_size;
+ size_t ret_size;
+ char * copy = 0;
+ char * ret = 0;
+ size_t t;
+
+ if (FAILED(StringCbLengthA(base, STRSAFE_MAX_CCH * sizeof(char), &t)))
+ goto cleanup;
+
+ base_size = t + 1;
+
+ if (FAILED(StringCbLengthA(postfix, STRSAFE_MAX_CCH * sizeof(char), &t)))
+ goto cleanup;
+
+ ret_size = base_size + t + 1;
+
+ copy = malloc(base_size);
+ ret = malloc(ret_size);
+
+ if (!copy || !ret)
+ goto cleanup;
+
+ StringCbCopyNA(copy, base_size, base, base_size);
+ StringCbCopyNA(ret, ret_size, base, base_size);
+ StringCbCopyNA(ret + (base_size - 1), ret_size - (base_size - 1),
+ postfix, ret_size - (base_size - 1));
+
+ cleanup:
+ if (!copy || !ret) {
+ if (copy)
+ free(copy);
+ if (ret)
+ free(ret);
+ copy = ret = 0;
+ }
+ // INVARIANT: (ret ==> copy) && (copy ==> ret)
+ *rcopy = copy;
+ return ret;
+}
+
+void
+khm_krb4_set_def_tkt_string(void) {
+ wchar_t wtkt_string[MAX_PATH];
+ char tkt_string[MAX_PATH];
+ khm_size cb;
+
+ cb = sizeof(wtkt_string);
+
+ if (KHM_FAILED(khc_read_string(csp_params, L"TktString",
+ wtkt_string, &cb)) ||
+ wtkt_string[0] == L'\0') {
+
+ pkrb_set_tkt_string(0);
+
+ } else {
+
+ UnicodeStrToAnsi(tkt_string, sizeof(tkt_string),
+ wtkt_string);
+ pkrb_set_tkt_string(tkt_string);
+ }
+}
+
+
+static
+long
+make_temp_cache_v4(const char * postfix)
+{
+ static char * old_cache = 0;
+
+ if (!pkrb_set_tkt_string || !ptkt_string || !pdest_tkt)
+ return 0; // XXX - is this appropriate?
+
+ if (old_cache) {
+ pdest_tkt();
+ pkrb_set_tkt_string(old_cache);
+ free(old_cache);
+ old_cache = 0;
+ }
+
+ if (postfix)
+ {
+ char * tmp_cache = make_postfix(ptkt_string(), postfix, &old_cache);
+
+ if (!tmp_cache)
+ return KFAILURE;
+
+ pkrb_set_tkt_string(tmp_cache);
+ free(tmp_cache);
+ }
+ return 0;
+}
+
+long
+khm_krb4_changepwd(char * principal,
+ char * password,
+ char * newpassword,
+ char** error_str)
+{
+ long k_errno;
+
+ if (!pkrb_set_tkt_string || !ptkt_string || !pkadm_change_your_password ||
+ !pdest_tkt)
+ return KFAILURE;
+
+ k_errno = make_temp_cache_v4("_chgpwd");
+ if (k_errno) return k_errno;
+ k_errno = pkadm_change_your_password(principal, password, newpassword,
+ error_str);
+ make_temp_cache_v4(0);
+ return k_errno;
+}
+
+struct tgt_filter_data {
+ khm_handle identity;
+ wchar_t realm[KCDB_IDENT_MAXCCH_NAME];
+};
+
+khm_int32 KHMAPI
+krb4_tgt_filter(khm_handle cred, khm_int32 flags, void * rock) {
+ struct tgt_filter_data * pdata;
+ wchar_t credname[KCDB_MAXCCH_NAME];
+ wchar_t * t;
+ khm_size cb;
+ khm_int32 ctype;
+
+ pdata = (struct tgt_filter_data *) rock;
+ cb = sizeof(credname);
+
+ if (KHM_FAILED(kcdb_cred_get_type(cred, &ctype)) ||
+ ctype != credtype_id_krb4)
+ return 0;
+
+ if (KHM_FAILED(kcdb_cred_get_name(cred, credname, &cb)))
+ return 0;
+
+ if (wcsncmp(credname, L"krbtgt.", 7))
+ return 0;
+
+ t = wcsrchr(credname, L'@');
+ if (t == NULL)
+ return 0;
+
+ if (wcscmp(t+1, pdata->realm))
+ return 0;
+
+ return 1;
+}
+
+khm_handle
+khm_krb4_find_tgt(khm_handle credset, khm_handle identity) {
+ khm_handle result = NULL;
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t * t;
+ khm_size cb;
+ struct tgt_filter_data filter_data;
+
+ cb = sizeof(idname);
+
+ if (KHM_FAILED(kcdb_identity_get_name(identity,
+ idname,
+ &cb)))
+ return NULL;
+
+ t = wcsrchr(idname, L'@');
+ if (t == NULL)
+ return NULL;
+
+ StringCbCopy(filter_data.realm, sizeof(filter_data.realm),
+ t + 1);
+ filter_data.identity = identity;
+
+ if (KHM_FAILED(kcdb_credset_find_filtered(credset,
+ -1,
+ krb4_tgt_filter,
+ &filter_data,
+ &result,
+ NULL)))
+ return NULL;
+ else
+ return result;
+}
+
+long
+khm_convert524(khm_handle identity)
+{
+#ifdef NO_KRB5
+ 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.
+ */
+
+ code = khm_krb5_initialize(identity, &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;
+
+ if (ctx)
+ pkrb5_free_cred_contents(ctx, &increds);
+
+ if (server) {
+ pkrb5_free_principal(ctx, server);
+ }
+
+ if (me) {
+ pkrb5_free_principal(ctx, me);
+ }
+
+ if (ctx && cc)
+ pkrb5_cc_close(ctx, cc);
+
+ if (ctx) {
+ pkrb5_free_context(ctx);
+ }
+
+ return (code || icode);
+#endif /* NO_KRB5 */
+}
+
+long
+khm_krb4_kinit(char * aname,
+ char * inst,
+ char * realm,
+ long lifetime,
+ char * password) {
+
+ wchar_t * functionName = NULL;
+ wchar_t * err_context = NULL;
+ int rc4 = 0;
+ int msg = 0;
+
+ if (pkname_parse == NULL) {
+ goto cleanup;
+ }
+
+ err_context = L"getting realm";
+ if (!*realm && (rc4 = (int)(*pkrb_get_lrealm)(realm, 1))) {
+ functionName = L"krb_get_lrealm()";
+ msg = IDS_ERR_REALM;
+ goto cleanup;
+ }
+
+ err_context = L"checking principal";
+ if ((!*aname) || (!(rc4 = (int)(*pk_isname)(aname)))) {
+ functionName = L"krb_get_lrealm()";
+ msg = IDS_ERR_PRINCIPAL;
+ goto cleanup;
+ }
+
+ /* optional instance */
+ if (!(rc4 = (int)(*pk_isinst)(inst))) {
+ functionName = L"k_isinst()";
+ msg = IDS_ERR_INVINST;
+ goto cleanup;
+ }
+
+ if (!(rc4 = (int)(*pk_isrealm)(realm))) {
+ functionName = L"k_isrealm()";
+ msg = IDS_ERR_REALM;
+ goto cleanup;
+ }
+
+ khm_krb4_set_def_tkt_string();
+
+ err_context = L"fetching ticket";
+ rc4 = (*pkrb_get_pw_in_tkt)(aname, inst, realm, "krbtgt", realm,
+ lifetime, password);
+
+ if (rc4) /* XXX: do we want: && (rc != NO_TKT_FIL) as well? */ {
+ functionName = L"krb_get_pw_in_tkt()";
+ msg = IDS_ERR_PWINTKT;
+ goto cleanup;
+ }
+
+ return 0;
+
+ cleanup:
+ {
+ _report_sr0(KHERR_ERROR, msg);
+ _location(functionName);
+ }
+ return rc4;
+}
+
+
+int khm_krb4_kdestroy(void) {
+ int k_errno = 0;
+
+ if (pdest_tkt != NULL)
+ {
+ k_errno = (*pdest_tkt)();
+ if (k_errno && (k_errno != RET_TKFIL))
+ return KRBERR(k_errno);
+ }
+
+ return k_errno;
+}
diff --git a/src/windows/identity/plugins/krb4/krb4funcs.h b/src/windows/identity/plugins/krb4/krb4funcs.h
index 5ec11cc63..05ed3e75d 100644
--- a/src/windows/identity/plugins/krb4/krb4funcs.h
+++ b/src/windows/identity/plugins/krb4/krb4funcs.h
@@ -1,132 +1,132 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Adapted from multiple Leash header files */
-
-#ifndef __KHIMAIRA_KRB5FUNCS_H
-#define __KHIMAIRA_KRB5FUNCS_H
-
-#include<stdlib.h>
-#include<krb5.h>
-
-#include <windows.h>
-#define SECURITY_WIN32
-#include <security.h>
-
-#if _WIN32_WINNT < 0x0501
-#define KHM_SAVE_WIN32_WINNT _WIN32_WINNT
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-#include<ntsecapi.h>
-#ifdef KHM_SAVE_WIN32_WINNT
-#undef _WIN32_WINNT
-#define _WIN32_WINNT KHM_SAVE_WIN32_WINNT
-#undef KHM_SAVE_WIN32_WINNT
-#endif
-
-#include <krb5common.h>
-
-#define LEASH_DEBUG_CLASS_GENERIC 0
-#define LEASH_DEBUG_CLASS_KRB4 1
-#define LEASH_DEBUG_CLASS_KRB4_APP 2
-
-#define LEASH_PRIORITY_LOW 0
-#define LEASH_PRIORITY_HIGH 1
-
-#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
-
-
-long
-khm_convert524(khm_handle identity);
-
-long
-khm_krb4_kinit(char * aname,
- char * inst,
- char * realm,
- long lifetime,
- char * password);
-
-long
-khm_krb4_list_tickets(void);
-
-int khm_krb4_kdestroy(void);
-
-khm_handle
-khm_krb4_find_tgt(khm_handle credset,
- khm_handle identity);
-
-LONG
-write_registry_setting(
- char* setting,
- DWORD type,
- void* buffer,
- size_t size
- );
-
-LONG
-read_registry_setting_user(
- char* setting,
- void* buffer,
- size_t size
- );
-
-LONG
-read_registry_setting(
- char* setting,
- void* buffer,
- size_t size
- );
-
-BOOL
-get_STRING_from_registry(
- HKEY hBaseKey,
- char * key,
- char * value,
- char * outbuf,
- DWORD outlen
- );
-
-BOOL
-get_DWORD_from_registry(
- HKEY hBaseKey,
- char * key,
- char * value,
- DWORD * result
- );
-
-int
-config_boolean_to_int(
- const char *s
- );
-
-void
-khm_krb4_set_def_tkt_string(void);
-
-wchar_t * khm_krb5_get_default_realm(void);
-wchar_t * khm_krb5_get_realm_list(void);
-
-#endif
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+/* Adapted from multiple Leash header files */
+
+#ifndef __KHIMAIRA_KRB5FUNCS_H
+#define __KHIMAIRA_KRB5FUNCS_H
+
+#include<stdlib.h>
+#include<krb5.h>
+
+#include <windows.h>
+#define SECURITY_WIN32
+#include <security.h>
+
+#if _WIN32_WINNT < 0x0501
+#define KHM_SAVE_WIN32_WINNT _WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
+#include<ntsecapi.h>
+#ifdef KHM_SAVE_WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT KHM_SAVE_WIN32_WINNT
+#undef KHM_SAVE_WIN32_WINNT
+#endif
+
+#include <krb5common.h>
+
+#define LEASH_DEBUG_CLASS_GENERIC 0
+#define LEASH_DEBUG_CLASS_KRB4 1
+#define LEASH_DEBUG_CLASS_KRB4_APP 2
+
+#define LEASH_PRIORITY_LOW 0
+#define LEASH_PRIORITY_HIGH 1
+
+#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
+
+
+long
+khm_convert524(khm_handle identity);
+
+long
+khm_krb4_kinit(char * aname,
+ char * inst,
+ char * realm,
+ long lifetime,
+ char * password);
+
+long
+khm_krb4_list_tickets(void);
+
+int khm_krb4_kdestroy(void);
+
+khm_handle
+khm_krb4_find_tgt(khm_handle credset,
+ khm_handle identity);
+
+LONG
+write_registry_setting(
+ char* setting,
+ DWORD type,
+ void* buffer,
+ size_t size
+ );
+
+LONG
+read_registry_setting_user(
+ char* setting,
+ void* buffer,
+ size_t size
+ );
+
+LONG
+read_registry_setting(
+ char* setting,
+ void* buffer,
+ size_t size
+ );
+
+BOOL
+get_STRING_from_registry(
+ HKEY hBaseKey,
+ char * key,
+ char * value,
+ char * outbuf,
+ DWORD outlen
+ );
+
+BOOL
+get_DWORD_from_registry(
+ HKEY hBaseKey,
+ char * key,
+ char * value,
+ DWORD * result
+ );
+
+int
+config_boolean_to_int(
+ const char *s
+ );
+
+void
+khm_krb4_set_def_tkt_string(void);
+
+wchar_t * khm_krb5_get_default_realm(void);
+wchar_t * khm_krb5_get_realm_list(void);
+
+#endif
diff --git a/src/windows/identity/plugins/krb4/krb4main.c b/src/windows/identity/plugins/krb4/krb4main.c
index 57e33a8d8..7ab2d71f3 100644
--- a/src/windows/identity/plugins/krb4/krb4main.c
+++ b/src/windows/identity/plugins/krb4/krb4main.c
@@ -1,157 +1,157 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<kherror.h>
-
-kmm_module h_khModule; /* KMM's handle to this module */
-HINSTANCE hInstance;
-HMODULE hResModule; /* HMODULE to the resource library */
-
-khm_int32 type_id_enctype = -1;
-khm_int32 type_id_addr_list = -1;
-khm_int32 type_id_krb5_flags = -1;
-
-khm_int32 attr_id_key_enctype = -1;
-khm_int32 attr_id_tkt_enctype = -1;
-khm_int32 attr_id_addr_list = -1;
-khm_int32 attr_id_krb5_flags = -1;
-
-khm_handle csp_plugins = NULL;
-khm_handle csp_krbcred = NULL;
-khm_handle csp_params = NULL;
-
-kmm_module_locale locales[] = {
- LOCALE_DEF(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US), L"krb4cred_en_us.dll", KMM_MLOC_FLAG_DEFAULT)
-};
-
-int n_locales = ARRAYLENGTH(locales);
-
-/* These two probably should not do anything */
-void init_krb() {
-}
-
-void exit_krb() {
-}
-
-/* called by the NetIDMgr module manager */
-KHMEXP khm_int32 KHMAPI init_module(kmm_module h_module) {
- khm_int32 rv = KHM_ERROR_SUCCESS;
- kmm_plugin_reg pi;
- wchar_t buf[256];
-
- h_khModule = h_module;
-
- rv = kmm_set_locale_info(h_module, locales, n_locales);
- if(KHM_SUCCEEDED(rv)) {
- hResModule = kmm_get_resource_hmodule(h_module);
- } else
- goto _exit;
-
- ZeroMemory(&pi, sizeof(pi));
- pi.name = KRB4_PLUGIN_NAME;
- pi.type = KHM_PITYPE_CRED;
- pi.icon = LoadImage(hResModule, MAKEINTRESOURCE(IDI_PLUGIN),
- IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
- pi.flags = 0;
- pi.msg_proc = krb4_cb;
- pi.dependencies = KRB4_PLUGIN_DEPS;
- pi.description = buf;
- LoadString(hResModule, IDS_PLUGIN_DESC,
- buf, ARRAYLENGTH(buf));
- kmm_provide_plugin(h_module, &pi);
-
- if(KHM_FAILED(rv = init_imports()))
- goto _exit;
-
- if(KHM_FAILED(rv = init_error_funcs()))
- goto _exit;
-
- rv = kmm_get_plugins_config(0, &csp_plugins);
- if(KHM_FAILED(rv)) goto _exit;
-
- rv = khc_load_schema(csp_plugins, schema_krbconfig);
- if(KHM_FAILED(rv)) goto _exit;
-
- rv = khc_open_space(csp_plugins, CSNAME_KRB4CRED, 0, &csp_krbcred);
- if(KHM_FAILED(rv)) goto _exit;
-
- rv = khc_open_space(csp_krbcred, CSNAME_PARAMS, 0, &csp_params);
- if(KHM_FAILED(rv)) goto _exit;
-
- _exit:
- return rv;
-}
-
-/* called by the NetIDMgr module manager */
-KHMEXP khm_int32 KHMAPI exit_module(kmm_module h_module) {
- exit_imports();
- exit_error_funcs();
-
- if(csp_params) {
- khc_close_space(csp_params);
- csp_params = NULL;
- }
-
- if(csp_krbcred) {
- khc_close_space(csp_krbcred);
- csp_krbcred = NULL;
- }
-
- if(csp_plugins) {
- khc_unload_schema(csp_plugins, schema_krbconfig);
- khc_close_space(csp_plugins);
- csp_plugins = NULL;
- }
-
- return KHM_ERROR_SUCCESS; /* the return code is ignored */
-}
-
-BOOL WINAPI DllMain(
- HINSTANCE hinstDLL,
- DWORD fdwReason,
- LPVOID lpvReserved
-)
-{
- switch(fdwReason) {
- case DLL_PROCESS_ATTACH:
- hInstance = hinstDLL;
- init_krb();
- break;
-
- case DLL_PROCESS_DETACH:
- exit_krb();
- break;
-
- case DLL_THREAD_ATTACH:
- break;
-
- case DLL_THREAD_DETACH:
- break;
- }
-
- return TRUE;
-}
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<kherror.h>
+
+kmm_module h_khModule; /* KMM's handle to this module */
+HINSTANCE hInstance;
+HMODULE hResModule; /* HMODULE to the resource library */
+
+khm_int32 type_id_enctype = -1;
+khm_int32 type_id_addr_list = -1;
+khm_int32 type_id_krb5_flags = -1;
+
+khm_int32 attr_id_key_enctype = -1;
+khm_int32 attr_id_tkt_enctype = -1;
+khm_int32 attr_id_addr_list = -1;
+khm_int32 attr_id_krb5_flags = -1;
+
+khm_handle csp_plugins = NULL;
+khm_handle csp_krbcred = NULL;
+khm_handle csp_params = NULL;
+
+kmm_module_locale locales[] = {
+ LOCALE_DEF(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US), L"krb4cred_en_us.dll", KMM_MLOC_FLAG_DEFAULT)
+};
+
+int n_locales = ARRAYLENGTH(locales);
+
+/* These two probably should not do anything */
+void init_krb() {
+}
+
+void exit_krb() {
+}
+
+/* called by the NetIDMgr module manager */
+KHMEXP khm_int32 KHMAPI init_module(kmm_module h_module) {
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+ kmm_plugin_reg pi;
+ wchar_t buf[256];
+
+ h_khModule = h_module;
+
+ rv = kmm_set_locale_info(h_module, locales, n_locales);
+ if(KHM_SUCCEEDED(rv)) {
+ hResModule = kmm_get_resource_hmodule(h_module);
+ } else
+ goto _exit;
+
+ ZeroMemory(&pi, sizeof(pi));
+ pi.name = KRB4_PLUGIN_NAME;
+ pi.type = KHM_PITYPE_CRED;
+ pi.icon = LoadImage(hResModule, MAKEINTRESOURCE(IDI_PLUGIN),
+ IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
+ pi.flags = 0;
+ pi.msg_proc = krb4_cb;
+ pi.dependencies = KRB4_PLUGIN_DEPS;
+ pi.description = buf;
+ LoadString(hResModule, IDS_PLUGIN_DESC,
+ buf, ARRAYLENGTH(buf));
+ kmm_provide_plugin(h_module, &pi);
+
+ if(KHM_FAILED(rv = init_imports()))
+ goto _exit;
+
+ if(KHM_FAILED(rv = init_error_funcs()))
+ goto _exit;
+
+ rv = kmm_get_plugins_config(0, &csp_plugins);
+ if(KHM_FAILED(rv)) goto _exit;
+
+ rv = khc_load_schema(csp_plugins, schema_krbconfig);
+ if(KHM_FAILED(rv)) goto _exit;
+
+ rv = khc_open_space(csp_plugins, CSNAME_KRB4CRED, 0, &csp_krbcred);
+ if(KHM_FAILED(rv)) goto _exit;
+
+ rv = khc_open_space(csp_krbcred, CSNAME_PARAMS, 0, &csp_params);
+ if(KHM_FAILED(rv)) goto _exit;
+
+ _exit:
+ return rv;
+}
+
+/* called by the NetIDMgr module manager */
+KHMEXP khm_int32 KHMAPI exit_module(kmm_module h_module) {
+ exit_imports();
+ exit_error_funcs();
+
+ if(csp_params) {
+ khc_close_space(csp_params);
+ csp_params = NULL;
+ }
+
+ if(csp_krbcred) {
+ khc_close_space(csp_krbcred);
+ csp_krbcred = NULL;
+ }
+
+ if(csp_plugins) {
+ khc_unload_schema(csp_plugins, schema_krbconfig);
+ khc_close_space(csp_plugins);
+ csp_plugins = NULL;
+ }
+
+ return KHM_ERROR_SUCCESS; /* the return code is ignored */
+}
+
+BOOL WINAPI DllMain(
+ HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved
+)
+{
+ switch(fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ hInstance = hinstDLL;
+ init_krb();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ exit_krb();
+ break;
+
+ case DLL_THREAD_ATTACH:
+ break;
+
+ case DLL_THREAD_DETACH:
+ break;
+ }
+
+ return TRUE;
+}
diff --git a/src/windows/identity/plugins/krb4/krb4newcreds.c b/src/windows/identity/plugins/krb4/krb4newcreds.c
index 54feae5b3..c2d477e0e 100644
--- a/src/windows/identity/plugins/krb4/krb4newcreds.c
+++ b/src/windows/identity/plugins/krb4/krb4newcreds.c
@@ -1,873 +1,873 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<kherror.h>
-#include<khmsgtypes.h>
-#include<khuidefs.h>
-#include<utils.h>
-#include<commctrl.h>
-#include<strsafe.h>
-#include<krb5.h>
-#include<assert.h>
-
-/* method identifiers should be contiguous */
-#define K4_METHOD_AUTO 0
-#define K4_METHOD_PASSWORD 1
-#define K4_METHOD_K524 2
-
-int method_to_id[] = {
- IDC_NCK4_AUTO,
- IDC_NCK4_PWD,
- IDC_NCK4_K524
-};
-
-typedef struct tag_k4_dlg_data {
- HWND hwnd;
- khui_new_creds * nc;
- khui_new_creds_by_type * nct;
-
- khm_boolean k4_enabled;
- khm_int32 method;
- time_t lifetime;
-} k4_dlg_data;
-
-void k4_update_display(k4_dlg_data * d, BOOL update_methods) {
- CheckDlgButton(d->hwnd, IDC_NCK4_OBTAIN,
- (d->k4_enabled)?BST_CHECKED: BST_UNCHECKED);
-
- if (d->k4_enabled) {
- EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_AUTO), TRUE);
- EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_K524), TRUE);
- EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_PWD ), TRUE);
- } else {
- EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_AUTO), FALSE);
- EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_K524), FALSE);
- EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_PWD ), FALSE);
- }
-
-#ifdef DEBUG
- assert(d->method >= 0 && d->method < ARRAYLENGTH(method_to_id));
-#endif
-
- CheckRadioButton(d->hwnd, IDC_NCK4_AUTO, IDC_NCK4_PWD, method_to_id[d->method]);
-
- khui_cw_enable_type(d->nc, credtype_id_krb4, d->k4_enabled);
-}
-
-void k4_update_data(k4_dlg_data * d) {
- int i;
- khm_boolean oldstate;
-
- oldstate = d->k4_enabled;
-
- if (IsDlgButtonChecked(d->hwnd, IDC_NCK4_OBTAIN) == BST_CHECKED)
- d->k4_enabled = TRUE;
- else
- d->k4_enabled = FALSE;
-
- if ((oldstate && !d->k4_enabled) ||
- (!oldstate && d->k4_enabled)) {
-
- khui_cw_enable_type(d->nc, credtype_id_krb4, d->k4_enabled);
- }
-
- d->method = K4_METHOD_AUTO;
-
- for (i=K4_METHOD_AUTO; i<=K4_METHOD_K524; i++) {
- if (IsDlgButtonChecked(d->hwnd, method_to_id[i]) == BST_CHECKED) {
- d->method = i;
- break;
- }
- }
-}
-
-khm_boolean k4_should_identity_get_k4(khm_handle ident) {
- khm_int32 idflags = 0;
- khm_int32 t = TRUE;
- khm_handle csp_ident = NULL;
- khm_handle csp_k4 = NULL;
- khm_boolean get_k4 = TRUE;
- khm_boolean id_spec = FALSE;
-
- if (KHM_FAILED(kcdb_identity_get_flags(ident, &idflags)))
- return FALSE;
-
- if (!(idflags & KCDB_IDENT_FLAG_DEFAULT)) {
- /* we only support k4 for one identity, and that is the
- default identity. If we are trying to get tickets for a
- non-default identity, then we start off as disabled unless
- there is no default identity. */
-
- khm_handle defident = NULL;
-
- if (KHM_SUCCEEDED(kcdb_identity_get_default(&defident))) {
- kcdb_identity_release(defident);
-
- return FALSE;
- }
- }
-
- if (KHM_SUCCEEDED(kcdb_identity_get_config(ident, 0, &csp_ident))) {
- if (KHM_SUCCEEDED(khc_open_space(csp_ident, CSNAME_KRB4CRED, 0,
- &csp_k4))) {
- khm_int32 t = 0;
-
- if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4NewCreds", &t))) {
- get_k4 = !!t;
- id_spec = TRUE;
- }
-
- khc_close_space(csp_k4);
- }
- khc_close_space(csp_ident);
- }
-
- /* if there was a value specified for the identity, then that
- takes precedence. */
- if (id_spec || !get_k4)
- return get_k4;
-
- if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4NewCreds", &t)) &&
- !t)
- return FALSE;
-
- return TRUE;
-}
-
-void k4_read_identity_data(k4_dlg_data * d) {
- khm_handle csp_ident = NULL;
- khm_handle csp_k4 = NULL;
-
- khm_int32 idflags = 0;
- khm_int32 t;
-
- if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4NewCreds", &t)))
- d->k4_enabled = !!t;
- else
- d->k4_enabled = TRUE;
-
- if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4Method", &t)))
- d->method = t;
- else
- d->method = K4_METHOD_AUTO;
-
- if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"DefaultLifetime", &t)))
- d->lifetime = t;
- else
- d->lifetime = 10 * 60 * 60; /* 10 hours */
-
- if (d->nc->n_identities > 0 &&
- d->nc->identities[0]) {
-
- if (KHM_SUCCEEDED(kcdb_identity_get_config(d->nc->identities[0],
- 0,
- &csp_ident))) {
-
- khc_open_space(csp_ident, CSNAME_KRB4CRED, 0, &csp_k4);
-
- if (csp_k4) {
- if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4NewCreds", &t)))
- d->k4_enabled = !!t;
- if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4Method", &t)))
- d->method = t;
- khc_close_space(csp_k4);
- }
-
- khc_close_space(csp_ident);
- }
-
- if (d->k4_enabled) {
- d->k4_enabled = k4_should_identity_get_k4(d->nc->identities[0]);
- }
- } else {
- d->k4_enabled = FALSE;
- }
-
- if (d->method < 0 || d->method > K4_METHOD_K524)
- d->method = K4_METHOD_AUTO;
-}
-
-void k4_write_identity_data(k4_dlg_data * d) {
- khm_handle csp_ident = NULL;
- khm_handle csp_k4 = NULL;
-
- if (d->nc->n_identities > 0 &&
- d->nc->identities[0] &&
- KHM_SUCCEEDED(kcdb_identity_get_config(d->nc->identities[0],
- KHM_FLAG_CREATE,
- &csp_ident))) {
- khc_open_space(csp_ident, CSNAME_KRB4CRED,
- KHM_FLAG_CREATE | KCONF_FLAG_WRITEIFMOD,
- &csp_k4);
-
- if (csp_k4) {
- khc_write_int32(csp_k4, L"Krb4NewCreds", !!d->k4_enabled);
- khc_write_int32(csp_k4, L"Krb4Method", d->method);
-
- khc_close_space(csp_k4);
- }
-
- khc_close_space(csp_ident);
- }
-}
-
-void k4_handle_wmnc_notify(k4_dlg_data * d,
- WPARAM wParam,
- LPARAM lParam) {
- switch(HIWORD(wParam)) {
- case WMNC_UPDATE_CREDTEXT:
- {
- if (d->nct->credtext) {
- PFREE(d->nct->credtext);
- d->nct->credtext = NULL;
- }
-
- if (d->nc->n_identities > 0 &&
- d->nc->identities[0]) {
-
- khm_int32 flags = 0;
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- wchar_t * atsign;
- wchar_t * realm;
- khm_size cb;
-
- kcdb_identity_get_flags(d->nc->identities[0], &flags);
-
- if (!(flags & KCDB_IDENT_FLAG_VALID)) {
- break;
- }
-
- cb = sizeof(idname);
- kcdb_identity_get_name(d->nc->identities[0], idname,
- &cb);
-
- atsign = wcsrchr(idname, L'@');
-
- if (atsign == NULL || !atsign[1])
- break;
-
- realm = ++atsign;
-
- if (d->k4_enabled) {
- wchar_t wmethod[128];
- wchar_t wfmt[128];
- wchar_t wct[512];
-
- LoadString(hResModule, IDS_CT_TGTFOR,
- wfmt, ARRAYLENGTH(wfmt));
-
- if (d->method == K4_METHOD_AUTO)
- LoadString(hResModule, IDS_METHOD_AUTO, wmethod,
- ARRAYLENGTH(wmethod));
- else if (d->method == K4_METHOD_PASSWORD)
- LoadString(hResModule, IDS_METHOD_PWD, wmethod,
- ARRAYLENGTH(wmethod));
- else if (d->method == K4_METHOD_K524)
- LoadString(hResModule, IDS_METHOD_K524, wmethod,
- ARRAYLENGTH(wmethod));
- else {
- assert(FALSE);
- }
-
- StringCbPrintf(wct, sizeof(wct), wfmt, realm, wmethod);
-
- StringCbLength(wct, sizeof(wct), &cb);
- cb += sizeof(wchar_t);
-
- d->nct->credtext = PMALLOC(cb);
-
- StringCbCopy(d->nct->credtext, cb, wct);
- } else {
- wchar_t wct[256];
-
- LoadString(hResModule, IDS_CT_DISABLED,
- wct, ARRAYLENGTH(wct));
-
- StringCbLength(wct, sizeof(wct), &cb);
- cb += sizeof(wchar_t);
-
- d->nct->credtext = PMALLOC(cb);
-
- StringCbCopy(d->nct->credtext, cb, wct);
- }
- }
- /* no identities were selected. it is not the
- responsibility of krb4 to complain about this. */
- }
- break;
-
- case WMNC_IDENTITY_CHANGE:
- k4_read_identity_data(d);
- k4_update_display(d, TRUE);
- break;
-
- case WMNC_CREDTEXT_LINK:
- {
- wchar_t wid[KHUI_MAXCCH_HTLINK_FIELD];
- wchar_t * wids;
- khui_htwnd_link * l;
-
- l = (khui_htwnd_link *) lParam;
-
- StringCchCopyN(wid, ARRAYLENGTH(wid), l->id, l->id_len);
- wids = wcschr(wid, L':');
-
- if (!wids)
- break;
- else
- wids++;
-
- if (!wcscmp(wids, L"Enable")) {
- d->k4_enabled = TRUE;
-
- k4_update_display(d, TRUE);
- khui_cw_enable_type(d->nc, credtype_id_krb4, TRUE);
- }
- }
- break;
- }
-}
-
-INT_PTR CALLBACK k4_nc_dlg_proc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
-
- k4_dlg_data * d;
-
- switch(uMsg) {
- case WM_INITDIALOG:
- {
- d = PMALLOC(sizeof(*d));
- ZeroMemory(d, sizeof(*d));
-
- d->nc = (khui_new_creds *) lParam;
- khui_cw_find_type(d->nc, credtype_id_krb4, &d->nct);
-
-#pragma warning(push)
-#pragma warning(disable: 4244)
- SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) d);
-#pragma warning(pop)
-
- d->nct->aux = (LPARAM) d;
- d->hwnd = hwnd;
-
- d->k4_enabled = TRUE;
- d->method = K4_METHOD_AUTO;
-
- k4_update_display(d, TRUE);
- }
- break;
-
- case WM_COMMAND:
- {
- if (HIWORD(wParam) == BN_CLICKED) {
- d = (k4_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- k4_update_data(d);
-
- if (LOWORD(wParam) == IDC_NCK4_OBTAIN) {
- k4_update_display(d, TRUE);
- }
-
- return TRUE;
- }
- }
- break;
-
- case KHUI_WM_NC_NOTIFY:
- {
- d = (k4_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
- k4_handle_wmnc_notify(d, wParam, lParam);
- }
- break;
-
- case WM_DESTROY:
- {
- d = (k4_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- d->nct->aux = 0;
-
- PFREE(d);
- }
- break;
- }
-
- return FALSE;
-}
-
-khm_int32
-krb4_msg_newcred(khm_int32 msg_type, khm_int32 msg_subtype,
- khm_ui_4 uparam, void * vparam) {
-
- switch(msg_subtype) {
- case KMSG_CRED_NEW_CREDS:
- {
- khui_new_creds * nc;
- khui_new_creds_by_type * nct;
- khm_size cbsize;
- wchar_t wbuf[256];
-
- nc = (khui_new_creds *) vparam;
-
- nct = PMALLOC(sizeof(*nct));
-#ifdef DEBUG
- assert(nct);
-#endif
- ZeroMemory(nct, sizeof(*nct));
-
- nct->type = credtype_id_krb4;
- nct->ordinal = 3;
- LoadString(hResModule, IDS_NC_K4_SHORT,
- wbuf, ARRAYLENGTH(wbuf));
- StringCbLength(wbuf, sizeof(wbuf), &cbsize);
- cbsize += sizeof(wchar_t);
-
- nct->name = PMALLOC(cbsize);
- StringCbCopy(nct->name, cbsize, wbuf);
-
- nct->type_deps[nct->n_type_deps++] = credtype_id_krb5;
-
- nct->h_module = hResModule;
- nct->dlg_proc = k4_nc_dlg_proc;
- nct->dlg_template = MAKEINTRESOURCE(IDD_NC_KRB4);
-
- khui_cw_add_type(nc, nct);
- }
- break;
-
- case KMSG_CRED_RENEW_CREDS:
- {
- khui_new_creds * nc;
- khui_new_creds_by_type * nct;
- khm_size cbsize;
- wchar_t wbuf[256];
-
- nc = (khui_new_creds *) vparam;
-
- if (!nc->ctx.identity)
- break;
-
- nct = PMALLOC(sizeof(*nct));
-#ifdef DEBUG
- assert(nct);
-#endif
-
- ZeroMemory(nct, sizeof(*nct));
-
- nct->type = credtype_id_krb4;
- nct->ordinal = 3;
- LoadString(hResModule, IDS_NC_K4_SHORT,
- wbuf, ARRAYLENGTH(wbuf));
- StringCbLength(wbuf, sizeof(wbuf), &cbsize);
- cbsize += sizeof(wchar_t);
-
- nct->name = PMALLOC(cbsize);
- StringCbCopy(nct->name, cbsize, wbuf);
-
- nct->type_deps[nct->n_type_deps++] = credtype_id_krb5;
-
- khui_cw_add_type(nc, nct);
- }
- break;
-
- case KMSG_CRED_DIALOG_SETUP:
- break;
-
- case KMSG_CRED_PROCESS:
- {
- khui_new_creds * nc;
- khui_new_creds_by_type * nct = NULL;
- khm_handle ident = NULL;
- k4_dlg_data * d = NULL;
- long code = 0;
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- khm_size cb;
-
- nc = (khui_new_creds *) vparam;
- if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct)))
- break;
-
- if (nc->subtype == KMSG_CRED_NEW_CREDS ||
- nc->subtype == KMSG_CRED_RENEW_CREDS) {
- khm_int32 method;
-
- if (nc->subtype == KMSG_CRED_NEW_CREDS) {
-
- d = (k4_dlg_data *) nct->aux;
- if (!d ||
- nc->n_identities == 0 ||
- nc->identities[0] == NULL ||
- nc->result != KHUI_NC_RESULT_PROCESS) {
- khui_cw_set_response(nc, credtype_id_krb4,
- KHUI_NC_RESPONSE_SUCCESS |
- KHUI_NC_RESPONSE_EXIT);
- break;
- }
-
- if (!d->k4_enabled) {
- k4_write_identity_data(d);
- khui_cw_set_response(nc, credtype_id_krb4,
- KHUI_NC_RESPONSE_SUCCESS |
- KHUI_NC_RESPONSE_EXIT);
- break;
- }
-
- method = d->method;
- ident = nc->identities[0];
-
- cb = sizeof(idname);
- kcdb_identity_get_name(ident, idname, &cb);
- _begin_task(0);
- _report_mr2(KHERR_NONE, MSG_K4_NEW_CREDS,
- _cstr(ident), _int32(method));
- _resolve();
- _describe();
-
- } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) {
-
- if ((nc->ctx.scope == KHUI_SCOPE_IDENT &&
- nc->ctx.identity != NULL) ||
-
- (nc->ctx.scope == KHUI_SCOPE_CREDTYPE &&
- nc->ctx.cred_type == credtype_id_krb4 &&
- nc->ctx.identity != NULL) ||
-
- (nc->ctx.scope == KHUI_SCOPE_CRED &&
- nc->ctx.cred_type == credtype_id_krb4 &&
- nc->ctx.identity != NULL &&
- nc->ctx.cred != NULL)) {
-
- ident = nc->ctx.identity;
-
- if (!k4_should_identity_get_k4(ident)) {
-
- _reportf(L"Kerberos 4 is not enabled for this identity. Skipping");
-
- khui_cw_set_response(nc, credtype_id_krb4,
- KHUI_NC_RESPONSE_FAILED |
- KHUI_NC_RESPONSE_EXIT);
- break;
- }
-
- } else {
-
- _reportf(L"Kerberos 4 is not within renewal scope. Skipping");
-
- khui_cw_set_response(nc, credtype_id_krb4,
- KHUI_NC_RESPONSE_FAILED |
- KHUI_NC_RESPONSE_EXIT);
- break;
- }
-
- method = K4_METHOD_K524; /* only k524 is supported
- for renewals */
-
- _begin_task(0);
- cb = sizeof(idname);
- kcdb_identity_get_name(ident, idname, &cb);
- _report_mr2(KHERR_NONE, MSG_K4_RENEW_CREDS,
- _cstr(ident), _int32(method));
- _resolve();
- _describe();
- } else {
- assert(FALSE);
- break;
- }
-
- if ((method == K4_METHOD_AUTO ||
- method == K4_METHOD_K524) &&
- khui_cw_type_succeeded(nc, credtype_id_krb5)) {
-
- khm_handle tgt;
- FILETIME ft_prev;
- FILETIME ft_new;
- khm_size cb;
-
- _report_mr0(KHERR_INFO, MSG_K4_TRY_K524);
-
- tgt = khm_krb4_find_tgt(NULL, ident);
- if (tgt) {
- cb = sizeof(ft_prev);
- if (KHM_FAILED(kcdb_cred_get_attr(tgt,
- KCDB_ATTR_EXPIRE,
- NULL,
- &ft_prev,
- &cb)))
- ZeroMemory(&ft_prev, sizeof(ft_prev));
- kcdb_cred_release(tgt);
- }
-
- code = khm_convert524(ident);
-
- _reportf(L"khm_convert524 returns code %d", code);
-
- if (code == 0) {
- khui_cw_set_response(nc, credtype_id_krb4,
- KHUI_NC_RESPONSE_SUCCESS |
- KHUI_NC_RESPONSE_EXIT);
-
- if (nc->subtype == KMSG_CRED_NEW_CREDS) {
- assert(d != NULL);
-
- k4_write_identity_data(d);
-
- } else if (nc->subtype == KMSG_CRED_RENEW_CREDS &&
- (nc->ctx.scope == KHUI_SCOPE_CREDTYPE ||
- nc->ctx.scope == KHUI_SCOPE_CRED)) {
-
- khm_krb4_list_tickets();
-
- tgt = khm_krb4_find_tgt(NULL, ident);
-
- if (tgt) {
- cb = sizeof(ft_new);
- ZeroMemory(&ft_new, sizeof(ft_new));
-
- kcdb_cred_get_attr(tgt,
- KCDB_ATTR_EXPIRE,
- NULL,
- &ft_new,
- &cb);
-
- kcdb_cred_release(tgt);
- }
-
- if (!tgt ||
- CompareFileTime(&ft_new,
- &ft_prev) <= 0) {
- /* The new TGT wasn't much of an
- improvement over what we already
- had. We should go out and try to
- renew the identity now. */
-
- khui_action_context ctx;
-
- _reportf(L"Renewal of Krb4 creds failed to get a longer TGT. Triggering identity renewal");
-
- khui_context_create(&ctx,
- KHUI_SCOPE_IDENT,
- nc->ctx.identity,
- KCDB_CREDTYPE_INVALID,
- NULL);
- khui_action_trigger(KHUI_ACTION_RENEW_CRED,
- &ctx);
-
- khui_context_release(&ctx);
- }
- }
-
- _end_task();
- break;
-
- } else if (method == K4_METHOD_K524) {
- khui_cw_set_response(nc, credtype_id_krb4,
- KHUI_NC_RESPONSE_FAILED |
- KHUI_NC_RESPONSE_EXIT);
-
- if (nc->subtype == KMSG_CRED_RENEW_CREDS &&
- (nc->ctx.scope == KHUI_SCOPE_CREDTYPE ||
- nc->ctx.scope == KHUI_SCOPE_CRED)) {
- /* We were trying to get a new Krb4 TGT
- for this identity. Sometimes this
- fails because of restrictions placed on
- K524d regarding the lifetime of the
- issued K4 TGT. In this case, we
- trigger a renewal of the identity in
- the hope that the new K5 TGT will allow
- us to successfully get a new K4 TGT
- next time over using the new K5 TGT. */
-
- khui_action_context ctx;
-
- _reportf(L"Renewal of Krb4 creds failed using k524. Triggerring identity renewal.");
-
- khui_context_create(&ctx,
- KHUI_SCOPE_IDENT,
- nc->ctx.identity,
- KCDB_CREDTYPE_INVALID,
- NULL);
-
- khui_action_trigger(KHUI_ACTION_RENEW_CRED,
- &ctx);
-
- khui_context_release(&ctx);
- }
-
- _end_task();
- break;
-
- }
- }
-
- /* only supported for new credentials */
- if (method == K4_METHOD_AUTO ||
- method == K4_METHOD_PASSWORD) {
-
- khm_size n_prompts = 0;
- khm_size idx;
- khm_size cb;
- wchar_t wpwd[KHUI_MAXCCH_PROMPT_VALUE];
- char pwd[KHUI_MAXCCH_PROMPT_VALUE];
- wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
- char idname[KCDB_IDENT_MAXCCH_NAME];
-
- char * aname = NULL;
- char * inst = NULL;
- char * realm = NULL;
-
- assert(nc->subtype == KMSG_CRED_NEW_CREDS);
-
- _report_mr0(KHERR_INFO, MSG_K4_TRY_PASSWORD);
-
- code = TRUE; /* just has to be non-zero */
-
- khui_cw_get_prompt_count(nc, &n_prompts);
-
- if (n_prompts == 0)
- goto _skip_pwd;
-
- for (idx = 0; idx < n_prompts; idx++) {
- khui_new_creds_prompt * p;
-
- if (KHM_FAILED(khui_cw_get_prompt(nc, idx, &p)))
- continue;
-
- if (p->type == KHUI_NCPROMPT_TYPE_PASSWORD)
- break;
- }
-
- if (idx >= n_prompts) {
- _reportf(L"Password prompt not found");
- goto _skip_pwd;
- }
-
- khui_cw_sync_prompt_values(nc);
-
- cb = sizeof(wpwd);
- if (KHM_FAILED(khui_cw_get_prompt_value(nc, idx,
- wpwd,
- &cb))) {
- _reportf(L"Failed to obtain password value");
- goto _skip_pwd;
- }
-
- UnicodeStrToAnsi(pwd, sizeof(pwd), wpwd);
-
- cb = sizeof(widname);
- kcdb_identity_get_name(ident,
- widname,
- &cb);
-
- UnicodeStrToAnsi(idname, sizeof(idname), widname);
-
- {
- char * atsign;
-
- atsign = strchr(idname, '@');
- if (atsign == NULL) {
- _reportf(L"Identity name does not contain an '@'");
- goto _skip_pwd;
- }
-
- *atsign++ = 0;
-
- realm = atsign;
- }
-
- {
- char * slash;
-
- slash = strchr(idname, '/');
- if (slash != NULL) {
- *slash++ = 0;
- inst = slash;
- } else {
- inst = "";
- }
- }
-
- aname = idname;
-
- code = khm_krb4_kinit(aname, inst, realm,
- (long) d->lifetime, pwd);
-
- _reportf(L"khm_krb4_kinit returns code %d", code);
-
- _skip_pwd:
-
- if (code) {
- khui_cw_set_response(nc, credtype_id_krb4,
- KHUI_NC_RESPONSE_EXIT |
- KHUI_NC_RESPONSE_FAILED);
-
- } else {
- khui_cw_set_response(nc, credtype_id_krb4,
- KHUI_NC_RESPONSE_EXIT |
- KHUI_NC_RESPONSE_SUCCESS);
-
- if (nc->subtype == KMSG_CRED_NEW_CREDS) {
-
- assert(d != NULL);
- k4_write_identity_data(d);
-
- }
- }
- }
-
- _end_task();
- }
- }
- break;
-
- case KMSG_CRED_END:
- {
- khui_new_creds * nc;
- khui_new_creds_by_type * nct = NULL;
-
- nc = (khui_new_creds *) vparam;
- if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct)))
- break;
-
- khui_cw_del_type(nc, credtype_id_krb4);
-
- if (nct->name)
- PFREE(nct->name);
-
- if (nct->credtext)
- PFREE(nct->credtext);
-
- PFREE(nct);
- }
- break;
- }
-
- return KHM_ERROR_SUCCESS;
-}
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<kherror.h>
+#include<khmsgtypes.h>
+#include<khuidefs.h>
+#include<utils.h>
+#include<commctrl.h>
+#include<strsafe.h>
+#include<krb5.h>
+#include<assert.h>
+
+/* method identifiers should be contiguous */
+#define K4_METHOD_AUTO 0
+#define K4_METHOD_PASSWORD 1
+#define K4_METHOD_K524 2
+
+int method_to_id[] = {
+ IDC_NCK4_AUTO,
+ IDC_NCK4_PWD,
+ IDC_NCK4_K524
+};
+
+typedef struct tag_k4_dlg_data {
+ HWND hwnd;
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct;
+
+ khm_boolean k4_enabled;
+ khm_int32 method;
+ time_t lifetime;
+} k4_dlg_data;
+
+void k4_update_display(k4_dlg_data * d, BOOL update_methods) {
+ CheckDlgButton(d->hwnd, IDC_NCK4_OBTAIN,
+ (d->k4_enabled)?BST_CHECKED: BST_UNCHECKED);
+
+ if (d->k4_enabled) {
+ EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_AUTO), TRUE);
+ EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_K524), TRUE);
+ EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_PWD ), TRUE);
+ } else {
+ EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_AUTO), FALSE);
+ EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_K524), FALSE);
+ EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_PWD ), FALSE);
+ }
+
+#ifdef DEBUG
+ assert(d->method >= 0 && d->method < ARRAYLENGTH(method_to_id));
+#endif
+
+ CheckRadioButton(d->hwnd, IDC_NCK4_AUTO, IDC_NCK4_PWD, method_to_id[d->method]);
+
+ khui_cw_enable_type(d->nc, credtype_id_krb4, d->k4_enabled);
+}
+
+void k4_update_data(k4_dlg_data * d) {
+ int i;
+ khm_boolean oldstate;
+
+ oldstate = d->k4_enabled;
+
+ if (IsDlgButtonChecked(d->hwnd, IDC_NCK4_OBTAIN) == BST_CHECKED)
+ d->k4_enabled = TRUE;
+ else
+ d->k4_enabled = FALSE;
+
+ if ((oldstate && !d->k4_enabled) ||
+ (!oldstate && d->k4_enabled)) {
+
+ khui_cw_enable_type(d->nc, credtype_id_krb4, d->k4_enabled);
+ }
+
+ d->method = K4_METHOD_AUTO;
+
+ for (i=K4_METHOD_AUTO; i<=K4_METHOD_K524; i++) {
+ if (IsDlgButtonChecked(d->hwnd, method_to_id[i]) == BST_CHECKED) {
+ d->method = i;
+ break;
+ }
+ }
+}
+
+khm_boolean k4_should_identity_get_k4(khm_handle ident) {
+ khm_int32 idflags = 0;
+ khm_int32 t = TRUE;
+ khm_handle csp_ident = NULL;
+ khm_handle csp_k4 = NULL;
+ khm_boolean get_k4 = TRUE;
+ khm_boolean id_spec = FALSE;
+
+ if (KHM_FAILED(kcdb_identity_get_flags(ident, &idflags)))
+ return FALSE;
+
+ if (!(idflags & KCDB_IDENT_FLAG_DEFAULT)) {
+ /* we only support k4 for one identity, and that is the
+ default identity. If we are trying to get tickets for a
+ non-default identity, then we start off as disabled unless
+ there is no default identity. */
+
+ khm_handle defident = NULL;
+
+ if (KHM_SUCCEEDED(kcdb_identity_get_default(&defident))) {
+ kcdb_identity_release(defident);
+
+ return FALSE;
+ }
+ }
+
+ if (KHM_SUCCEEDED(kcdb_identity_get_config(ident, 0, &csp_ident))) {
+ if (KHM_SUCCEEDED(khc_open_space(csp_ident, CSNAME_KRB4CRED, 0,
+ &csp_k4))) {
+ khm_int32 t = 0;
+
+ if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4NewCreds", &t))) {
+ get_k4 = !!t;
+ id_spec = TRUE;
+ }
+
+ khc_close_space(csp_k4);
+ }
+ khc_close_space(csp_ident);
+ }
+
+ /* if there was a value specified for the identity, then that
+ takes precedence. */
+ if (id_spec || !get_k4)
+ return get_k4;
+
+ if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4NewCreds", &t)) &&
+ !t)
+ return FALSE;
+
+ return TRUE;
+}
+
+void k4_read_identity_data(k4_dlg_data * d) {
+ khm_handle csp_ident = NULL;
+ khm_handle csp_k4 = NULL;
+
+ khm_int32 idflags = 0;
+ khm_int32 t;
+
+ if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4NewCreds", &t)))
+ d->k4_enabled = !!t;
+ else
+ d->k4_enabled = TRUE;
+
+ if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4Method", &t)))
+ d->method = t;
+ else
+ d->method = K4_METHOD_AUTO;
+
+ if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"DefaultLifetime", &t)))
+ d->lifetime = t;
+ else
+ d->lifetime = 10 * 60 * 60; /* 10 hours */
+
+ if (d->nc->n_identities > 0 &&
+ d->nc->identities[0]) {
+
+ if (KHM_SUCCEEDED(kcdb_identity_get_config(d->nc->identities[0],
+ 0,
+ &csp_ident))) {
+
+ khc_open_space(csp_ident, CSNAME_KRB4CRED, 0, &csp_k4);
+
+ if (csp_k4) {
+ if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4NewCreds", &t)))
+ d->k4_enabled = !!t;
+ if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4Method", &t)))
+ d->method = t;
+ khc_close_space(csp_k4);
+ }
+
+ khc_close_space(csp_ident);
+ }
+
+ if (d->k4_enabled) {
+ d->k4_enabled = k4_should_identity_get_k4(d->nc->identities[0]);
+ }
+ } else {
+ d->k4_enabled = FALSE;
+ }
+
+ if (d->method < 0 || d->method > K4_METHOD_K524)
+ d->method = K4_METHOD_AUTO;
+}
+
+void k4_write_identity_data(k4_dlg_data * d) {
+ khm_handle csp_ident = NULL;
+ khm_handle csp_k4 = NULL;
+
+ if (d->nc->n_identities > 0 &&
+ d->nc->identities[0] &&
+ KHM_SUCCEEDED(kcdb_identity_get_config(d->nc->identities[0],
+ KHM_FLAG_CREATE,
+ &csp_ident))) {
+ khc_open_space(csp_ident, CSNAME_KRB4CRED,
+ KHM_FLAG_CREATE | KCONF_FLAG_WRITEIFMOD,
+ &csp_k4);
+
+ if (csp_k4) {
+ khc_write_int32(csp_k4, L"Krb4NewCreds", !!d->k4_enabled);
+ khc_write_int32(csp_k4, L"Krb4Method", d->method);
+
+ khc_close_space(csp_k4);
+ }
+
+ khc_close_space(csp_ident);
+ }
+}
+
+void k4_handle_wmnc_notify(k4_dlg_data * d,
+ WPARAM wParam,
+ LPARAM lParam) {
+ switch(HIWORD(wParam)) {
+ case WMNC_UPDATE_CREDTEXT:
+ {
+ if (d->nct->credtext) {
+ PFREE(d->nct->credtext);
+ d->nct->credtext = NULL;
+ }
+
+ if (d->nc->n_identities > 0 &&
+ d->nc->identities[0]) {
+
+ khm_int32 flags = 0;
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t * atsign;
+ wchar_t * realm;
+ khm_size cb;
+
+ kcdb_identity_get_flags(d->nc->identities[0], &flags);
+
+ if (!(flags & KCDB_IDENT_FLAG_VALID)) {
+ break;
+ }
+
+ cb = sizeof(idname);
+ kcdb_identity_get_name(d->nc->identities[0], idname,
+ &cb);
+
+ atsign = wcsrchr(idname, L'@');
+
+ if (atsign == NULL || !atsign[1])
+ break;
+
+ realm = ++atsign;
+
+ if (d->k4_enabled) {
+ wchar_t wmethod[128];
+ wchar_t wfmt[128];
+ wchar_t wct[512];
+
+ LoadString(hResModule, IDS_CT_TGTFOR,
+ wfmt, ARRAYLENGTH(wfmt));
+
+ if (d->method == K4_METHOD_AUTO)
+ LoadString(hResModule, IDS_METHOD_AUTO, wmethod,
+ ARRAYLENGTH(wmethod));
+ else if (d->method == K4_METHOD_PASSWORD)
+ LoadString(hResModule, IDS_METHOD_PWD, wmethod,
+ ARRAYLENGTH(wmethod));
+ else if (d->method == K4_METHOD_K524)
+ LoadString(hResModule, IDS_METHOD_K524, wmethod,
+ ARRAYLENGTH(wmethod));
+ else {
+ assert(FALSE);
+ }
+
+ StringCbPrintf(wct, sizeof(wct), wfmt, realm, wmethod);
+
+ StringCbLength(wct, sizeof(wct), &cb);
+ cb += sizeof(wchar_t);
+
+ d->nct->credtext = PMALLOC(cb);
+
+ StringCbCopy(d->nct->credtext, cb, wct);
+ } else {
+ wchar_t wct[256];
+
+ LoadString(hResModule, IDS_CT_DISABLED,
+ wct, ARRAYLENGTH(wct));
+
+ StringCbLength(wct, sizeof(wct), &cb);
+ cb += sizeof(wchar_t);
+
+ d->nct->credtext = PMALLOC(cb);
+
+ StringCbCopy(d->nct->credtext, cb, wct);
+ }
+ }
+ /* no identities were selected. it is not the
+ responsibility of krb4 to complain about this. */
+ }
+ break;
+
+ case WMNC_IDENTITY_CHANGE:
+ k4_read_identity_data(d);
+ k4_update_display(d, TRUE);
+ break;
+
+ case WMNC_CREDTEXT_LINK:
+ {
+ wchar_t wid[KHUI_MAXCCH_HTLINK_FIELD];
+ wchar_t * wids;
+ khui_htwnd_link * l;
+
+ l = (khui_htwnd_link *) lParam;
+
+ StringCchCopyN(wid, ARRAYLENGTH(wid), l->id, l->id_len);
+ wids = wcschr(wid, L':');
+
+ if (!wids)
+ break;
+ else
+ wids++;
+
+ if (!wcscmp(wids, L"Enable")) {
+ d->k4_enabled = TRUE;
+
+ k4_update_display(d, TRUE);
+ khui_cw_enable_type(d->nc, credtype_id_krb4, TRUE);
+ }
+ }
+ break;
+ }
+}
+
+INT_PTR CALLBACK k4_nc_dlg_proc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+
+ k4_dlg_data * d;
+
+ switch(uMsg) {
+ case WM_INITDIALOG:
+ {
+ d = PMALLOC(sizeof(*d));
+ ZeroMemory(d, sizeof(*d));
+
+ d->nc = (khui_new_creds *) lParam;
+ khui_cw_find_type(d->nc, credtype_id_krb4, &d->nct);
+
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) d);
+#pragma warning(pop)
+
+ d->nct->aux = (LPARAM) d;
+ d->hwnd = hwnd;
+
+ d->k4_enabled = TRUE;
+ d->method = K4_METHOD_AUTO;
+
+ k4_update_display(d, TRUE);
+ }
+ break;
+
+ case WM_COMMAND:
+ {
+ if (HIWORD(wParam) == BN_CLICKED) {
+ d = (k4_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ k4_update_data(d);
+
+ if (LOWORD(wParam) == IDC_NCK4_OBTAIN) {
+ k4_update_display(d, TRUE);
+ }
+
+ return TRUE;
+ }
+ }
+ break;
+
+ case KHUI_WM_NC_NOTIFY:
+ {
+ d = (k4_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+ k4_handle_wmnc_notify(d, wParam, lParam);
+ }
+ break;
+
+ case WM_DESTROY:
+ {
+ d = (k4_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ d->nct->aux = 0;
+
+ PFREE(d);
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+khm_int32
+krb4_msg_newcred(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam) {
+
+ switch(msg_subtype) {
+ case KMSG_CRED_NEW_CREDS:
+ {
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct;
+ khm_size cbsize;
+ wchar_t wbuf[256];
+
+ nc = (khui_new_creds *) vparam;
+
+ nct = PMALLOC(sizeof(*nct));
+#ifdef DEBUG
+ assert(nct);
+#endif
+ ZeroMemory(nct, sizeof(*nct));
+
+ nct->type = credtype_id_krb4;
+ nct->ordinal = 3;
+ LoadString(hResModule, IDS_NC_K4_SHORT,
+ wbuf, ARRAYLENGTH(wbuf));
+ StringCbLength(wbuf, sizeof(wbuf), &cbsize);
+ cbsize += sizeof(wchar_t);
+
+ nct->name = PMALLOC(cbsize);
+ StringCbCopy(nct->name, cbsize, wbuf);
+
+ nct->type_deps[nct->n_type_deps++] = credtype_id_krb5;
+
+ nct->h_module = hResModule;
+ nct->dlg_proc = k4_nc_dlg_proc;
+ nct->dlg_template = MAKEINTRESOURCE(IDD_NC_KRB4);
+
+ khui_cw_add_type(nc, nct);
+ }
+ break;
+
+ case KMSG_CRED_RENEW_CREDS:
+ {
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct;
+ khm_size cbsize;
+ wchar_t wbuf[256];
+
+ nc = (khui_new_creds *) vparam;
+
+ if (!nc->ctx.identity)
+ break;
+
+ nct = PMALLOC(sizeof(*nct));
+#ifdef DEBUG
+ assert(nct);
+#endif
+
+ ZeroMemory(nct, sizeof(*nct));
+
+ nct->type = credtype_id_krb4;
+ nct->ordinal = 3;
+ LoadString(hResModule, IDS_NC_K4_SHORT,
+ wbuf, ARRAYLENGTH(wbuf));
+ StringCbLength(wbuf, sizeof(wbuf), &cbsize);
+ cbsize += sizeof(wchar_t);
+
+ nct->name = PMALLOC(cbsize);
+ StringCbCopy(nct->name, cbsize, wbuf);
+
+ nct->type_deps[nct->n_type_deps++] = credtype_id_krb5;
+
+ khui_cw_add_type(nc, nct);
+ }
+ break;
+
+ case KMSG_CRED_DIALOG_SETUP:
+ break;
+
+ case KMSG_CRED_PROCESS:
+ {
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct = NULL;
+ khm_handle ident = NULL;
+ k4_dlg_data * d = NULL;
+ long code = 0;
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb;
+
+ nc = (khui_new_creds *) vparam;
+ if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct)))
+ break;
+
+ if (nc->subtype == KMSG_CRED_NEW_CREDS ||
+ nc->subtype == KMSG_CRED_RENEW_CREDS) {
+ khm_int32 method;
+
+ if (nc->subtype == KMSG_CRED_NEW_CREDS) {
+
+ d = (k4_dlg_data *) nct->aux;
+ if (!d ||
+ nc->n_identities == 0 ||
+ nc->identities[0] == NULL ||
+ nc->result != KHUI_NC_RESULT_PROCESS) {
+ khui_cw_set_response(nc, credtype_id_krb4,
+ KHUI_NC_RESPONSE_SUCCESS |
+ KHUI_NC_RESPONSE_EXIT);
+ break;
+ }
+
+ if (!d->k4_enabled) {
+ k4_write_identity_data(d);
+ khui_cw_set_response(nc, credtype_id_krb4,
+ KHUI_NC_RESPONSE_SUCCESS |
+ KHUI_NC_RESPONSE_EXIT);
+ break;
+ }
+
+ method = d->method;
+ ident = nc->identities[0];
+
+ cb = sizeof(idname);
+ kcdb_identity_get_name(ident, idname, &cb);
+ _begin_task(0);
+ _report_mr2(KHERR_NONE, MSG_K4_NEW_CREDS,
+ _cstr(ident), _int32(method));
+ _resolve();
+ _describe();
+
+ } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) {
+
+ if ((nc->ctx.scope == KHUI_SCOPE_IDENT &&
+ nc->ctx.identity != NULL) ||
+
+ (nc->ctx.scope == KHUI_SCOPE_CREDTYPE &&
+ nc->ctx.cred_type == credtype_id_krb4 &&
+ nc->ctx.identity != NULL) ||
+
+ (nc->ctx.scope == KHUI_SCOPE_CRED &&
+ nc->ctx.cred_type == credtype_id_krb4 &&
+ nc->ctx.identity != NULL &&
+ nc->ctx.cred != NULL)) {
+
+ ident = nc->ctx.identity;
+
+ if (!k4_should_identity_get_k4(ident)) {
+
+ _reportf(L"Kerberos 4 is not enabled for this identity. Skipping");
+
+ khui_cw_set_response(nc, credtype_id_krb4,
+ KHUI_NC_RESPONSE_FAILED |
+ KHUI_NC_RESPONSE_EXIT);
+ break;
+ }
+
+ } else {
+
+ _reportf(L"Kerberos 4 is not within renewal scope. Skipping");
+
+ khui_cw_set_response(nc, credtype_id_krb4,
+ KHUI_NC_RESPONSE_FAILED |
+ KHUI_NC_RESPONSE_EXIT);
+ break;
+ }
+
+ method = K4_METHOD_K524; /* only k524 is supported
+ for renewals */
+
+ _begin_task(0);
+ cb = sizeof(idname);
+ kcdb_identity_get_name(ident, idname, &cb);
+ _report_mr2(KHERR_NONE, MSG_K4_RENEW_CREDS,
+ _cstr(ident), _int32(method));
+ _resolve();
+ _describe();
+ } else {
+ assert(FALSE);
+ break;
+ }
+
+ if ((method == K4_METHOD_AUTO ||
+ method == K4_METHOD_K524) &&
+ khui_cw_type_succeeded(nc, credtype_id_krb5)) {
+
+ khm_handle tgt;
+ FILETIME ft_prev;
+ FILETIME ft_new;
+ khm_size cb;
+
+ _report_mr0(KHERR_INFO, MSG_K4_TRY_K524);
+
+ tgt = khm_krb4_find_tgt(NULL, ident);
+ if (tgt) {
+ cb = sizeof(ft_prev);
+ if (KHM_FAILED(kcdb_cred_get_attr(tgt,
+ KCDB_ATTR_EXPIRE,
+ NULL,
+ &ft_prev,
+ &cb)))
+ ZeroMemory(&ft_prev, sizeof(ft_prev));
+ kcdb_cred_release(tgt);
+ }
+
+ code = khm_convert524(ident);
+
+ _reportf(L"khm_convert524 returns code %d", code);
+
+ if (code == 0) {
+ khui_cw_set_response(nc, credtype_id_krb4,
+ KHUI_NC_RESPONSE_SUCCESS |
+ KHUI_NC_RESPONSE_EXIT);
+
+ if (nc->subtype == KMSG_CRED_NEW_CREDS) {
+ assert(d != NULL);
+
+ k4_write_identity_data(d);
+
+ } else if (nc->subtype == KMSG_CRED_RENEW_CREDS &&
+ (nc->ctx.scope == KHUI_SCOPE_CREDTYPE ||
+ nc->ctx.scope == KHUI_SCOPE_CRED)) {
+
+ khm_krb4_list_tickets();
+
+ tgt = khm_krb4_find_tgt(NULL, ident);
+
+ if (tgt) {
+ cb = sizeof(ft_new);
+ ZeroMemory(&ft_new, sizeof(ft_new));
+
+ kcdb_cred_get_attr(tgt,
+ KCDB_ATTR_EXPIRE,
+ NULL,
+ &ft_new,
+ &cb);
+
+ kcdb_cred_release(tgt);
+ }
+
+ if (!tgt ||
+ CompareFileTime(&ft_new,
+ &ft_prev) <= 0) {
+ /* The new TGT wasn't much of an
+ improvement over what we already
+ had. We should go out and try to
+ renew the identity now. */
+
+ khui_action_context ctx;
+
+ _reportf(L"Renewal of Krb4 creds failed to get a longer TGT. Triggering identity renewal");
+
+ khui_context_create(&ctx,
+ KHUI_SCOPE_IDENT,
+ nc->ctx.identity,
+ KCDB_CREDTYPE_INVALID,
+ NULL);
+ khui_action_trigger(KHUI_ACTION_RENEW_CRED,
+ &ctx);
+
+ khui_context_release(&ctx);
+ }
+ }
+
+ _end_task();
+ break;
+
+ } else if (method == K4_METHOD_K524) {
+ khui_cw_set_response(nc, credtype_id_krb4,
+ KHUI_NC_RESPONSE_FAILED |
+ KHUI_NC_RESPONSE_EXIT);
+
+ if (nc->subtype == KMSG_CRED_RENEW_CREDS &&
+ (nc->ctx.scope == KHUI_SCOPE_CREDTYPE ||
+ nc->ctx.scope == KHUI_SCOPE_CRED)) {
+ /* We were trying to get a new Krb4 TGT
+ for this identity. Sometimes this
+ fails because of restrictions placed on
+ K524d regarding the lifetime of the
+ issued K4 TGT. In this case, we
+ trigger a renewal of the identity in
+ the hope that the new K5 TGT will allow
+ us to successfully get a new K4 TGT
+ next time over using the new K5 TGT. */
+
+ khui_action_context ctx;
+
+ _reportf(L"Renewal of Krb4 creds failed using k524. Triggerring identity renewal.");
+
+ khui_context_create(&ctx,
+ KHUI_SCOPE_IDENT,
+ nc->ctx.identity,
+ KCDB_CREDTYPE_INVALID,
+ NULL);
+
+ khui_action_trigger(KHUI_ACTION_RENEW_CRED,
+ &ctx);
+
+ khui_context_release(&ctx);
+ }
+
+ _end_task();
+ break;
+
+ }
+ }
+
+ /* only supported for new credentials */
+ if (method == K4_METHOD_AUTO ||
+ method == K4_METHOD_PASSWORD) {
+
+ khm_size n_prompts = 0;
+ khm_size idx;
+ khm_size cb;
+ wchar_t wpwd[KHUI_MAXCCH_PROMPT_VALUE];
+ char pwd[KHUI_MAXCCH_PROMPT_VALUE];
+ wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
+ char idname[KCDB_IDENT_MAXCCH_NAME];
+
+ char * aname = NULL;
+ char * inst = NULL;
+ char * realm = NULL;
+
+ assert(nc->subtype == KMSG_CRED_NEW_CREDS);
+
+ _report_mr0(KHERR_INFO, MSG_K4_TRY_PASSWORD);
+
+ code = TRUE; /* just has to be non-zero */
+
+ khui_cw_get_prompt_count(nc, &n_prompts);
+
+ if (n_prompts == 0)
+ goto _skip_pwd;
+
+ for (idx = 0; idx < n_prompts; idx++) {
+ khui_new_creds_prompt * p;
+
+ if (KHM_FAILED(khui_cw_get_prompt(nc, idx, &p)))
+ continue;
+
+ if (p->type == KHUI_NCPROMPT_TYPE_PASSWORD)
+ break;
+ }
+
+ if (idx >= n_prompts) {
+ _reportf(L"Password prompt not found");
+ goto _skip_pwd;
+ }
+
+ khui_cw_sync_prompt_values(nc);
+
+ cb = sizeof(wpwd);
+ if (KHM_FAILED(khui_cw_get_prompt_value(nc, idx,
+ wpwd,
+ &cb))) {
+ _reportf(L"Failed to obtain password value");
+ goto _skip_pwd;
+ }
+
+ UnicodeStrToAnsi(pwd, sizeof(pwd), wpwd);
+
+ cb = sizeof(widname);
+ kcdb_identity_get_name(ident,
+ widname,
+ &cb);
+
+ UnicodeStrToAnsi(idname, sizeof(idname), widname);
+
+ {
+ char * atsign;
+
+ atsign = strchr(idname, '@');
+ if (atsign == NULL) {
+ _reportf(L"Identity name does not contain an '@'");
+ goto _skip_pwd;
+ }
+
+ *atsign++ = 0;
+
+ realm = atsign;
+ }
+
+ {
+ char * slash;
+
+ slash = strchr(idname, '/');
+ if (slash != NULL) {
+ *slash++ = 0;
+ inst = slash;
+ } else {
+ inst = "";
+ }
+ }
+
+ aname = idname;
+
+ code = khm_krb4_kinit(aname, inst, realm,
+ (long) d->lifetime, pwd);
+
+ _reportf(L"khm_krb4_kinit returns code %d", code);
+
+ _skip_pwd:
+
+ if (code) {
+ khui_cw_set_response(nc, credtype_id_krb4,
+ KHUI_NC_RESPONSE_EXIT |
+ KHUI_NC_RESPONSE_FAILED);
+
+ } else {
+ khui_cw_set_response(nc, credtype_id_krb4,
+ KHUI_NC_RESPONSE_EXIT |
+ KHUI_NC_RESPONSE_SUCCESS);
+
+ if (nc->subtype == KMSG_CRED_NEW_CREDS) {
+
+ assert(d != NULL);
+ k4_write_identity_data(d);
+
+ }
+ }
+ }
+
+ _end_task();
+ }
+ }
+ break;
+
+ case KMSG_CRED_END:
+ {
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct = NULL;
+
+ nc = (khui_new_creds *) vparam;
+ if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct)))
+ break;
+
+ khui_cw_del_type(nc, credtype_id_krb4);
+
+ if (nct->name)
+ PFREE(nct->name);
+
+ if (nct->credtext)
+ PFREE(nct->credtext);
+
+ PFREE(nct);
+ }
+ break;
+ }
+
+ return KHM_ERROR_SUCCESS;
+}
diff --git a/src/windows/identity/plugins/krb4/krb4plugin.c b/src/windows/identity/plugins/krb4/krb4plugin.c
index b4edd4192..9a50249f7 100644
--- a/src/windows/identity/plugins/krb4/krb4plugin.c
+++ b/src/windows/identity/plugins/krb4/krb4plugin.c
@@ -1,297 +1,297 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<kherror.h>
-#include<khmsgtypes.h>
-#include<khuidefs.h>
-#include<utils.h>
-#include<commctrl.h>
-#include<strsafe.h>
-#include<krb5.h>
-
-khm_int32 credtype_id_krb4 = KCDB_CREDTYPE_INVALID;
-khm_int32 credtype_id_krb5 = KCDB_CREDTYPE_INVALID;
-
-khm_boolean krb4_initialized = FALSE;
-khm_handle krb4_credset = NULL;
-
-/* Kerberos IV stuff */
-khm_int32 KHMAPI
-krb4_msg_system(khm_int32 msg_type, khm_int32 msg_subtype,
- khm_ui_4 uparam, void * vparam)
-{
- khm_int32 rv = KHM_ERROR_SUCCESS;
-
- switch(msg_subtype) {
- case KMSG_SYSTEM_INIT:
- {
-#ifdef _WIN64
- return KHM_ERROR_NOT_IMPLEMENTED;
-#else
- kcdb_credtype ct;
- wchar_t buf[KCDB_MAXCCH_SHORT_DESC];
- size_t cbsize;
- khui_config_node_reg reg;
- wchar_t wshort_desc[KHUI_MAXCCH_SHORT_DESC];
- wchar_t wlong_desc[KHUI_MAXCCH_LONG_DESC];
-
- /* perform critical registrations and initialization
- stuff */
- ZeroMemory(&ct, sizeof(ct));
- ct.id = KCDB_CREDTYPE_AUTO;
- ct.name = KRB4_CREDTYPE_NAME;
-
- if(LoadString(hResModule, IDS_KRB4_SHORT_DESC,
- buf, ARRAYLENGTH(buf)))
- {
- StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize);
- cbsize += sizeof(wchar_t);
- ct.short_desc = PMALLOC(cbsize);
- StringCbCopy(ct.short_desc, cbsize, buf);
- }
-
- /* even though ideally we should be setting limits
- based KCDB_MAXCB_LONG_DESC, our long description
- actually fits nicely in KCDB_MAXCB_SHORT_DESC */
- if(LoadString(hResModule, IDS_KRB4_LONG_DESC,
- buf, ARRAYLENGTH(buf)))
- {
- StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize);
- cbsize += sizeof(wchar_t);
- ct.long_desc = PMALLOC(cbsize);
- StringCbCopy(ct.long_desc, cbsize, buf);
- }
-
- ct.icon = NULL; /* TODO: set a proper icon */
- kmq_create_subscription(krb4_cb, &ct.sub);
-
- rv = kcdb_credtype_register(&ct, &credtype_id_krb4);
-
- if(KHM_SUCCEEDED(rv))
- rv = kcdb_credset_create(&krb4_credset);
-
- if (KHM_SUCCEEDED(rv))
- rv = kcdb_credtype_get_id(KRB5_CREDTYPE_NAME,
- &credtype_id_krb5);
-
- if(ct.short_desc)
- PFREE(ct.short_desc);
-
- if(ct.long_desc)
- PFREE(ct.long_desc);
-
- if (KHM_SUCCEEDED(rv)) {
- khui_config_node idents;
-
- ZeroMemory(&reg, sizeof(reg));
-
- reg.name = KRB4_CONFIG_NODE_NAME;
- reg.short_desc = wshort_desc;
- reg.long_desc = wlong_desc;
- reg.h_module = hResModule;
- reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_KRB4);
- reg.dlg_proc = krb4_confg_proc;
- reg.flags = 0;
-
- LoadString(hResModule, IDS_CFG_KRB4_LONG,
- wlong_desc, ARRAYLENGTH(wlong_desc));
- LoadString(hResModule, IDS_CFG_KRB4_SHORT,
- wshort_desc, ARRAYLENGTH(wshort_desc));
-
- khui_cfg_register(NULL, &reg);
-
- khui_cfg_open(NULL, L"KhmIdentities", &idents);
-
- ZeroMemory(&reg, sizeof(reg));
-
- reg.name = KRB4_IDS_CONFIG_NODE_NAME;
- reg.short_desc = wshort_desc;
- reg.long_desc = wlong_desc;
- reg.h_module = hResModule;
- reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_IDS_KRB4);
- reg.dlg_proc = krb4_ids_config_proc;
- reg.flags = KHUI_CNFLAG_SUBPANEL;
-
- LoadString(hResModule, IDS_CFG_KRB4_SHORT,
- wlong_desc, ARRAYLENGTH(wlong_desc));
- LoadString(hResModule, IDS_CFG_KRB4_SHORT,
- wshort_desc, ARRAYLENGTH(wshort_desc));
-
- khui_cfg_register(idents, &reg);
-
- ZeroMemory(&reg, sizeof(reg));
-
- reg.name = KRB4_ID_CONFIG_NODE_NAME;
- reg.short_desc = wshort_desc;
- reg.long_desc = wlong_desc;
- reg.h_module = hResModule;
- reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_ID_KRB4);
- reg.dlg_proc = krb4_id_config_proc;
- reg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_PLURAL;
-
- LoadString(hResModule, IDS_CFG_KRB4_SHORT,
- wlong_desc, ARRAYLENGTH(wlong_desc));
- LoadString(hResModule, IDS_CFG_KRB4_SHORT,
- wshort_desc, ARRAYLENGTH(wshort_desc));
-
- khui_cfg_register(idents, &reg);
-
- khui_cfg_release(idents);
-
- }
-
- /* Lookup common data types */
- if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ENCTYPE,
- &type_id_enctype))) {
- rv = KHM_ERROR_UNKNOWN;
- }
-
- if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ADDR_LIST,
- &type_id_addr_list))) {
- rv = KHM_ERROR_UNKNOWN;
- }
-
- if(KHM_FAILED(kcdb_type_get_id(TYPENAME_KRB5_FLAGS,
- &type_id_krb5_flags))) {
- rv = KHM_ERROR_UNKNOWN;
- }
-
- /* Lookup common attributes */
- if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KEY_ENCTYPE,
- &attr_id_key_enctype))) {
- rv = KHM_ERROR_UNKNOWN;
- }
-
- if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_TKT_ENCTYPE,
- &attr_id_tkt_enctype))) {
- rv = KHM_ERROR_UNKNOWN;
- }
-
- if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_ADDR_LIST,
- &attr_id_addr_list))) {
- rv = KHM_ERROR_UNKNOWN;
- }
-
- if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_FLAGS,
- &attr_id_krb5_flags))) {
- rv = KHM_ERROR_UNKNOWN;
- }
-
- krb4_initialized = TRUE;
-
- khm_krb4_set_def_tkt_string();
-
- khm_krb4_list_tickets();
-#endif
- }
- break;
-
- case KMSG_SYSTEM_EXIT:
-#ifdef _WIN64
- /* See above. On 64-bit platforms, we don't support Krb4 at
- all. */
- return 0;
-#else
- if(credtype_id_krb4 >= 0)
- {
- /* basically just unregister the credential type */
- kcdb_credtype_unregister(credtype_id_krb4);
-
- kcdb_credset_delete(krb4_credset);
- }
- break;
-#endif
- }
-
- return rv;
-}
-
-khm_int32 KHMAPI
-krb4_msg_cred(khm_int32 msg_type, khm_int32 msg_subtype,
- khm_ui_4 uparam, void * vparam)
-{
- khm_int32 rv = KHM_ERROR_SUCCESS;
-
- switch(msg_subtype) {
- case KMSG_CRED_REFRESH:
- {
- khm_krb4_list_tickets();
- }
- break;
-
- case KMSG_CRED_DESTROY_CREDS:
- {
- khui_action_context * ctx;
- khm_handle credset;
- khm_size nc_root = 0;
- khm_size nc_sel = 0;
-
- ctx = (khui_action_context *) vparam;
-
- /* if all krb4 tickets are selected, then we destroy all
- of them. Otherwise, we do nothing. */
-
- kcdb_credset_create(&credset);
-
- kcdb_credset_extract(credset, ctx->credset,
- NULL, credtype_id_krb4);
- kcdb_credset_get_size(credset, &nc_sel);
-
- kcdb_credset_flush(credset);
-
- kcdb_credset_extract(credset, NULL,
- NULL, credtype_id_krb4);
- kcdb_credset_get_size(credset, &nc_root);
-
- kcdb_credset_delete(credset);
-
- if (nc_root == nc_sel) {
- khm_krb4_kdestroy();
- }
- }
- break;
-
- default:
- if (IS_CRED_ACQ_MSG(msg_subtype))
- return krb4_msg_newcred(msg_type, msg_subtype, uparam, vparam);
- }
-
- return rv;
-}
-
-khm_int32 KHMAPI
-krb4_cb(khm_int32 msg_type, khm_int32 msg_subtype,
- khm_ui_4 uparam, void * vparam)
-{
- switch(msg_type) {
- case KMSG_SYSTEM:
- return krb4_msg_system(msg_type, msg_subtype, uparam, vparam);
- case KMSG_CRED:
- return krb4_msg_cred(msg_type, msg_subtype, uparam, vparam);
- }
- return KHM_ERROR_SUCCESS;
-}
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<kherror.h>
+#include<khmsgtypes.h>
+#include<khuidefs.h>
+#include<utils.h>
+#include<commctrl.h>
+#include<strsafe.h>
+#include<krb5.h>
+
+khm_int32 credtype_id_krb4 = KCDB_CREDTYPE_INVALID;
+khm_int32 credtype_id_krb5 = KCDB_CREDTYPE_INVALID;
+
+khm_boolean krb4_initialized = FALSE;
+khm_handle krb4_credset = NULL;
+
+/* Kerberos IV stuff */
+khm_int32 KHMAPI
+krb4_msg_system(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam)
+{
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+
+ switch(msg_subtype) {
+ case KMSG_SYSTEM_INIT:
+ {
+#ifdef _WIN64
+ return KHM_ERROR_NOT_IMPLEMENTED;
+#else
+ kcdb_credtype ct;
+ wchar_t buf[KCDB_MAXCCH_SHORT_DESC];
+ size_t cbsize;
+ khui_config_node_reg reg;
+ wchar_t wshort_desc[KHUI_MAXCCH_SHORT_DESC];
+ wchar_t wlong_desc[KHUI_MAXCCH_LONG_DESC];
+
+ /* perform critical registrations and initialization
+ stuff */
+ ZeroMemory(&ct, sizeof(ct));
+ ct.id = KCDB_CREDTYPE_AUTO;
+ ct.name = KRB4_CREDTYPE_NAME;
+
+ if(LoadString(hResModule, IDS_KRB4_SHORT_DESC,
+ buf, ARRAYLENGTH(buf)))
+ {
+ StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize);
+ cbsize += sizeof(wchar_t);
+ ct.short_desc = PMALLOC(cbsize);
+ StringCbCopy(ct.short_desc, cbsize, buf);
+ }
+
+ /* even though ideally we should be setting limits
+ based KCDB_MAXCB_LONG_DESC, our long description
+ actually fits nicely in KCDB_MAXCB_SHORT_DESC */
+ if(LoadString(hResModule, IDS_KRB4_LONG_DESC,
+ buf, ARRAYLENGTH(buf)))
+ {
+ StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize);
+ cbsize += sizeof(wchar_t);
+ ct.long_desc = PMALLOC(cbsize);
+ StringCbCopy(ct.long_desc, cbsize, buf);
+ }
+
+ ct.icon = NULL; /* TODO: set a proper icon */
+ kmq_create_subscription(krb4_cb, &ct.sub);
+
+ rv = kcdb_credtype_register(&ct, &credtype_id_krb4);
+
+ if(KHM_SUCCEEDED(rv))
+ rv = kcdb_credset_create(&krb4_credset);
+
+ if (KHM_SUCCEEDED(rv))
+ rv = kcdb_credtype_get_id(KRB5_CREDTYPE_NAME,
+ &credtype_id_krb5);
+
+ if(ct.short_desc)
+ PFREE(ct.short_desc);
+
+ if(ct.long_desc)
+ PFREE(ct.long_desc);
+
+ if (KHM_SUCCEEDED(rv)) {
+ khui_config_node idents;
+
+ ZeroMemory(&reg, sizeof(reg));
+
+ reg.name = KRB4_CONFIG_NODE_NAME;
+ reg.short_desc = wshort_desc;
+ reg.long_desc = wlong_desc;
+ reg.h_module = hResModule;
+ reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_KRB4);
+ reg.dlg_proc = krb4_confg_proc;
+ reg.flags = 0;
+
+ LoadString(hResModule, IDS_CFG_KRB4_LONG,
+ wlong_desc, ARRAYLENGTH(wlong_desc));
+ LoadString(hResModule, IDS_CFG_KRB4_SHORT,
+ wshort_desc, ARRAYLENGTH(wshort_desc));
+
+ khui_cfg_register(NULL, &reg);
+
+ khui_cfg_open(NULL, L"KhmIdentities", &idents);
+
+ ZeroMemory(&reg, sizeof(reg));
+
+ reg.name = KRB4_IDS_CONFIG_NODE_NAME;
+ reg.short_desc = wshort_desc;
+ reg.long_desc = wlong_desc;
+ reg.h_module = hResModule;
+ reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_IDS_KRB4);
+ reg.dlg_proc = krb4_ids_config_proc;
+ reg.flags = KHUI_CNFLAG_SUBPANEL;
+
+ LoadString(hResModule, IDS_CFG_KRB4_SHORT,
+ wlong_desc, ARRAYLENGTH(wlong_desc));
+ LoadString(hResModule, IDS_CFG_KRB4_SHORT,
+ wshort_desc, ARRAYLENGTH(wshort_desc));
+
+ khui_cfg_register(idents, &reg);
+
+ ZeroMemory(&reg, sizeof(reg));
+
+ reg.name = KRB4_ID_CONFIG_NODE_NAME;
+ reg.short_desc = wshort_desc;
+ reg.long_desc = wlong_desc;
+ reg.h_module = hResModule;
+ reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_ID_KRB4);
+ reg.dlg_proc = krb4_id_config_proc;
+ reg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_PLURAL;
+
+ LoadString(hResModule, IDS_CFG_KRB4_SHORT,
+ wlong_desc, ARRAYLENGTH(wlong_desc));
+ LoadString(hResModule, IDS_CFG_KRB4_SHORT,
+ wshort_desc, ARRAYLENGTH(wshort_desc));
+
+ khui_cfg_register(idents, &reg);
+
+ khui_cfg_release(idents);
+
+ }
+
+ /* Lookup common data types */
+ if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ENCTYPE,
+ &type_id_enctype))) {
+ rv = KHM_ERROR_UNKNOWN;
+ }
+
+ if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ADDR_LIST,
+ &type_id_addr_list))) {
+ rv = KHM_ERROR_UNKNOWN;
+ }
+
+ if(KHM_FAILED(kcdb_type_get_id(TYPENAME_KRB5_FLAGS,
+ &type_id_krb5_flags))) {
+ rv = KHM_ERROR_UNKNOWN;
+ }
+
+ /* Lookup common attributes */
+ if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KEY_ENCTYPE,
+ &attr_id_key_enctype))) {
+ rv = KHM_ERROR_UNKNOWN;
+ }
+
+ if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_TKT_ENCTYPE,
+ &attr_id_tkt_enctype))) {
+ rv = KHM_ERROR_UNKNOWN;
+ }
+
+ if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_ADDR_LIST,
+ &attr_id_addr_list))) {
+ rv = KHM_ERROR_UNKNOWN;
+ }
+
+ if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_FLAGS,
+ &attr_id_krb5_flags))) {
+ rv = KHM_ERROR_UNKNOWN;
+ }
+
+ krb4_initialized = TRUE;
+
+ khm_krb4_set_def_tkt_string();
+
+ khm_krb4_list_tickets();
+#endif
+ }
+ break;
+
+ case KMSG_SYSTEM_EXIT:
+#ifdef _WIN64
+ /* See above. On 64-bit platforms, we don't support Krb4 at
+ all. */
+ return 0;
+#else
+ if(credtype_id_krb4 >= 0)
+ {
+ /* basically just unregister the credential type */
+ kcdb_credtype_unregister(credtype_id_krb4);
+
+ kcdb_credset_delete(krb4_credset);
+ }
+ break;
+#endif
+ }
+
+ return rv;
+}
+
+khm_int32 KHMAPI
+krb4_msg_cred(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam)
+{
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+
+ switch(msg_subtype) {
+ case KMSG_CRED_REFRESH:
+ {
+ khm_krb4_list_tickets();
+ }
+ break;
+
+ case KMSG_CRED_DESTROY_CREDS:
+ {
+ khui_action_context * ctx;
+ khm_handle credset;
+ khm_size nc_root = 0;
+ khm_size nc_sel = 0;
+
+ ctx = (khui_action_context *) vparam;
+
+ /* if all krb4 tickets are selected, then we destroy all
+ of them. Otherwise, we do nothing. */
+
+ kcdb_credset_create(&credset);
+
+ kcdb_credset_extract(credset, ctx->credset,
+ NULL, credtype_id_krb4);
+ kcdb_credset_get_size(credset, &nc_sel);
+
+ kcdb_credset_flush(credset);
+
+ kcdb_credset_extract(credset, NULL,
+ NULL, credtype_id_krb4);
+ kcdb_credset_get_size(credset, &nc_root);
+
+ kcdb_credset_delete(credset);
+
+ if (nc_root == nc_sel) {
+ khm_krb4_kdestroy();
+ }
+ }
+ break;
+
+ default:
+ if (IS_CRED_ACQ_MSG(msg_subtype))
+ return krb4_msg_newcred(msg_type, msg_subtype, uparam, vparam);
+ }
+
+ return rv;
+}
+
+khm_int32 KHMAPI
+krb4_cb(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam)
+{
+ switch(msg_type) {
+ case KMSG_SYSTEM:
+ return krb4_msg_system(msg_type, msg_subtype, uparam, vparam);
+ case KMSG_CRED:
+ return krb4_msg_cred(msg_type, msg_subtype, uparam, vparam);
+ }
+ return KHM_ERROR_SUCCESS;
+}
diff --git a/src/windows/identity/plugins/krb4/krbcred.h b/src/windows/identity/plugins/krb4/krbcred.h
index 7c3b31a13..53e22c892 100644
--- a/src/windows/identity/plugins/krb4/krbcred.h
+++ b/src/windows/identity/plugins/krb4/krbcred.h
@@ -1,136 +1,136 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef __KHIMAIRA_KRBAFSCRED_H
-#define __KHIMAIRA_KRBAFSCRED_H
-
-#include<windows.h>
-
-#define KHERR_FACILITY L"Krb4Cred"
-#define KHERR_FACILITY_ID 65
-#define KHERR_HMODULE hResModule
-
-#include<netidmgr.h>
-
-#include<krb4funcs.h>
-#include<krb5common.h>
-#include<errorfuncs.h>
-#include<dynimport.h>
-
-#include<langres.h>
-#include<krb4_msgs.h>
-
-#define TYPENAME_ENCTYPE L"EncType"
-#define TYPENAME_ADDR_LIST L"AddrList"
-#define TYPENAME_KRB5_FLAGS L"Krb5Flags"
-
-#define ATTRNAME_KEY_ENCTYPE L"KeyEncType"
-#define ATTRNAME_TKT_ENCTYPE L"TktEncType"
-#define ATTRNAME_ADDR_LIST L"AddrList"
-#define ATTRNAME_KRB5_FLAGS L"Krb5Flags"
-#define ATTRNAME_RENEW_TILL L"RenewTill"
-#define ATTRNAME_RENEW_FOR L"RenewFor"
-
-void init_krb();
-void exit_krb();
-KHMEXP khm_int32 KHMAPI init_module(kmm_module h_module);
-KHMEXP khm_int32 KHMAPI exit_module(kmm_module h_module);
-
-/* globals */
-extern kmm_module h_khModule;
-extern HMODULE hResModule;
-extern HINSTANCE hInstance;
-
-extern khm_int32 type_id_enctype;
-extern khm_int32 type_id_addr_list;
-extern khm_int32 type_id_krb5_flags;
-
-extern khm_int32 attr_id_key_enctype;
-extern khm_int32 attr_id_tkt_enctype;
-extern khm_int32 attr_id_addr_list;
-extern khm_int32 attr_id_krb5_flags;
-extern khm_int32 attr_id_renew_till;
-extern khm_int32 attr_id_renew_for;
-
-/* Configuration spaces */
-#define CSNAME_KRB4CRED L"Krb4Cred"
-#define CSNAME_PARAMS L"Parameters"
-
-/* plugin constants */
-#define KRB4_PLUGIN_NAME L"Krb4Cred"
-
-#define KRB4_PLUGIN_DEPS L"Krb5Cred\0"
-
-#define KRB4_CREDTYPE_NAME L"Krb4Cred"
-
-#define KRB5_CREDTYPE_NAME L"Krb5Cred"
-
-#define KRB4_CONFIG_NODE_NAME L"Krb4Config"
-
-#define KRB4_ID_CONFIG_NODE_NAME L"Krb4IdentConfig"
-#define KRB4_IDS_CONFIG_NODE_NAME L"Krb4IdentsConfig"
-
-extern khm_handle csp_plugins;
-extern khm_handle csp_krbcred;
-extern khm_handle csp_params;
-
-extern kconf_schema schema_krbconfig[];
-
-/* other globals */
-extern khm_int32 credtype_id_krb4;
-extern khm_int32 credtype_id_krb5;
-
-extern khm_boolean krb4_initialized;
-
-extern khm_handle krb4_credset;
-
-/* plugin callbacks */
-khm_int32 KHMAPI
-krb4_cb(khm_int32 msg_type, khm_int32 msg_subtype,
- khm_ui_4 uparam, void * vparam);
-
-INT_PTR CALLBACK
-krb4_confg_proc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam);
-
-INT_PTR CALLBACK
-krb4_ids_config_proc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam);
-
-INT_PTR CALLBACK
-krb4_id_config_proc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam);
-
-khm_int32
-krb4_msg_newcred(khm_int32 msg_type, khm_int32 msg_subtype,
- khm_ui_4 uparam, void * vparam);
-#endif
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef __KHIMAIRA_KRBAFSCRED_H
+#define __KHIMAIRA_KRBAFSCRED_H
+
+#include<windows.h>
+
+#define KHERR_FACILITY L"Krb4Cred"
+#define KHERR_FACILITY_ID 65
+#define KHERR_HMODULE hResModule
+
+#include<netidmgr.h>
+
+#include<krb4funcs.h>
+#include<krb5common.h>
+#include<errorfuncs.h>
+#include<dynimport.h>
+
+#include<langres.h>
+#include<krb4_msgs.h>
+
+#define TYPENAME_ENCTYPE L"EncType"
+#define TYPENAME_ADDR_LIST L"AddrList"
+#define TYPENAME_KRB5_FLAGS L"Krb5Flags"
+
+#define ATTRNAME_KEY_ENCTYPE L"KeyEncType"
+#define ATTRNAME_TKT_ENCTYPE L"TktEncType"
+#define ATTRNAME_ADDR_LIST L"AddrList"
+#define ATTRNAME_KRB5_FLAGS L"Krb5Flags"
+#define ATTRNAME_RENEW_TILL L"RenewTill"
+#define ATTRNAME_RENEW_FOR L"RenewFor"
+
+void init_krb();
+void exit_krb();
+KHMEXP khm_int32 KHMAPI init_module(kmm_module h_module);
+KHMEXP khm_int32 KHMAPI exit_module(kmm_module h_module);
+
+/* globals */
+extern kmm_module h_khModule;
+extern HMODULE hResModule;
+extern HINSTANCE hInstance;
+
+extern khm_int32 type_id_enctype;
+extern khm_int32 type_id_addr_list;
+extern khm_int32 type_id_krb5_flags;
+
+extern khm_int32 attr_id_key_enctype;
+extern khm_int32 attr_id_tkt_enctype;
+extern khm_int32 attr_id_addr_list;
+extern khm_int32 attr_id_krb5_flags;
+extern khm_int32 attr_id_renew_till;
+extern khm_int32 attr_id_renew_for;
+
+/* Configuration spaces */
+#define CSNAME_KRB4CRED L"Krb4Cred"
+#define CSNAME_PARAMS L"Parameters"
+
+/* plugin constants */
+#define KRB4_PLUGIN_NAME L"Krb4Cred"
+
+#define KRB4_PLUGIN_DEPS L"Krb5Cred\0"
+
+#define KRB4_CREDTYPE_NAME L"Krb4Cred"
+
+#define KRB5_CREDTYPE_NAME L"Krb5Cred"
+
+#define KRB4_CONFIG_NODE_NAME L"Krb4Config"
+
+#define KRB4_ID_CONFIG_NODE_NAME L"Krb4IdentConfig"
+#define KRB4_IDS_CONFIG_NODE_NAME L"Krb4IdentsConfig"
+
+extern khm_handle csp_plugins;
+extern khm_handle csp_krbcred;
+extern khm_handle csp_params;
+
+extern kconf_schema schema_krbconfig[];
+
+/* other globals */
+extern khm_int32 credtype_id_krb4;
+extern khm_int32 credtype_id_krb5;
+
+extern khm_boolean krb4_initialized;
+
+extern khm_handle krb4_credset;
+
+/* plugin callbacks */
+khm_int32 KHMAPI
+krb4_cb(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam);
+
+INT_PTR CALLBACK
+krb4_confg_proc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam);
+
+INT_PTR CALLBACK
+krb4_ids_config_proc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam);
+
+INT_PTR CALLBACK
+krb4_id_config_proc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam);
+
+khm_int32
+krb4_msg_newcred(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam);
+#endif
diff --git a/src/windows/identity/plugins/krb4/langres.h b/src/windows/identity/plugins/krb4/langres.h
index c78ae4167..5c0e46f9a 100644
--- a/src/windows/identity/plugins/krb4/langres.h
+++ b/src/windows/identity/plugins/krb4/langres.h
@@ -1,49 +1,49 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by C:\work\pismere\athena\auth\krb5\src\windows\identity\plugins\krb4\lang\en_us\langres.rc
-//
-#define IDD_NC_KRB4 103
-#define IDS_PLUGIN_DESC 103
-#define IDD_CFG_KRB4 104
-#define IDS_NC_K4_SHORT 104
-#define IDS_ERR_REALM 105
-#define IDD_CFG_IDS_KRB4 105
-#define IDS_ERR_PRINCIPAL 106
-#define IDD_CFG_ID_KRB4 106
-#define IDS_ERR_INVINST 107
-#define IDI_PLUGIN 107
-#define IDS_ERR_PWINTKT 108
-#define IDS_CT_DISABLED 109
-#define IDS_CT_TGTFOR 110
-#define IDS_METHOD_AUTO 111
-#define IDS_METHOD_PWD 112
-#define IDS_METHOD_K524 113
-#define IDS_CFG_IDS_KRB4_SHORT 114
-#define IDS_KRB4_SHORT_DESC 128
-#define IDS_KRB4_LONG_DESC 129
-#define IDS_CFG_KRB4_LONG 135
-#define IDS_CFG_KRB4_SHORT 136
-#define IDC_CFG_LBL_CACHE 1025
-#define IDC_CFG_LBL_CFGFILE 1026
-#define IDC_CFG_LBL_RLMPATH 1027
-#define IDC_CFG_CACHE 1028
-#define IDC_CFG_CFGPATH 1029
-#define IDC_CFG_RLMPATH 1030
-#define IDC_CFG_CFGBROW 1031
-#define IDC_CFG_RLMBROW 1032
-#define IDC_NCK4_OBTAIN 1033
-#define IDC_NCK4_AUTO 1034
-#define IDC_NCK4_K524 1035
-#define IDC_NCK4_PWD 1036
-#define IDC_CFG_GETTIX 1037
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 108
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1043
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by C:\work\pismere\athena\auth\krb5\src\windows\identity\plugins\krb4\lang\en_us\langres.rc
+//
+#define IDD_NC_KRB4 103
+#define IDS_PLUGIN_DESC 103
+#define IDD_CFG_KRB4 104
+#define IDS_NC_K4_SHORT 104
+#define IDS_ERR_REALM 105
+#define IDD_CFG_IDS_KRB4 105
+#define IDS_ERR_PRINCIPAL 106
+#define IDD_CFG_ID_KRB4 106
+#define IDS_ERR_INVINST 107
+#define IDI_PLUGIN 107
+#define IDS_ERR_PWINTKT 108
+#define IDS_CT_DISABLED 109
+#define IDS_CT_TGTFOR 110
+#define IDS_METHOD_AUTO 111
+#define IDS_METHOD_PWD 112
+#define IDS_METHOD_K524 113
+#define IDS_CFG_IDS_KRB4_SHORT 114
+#define IDS_KRB4_SHORT_DESC 128
+#define IDS_KRB4_LONG_DESC 129
+#define IDS_CFG_KRB4_LONG 135
+#define IDS_CFG_KRB4_SHORT 136
+#define IDC_CFG_LBL_CACHE 1025
+#define IDC_CFG_LBL_CFGFILE 1026
+#define IDC_CFG_LBL_RLMPATH 1027
+#define IDC_CFG_CACHE 1028
+#define IDC_CFG_CFGPATH 1029
+#define IDC_CFG_RLMPATH 1030
+#define IDC_CFG_CFGBROW 1031
+#define IDC_CFG_RLMBROW 1032
+#define IDC_NCK4_OBTAIN 1033
+#define IDC_NCK4_AUTO 1034
+#define IDC_NCK4_K524 1035
+#define IDC_NCK4_PWD 1036
+#define IDC_CFG_GETTIX 1037
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 108
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1043
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/windows/identity/plugins/krb5/datarep.c b/src/windows/identity/plugins/krb5/datarep.c
index 92eabf4da..5c292e478 100644
--- a/src/windows/identity/plugins/krb5/datarep.c
+++ b/src/windows/identity/plugins/krb5/datarep.c
@@ -1,407 +1,407 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Data representation and related functions */
-
-#include<winsock2.h>
-#include<krbcred.h>
-#include<krb5.h>
-#include<kherror.h>
-#include<strsafe.h>
-#include<assert.h>
-
-khm_int32 KHMAPI
-enctype_toString(const void * data, khm_size cbdata,
- wchar_t *destbuf, khm_size *pcbdestbuf,
- khm_int32 flags)
-{
- int resid = 0;
- int etype;
- wchar_t buf[256];
- size_t cblength;
-
- if(cbdata != sizeof(khm_int32))
- return KHM_ERROR_INVALID_PARAM;
-
- etype = *((khm_int32 *) data);
-
- switch(etype) {
- case ENCTYPE_NULL:
- resid = IDS_ETYPE_NULL;
- break;
-
- case ENCTYPE_DES_CBC_CRC:
- resid = IDS_ETYPE_DES_CBC_CRC;
- break;
-
- case ENCTYPE_DES_CBC_MD4:
- resid = IDS_ETYPE_DES_CBC_MD4;
- break;
-
- case ENCTYPE_DES_CBC_MD5:
- resid = IDS_ETYPE_DES_CBC_MD5;
- break;
-
- case ENCTYPE_DES_CBC_RAW:
- resid = IDS_ETYPE_DES_CBC_RAW;
- break;
-
- case ENCTYPE_DES3_CBC_SHA:
- resid = IDS_ETYPE_DES3_CBC_SHA;
- break;
-
- case ENCTYPE_DES3_CBC_RAW:
- resid = IDS_ETYPE_DES3_CBC_RAW;
- break;
-
- case ENCTYPE_DES_HMAC_SHA1:
- resid = IDS_ETYPE_DES_HMAC_SHA1;
- break;
-
- case ENCTYPE_DES3_CBC_SHA1:
- resid = IDS_ETYPE_DES3_CBC_SHA1;
- break;
-
- case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
- resid = IDS_ETYPE_AES128_CTS_HMAC_SHA1_96;
- break;
-
- case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
- resid = IDS_ETYPE_AES256_CTS_HMAC_SHA1_96;
- break;
-
- case ENCTYPE_ARCFOUR_HMAC:
- resid = IDS_ETYPE_ARCFOUR_HMAC;
- break;
-
- case ENCTYPE_ARCFOUR_HMAC_EXP:
- resid = IDS_ETYPE_ARCFOUR_HMAC_EXP;
- break;
-
- case ENCTYPE_UNKNOWN:
- resid = IDS_ETYPE_UNKNOWN;
- break;
-
-#if 0
- case ENCTYPE_LOCAL_DES3_HMAC_SHA1:
- resid = IDS_ETYPE_LOCAL_DES3_HMAC_SHA1;
- break;
-
- case ENCTYPE_LOCAL_RC4_MD4:
- resid = IDS_ETYPE_LOCAL_RC4_MD4;
- break;
-#endif
- }
-
- if(resid != 0) {
- LoadString(hResModule, (UINT) resid, buf, ARRAYLENGTH(buf));
- } else {
- StringCbPrintf(buf, sizeof(buf), L"#%d", etype);
- }
-
- StringCbLength(buf, ARRAYLENGTH(buf), &cblength);
- cblength += sizeof(wchar_t);
-
- if(!destbuf || *pcbdestbuf < cblength) {
- *pcbdestbuf = cblength;
- return KHM_ERROR_TOO_LONG;
- } else {
- StringCbCopy(destbuf, *pcbdestbuf, buf);
- *pcbdestbuf = cblength;
- return KHM_ERROR_SUCCESS;
- }
-}
-
-khm_int32 KHMAPI
-addr_list_comp(const void *d1, khm_size cb_d1,
- const void *d2, khm_size cb_d2)
-{
- if (cb_d1 < cb_d2)
- return -1;
- if (cb_d1 > cb_d2)
- return 1;
- return memcmp(d1, d2, cb_d1);
-}
-
-khm_int32 KHMAPI
-addr_list_toString(const void *d, khm_size cb_d,
- wchar_t *buf, khm_size *pcb_buf,
- khm_int32 flags)
-{
- wchar_t tbuf[2048];
- wchar_t * strpos;
- khm_size cbleft;
- size_t t;
- k5_serial_address * addrs;
-
- if (cb_d == 0 || d == NULL) {
- tbuf[0] = L'\0';
- } else {
- addrs = (k5_serial_address *) d;
-
- strpos = tbuf;
- cbleft = sizeof(tbuf);
- tbuf[0] = L'\0';
-
- while (TRUE) {
- if (cb_d < sizeof(*addrs) ||
- addrs->magic != K5_SERIAL_ADDRESS_MAGIC ||
- cb_d < sizeof(*addrs) + addrs->length - sizeof(khm_int32))
- break;
-
- if (strpos != tbuf) {
- if (FAILED(StringCbCatEx(strpos, cbleft, L" ",
- &strpos, &cbleft,
- 0)))
- break;
- }
-
-#ifdef DEBUG
- assert(*strpos == L'\0');
-#endif
-
- one_addr(addrs, strpos, cbleft);
-
- t = 0;
- if (FAILED(StringCchLength(strpos,
- cbleft / sizeof(wchar_t),
- &t)))
- break;
-
- strpos += t;
- cbleft -= t * sizeof(wchar_t);
-
- t = sizeof(*addrs) + addrs->length - sizeof(khm_int32);
- addrs = (k5_serial_address *) BYTEOFFSET(addrs, t);
- cb_d -= t;
- }
- }
-
- StringCbLength(tbuf, sizeof(tbuf), &t);
-
- if (!buf || *pcb_buf < t) {
- *pcb_buf = t;
- return KHM_ERROR_TOO_LONG;
- }
-
- StringCbCopy(buf, *pcb_buf, tbuf);
- *pcb_buf = t;
-
- return KHM_ERROR_SUCCESS;
-}
-
-khm_int32 KHMAPI
-krb5flags_toString(const void *d,
- khm_size cb_d,
- wchar_t *buf,
- khm_size *pcb_buf,
- khm_int32 f)
-{
- wchar_t sbuf[32];
- int i = 0;
- khm_size cb;
- khm_int32 flags;
-
- flags = *((khm_int32 *) d);
-
- if (flags & TKT_FLG_FORWARDABLE)
- sbuf[i++] = L'F';
-
- if (flags & TKT_FLG_FORWARDED)
- sbuf[i++] = L'f';
-
- if (flags & TKT_FLG_PROXIABLE)
- sbuf[i++] = L'P';
-
- if (flags & TKT_FLG_PROXY)
- sbuf[i++] = L'p';
-
- if (flags & TKT_FLG_MAY_POSTDATE)
- sbuf[i++] = L'D';
-
- if (flags & TKT_FLG_POSTDATED)
- sbuf[i++] = L'd';
-
- if (flags & TKT_FLG_INVALID)
- sbuf[i++] = L'i';
-
- if (flags & TKT_FLG_RENEWABLE)
- sbuf[i++] = L'R';
-
- if (flags & TKT_FLG_INITIAL)
- sbuf[i++] = L'I';
-
- if (flags & TKT_FLG_HW_AUTH)
- sbuf[i++] = L'H';
-
- if (flags & TKT_FLG_PRE_AUTH)
- sbuf[i++] = L'A';
-
- sbuf[i++] = L'\0';
-
- cb = i * sizeof(wchar_t);
-
- if (!buf || *pcb_buf < cb) {
- *pcb_buf = cb;
- return KHM_ERROR_TOO_LONG;
- } else {
- StringCbCopy(buf, *pcb_buf, sbuf);
- *pcb_buf = cb;
- return KHM_ERROR_SUCCESS;
- }
-}
-
-khm_int32 KHMAPI
-kvno_toString(const void * data, khm_size cbdata,
- wchar_t *destbuf, khm_size *pcbdestbuf,
- khm_int32 flags)
-{
- int resid = 0;
- int kvno;
- wchar_t buf[256];
- size_t cblength;
-
- if (cbdata != sizeof(khm_int32))
- return KHM_ERROR_INVALID_PARAM;
-
- kvno = *((khm_int32 *) data);
-
- StringCbPrintf(buf, sizeof(buf), L"#%d", kvno);
-
- StringCbLength(buf, ARRAYLENGTH(buf), &cblength);
- cblength += sizeof(wchar_t);
-
- if (!destbuf || *pcbdestbuf < cblength) {
- *pcbdestbuf = cblength;
- return KHM_ERROR_TOO_LONG;
- } else {
- StringCbCopy(destbuf, *pcbdestbuf, buf);
- *pcbdestbuf = cblength;
- return KHM_ERROR_SUCCESS;
- }
-}
-
-khm_int32
-serialize_krb5_addresses(krb5_address ** a, void * buf, size_t * pcbbuf)
-{
- k5_serial_address * addr;
- khm_size cb_req;
- khm_size t;
- khm_boolean overflow = FALSE;
-
- addr = (k5_serial_address *) buf;
- cb_req = 0;
-
- for(; *a; a++) {
- t = sizeof(k5_serial_address) + (*a)->length - sizeof(khm_int32);
- cb_req += t;
- if (cb_req < *pcbbuf) {
- addr->magic = K5_SERIAL_ADDRESS_MAGIC;
- addr->addrtype = (*a)->addrtype;
- addr->length = (*a)->length;
- memcpy(&addr->data, (*a)->contents, (*a)->length);
-
- addr = (k5_serial_address *) BYTEOFFSET(addr, t);
- } else {
- overflow = TRUE;
- }
- }
-
- *pcbbuf = cb_req;
-
- return (overflow)?KHM_ERROR_TOO_LONG: KHM_ERROR_SUCCESS;
-}
-
-void
-one_addr(k5_serial_address *a, wchar_t * buf, khm_size cbbuf)
-{
- wchar_t retstr[256];
- struct hostent *h = NULL;
- int no_resolve = 1;
-
- retstr[0] = L'\0';
-
- if ((a->addrtype == ADDRTYPE_INET && a->length == 4)
-#ifdef AF_INET6
- || (a->addrtype == ADDRTYPE_INET6 && a->length == 16)
-#endif
- )
- {
- int af = AF_INET;
-#ifdef AF_INET6
- if (a->addrtype == ADDRTYPE_INET6)
- af = AF_INET6;
-#endif
- if (!no_resolve) {
-#ifdef HAVE_GETIPNODEBYADDR
- int err;
- h = getipnodebyaddr(&a->data, a->length, af, &err);
- if (h) {
- StringCbPrintf(retstr, sizeof(retstr), L"%S", h->h_name);
- freehostent(h);
- }
- else
- h = gethostbyaddr(&a->data, a->length, af);
- if (h) {
- StringCbPrintf(retstr, sizeof(retstr), L"%S", h->h_name);
- }
-#endif
- if (h)
- goto _copy_string;
- }
- if (no_resolve || !h) {
-#ifdef HAVE_INET_NTOP
- char buf[46];
- const char *name = inet_ntop(a->addrtype, &a->data, buf, sizeof(buf));
- if (name) {
- StringCbPrintf(retstr, sizeof(retstr), L"%S", name);
- goto _copy_string;
- }
-#else
- if (a->addrtype == ADDRTYPE_INET) {
- khm_ui_4 addr = a->data;
- StringCbPrintf(retstr, sizeof(retstr),
- L"%d.%d.%d.%d",
- (int) (addr & 0xff),
- (int) ((addr >> 8) & 0xff),
- (int) ((addr >> 16)& 0xff),
- (int) ((addr >> 24)& 0xff));
- goto _copy_string;
- }
-#endif
- }
- }
-
- {
- wchar_t tmpfmt[128];
- LoadString(hResModule, IDS_UNK_ADDR_FMT, tmpfmt, sizeof(tmpfmt)/sizeof(wchar_t));
- StringCbPrintf(retstr, sizeof(retstr), tmpfmt, a->addrtype);
- }
-
- _copy_string:
- StringCbCopy(buf, cbbuf, retstr);
-}
-
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+/* Data representation and related functions */
+
+#include<winsock2.h>
+#include<krbcred.h>
+#include<krb5.h>
+#include<kherror.h>
+#include<strsafe.h>
+#include<assert.h>
+
+khm_int32 KHMAPI
+enctype_toString(const void * data, khm_size cbdata,
+ wchar_t *destbuf, khm_size *pcbdestbuf,
+ khm_int32 flags)
+{
+ int resid = 0;
+ int etype;
+ wchar_t buf[256];
+ size_t cblength;
+
+ if(cbdata != sizeof(khm_int32))
+ return KHM_ERROR_INVALID_PARAM;
+
+ etype = *((khm_int32 *) data);
+
+ switch(etype) {
+ case ENCTYPE_NULL:
+ resid = IDS_ETYPE_NULL;
+ break;
+
+ case ENCTYPE_DES_CBC_CRC:
+ resid = IDS_ETYPE_DES_CBC_CRC;
+ break;
+
+ case ENCTYPE_DES_CBC_MD4:
+ resid = IDS_ETYPE_DES_CBC_MD4;
+ break;
+
+ case ENCTYPE_DES_CBC_MD5:
+ resid = IDS_ETYPE_DES_CBC_MD5;
+ break;
+
+ case ENCTYPE_DES_CBC_RAW:
+ resid = IDS_ETYPE_DES_CBC_RAW;
+ break;
+
+ case ENCTYPE_DES3_CBC_SHA:
+ resid = IDS_ETYPE_DES3_CBC_SHA;
+ break;
+
+ case ENCTYPE_DES3_CBC_RAW:
+ resid = IDS_ETYPE_DES3_CBC_RAW;
+ break;
+
+ case ENCTYPE_DES_HMAC_SHA1:
+ resid = IDS_ETYPE_DES_HMAC_SHA1;
+ break;
+
+ case ENCTYPE_DES3_CBC_SHA1:
+ resid = IDS_ETYPE_DES3_CBC_SHA1;
+ break;
+
+ case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
+ resid = IDS_ETYPE_AES128_CTS_HMAC_SHA1_96;
+ break;
+
+ case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
+ resid = IDS_ETYPE_AES256_CTS_HMAC_SHA1_96;
+ break;
+
+ case ENCTYPE_ARCFOUR_HMAC:
+ resid = IDS_ETYPE_ARCFOUR_HMAC;
+ break;
+
+ case ENCTYPE_ARCFOUR_HMAC_EXP:
+ resid = IDS_ETYPE_ARCFOUR_HMAC_EXP;
+ break;
+
+ case ENCTYPE_UNKNOWN:
+ resid = IDS_ETYPE_UNKNOWN;
+ break;
+
+#if 0
+ case ENCTYPE_LOCAL_DES3_HMAC_SHA1:
+ resid = IDS_ETYPE_LOCAL_DES3_HMAC_SHA1;
+ break;
+
+ case ENCTYPE_LOCAL_RC4_MD4:
+ resid = IDS_ETYPE_LOCAL_RC4_MD4;
+ break;
+#endif
+ }
+
+ if(resid != 0) {
+ LoadString(hResModule, (UINT) resid, buf, ARRAYLENGTH(buf));
+ } else {
+ StringCbPrintf(buf, sizeof(buf), L"#%d", etype);
+ }
+
+ StringCbLength(buf, ARRAYLENGTH(buf), &cblength);
+ cblength += sizeof(wchar_t);
+
+ if(!destbuf || *pcbdestbuf < cblength) {
+ *pcbdestbuf = cblength;
+ return KHM_ERROR_TOO_LONG;
+ } else {
+ StringCbCopy(destbuf, *pcbdestbuf, buf);
+ *pcbdestbuf = cblength;
+ return KHM_ERROR_SUCCESS;
+ }
+}
+
+khm_int32 KHMAPI
+addr_list_comp(const void *d1, khm_size cb_d1,
+ const void *d2, khm_size cb_d2)
+{
+ if (cb_d1 < cb_d2)
+ return -1;
+ if (cb_d1 > cb_d2)
+ return 1;
+ return memcmp(d1, d2, cb_d1);
+}
+
+khm_int32 KHMAPI
+addr_list_toString(const void *d, khm_size cb_d,
+ wchar_t *buf, khm_size *pcb_buf,
+ khm_int32 flags)
+{
+ wchar_t tbuf[2048];
+ wchar_t * strpos;
+ khm_size cbleft;
+ size_t t;
+ k5_serial_address * addrs;
+
+ if (cb_d == 0 || d == NULL) {
+ tbuf[0] = L'\0';
+ } else {
+ addrs = (k5_serial_address *) d;
+
+ strpos = tbuf;
+ cbleft = sizeof(tbuf);
+ tbuf[0] = L'\0';
+
+ while (TRUE) {
+ if (cb_d < sizeof(*addrs) ||
+ addrs->magic != K5_SERIAL_ADDRESS_MAGIC ||
+ cb_d < sizeof(*addrs) + addrs->length - sizeof(khm_int32))
+ break;
+
+ if (strpos != tbuf) {
+ if (FAILED(StringCbCatEx(strpos, cbleft, L" ",
+ &strpos, &cbleft,
+ 0)))
+ break;
+ }
+
+#ifdef DEBUG
+ assert(*strpos == L'\0');
+#endif
+
+ one_addr(addrs, strpos, cbleft);
+
+ t = 0;
+ if (FAILED(StringCchLength(strpos,
+ cbleft / sizeof(wchar_t),
+ &t)))
+ break;
+
+ strpos += t;
+ cbleft -= t * sizeof(wchar_t);
+
+ t = sizeof(*addrs) + addrs->length - sizeof(khm_int32);
+ addrs = (k5_serial_address *) BYTEOFFSET(addrs, t);
+ cb_d -= t;
+ }
+ }
+
+ StringCbLength(tbuf, sizeof(tbuf), &t);
+
+ if (!buf || *pcb_buf < t) {
+ *pcb_buf = t;
+ return KHM_ERROR_TOO_LONG;
+ }
+
+ StringCbCopy(buf, *pcb_buf, tbuf);
+ *pcb_buf = t;
+
+ return KHM_ERROR_SUCCESS;
+}
+
+khm_int32 KHMAPI
+krb5flags_toString(const void *d,
+ khm_size cb_d,
+ wchar_t *buf,
+ khm_size *pcb_buf,
+ khm_int32 f)
+{
+ wchar_t sbuf[32];
+ int i = 0;
+ khm_size cb;
+ khm_int32 flags;
+
+ flags = *((khm_int32 *) d);
+
+ if (flags & TKT_FLG_FORWARDABLE)
+ sbuf[i++] = L'F';
+
+ if (flags & TKT_FLG_FORWARDED)
+ sbuf[i++] = L'f';
+
+ if (flags & TKT_FLG_PROXIABLE)
+ sbuf[i++] = L'P';
+
+ if (flags & TKT_FLG_PROXY)
+ sbuf[i++] = L'p';
+
+ if (flags & TKT_FLG_MAY_POSTDATE)
+ sbuf[i++] = L'D';
+
+ if (flags & TKT_FLG_POSTDATED)
+ sbuf[i++] = L'd';
+
+ if (flags & TKT_FLG_INVALID)
+ sbuf[i++] = L'i';
+
+ if (flags & TKT_FLG_RENEWABLE)
+ sbuf[i++] = L'R';
+
+ if (flags & TKT_FLG_INITIAL)
+ sbuf[i++] = L'I';
+
+ if (flags & TKT_FLG_HW_AUTH)
+ sbuf[i++] = L'H';
+
+ if (flags & TKT_FLG_PRE_AUTH)
+ sbuf[i++] = L'A';
+
+ sbuf[i++] = L'\0';
+
+ cb = i * sizeof(wchar_t);
+
+ if (!buf || *pcb_buf < cb) {
+ *pcb_buf = cb;
+ return KHM_ERROR_TOO_LONG;
+ } else {
+ StringCbCopy(buf, *pcb_buf, sbuf);
+ *pcb_buf = cb;
+ return KHM_ERROR_SUCCESS;
+ }
+}
+
+khm_int32 KHMAPI
+kvno_toString(const void * data, khm_size cbdata,
+ wchar_t *destbuf, khm_size *pcbdestbuf,
+ khm_int32 flags)
+{
+ int resid = 0;
+ int kvno;
+ wchar_t buf[256];
+ size_t cblength;
+
+ if (cbdata != sizeof(khm_int32))
+ return KHM_ERROR_INVALID_PARAM;
+
+ kvno = *((khm_int32 *) data);
+
+ StringCbPrintf(buf, sizeof(buf), L"#%d", kvno);
+
+ StringCbLength(buf, ARRAYLENGTH(buf), &cblength);
+ cblength += sizeof(wchar_t);
+
+ if (!destbuf || *pcbdestbuf < cblength) {
+ *pcbdestbuf = cblength;
+ return KHM_ERROR_TOO_LONG;
+ } else {
+ StringCbCopy(destbuf, *pcbdestbuf, buf);
+ *pcbdestbuf = cblength;
+ return KHM_ERROR_SUCCESS;
+ }
+}
+
+khm_int32
+serialize_krb5_addresses(krb5_address ** a, void * buf, size_t * pcbbuf)
+{
+ k5_serial_address * addr;
+ khm_size cb_req;
+ khm_size t;
+ khm_boolean overflow = FALSE;
+
+ addr = (k5_serial_address *) buf;
+ cb_req = 0;
+
+ for(; *a; a++) {
+ t = sizeof(k5_serial_address) + (*a)->length - sizeof(khm_int32);
+ cb_req += t;
+ if (cb_req < *pcbbuf) {
+ addr->magic = K5_SERIAL_ADDRESS_MAGIC;
+ addr->addrtype = (*a)->addrtype;
+ addr->length = (*a)->length;
+ memcpy(&addr->data, (*a)->contents, (*a)->length);
+
+ addr = (k5_serial_address *) BYTEOFFSET(addr, t);
+ } else {
+ overflow = TRUE;
+ }
+ }
+
+ *pcbbuf = cb_req;
+
+ return (overflow)?KHM_ERROR_TOO_LONG: KHM_ERROR_SUCCESS;
+}
+
+void
+one_addr(k5_serial_address *a, wchar_t * buf, khm_size cbbuf)
+{
+ wchar_t retstr[256];
+ struct hostent *h = NULL;
+ int no_resolve = 1;
+
+ retstr[0] = L'\0';
+
+ if ((a->addrtype == ADDRTYPE_INET && a->length == 4)
+#ifdef AF_INET6
+ || (a->addrtype == ADDRTYPE_INET6 && a->length == 16)
+#endif
+ )
+ {
+ int af = AF_INET;
+#ifdef AF_INET6
+ if (a->addrtype == ADDRTYPE_INET6)
+ af = AF_INET6;
+#endif
+ if (!no_resolve) {
+#ifdef HAVE_GETIPNODEBYADDR
+ int err;
+ h = getipnodebyaddr(&a->data, a->length, af, &err);
+ if (h) {
+ StringCbPrintf(retstr, sizeof(retstr), L"%S", h->h_name);
+ freehostent(h);
+ }
+ else
+ h = gethostbyaddr(&a->data, a->length, af);
+ if (h) {
+ StringCbPrintf(retstr, sizeof(retstr), L"%S", h->h_name);
+ }
+#endif
+ if (h)
+ goto _copy_string;
+ }
+ if (no_resolve || !h) {
+#ifdef HAVE_INET_NTOP
+ char buf[46];
+ const char *name = inet_ntop(a->addrtype, &a->data, buf, sizeof(buf));
+ if (name) {
+ StringCbPrintf(retstr, sizeof(retstr), L"%S", name);
+ goto _copy_string;
+ }
+#else
+ if (a->addrtype == ADDRTYPE_INET) {
+ khm_ui_4 addr = a->data;
+ StringCbPrintf(retstr, sizeof(retstr),
+ L"%d.%d.%d.%d",
+ (int) (addr & 0xff),
+ (int) ((addr >> 8) & 0xff),
+ (int) ((addr >> 16)& 0xff),
+ (int) ((addr >> 24)& 0xff));
+ goto _copy_string;
+ }
+#endif
+ }
+ }
+
+ {
+ wchar_t tmpfmt[128];
+ LoadString(hResModule, IDS_UNK_ADDR_FMT, tmpfmt, sizeof(tmpfmt)/sizeof(wchar_t));
+ StringCbPrintf(retstr, sizeof(retstr), tmpfmt, a->addrtype);
+ }
+
+ _copy_string:
+ StringCbCopy(buf, cbbuf, retstr);
+}
+
diff --git a/src/windows/identity/plugins/krb5/datarep.h b/src/windows/identity/plugins/krb5/datarep.h
index 90f1923fa..d81e7b91e 100644
--- a/src/windows/identity/plugins/krb5/datarep.h
+++ b/src/windows/identity/plugins/krb5/datarep.h
@@ -1,76 +1,76 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef __KHIMAIRA_KRB_DATAREP_H
-#define __KHIMAIRA_KRB_DATAREP_H
-
-typedef struct tag_k5_serial_address {
- khm_int32 magic; /* should be K5_SERIAL_ADDRESS_MAGIC */
- khm_int32 addrtype; /* Address type. We only know what to
- do with ADDRTYPE_INET and
- ADDRTYPE_INET6 */
- khm_size length; /* number of bytes of data in [data].
- This should always be greater than
- sizeof(khm_int32) */
- khm_int32 data; /* actually, &data is the beginning of
- the data buffer that is [length]
- bytes long. */
-} k5_serial_address;
-
-#define K5_SERIAL_ADDRESS_MAGIC 0x44ce832d
-
-khm_int32 KHMAPI
-enctype_toString(const void * data, khm_size cbdata,
- wchar_t *destbuf, khm_size *pcbdestbuf,
- khm_int32 flags);
-
-khm_int32 KHMAPI
-addr_list_comp(const void *d1, khm_size cb_d1,
- const void *d2, khm_size cb_d2);
-
-khm_int32 KHMAPI
-addr_list_toString(const void *, khm_size, wchar_t *,
- khm_size *, khm_int32);
-
-khm_int32 KHMAPI
-krb5flags_toString(const void *, khm_size, wchar_t *,
- khm_size *, khm_int32);
-
-khm_int32 KHMAPI
-kvno_toString(const void * data, khm_size cbdata,
- wchar_t *destbuf, khm_size *pcbdestbuf,
- khm_int32 flags);
-
-khm_int32 KHMAPI
-renew_for_cb(khm_handle cred, khm_int32 id, void * buffer,
- khm_size * pcbsize);
-
-khm_int32
-serialize_krb5_addresses(krb5_address ** a, void * buf, size_t * pcbbuf);
-
-void
-one_addr(k5_serial_address *a, wchar_t * buf, khm_size cbbuf);
-#endif
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef __KHIMAIRA_KRB_DATAREP_H
+#define __KHIMAIRA_KRB_DATAREP_H
+
+typedef struct tag_k5_serial_address {
+ khm_int32 magic; /* should be K5_SERIAL_ADDRESS_MAGIC */
+ khm_int32 addrtype; /* Address type. We only know what to
+ do with ADDRTYPE_INET and
+ ADDRTYPE_INET6 */
+ khm_size length; /* number of bytes of data in [data].
+ This should always be greater than
+ sizeof(khm_int32) */
+ khm_int32 data; /* actually, &data is the beginning of
+ the data buffer that is [length]
+ bytes long. */
+} k5_serial_address;
+
+#define K5_SERIAL_ADDRESS_MAGIC 0x44ce832d
+
+khm_int32 KHMAPI
+enctype_toString(const void * data, khm_size cbdata,
+ wchar_t *destbuf, khm_size *pcbdestbuf,
+ khm_int32 flags);
+
+khm_int32 KHMAPI
+addr_list_comp(const void *d1, khm_size cb_d1,
+ const void *d2, khm_size cb_d2);
+
+khm_int32 KHMAPI
+addr_list_toString(const void *, khm_size, wchar_t *,
+ khm_size *, khm_int32);
+
+khm_int32 KHMAPI
+krb5flags_toString(const void *, khm_size, wchar_t *,
+ khm_size *, khm_int32);
+
+khm_int32 KHMAPI
+kvno_toString(const void * data, khm_size cbdata,
+ wchar_t *destbuf, khm_size *pcbdestbuf,
+ khm_int32 flags);
+
+khm_int32 KHMAPI
+renew_for_cb(khm_handle cred, khm_int32 id, void * buffer,
+ khm_size * pcbsize);
+
+khm_int32
+serialize_krb5_addresses(krb5_address ** a, void * buf, size_t * pcbbuf);
+
+void
+one_addr(k5_serial_address *a, wchar_t * buf, khm_size cbbuf);
+#endif
diff --git a/src/windows/identity/plugins/krb5/errorfuncs.c b/src/windows/identity/plugins/krb5/errorfuncs.c
index f631b3c0c..4c2d78c63 100644
--- a/src/windows/identity/plugins/krb5/errorfuncs.c
+++ b/src/windows/identity/plugins/krb5/errorfuncs.c
@@ -1,297 +1,297 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<kherror.h>
-
-extern void (__cdecl *pinitialize_krb_error_func)();
-extern void (__cdecl *pinitialize_kadm_error_table)();
-
-
-khm_int32 init_error_funcs()
-{
- return KHM_ERROR_SUCCESS;
-}
-
-khm_int32 exit_error_funcs()
-{
- return KHM_ERROR_SUCCESS;
-}
-
-#ifdef DEPRECATED_REMOVABLE
-HWND GetRootParent (HWND Child)
-{
- HWND Last;
- while (Child)
- {
- Last = Child;
- Child = GetParent (Child);
- }
- return Last;
-}
-#endif
-
-void khm_err_describe(long code, wchar_t * buf, khm_size cbbuf,
- DWORD * suggestion,
- kherr_suggestion * suggest_code)
-{
- const char * com_err_msg;
- int offset;
- long table_num;
- DWORD msg_id = 0;
- DWORD sugg_id = 0;
- kherr_suggestion sugg_code = KHERR_SUGGEST_NONE;
-
- if (suggestion == NULL || buf == NULL || cbbuf == 0 || suggest_code == 0)
- return;
-
- *buf = L'\0';
-
- offset = (int) (code & 255);
- table_num = code - offset;
- com_err_msg = perror_message(code);
-
- *suggestion = 0;
- *suggest_code = KHERR_SUGGEST_NONE;
-
- if (WSABASEERR <= code && code < (WSABASEERR + 1064)) {
- /* winsock error */
- table_num = WSABASEERR;
- offset = code - WSABASEERR;
- }
-
- switch(table_num)
- {
- case krb_err_base:
- case kadm_err_base:
- case WSABASEERR:
- break;
- default:
-
- if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
- *suggestion = MSG_ERR_S_INTEGRITY;
- }
- *suggest_code = KHERR_SUGGEST_RETRY;
- AnsiStrToUnicode(buf, cbbuf, com_err_msg);
- return;
- }
-
- if (table_num == krb_err_base) {
- switch(offset) {
- case KDC_NAME_EXP: /* 001 Principal expired */
- case KDC_SERVICE_EXP: /* 002 Service expired */
- case KDC_AUTH_EXP: /* 003 Auth expired */
- case KDC_PKT_VER: /* 004 Protocol version unknown */
- case KDC_P_MKEY_VER: /* 005 Wrong master key version */
- case KDC_S_MKEY_VER: /* 006 Wrong master key version */
- case KDC_BYTE_ORDER: /* 007 Byte order unknown */
- case KDC_PR_N_UNIQUE: /* 009 Principal not unique */
- case KDC_NULL_KEY: /* 010 Principal has null key */
- case KDC_GEN_ERR: /* 011 Generic error from KDC */
- case INTK_W_NOTALL : /* 061 Not ALL tickets returned */
- case INTK_PROT : /* 063 Protocol Error */
- case INTK_ERR : /* 070 Other error */
- msg_id = MSG_ERR_UNKNOWN;
- sugg_code = KHERR_SUGGEST_RETRY;
- break;
-
- case KDC_PR_UNKNOWN: /* 008 Principal unknown */
- msg_id = MSG_ERR_PR_UNKNOWN;
- sugg_code = KHERR_SUGGEST_RETRY;
- break;
- case GC_TKFIL : /* 021 Can't read ticket file */
- case GC_NOTKT : /* 022 Can't find ticket or TGT */
- msg_id = MSG_ERR_TKFIL;
- sugg_id = MSG_ERR_S_TKFIL;
- sugg_code = KHERR_SUGGEST_RETRY;
- break;
- case MK_AP_TGTEXP : /* 026 TGT Expired */
- /* no extra error msg */
- break;
-
- case RD_AP_TIME : /* 037 delta_t too big */
- msg_id = MSG_ERR_CLOCKSKEW;
- sugg_id = MSG_ERR_S_CLOCKSKEW;
- sugg_code = KHERR_SUGGEST_RETRY;
- break;
-
- case RD_AP_UNDEC : /* 031 Can't decode
- authenticator */
- case RD_AP_EXP : /* 032 Ticket expired */
- case RD_AP_NYV : /* 033 Ticket not yet valid */
- case RD_AP_REPEAT : /* 034 Repeated request */
- case RD_AP_NOT_US : /* 035 The ticket isn't for us */
- case RD_AP_INCON : /* 036 Request is inconsistent */
- case RD_AP_BADD : /* 038 Incorrect net address */
- case RD_AP_VERSION : /* 039 protocol version mismatch */
- case RD_AP_MSG_TYPE : /* 040 invalid msg type */
- case RD_AP_MODIFIED : /* 041 message stream modified */
- case RD_AP_ORDER : /* 042 message out of order */
- case RD_AP_UNAUTHOR : /* 043 unauthorized request */
- /* no extra error msg */
- sugg_code = KHERR_SUGGEST_RETRY;
- break;
-
- case GT_PW_NULL: /* 51 Current PW is null */
- case GT_PW_BADPW: /* 52 Incorrect current password */
- case GT_PW_PROT: /* 53 Protocol Error */
- case GT_PW_KDCERR: /* 54 Error returned by KDC */
- case GT_PW_NULLTKT: /* 55 Null tkt returned by KDC */
- /* no error msg yet */
- sugg_code = KHERR_SUGGEST_RETRY;
- break;
-
- /* Values returned by send_to_kdc */
- case SKDC_RETRY : /* 56 Retry count exceeded */
- case SKDC_CANT : /* 57 Can't send request */
- msg_id = MSG_ERR_KDC_CONTACT;
- break;
- /* no error message on purpose: */
- case INTK_BADPW : /* 062 Incorrect password */
- sugg_code = KHERR_SUGGEST_RETRY;
- break;
- default:
- /* no extra error msg */
- break;
- }
- } else if (table_num == kadm_err_base) {
- switch(code) {
- case KADM_INSECURE_PW:
- /* if( kadm_info != NULL ){
- * wsprintf(buf, "%s\n%s", com_err_msg, kadm_info);
- * } else {
- * wsprintf(buf, "%s\nPlease see the help file for information "
- * "about secure passwords.", com_err_msg);
- * }
- * com_err_msg = buf;
- */
-
- /* The above code would be preferred since it allows site
- * specific information to be delivered from the Kerberos
- * server. However the message box is too small for VGA
- * screens. It does work well if we only have to support
- * 1024x768
- */
-
- msg_id = MSG_ERR_INSECURE_PW;
- sugg_code = KHERR_SUGGEST_RETRY;
- break;
-
- default:
- /* no extra error msg */
- break;
- }
- } else if (table_num == WSABASEERR) {
- switch(code) {
- case WSAENETDOWN:
- msg_id = MSG_ERR_NETDOWN;
- sugg_id = MSG_ERR_S_NETRETRY;
- sugg_code = KHERR_SUGGEST_RETRY;
- break;
-
- case WSATRY_AGAIN:
- msg_id = MSG_ERR_TEMPDOWN;
- sugg_id = MSG_ERR_S_TEMPDOWN;
- sugg_code = KHERR_SUGGEST_RETRY;
- break;
-
- case WSAENETUNREACH:
- case WSAENETRESET:
- case WSAECONNABORTED:
- case WSAECONNRESET:
- case WSAETIMEDOUT:
- case WSAECONNREFUSED:
- case WSAEHOSTDOWN:
- case WSAEHOSTUNREACH:
- msg_id = MSG_ERR_NOHOST;
- sugg_id = MSG_ERR_S_NOHOST;
- sugg_code = KHERR_SUGGEST_RETRY;
- break;
- }
- }
-
- if (msg_id != 0) {
- FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- KHERR_HMODULE,
- msg_id,
- 0,
- buf,
- (int) (cbbuf / sizeof(buf[0])),
- NULL);
- }
-
- if (sugg_id != 0) {
- *suggestion = sugg_id;
- }
-
- if (sugg_code != KHERR_SUGGEST_NONE)
- *suggest_code = sugg_code;
-}
-
-#ifdef DEPRECATED_REMOVABLE
-int lsh_com_err_proc (LPSTR whoami, long code,
- LPSTR fmt, va_list args)
-{
- int retval;
- HWND hOldFocus;
- char buf[1024], *cp;
- WORD mbformat = MB_OK | MB_ICONEXCLAMATION;
-
- cp = buf;
- memset(buf, '\0', sizeof(buf));
- cp[0] = '\0';
-
- if (code)
- {
- err_describe(buf, code);
- while (*cp)
- cp++;
- }
-
- if (fmt)
- {
- if (fmt[0] == '%' && fmt[1] == 'b')
- {
- fmt += 2;
- mbformat = va_arg(args, WORD);
- /* if the first arg is a %b, we use it for the message
- box MB_??? flags. */
- }
- if (code)
- {
- *cp++ = '\n';
- *cp++ = '\n';
- }
- wvsprintfA((LPSTR)cp, fmt, args);
- }
- hOldFocus = GetFocus();
- retval = MessageBoxA(/*GetRootParent(hOldFocus)*/NULL, buf, whoami,
- mbformat | MB_ICONHAND | MB_TASKMODAL);
- SetFocus(hOldFocus);
- return retval;
-}
-#endif
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<kherror.h>
+
+extern void (__cdecl *pinitialize_krb_error_func)();
+extern void (__cdecl *pinitialize_kadm_error_table)();
+
+
+khm_int32 init_error_funcs()
+{
+ return KHM_ERROR_SUCCESS;
+}
+
+khm_int32 exit_error_funcs()
+{
+ return KHM_ERROR_SUCCESS;
+}
+
+#ifdef DEPRECATED_REMOVABLE
+HWND GetRootParent (HWND Child)
+{
+ HWND Last;
+ while (Child)
+ {
+ Last = Child;
+ Child = GetParent (Child);
+ }
+ return Last;
+}
+#endif
+
+void khm_err_describe(long code, wchar_t * buf, khm_size cbbuf,
+ DWORD * suggestion,
+ kherr_suggestion * suggest_code)
+{
+ const char * com_err_msg;
+ int offset;
+ long table_num;
+ DWORD msg_id = 0;
+ DWORD sugg_id = 0;
+ kherr_suggestion sugg_code = KHERR_SUGGEST_NONE;
+
+ if (suggestion == NULL || buf == NULL || cbbuf == 0 || suggest_code == 0)
+ return;
+
+ *buf = L'\0';
+
+ offset = (int) (code & 255);
+ table_num = code - offset;
+ com_err_msg = perror_message(code);
+
+ *suggestion = 0;
+ *suggest_code = KHERR_SUGGEST_NONE;
+
+ if (WSABASEERR <= code && code < (WSABASEERR + 1064)) {
+ /* winsock error */
+ table_num = WSABASEERR;
+ offset = code - WSABASEERR;
+ }
+
+ switch(table_num)
+ {
+ case krb_err_base:
+ case kadm_err_base:
+ case WSABASEERR:
+ break;
+ default:
+
+ if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+ *suggestion = MSG_ERR_S_INTEGRITY;
+ }
+ *suggest_code = KHERR_SUGGEST_RETRY;
+ AnsiStrToUnicode(buf, cbbuf, com_err_msg);
+ return;
+ }
+
+ if (table_num == krb_err_base) {
+ switch(offset) {
+ case KDC_NAME_EXP: /* 001 Principal expired */
+ case KDC_SERVICE_EXP: /* 002 Service expired */
+ case KDC_AUTH_EXP: /* 003 Auth expired */
+ case KDC_PKT_VER: /* 004 Protocol version unknown */
+ case KDC_P_MKEY_VER: /* 005 Wrong master key version */
+ case KDC_S_MKEY_VER: /* 006 Wrong master key version */
+ case KDC_BYTE_ORDER: /* 007 Byte order unknown */
+ case KDC_PR_N_UNIQUE: /* 009 Principal not unique */
+ case KDC_NULL_KEY: /* 010 Principal has null key */
+ case KDC_GEN_ERR: /* 011 Generic error from KDC */
+ case INTK_W_NOTALL : /* 061 Not ALL tickets returned */
+ case INTK_PROT : /* 063 Protocol Error */
+ case INTK_ERR : /* 070 Other error */
+ msg_id = MSG_ERR_UNKNOWN;
+ sugg_code = KHERR_SUGGEST_RETRY;
+ break;
+
+ case KDC_PR_UNKNOWN: /* 008 Principal unknown */
+ msg_id = MSG_ERR_PR_UNKNOWN;
+ sugg_code = KHERR_SUGGEST_RETRY;
+ break;
+ case GC_TKFIL : /* 021 Can't read ticket file */
+ case GC_NOTKT : /* 022 Can't find ticket or TGT */
+ msg_id = MSG_ERR_TKFIL;
+ sugg_id = MSG_ERR_S_TKFIL;
+ sugg_code = KHERR_SUGGEST_RETRY;
+ break;
+ case MK_AP_TGTEXP : /* 026 TGT Expired */
+ /* no extra error msg */
+ break;
+
+ case RD_AP_TIME : /* 037 delta_t too big */
+ msg_id = MSG_ERR_CLOCKSKEW;
+ sugg_id = MSG_ERR_S_CLOCKSKEW;
+ sugg_code = KHERR_SUGGEST_RETRY;
+ break;
+
+ case RD_AP_UNDEC : /* 031 Can't decode
+ authenticator */
+ case RD_AP_EXP : /* 032 Ticket expired */
+ case RD_AP_NYV : /* 033 Ticket not yet valid */
+ case RD_AP_REPEAT : /* 034 Repeated request */
+ case RD_AP_NOT_US : /* 035 The ticket isn't for us */
+ case RD_AP_INCON : /* 036 Request is inconsistent */
+ case RD_AP_BADD : /* 038 Incorrect net address */
+ case RD_AP_VERSION : /* 039 protocol version mismatch */
+ case RD_AP_MSG_TYPE : /* 040 invalid msg type */
+ case RD_AP_MODIFIED : /* 041 message stream modified */
+ case RD_AP_ORDER : /* 042 message out of order */
+ case RD_AP_UNAUTHOR : /* 043 unauthorized request */
+ /* no extra error msg */
+ sugg_code = KHERR_SUGGEST_RETRY;
+ break;
+
+ case GT_PW_NULL: /* 51 Current PW is null */
+ case GT_PW_BADPW: /* 52 Incorrect current password */
+ case GT_PW_PROT: /* 53 Protocol Error */
+ case GT_PW_KDCERR: /* 54 Error returned by KDC */
+ case GT_PW_NULLTKT: /* 55 Null tkt returned by KDC */
+ /* no error msg yet */
+ sugg_code = KHERR_SUGGEST_RETRY;
+ break;
+
+ /* Values returned by send_to_kdc */
+ case SKDC_RETRY : /* 56 Retry count exceeded */
+ case SKDC_CANT : /* 57 Can't send request */
+ msg_id = MSG_ERR_KDC_CONTACT;
+ break;
+ /* no error message on purpose: */
+ case INTK_BADPW : /* 062 Incorrect password */
+ sugg_code = KHERR_SUGGEST_RETRY;
+ break;
+ default:
+ /* no extra error msg */
+ break;
+ }
+ } else if (table_num == kadm_err_base) {
+ switch(code) {
+ case KADM_INSECURE_PW:
+ /* if( kadm_info != NULL ){
+ * wsprintf(buf, "%s\n%s", com_err_msg, kadm_info);
+ * } else {
+ * wsprintf(buf, "%s\nPlease see the help file for information "
+ * "about secure passwords.", com_err_msg);
+ * }
+ * com_err_msg = buf;
+ */
+
+ /* The above code would be preferred since it allows site
+ * specific information to be delivered from the Kerberos
+ * server. However the message box is too small for VGA
+ * screens. It does work well if we only have to support
+ * 1024x768
+ */
+
+ msg_id = MSG_ERR_INSECURE_PW;
+ sugg_code = KHERR_SUGGEST_RETRY;
+ break;
+
+ default:
+ /* no extra error msg */
+ break;
+ }
+ } else if (table_num == WSABASEERR) {
+ switch(code) {
+ case WSAENETDOWN:
+ msg_id = MSG_ERR_NETDOWN;
+ sugg_id = MSG_ERR_S_NETRETRY;
+ sugg_code = KHERR_SUGGEST_RETRY;
+ break;
+
+ case WSATRY_AGAIN:
+ msg_id = MSG_ERR_TEMPDOWN;
+ sugg_id = MSG_ERR_S_TEMPDOWN;
+ sugg_code = KHERR_SUGGEST_RETRY;
+ break;
+
+ case WSAENETUNREACH:
+ case WSAENETRESET:
+ case WSAECONNABORTED:
+ case WSAECONNRESET:
+ case WSAETIMEDOUT:
+ case WSAECONNREFUSED:
+ case WSAEHOSTDOWN:
+ case WSAEHOSTUNREACH:
+ msg_id = MSG_ERR_NOHOST;
+ sugg_id = MSG_ERR_S_NOHOST;
+ sugg_code = KHERR_SUGGEST_RETRY;
+ break;
+ }
+ }
+
+ if (msg_id != 0) {
+ FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ KHERR_HMODULE,
+ msg_id,
+ 0,
+ buf,
+ (int) (cbbuf / sizeof(buf[0])),
+ NULL);
+ }
+
+ if (sugg_id != 0) {
+ *suggestion = sugg_id;
+ }
+
+ if (sugg_code != KHERR_SUGGEST_NONE)
+ *suggest_code = sugg_code;
+}
+
+#ifdef DEPRECATED_REMOVABLE
+int lsh_com_err_proc (LPSTR whoami, long code,
+ LPSTR fmt, va_list args)
+{
+ int retval;
+ HWND hOldFocus;
+ char buf[1024], *cp;
+ WORD mbformat = MB_OK | MB_ICONEXCLAMATION;
+
+ cp = buf;
+ memset(buf, '\0', sizeof(buf));
+ cp[0] = '\0';
+
+ if (code)
+ {
+ err_describe(buf, code);
+ while (*cp)
+ cp++;
+ }
+
+ if (fmt)
+ {
+ if (fmt[0] == '%' && fmt[1] == 'b')
+ {
+ fmt += 2;
+ mbformat = va_arg(args, WORD);
+ /* if the first arg is a %b, we use it for the message
+ box MB_??? flags. */
+ }
+ if (code)
+ {
+ *cp++ = '\n';
+ *cp++ = '\n';
+ }
+ wvsprintfA((LPSTR)cp, fmt, args);
+ }
+ hOldFocus = GetFocus();
+ retval = MessageBoxA(/*GetRootParent(hOldFocus)*/NULL, buf, whoami,
+ mbformat | MB_ICONHAND | MB_TASKMODAL);
+ SetFocus(hOldFocus);
+ return retval;
+}
+#endif
diff --git a/src/windows/identity/plugins/krb5/errorfuncs.h b/src/windows/identity/plugins/krb5/errorfuncs.h
index 86fc5b440..4b1d2e2b5 100644
--- a/src/windows/identity/plugins/krb5/errorfuncs.h
+++ b/src/windows/identity/plugins/krb5/errorfuncs.h
@@ -1,75 +1,75 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef __KHIMAIRA_ERR_H
-#define __KHIMAIRA_ERR_H
-
-/* All error handling and reporting related functions for the krb4/5
- and AFS plugins */
-
-#include <errno.h>
-#include <com_err.h>
-/*
- * This is a hack needed because the real com_err.h does
- * not define err_func. We need it in the case where
- * we pull in the real com_err instead of the krb4
- * impostor.
- */
-#ifndef _DCNS_MIT_COM_ERR_H
-typedef LPSTR (*err_func)(int, long);
-#endif
-
-#include <krberr.h>
-#include <kadm_err.h>
-
-#define kadm_err_base ERROR_TABLE_BASE_kadm
-
-#include <stdarg.h>
-
-#ifndef KRBERR
-#define KRBERR(code) (code + krb_err_base)
-#endif
-
-/*! \internal
- \brief Describe an error
-
- \param[in] code Error code returned by Kerberos
- \param[out] buf Receives the error string
- \param[in] cbbuf Size of buffer pointed to by \a buf
- \param[out] suggestion Message ID of suggestion
- \param[out] suggest_code Suggestion ID
-*/
-void khm_err_describe(long code, wchar_t * buf, khm_size cbbuf,
- DWORD * suggestion,
- kherr_suggestion * suggest_code);
-
-/* */
-khm_int32 init_error_funcs();
-
-khm_int32 exit_error_funcs();
-
-
-#endif
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef __KHIMAIRA_ERR_H
+#define __KHIMAIRA_ERR_H
+
+/* All error handling and reporting related functions for the krb4/5
+ and AFS plugins */
+
+#include <errno.h>
+#include <com_err.h>
+/*
+ * This is a hack needed because the real com_err.h does
+ * not define err_func. We need it in the case where
+ * we pull in the real com_err instead of the krb4
+ * impostor.
+ */
+#ifndef _DCNS_MIT_COM_ERR_H
+typedef LPSTR (*err_func)(int, long);
+#endif
+
+#include <krberr.h>
+#include <kadm_err.h>
+
+#define kadm_err_base ERROR_TABLE_BASE_kadm
+
+#include <stdarg.h>
+
+#ifndef KRBERR
+#define KRBERR(code) (code + krb_err_base)
+#endif
+
+/*! \internal
+ \brief Describe an error
+
+ \param[in] code Error code returned by Kerberos
+ \param[out] buf Receives the error string
+ \param[in] cbbuf Size of buffer pointed to by \a buf
+ \param[out] suggestion Message ID of suggestion
+ \param[out] suggest_code Suggestion ID
+*/
+void khm_err_describe(long code, wchar_t * buf, khm_size cbbuf,
+ DWORD * suggestion,
+ kherr_suggestion * suggest_code);
+
+/* */
+khm_int32 init_error_funcs();
+
+khm_int32 exit_error_funcs();
+
+
+#endif
diff --git a/src/windows/identity/plugins/krb5/krb5configcc.c b/src/windows/identity/plugins/krb5/krb5configcc.c
index 5edc02b1f..b2b498e68 100644
--- a/src/windows/identity/plugins/krb5/krb5configcc.c
+++ b/src/windows/identity/plugins/krb5/krb5configcc.c
@@ -1,571 +1,571 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#if _WIN32_WINNT < 0x501
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x501
-#endif
-
-#include<krbcred.h>
-#include<krb5.h>
-#include<assert.h>
-#include<lm.h>
-#include<commctrl.h>
-#include<shlwapi.h>
-
-#include<strsafe.h>
-
-typedef struct tag_k5_file_cc {
- wchar_t path[MAX_PATH];
- khm_int32 flags;
-} k5_file_cc;
-
-#define K5_FCC_ALLOC_INCR 8
-
-#define K5_FCC_FLAG_EXISTS 1
-
-typedef struct tag_k5_ccc_data {
- khm_boolean inc_api;
- khm_boolean inc_mslsa;
- k5_file_cc * file_ccs;
- khm_size n_file_ccs;
- khm_size nc_file_ccs;
-} k5_ccc_data;
-
-typedef struct tag_k5_ccc_dlg_data {
- khui_config_node node;
- k5_ccc_data save;
- k5_ccc_data work;
-} k5_ccc_dlg_data;
-
-void k5_free_file_ccs(k5_ccc_data * d) {
- if (d->file_ccs)
- PFREE(d->file_ccs);
- d->n_file_ccs = 0;
- d->nc_file_ccs = 0;
-}
-
-void k5_flush_file_ccs(k5_ccc_data * d) {
- d->n_file_ccs = 0;
-}
-
-void k5_del_file_cc(k5_ccc_data * d, khm_size idx) {
- if (idx > d->n_file_ccs)
- return;
-
- if (idx < d->n_file_ccs - 1) {
- MoveMemory(&d->file_ccs[idx],
- &d->file_ccs[idx + 1],
- sizeof(d->file_ccs[0]) * (d->n_file_ccs - (idx + 1)));
- }
-
- d->n_file_ccs--;
-}
-
-void k5_add_file_cc(k5_ccc_data * d, wchar_t * path) {
- khm_size i;
- khm_size cch;
-
- if (FAILED(StringCchLength(path, MAX_PATH, &cch)) ||
- cch == 0)
- return;
-
- /* see if it's there first */
- for (i=0; i < d->n_file_ccs; i++) {
- if(!_wcsicmp(d->file_ccs[i].path, path))
- return;
- }
-
- if (d->n_file_ccs == d->nc_file_ccs) {
- k5_file_cc * f;
-
- d->nc_file_ccs = UBOUNDSS(d->n_file_ccs + 1,
- K5_FCC_ALLOC_INCR,
- K5_FCC_ALLOC_INCR);
-#ifdef DEBUG
- assert(d->nc_file_ccs > d->n_file_ccs);
-#endif
- f = PMALLOC(sizeof(*f) * d->nc_file_ccs);
- ZeroMemory(f, sizeof(*f) * d->nc_file_ccs);
-
- if (d->n_file_ccs > 0) {
-#ifdef DEBUG
- assert(d->file_ccs != NULL);
-#endif
- memcpy(f, d->file_ccs, sizeof(*f) * d->n_file_ccs);
- }
- if (d->file_ccs)
- PFREE(d->file_ccs);
- d->file_ccs = f;
- }
-
- StringCbCopy(d->file_ccs[d->n_file_ccs].path,
- sizeof(d->file_ccs[0].path),
- path);
- if(PathFileExists(path))
- d->file_ccs[d->n_file_ccs].flags = K5_FCC_FLAG_EXISTS;
- else
- d->file_ccs[d->n_file_ccs].flags = 0;
-
- d->n_file_ccs++;
-}
-
-void k5_read_file_cc_data(k5_ccc_data * d) {
- khm_int32 t;
- wchar_t * fclist = NULL;
- wchar_t * fc;
- khm_size cb;
-
-#ifdef DEBUG
- assert(csp_params);
-#endif
-
- d->inc_api = TRUE;
- t = TRUE;
- khc_read_int32(csp_params, L"MsLsaList", &t);
- d->inc_mslsa = t;
-
- if (khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
- != KHM_ERROR_TOO_LONG ||
- cb <= sizeof(wchar_t) * 2) {
-
- k5_flush_file_ccs(d);
- } else {
- fclist = PMALLOC(cb);
-#ifdef DEBUG
- assert(fclist);
-#endif
- khc_read_multi_string(csp_params, L"FileCCList", fclist, &cb);
-
- for(fc = fclist; fc && *fc; fc = multi_string_next(fc)) {
- k5_add_file_cc(d, fc);
- }
-
- PFREE(fclist);
- }
-}
-
-void k5_write_file_cc_data(k5_ccc_data * d) {
- wchar_t * ms;
- khm_size cb;
- khm_size cbt;
- khm_int32 t;
- khm_size i;
-
-#ifdef DEBUG
- assert(csp_params);
-#endif
- if (KHM_FAILED(khc_read_int32(csp_params, L"MsLsaList", &t)) ||
- !!t != !!d->inc_mslsa) {
- khc_write_int32(csp_params, L"MsLsaList", !!d->inc_mslsa);
- }
-
- if (d->n_file_ccs > 0) {
- cb = d->n_file_ccs * MAX_PATH * sizeof(wchar_t);
- ms = PMALLOC(cb);
-#ifdef DEBUG
- assert(ms);
-#endif
- multi_string_init(ms, cb);
-
- for(i=0; i<d->n_file_ccs; i++) {
- cbt = cb;
- multi_string_append(ms, &cbt, d->file_ccs[i].path);
- }
-
- khc_write_multi_string(csp_params, L"FileCCList", ms);
-
- PFREE(ms);
- } else {
- if (khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
- != KHM_ERROR_TOO_LONG ||
- cb != sizeof(wchar_t) * 2)
-
- khc_write_multi_string(csp_params, L"FileCCList", L"\0\0");
- }
-}
-
-void k5_copy_file_cc_data(k5_ccc_data * dest, const k5_ccc_data * src) {
- khm_size i;
-
- k5_flush_file_ccs(dest);
- dest->inc_mslsa = src->inc_mslsa;
- dest->inc_api = src->inc_api;
-
- for (i=0; i < src->n_file_ccs; i++) {
- k5_add_file_cc(dest, src->file_ccs[i].path);
- }
-}
-
-BOOL k5_ccc_get_mod(k5_ccc_dlg_data * d) {
- khm_size i, j;
-
- if (!!d->work.inc_mslsa != !!d->save.inc_mslsa ||
- !!d->work.inc_api != !!d->save.inc_api ||
- d->work.n_file_ccs != d->save.n_file_ccs)
- return TRUE;
-
- for (i=0; i < d->work.n_file_ccs; i++) {
- for (j=0; j < d->save.n_file_ccs; j++) {
- if (!_wcsicmp(d->work.file_ccs[i].path,
- d->save.file_ccs[j].path))
- break;
- }
- if (j >= d->save.n_file_ccs)
- return TRUE;
- }
-
- return FALSE;
-}
-
-void k5_ccc_update_ui(HWND hwnd, k5_ccc_dlg_data * d) {
- khm_size i;
- HWND lv;
-
- if (d->work.inc_api)
- CheckDlgButton(hwnd, IDC_CFG_INCAPI, BST_CHECKED);
- else
- CheckDlgButton(hwnd, IDC_CFG_INCAPI, BST_UNCHECKED);
- if (d->work.inc_mslsa)
- CheckDlgButton(hwnd, IDC_CFG_INCMSLSA, BST_CHECKED);
- else
- CheckDlgButton(hwnd, IDC_CFG_INCMSLSA, BST_UNCHECKED);
-
- lv = GetDlgItem(hwnd, IDC_CFG_FCLIST);
-#ifdef DEBUG
- assert(lv);
-#endif
- ListView_DeleteAllItems(lv);
-
- for (i=0; i<d->work.n_file_ccs; i++) {
- LVITEM lvi;
-
- ZeroMemory(&lvi, sizeof(lvi));
-
- lvi.mask = LVIF_PARAM | LVIF_TEXT;
- lvi.lParam = (LPARAM) i;
- lvi.pszText = d->work.file_ccs[i].path;
-
- ListView_InsertItem(lv, &lvi);
- }
-
- if (k5_ccc_get_mod(d)) {
- khui_cfg_set_flags(d->node,
- KHUI_CNFLAG_MODIFIED,
- KHUI_CNFLAG_MODIFIED);
- } else {
- khui_cfg_set_flags(d->node,
- 0,
- KHUI_CNFLAG_MODIFIED);
- }
-}
-
-void k5_ccc_update_data(HWND hwnd, k5_ccc_data * d) {
- if (IsDlgButtonChecked(hwnd, IDC_CFG_INCAPI) == BST_CHECKED)
- d->inc_api = TRUE;
- else
- d->inc_api = FALSE;
-
- if (IsDlgButtonChecked(hwnd, IDC_CFG_INCMSLSA) == BST_CHECKED)
- d->inc_mslsa = TRUE;
- else
- d->inc_mslsa = FALSE;
- /* everything else is controlled by buttons */
-}
-
-INT_PTR CALLBACK
-k5_ccconfig_dlgproc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
-
- k5_ccc_dlg_data * d;
-
- switch(uMsg) {
- case WM_INITDIALOG:
- d = PMALLOC(sizeof(*d));
-#ifdef DEBUG
- assert(d);
-#endif
- ZeroMemory(d, sizeof(*d));
- k5_read_file_cc_data(&d->save);
- k5_copy_file_cc_data(&d->work, &d->save);
-
- d->node = (khui_config_node) lParam;
-
-#pragma warning(push)
-#pragma warning(disable: 4244)
- SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
-#pragma warning(pop)
-
- {
- LVCOLUMN lvc;
- HWND lv;
- wchar_t buf[256];
- RECT r;
-
- lv = GetDlgItem(hwnd, IDC_CFG_FCLIST);
-#ifdef DEBUG
- assert(lv);
-#endif
- ZeroMemory(&lvc, sizeof(lvc));
- lvc.mask = LVCF_TEXT | LVCF_WIDTH;
-
- LoadString(hResModule, IDS_CFG_FCTITLE,
- buf, ARRAYLENGTH(buf));
-
- GetWindowRect(lv, &r);
-
- lvc.pszText = buf;
- lvc.cx = (r.right - r.left) * 9 / 10;
-
- ListView_InsertColumn(lv, 0, &lvc);
- }
-
- SendDlgItemMessage(hwnd, IDC_CFG_FCNAME, EM_SETLIMITTEXT,
- MAX_PATH - 1, 0);
-
- k5_ccc_update_ui(hwnd, d);
- break;
-
- case WM_COMMAND:
- d = (k5_ccc_dlg_data *) (DWORD_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
- switch(wParam) {
- case MAKEWPARAM(IDC_CFG_ADD, BN_CLICKED):
- {
- wchar_t path[MAX_PATH];
- wchar_t cpath[MAX_PATH];
- khm_size i;
-
- GetDlgItemText(hwnd, IDC_CFG_FCNAME,
- cpath, ARRAYLENGTH(cpath));
-
- PathCanonicalize(path, cpath);
-
- if (!*path)
- return TRUE; /* nothing to add */
-
- for (i=0; i < d->work.n_file_ccs; i++) {
- if (!_wcsicmp(path, d->work.file_ccs[i].path)) {
-
- /* allow the user to correct case, as appropriate */
- StringCbCopy(d->work.file_ccs[i].path,
- sizeof(d->work.file_ccs[i].path),
- path);
- k5_ccc_update_ui(hwnd, d);
- return TRUE;
- }
- }
-
- /* not there. we need to add. but check a few things
- first */
- if (!PathFileExists(path)) {
- wchar_t title[64];
- wchar_t text[128];
-
- LoadString(hResModule, IDS_CFG_FCN_WARNING,
- title, ARRAYLENGTH(title));
-
- LoadString(hResModule, IDS_CFG_FCN_W_NOTFOUND,
- text, ARRAYLENGTH(text));
-#if _WIN32_WINNT >= 0x501
- if (IS_COMMCTL6())
- {
- EDITBALLOONTIP bt;
-
- bt.cbStruct = sizeof(bt);
- bt.pszTitle = title;
- bt.pszText = text;
- bt.ttiIcon = TTI_WARNING;
-
- SendDlgItemMessage(hwnd, IDC_CFG_FCNAME,
- EM_SHOWBALLOONTIP,
- 0,
- (LPARAM) &bt);
- } else {
-#endif
- MessageBox(hwnd, text, title, MB_OK | MB_ICONWARNING);
-#if _WIN32_WINNT >= 0x501
- }
-#endif
- } else if (PathIsRelative(path)) {
- wchar_t title[64];
- wchar_t text[128];
-
- LoadString(hResModule, IDS_CFG_FCN_WARNING,
- title, ARRAYLENGTH(title));
- LoadString(hResModule, IDS_CFG_FCN_W_RELATIVE,
- text, ARRAYLENGTH(text));
-
-#if _WIN32_WINNT >= 0x501
- if (IS_COMMCTL6())
- {
- EDITBALLOONTIP bt;
-
- bt.cbStruct = sizeof(bt);
- bt.pszTitle = title;
- bt.pszText = text;
- bt.ttiIcon = TTI_WARNING;
-
- SendDlgItemMessage(hwnd, IDC_CFG_FCNAME,
- EM_SHOWBALLOONTIP,
- 0,
- (LPARAM) &bt);
- } else {
-#endif
- MessageBox(hwnd, text, title, MB_OK | MB_ICONWARNING);
-#if _WIN32_WINNT >= 0x501
- }
-#endif
- }
-
- k5_add_file_cc(&d->work, path);
-
- k5_ccc_update_ui(hwnd, d);
- }
- return TRUE;
-
- case MAKEWPARAM(IDC_CFG_BROWSE, BN_CLICKED):
- {
- OPENFILENAME ofn;
- wchar_t path[MAX_PATH * 8];
- wchar_t title[128];
-
- ZeroMemory(&ofn, sizeof(ofn));
- ZeroMemory(path, sizeof(path));
-
- GetDlgItemText(hwnd, IDC_CFG_FCNAME,
- path, ARRAYLENGTH(path));
-
- /* don't pass in invalid paths */
- if (!PathFileExists(path))
- *path = 0;
-
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = hwnd;
- ofn.lpstrFilter = L"All files\0*.*\0\0";
- ofn.nFilterIndex = 1;
- ofn.lpstrFile = path;
- ofn.nMaxFile = ARRAYLENGTH(path);
- ofn.lpstrTitle = title;
-
- LoadString(hResModule, IDS_CFG_FCOPENTITLE,
- title, ARRAYLENGTH(title));
-
- ofn.Flags = OFN_ALLOWMULTISELECT |
- OFN_DONTADDTORECENT |
- OFN_FORCESHOWHIDDEN |
- OFN_EXPLORER;
-
- if (GetOpenFileName(&ofn)) {
- wchar_t * p;
- wchar_t spath[MAX_PATH];
-
- p = multi_string_next(path);
- if (p) {
- /* multi select */
- for(;p && *p; p = multi_string_next(p)) {
- StringCbCopy(spath, sizeof(spath), path);
- PathAppend(spath, p);
-
- k5_add_file_cc(&d->work, spath);
- }
- } else {
- /* single select */
- k5_add_file_cc(&d->work, path);
- }
- k5_ccc_update_ui(hwnd, d);
- }
- }
- return TRUE;
-
- case MAKEWPARAM(IDC_CFG_REMOVE, BN_CLICKED):
- {
- khm_size i;
- int lv_idx;
- HWND lv;
- wchar_t buf[MAX_PATH];
-
- lv = GetDlgItem(hwnd, IDC_CFG_FCLIST);
-#ifdef DEBUG
- assert(lv);
-#endif
-
- lv_idx = -1;
- while((lv_idx = ListView_GetNextItem(lv, lv_idx,
- LVNI_SELECTED)) != -1) {
- ListView_GetItemText(lv, lv_idx, 0, buf, ARRAYLENGTH(buf));
- for (i=0; i < d->work.n_file_ccs; i++) {
- if (!_wcsicmp(buf, d->work.file_ccs[i].path)) {
- k5_del_file_cc(&d->work, i);
- break;
- }
- }
- }
-
- k5_ccc_update_ui(hwnd, d);
- }
- return TRUE;
-
- case MAKEWPARAM(IDC_CFG_INCAPI, BN_CLICKED):
- case MAKEWPARAM(IDC_CFG_INCMSLSA, BN_CLICKED):
- k5_ccc_update_data(hwnd, &d->work);
- k5_ccc_update_ui(hwnd, d);
- return TRUE;
- }
- break;
-
- case WM_DESTROY:
- d = (k5_ccc_dlg_data *) (DWORD_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- k5_free_file_ccs(&d->work);
- k5_free_file_ccs(&d->save);
- PFREE(d);
- return TRUE;
-
- case KHUI_WM_CFG_NOTIFY:
- d = (k5_ccc_dlg_data *) (DWORD_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- switch(HIWORD(wParam)) {
- case WMCFG_APPLY:
- if (k5_ccc_get_mod(d)) {
- k5_write_file_cc_data(&d->work);
- k5_copy_file_cc_data(&d->save, &d->work);
- khui_cfg_set_flags(d->node,
- KHUI_CNFLAG_APPLIED,
- KHUI_CNFLAG_APPLIED);
- k5_ccc_update_ui(hwnd, d);
-
- kmq_post_sub_msg(k5_sub, KMSG_CRED, KMSG_CRED_REFRESH, 0, 0);
- }
- break;
- }
- }
- return FALSE;
-}
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#if _WIN32_WINNT < 0x501
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x501
+#endif
+
+#include<krbcred.h>
+#include<krb5.h>
+#include<assert.h>
+#include<lm.h>
+#include<commctrl.h>
+#include<shlwapi.h>
+
+#include<strsafe.h>
+
+typedef struct tag_k5_file_cc {
+ wchar_t path[MAX_PATH];
+ khm_int32 flags;
+} k5_file_cc;
+
+#define K5_FCC_ALLOC_INCR 8
+
+#define K5_FCC_FLAG_EXISTS 1
+
+typedef struct tag_k5_ccc_data {
+ khm_boolean inc_api;
+ khm_boolean inc_mslsa;
+ k5_file_cc * file_ccs;
+ khm_size n_file_ccs;
+ khm_size nc_file_ccs;
+} k5_ccc_data;
+
+typedef struct tag_k5_ccc_dlg_data {
+ khui_config_node node;
+ k5_ccc_data save;
+ k5_ccc_data work;
+} k5_ccc_dlg_data;
+
+void k5_free_file_ccs(k5_ccc_data * d) {
+ if (d->file_ccs)
+ PFREE(d->file_ccs);
+ d->n_file_ccs = 0;
+ d->nc_file_ccs = 0;
+}
+
+void k5_flush_file_ccs(k5_ccc_data * d) {
+ d->n_file_ccs = 0;
+}
+
+void k5_del_file_cc(k5_ccc_data * d, khm_size idx) {
+ if (idx > d->n_file_ccs)
+ return;
+
+ if (idx < d->n_file_ccs - 1) {
+ MoveMemory(&d->file_ccs[idx],
+ &d->file_ccs[idx + 1],
+ sizeof(d->file_ccs[0]) * (d->n_file_ccs - (idx + 1)));
+ }
+
+ d->n_file_ccs--;
+}
+
+void k5_add_file_cc(k5_ccc_data * d, wchar_t * path) {
+ khm_size i;
+ khm_size cch;
+
+ if (FAILED(StringCchLength(path, MAX_PATH, &cch)) ||
+ cch == 0)
+ return;
+
+ /* see if it's there first */
+ for (i=0; i < d->n_file_ccs; i++) {
+ if(!_wcsicmp(d->file_ccs[i].path, path))
+ return;
+ }
+
+ if (d->n_file_ccs == d->nc_file_ccs) {
+ k5_file_cc * f;
+
+ d->nc_file_ccs = UBOUNDSS(d->n_file_ccs + 1,
+ K5_FCC_ALLOC_INCR,
+ K5_FCC_ALLOC_INCR);
+#ifdef DEBUG
+ assert(d->nc_file_ccs > d->n_file_ccs);
+#endif
+ f = PMALLOC(sizeof(*f) * d->nc_file_ccs);
+ ZeroMemory(f, sizeof(*f) * d->nc_file_ccs);
+
+ if (d->n_file_ccs > 0) {
+#ifdef DEBUG
+ assert(d->file_ccs != NULL);
+#endif
+ memcpy(f, d->file_ccs, sizeof(*f) * d->n_file_ccs);
+ }
+ if (d->file_ccs)
+ PFREE(d->file_ccs);
+ d->file_ccs = f;
+ }
+
+ StringCbCopy(d->file_ccs[d->n_file_ccs].path,
+ sizeof(d->file_ccs[0].path),
+ path);
+ if(PathFileExists(path))
+ d->file_ccs[d->n_file_ccs].flags = K5_FCC_FLAG_EXISTS;
+ else
+ d->file_ccs[d->n_file_ccs].flags = 0;
+
+ d->n_file_ccs++;
+}
+
+void k5_read_file_cc_data(k5_ccc_data * d) {
+ khm_int32 t;
+ wchar_t * fclist = NULL;
+ wchar_t * fc;
+ khm_size cb;
+
+#ifdef DEBUG
+ assert(csp_params);
+#endif
+
+ d->inc_api = TRUE;
+ t = TRUE;
+ khc_read_int32(csp_params, L"MsLsaList", &t);
+ d->inc_mslsa = t;
+
+ if (khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
+ != KHM_ERROR_TOO_LONG ||
+ cb <= sizeof(wchar_t) * 2) {
+
+ k5_flush_file_ccs(d);
+ } else {
+ fclist = PMALLOC(cb);
+#ifdef DEBUG
+ assert(fclist);
+#endif
+ khc_read_multi_string(csp_params, L"FileCCList", fclist, &cb);
+
+ for(fc = fclist; fc && *fc; fc = multi_string_next(fc)) {
+ k5_add_file_cc(d, fc);
+ }
+
+ PFREE(fclist);
+ }
+}
+
+void k5_write_file_cc_data(k5_ccc_data * d) {
+ wchar_t * ms;
+ khm_size cb;
+ khm_size cbt;
+ khm_int32 t;
+ khm_size i;
+
+#ifdef DEBUG
+ assert(csp_params);
+#endif
+ if (KHM_FAILED(khc_read_int32(csp_params, L"MsLsaList", &t)) ||
+ !!t != !!d->inc_mslsa) {
+ khc_write_int32(csp_params, L"MsLsaList", !!d->inc_mslsa);
+ }
+
+ if (d->n_file_ccs > 0) {
+ cb = d->n_file_ccs * MAX_PATH * sizeof(wchar_t);
+ ms = PMALLOC(cb);
+#ifdef DEBUG
+ assert(ms);
+#endif
+ multi_string_init(ms, cb);
+
+ for(i=0; i<d->n_file_ccs; i++) {
+ cbt = cb;
+ multi_string_append(ms, &cbt, d->file_ccs[i].path);
+ }
+
+ khc_write_multi_string(csp_params, L"FileCCList", ms);
+
+ PFREE(ms);
+ } else {
+ if (khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
+ != KHM_ERROR_TOO_LONG ||
+ cb != sizeof(wchar_t) * 2)
+
+ khc_write_multi_string(csp_params, L"FileCCList", L"\0\0");
+ }
+}
+
+void k5_copy_file_cc_data(k5_ccc_data * dest, const k5_ccc_data * src) {
+ khm_size i;
+
+ k5_flush_file_ccs(dest);
+ dest->inc_mslsa = src->inc_mslsa;
+ dest->inc_api = src->inc_api;
+
+ for (i=0; i < src->n_file_ccs; i++) {
+ k5_add_file_cc(dest, src->file_ccs[i].path);
+ }
+}
+
+BOOL k5_ccc_get_mod(k5_ccc_dlg_data * d) {
+ khm_size i, j;
+
+ if (!!d->work.inc_mslsa != !!d->save.inc_mslsa ||
+ !!d->work.inc_api != !!d->save.inc_api ||
+ d->work.n_file_ccs != d->save.n_file_ccs)
+ return TRUE;
+
+ for (i=0; i < d->work.n_file_ccs; i++) {
+ for (j=0; j < d->save.n_file_ccs; j++) {
+ if (!_wcsicmp(d->work.file_ccs[i].path,
+ d->save.file_ccs[j].path))
+ break;
+ }
+ if (j >= d->save.n_file_ccs)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void k5_ccc_update_ui(HWND hwnd, k5_ccc_dlg_data * d) {
+ khm_size i;
+ HWND lv;
+
+ if (d->work.inc_api)
+ CheckDlgButton(hwnd, IDC_CFG_INCAPI, BST_CHECKED);
+ else
+ CheckDlgButton(hwnd, IDC_CFG_INCAPI, BST_UNCHECKED);
+ if (d->work.inc_mslsa)
+ CheckDlgButton(hwnd, IDC_CFG_INCMSLSA, BST_CHECKED);
+ else
+ CheckDlgButton(hwnd, IDC_CFG_INCMSLSA, BST_UNCHECKED);
+
+ lv = GetDlgItem(hwnd, IDC_CFG_FCLIST);
+#ifdef DEBUG
+ assert(lv);
+#endif
+ ListView_DeleteAllItems(lv);
+
+ for (i=0; i<d->work.n_file_ccs; i++) {
+ LVITEM lvi;
+
+ ZeroMemory(&lvi, sizeof(lvi));
+
+ lvi.mask = LVIF_PARAM | LVIF_TEXT;
+ lvi.lParam = (LPARAM) i;
+ lvi.pszText = d->work.file_ccs[i].path;
+
+ ListView_InsertItem(lv, &lvi);
+ }
+
+ if (k5_ccc_get_mod(d)) {
+ khui_cfg_set_flags(d->node,
+ KHUI_CNFLAG_MODIFIED,
+ KHUI_CNFLAG_MODIFIED);
+ } else {
+ khui_cfg_set_flags(d->node,
+ 0,
+ KHUI_CNFLAG_MODIFIED);
+ }
+}
+
+void k5_ccc_update_data(HWND hwnd, k5_ccc_data * d) {
+ if (IsDlgButtonChecked(hwnd, IDC_CFG_INCAPI) == BST_CHECKED)
+ d->inc_api = TRUE;
+ else
+ d->inc_api = FALSE;
+
+ if (IsDlgButtonChecked(hwnd, IDC_CFG_INCMSLSA) == BST_CHECKED)
+ d->inc_mslsa = TRUE;
+ else
+ d->inc_mslsa = FALSE;
+ /* everything else is controlled by buttons */
+}
+
+INT_PTR CALLBACK
+k5_ccconfig_dlgproc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+
+ k5_ccc_dlg_data * d;
+
+ switch(uMsg) {
+ case WM_INITDIALOG:
+ d = PMALLOC(sizeof(*d));
+#ifdef DEBUG
+ assert(d);
+#endif
+ ZeroMemory(d, sizeof(*d));
+ k5_read_file_cc_data(&d->save);
+ k5_copy_file_cc_data(&d->work, &d->save);
+
+ d->node = (khui_config_node) lParam;
+
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
+#pragma warning(pop)
+
+ {
+ LVCOLUMN lvc;
+ HWND lv;
+ wchar_t buf[256];
+ RECT r;
+
+ lv = GetDlgItem(hwnd, IDC_CFG_FCLIST);
+#ifdef DEBUG
+ assert(lv);
+#endif
+ ZeroMemory(&lvc, sizeof(lvc));
+ lvc.mask = LVCF_TEXT | LVCF_WIDTH;
+
+ LoadString(hResModule, IDS_CFG_FCTITLE,
+ buf, ARRAYLENGTH(buf));
+
+ GetWindowRect(lv, &r);
+
+ lvc.pszText = buf;
+ lvc.cx = (r.right - r.left) * 9 / 10;
+
+ ListView_InsertColumn(lv, 0, &lvc);
+ }
+
+ SendDlgItemMessage(hwnd, IDC_CFG_FCNAME, EM_SETLIMITTEXT,
+ MAX_PATH - 1, 0);
+
+ k5_ccc_update_ui(hwnd, d);
+ break;
+
+ case WM_COMMAND:
+ d = (k5_ccc_dlg_data *) (DWORD_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+ switch(wParam) {
+ case MAKEWPARAM(IDC_CFG_ADD, BN_CLICKED):
+ {
+ wchar_t path[MAX_PATH];
+ wchar_t cpath[MAX_PATH];
+ khm_size i;
+
+ GetDlgItemText(hwnd, IDC_CFG_FCNAME,
+ cpath, ARRAYLENGTH(cpath));
+
+ PathCanonicalize(path, cpath);
+
+ if (!*path)
+ return TRUE; /* nothing to add */
+
+ for (i=0; i < d->work.n_file_ccs; i++) {
+ if (!_wcsicmp(path, d->work.file_ccs[i].path)) {
+
+ /* allow the user to correct case, as appropriate */
+ StringCbCopy(d->work.file_ccs[i].path,
+ sizeof(d->work.file_ccs[i].path),
+ path);
+ k5_ccc_update_ui(hwnd, d);
+ return TRUE;
+ }
+ }
+
+ /* not there. we need to add. but check a few things
+ first */
+ if (!PathFileExists(path)) {
+ wchar_t title[64];
+ wchar_t text[128];
+
+ LoadString(hResModule, IDS_CFG_FCN_WARNING,
+ title, ARRAYLENGTH(title));
+
+ LoadString(hResModule, IDS_CFG_FCN_W_NOTFOUND,
+ text, ARRAYLENGTH(text));
+#if _WIN32_WINNT >= 0x501
+ if (IS_COMMCTL6())
+ {
+ EDITBALLOONTIP bt;
+
+ bt.cbStruct = sizeof(bt);
+ bt.pszTitle = title;
+ bt.pszText = text;
+ bt.ttiIcon = TTI_WARNING;
+
+ SendDlgItemMessage(hwnd, IDC_CFG_FCNAME,
+ EM_SHOWBALLOONTIP,
+ 0,
+ (LPARAM) &bt);
+ } else {
+#endif
+ MessageBox(hwnd, text, title, MB_OK | MB_ICONWARNING);
+#if _WIN32_WINNT >= 0x501
+ }
+#endif
+ } else if (PathIsRelative(path)) {
+ wchar_t title[64];
+ wchar_t text[128];
+
+ LoadString(hResModule, IDS_CFG_FCN_WARNING,
+ title, ARRAYLENGTH(title));
+ LoadString(hResModule, IDS_CFG_FCN_W_RELATIVE,
+ text, ARRAYLENGTH(text));
+
+#if _WIN32_WINNT >= 0x501
+ if (IS_COMMCTL6())
+ {
+ EDITBALLOONTIP bt;
+
+ bt.cbStruct = sizeof(bt);
+ bt.pszTitle = title;
+ bt.pszText = text;
+ bt.ttiIcon = TTI_WARNING;
+
+ SendDlgItemMessage(hwnd, IDC_CFG_FCNAME,
+ EM_SHOWBALLOONTIP,
+ 0,
+ (LPARAM) &bt);
+ } else {
+#endif
+ MessageBox(hwnd, text, title, MB_OK | MB_ICONWARNING);
+#if _WIN32_WINNT >= 0x501
+ }
+#endif
+ }
+
+ k5_add_file_cc(&d->work, path);
+
+ k5_ccc_update_ui(hwnd, d);
+ }
+ return TRUE;
+
+ case MAKEWPARAM(IDC_CFG_BROWSE, BN_CLICKED):
+ {
+ OPENFILENAME ofn;
+ wchar_t path[MAX_PATH * 8];
+ wchar_t title[128];
+
+ ZeroMemory(&ofn, sizeof(ofn));
+ ZeroMemory(path, sizeof(path));
+
+ GetDlgItemText(hwnd, IDC_CFG_FCNAME,
+ path, ARRAYLENGTH(path));
+
+ /* don't pass in invalid paths */
+ if (!PathFileExists(path))
+ *path = 0;
+
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = hwnd;
+ ofn.lpstrFilter = L"All files\0*.*\0\0";
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFile = path;
+ ofn.nMaxFile = ARRAYLENGTH(path);
+ ofn.lpstrTitle = title;
+
+ LoadString(hResModule, IDS_CFG_FCOPENTITLE,
+ title, ARRAYLENGTH(title));
+
+ ofn.Flags = OFN_ALLOWMULTISELECT |
+ OFN_DONTADDTORECENT |
+ OFN_FORCESHOWHIDDEN |
+ OFN_EXPLORER;
+
+ if (GetOpenFileName(&ofn)) {
+ wchar_t * p;
+ wchar_t spath[MAX_PATH];
+
+ p = multi_string_next(path);
+ if (p) {
+ /* multi select */
+ for(;p && *p; p = multi_string_next(p)) {
+ StringCbCopy(spath, sizeof(spath), path);
+ PathAppend(spath, p);
+
+ k5_add_file_cc(&d->work, spath);
+ }
+ } else {
+ /* single select */
+ k5_add_file_cc(&d->work, path);
+ }
+ k5_ccc_update_ui(hwnd, d);
+ }
+ }
+ return TRUE;
+
+ case MAKEWPARAM(IDC_CFG_REMOVE, BN_CLICKED):
+ {
+ khm_size i;
+ int lv_idx;
+ HWND lv;
+ wchar_t buf[MAX_PATH];
+
+ lv = GetDlgItem(hwnd, IDC_CFG_FCLIST);
+#ifdef DEBUG
+ assert(lv);
+#endif
+
+ lv_idx = -1;
+ while((lv_idx = ListView_GetNextItem(lv, lv_idx,
+ LVNI_SELECTED)) != -1) {
+ ListView_GetItemText(lv, lv_idx, 0, buf, ARRAYLENGTH(buf));
+ for (i=0; i < d->work.n_file_ccs; i++) {
+ if (!_wcsicmp(buf, d->work.file_ccs[i].path)) {
+ k5_del_file_cc(&d->work, i);
+ break;
+ }
+ }
+ }
+
+ k5_ccc_update_ui(hwnd, d);
+ }
+ return TRUE;
+
+ case MAKEWPARAM(IDC_CFG_INCAPI, BN_CLICKED):
+ case MAKEWPARAM(IDC_CFG_INCMSLSA, BN_CLICKED):
+ k5_ccc_update_data(hwnd, &d->work);
+ k5_ccc_update_ui(hwnd, d);
+ return TRUE;
+ }
+ break;
+
+ case WM_DESTROY:
+ d = (k5_ccc_dlg_data *) (DWORD_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ k5_free_file_ccs(&d->work);
+ k5_free_file_ccs(&d->save);
+ PFREE(d);
+ return TRUE;
+
+ case KHUI_WM_CFG_NOTIFY:
+ d = (k5_ccc_dlg_data *) (DWORD_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ switch(HIWORD(wParam)) {
+ case WMCFG_APPLY:
+ if (k5_ccc_get_mod(d)) {
+ k5_write_file_cc_data(&d->work);
+ k5_copy_file_cc_data(&d->save, &d->work);
+ khui_cfg_set_flags(d->node,
+ KHUI_CNFLAG_APPLIED,
+ KHUI_CNFLAG_APPLIED);
+ k5_ccc_update_ui(hwnd, d);
+
+ kmq_post_sub_msg(k5_sub, KMSG_CRED, KMSG_CRED_REFRESH, 0, 0);
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
diff --git a/src/windows/identity/plugins/krb5/krb5configid.c b/src/windows/identity/plugins/krb5/krb5configid.c
index e09281906..b5af1c2b2 100644
--- a/src/windows/identity/plugins/krb5/krb5configid.c
+++ b/src/windows/identity/plugins/krb5/krb5configid.c
@@ -1,355 +1,355 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<krb5.h>
-#include<assert.h>
-#include<lm.h>
-#include<commctrl.h>
-#include<shlwapi.h>
-
-#include<strsafe.h>
-
-typedef struct tag_k5_id_dlg_data {
- khui_config_init_data cfg;
-
- khm_handle ident;
-
- khui_tracker tc_life;
- khui_tracker tc_renew;
-
- wchar_t ccache[KRB5_MAXCCH_CCNAME];
-
- khm_boolean renewable;
- khm_boolean forwardable;
- khm_boolean proxiable;
- khm_boolean addressless;
-
- DWORD public_ip;
-
- time_t life;
- time_t renew_life;
-} k5_id_dlg_data;
-
-static void
-k5_id_read_params(k5_id_dlg_data * d) {
-
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- khm_size cb;
- khm_int32 rv;
- khm_int32 t;
- khm_handle csp_ident;
- khm_handle csp_idroot = NULL;
-
- cb = sizeof(idname);
- rv = khui_cfg_get_name(d->cfg.ctx_node, idname, &cb);
-#ifdef DEBUG
- assert(KHM_SUCCEEDED(rv));
-#endif
-
- rv = kcdb_identity_create(idname, 0, &d->ident);
-#ifdef DEBUG
- assert(KHM_SUCCEEDED(rv));
-#endif
-
- rv = kcdb_identity_get_config(d->ident, 0, &csp_idroot);
- if (KHM_SUCCEEDED(rv) &&
- KHM_SUCCEEDED(khc_open_space(csp_idroot, CSNAME_KRB5CRED, 0,
- &csp_ident))) {
- khc_shadow_space(csp_ident, csp_params);
- } else {
- csp_ident = csp_params;
- }
-
- if (csp_idroot)
- khc_close_space(csp_idroot);
-
- rv = khc_read_int32(csp_ident, L"DefaultLifetime", &t);
- if (KHM_SUCCEEDED(rv))
- d->life = t;
- else
- d->life = 36000;
-
- rv = khc_read_int32(csp_ident, L"DefaultRenewLifetime", &t);
- if (KHM_SUCCEEDED(rv))
- d->renew_life = t;
- else
- d->renew_life = 604800;
-
- rv = khc_read_int32(csp_ident, L"Renewable", &t);
- if (KHM_SUCCEEDED(rv))
- d->renewable = !!t;
- else
- d->renewable = TRUE;
-
- rv = khc_read_int32(csp_ident, L"Forwardable", &t);
- if (KHM_SUCCEEDED(rv))
- d->forwardable = !!t;
- else
- d->forwardable = FALSE;
-
- rv = khc_read_int32(csp_ident, L"Proxiable", &t);
- if (KHM_SUCCEEDED(rv))
- d->proxiable = !!t;
- else
- d->proxiable = FALSE;
-
- rv = khc_read_int32(csp_ident, L"Addressless", &t);
- if (KHM_SUCCEEDED(rv))
- d->addressless = !!t;
- else
- d->addressless = TRUE;
-
- rv = khc_read_int32(csp_ident, L"PublicIP", &t);
- if (KHM_SUCCEEDED(rv))
- d->public_ip = (khm_ui_4) t;
- else
- d->public_ip = 0;
-
- cb = sizeof(d->ccache);
- rv = khc_read_string(csp_ident, L"DefaultCCName", d->ccache, &cb);
- if (KHM_FAILED(rv) || cb <= sizeof(wchar_t)) {
- cb = sizeof(d->ccache);
- if (KHM_FAILED(kcdb_identity_get_attr(d->ident, attr_id_krb5_ccname,
- NULL, d->ccache, &cb)))
- ZeroMemory(d->ccache, sizeof(d->ccache));
- }
-
- khui_tracker_initialize(&d->tc_life);
- d->tc_life.current = d->life;
- d->tc_life.min = 0;
- d->tc_life.max = 3600 * 24 * 7;
-
- khui_tracker_initialize(&d->tc_renew);
- d->tc_renew.current = d->renew_life;
- d->tc_renew.min = 0;
- d->tc_renew.max = 3600 * 24 * 30;
-
- if (csp_ident != csp_params)
- khc_close_space(csp_ident);
-}
-
-static khm_boolean
-k5_id_is_mod(HWND hw, k5_id_dlg_data * d) {
- wchar_t ccache[KRB5_MAXCCH_CCNAME];
- DWORD dwaddress = 0;
-
- GetDlgItemText(hw, IDC_CFG_CCACHE, ccache, ARRAYLENGTH(ccache));
-
- SendDlgItemMessage(hw, IDC_CFG_PUBLICIP, IPM_GETADDRESS,
- 0, (LPARAM) &dwaddress);
-
- if (_wcsicmp(ccache, d->ccache) ||
-
- d->tc_renew.current != d->renew_life ||
-
- d->tc_life.current != d->life ||
-
- (IsDlgButtonChecked(hw, IDC_CFG_RENEW) == BST_CHECKED) != d->renewable ||
-
- (IsDlgButtonChecked(hw, IDC_CFG_FORWARD) == BST_CHECKED) != d->forwardable ||
-
- (IsDlgButtonChecked(hw, IDC_CFG_ADDRESSLESS) == BST_CHECKED)
- != d->addressless ||
-
- dwaddress != d->public_ip)
-
- return TRUE;
-
- return FALSE;
-}
-
-static void
-k5_id_check_mod(HWND hw, k5_id_dlg_data * d) {
- BOOL modified = k5_id_is_mod(hw, d);
-
- khui_cfg_set_flags_inst(&d->cfg,
- (modified)?KHUI_CNFLAG_MODIFIED:0,
- KHUI_CNFLAG_MODIFIED);
-}
-
-static void
-k5_id_write_params(HWND hw, k5_id_dlg_data * d) {
-
- khm_handle csp_idroot = NULL;
- khm_handle csp_ident = NULL;
- wchar_t ccache[KRB5_MAXCCH_CCNAME];
- khm_size cb;
- khm_int32 rv;
- khm_boolean b;
- DWORD dwaddress = 0;
-
- if (!k5_id_is_mod(hw, d))
- return;
-
- rv = kcdb_identity_get_config(d->ident, KHM_FLAG_CREATE, &csp_idroot);
- if (KHM_SUCCEEDED(rv)) {
- khc_open_space(csp_idroot, CSNAME_KRB5CRED,
- KHM_FLAG_CREATE,
- &csp_ident);
- }
-
- if (csp_idroot)
- khc_close_space(csp_idroot);
-
- if (!csp_ident)
- return;
-
- if (d->life != d->tc_life.current) {
- d->life = d->tc_life.current;
- khc_write_int32(csp_ident, L"DefaultLifetime", (khm_int32) d->life);
- }
-
- if (d->renew_life != d->tc_renew.current) {
- d->renew_life = d->tc_renew.current;
- khc_write_int32(csp_ident, L"DefaultRenewLifetime", (khm_int32) d->renew_life);
- }
-
- b = (IsDlgButtonChecked(hw, IDC_CFG_RENEW) == BST_CHECKED);
- if (b != d->renewable) {
- d->renewable = b;
- khc_write_int32(csp_ident, L"Renewable", (khm_int32) b);
- }
-
- b = (IsDlgButtonChecked(hw, IDC_CFG_FORWARD) == BST_CHECKED);
- if (b != d->forwardable) {
- d->forwardable = b;
- khc_write_int32(csp_ident, L"Forwardable", (khm_int32) b);
- }
-
- b = (IsDlgButtonChecked(hw, IDC_CFG_ADDRESSLESS) == BST_CHECKED);
- if (b != d->addressless) {
- d->addressless = b;
- khc_write_int32(csp_ident, L"Addressless", (khm_int32) b);
- }
-
- SendDlgItemMessage(hw, IDC_CFG_PUBLICIP, IPM_GETADDRESS,
- 0, (LPARAM) &dwaddress);
-
- if (dwaddress != d->public_ip) {
- d->public_ip = dwaddress;
- khc_write_int32(csp_ident, L"PublicIP", (khm_int32) dwaddress);
- }
-
- GetDlgItemText(hw, IDC_CFG_CCACHE, ccache, ARRAYLENGTH(ccache));
-
- if (SUCCEEDED(StringCbLength(ccache, sizeof(ccache), &cb)) &&
- _wcsicmp(ccache, d->ccache)) {
- khc_write_string(csp_ident, L"DefaultCCName", ccache);
- StringCbCopy(d->ccache, sizeof(d->ccache), ccache);
- } else {
- khc_remove_value(csp_ident, L"DefaultCCName", KCONF_FLAG_USER);
- }
-
- if (csp_ident)
- khc_close_space(csp_ident);
-
- khui_cfg_set_flags_inst(&d->cfg,
- KHUI_CNFLAG_APPLIED,
- KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED);
-}
-
-INT_PTR CALLBACK
-k5_id_tab_dlgproc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
-
- k5_id_dlg_data * d;
-
- switch(uMsg) {
- case WM_INITDIALOG:
- d = PMALLOC(sizeof(*d));
-#ifdef DEBUG
- assert(d);
-#endif
- ZeroMemory(d, sizeof(*d));
-
- d->cfg = *((khui_config_init_data *) lParam);
-
-#pragma warning(push)
-#pragma warning(disable: 4244)
- SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
-#pragma warning(pop)
-
- k5_id_read_params(d);
-
- khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFLIFE),
- &d->tc_life);
- khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFRLIFE),
- &d->tc_renew);
- khui_tracker_refresh(&d->tc_life);
- khui_tracker_refresh(&d->tc_renew);
-
- SetDlgItemText(hwnd, IDC_CFG_CCACHE, d->ccache);
-
- CheckDlgButton(hwnd, IDC_CFG_RENEW,
- (d->renewable? BST_CHECKED: BST_UNCHECKED));
-
- CheckDlgButton(hwnd, IDC_CFG_FORWARD,
- (d->forwardable? BST_CHECKED: BST_UNCHECKED));
-
- CheckDlgButton(hwnd, IDC_CFG_ADDRESSLESS,
- (d->addressless? BST_CHECKED: BST_UNCHECKED));
-
- SendDlgItemMessage(hwnd, IDC_CFG_PUBLICIP,
- IPM_SETADDRESS,
- 0, (LPARAM) d->public_ip);
- break;
-
- case WM_COMMAND:
- d = (k5_id_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (HIWORD(wParam) == EN_CHANGE ||
- HIWORD(wParam) == BN_CLICKED)
- k5_id_check_mod(hwnd, d);
- break;
-
- case KHUI_WM_CFG_NOTIFY:
- d = (k5_id_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (HIWORD(wParam) == WMCFG_APPLY) {
- k5_id_write_params(hwnd, d);
- }
- break;
-
- case WM_DESTROY:
- d = (k5_id_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- khui_tracker_kill_controls(&d->tc_life);
- khui_tracker_kill_controls(&d->tc_renew);
-
- if (d->ident)
- kcdb_identity_release(d->ident);
-
- PFREE(d);
- break;
- }
- return FALSE;
-}
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<krb5.h>
+#include<assert.h>
+#include<lm.h>
+#include<commctrl.h>
+#include<shlwapi.h>
+
+#include<strsafe.h>
+
+typedef struct tag_k5_id_dlg_data {
+ khui_config_init_data cfg;
+
+ khm_handle ident;
+
+ khui_tracker tc_life;
+ khui_tracker tc_renew;
+
+ wchar_t ccache[KRB5_MAXCCH_CCNAME];
+
+ khm_boolean renewable;
+ khm_boolean forwardable;
+ khm_boolean proxiable;
+ khm_boolean addressless;
+
+ DWORD public_ip;
+
+ time_t life;
+ time_t renew_life;
+} k5_id_dlg_data;
+
+static void
+k5_id_read_params(k5_id_dlg_data * d) {
+
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb;
+ khm_int32 rv;
+ khm_int32 t;
+ khm_handle csp_ident;
+ khm_handle csp_idroot = NULL;
+
+ cb = sizeof(idname);
+ rv = khui_cfg_get_name(d->cfg.ctx_node, idname, &cb);
+#ifdef DEBUG
+ assert(KHM_SUCCEEDED(rv));
+#endif
+
+ rv = kcdb_identity_create(idname, 0, &d->ident);
+#ifdef DEBUG
+ assert(KHM_SUCCEEDED(rv));
+#endif
+
+ rv = kcdb_identity_get_config(d->ident, 0, &csp_idroot);
+ if (KHM_SUCCEEDED(rv) &&
+ KHM_SUCCEEDED(khc_open_space(csp_idroot, CSNAME_KRB5CRED, 0,
+ &csp_ident))) {
+ khc_shadow_space(csp_ident, csp_params);
+ } else {
+ csp_ident = csp_params;
+ }
+
+ if (csp_idroot)
+ khc_close_space(csp_idroot);
+
+ rv = khc_read_int32(csp_ident, L"DefaultLifetime", &t);
+ if (KHM_SUCCEEDED(rv))
+ d->life = t;
+ else
+ d->life = 36000;
+
+ rv = khc_read_int32(csp_ident, L"DefaultRenewLifetime", &t);
+ if (KHM_SUCCEEDED(rv))
+ d->renew_life = t;
+ else
+ d->renew_life = 604800;
+
+ rv = khc_read_int32(csp_ident, L"Renewable", &t);
+ if (KHM_SUCCEEDED(rv))
+ d->renewable = !!t;
+ else
+ d->renewable = TRUE;
+
+ rv = khc_read_int32(csp_ident, L"Forwardable", &t);
+ if (KHM_SUCCEEDED(rv))
+ d->forwardable = !!t;
+ else
+ d->forwardable = FALSE;
+
+ rv = khc_read_int32(csp_ident, L"Proxiable", &t);
+ if (KHM_SUCCEEDED(rv))
+ d->proxiable = !!t;
+ else
+ d->proxiable = FALSE;
+
+ rv = khc_read_int32(csp_ident, L"Addressless", &t);
+ if (KHM_SUCCEEDED(rv))
+ d->addressless = !!t;
+ else
+ d->addressless = TRUE;
+
+ rv = khc_read_int32(csp_ident, L"PublicIP", &t);
+ if (KHM_SUCCEEDED(rv))
+ d->public_ip = (khm_ui_4) t;
+ else
+ d->public_ip = 0;
+
+ cb = sizeof(d->ccache);
+ rv = khc_read_string(csp_ident, L"DefaultCCName", d->ccache, &cb);
+ if (KHM_FAILED(rv) || cb <= sizeof(wchar_t)) {
+ cb = sizeof(d->ccache);
+ if (KHM_FAILED(kcdb_identity_get_attr(d->ident, attr_id_krb5_ccname,
+ NULL, d->ccache, &cb)))
+ ZeroMemory(d->ccache, sizeof(d->ccache));
+ }
+
+ khui_tracker_initialize(&d->tc_life);
+ d->tc_life.current = d->life;
+ d->tc_life.min = 0;
+ d->tc_life.max = 3600 * 24 * 7;
+
+ khui_tracker_initialize(&d->tc_renew);
+ d->tc_renew.current = d->renew_life;
+ d->tc_renew.min = 0;
+ d->tc_renew.max = 3600 * 24 * 30;
+
+ if (csp_ident != csp_params)
+ khc_close_space(csp_ident);
+}
+
+static khm_boolean
+k5_id_is_mod(HWND hw, k5_id_dlg_data * d) {
+ wchar_t ccache[KRB5_MAXCCH_CCNAME];
+ DWORD dwaddress = 0;
+
+ GetDlgItemText(hw, IDC_CFG_CCACHE, ccache, ARRAYLENGTH(ccache));
+
+ SendDlgItemMessage(hw, IDC_CFG_PUBLICIP, IPM_GETADDRESS,
+ 0, (LPARAM) &dwaddress);
+
+ if (_wcsicmp(ccache, d->ccache) ||
+
+ d->tc_renew.current != d->renew_life ||
+
+ d->tc_life.current != d->life ||
+
+ (IsDlgButtonChecked(hw, IDC_CFG_RENEW) == BST_CHECKED) != d->renewable ||
+
+ (IsDlgButtonChecked(hw, IDC_CFG_FORWARD) == BST_CHECKED) != d->forwardable ||
+
+ (IsDlgButtonChecked(hw, IDC_CFG_ADDRESSLESS) == BST_CHECKED)
+ != d->addressless ||
+
+ dwaddress != d->public_ip)
+
+ return TRUE;
+
+ return FALSE;
+}
+
+static void
+k5_id_check_mod(HWND hw, k5_id_dlg_data * d) {
+ BOOL modified = k5_id_is_mod(hw, d);
+
+ khui_cfg_set_flags_inst(&d->cfg,
+ (modified)?KHUI_CNFLAG_MODIFIED:0,
+ KHUI_CNFLAG_MODIFIED);
+}
+
+static void
+k5_id_write_params(HWND hw, k5_id_dlg_data * d) {
+
+ khm_handle csp_idroot = NULL;
+ khm_handle csp_ident = NULL;
+ wchar_t ccache[KRB5_MAXCCH_CCNAME];
+ khm_size cb;
+ khm_int32 rv;
+ khm_boolean b;
+ DWORD dwaddress = 0;
+
+ if (!k5_id_is_mod(hw, d))
+ return;
+
+ rv = kcdb_identity_get_config(d->ident, KHM_FLAG_CREATE, &csp_idroot);
+ if (KHM_SUCCEEDED(rv)) {
+ khc_open_space(csp_idroot, CSNAME_KRB5CRED,
+ KHM_FLAG_CREATE,
+ &csp_ident);
+ }
+
+ if (csp_idroot)
+ khc_close_space(csp_idroot);
+
+ if (!csp_ident)
+ return;
+
+ if (d->life != d->tc_life.current) {
+ d->life = d->tc_life.current;
+ khc_write_int32(csp_ident, L"DefaultLifetime", (khm_int32) d->life);
+ }
+
+ if (d->renew_life != d->tc_renew.current) {
+ d->renew_life = d->tc_renew.current;
+ khc_write_int32(csp_ident, L"DefaultRenewLifetime", (khm_int32) d->renew_life);
+ }
+
+ b = (IsDlgButtonChecked(hw, IDC_CFG_RENEW) == BST_CHECKED);
+ if (b != d->renewable) {
+ d->renewable = b;
+ khc_write_int32(csp_ident, L"Renewable", (khm_int32) b);
+ }
+
+ b = (IsDlgButtonChecked(hw, IDC_CFG_FORWARD) == BST_CHECKED);
+ if (b != d->forwardable) {
+ d->forwardable = b;
+ khc_write_int32(csp_ident, L"Forwardable", (khm_int32) b);
+ }
+
+ b = (IsDlgButtonChecked(hw, IDC_CFG_ADDRESSLESS) == BST_CHECKED);
+ if (b != d->addressless) {
+ d->addressless = b;
+ khc_write_int32(csp_ident, L"Addressless", (khm_int32) b);
+ }
+
+ SendDlgItemMessage(hw, IDC_CFG_PUBLICIP, IPM_GETADDRESS,
+ 0, (LPARAM) &dwaddress);
+
+ if (dwaddress != d->public_ip) {
+ d->public_ip = dwaddress;
+ khc_write_int32(csp_ident, L"PublicIP", (khm_int32) dwaddress);
+ }
+
+ GetDlgItemText(hw, IDC_CFG_CCACHE, ccache, ARRAYLENGTH(ccache));
+
+ if (SUCCEEDED(StringCbLength(ccache, sizeof(ccache), &cb)) &&
+ _wcsicmp(ccache, d->ccache)) {
+ khc_write_string(csp_ident, L"DefaultCCName", ccache);
+ StringCbCopy(d->ccache, sizeof(d->ccache), ccache);
+ } else {
+ khc_remove_value(csp_ident, L"DefaultCCName", KCONF_FLAG_USER);
+ }
+
+ if (csp_ident)
+ khc_close_space(csp_ident);
+
+ khui_cfg_set_flags_inst(&d->cfg,
+ KHUI_CNFLAG_APPLIED,
+ KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED);
+}
+
+INT_PTR CALLBACK
+k5_id_tab_dlgproc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+
+ k5_id_dlg_data * d;
+
+ switch(uMsg) {
+ case WM_INITDIALOG:
+ d = PMALLOC(sizeof(*d));
+#ifdef DEBUG
+ assert(d);
+#endif
+ ZeroMemory(d, sizeof(*d));
+
+ d->cfg = *((khui_config_init_data *) lParam);
+
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
+#pragma warning(pop)
+
+ k5_id_read_params(d);
+
+ khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFLIFE),
+ &d->tc_life);
+ khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFRLIFE),
+ &d->tc_renew);
+ khui_tracker_refresh(&d->tc_life);
+ khui_tracker_refresh(&d->tc_renew);
+
+ SetDlgItemText(hwnd, IDC_CFG_CCACHE, d->ccache);
+
+ CheckDlgButton(hwnd, IDC_CFG_RENEW,
+ (d->renewable? BST_CHECKED: BST_UNCHECKED));
+
+ CheckDlgButton(hwnd, IDC_CFG_FORWARD,
+ (d->forwardable? BST_CHECKED: BST_UNCHECKED));
+
+ CheckDlgButton(hwnd, IDC_CFG_ADDRESSLESS,
+ (d->addressless? BST_CHECKED: BST_UNCHECKED));
+
+ SendDlgItemMessage(hwnd, IDC_CFG_PUBLICIP,
+ IPM_SETADDRESS,
+ 0, (LPARAM) d->public_ip);
+ break;
+
+ case WM_COMMAND:
+ d = (k5_id_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (HIWORD(wParam) == EN_CHANGE ||
+ HIWORD(wParam) == BN_CLICKED)
+ k5_id_check_mod(hwnd, d);
+ break;
+
+ case KHUI_WM_CFG_NOTIFY:
+ d = (k5_id_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (HIWORD(wParam) == WMCFG_APPLY) {
+ k5_id_write_params(hwnd, d);
+ }
+ break;
+
+ case WM_DESTROY:
+ d = (k5_id_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ khui_tracker_kill_controls(&d->tc_life);
+ khui_tracker_kill_controls(&d->tc_renew);
+
+ if (d->ident)
+ kcdb_identity_release(d->ident);
+
+ PFREE(d);
+ break;
+ }
+ return FALSE;
+}
diff --git a/src/windows/identity/plugins/krb5/krb5configids.c b/src/windows/identity/plugins/krb5/krb5configids.c
index 5f4729253..8d6afd473 100644
--- a/src/windows/identity/plugins/krb5/krb5configids.c
+++ b/src/windows/identity/plugins/krb5/krb5configids.c
@@ -1,270 +1,270 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<krb5.h>
-#include<assert.h>
-#include<lm.h>
-#include<commctrl.h>
-#include<shlwapi.h>
-
-typedef struct tag_k5_ids_opts {
- khm_int32 renewable;
- khm_int32 forwardable;
- khm_int32 addressless;
-} k5_ids_opts;
-
-typedef struct tag_k5_ids_dlg_data {
- khui_config_init_data cfg;
-
- khui_tracker tc_life;
- khui_tracker tc_renew;
- khui_tracker tc_life_min;
- khui_tracker tc_life_max;
- khui_tracker tc_renew_min;
- khui_tracker tc_renew_max;
-
- time_t life;
- time_t renew_life;
- time_t life_min;
- time_t life_max;
- time_t renew_min;
- time_t renew_max;
-
- k5_ids_opts opt;
- k5_ids_opts opt_saved;
-
-} k5_ids_dlg_data;
-
-static khm_boolean
-k5_ids_is_mod(k5_ids_dlg_data * d) {
- if (d->life != d->tc_life.current ||
- d->renew_life != d->tc_renew.current ||
- d->life_max != d->tc_life_max.current ||
- d->life_min != d->tc_life_min.current ||
- d->renew_max != d->tc_renew_max.current ||
- d->renew_min != d->tc_renew_min.current ||
- !!d->opt.renewable != !!d->opt_saved.renewable ||
- !!d->opt.forwardable != !!d->opt_saved.forwardable ||
- !!d->opt.addressless != !!d->opt_saved.addressless)
- return TRUE;
- return FALSE;
-}
-
-static void
-k5_ids_check_mod(k5_ids_dlg_data * d) {
- BOOL modified = k5_ids_is_mod(d);
-
- khui_cfg_set_flags_inst(&d->cfg,
- (modified)?KHUI_CNFLAG_MODIFIED:0,
- KHUI_CNFLAG_MODIFIED);
-}
-
-static void
-k5_ids_write_params(k5_ids_dlg_data * d) {
-
- khm_int32 rv;
-
-#ifdef DEBUG
- assert(csp_params);
-#endif
-
- if (!k5_ids_is_mod(d))
- return;
-
-#define WRITEPARAM(po,pn,vn) \
- if (po != pn) { \
- po = pn; \
- rv = khc_write_int32(csp_params, vn, (khm_int32) po); \
- assert(KHM_SUCCEEDED(rv)); \
- }
-
- WRITEPARAM(d->life,d->tc_life.current, L"DefaultLifetime");
- WRITEPARAM(d->renew_life,d->tc_renew.current, L"DefaultRenewLifetime");
- WRITEPARAM(d->life_max,d->tc_life_max.current, L"MaxLifetime");
- WRITEPARAM(d->life_min,d->tc_life_min.current, L"MinLifetime");
- WRITEPARAM(d->renew_max,d->tc_renew_max.current, L"MaxRenewLifetime");
- WRITEPARAM(d->renew_min,d->tc_renew_min.current, L"MinRenewLifetime");
- WRITEPARAM(d->opt_saved.renewable, d->opt.renewable, L"Renewable");
- WRITEPARAM(d->opt_saved.forwardable, d->opt.forwardable, L"Forwardable");
- WRITEPARAM(d->opt_saved.addressless, d->opt.addressless, L"Addressless");
-
-#undef WRITEPARAM
-
- khui_cfg_set_flags_inst(&d->cfg,
- KHUI_CNFLAG_APPLIED,
- KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED);
-}
-
-static void
-k5_ids_read_params(k5_ids_dlg_data * d) {
- k5_params p;
-
- khm_krb5_get_identity_params(NULL, &p);
-
- d->life = p.lifetime;
- d->life_max = p.lifetime_max;
- d->life_min = p.lifetime_min;
-
- d->renew_life = p.renew_life;
- d->renew_max = p.renew_life_max;
- d->renew_min = p.renew_life_min;
-
- d->opt_saved.forwardable = p.forwardable;
- d->opt_saved.renewable = p.renewable;
- d->opt_saved.addressless = p.addressless;
-
- d->opt = d->opt_saved;
-
- khui_tracker_initialize(&d->tc_life);
- d->tc_life.current = d->life;
- d->tc_life.min = 0;
- d->tc_life.max = 3600 * 24 * 7;
-
- khui_tracker_initialize(&d->tc_renew);
- d->tc_renew.current = d->renew_life;
- d->tc_renew.min = 0;
- d->tc_renew.max = 3600 * 24 * 30;
-
- khui_tracker_initialize(&d->tc_life_min);
- d->tc_life_min.current = d->life_min;
- d->tc_life_min.min = d->tc_life.min;
- d->tc_life_min.max = d->tc_life.max;
-
- khui_tracker_initialize(&d->tc_life_max);
- d->tc_life_max.current = d->life_max;
- d->tc_life_max.min = d->tc_life.min;
- d->tc_life_max.max = d->tc_life.max;
-
- khui_tracker_initialize(&d->tc_renew_min);
- d->tc_renew_min.current = d->renew_min;
- d->tc_renew_min.min = d->tc_renew.min;
- d->tc_renew_min.max = d->tc_renew.max;
-
- khui_tracker_initialize(&d->tc_renew_max);
- d->tc_renew_max.current = d->renew_max;
- d->tc_renew_max.min = d->tc_renew.min;
- d->tc_renew_max.max = d->tc_renew.max;
-}
-
-INT_PTR CALLBACK
-k5_ids_tab_dlgproc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
- k5_ids_dlg_data * d;
-
- switch(uMsg) {
- case WM_INITDIALOG:
- d = PMALLOC(sizeof(*d));
-#ifdef DEBUG
- assert(d);
-#endif
- ZeroMemory(d, sizeof(*d));
-#pragma warning(push)
-#pragma warning(disable: 4244)
- SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
-#pragma warning(pop)
-
- d->cfg = *((khui_config_init_data *) lParam);
-
- k5_ids_read_params(d);
-
- khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFLIFE),
- &d->tc_life);
- khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFRLIFE),
- &d->tc_renew);
- khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_LRNG_MIN),
- &d->tc_life_min);
- khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_LRNG_MAX),
- &d->tc_life_max);
- khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_RLRNG_MIN),
- &d->tc_renew_min);
- khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_RLRNG_MAX),
- &d->tc_renew_max);
- khui_tracker_refresh(&d->tc_life);
- khui_tracker_refresh(&d->tc_life_min);
- khui_tracker_refresh(&d->tc_life_max);
- khui_tracker_refresh(&d->tc_renew);
- khui_tracker_refresh(&d->tc_renew_min);
- khui_tracker_refresh(&d->tc_renew_max);
-
- CheckDlgButton(hwnd, IDC_CFG_RENEW, (d->opt.renewable ? BST_CHECKED: BST_UNCHECKED));
- CheckDlgButton(hwnd, IDC_CFG_FORWARD, (d->opt.forwardable ? BST_CHECKED: BST_UNCHECKED));
- CheckDlgButton(hwnd, IDC_CFG_ADDRESSLESS, (d->opt.addressless ? BST_CHECKED: BST_UNCHECKED));
- break;
-
- case WM_COMMAND:
- d = (k5_ids_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (HIWORD(wParam) == EN_CHANGE) {
- k5_ids_check_mod(d);
- } else if (HIWORD(wParam) == BN_CLICKED) {
- switch (LOWORD(wParam)) {
- case IDC_CFG_RENEW:
- d->opt.renewable = (IsDlgButtonChecked(hwnd, IDC_CFG_RENEW) == BST_CHECKED);
- break;
-
- case IDC_CFG_FORWARD:
- d->opt.forwardable = (IsDlgButtonChecked(hwnd, IDC_CFG_FORWARD) == BST_CHECKED);
- break;
-
- case IDC_CFG_ADDRESSLESS:
- d->opt.addressless = (IsDlgButtonChecked(hwnd, IDC_CFG_ADDRESSLESS) == BST_CHECKED);
- break;
- }
-
- k5_ids_check_mod(d);
- }
- break;
-
- case KHUI_WM_CFG_NOTIFY:
- d = (k5_ids_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
- if (HIWORD(wParam) == WMCFG_APPLY) {
- k5_ids_write_params(d);
- }
- break;
-
- case WM_DESTROY:
- d = (k5_ids_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- khui_tracker_kill_controls(&d->tc_life);
- khui_tracker_kill_controls(&d->tc_renew);
- khui_tracker_kill_controls(&d->tc_life_min);
- khui_tracker_kill_controls(&d->tc_life_max);
- khui_tracker_kill_controls(&d->tc_renew_min);
- khui_tracker_kill_controls(&d->tc_renew_max);
-
- PFREE(d);
- break;
- }
- return FALSE;
-}
-
-
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<krb5.h>
+#include<assert.h>
+#include<lm.h>
+#include<commctrl.h>
+#include<shlwapi.h>
+
+typedef struct tag_k5_ids_opts {
+ khm_int32 renewable;
+ khm_int32 forwardable;
+ khm_int32 addressless;
+} k5_ids_opts;
+
+typedef struct tag_k5_ids_dlg_data {
+ khui_config_init_data cfg;
+
+ khui_tracker tc_life;
+ khui_tracker tc_renew;
+ khui_tracker tc_life_min;
+ khui_tracker tc_life_max;
+ khui_tracker tc_renew_min;
+ khui_tracker tc_renew_max;
+
+ time_t life;
+ time_t renew_life;
+ time_t life_min;
+ time_t life_max;
+ time_t renew_min;
+ time_t renew_max;
+
+ k5_ids_opts opt;
+ k5_ids_opts opt_saved;
+
+} k5_ids_dlg_data;
+
+static khm_boolean
+k5_ids_is_mod(k5_ids_dlg_data * d) {
+ if (d->life != d->tc_life.current ||
+ d->renew_life != d->tc_renew.current ||
+ d->life_max != d->tc_life_max.current ||
+ d->life_min != d->tc_life_min.current ||
+ d->renew_max != d->tc_renew_max.current ||
+ d->renew_min != d->tc_renew_min.current ||
+ !!d->opt.renewable != !!d->opt_saved.renewable ||
+ !!d->opt.forwardable != !!d->opt_saved.forwardable ||
+ !!d->opt.addressless != !!d->opt_saved.addressless)
+ return TRUE;
+ return FALSE;
+}
+
+static void
+k5_ids_check_mod(k5_ids_dlg_data * d) {
+ BOOL modified = k5_ids_is_mod(d);
+
+ khui_cfg_set_flags_inst(&d->cfg,
+ (modified)?KHUI_CNFLAG_MODIFIED:0,
+ KHUI_CNFLAG_MODIFIED);
+}
+
+static void
+k5_ids_write_params(k5_ids_dlg_data * d) {
+
+ khm_int32 rv;
+
+#ifdef DEBUG
+ assert(csp_params);
+#endif
+
+ if (!k5_ids_is_mod(d))
+ return;
+
+#define WRITEPARAM(po,pn,vn) \
+ if (po != pn) { \
+ po = pn; \
+ rv = khc_write_int32(csp_params, vn, (khm_int32) po); \
+ assert(KHM_SUCCEEDED(rv)); \
+ }
+
+ WRITEPARAM(d->life,d->tc_life.current, L"DefaultLifetime");
+ WRITEPARAM(d->renew_life,d->tc_renew.current, L"DefaultRenewLifetime");
+ WRITEPARAM(d->life_max,d->tc_life_max.current, L"MaxLifetime");
+ WRITEPARAM(d->life_min,d->tc_life_min.current, L"MinLifetime");
+ WRITEPARAM(d->renew_max,d->tc_renew_max.current, L"MaxRenewLifetime");
+ WRITEPARAM(d->renew_min,d->tc_renew_min.current, L"MinRenewLifetime");
+ WRITEPARAM(d->opt_saved.renewable, d->opt.renewable, L"Renewable");
+ WRITEPARAM(d->opt_saved.forwardable, d->opt.forwardable, L"Forwardable");
+ WRITEPARAM(d->opt_saved.addressless, d->opt.addressless, L"Addressless");
+
+#undef WRITEPARAM
+
+ khui_cfg_set_flags_inst(&d->cfg,
+ KHUI_CNFLAG_APPLIED,
+ KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED);
+}
+
+static void
+k5_ids_read_params(k5_ids_dlg_data * d) {
+ k5_params p;
+
+ khm_krb5_get_identity_params(NULL, &p);
+
+ d->life = p.lifetime;
+ d->life_max = p.lifetime_max;
+ d->life_min = p.lifetime_min;
+
+ d->renew_life = p.renew_life;
+ d->renew_max = p.renew_life_max;
+ d->renew_min = p.renew_life_min;
+
+ d->opt_saved.forwardable = p.forwardable;
+ d->opt_saved.renewable = p.renewable;
+ d->opt_saved.addressless = p.addressless;
+
+ d->opt = d->opt_saved;
+
+ khui_tracker_initialize(&d->tc_life);
+ d->tc_life.current = d->life;
+ d->tc_life.min = 0;
+ d->tc_life.max = 3600 * 24 * 7;
+
+ khui_tracker_initialize(&d->tc_renew);
+ d->tc_renew.current = d->renew_life;
+ d->tc_renew.min = 0;
+ d->tc_renew.max = 3600 * 24 * 30;
+
+ khui_tracker_initialize(&d->tc_life_min);
+ d->tc_life_min.current = d->life_min;
+ d->tc_life_min.min = d->tc_life.min;
+ d->tc_life_min.max = d->tc_life.max;
+
+ khui_tracker_initialize(&d->tc_life_max);
+ d->tc_life_max.current = d->life_max;
+ d->tc_life_max.min = d->tc_life.min;
+ d->tc_life_max.max = d->tc_life.max;
+
+ khui_tracker_initialize(&d->tc_renew_min);
+ d->tc_renew_min.current = d->renew_min;
+ d->tc_renew_min.min = d->tc_renew.min;
+ d->tc_renew_min.max = d->tc_renew.max;
+
+ khui_tracker_initialize(&d->tc_renew_max);
+ d->tc_renew_max.current = d->renew_max;
+ d->tc_renew_max.min = d->tc_renew.min;
+ d->tc_renew_max.max = d->tc_renew.max;
+}
+
+INT_PTR CALLBACK
+k5_ids_tab_dlgproc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+ k5_ids_dlg_data * d;
+
+ switch(uMsg) {
+ case WM_INITDIALOG:
+ d = PMALLOC(sizeof(*d));
+#ifdef DEBUG
+ assert(d);
+#endif
+ ZeroMemory(d, sizeof(*d));
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
+#pragma warning(pop)
+
+ d->cfg = *((khui_config_init_data *) lParam);
+
+ k5_ids_read_params(d);
+
+ khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFLIFE),
+ &d->tc_life);
+ khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFRLIFE),
+ &d->tc_renew);
+ khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_LRNG_MIN),
+ &d->tc_life_min);
+ khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_LRNG_MAX),
+ &d->tc_life_max);
+ khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_RLRNG_MIN),
+ &d->tc_renew_min);
+ khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_RLRNG_MAX),
+ &d->tc_renew_max);
+ khui_tracker_refresh(&d->tc_life);
+ khui_tracker_refresh(&d->tc_life_min);
+ khui_tracker_refresh(&d->tc_life_max);
+ khui_tracker_refresh(&d->tc_renew);
+ khui_tracker_refresh(&d->tc_renew_min);
+ khui_tracker_refresh(&d->tc_renew_max);
+
+ CheckDlgButton(hwnd, IDC_CFG_RENEW, (d->opt.renewable ? BST_CHECKED: BST_UNCHECKED));
+ CheckDlgButton(hwnd, IDC_CFG_FORWARD, (d->opt.forwardable ? BST_CHECKED: BST_UNCHECKED));
+ CheckDlgButton(hwnd, IDC_CFG_ADDRESSLESS, (d->opt.addressless ? BST_CHECKED: BST_UNCHECKED));
+ break;
+
+ case WM_COMMAND:
+ d = (k5_ids_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (HIWORD(wParam) == EN_CHANGE) {
+ k5_ids_check_mod(d);
+ } else if (HIWORD(wParam) == BN_CLICKED) {
+ switch (LOWORD(wParam)) {
+ case IDC_CFG_RENEW:
+ d->opt.renewable = (IsDlgButtonChecked(hwnd, IDC_CFG_RENEW) == BST_CHECKED);
+ break;
+
+ case IDC_CFG_FORWARD:
+ d->opt.forwardable = (IsDlgButtonChecked(hwnd, IDC_CFG_FORWARD) == BST_CHECKED);
+ break;
+
+ case IDC_CFG_ADDRESSLESS:
+ d->opt.addressless = (IsDlgButtonChecked(hwnd, IDC_CFG_ADDRESSLESS) == BST_CHECKED);
+ break;
+ }
+
+ k5_ids_check_mod(d);
+ }
+ break;
+
+ case KHUI_WM_CFG_NOTIFY:
+ d = (k5_ids_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+ if (HIWORD(wParam) == WMCFG_APPLY) {
+ k5_ids_write_params(d);
+ }
+ break;
+
+ case WM_DESTROY:
+ d = (k5_ids_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ khui_tracker_kill_controls(&d->tc_life);
+ khui_tracker_kill_controls(&d->tc_renew);
+ khui_tracker_kill_controls(&d->tc_life_min);
+ khui_tracker_kill_controls(&d->tc_life_max);
+ khui_tracker_kill_controls(&d->tc_renew_min);
+ khui_tracker_kill_controls(&d->tc_renew_max);
+
+ PFREE(d);
+ break;
+ }
+ return FALSE;
+}
+
+
diff --git a/src/windows/identity/plugins/krb5/krb5funcs.c b/src/windows/identity/plugins/krb5/krb5funcs.c
index e66e755a7..6f657e851 100644
--- a/src/windows/identity/plugins/krb5/krb5funcs.c
+++ b/src/windows/identity/plugins/krb5/krb5funcs.c
@@ -1,3487 +1,3487 @@
-/*
-* Copyright (c) 2005 Massachusetts Institute of Technology
-* Copyright (c) 2006,2007 Secure Endpoints Inc.
-*
-* Permission is hereby granted, free of charge, to any person
-* obtaining a copy of this software and associated documentation
-* files (the "Software"), to deal in the Software without
-* restriction, including without limitation the rights to use, copy,
-* modify, merge, publish, distribute, sublicense, and/or sell copies
-* of the Software, and to permit persons to whom the Software is
-* furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be
-* included in all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-* SOFTWARE.
-*/
-
-/* $Id$ */
-
-/* Originally this was krb5routines.c in Leash sources. Subsequently
- * modified and adapted for NetIDMgr */
-
-#include<krbcred.h>
-#include<kherror.h>
-
-#define SECURITY_WIN32
-#include <security.h>
-
-#include <string.h>
-#include <time.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <strsafe.h>
-
-long
-khm_convert524(krb5_context alt_ctx)
-{
- 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 *) PMALLOC(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));
- PFREE(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);
-}
-
-#ifdef DEPRECATED_REMOVABLE
-int com_addr(void)
-{
- long ipAddr;
- char loc_addr[ADDR_SZ];
- CREDENTIALS cred;
- char service[40];
- char instance[40];
- // char addr[40];
- char realm[40];
- struct in_addr LocAddr;
- int k_errno;
-
- if (pkrb_get_cred == NULL)
- return(KSUCCESS);
-
- k_errno = (*pkrb_get_cred)(service,instance,realm,&cred);
- if (k_errno)
- return KRBERR(k_errno);
-
- while(1) {
- ipAddr = (*pLocalHostAddr)();
- LocAddr.s_addr = ipAddr;
- StringCbCopyA(loc_addr, sizeof(loc_addr), inet_ntoa(LocAddr));
- if ( strcmp(cred.address, loc_addr) != 0) {
- /* TODO: do something about this */
- //Leash_kdestroy ();
- break;
- }
- break;
- } // while()
- return 0;
-}
-#endif
-
-/* we use these structures to keep track of identities that we find
- while going through the API, FILE and MSLSA caches and enumerating
- credentials. The only identities we want to keep track of are the
- ones that have an initial ticket. We collect information for each
- of the identities we find that we have initial tickets for and
- then set the properties for the identities at once. */
-
-typedef struct tag_ident_data {
- khm_handle ident; /* handle to the identity */
- khm_int32 count; /* number of initial tickets we have
- found for this identity. */
- wchar_t ccname[MAX_PATH];
- FILETIME ft_issue;
- FILETIME ft_expire;
- FILETIME ft_renewexpire;
- khm_int32 krb5_flags;
-} ident_data;
-
-typedef struct tag_identlist {
- ident_data * list;
- khm_size n_list;
- khm_size nc_list;
-} identlist;
-
-#define IDLIST_ALLOC_INCR 8
-
-static void
-tc_prep_idlist(identlist * idlist) {
- khm_int32 rv;
- khm_size cb_ids = 0;
- khm_size n_ids = 0;
- khm_size i;
- wchar_t * ids = NULL;
- wchar_t *thisid;
-
- idlist->list = NULL;
- idlist->n_list = 0;
- idlist->nc_list = 0;
-
- do {
-
- if (ids) {
- PFREE(ids);
- ids = NULL;
- }
-
- rv = kcdb_identity_enum(KCDB_IDENT_FLAG_ACTIVE,
- KCDB_IDENT_FLAG_ACTIVE,
- NULL,
- &cb_ids,
- &n_ids);
-
- if (rv != KHM_ERROR_TOO_LONG)
- break; /* something else is wrong */
-
- if (n_ids == 0 || cb_ids == 0)
- break; /* no identities to process */
-
-#ifdef DEBUG
- assert(cb_ids > 0);
-#endif
-
- ids = PMALLOC(cb_ids);
-#ifdef DEBUG
- assert(ids != NULL);
-#endif
- if (ids == NULL)
- break;
-
- rv = kcdb_identity_enum(KCDB_IDENT_FLAG_ACTIVE,
- KCDB_IDENT_FLAG_ACTIVE,
- ids,
- &cb_ids,
- &n_ids);
-
- if (KHM_SUCCEEDED(rv))
- break;
-
- } while (TRUE);
-
- if (ids == NULL)
- return;
-
- if (KHM_FAILED(rv) || n_ids == 0) {
- if (ids)
- PFREE(ids);
- return;
- }
-
- idlist->nc_list = UBOUNDSS(n_ids, IDLIST_ALLOC_INCR, IDLIST_ALLOC_INCR);
-
- idlist->list = PCALLOC(idlist->nc_list, sizeof(idlist->list[0]));
-
- for (i = 0, thisid = ids;
- thisid && thisid[0];
- thisid = multi_string_next(thisid)) {
-
- khm_handle ident;
-
- rv = kcdb_identity_create(thisid, 0, &ident);
-
- if (KHM_FAILED(rv))
- continue;
-
- idlist->list[i].ident = ident;
- idlist->list[i].count = 0;
-
- i++;
- }
-
- idlist->n_list = i;
-
- PFREE(ids);
-}
-
-static ident_data *
-tc_add_ident_to_list(identlist * idlist, khm_handle ident) {
- khm_size i;
- ident_data * d;
-
- for (i=0; i < idlist->n_list; i++) {
- if (kcdb_identity_is_equal(ident, idlist->list[i].ident))
- break;
- }
-
- if (i < idlist->n_list) {
- /* we already have this identity on our list. Increment the
- count */
- idlist->list[i].count++;
- return &idlist->list[i];
- }
-
- /* it wasn't in our list. Add it */
-
- if (idlist->n_list + 1 > idlist->nc_list) {
- idlist->nc_list = UBOUNDSS(idlist->n_list + 1,
- IDLIST_ALLOC_INCR,
- IDLIST_ALLOC_INCR);
-#ifdef DEBUG
- assert(idlist->n_list + 1 <= idlist->nc_list);
-#endif
- idlist->list = PREALLOC(idlist->list,
- sizeof(idlist->list[0]) * idlist->nc_list);
-#ifdef DEBUG
- assert(idlist->list);
-#endif
- ZeroMemory(&idlist->list[idlist->n_list],
- sizeof(idlist->list[0]) *
- (idlist->nc_list - idlist->n_list));
- }
-
- d = &idlist->list[idlist->n_list];
-
- ZeroMemory(d, sizeof(*d));
-
- d->ident = ident;
- d->count = 1;
-
- idlist->n_list++;
-
- kcdb_identity_hold(ident);
-
- return d;
-}
-
-static void
-tc_set_ident_data(identlist * idlist) {
- khm_size i;
- wchar_t k5idtype[KCDB_MAXCCH_NAME];
-
- k5idtype[0] = L'\0';
- LoadString(hResModule, IDS_KRB5_NC_NAME,
- k5idtype, ARRAYLENGTH(k5idtype));
-
- for (i=0; i < idlist->n_list; i++) {
-#ifdef DEBUG
- assert(idlist->list[i].ident);
-#endif
-
- if (idlist->list[i].count > 0) {
- khm_int32 t;
-
- t = credtype_id_krb5;
- kcdb_identity_set_attr(idlist->list[i].ident,
- KCDB_ATTR_TYPE,
- &t,
- sizeof(t));
-
- /* We need to manually add the type name if we want the
- name to show up in the property list for the identity.
- The type name is only automatically calculated for
- credentials. */
- kcdb_identity_set_attr(idlist->list[i].ident,
- KCDB_ATTR_TYPE_NAME,
- k5idtype,
- KCDB_CBSIZE_AUTO);
-
- kcdb_identity_set_attr(idlist->list[i].ident,
- attr_id_krb5_ccname,
- idlist->list[i].ccname,
- KCDB_CBSIZE_AUTO);
-
- kcdb_identity_set_attr(idlist->list[i].ident,
- KCDB_ATTR_EXPIRE,
- &idlist->list[i].ft_expire,
- sizeof(idlist->list[i].ft_expire));
-
- kcdb_identity_set_attr(idlist->list[i].ident,
- KCDB_ATTR_ISSUE,
- &idlist->list[i].ft_issue,
- sizeof(idlist->list[i].ft_issue));
-
- kcdb_identity_set_attr(idlist->list[i].ident,
- attr_id_krb5_flags,
- &idlist->list[i].krb5_flags,
- sizeof(idlist->list[i].krb5_flags));
-
- if (idlist->list[i].ft_renewexpire.dwLowDateTime == 0 &&
- idlist->list[i].ft_renewexpire.dwHighDateTime == 0) {
- kcdb_identity_set_attr(idlist->list[i].ident,
- KCDB_ATTR_RENEW_EXPIRE,
- NULL, 0);
- } else {
- kcdb_identity_set_attr(idlist->list[i].ident,
- KCDB_ATTR_RENEW_EXPIRE,
- &idlist->list[i].ft_renewexpire,
- sizeof(idlist->list[i].ft_renewexpire));
- }
-
- } else {
- /* We didn't see any TGTs for this identity. We have to
- remove all the Krb5 supplied properties. */
-
- khm_int32 t;
- khm_size cb;
-
- cb = sizeof(t);
- if (KHM_SUCCEEDED(kcdb_identity_get_attr(idlist->list[i].ident,
- KCDB_ATTR_TYPE, NULL,
- &t,
- &cb)) &&
- t == credtype_id_krb5) {
-
- /* disown this and remove all our properties. the
- system will GC this identity if nobody claims it.*/
-
- kcdb_identity_set_attr(idlist->list[i].ident,
- KCDB_ATTR_TYPE, NULL, 0);
- kcdb_identity_set_attr(idlist->list[i].ident,
- KCDB_ATTR_TYPE_NAME, NULL, 0);
- kcdb_identity_set_attr(idlist->list[i].ident,
- attr_id_krb5_ccname, NULL, 0);
- kcdb_identity_set_attr(idlist->list[i].ident,
- KCDB_ATTR_EXPIRE, NULL, 0);
- kcdb_identity_set_attr(idlist->list[i].ident,
- KCDB_ATTR_ISSUE, NULL, 0);
- kcdb_identity_set_attr(idlist->list[i].ident,
- attr_id_krb5_flags, NULL, 0);
- kcdb_identity_set_attr(idlist->list[i].ident,
- KCDB_ATTR_RENEW_EXPIRE, NULL, 0);
- } else {
- /* otherwise, this identity doesn't belong to us. We
- should leave it as is. */
- }
- }
- }
-}
-
-static void
-tc_free_idlist(identlist * idlist) {
- khm_size i;
-
- for (i=0; i < idlist->n_list; i++) {
- if (idlist->list[i].ident != NULL) {
- kcdb_identity_release(idlist->list[i].ident);
- idlist->list[i].ident = NULL;
- }
- }
-
- if (idlist->list)
- PFREE(idlist->list);
- idlist->list = NULL;
- idlist->n_list = 0;
- idlist->nc_list = 0;
-}
-
-#ifndef ENCTYPE_LOCAL_RC4_MD4
-#define ENCTYPE_LOCAL_RC4_MD4 0xFFFFFF80
-#endif
-
-#define MAX_ADDRS 256
-
-static long get_tickets_from_cache(krb5_context ctx,
- krb5_ccache cache,
- identlist * idlist)
-{
- krb5_error_code code;
- krb5_principal KRBv5Principal;
- krb5_flags flags = 0;
- krb5_cc_cursor KRBv5Cursor;
- krb5_creds KRBv5Credentials;
- krb5_ticket *tkt=NULL;
- char *ClientName = NULL;
- char *PrincipalName = NULL;
- wchar_t wbuf[256]; /* temporary conversion buffer */
- wchar_t wcc_name[KRB5_MAXCCH_CCNAME]; /* credential cache name */
- char *sServerName = NULL;
- khm_handle ident = NULL;
- khm_handle cred = NULL;
- time_t tt;
- FILETIME ft, eft;
- khm_int32 ti;
-
-#ifdef KRB5_TC_NOTICKET
- flags = KRB5_TC_NOTICKET;
-#else
- flags = 0;
-#endif
-
- {
- const char * cc_name;
- const char * cc_type;
-
- cc_name = (*pkrb5_cc_get_name)(ctx, cache);
- if(cc_name) {
- cc_type = (*pkrb5_cc_get_type)(ctx, cache);
- if (cc_type) {
- StringCbPrintf(wcc_name, sizeof(wcc_name), L"%S:%S", cc_type, cc_name);
- } else {
- AnsiStrToUnicode(wcc_name, sizeof(wcc_name), cc_name);
- khm_krb5_canon_cc_name(wcc_name, sizeof(wcc_name));
- }
- } else {
- cc_type = (*pkrb5_cc_get_type)(ctx, cache);
- if (cc_type) {
- StringCbPrintf(wcc_name, sizeof(wcc_name), L"%S:", cc_type);
- } else {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- StringCbCopy(wcc_name, sizeof(wcc_name), L"");
- }
- }
- }
-
- _reportf(L"Getting tickets from cache [%s]", wcc_name);
-
- if ((code = (*pkrb5_cc_set_flags)(ctx, cache, flags)))
- {
- if (code != KRB5_FCC_NOFILE && code != KRB5_CC_NOTFOUND)
- khm_krb5_error(code, "krb5_cc_set_flags()", 0, &ctx, &cache);
-
- goto _exit;
- }
-
- if ((code = (*pkrb5_cc_get_principal)(ctx, cache, &KRBv5Principal)))
- {
- if (code != KRB5_FCC_NOFILE && code != KRB5_CC_NOTFOUND)
- khm_krb5_error(code, "krb5_cc_get_principal()", 0, &ctx, &cache);
-
- goto _exit;
- }
-
- PrincipalName = NULL;
- ClientName = NULL;
- sServerName = NULL;
- if ((code = (*pkrb5_unparse_name)(ctx, KRBv5Principal,
- (char **)&PrincipalName)))
- {
- if (PrincipalName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
-
- (*pkrb5_free_principal)(ctx, KRBv5Principal);
-
- goto _exit;
- }
-
- if (!strcspn(PrincipalName, "@" ))
- {
- if (PrincipalName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
-
- (*pkrb5_free_principal)(ctx, KRBv5Principal);
-
- goto _exit;
- }
-
- AnsiStrToUnicode(wbuf, sizeof(wbuf), PrincipalName);
- if(KHM_FAILED(kcdb_identity_create(wbuf, KCDB_IDENT_FLAG_CREATE,
- &ident))) {
- /* something bad happened */
- code = 1;
- goto _exit;
- }
-
- _reportf(L"Found principal [%s]", wbuf);
-
- (*pkrb5_free_principal)(ctx, KRBv5Principal);
-
- if ((code = (*pkrb5_cc_start_seq_get)(ctx, cache, &KRBv5Cursor)))
- {
- goto _exit;
- }
-
- memset(&KRBv5Credentials, '\0', sizeof(KRBv5Credentials));
-
- ClientName = NULL;
- sServerName = NULL;
- cred = NULL;
-
- while (!(code = pkrb5_cc_next_cred(ctx, cache, &KRBv5Cursor,
- &KRBv5Credentials)))
- {
- khm_handle tident = NULL;
- khm_int32 cred_flags = 0;
-
- if(ClientName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, ClientName);
- if(sServerName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, sServerName);
- if(cred)
- kcdb_cred_release(cred);
-
- ClientName = NULL;
- sServerName = NULL;
- cred = NULL;
-
- if ((*pkrb5_unparse_name)(ctx, KRBv5Credentials.client, &ClientName))
- {
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
- khm_krb5_error(code, "krb5_free_cred_contents()", 0, &ctx, &cache);
- continue;
- }
-
- if ((*pkrb5_unparse_name)(ctx, KRBv5Credentials.server, &sServerName))
- {
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
- khm_krb5_error(code, "krb5_free_cred_contents()", 0, &ctx, &cache);
- continue;
- }
-
- /* if the ClientName differs from PrincipalName for some
- reason, we need to create a new identity */
- if(strcmp(ClientName, PrincipalName)) {
- AnsiStrToUnicode(wbuf, sizeof(wbuf), ClientName);
- if(KHM_FAILED(kcdb_identity_create(wbuf, KCDB_IDENT_FLAG_CREATE,
- &tident))) {
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
- continue;
- }
- } else {
- tident = ident;
- }
-
- AnsiStrToUnicode(wbuf, sizeof(wbuf), sServerName);
- if(KHM_FAILED(kcdb_cred_create(wbuf, tident, credtype_id_krb5,
- &cred))) {
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
- continue;
- }
-
- if (!KRBv5Credentials.times.starttime)
- KRBv5Credentials.times.starttime = KRBv5Credentials.times.authtime;
-
- tt = KRBv5Credentials.times.starttime;
- TimetToFileTime(tt, &ft);
- kcdb_cred_set_attr(cred, KCDB_ATTR_ISSUE, &ft, sizeof(ft));
-
- tt = KRBv5Credentials.times.endtime;
- TimetToFileTime(tt, &eft);
- kcdb_cred_set_attr(cred, KCDB_ATTR_EXPIRE, &eft, sizeof(eft));
-
- {
- FILETIME ftl;
-
- ftl = FtSub(&eft, &ft);
- kcdb_cred_set_attr(cred, KCDB_ATTR_LIFETIME, &ftl, sizeof(ftl));
- }
-
- if (KRBv5Credentials.times.renew_till > 0) {
- FILETIME ftl;
-
- tt = KRBv5Credentials.times.renew_till;
- TimetToFileTime(tt, &eft);
- kcdb_cred_set_attr(cred, KCDB_ATTR_RENEW_EXPIRE, &eft,
- sizeof(eft));
-
-
- ftl = FtSub(&eft, &ft);
- kcdb_cred_set_attr(cred, KCDB_ATTR_RENEW_LIFETIME, &ftl,
- sizeof(ftl));
- }
-
- ti = KRBv5Credentials.ticket_flags;
- kcdb_cred_set_attr(cred, attr_id_krb5_flags, &ti, sizeof(ti));
-
- /* special flags understood by NetIDMgr */
- {
- khm_int32 nflags = 0;
-
- if (ti & TKT_FLG_RENEWABLE)
- nflags |= KCDB_CRED_FLAG_RENEWABLE;
- if (ti & TKT_FLG_INITIAL)
- nflags |= KCDB_CRED_FLAG_INITIAL;
- else {
- krb5_data * c0, *c1, *r;
-
- /* these are macros that do not allocate any memory */
- c0 = krb5_princ_component(ctx,KRBv5Credentials.server,0);
- c1 = krb5_princ_component(ctx,KRBv5Credentials.server,1);
- r = krb5_princ_realm(ctx,KRBv5Credentials.server);
-
- if ( c0 && c1 && r && c1->length == r->length &&
- !strncmp(c1->data,r->data,r->length) &&
- !strncmp("krbtgt",c0->data,c0->length) )
- nflags |= KCDB_CRED_FLAG_INITIAL;
- }
-
- kcdb_cred_set_flags(cred, nflags, KCDB_CRED_FLAGMASK_EXT);
-
- cred_flags = nflags;
- }
-
- if ( !pkrb5_decode_ticket(&KRBv5Credentials.ticket, &tkt)) {
- ti = tkt->enc_part.enctype;
- kcdb_cred_set_attr(cred, attr_id_tkt_enctype, &ti, sizeof(ti));
- ti = tkt->enc_part.kvno;
- kcdb_cred_set_attr(cred, attr_id_kvno, &ti, sizeof(ti));
- pkrb5_free_ticket(ctx, tkt);
- tkt = NULL;
- }
-
- ti = KRBv5Credentials.keyblock.enctype;
- kcdb_cred_set_attr(cred, attr_id_key_enctype, &ti, sizeof(ti));
-
- kcdb_cred_set_attr(cred, KCDB_ATTR_LOCATION, wcc_name,
- KCDB_CBSIZE_AUTO);
-
- if ( KRBv5Credentials.addresses && KRBv5Credentials.addresses[0] ) {
- khm_int32 buffer[1024];
- void * bufp;
- khm_size cb;
- khm_int32 rv;
-
- bufp = (void *) buffer;
- cb = sizeof(buffer);
-
- rv = serialize_krb5_addresses(KRBv5Credentials.addresses,
- bufp,
- &cb);
- if (rv == KHM_ERROR_TOO_LONG) {
- bufp = PMALLOC(cb);
- rv = serialize_krb5_addresses(KRBv5Credentials.addresses,
- bufp,
- &cb);
- }
-
- if (KHM_SUCCEEDED(rv)) {
- kcdb_cred_set_attr(cred, attr_id_addr_list,
- bufp, cb);
- }
-
- if (bufp != (void *) buffer)
- PFREE(bufp);
- }
-
- if(cred_flags & KCDB_CRED_FLAG_INITIAL) {
- FILETIME ft_issue_new;
- FILETIME ft_expire_old;
- FILETIME ft_expire_new;
- ident_data * d;
-
- /* an initial ticket! Add it to the list of identities we
- have seen so far with initial tickets. */
- d = tc_add_ident_to_list(idlist, ident);
-#ifdef DEBUG
- assert(d);
- assert(d->count > 0);
-#endif
-
- tt = KRBv5Credentials.times.endtime;
- TimetToFileTime(tt, &ft_expire_new);
-
- tt = KRBv5Credentials.times.starttime;
- TimetToFileTime(tt, &ft_issue_new);
-
- /* so now, we have to set the properties of the identity
- based on the properties of this credential under the
- following circumstances:
-
- - If this is the first time we are hitting this
- identity.
-
- - If this is not the MSLSA: cache and the expiry time
- for this credential is longer than the time already
- found for this identity.
- */
-
- ft_expire_old = d->ft_expire;
-
- if(d->count == 1
- || (CompareFileTime(&ft_expire_new, &ft_expire_old) > 0 &&
- wcscmp(wcc_name, L"MSLSA:") != 0)) {
-
- _reportf(L"Setting properties for identity (count=%d)", d->count);
-
- StringCbCopy(d->ccname, sizeof(d->ccname),
- wcc_name);
- d->ft_expire = ft_expire_new;
- d->ft_issue = ft_issue_new;
-
- if (KRBv5Credentials.times.renew_till > 0) {
- tt = KRBv5Credentials.times.renew_till;
- TimetToFileTime(tt, &ft);
- d->ft_renewexpire = ft;
- } else {
- ZeroMemory(&d->ft_renewexpire, sizeof(d->ft_renewexpire));
- }
-
- d->krb5_flags = KRBv5Credentials.ticket_flags;
- }
- }
-
- kcdb_credset_add_cred(krb5_credset, cred, -1);
-
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
-
- if(tident != ident)
- kcdb_identity_release(tident);
- }
-
- if (PrincipalName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
-
- if (ClientName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, ClientName);
-
- if (sServerName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, sServerName);
-
- if (cred)
- kcdb_cred_release(cred);
-
- if ((code == KRB5_CC_END) || (code == KRB5_CC_NOTFOUND))
- {
- if ((code = pkrb5_cc_end_seq_get(ctx, cache, &KRBv5Cursor)))
- {
- goto _exit;
- }
-
- flags = KRB5_TC_OPENCLOSE;
-#ifdef KRB5_TC_NOTICKET
- flags |= KRB5_TC_NOTICKET;
-#endif
- if ((code = pkrb5_cc_set_flags(ctx, cache, flags)))
- {
- goto _exit;
- }
- }
- else
- {
- goto _exit;
- }
-
-_exit:
-
- return code;
-}
-
-long
-khm_krb5_list_tickets(krb5_context *krbv5Context)
-{
- krb5_context ctx = NULL;
- krb5_ccache cache = NULL;
- krb5_error_code code = 0;
- apiCB * cc_ctx = NULL;
- struct _infoNC ** pNCi = NULL;
- int i;
- khm_int32 t;
- wchar_t * ms = NULL;
- khm_size cb;
- identlist idl;
-
- kcdb_credset_flush(krb5_credset);
- tc_prep_idlist(&idl);
-
- if((*krbv5Context == 0) && (code = (*pkrb5_init_context)(krbv5Context))) {
- goto _exit;
- }
-
- ctx = (*krbv5Context);
-
- if (!pcc_initialize ||
- !pcc_get_NC_info ||
- !pcc_free_NC_info ||
- !pcc_shutdown)
- goto _skip_cc_iter;
-
- code = pcc_initialize(&cc_ctx, CC_API_VER_2, NULL, NULL);
- if (code)
- goto _exit;
-
- code = pcc_get_NC_info(cc_ctx, &pNCi);
- if (code)
- goto _exit;
-
- for(i=0; pNCi[i]; i++) {
- char ccname[KRB5_MAXCCH_CCNAME];
-
- if (pNCi[i]->vers != CC_CRED_V5)
- continue;
-
- if (FAILED(StringCchPrintfA(ccname, sizeof(ccname), "API:%s",
- pNCi[i]->name)))
- continue;
-
- code = (*pkrb5_cc_resolve)(ctx, ccname, &cache);
-
- if (code)
- continue;
-
- code = get_tickets_from_cache(ctx, cache, &idl);
-
- if(ctx != NULL && cache != NULL)
- (*pkrb5_cc_close)(ctx, cache);
-
- cache = 0;
- }
-
- _skip_cc_iter:
-
- if (khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
- == KHM_ERROR_TOO_LONG &&
- cb > sizeof(wchar_t) * 2) {
- wchar_t * t;
- char ccname[MAX_PATH + 6];
-
- ms = PMALLOC(cb);
-#ifdef DEBUG
- assert(ms);
-#endif
- khc_read_multi_string(csp_params, L"FileCCList", ms, &cb);
-
- for(t = ms; t && *t; t = multi_string_next(t)) {
- StringCchPrintfA(ccname, ARRAYLENGTH(ccname),
- "FILE:%S", t);
-
- code = (*pkrb5_cc_resolve)(ctx, ccname, &cache);
-
- if (code)
- continue;
-
- code = get_tickets_from_cache(ctx, cache, &idl);
-
- if (ctx != NULL && cache != NULL)
- (*pkrb5_cc_close)(ctx, cache);
- cache = 0;
- }
-
- PFREE(ms);
- }
-
- if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"MsLsaList", &t)) && t) {
- code = (*pkrb5_cc_resolve)(ctx, "MSLSA:", &cache);
-
- if (code == 0 && cache) {
- code = get_tickets_from_cache(ctx, cache, &idl);
- }
-
- if (ctx != NULL && cache != NULL)
- (*pkrb5_cc_close)(ctx, cache);
- cache = 0;
- }
-
-_exit:
- if (pNCi)
- (*pcc_free_NC_info)(cc_ctx, &pNCi);
- if (cc_ctx)
- (*pcc_shutdown)(&cc_ctx);
-
- kcdb_credset_collect(NULL, krb5_credset, NULL, credtype_id_krb5, NULL);
- tc_set_ident_data(&idl);
- tc_free_idlist(&idl);
-
- return(code);
-}
-
-int
-khm_krb5_renew_cred(khm_handle cred)
-{
- khm_handle identity = NULL;
- krb5_error_code code = 0;
- krb5_context ctx = NULL;
- krb5_ccache cc = NULL;
- krb5_principal me = NULL, server = NULL;
- krb5_creds in_creds, cc_creds;
- krb5_creds * out_creds = NULL;
-
- wchar_t wname[512];
- khm_size cbname;
- char name[512];
- khm_boolean brenewIdentity = FALSE;
- khm_boolean istgt = FALSE;
-
- khm_int32 flags;
-
- cbname = sizeof(wname);
- kcdb_cred_get_name(cred, wname, &cbname);
- _reportf(L"Krb5 renew cred for %s", wname);
-
- kcdb_cred_get_flags(cred, &flags);
-
- if (!(flags & KCDB_CRED_FLAG_INITIAL)) {
- _reportf(L"Krb5 skipping renewal because this is not an initial credential");
- return 0;
- }
-
- memset(&in_creds, 0, sizeof(in_creds));
- memset(&cc_creds, 0, sizeof(cc_creds));
-
- if (cred == NULL) {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- goto cleanup;
- }
-
- if (KHM_FAILED(kcdb_cred_get_identity(cred, &identity))) {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- goto cleanup;
- }
-
- code = khm_krb5_initialize(identity, &ctx, &cc);
- if (code)
- goto cleanup;
-
- code = pkrb5_cc_get_principal(ctx, cc, &me);
- if (code)
- goto cleanup;
-
- cbname = sizeof(wname);
- if (KHM_FAILED(kcdb_cred_get_name(cred, wname, &cbname)))
- goto cleanup;
-
- UnicodeStrToAnsi(name, sizeof(name), wname);
-
- code = pkrb5_parse_name(ctx, name, &server);
- if (code)
- goto cleanup;
-
- in_creds.client = me;
- in_creds.server = server;
-
-#ifdef KRB5_TC_NOTICKET
- pkrb5_cc_set_flags(ctx, cc, 0);
-#endif
-
- if (strlen("krbtgt") != krb5_princ_name(ctx, server)->length ||
- strncmp("krbtgt", krb5_princ_name(ctx, server)->data, krb5_princ_name(ctx, server)->length))
- {
- code = pkrb5_get_renewed_creds(ctx, &cc_creds, me, cc, name);
- if (code) {
- code = pkrb5_cc_retrieve_cred(ctx, cc, 0, &in_creds, &cc_creds);
- if (code == 0) {
- code = pkrb5_cc_remove_cred(ctx, cc, 0, &cc_creds);
- if (code) {
- brenewIdentity = TRUE;
- goto cleanup;
- }
- }
- }
-
- code = pkrb5_get_credentials(ctx, 0, cc, &in_creds, &out_creds);
- } else {
- istgt = TRUE;
- code = pkrb5_get_renewed_creds(ctx, &cc_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)
- khm_krb5_error(code, "krb5_get_renewed_creds()", 0, &ctx, &cc);
- goto cleanup;
- }
-
- if (istgt) {
- code = pkrb5_cc_initialize(ctx, cc, me);
- if (code) goto cleanup;
-
- }
-
- code = pkrb5_cc_store_cred(ctx, cc, istgt ? &cc_creds : out_creds);
- if (code) goto cleanup;
-
-
- cleanup:
-
- if (in_creds.client == me)
- in_creds.client = NULL;
- if (in_creds.server == server)
- in_creds.server = NULL;
-
- if (me)
- pkrb5_free_principal(ctx, me);
-
- if (server)
- pkrb5_free_principal(ctx, server);
-
- pkrb5_free_cred_contents(ctx, &in_creds);
- pkrb5_free_cred_contents(ctx, &cc_creds);
-
- if (out_creds)
- pkrb5_free_creds(ctx, out_creds);
-
- if (cc && ctx)
- pkrb5_cc_close(ctx, cc);
-
- if (ctx)
- pkrb5_free_context(ctx);
-
- if (identity) {
- if (brenewIdentity)
- code = khm_krb5_renew_ident(identity);
- kcdb_identity_release(identity);
- }
-
- return code;
-}
-
-int
-khm_krb5_renew_ident(khm_handle identity)
-{
- krb5_error_code code = 0;
- krb5_context ctx = NULL;
- krb5_ccache cc = NULL;
- krb5_principal me = NULL;
- krb5_principal server = NULL;
- krb5_creds my_creds;
- krb5_data *realm = NULL;
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- khm_size cb;
- khm_int32 k5_flags;
-
- memset(&my_creds, 0, sizeof(krb5_creds));
-
- if ( !pkrb5_init_context )
- goto cleanup;
-
- cb = sizeof(idname);
- kcdb_identity_get_name(identity, idname, &cb);
-
- if (khm_krb5_get_identity_flags(identity) & K5IDFLAG_IMPORTED) {
-#ifndef NO_REIMPORT_MSLSA_CREDS
- /* we are trying to renew the identity that was imported from
- MSLSA: */
- BOOL imported;
- BOOL retry_import = FALSE;
- char cidname[KCDB_IDENT_MAXCCH_NAME];
- khm_handle imported_id = NULL;
- khm_size cb;
- FILETIME ft_expire;
- FILETIME ft_now;
- FILETIME ft_threshold;
- krb5_principal princ = NULL;
-
- UnicodeStrToAnsi(cidname, sizeof(cidname), idname);
-
- imported = khm_krb5_ms2mit(cidname, FALSE, TRUE, &imported_id);
-
- if (imported == 0)
- goto import_failed;
-
- /* if the imported identity has already expired or will soon,
- we clear the cache and try again. */
- khm_krb5_list_tickets(&ctx);
-
- cb = sizeof(ft_expire);
- if (KHM_FAILED(kcdb_identity_get_attr(imported_id, KCDB_ATTR_EXPIRE,
- NULL, &ft_expire, &cb)))
- goto import_failed;
-
- GetSystemTimeAsFileTime(&ft_now);
- TimetToFileTimeInterval(5 * 60, &ft_threshold);
-
- ft_now = FtAdd(&ft_now, &ft_threshold);
-
- if (CompareFileTime(&ft_expire, &ft_now) < 0) {
- /* the ticket lifetime is not long enough */
-
- code = 0;
-
- if (ctx == NULL)
- code = pkrb5_init_context(&ctx);
- if (code)
- goto import_failed;
-
- code = pkrb5_cc_resolve(ctx, "MSLSA:", &cc);
- if (code)
- goto import_failed;
-
- code = pkrb5_cc_get_principal(ctx, cc, &princ);
- if (code)
- goto import_failed;
-
- pkrb5_cc_initialize(ctx, cc, princ);
-
- retry_import = TRUE;
- }
-
- import_failed:
-
- if (imported_id) {
- kcdb_identity_release(imported_id);
- imported_id = NULL;
- }
-
- if (ctx) {
- if (cc) {
- pkrb5_cc_close(ctx, cc);
- cc = NULL;
- }
-
- if (princ) {
- pkrb5_free_principal(ctx, princ);
- princ = NULL;
- }
-
- /* leave ctx so we can use it later */
- }
-
- if (retry_import)
- imported = khm_krb5_ms2mit(cidname, FALSE, TRUE, NULL);
-
- if (imported)
- goto cleanup;
-
- /* if the import failed, then we try to renew the identity via
- the usual procedure. */
-
-#else
- /* if we are suppressing further imports from MSLSA, we just
- skip renewing this identity. */
- goto cleanup;
-#endif
- }
-
- cb = sizeof(k5_flags);
- if (KHM_SUCCEEDED(kcdb_identity_get_attr(identity,
- attr_id_krb5_flags,
- NULL,
- &k5_flags,
- &cb)) &&
- !(k5_flags & TKT_FLG_RENEWABLE)) {
-
- code = KRB5KDC_ERR_BADOPTION;
- goto cleanup;
- }
-
- {
- FILETIME ft_now;
- FILETIME ft_exp;
-
- cb = sizeof(ft_exp);
- GetSystemTimeAsFileTime(&ft_now);
- if (KHM_SUCCEEDED(kcdb_identity_get_attr(identity,
- KCDB_ATTR_EXPIRE,
- NULL,
- &ft_exp,
- &cb)) &&
- CompareFileTime(&ft_exp, &ft_now) < 0) {
-
- code = KRB5KRB_AP_ERR_TKT_EXPIRED;
- goto cleanup;
-
- }
- }
-
- code = khm_krb5_initialize(identity, &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)
- khm_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 = NULL;
- if (my_creds.server == server)
- my_creds.server = NULL;
-
- if (ctx) {
- 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);
- pkrb5_free_context(ctx);
- }
-
- return(code);
-}
-
-int
-khm_krb5_kinit(krb5_context alt_ctx,
- char * principal_name,
- char * password,
- char * ccache,
- krb5_deltat lifetime,
- DWORD forwardable,
- DWORD proxiable,
- krb5_deltat renew_life,
- DWORD addressless,
- DWORD publicIP,
- krb5_prompter_fct prompter,
- void * p_data)
-{
- krb5_error_code code = 0;
- krb5_context ctx = NULL;
- krb5_ccache cc = NULL;
- krb5_principal me = NULL;
- char* name = NULL;
- krb5_creds my_creds;
- krb5_get_init_creds_opt options;
- krb5_address ** addrs = NULL;
- int i = 0, addr_count = 0;
-
- if (!pkrb5_init_context)
- return 0;
-
- _reportf(L"In khm_krb5_kinit");
-
- pkrb5_get_init_creds_opt_init(&options);
- pkrb5_get_init_creds_opt_set_change_password_prompt(&options, 0);
-
- memset(&my_creds, 0, sizeof(my_creds));
-
- if (alt_ctx) {
- ctx = alt_ctx;
- } else {
- code = pkrb5_init_context(&ctx);
- if (code)
- goto cleanup;
- }
-
- if (ccache) {
- _reportf(L"Using supplied ccache name %S", ccache);
- code = pkrb5_cc_resolve(ctx, ccache, &cc);
- } else {
- khm_handle identity = NULL;
- khm_handle csp_ident = NULL;
- khm_handle csp_k5 = NULL;
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- wchar_t wccname[MAX_PATH];
- char ccname[MAX_PATH];
- char * pccname = principal_name;
- khm_size cb;
-
- idname[0] = L'\0';
- AnsiStrToUnicode(idname, sizeof(idname), principal_name);
-
- cb = sizeof(wccname);
-
- if (KHM_SUCCEEDED(kcdb_identity_create(idname, 0, &identity)) &&
-
- KHM_SUCCEEDED(kcdb_identity_get_config(identity, 0, &csp_ident)) &&
-
- KHM_SUCCEEDED(khc_open_space(csp_ident, CSNAME_KRB5CRED, 0,
- &csp_k5)) &&
-
- KHM_SUCCEEDED(khc_read_string(csp_k5, L"DefaultCCName",
- wccname, &cb)) &&
-
- cb > sizeof(wchar_t)) {
-
- _reportf(L"Using DefaultCCName [%s] from identity", wccname);
-
- UnicodeStrToAnsi(ccname, sizeof(ccname), wccname);
- pccname = ccname;
- }
-
- if (csp_k5)
- khc_close_space(csp_k5);
- if (csp_ident)
- khc_close_space(csp_ident);
- if (identity)
- kcdb_identity_release(identity);
-
- code = pkrb5_cc_resolve(ctx, pccname, &cc);
- }
-
- _reportf(L"krb5_cc_resolve returns code %d", code);
-
- if (code) goto cleanup;
-
- code = pkrb5_parse_name(ctx, principal_name, &me);
- if (code) goto cleanup;
-
- code = pkrb5_unparse_name(ctx, me, &name);
- if (code) goto cleanup;
-
- if (lifetime == 0) {
- khc_read_int32(csp_params, L"DefaultLifetime", &lifetime);
- }
-
- 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 {
- krb5_address ** local_addrs=NULL;
- DWORD netIPAddr;
-
- pkrb5_os_localaddr(ctx, &local_addrs);
- i = 0;
- while ( local_addrs[i++] );
- addr_count = i + 1;
-
- addrs = (krb5_address **) PMALLOC((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 *)PMALLOC(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 *)PMALLOC(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);
-
- if (publicIP) {
- // we are going to add the public IP address specified by the user
- // to the list provided by the operating system
- addrs[i] = (krb5_address *)PMALLOC(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 *)PMALLOC(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_password(ctx,
- &my_creds,
- me,
- password, // password
- prompter, // prompter
- p_data, // prompter data
- 0, // start time
- 0, // service name
- &options);
- _reportf(L"krb5_get_init_creds_password returns code %d", code);
-
- if (code) goto cleanup;
-
- code = pkrb5_cc_initialize(ctx, cc, me);
- _reportf(L"krb5_cc_initialize returns code %d", code);
- if (code) goto cleanup;
-
- code = pkrb5_cc_store_cred(ctx, cc, &my_creds);
- _reportf(L"krb5_cc_store_cred returns code %d", code);
- if (code) goto cleanup;
-
-cleanup:
- if ( addrs ) {
- for ( i=0;i<addr_count;i++ ) {
- if ( addrs[i] ) {
- if ( addrs[i]->contents )
- PFREE(addrs[i]->contents);
- PFREE(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 (ctx && (ctx != alt_ctx))
- pkrb5_free_context(ctx);
- return(code);
-}
-
-long
-khm_krb5_copy_ccache_by_name(krb5_context in_ctx,
- wchar_t * wscc_dest,
- wchar_t * wscc_src) {
- krb5_context ctx = NULL;
- krb5_error_code code = 0;
- khm_boolean free_ctx;
- krb5_ccache cc_src = NULL;
- krb5_ccache cc_dest = NULL;
- krb5_principal princ_src = NULL;
- char scc_dest[KRB5_MAXCCH_CCNAME];
- char scc_src[KRB5_MAXCCH_CCNAME];
- int t;
-
- t = UnicodeStrToAnsi(scc_dest, sizeof(scc_dest), wscc_dest);
- if (t == 0)
- return KHM_ERROR_TOO_LONG;
- t = UnicodeStrToAnsi(scc_src, sizeof(scc_src), wscc_src);
- if (t == 0)
- return KHM_ERROR_TOO_LONG;
-
- if (in_ctx) {
- ctx = in_ctx;
- free_ctx = FALSE;
- } else {
- code = pkrb5_init_context(&ctx);
- if (code) {
- if (ctx)
- pkrb5_free_context(ctx);
- return code;
- }
- free_ctx = TRUE;
- }
-
- code = pkrb5_cc_resolve(ctx, scc_dest, &cc_dest);
- if (code)
- goto _cleanup;
-
- code = pkrb5_cc_resolve(ctx, scc_src, &cc_src);
- if (code)
- goto _cleanup;
-
- code = pkrb5_cc_get_principal(ctx, cc_src, &princ_src);
- if (code)
- goto _cleanup;
-
- code = pkrb5_cc_initialize(ctx, cc_dest, princ_src);
- if (code)
- goto _cleanup;
-
- code = pkrb5_cc_copy_creds(ctx, cc_src, cc_dest);
-
- _cleanup:
- if (princ_src)
- pkrb5_free_principal(ctx, princ_src);
-
- if (cc_dest)
- pkrb5_cc_close(ctx, cc_dest);
-
- if (cc_src)
- pkrb5_cc_close(ctx, cc_src);
-
- if (free_ctx && ctx)
- pkrb5_free_context(ctx);
-
- return code;
-}
-
-long
-khm_krb5_canon_cc_name(wchar_t * wcc_name,
- size_t cb_cc_name) {
- size_t cb_len;
- wchar_t * colon;
-
- if (FAILED(StringCbLength(wcc_name,
- cb_cc_name,
- &cb_len))) {
-#ifdef DEBUG
- assert(FALSE);
-#else
- return KHM_ERROR_TOO_LONG;
-#endif
- }
-
- cb_len += sizeof(wchar_t);
-
- colon = wcschr(wcc_name, L':');
-
- if (colon) {
- /* if the colon is just 1 character away from the beginning,
- it's a FILE: cc */
- if (colon - wcc_name == 1) {
- if (cb_len + 5 * sizeof(wchar_t) > cb_cc_name)
- return KHM_ERROR_TOO_LONG;
-
- memmove(&wcc_name[5], &wcc_name[0], cb_len);
- memmove(&wcc_name[0], L"FILE:", sizeof(wchar_t) * 5);
- }
-
- return 0;
- }
-
- if (cb_len + 4 * sizeof(wchar_t) > cb_cc_name)
- return KHM_ERROR_TOO_LONG;
-
- memmove(&wcc_name[4], &wcc_name[0], cb_len);
- memmove(&wcc_name[0], L"API:", sizeof(wchar_t) * 4);
-
- return 0;
-}
-
-int
-khm_krb5_cc_name_cmp(const wchar_t * cc_name_1,
- const wchar_t * cc_name_2) {
- if (!wcsncmp(cc_name_1, L"API:", 4))
- cc_name_1 += 4;
-
- if (!wcsncmp(cc_name_2, L"API:", 4))
- cc_name_2 += 4;
-
- return wcscmp(cc_name_1, cc_name_2);
-}
-
-static khm_int32 KHMAPI
-khmint_location_comp_func(khm_handle cred1,
- khm_handle cred2,
- void * rock) {
- return kcdb_creds_comp_attr(cred1, cred2, KCDB_ATTR_LOCATION);
-}
-
-struct khmint_location_check {
- khm_handle credset;
- khm_handle cred;
- wchar_t * ccname;
- khm_boolean success;
-};
-
-static khm_int32 KHMAPI
-khmint_find_matching_cred_func(khm_handle cred,
- void * rock) {
- struct khmint_location_check * lc;
-
- lc = (struct khmint_location_check *) rock;
-
- if (!kcdb_creds_is_equal(cred, lc->cred))
- return KHM_ERROR_SUCCESS;
- if (kcdb_creds_comp_attr(cred, lc->cred, KCDB_ATTR_LOCATION))
- return KHM_ERROR_SUCCESS;
-
- /* found it */
- lc->success = TRUE;
-
- /* break the search */
- return !KHM_ERROR_SUCCESS;
-}
-
-static khm_int32 KHMAPI
-khmint_location_check_func(khm_handle cred,
- void * rock) {
- khm_int32 t;
- khm_size cb;
- wchar_t ccname[KRB5_MAXCCH_CCNAME];
- struct khmint_location_check * lc;
-
- lc = (struct khmint_location_check *) rock;
-
- if (KHM_FAILED(kcdb_cred_get_type(cred, &t)))
- return KHM_ERROR_SUCCESS;
-
- if (t != credtype_id_krb5)
- return KHM_ERROR_SUCCESS;
-
- cb = sizeof(ccname);
- if (KHM_FAILED(kcdb_cred_get_attr(cred,
- KCDB_ATTR_LOCATION,
- NULL,
- ccname,
- &cb)))
- return KHM_ERROR_SUCCESS;
-
- if(wcscmp(ccname, lc->ccname))
- return KHM_ERROR_SUCCESS;
-
- lc->cred = cred;
-
- lc->success = FALSE;
-
- kcdb_credset_apply(lc->credset,
- khmint_find_matching_cred_func,
- (void *) lc);
-
- if (!lc->success)
- return KHM_ERROR_NOT_FOUND;
- else
- return KHM_ERROR_SUCCESS;
-}
-
-static khm_int32 KHMAPI
-khmint_delete_location_func(khm_handle cred,
- void * rock) {
- wchar_t cc_cred[KRB5_MAXCCH_CCNAME];
- struct khmint_location_check * lc;
- khm_size cb;
-
- lc = (struct khmint_location_check *) rock;
-
- cb = sizeof(cc_cred);
-
- if (KHM_FAILED(kcdb_cred_get_attr(cred,
- KCDB_ATTR_LOCATION,
- NULL,
- cc_cred,
- &cb)))
- return KHM_ERROR_SUCCESS;
-
- if (wcscmp(cc_cred, lc->ccname))
- return KHM_ERROR_SUCCESS;
-
- kcdb_credset_del_cred_ref(lc->credset,
- cred);
-
- return KHM_ERROR_SUCCESS;
-}
-
-int
-khm_krb5_destroy_by_credset(khm_handle p_cs)
-{
- khm_handle d_cs = NULL;
- khm_int32 rv = KHM_ERROR_SUCCESS;
- khm_size s, cb;
- krb5_context ctx = NULL;
- krb5_error_code code = 0;
- int i;
- wchar_t ccname[KRB5_MAXCCH_CCNAME];
- struct khmint_location_check lc;
-
- rv = kcdb_credset_create(&d_cs);
-
- assert(KHM_SUCCEEDED(rv) && d_cs != NULL);
-
- kcdb_credset_extract(d_cs, p_cs, NULL, credtype_id_krb5);
-
- kcdb_credset_get_size(d_cs, &s);
-
- if (s == 0) {
- _reportf(L"No tickets to delete");
-
- kcdb_credset_delete(d_cs);
- return 0;
- }
-
- code = pkrb5_init_context(&ctx);
- if (code != 0) {
- rv = code;
- goto _cleanup;
- }
-
- /* we should synchronize the credential lists before we attempt to
- make any assumptions on the state of the root credset */
- khm_krb5_list_tickets(&ctx);
-
- /* so, we need to make a decision about whether to destroy entire
- ccaches or just individual credentials. Therefore we first
- sort them by ccache. */
- kcdb_credset_sort(d_cs,
- khmint_location_comp_func,
- NULL);
-
- /* now, for each ccache we encounter, we check if we have all the
- credentials from that ccache in the to-be-deleted list. */
- for (i=0; i < (int) s; i++) {
- khm_handle cred;
-
- if (KHM_FAILED(kcdb_credset_get_cred(d_cs,
- i,
- &cred)))
- continue;
-
- cb = sizeof(ccname);
- rv = kcdb_cred_get_attr(cred,
- KCDB_ATTR_LOCATION,
- NULL,
- ccname,
- &cb);
-
-#ifdef DEBUG
- assert(KHM_SUCCEEDED(rv));
-#endif
- kcdb_cred_release(cred);
-
- lc.credset = d_cs;
- lc.cred = NULL;
- lc.ccname = ccname;
- lc.success = FALSE;
-
- kcdb_credset_apply(NULL,
- khmint_location_check_func,
- (void *) &lc);
-
- if (lc.success) {
- /* ok the destroy the ccache */
- char a_ccname[KRB5_MAXCCH_CCNAME];
- krb5_ccache cc = NULL;
-
- _reportf(L"Destroying ccache [%s]", ccname);
-
- UnicodeStrToAnsi(a_ccname,
- sizeof(a_ccname),
- ccname);
-
- code = pkrb5_cc_resolve(ctx,
- a_ccname,
- &cc);
- if (code)
- goto _delete_this_set;
-
- code = pkrb5_cc_destroy(ctx, cc);
-
- if (code) {
- _reportf(L"krb5_cc_destroy returns code %d", code);
- }
-
- _delete_this_set:
-
- lc.credset = d_cs;
- lc.ccname = ccname;
-
- /* note that although we are deleting credentials off the
- credential set, the size of the credential set does not
- decrease since we are doing it from inside
- kcdb_credset_apply(). The deleted creds will simply be
- marked as deleted until kcdb_credset_purge() is
- called. */
-
- kcdb_credset_apply(d_cs,
- khmint_delete_location_func,
- (void *) &lc);
- }
- }
-
- kcdb_credset_purge(d_cs);
-
- /* the remainder need to be deleted one by one */
-
- kcdb_credset_get_size(d_cs, &s);
-
- for (i=0; i < (int) s; ) {
- khm_handle cred;
- char a_ccname[KRB5_MAXCCH_CCNAME];
- char a_srvname[KCDB_CRED_MAXCCH_NAME];
- wchar_t srvname[KCDB_CRED_MAXCCH_NAME];
- krb5_ccache cc;
- krb5_creds in_cred, out_cred;
- krb5_principal princ;
- khm_int32 etype;
-
- if (KHM_FAILED(kcdb_credset_get_cred(d_cs,
- i,
- &cred))) {
- i++;
- continue;
- }
-
- cb = sizeof(ccname);
- if (KHM_FAILED(kcdb_cred_get_attr(cred,
- KCDB_ATTR_LOCATION,
- NULL,
- ccname,
- &cb)))
- goto _done_with_this_cred;
-
- _reportf(L"Looking at ccache [%s]", ccname);
-
- UnicodeStrToAnsi(a_ccname,
- sizeof(a_ccname),
- ccname);
-
- code = pkrb5_cc_resolve(ctx,
- a_ccname,
- &cc);
-
- if (code)
- goto _skip_similar;
-
- code = pkrb5_cc_get_principal(ctx, cc, &princ);
-
- if (code) {
- pkrb5_cc_close(ctx, cc);
- goto _skip_similar;
- }
-
- _del_this_cred:
-
- cb = sizeof(etype);
-
- if (KHM_FAILED(kcdb_cred_get_attr(cred,
- attr_id_key_enctype,
- NULL,
- &etype,
- &cb)))
- goto _do_next_cred;
-
- cb = sizeof(srvname);
- if (KHM_FAILED(kcdb_cred_get_name(cred,
- srvname,
- &cb)))
- goto _do_next_cred;
-
- _reportf(L"Attempting to delete ticket %s", srvname);
-
- UnicodeStrToAnsi(a_srvname, sizeof(a_srvname), srvname);
-
- ZeroMemory(&in_cred, sizeof(in_cred));
-
- code = pkrb5_parse_name(ctx, a_srvname, &in_cred.server);
- if (code)
- goto _do_next_cred;
- in_cred.client = princ;
- in_cred.keyblock.enctype = etype;
-
- code = pkrb5_cc_retrieve_cred(ctx,
- cc,
- KRB5_TC_MATCH_SRV_NAMEONLY |
- KRB5_TC_SUPPORTED_KTYPES,
- &in_cred,
- &out_cred);
- if (code)
- goto _do_next_cred_0;
-
- code = pkrb5_cc_remove_cred(ctx, cc,
- KRB5_TC_MATCH_SRV_NAMEONLY |
- KRB5_TC_SUPPORTED_KTYPES |
- KRB5_TC_MATCH_AUTHDATA,
- &out_cred);
-
- pkrb5_free_cred_contents(ctx, &out_cred);
- _do_next_cred_0:
- pkrb5_free_principal(ctx, in_cred.server);
- _do_next_cred:
-
- /* check if the next cred is also of the same ccache */
- kcdb_cred_release(cred);
-
- for (i++; i < (int) s; i++) {
- if (KHM_FAILED(kcdb_credset_get_cred(d_cs,
- i,
- &cred)))
- continue;
- }
-
- if (i < (int) s) {
- wchar_t newcc[KRB5_MAXCCH_CCNAME];
-
- cb = sizeof(newcc);
- if (KHM_FAILED(kcdb_cred_get_attr(cred,
- KCDB_ATTR_LOCATION,
- NULL,
- newcc,
- &cb)) ||
- wcscmp(newcc, ccname)) {
- i--; /* we have to look at this again */
- goto _done_with_this_set;
- }
- goto _del_this_cred;
- }
-
-
- _done_with_this_set:
- pkrb5_free_principal(ctx, princ);
-
- pkrb5_cc_close(ctx, cc);
-
- _done_with_this_cred:
- kcdb_cred_release(cred);
- i++;
- continue;
-
- _skip_similar:
- kcdb_cred_release(cred);
-
- for (++i; i < (int) s; i++) {
- wchar_t newcc[KRB5_MAXCCH_CCNAME];
-
- if (KHM_FAILED(kcdb_credset_get_cred(d_cs,
- i,
- &cred)))
- continue;
-
- cb = sizeof(newcc);
- if (KHM_FAILED(kcdb_cred_get_attr(cred,
- KCDB_ATTR_LOCATION,
- NULL,
- &newcc,
- &cb))) {
- kcdb_cred_release(cred);
- continue;
- }
-
- if (wcscmp(newcc, ccname)) {
- kcdb_cred_release(cred);
- break;
- }
- }
- }
-
- _cleanup:
-
- if (d_cs)
- kcdb_credset_delete(&d_cs);
-
- if (ctx != NULL)
- pkrb5_free_context(ctx);
-
- return rv;
-}
-
-int
-khm_krb5_destroy_identity(khm_handle identity)
-{
- krb5_context ctx;
- krb5_ccache cache;
- krb5_error_code rc;
-
- ctx = NULL;
- cache = NULL;
-
- if (rc = khm_krb5_initialize(identity, &ctx, &cache))
- return(rc);
-
- rc = pkrb5_cc_destroy(ctx, cache);
-
- if (ctx != NULL)
- pkrb5_free_context(ctx);
-
- return(rc);
-}
-
-static BOOL
-GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData)
-{
- NTSTATUS Status = 0;
- HANDLE TokenHandle;
- TOKEN_STATISTICS Stats;
- DWORD ReqLen;
- BOOL Success;
-
- if (!ppSessionData)
- return FALSE;
- *ppSessionData = NULL;
-
- Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
- if ( !Success )
- return FALSE;
-
- Success = GetTokenInformation( TokenHandle, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen );
- CloseHandle( TokenHandle );
- if ( !Success )
- return FALSE;
-
- Status = pLsaGetLogonSessionData( &Stats.AuthenticationId, ppSessionData );
- if ( FAILED(Status) || !ppSessionData )
- return FALSE;
-
- return TRUE;
-}
-
-// IsKerberosLogon() does not validate whether or not there are valid
-// tickets in the cache. It validates whether or not it is reasonable
-// to assume that if we attempted to retrieve valid tickets we could
-// do so. Microsoft does not automatically renew expired tickets.
-// Therefore, the cache could contain expired or invalid tickets.
-// Microsoft also caches the user's password and will use it to
-// retrieve new TGTs if the cache is empty and tickets are requested.
-
-static BOOL
-IsKerberosLogon(VOID)
-{
- PSECURITY_LOGON_SESSION_DATA pSessionData = NULL;
- BOOL Success = FALSE;
-
- if ( GetSecurityLogonSessionData(&pSessionData) ) {
- if ( pSessionData->AuthenticationPackage.Buffer ) {
- WCHAR buffer[256];
- WCHAR *usBuffer;
- int usLength;
-
- Success = FALSE;
- usBuffer = (pSessionData->AuthenticationPackage).Buffer;
- usLength = (pSessionData->AuthenticationPackage).Length;
- if (usLength < 256)
- {
- lstrcpynW (buffer, usBuffer, usLength);
- StringCbCatW (buffer, sizeof(buffer), L"");
- if ( !lstrcmpW(L"Kerberos",buffer) )
- Success = TRUE;
- }
- }
- pLsaFreeReturnBuffer(pSessionData);
- }
- return Success;
-}
-
-
-BOOL
-khm_krb5_ms2mit(char * match_princ, BOOL match_realm, BOOL save_creds,
- khm_handle * ret_ident)
-{
-#ifdef NO_KRB5
- return(FALSE);
-#else /* NO_KRB5 */
- krb5_context kcontext = 0;
- krb5_error_code code = 0;
- krb5_ccache ccache=0;
- krb5_ccache mslsa_ccache=0;
- krb5_creds creds;
- krb5_cc_cursor cursor=0;
- krb5_principal princ = 0;
- khm_handle ident = NULL;
- wchar_t wname[KCDB_IDENT_MAXCCH_NAME];
- char cname[KCDB_IDENT_MAXCCH_NAME];
- char *cache_name = NULL;
- char *princ_name = NULL;
- BOOL rc = FALSE;
-
- kherr_reportf(L"Begin : khm_krb5_ms2mit. save_cred=%d\n", (int) save_creds);
-
- if ( !pkrb5_init_context )
- goto cleanup;
-
- if (code = pkrb5_init_context(&kcontext))
- goto cleanup;
-
- kherr_reportf(L"Resolving MSLSA\n");
-
- if (code = pkrb5_cc_resolve(kcontext, "MSLSA:", &mslsa_ccache))
- goto cleanup;
-
- if ( save_creds ) {
- kherr_reportf(L"Getting principal\n");
- if (code = pkrb5_cc_get_principal(kcontext, mslsa_ccache, &princ))
- goto cleanup;
-
- kherr_reportf(L"Unparsing name\n");
- if (code = pkrb5_unparse_name(kcontext, princ, &princ_name))
- goto cleanup;
-
- AnsiStrToUnicode(wname, sizeof(wname), princ_name);
-
- kherr_reportf(L"Unparsed name [%s]", wname);
-
- /* see if we have to match a specific principal */
- if (match_princ != NULL) {
- if (strcmp(princ_name, match_princ)) {
- kherr_reportf(L"Principal mismatch. Wanted [%S], found [%S]",
- match_princ, princ_name);
- goto cleanup;
- }
- } else if (match_realm) {
- wchar_t * wdefrealm;
- char defrealm[256];
- krb5_data * princ_realm;
-
- wdefrealm = khm_krb5_get_default_realm();
- if (wdefrealm == NULL) {
- kherr_reportf(L"Can't determine default realm");
- goto cleanup;
- }
-
- princ_realm = krb5_princ_realm(kcontext, princ);
- UnicodeStrToAnsi(defrealm, sizeof(defrealm), wdefrealm);
-
- if (strncmp(defrealm, princ_realm->data, princ_realm->length)) {
- kherr_reportf(L"Realm mismatch. Wanted [%S], found [%*S]",
- defrealm, princ_realm->length, princ_realm->data);
- PFREE(wdefrealm);
- goto cleanup;
- }
-
- PFREE(wdefrealm);
- }
-
- if (KHM_SUCCEEDED(kcdb_identity_create(wname,
- KCDB_IDENT_FLAG_CREATE,
- &ident))) {
- khm_handle idconfig = NULL;
- khm_handle k5config = NULL;
- khm_size cb;
-
- wname[0] = L'\0';
-
- kcdb_identity_get_config(ident, KHM_FLAG_CREATE, &idconfig);
- if (idconfig == NULL)
- goto _done_checking_config;
-
- khc_open_space(idconfig, CSNAME_KRB5CRED, KHM_FLAG_CREATE, &k5config);
- if (k5config == NULL)
- goto _done_checking_config;
-
- cb = sizeof(wname);
- khc_read_string(k5config,
- L"DefaultCCName",
- wname, &cb);
-
- _done_checking_config:
-
- if (idconfig)
- khc_close_space(idconfig);
- if (k5config)
- khc_close_space(k5config);
-
- if (wname[0]) {
- UnicodeStrToAnsi(cname, sizeof(cname), wname);
- } else {
- StringCbPrintfA(cname, sizeof(cname), "API:%s", princ_name);
- }
-
- cache_name = cname;
-
- } else {
- /* the identity could not be created. we just use the
- name of the principal as the ccache name. */
- StringCbPrintfA(cname, sizeof(cname), "API:%s", princ_name);
- cache_name = cname;
- }
-
- kherr_reportf(L"Resolving target cache [%S]\n", cache_name);
-
- if (code = pkrb5_cc_resolve(kcontext, cache_name, &ccache)) {
- kherr_reportf(L"Cannot resolve cache [%S] with code=%d. Trying default.\n", cache_name, code);
-
- if (code = pkrb5_cc_default(kcontext, &ccache)) {
- kherr_reportf(L"Failed to resolve default ccache. Code=%d", code);
- goto cleanup;
- }
- }
-
- kherr_reportf(L"Initializing ccache\n");
- if (code = pkrb5_cc_initialize(kcontext, ccache, princ))
- goto cleanup;
-
- kherr_reportf(L"Copying credentials\n");
- if (code = pkrb5_cc_copy_creds(kcontext, mslsa_ccache, ccache))
- goto cleanup;
-
- /* and mark the identity as having been imported */
- if (ident) {
- khm_krb5_set_identity_flags(ident, K5IDFLAG_IMPORTED, K5IDFLAG_IMPORTED);
-
- if (ret_ident) {
- *ret_ident = ident;
- kcdb_identity_hold(*ret_ident);
- }
- }
-
- 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:
- kherr_reportf(L" Received code=%d", code);
-
- if (princ_name)
- pkrb5_free_unparsed_name(kcontext, princ_name);
- 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);
- if (ident)
- kcdb_identity_release(ident);
-
- return(rc);
-#endif /* NO_KRB5 */
-}
-
-#define KRB_FILE "KRB.CON"
-#define KRBREALM_FILE "KRBREALM.CON"
-#define KRB5_FILE "KRB5.INI"
-#define KRB5_TMP_FILE "KRB5.INI.TMP"
-
-BOOL
-khm_krb5_get_temp_profile_file(LPSTR confname, UINT szConfname)
-{
- GetTempPathA(szConfname, confname);
- confname[szConfname-1] = '\0';
- StringCchCatA(confname, szConfname, KRB5_TMP_FILE);
- confname[szConfname-1] = '\0';
- return FALSE;
-}
-
-#ifdef NOT_QUITE_IMPLEMENTED_YET
-BOOL
-khm_krb5_set_profile_file(krb5_context ctx, LPSTR confname)
-{
- char *conffiles[2];
-
- if (confname == NULL ||
- pkrb5_set_config_files == NULL ||
- ctx == NULL)
- return FALSE;
-
- conffiles[0] = confname;
- conffiles[1] = NULL;
-
- if (pkrb5_set_config_files(ctx, conffiles))
- return FALSE;
- else
- return TRUE;
-}
-#endif
-
-BOOL
-khm_krb5_get_profile_file(LPSTR confname, UINT szConfname)
-{
- char **configFile = NULL;
- if (pkrb5_get_default_config_files(&configFile))
- {
- GetWindowsDirectoryA(confname,szConfname);
- confname[szConfname-1] = '\0';
-
- StringCchCatA(confname, szConfname, "\\");
- StringCchCatA(confname, szConfname, KRB5_FILE);
-
- return FALSE;
- }
-
- *confname = 0;
-
- if (configFile)
- {
- StringCchCopyA(confname, szConfname, *configFile);
- pkrb5_free_config_files(configFile);
- }
-
- if (!*confname)
- {
- GetWindowsDirectoryA(confname,szConfname);
- confname[szConfname-1] = '\0';
- StringCchCatA(confname, szConfname, "\\");
- StringCchCatA(confname, szConfname, KRB5_FILE);
- }
-
- return FALSE;
-}
-
-BOOL
-khm_get_krb4_con_file(LPSTR confname, UINT szConfname)
-{
- if (hKrb5 && !hKrb4) { // hold krb.con where krb5.ini is located
- CHAR krbConFile[MAX_PATH]="";
- LPSTR pFind;
-
- //strcpy(krbConFile, CLeashApp::m_krbv5_profile->first_file->filename);
- if (khm_krb5_get_profile_file(krbConFile, sizeof(krbConFile))) {
- GetWindowsDirectoryA(krbConFile,sizeof(krbConFile));
- krbConFile[MAX_PATH-1] = '\0';
- StringCchCatA(confname, szConfname, "\\");
- }
-
- pFind = strrchr(krbConFile, '\\');
- if (pFind) {
- *pFind = '\0';
- StringCchCatA(krbConFile, ARRAYLENGTH(krbConFile), "\\");
- StringCchCatA(krbConFile, ARRAYLENGTH(krbConFile), KRB_FILE);
- }
- else
- krbConFile[0] = '\0';
-
- StringCchCopyA(confname, szConfname, krbConFile);
- }
- else if (hKrb4) {
- unsigned int size = szConfname;
- memset(confname, '\0', szConfname);
- if (!pkrb_get_krbconf2(confname, &size))
- { // Error has happened
- GetWindowsDirectoryA(confname,szConfname);
- confname[szConfname-1] = '\0';
- StringCchCatA(confname, szConfname, "\\");
- StringCchCatA(confname, szConfname, KRB_FILE);
- }
- }
- return FALSE;
-}
-
-int
-readstring(FILE * file, char * buf, int len)
-{
- int c,i;
- memset(buf, '\0', sizeof(buf));
- for (i=0, c=fgetc(file); c != EOF ; c=fgetc(file), i++) {
- if (i < sizeof(buf)) {
- if (c == '\n') {
- buf[i] = '\0';
- return i;
- } else {
- buf[i] = c;
- }
- } else {
- if (c == '\n') {
- buf[len-1] = '\0';
- return(i);
- }
- }
- }
- if (c == EOF) {
- if (i > 0 && i < len) {
- buf[i] = '\0';
- return(i);
- } else {
- buf[len-1] = '\0';
- return(-1);
- }
- }
- return(-1);
-}
-
-/*! \internal
- \brief Return a list of configured realms
-
- The string that is returned is a set of null terminated unicode
- strings, each of which denotes one realm. The set is terminated
- by a zero length null terminated string.
-
- The caller should free the returned string using free()
-
- \return The string with the list of realms or NULL if the
- operation fails.
-*/
-wchar_t *
-khm_krb5_get_realm_list(void)
-{
- wchar_t * rlist = NULL;
-
- if (pprofile_get_subsection_names && pprofile_free_list) {
- const char* rootSection[] = {"realms", NULL};
- const char** rootsec = rootSection;
- char **sections = NULL, **cpp = NULL, *value = NULL;
-
- char krb5_conf[MAX_PATH+1];
-
- if (!khm_krb5_get_profile_file(krb5_conf,sizeof(krb5_conf))) {
- profile_t profile;
- long retval;
- const char *filenames[2];
- wchar_t * d;
- size_t cbsize;
- size_t t;
-
- filenames[0] = krb5_conf;
- filenames[1] = NULL;
- retval = pprofile_init(filenames, &profile);
- if (!retval) {
- retval = pprofile_get_subsection_names(profile, rootsec,
- &sections);
-
- if (!retval)
- {
- /* first figure out how much space to allocate */
- cbsize = 0;
- for (cpp = sections; *cpp; cpp++)
- {
- cbsize += sizeof(wchar_t) * (strlen(*cpp) + 1);
- }
- cbsize += sizeof(wchar_t); /* double null terminated */
-
- rlist = PMALLOC(cbsize);
- d = rlist;
- for (cpp = sections; *cpp; cpp++)
- {
- AnsiStrToUnicode(d, cbsize, *cpp);
- t = wcslen(d) + 1;
- d += t;
- cbsize -= sizeof(wchar_t) * t;
- }
- *d = L'\0';
- }
-
- pprofile_free_list(sections);
-
-#if 0
- retval = pprofile_get_string(profile, "libdefaults","noaddresses", 0, "true", &value);
- if ( value ) {
- disable_noaddresses = config_boolean_to_int(value);
- pprofile_release_string(value);
- }
-#endif
- pprofile_release(profile);
- }
- }
- } else {
- FILE * file;
- char krb_conf[MAX_PATH+1];
- char * p;
- size_t cbsize, t;
- wchar_t * d;
-
- if (!khm_get_krb4_con_file(krb_conf,sizeof(krb_conf)) &&
-#if _MSC_VER >= 1400
- !fopen_s(&file, krb_conf, "rt")
-#else
- (file = fopen(krb_conf, "rt"))
-#endif
- )
- {
- char lineBuf[256];
-
- /*TODO: compute the actual required buffer size instead of hardcoding */
- cbsize = 16384; // arbitrary
- rlist = PMALLOC(cbsize);
- d = rlist;
-
- // Skip the default realm
- readstring(file,lineBuf,sizeof(lineBuf));
-
- // Read the defined realms
- while (TRUE)
- {
- if (readstring(file,lineBuf,sizeof(lineBuf)) < 0)
- break;
-
- if (*(lineBuf + strlen(lineBuf) - 1) == '\r')
- *(lineBuf + strlen(lineBuf) - 1) = 0;
-
- for (p=lineBuf; *p ; p++)
- {
- if (isspace(*p)) {
- *p = 0;
- break;
- }
- }
-
- if ( strncmp(".KERBEROS.OPTION.",lineBuf,17) ) {
- t = strlen(lineBuf) + 1;
- if(cbsize > (1 + t*sizeof(wchar_t))) {
- AnsiStrToUnicode(d, cbsize, lineBuf);
- d += t;
- cbsize -= t * sizeof(wchar_t);
- } else
- break;
- }
- }
-
- *d = L'\0';
-
- fclose(file);
- }
- }
-
- return rlist;
-}
-
-/*! \internal
- \brief Get the default realm
-
- A string will be returned that specifies the default realm. The
- caller should free the string using PFREE().
-
- Returns NULL if the operation fails.
-*/
-wchar_t *
-khm_krb5_get_default_realm(void)
-{
- wchar_t * realm;
- size_t cch;
- krb5_context ctx=0;
- char * def = 0;
-
- pkrb5_init_context(&ctx);
-
- if (ctx == 0)
- return NULL;
-
- pkrb5_get_default_realm(ctx,&def);
-
- if (def) {
- cch = strlen(def) + 1;
- realm = PMALLOC(sizeof(wchar_t) * cch);
- AnsiStrToUnicode(realm, sizeof(wchar_t) * cch, def);
- pkrb5_free_default_realm(ctx, def);
- } else
- realm = NULL;
-
- pkrb5_free_context(ctx);
-
- return realm;
-}
-
-long
-khm_krb5_set_default_realm(wchar_t * realm) {
- krb5_context ctx=0;
- char * def = 0;
- long rv = 0;
- char astr[K5_MAXCCH_REALM];
-
- UnicodeStrToAnsi(astr, sizeof(astr), realm);
-
- pkrb5_init_context(&ctx);
- pkrb5_get_default_realm(ctx,&def);
-
- if ((def && strcmp(def, astr)) ||
- !def) {
- rv = pkrb5_set_default_realm(ctx, astr);
- }
-
- if (def) {
- pkrb5_free_default_realm(ctx, def);
- }
-
- pkrb5_free_context(ctx);
-
- return rv;
-}
-
-wchar_t *
-khm_get_realm_from_princ(wchar_t * princ) {
- wchar_t * t;
-
- if(!princ)
- return NULL;
-
- for (t = princ; *t; t++) {
- if(*t == L'\\') { /* escape */
- t++;
- if(! *t) /* malformed */
- break;
- } else if (*t == L'@')
- break;
- }
-
- if (*t == '@' && *(t+1) != L'\0')
- return (t+1);
- else
- return NULL;
-}
-
-long
-khm_krb5_changepwd(char * principal,
- char * password,
- char * newpassword,
- char** error_str)
-{
- krb5_error_code rc = 0;
- int result_code = 0;
- krb5_data result_code_string, result_string;
- krb5_context context = 0;
- krb5_principal princ = 0;
- krb5_get_init_creds_opt opts;
- krb5_creds creds;
-
- result_string.data = 0;
- result_code_string.data = 0;
-
- if ( !pkrb5_init_context )
- goto cleanup;
-
- if (rc = pkrb5_init_context(&context)) {
- goto cleanup;
- }
-
- if (rc = pkrb5_parse_name(context, principal, &princ)) {
- goto cleanup;
- }
-
- pkrb5_get_init_creds_opt_init(&opts);
- pkrb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
- pkrb5_get_init_creds_opt_set_renew_life(&opts, 0);
- pkrb5_get_init_creds_opt_set_forwardable(&opts, 0);
- pkrb5_get_init_creds_opt_set_proxiable(&opts, 0);
- pkrb5_get_init_creds_opt_set_address_list(&opts,NULL);
-
- if (rc = pkrb5_get_init_creds_password(context, &creds, princ,
- password, 0, 0, 0,
- "kadmin/changepw", &opts)) {
- if (rc == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
-#if 0
- com_err(argv[0], 0,
- "Password incorrect while getting initial ticket");
-#endif
- } else {
-#if 0
- com_err(argv[0], ret, "getting initial ticket");
-#endif
- }
- goto cleanup;
- }
-
- if (rc = pkrb5_change_password(context, &creds, newpassword,
- &result_code, &result_code_string,
- &result_string)) {
-#if 0
- com_err(argv[0], ret, "changing password");
-#endif
- goto cleanup;
- }
-
- if (result_code) {
- int len = result_code_string.length +
- (result_string.length ? (sizeof(": ") - 1) : 0) +
- result_string.length;
- if (len && error_str) {
- *error_str = PMALLOC(len + 1);
- if (*error_str)
- StringCchPrintfA(*error_str, len+1,
- "%.*s%s%.*s",
- result_code_string.length,
- result_code_string.data,
- result_string.length?": ":"",
- result_string.length,
- result_string.data);
- }
- rc = result_code;
- goto cleanup;
- }
-
- cleanup:
- if (result_string.data)
- pkrb5_free_data_contents(context, &result_string);
-
- if (result_code_string.data)
- pkrb5_free_data_contents(context, &result_code_string);
-
- if (princ)
- pkrb5_free_principal(context, princ);
-
- if (context)
- pkrb5_free_context(context);
-
- return rc;
-}
-
-khm_int32 KHMAPI
-khm_krb5_creds_is_equal(khm_handle vcred1, khm_handle vcred2, void * dummy) {
- if (kcdb_creds_comp_attr(vcred1, vcred2, KCDB_ATTR_LOCATION) ||
- kcdb_creds_comp_attr(vcred1, vcred2, attr_id_key_enctype) ||
- kcdb_creds_comp_attr(vcred1, vcred2, attr_id_tkt_enctype) ||
- kcdb_creds_comp_attr(vcred1, vcred2, attr_id_kvno))
- return 1;
- else
- return 0;
-}
-
-void
-khm_krb5_set_identity_flags(khm_handle identity,
- khm_int32 flag_mask,
- khm_int32 flag_value) {
-
- khm_int32 t = 0;
- khm_size cb;
-
- cb = sizeof(t);
- if (KHM_FAILED(kcdb_identity_get_attr(identity,
- attr_id_krb5_idflags,
- NULL,
- &t, &cb))) {
- t = 0;
- }
-
- t &= ~flag_mask;
- t |= (flag_value & flag_mask);
-
- kcdb_identity_set_attr(identity,
- attr_id_krb5_idflags,
- &t, sizeof(t));
-}
-
-khm_int32
-khm_krb5_get_identity_flags(khm_handle identity) {
- khm_int32 t = 0;
- khm_size cb;
-
- cb = sizeof(t);
- kcdb_identity_get_attr(identity,
- attr_id_krb5_idflags,
- NULL, &t, &cb);
-
- return t;
-}
-
-long
-khm_krb5_get_temp_ccache(krb5_context ctx,
- krb5_ccache * prcc) {
- int rnd = rand();
- char ccname[MAX_PATH];
- long code = 0;
- krb5_ccache cc = 0;
-
- StringCbPrintfA(ccname, sizeof(ccname), "MEMORY:TempCache%8x", rnd);
-
- code = pkrb5_cc_resolve(ctx, ccname, &cc);
-
- if (code == 0)
- *prcc = cc;
-
- return code;
-}
-
-/*
-
- The configuration information for each identity comes from a
- multitude of layers organized as follows. The ordering is
- decreasing in priority. When looking up a value, the value will be
- looked up in each layer in turn starting at level 0. The first
- instance of the value found will be the effective value.
-
- 0 : <identity configuration>\Krb5Cred
-
- 0.1: per user
-
- 0.2: per machine
-
- 1 : <plugin configuration>\Parameters\Realms\<realm of identity>
-
- 1.1: per user
-
- 1.2: per machine
-
- 2 : <plugin configuration>\Parameters
-
- 2.1: per user
-
- 2.2: per machine
-
- 2.3: schema
-
- */
-khm_int32
-khm_krb5_get_identity_config(khm_handle ident,
- khm_int32 flags,
- khm_handle * ret_csp) {
-
- khm_int32 rv = KHM_ERROR_SUCCESS;
- khm_handle csp_i = NULL;
- khm_handle csp_ik5 = NULL;
- khm_handle csp_realms = NULL;
- khm_handle csp_realm = NULL;
- khm_handle csp_plugins = NULL;
- khm_handle csp_krbcfg = NULL;
- khm_handle csp_rv = NULL;
- wchar_t realm[KCDB_IDENT_MAXCCH_NAME];
-
- realm[0] = L'\0';
-
- if (ident) {
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- wchar_t * trealm;
- khm_size cb_idname = sizeof(idname);
-
- rv = kcdb_identity_get_name(ident, idname, &cb_idname);
- if (KHM_SUCCEEDED(rv) &&
- (trealm = khm_get_realm_from_princ(idname)) != NULL) {
- StringCbCopy(realm, sizeof(realm), trealm);
- }
- }
-
- if (ident) {
- rv = kcdb_identity_get_config(ident, flags, &csp_i);
- if (KHM_FAILED(rv))
- goto try_realm;
-
- rv = khc_open_space(csp_i, CSNAME_KRB5CRED, flags, &csp_ik5);
- if (KHM_FAILED(rv))
- goto try_realm;
-
- try_realm:
-
- if (realm[0] == L'\0')
- goto done_shadow_realm;
-
- rv = khc_open_space(csp_params, CSNAME_REALMS, flags, &csp_realms);
- if (KHM_FAILED(rv))
- goto done_shadow_realm;
-
- rv = khc_open_space(csp_realms, realm, flags, &csp_realm);
- if (KHM_FAILED(rv))
- goto done_shadow_realm;
-
- rv = khc_shadow_space(csp_realm, csp_params);
-
- done_shadow_realm:
-
- if (csp_ik5) {
- if (csp_realm)
- rv = khc_shadow_space(csp_ik5, csp_realm);
- else
- rv = khc_shadow_space(csp_ik5, csp_params);
-
- csp_rv = csp_ik5;
- } else {
- if (csp_realm)
- csp_rv = csp_realm;
- }
- }
-
- if (csp_rv == NULL) {
-
- /* No valid identity specified or the specified identity
- doesn't have any configuration. We default to the
- parameters key. */
-
- /* we don't just return csp_params since that's a global
- handle that we shouldn't close until the plugin is
- unloaded. The caller is going to close the returned handle
- when it is done. So we need to create a new csp_params
- that can safely be closed. */
-
- rv = kmm_get_plugins_config(0, &csp_plugins);
- if (KHM_FAILED(rv))
- goto done;
-
- rv = khc_open_space(csp_plugins, CSNAME_KRB5CRED, flags, &csp_krbcfg);
- if (KHM_FAILED(rv))
- goto done;
-
- rv = khc_open_space(csp_krbcfg, CSNAME_PARAMS, flags, &csp_rv);
- }
-
- done:
-
- *ret_csp = csp_rv;
-
- /* leave csp_ik5. If it's non-NULL, then it's the return value */
- /* leave csp_rv. It's the return value. */
- if (csp_i)
- khc_close_space(csp_i);
- if (csp_realms)
- khc_close_space(csp_realms);
-
- /* csp_realm can also be a return value if csp_ik5 was NULL */
- if (csp_realm && csp_realm != csp_rv)
- khc_close_space(csp_realm);
-
- if (csp_plugins)
- khc_close_space(csp_plugins);
- if (csp_krbcfg)
- khc_close_space(csp_krbcfg);
-
- return rv;
-}
-
-/* from get_in_tkt.c */
-static krb5_error_code
-get_libdefault_string(profile_t profile, const char * realm,
- const char * option, char ** ret_val) {
- char realmstr[K5_MAXCCH_REALM];
- char **nameval = NULL;
- const char * names[4];
- krb5_error_code code = 0;
-
- names[0] = "libdefaults";
-
- if (!realm || !realm[0])
- goto try_number_two;
-
- StringCbCopyA(realmstr, sizeof(realmstr), realm);
-
- /*
- * Try number one:
- *
- * [libdefaults]
- * REALM = {
- * option = <boolean>
- * }
- */
-
- names[1] = realmstr;
- names[2] = option;
- names[3] = 0;
- code = pprofile_get_values(profile, names, &nameval);
- if (code == 0 && nameval && nameval[0])
- goto goodbye;
-
- try_number_two:
-
- /*
- * Try number two:
- *
- * [libdefaults]
- * option = <boolean>
- */
-
- names[1] = option;
- names[2] = 0;
- code = pprofile_get_values(profile, names, &nameval);
- if (code == 0 && nameval && nameval[0])
- goto goodbye;
-
- goodbye:
- if (!nameval)
- return(ENOENT);
-
- if (!nameval[0]) {
- code = ENOENT;
- } else {
- size_t cb;
-
- if (FAILED(StringCbLengthA(nameval[0], K5_MAXCCH_REALM * sizeof(char), &cb))) {
- code = ENOMEM;
- } else {
- cb += sizeof(char);
- *ret_val = PMALLOC(cb);
-
- if (!*ret_val)
- code = ENOMEM;
- else {
- StringCbCopyA(*ret_val, cb, nameval[0]);
- code = 0;
- }
- }
- }
-
- pprofile_free_list(nameval);
-
- return code;
-}
-
-khm_int32
-khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {
-
- khm_int32 rv = KHM_ERROR_SUCCESS;
- khm_handle csp_id = NULL;
- khm_int32 regf = 0;
- khm_int32 proff = 0;
- khm_int32 e;
- khm_int32 v;
- CHAR confname[MAX_PATH];
- CHAR realmname[K5_MAXCCH_REALM];
-
- ZeroMemory(p, sizeof(*p));
-
- rv = khm_krb5_get_identity_config(ident, 0, &csp_id);
- if (KHM_FAILED(rv))
- goto done_reg;
-
-
-#define GETVAL(vname, vfield, flag) \
- do { \
- e = khc_value_exists(csp_id, vname); \
- rv = khc_read_int32(csp_id, vname, &v); \
- if (KHM_FAILED(rv)) goto done_reg; \
- p->vfield = v; \
- if ((e & ~KCONF_FLAG_SCHEMA) != 0) regf |= flag; \
- } while(FALSE)
-
- /* Flags */
- GETVAL(L"Renewable", renewable, K5PARAM_F_RENEW);
- GETVAL(L"Forwardable", forwardable, K5PARAM_F_FORW);
- GETVAL(L"Proxiable", proxiable, K5PARAM_F_PROX);
- GETVAL(L"Addressless", addressless, K5PARAM_F_ADDL);
- GETVAL(L"PublicIP", publicIP, K5PARAM_F_PUBIP);
-
- /* Lifetime */
- GETVAL(L"DefaultLifetime", lifetime, K5PARAM_F_LIFE);
- GETVAL(L"MaxLifetime", lifetime_max, K5PARAM_F_LIFE_H);
- GETVAL(L"MinLifetime", lifetime_min, K5PARAM_F_LIFE_L);
-
- /* Renewable lifetime */
- GETVAL(L"DefaultRenewLifetime", renew_life, K5PARAM_F_RLIFE);
- GETVAL(L"MaxRenewLifetime", renew_life_max, K5PARAM_F_RLIFE_H);
- GETVAL(L"MinRenewLifetime", renew_life_min, K5PARAM_F_RLIFE_L);
-
-#undef GETVAL
-
- done_reg:
-
- if (csp_id)
- khc_close_space(csp_id);
-
- /* if all the parameters were read from the registry, then we have
- no reason to read from the profile file. */
- if (regf == K5PARAM_FM_ALL) {
- p->source_reg = regf;
- return KHM_ERROR_SUCCESS;
- }
-
- if (rv)
- return rv;
-
- /* we need to figure out the realm name, since there might be
- per-realm configuration in the profile file. */
-
- realmname[0] = '\0';
-
- if (ident) {
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- khm_size cb;
-
- idname[0] = L'\0';
- cb = sizeof(idname);
- rv = kcdb_identity_get_name(ident, idname, &cb);
- if (KHM_SUCCEEDED(rv)) {
- wchar_t * wrealm;
-
- wrealm = khm_get_realm_from_princ(idname);
- if (wrealm) {
- UnicodeStrToAnsi(realmname, sizeof(realmname), wrealm);
- }
- }
- }
-
- /* If we get here, then some of the settings we read from the
- configuration actually came from the schema. In other words,
- the values weren't really defined for this identity. So we now
- have to read the values from the krb5 configuration file. */
-
- if (!khm_krb5_get_profile_file(confname, sizeof(confname))) {
- profile_t profile;
- const char * filenames[2];
- long retval;
-
- filenames[0] = confname;
- filenames[1] = NULL;
-
- if (!pprofile_init(filenames, &profile)) {
-
- /* default ticket lifetime */
- if (!(regf & K5PARAM_F_LIFE)) {
- char * value = NULL;
- retval = get_libdefault_string(profile, realmname,
- "ticket_lifetime", &value);
-
- if (retval == 0 && value) {
- krb5_deltat d;
-
- retval = pkrb5_string_to_deltat(value, &d);
- if (retval == KRB5_DELTAT_BADFORMAT) {
- /* Historically some sites use relations of
- the form 'ticket_lifetime = 24000' where
- the unit is left out but is assumed to be
- seconds. Then there are other sites which
- use the form 'ticket_lifetime = 600' where
- the unit is assumed to be minutes. While
- these are technically wrong (a unit needs
- to be specified), we try to accomodate for
- this using the safe assumption that the
- unit is seconds and tack an 's' to the end
- and see if that works. */
-
- size_t cch;
- char tmpbuf[256];
- char * buf;
-
- do {
- if (FAILED(StringCchLengthA(value, 1024 /* unresonably large size */,
- &cch)))
- break;
-
- cch += sizeof(char) * 2; /* NULL and new 's' */
- if (cch > ARRAYLENGTH(tmpbuf))
- buf = PMALLOC(cch * sizeof(char));
- else
- buf = tmpbuf;
-
- StringCchCopyA(buf, cch, value);
- StringCchCatA(buf, cch, "s");
-
- retval = pkrb5_string_to_deltat(buf, &d);
- if (retval == 0) {
- p->lifetime = d;
- proff |= K5PARAM_F_LIFE;
- }
-
- if (buf != tmpbuf)
- PFREE(buf);
-
- } while(0);
-
- } else if (retval == 0) {
- p->lifetime = d;
- proff |= K5PARAM_F_LIFE;
- }
-
- PFREE(value);
- }
- }
-
- if (!(regf & K5PARAM_F_RLIFE)) {
- char * value = NULL;
- retval = get_libdefault_string(profile, realmname,
- "renew_lifetime", &value);
- if (retval == 0 && value) {
- krb5_deltat d;
-
- retval = pkrb5_string_to_deltat(value, &d);
- if (retval == 0) {
- p->renew_life = d;
- proff |= K5PARAM_F_RLIFE;
- }
- PFREE(value);
- }
- }
-
- if (!(regf & K5PARAM_F_FORW)) {
- char * value = NULL;
- retval = get_libdefault_string(profile, realmname,
- "forwardable", &value);
- if (retval == 0 && value) {
- khm_boolean b;
-
- if (!khm_krb5_parse_boolean(value, &b))
- p->forwardable = b;
- else
- p->forwardable = FALSE;
- PFREE(value);
- proff |= K5PARAM_F_FORW;
- }
- }
-
- if (!(regf & K5PARAM_F_RENEW)) {
- char * value = NULL;
- retval = get_libdefault_string(profile, realmname,
- "renewable", &value);
- if (retval == 0 && value) {
- khm_boolean b;
-
- if (!khm_krb5_parse_boolean(value, &b))
- p->renewable = b;
- else
- p->renewable = TRUE;
- PFREE(value);
- proff |= K5PARAM_F_RENEW;
- }
- }
-
- if (!(regf & K5PARAM_F_ADDL)) {
- char * value = NULL;
- retval = get_libdefault_string(profile, realmname,
- "noaddresses", &value);
- if (retval == 0 && value) {
- khm_boolean b;
-
- if (!khm_krb5_parse_boolean(value, &b))
- p->addressless = b;
- else
- p->addressless = TRUE;
- PFREE(value);
- proff |= K5PARAM_F_ADDL;
- }
- }
-
- if (!(regf & K5PARAM_F_PROX)) {
- char * value = NULL;
- retval = get_libdefault_string(profile, realmname,
- "proxiable", &value);
- if (retval == 0 && value) {
- khm_boolean b;
-
- if (!khm_krb5_parse_boolean(value, &b))
- p->proxiable = b;
- else
- p->proxiable = FALSE;
- PFREE(value);
- proff |= K5PARAM_F_PROX;
- }
- }
-
- pprofile_release(profile);
- }
- }
-
- p->source_reg = regf;
- p->source_prof = proff;
-
- return rv;
-}
-
-/* Note that p->source_reg and p->source_prof is used in special ways
- here. All fields that are flagged in source_reg will be written to
- the configuration (if they are different from what
- khm_krb5_get_identity_params() reports). All fields that are
- flagged in source_prof will be removed from the configuration
- (thereby exposing the value defined in the profile file). */
-khm_int32
-khm_krb5_set_identity_params(khm_handle ident, const k5_params * p) {
- khm_int32 rv = KHM_ERROR_SUCCESS;
- khm_handle csp_id = NULL;
- k5_params p_s;
- khm_int32 source_reg = p->source_reg;
- khm_int32 source_prof = p->source_prof;
-
- rv = khm_krb5_get_identity_config(ident,
- KHM_PERM_WRITE | KHM_FLAG_CREATE |
- KCONF_FLAG_WRITEIFMOD,
- &csp_id);
- if (KHM_FAILED(rv))
- goto done_reg;
-
- khm_krb5_get_identity_params(ident, &p_s);
-
- /* Remove any bits that don't make sense. Not all values can be
- specified in the profile file. */
- source_prof &= K5PARAM_FM_PROF;
-
- /* if a flag appears in both source_prof and source_reg, remove
- the flag from source_reg. */
- source_reg &= ~source_prof;
-
- /* we only write values that have changed, and that are flagged in
- source_reg */
-
- if ((source_reg & K5PARAM_F_RENEW) &&
- !!p_s.renewable != !!p->renewable)
- khc_write_int32(csp_id, L"Renewable", !!p->renewable);
-
- if ((source_reg & K5PARAM_F_FORW) &&
- !!p_s.forwardable != !!p->forwardable)
- khc_write_int32(csp_id, L"Forwardable", !!p->forwardable);
-
- if ((source_reg & K5PARAM_F_PROX) &&
- !!p_s.proxiable != !!p->proxiable)
- khc_write_int32(csp_id, L"Proxiable", !!p->proxiable);
-
- if ((source_reg & K5PARAM_F_ADDL) &&
- !!p_s.addressless != !!p->addressless)
- khc_write_int32(csp_id, L"Addressless", !!p->addressless);
-
- if ((source_reg & K5PARAM_F_PUBIP) &&
- p_s.publicIP != p->publicIP)
- khc_write_int32(csp_id, L"PublicIP", p->publicIP);
-
- if ((source_reg & K5PARAM_F_LIFE) &&
- p_s.lifetime != p->lifetime)
- khc_write_int32(csp_id, L"DefaultLifetime", p->lifetime);
-
- if ((source_reg & K5PARAM_F_LIFE_H) &&
- p_s.lifetime_max != p->lifetime_max)
- khc_write_int32(csp_id, L"MaxLifetime", p->lifetime_max);
-
- if ((source_reg & K5PARAM_F_LIFE_L) &&
- p_s.lifetime_min != p->lifetime_min)
- khc_write_int32(csp_id, L"MinLifetime", p->lifetime_min);
-
- if ((source_reg & K5PARAM_F_RLIFE) &&
- p_s.renew_life != p->renew_life)
- khc_write_int32(csp_id, L"DefaultRenewLifetime", p->renew_life);
-
- if ((source_reg & K5PARAM_F_RLIFE_H) &&
- p_s.renew_life_max != p->renew_life_max)
- khc_write_int32(csp_id, L"MaxRenewLifetime", p->renew_life_max);
-
- if ((source_reg & K5PARAM_F_RLIFE_L) &&
- p_s.renew_life_min != p->renew_life_min)
- khc_write_int32(csp_id, L"MinRenewLifetime", p->renew_life_min);
-
- /* and now, remove the values that are present in source_prof.
- Not all values are removed since not all values can be
- specified in the profile file. */
- if (source_prof & K5PARAM_F_RENEW)
- khc_remove_value(csp_id, L"Renewable", 0);
-
- if (source_prof & K5PARAM_F_FORW)
- khc_remove_value(csp_id, L"Forwardable", 0);
-
- if (source_prof & K5PARAM_F_PROX)
- khc_remove_value(csp_id, L"Proxiable", 0);
-
- if (source_prof & K5PARAM_F_ADDL)
- khc_remove_value(csp_id, L"Addressless", 0);
-
- if (source_prof & K5PARAM_F_LIFE)
- khc_remove_value(csp_id, L"DefaultLifetime", 0);
-
- if (source_prof & K5PARAM_F_RLIFE)
- khc_remove_value(csp_id, L"DefaultRenewLifetime", 0);
-
- done_reg:
- if (csp_id != NULL)
- khc_close_space(csp_id);
-
- return rv;
-}
-
-static const char *const conf_yes[] = {
- "y", "yes", "true", "t", "1", "on",
- 0,
-};
-
-static const char *const conf_no[] = {
- "n", "no", "false", "nil", "0", "off",
- 0,
-};
-
-int
-khm_krb5_parse_boolean(const char *s, khm_boolean * b)
-{
- const char *const *p;
-
- for(p=conf_yes; *p; p++) {
- if (!_stricmp(*p,s)) {
- *b = TRUE;
- return 0;
- }
- }
-
- for(p=conf_no; *p; p++) {
- if (!_stricmp(*p,s)) {
- *b = FALSE;
- return 0;
- }
- }
-
- /* Default to "no" */
- return KHM_ERROR_INVALID_PARAM;
-}
+/*
+* Copyright (c) 2005 Massachusetts Institute of Technology
+* Copyright (c) 2006,2007 Secure Endpoints Inc.
+*
+* Permission is hereby granted, free of charge, to any person
+* obtaining a copy of this software and associated documentation
+* files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy,
+* modify, merge, publish, distribute, sublicense, and/or sell copies
+* of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*/
+
+/* $Id$ */
+
+/* Originally this was krb5routines.c in Leash sources. Subsequently
+ * modified and adapted for NetIDMgr */
+
+#include<krbcred.h>
+#include<kherror.h>
+
+#define SECURITY_WIN32
+#include <security.h>
+
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <strsafe.h>
+
+long
+khm_convert524(krb5_context alt_ctx)
+{
+ 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 *) PMALLOC(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));
+ PFREE(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);
+}
+
+#ifdef DEPRECATED_REMOVABLE
+int com_addr(void)
+{
+ long ipAddr;
+ char loc_addr[ADDR_SZ];
+ CREDENTIALS cred;
+ char service[40];
+ char instance[40];
+ // char addr[40];
+ char realm[40];
+ struct in_addr LocAddr;
+ int k_errno;
+
+ if (pkrb_get_cred == NULL)
+ return(KSUCCESS);
+
+ k_errno = (*pkrb_get_cred)(service,instance,realm,&cred);
+ if (k_errno)
+ return KRBERR(k_errno);
+
+ while(1) {
+ ipAddr = (*pLocalHostAddr)();
+ LocAddr.s_addr = ipAddr;
+ StringCbCopyA(loc_addr, sizeof(loc_addr), inet_ntoa(LocAddr));
+ if ( strcmp(cred.address, loc_addr) != 0) {
+ /* TODO: do something about this */
+ //Leash_kdestroy ();
+ break;
+ }
+ break;
+ } // while()
+ return 0;
+}
+#endif
+
+/* we use these structures to keep track of identities that we find
+ while going through the API, FILE and MSLSA caches and enumerating
+ credentials. The only identities we want to keep track of are the
+ ones that have an initial ticket. We collect information for each
+ of the identities we find that we have initial tickets for and
+ then set the properties for the identities at once. */
+
+typedef struct tag_ident_data {
+ khm_handle ident; /* handle to the identity */
+ khm_int32 count; /* number of initial tickets we have
+ found for this identity. */
+ wchar_t ccname[MAX_PATH];
+ FILETIME ft_issue;
+ FILETIME ft_expire;
+ FILETIME ft_renewexpire;
+ khm_int32 krb5_flags;
+} ident_data;
+
+typedef struct tag_identlist {
+ ident_data * list;
+ khm_size n_list;
+ khm_size nc_list;
+} identlist;
+
+#define IDLIST_ALLOC_INCR 8
+
+static void
+tc_prep_idlist(identlist * idlist) {
+ khm_int32 rv;
+ khm_size cb_ids = 0;
+ khm_size n_ids = 0;
+ khm_size i;
+ wchar_t * ids = NULL;
+ wchar_t *thisid;
+
+ idlist->list = NULL;
+ idlist->n_list = 0;
+ idlist->nc_list = 0;
+
+ do {
+
+ if (ids) {
+ PFREE(ids);
+ ids = NULL;
+ }
+
+ rv = kcdb_identity_enum(KCDB_IDENT_FLAG_ACTIVE,
+ KCDB_IDENT_FLAG_ACTIVE,
+ NULL,
+ &cb_ids,
+ &n_ids);
+
+ if (rv != KHM_ERROR_TOO_LONG)
+ break; /* something else is wrong */
+
+ if (n_ids == 0 || cb_ids == 0)
+ break; /* no identities to process */
+
+#ifdef DEBUG
+ assert(cb_ids > 0);
+#endif
+
+ ids = PMALLOC(cb_ids);
+#ifdef DEBUG
+ assert(ids != NULL);
+#endif
+ if (ids == NULL)
+ break;
+
+ rv = kcdb_identity_enum(KCDB_IDENT_FLAG_ACTIVE,
+ KCDB_IDENT_FLAG_ACTIVE,
+ ids,
+ &cb_ids,
+ &n_ids);
+
+ if (KHM_SUCCEEDED(rv))
+ break;
+
+ } while (TRUE);
+
+ if (ids == NULL)
+ return;
+
+ if (KHM_FAILED(rv) || n_ids == 0) {
+ if (ids)
+ PFREE(ids);
+ return;
+ }
+
+ idlist->nc_list = UBOUNDSS(n_ids, IDLIST_ALLOC_INCR, IDLIST_ALLOC_INCR);
+
+ idlist->list = PCALLOC(idlist->nc_list, sizeof(idlist->list[0]));
+
+ for (i = 0, thisid = ids;
+ thisid && thisid[0];
+ thisid = multi_string_next(thisid)) {
+
+ khm_handle ident;
+
+ rv = kcdb_identity_create(thisid, 0, &ident);
+
+ if (KHM_FAILED(rv))
+ continue;
+
+ idlist->list[i].ident = ident;
+ idlist->list[i].count = 0;
+
+ i++;
+ }
+
+ idlist->n_list = i;
+
+ PFREE(ids);
+}
+
+static ident_data *
+tc_add_ident_to_list(identlist * idlist, khm_handle ident) {
+ khm_size i;
+ ident_data * d;
+
+ for (i=0; i < idlist->n_list; i++) {
+ if (kcdb_identity_is_equal(ident, idlist->list[i].ident))
+ break;
+ }
+
+ if (i < idlist->n_list) {
+ /* we already have this identity on our list. Increment the
+ count */
+ idlist->list[i].count++;
+ return &idlist->list[i];
+ }
+
+ /* it wasn't in our list. Add it */
+
+ if (idlist->n_list + 1 > idlist->nc_list) {
+ idlist->nc_list = UBOUNDSS(idlist->n_list + 1,
+ IDLIST_ALLOC_INCR,
+ IDLIST_ALLOC_INCR);
+#ifdef DEBUG
+ assert(idlist->n_list + 1 <= idlist->nc_list);
+#endif
+ idlist->list = PREALLOC(idlist->list,
+ sizeof(idlist->list[0]) * idlist->nc_list);
+#ifdef DEBUG
+ assert(idlist->list);
+#endif
+ ZeroMemory(&idlist->list[idlist->n_list],
+ sizeof(idlist->list[0]) *
+ (idlist->nc_list - idlist->n_list));
+ }
+
+ d = &idlist->list[idlist->n_list];
+
+ ZeroMemory(d, sizeof(*d));
+
+ d->ident = ident;
+ d->count = 1;
+
+ idlist->n_list++;
+
+ kcdb_identity_hold(ident);
+
+ return d;
+}
+
+static void
+tc_set_ident_data(identlist * idlist) {
+ khm_size i;
+ wchar_t k5idtype[KCDB_MAXCCH_NAME];
+
+ k5idtype[0] = L'\0';
+ LoadString(hResModule, IDS_KRB5_NC_NAME,
+ k5idtype, ARRAYLENGTH(k5idtype));
+
+ for (i=0; i < idlist->n_list; i++) {
+#ifdef DEBUG
+ assert(idlist->list[i].ident);
+#endif
+
+ if (idlist->list[i].count > 0) {
+ khm_int32 t;
+
+ t = credtype_id_krb5;
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ KCDB_ATTR_TYPE,
+ &t,
+ sizeof(t));
+
+ /* We need to manually add the type name if we want the
+ name to show up in the property list for the identity.
+ The type name is only automatically calculated for
+ credentials. */
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ KCDB_ATTR_TYPE_NAME,
+ k5idtype,
+ KCDB_CBSIZE_AUTO);
+
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ attr_id_krb5_ccname,
+ idlist->list[i].ccname,
+ KCDB_CBSIZE_AUTO);
+
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ KCDB_ATTR_EXPIRE,
+ &idlist->list[i].ft_expire,
+ sizeof(idlist->list[i].ft_expire));
+
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ KCDB_ATTR_ISSUE,
+ &idlist->list[i].ft_issue,
+ sizeof(idlist->list[i].ft_issue));
+
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ attr_id_krb5_flags,
+ &idlist->list[i].krb5_flags,
+ sizeof(idlist->list[i].krb5_flags));
+
+ if (idlist->list[i].ft_renewexpire.dwLowDateTime == 0 &&
+ idlist->list[i].ft_renewexpire.dwHighDateTime == 0) {
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ KCDB_ATTR_RENEW_EXPIRE,
+ NULL, 0);
+ } else {
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ KCDB_ATTR_RENEW_EXPIRE,
+ &idlist->list[i].ft_renewexpire,
+ sizeof(idlist->list[i].ft_renewexpire));
+ }
+
+ } else {
+ /* We didn't see any TGTs for this identity. We have to
+ remove all the Krb5 supplied properties. */
+
+ khm_int32 t;
+ khm_size cb;
+
+ cb = sizeof(t);
+ if (KHM_SUCCEEDED(kcdb_identity_get_attr(idlist->list[i].ident,
+ KCDB_ATTR_TYPE, NULL,
+ &t,
+ &cb)) &&
+ t == credtype_id_krb5) {
+
+ /* disown this and remove all our properties. the
+ system will GC this identity if nobody claims it.*/
+
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ KCDB_ATTR_TYPE, NULL, 0);
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ KCDB_ATTR_TYPE_NAME, NULL, 0);
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ attr_id_krb5_ccname, NULL, 0);
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ KCDB_ATTR_EXPIRE, NULL, 0);
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ KCDB_ATTR_ISSUE, NULL, 0);
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ attr_id_krb5_flags, NULL, 0);
+ kcdb_identity_set_attr(idlist->list[i].ident,
+ KCDB_ATTR_RENEW_EXPIRE, NULL, 0);
+ } else {
+ /* otherwise, this identity doesn't belong to us. We
+ should leave it as is. */
+ }
+ }
+ }
+}
+
+static void
+tc_free_idlist(identlist * idlist) {
+ khm_size i;
+
+ for (i=0; i < idlist->n_list; i++) {
+ if (idlist->list[i].ident != NULL) {
+ kcdb_identity_release(idlist->list[i].ident);
+ idlist->list[i].ident = NULL;
+ }
+ }
+
+ if (idlist->list)
+ PFREE(idlist->list);
+ idlist->list = NULL;
+ idlist->n_list = 0;
+ idlist->nc_list = 0;
+}
+
+#ifndef ENCTYPE_LOCAL_RC4_MD4
+#define ENCTYPE_LOCAL_RC4_MD4 0xFFFFFF80
+#endif
+
+#define MAX_ADDRS 256
+
+static long get_tickets_from_cache(krb5_context ctx,
+ krb5_ccache cache,
+ identlist * idlist)
+{
+ krb5_error_code code;
+ krb5_principal KRBv5Principal;
+ krb5_flags flags = 0;
+ krb5_cc_cursor KRBv5Cursor;
+ krb5_creds KRBv5Credentials;
+ krb5_ticket *tkt=NULL;
+ char *ClientName = NULL;
+ char *PrincipalName = NULL;
+ wchar_t wbuf[256]; /* temporary conversion buffer */
+ wchar_t wcc_name[KRB5_MAXCCH_CCNAME]; /* credential cache name */
+ char *sServerName = NULL;
+ khm_handle ident = NULL;
+ khm_handle cred = NULL;
+ time_t tt;
+ FILETIME ft, eft;
+ khm_int32 ti;
+
+#ifdef KRB5_TC_NOTICKET
+ flags = KRB5_TC_NOTICKET;
+#else
+ flags = 0;
+#endif
+
+ {
+ const char * cc_name;
+ const char * cc_type;
+
+ cc_name = (*pkrb5_cc_get_name)(ctx, cache);
+ if(cc_name) {
+ cc_type = (*pkrb5_cc_get_type)(ctx, cache);
+ if (cc_type) {
+ StringCbPrintf(wcc_name, sizeof(wcc_name), L"%S:%S", cc_type, cc_name);
+ } else {
+ AnsiStrToUnicode(wcc_name, sizeof(wcc_name), cc_name);
+ khm_krb5_canon_cc_name(wcc_name, sizeof(wcc_name));
+ }
+ } else {
+ cc_type = (*pkrb5_cc_get_type)(ctx, cache);
+ if (cc_type) {
+ StringCbPrintf(wcc_name, sizeof(wcc_name), L"%S:", cc_type);
+ } else {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ StringCbCopy(wcc_name, sizeof(wcc_name), L"");
+ }
+ }
+ }
+
+ _reportf(L"Getting tickets from cache [%s]", wcc_name);
+
+ if ((code = (*pkrb5_cc_set_flags)(ctx, cache, flags)))
+ {
+ if (code != KRB5_FCC_NOFILE && code != KRB5_CC_NOTFOUND)
+ khm_krb5_error(code, "krb5_cc_set_flags()", 0, &ctx, &cache);
+
+ goto _exit;
+ }
+
+ if ((code = (*pkrb5_cc_get_principal)(ctx, cache, &KRBv5Principal)))
+ {
+ if (code != KRB5_FCC_NOFILE && code != KRB5_CC_NOTFOUND)
+ khm_krb5_error(code, "krb5_cc_get_principal()", 0, &ctx, &cache);
+
+ goto _exit;
+ }
+
+ PrincipalName = NULL;
+ ClientName = NULL;
+ sServerName = NULL;
+ if ((code = (*pkrb5_unparse_name)(ctx, KRBv5Principal,
+ (char **)&PrincipalName)))
+ {
+ if (PrincipalName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
+
+ (*pkrb5_free_principal)(ctx, KRBv5Principal);
+
+ goto _exit;
+ }
+
+ if (!strcspn(PrincipalName, "@" ))
+ {
+ if (PrincipalName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
+
+ (*pkrb5_free_principal)(ctx, KRBv5Principal);
+
+ goto _exit;
+ }
+
+ AnsiStrToUnicode(wbuf, sizeof(wbuf), PrincipalName);
+ if(KHM_FAILED(kcdb_identity_create(wbuf, KCDB_IDENT_FLAG_CREATE,
+ &ident))) {
+ /* something bad happened */
+ code = 1;
+ goto _exit;
+ }
+
+ _reportf(L"Found principal [%s]", wbuf);
+
+ (*pkrb5_free_principal)(ctx, KRBv5Principal);
+
+ if ((code = (*pkrb5_cc_start_seq_get)(ctx, cache, &KRBv5Cursor)))
+ {
+ goto _exit;
+ }
+
+ memset(&KRBv5Credentials, '\0', sizeof(KRBv5Credentials));
+
+ ClientName = NULL;
+ sServerName = NULL;
+ cred = NULL;
+
+ while (!(code = pkrb5_cc_next_cred(ctx, cache, &KRBv5Cursor,
+ &KRBv5Credentials)))
+ {
+ khm_handle tident = NULL;
+ khm_int32 cred_flags = 0;
+
+ if(ClientName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, ClientName);
+ if(sServerName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, sServerName);
+ if(cred)
+ kcdb_cred_release(cred);
+
+ ClientName = NULL;
+ sServerName = NULL;
+ cred = NULL;
+
+ if ((*pkrb5_unparse_name)(ctx, KRBv5Credentials.client, &ClientName))
+ {
+ (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
+ khm_krb5_error(code, "krb5_free_cred_contents()", 0, &ctx, &cache);
+ continue;
+ }
+
+ if ((*pkrb5_unparse_name)(ctx, KRBv5Credentials.server, &sServerName))
+ {
+ (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
+ khm_krb5_error(code, "krb5_free_cred_contents()", 0, &ctx, &cache);
+ continue;
+ }
+
+ /* if the ClientName differs from PrincipalName for some
+ reason, we need to create a new identity */
+ if(strcmp(ClientName, PrincipalName)) {
+ AnsiStrToUnicode(wbuf, sizeof(wbuf), ClientName);
+ if(KHM_FAILED(kcdb_identity_create(wbuf, KCDB_IDENT_FLAG_CREATE,
+ &tident))) {
+ (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
+ continue;
+ }
+ } else {
+ tident = ident;
+ }
+
+ AnsiStrToUnicode(wbuf, sizeof(wbuf), sServerName);
+ if(KHM_FAILED(kcdb_cred_create(wbuf, tident, credtype_id_krb5,
+ &cred))) {
+ (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
+ continue;
+ }
+
+ if (!KRBv5Credentials.times.starttime)
+ KRBv5Credentials.times.starttime = KRBv5Credentials.times.authtime;
+
+ tt = KRBv5Credentials.times.starttime;
+ TimetToFileTime(tt, &ft);
+ kcdb_cred_set_attr(cred, KCDB_ATTR_ISSUE, &ft, sizeof(ft));
+
+ tt = KRBv5Credentials.times.endtime;
+ TimetToFileTime(tt, &eft);
+ kcdb_cred_set_attr(cred, KCDB_ATTR_EXPIRE, &eft, sizeof(eft));
+
+ {
+ FILETIME ftl;
+
+ ftl = FtSub(&eft, &ft);
+ kcdb_cred_set_attr(cred, KCDB_ATTR_LIFETIME, &ftl, sizeof(ftl));
+ }
+
+ if (KRBv5Credentials.times.renew_till > 0) {
+ FILETIME ftl;
+
+ tt = KRBv5Credentials.times.renew_till;
+ TimetToFileTime(tt, &eft);
+ kcdb_cred_set_attr(cred, KCDB_ATTR_RENEW_EXPIRE, &eft,
+ sizeof(eft));
+
+
+ ftl = FtSub(&eft, &ft);
+ kcdb_cred_set_attr(cred, KCDB_ATTR_RENEW_LIFETIME, &ftl,
+ sizeof(ftl));
+ }
+
+ ti = KRBv5Credentials.ticket_flags;
+ kcdb_cred_set_attr(cred, attr_id_krb5_flags, &ti, sizeof(ti));
+
+ /* special flags understood by NetIDMgr */
+ {
+ khm_int32 nflags = 0;
+
+ if (ti & TKT_FLG_RENEWABLE)
+ nflags |= KCDB_CRED_FLAG_RENEWABLE;
+ if (ti & TKT_FLG_INITIAL)
+ nflags |= KCDB_CRED_FLAG_INITIAL;
+ else {
+ krb5_data * c0, *c1, *r;
+
+ /* these are macros that do not allocate any memory */
+ c0 = krb5_princ_component(ctx,KRBv5Credentials.server,0);
+ c1 = krb5_princ_component(ctx,KRBv5Credentials.server,1);
+ r = krb5_princ_realm(ctx,KRBv5Credentials.server);
+
+ if ( c0 && c1 && r && c1->length == r->length &&
+ !strncmp(c1->data,r->data,r->length) &&
+ !strncmp("krbtgt",c0->data,c0->length) )
+ nflags |= KCDB_CRED_FLAG_INITIAL;
+ }
+
+ kcdb_cred_set_flags(cred, nflags, KCDB_CRED_FLAGMASK_EXT);
+
+ cred_flags = nflags;
+ }
+
+ if ( !pkrb5_decode_ticket(&KRBv5Credentials.ticket, &tkt)) {
+ ti = tkt->enc_part.enctype;
+ kcdb_cred_set_attr(cred, attr_id_tkt_enctype, &ti, sizeof(ti));
+ ti = tkt->enc_part.kvno;
+ kcdb_cred_set_attr(cred, attr_id_kvno, &ti, sizeof(ti));
+ pkrb5_free_ticket(ctx, tkt);
+ tkt = NULL;
+ }
+
+ ti = KRBv5Credentials.keyblock.enctype;
+ kcdb_cred_set_attr(cred, attr_id_key_enctype, &ti, sizeof(ti));
+
+ kcdb_cred_set_attr(cred, KCDB_ATTR_LOCATION, wcc_name,
+ KCDB_CBSIZE_AUTO);
+
+ if ( KRBv5Credentials.addresses && KRBv5Credentials.addresses[0] ) {
+ khm_int32 buffer[1024];
+ void * bufp;
+ khm_size cb;
+ khm_int32 rv;
+
+ bufp = (void *) buffer;
+ cb = sizeof(buffer);
+
+ rv = serialize_krb5_addresses(KRBv5Credentials.addresses,
+ bufp,
+ &cb);
+ if (rv == KHM_ERROR_TOO_LONG) {
+ bufp = PMALLOC(cb);
+ rv = serialize_krb5_addresses(KRBv5Credentials.addresses,
+ bufp,
+ &cb);
+ }
+
+ if (KHM_SUCCEEDED(rv)) {
+ kcdb_cred_set_attr(cred, attr_id_addr_list,
+ bufp, cb);
+ }
+
+ if (bufp != (void *) buffer)
+ PFREE(bufp);
+ }
+
+ if(cred_flags & KCDB_CRED_FLAG_INITIAL) {
+ FILETIME ft_issue_new;
+ FILETIME ft_expire_old;
+ FILETIME ft_expire_new;
+ ident_data * d;
+
+ /* an initial ticket! Add it to the list of identities we
+ have seen so far with initial tickets. */
+ d = tc_add_ident_to_list(idlist, ident);
+#ifdef DEBUG
+ assert(d);
+ assert(d->count > 0);
+#endif
+
+ tt = KRBv5Credentials.times.endtime;
+ TimetToFileTime(tt, &ft_expire_new);
+
+ tt = KRBv5Credentials.times.starttime;
+ TimetToFileTime(tt, &ft_issue_new);
+
+ /* so now, we have to set the properties of the identity
+ based on the properties of this credential under the
+ following circumstances:
+
+ - If this is the first time we are hitting this
+ identity.
+
+ - If this is not the MSLSA: cache and the expiry time
+ for this credential is longer than the time already
+ found for this identity.
+ */
+
+ ft_expire_old = d->ft_expire;
+
+ if(d->count == 1
+ || (CompareFileTime(&ft_expire_new, &ft_expire_old) > 0 &&
+ wcscmp(wcc_name, L"MSLSA:") != 0)) {
+
+ _reportf(L"Setting properties for identity (count=%d)", d->count);
+
+ StringCbCopy(d->ccname, sizeof(d->ccname),
+ wcc_name);
+ d->ft_expire = ft_expire_new;
+ d->ft_issue = ft_issue_new;
+
+ if (KRBv5Credentials.times.renew_till > 0) {
+ tt = KRBv5Credentials.times.renew_till;
+ TimetToFileTime(tt, &ft);
+ d->ft_renewexpire = ft;
+ } else {
+ ZeroMemory(&d->ft_renewexpire, sizeof(d->ft_renewexpire));
+ }
+
+ d->krb5_flags = KRBv5Credentials.ticket_flags;
+ }
+ }
+
+ kcdb_credset_add_cred(krb5_credset, cred, -1);
+
+ (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
+
+ if(tident != ident)
+ kcdb_identity_release(tident);
+ }
+
+ if (PrincipalName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
+
+ if (ClientName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, ClientName);
+
+ if (sServerName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, sServerName);
+
+ if (cred)
+ kcdb_cred_release(cred);
+
+ if ((code == KRB5_CC_END) || (code == KRB5_CC_NOTFOUND))
+ {
+ if ((code = pkrb5_cc_end_seq_get(ctx, cache, &KRBv5Cursor)))
+ {
+ goto _exit;
+ }
+
+ flags = KRB5_TC_OPENCLOSE;
+#ifdef KRB5_TC_NOTICKET
+ flags |= KRB5_TC_NOTICKET;
+#endif
+ if ((code = pkrb5_cc_set_flags(ctx, cache, flags)))
+ {
+ goto _exit;
+ }
+ }
+ else
+ {
+ goto _exit;
+ }
+
+_exit:
+
+ return code;
+}
+
+long
+khm_krb5_list_tickets(krb5_context *krbv5Context)
+{
+ krb5_context ctx = NULL;
+ krb5_ccache cache = NULL;
+ krb5_error_code code = 0;
+ apiCB * cc_ctx = NULL;
+ struct _infoNC ** pNCi = NULL;
+ int i;
+ khm_int32 t;
+ wchar_t * ms = NULL;
+ khm_size cb;
+ identlist idl;
+
+ kcdb_credset_flush(krb5_credset);
+ tc_prep_idlist(&idl);
+
+ if((*krbv5Context == 0) && (code = (*pkrb5_init_context)(krbv5Context))) {
+ goto _exit;
+ }
+
+ ctx = (*krbv5Context);
+
+ if (!pcc_initialize ||
+ !pcc_get_NC_info ||
+ !pcc_free_NC_info ||
+ !pcc_shutdown)
+ goto _skip_cc_iter;
+
+ code = pcc_initialize(&cc_ctx, CC_API_VER_2, NULL, NULL);
+ if (code)
+ goto _exit;
+
+ code = pcc_get_NC_info(cc_ctx, &pNCi);
+ if (code)
+ goto _exit;
+
+ for(i=0; pNCi[i]; i++) {
+ char ccname[KRB5_MAXCCH_CCNAME];
+
+ if (pNCi[i]->vers != CC_CRED_V5)
+ continue;
+
+ if (FAILED(StringCchPrintfA(ccname, sizeof(ccname), "API:%s",
+ pNCi[i]->name)))
+ continue;
+
+ code = (*pkrb5_cc_resolve)(ctx, ccname, &cache);
+
+ if (code)
+ continue;
+
+ code = get_tickets_from_cache(ctx, cache, &idl);
+
+ if(ctx != NULL && cache != NULL)
+ (*pkrb5_cc_close)(ctx, cache);
+
+ cache = 0;
+ }
+
+ _skip_cc_iter:
+
+ if (khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
+ == KHM_ERROR_TOO_LONG &&
+ cb > sizeof(wchar_t) * 2) {
+ wchar_t * t;
+ char ccname[MAX_PATH + 6];
+
+ ms = PMALLOC(cb);
+#ifdef DEBUG
+ assert(ms);
+#endif
+ khc_read_multi_string(csp_params, L"FileCCList", ms, &cb);
+
+ for(t = ms; t && *t; t = multi_string_next(t)) {
+ StringCchPrintfA(ccname, ARRAYLENGTH(ccname),
+ "FILE:%S", t);
+
+ code = (*pkrb5_cc_resolve)(ctx, ccname, &cache);
+
+ if (code)
+ continue;
+
+ code = get_tickets_from_cache(ctx, cache, &idl);
+
+ if (ctx != NULL && cache != NULL)
+ (*pkrb5_cc_close)(ctx, cache);
+ cache = 0;
+ }
+
+ PFREE(ms);
+ }
+
+ if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"MsLsaList", &t)) && t) {
+ code = (*pkrb5_cc_resolve)(ctx, "MSLSA:", &cache);
+
+ if (code == 0 && cache) {
+ code = get_tickets_from_cache(ctx, cache, &idl);
+ }
+
+ if (ctx != NULL && cache != NULL)
+ (*pkrb5_cc_close)(ctx, cache);
+ cache = 0;
+ }
+
+_exit:
+ if (pNCi)
+ (*pcc_free_NC_info)(cc_ctx, &pNCi);
+ if (cc_ctx)
+ (*pcc_shutdown)(&cc_ctx);
+
+ kcdb_credset_collect(NULL, krb5_credset, NULL, credtype_id_krb5, NULL);
+ tc_set_ident_data(&idl);
+ tc_free_idlist(&idl);
+
+ return(code);
+}
+
+int
+khm_krb5_renew_cred(khm_handle cred)
+{
+ khm_handle identity = NULL;
+ krb5_error_code code = 0;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
+ krb5_principal me = NULL, server = NULL;
+ krb5_creds in_creds, cc_creds;
+ krb5_creds * out_creds = NULL;
+
+ wchar_t wname[512];
+ khm_size cbname;
+ char name[512];
+ khm_boolean brenewIdentity = FALSE;
+ khm_boolean istgt = FALSE;
+
+ khm_int32 flags;
+
+ cbname = sizeof(wname);
+ kcdb_cred_get_name(cred, wname, &cbname);
+ _reportf(L"Krb5 renew cred for %s", wname);
+
+ kcdb_cred_get_flags(cred, &flags);
+
+ if (!(flags & KCDB_CRED_FLAG_INITIAL)) {
+ _reportf(L"Krb5 skipping renewal because this is not an initial credential");
+ return 0;
+ }
+
+ memset(&in_creds, 0, sizeof(in_creds));
+ memset(&cc_creds, 0, sizeof(cc_creds));
+
+ if (cred == NULL) {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ goto cleanup;
+ }
+
+ if (KHM_FAILED(kcdb_cred_get_identity(cred, &identity))) {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ goto cleanup;
+ }
+
+ code = khm_krb5_initialize(identity, &ctx, &cc);
+ if (code)
+ goto cleanup;
+
+ code = pkrb5_cc_get_principal(ctx, cc, &me);
+ if (code)
+ goto cleanup;
+
+ cbname = sizeof(wname);
+ if (KHM_FAILED(kcdb_cred_get_name(cred, wname, &cbname)))
+ goto cleanup;
+
+ UnicodeStrToAnsi(name, sizeof(name), wname);
+
+ code = pkrb5_parse_name(ctx, name, &server);
+ if (code)
+ goto cleanup;
+
+ in_creds.client = me;
+ in_creds.server = server;
+
+#ifdef KRB5_TC_NOTICKET
+ pkrb5_cc_set_flags(ctx, cc, 0);
+#endif
+
+ if (strlen("krbtgt") != krb5_princ_name(ctx, server)->length ||
+ strncmp("krbtgt", krb5_princ_name(ctx, server)->data, krb5_princ_name(ctx, server)->length))
+ {
+ code = pkrb5_get_renewed_creds(ctx, &cc_creds, me, cc, name);
+ if (code) {
+ code = pkrb5_cc_retrieve_cred(ctx, cc, 0, &in_creds, &cc_creds);
+ if (code == 0) {
+ code = pkrb5_cc_remove_cred(ctx, cc, 0, &cc_creds);
+ if (code) {
+ brenewIdentity = TRUE;
+ goto cleanup;
+ }
+ }
+ }
+
+ code = pkrb5_get_credentials(ctx, 0, cc, &in_creds, &out_creds);
+ } else {
+ istgt = TRUE;
+ code = pkrb5_get_renewed_creds(ctx, &cc_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)
+ khm_krb5_error(code, "krb5_get_renewed_creds()", 0, &ctx, &cc);
+ goto cleanup;
+ }
+
+ if (istgt) {
+ code = pkrb5_cc_initialize(ctx, cc, me);
+ if (code) goto cleanup;
+
+ }
+
+ code = pkrb5_cc_store_cred(ctx, cc, istgt ? &cc_creds : out_creds);
+ if (code) goto cleanup;
+
+
+ cleanup:
+
+ if (in_creds.client == me)
+ in_creds.client = NULL;
+ if (in_creds.server == server)
+ in_creds.server = NULL;
+
+ if (me)
+ pkrb5_free_principal(ctx, me);
+
+ if (server)
+ pkrb5_free_principal(ctx, server);
+
+ pkrb5_free_cred_contents(ctx, &in_creds);
+ pkrb5_free_cred_contents(ctx, &cc_creds);
+
+ if (out_creds)
+ pkrb5_free_creds(ctx, out_creds);
+
+ if (cc && ctx)
+ pkrb5_cc_close(ctx, cc);
+
+ if (ctx)
+ pkrb5_free_context(ctx);
+
+ if (identity) {
+ if (brenewIdentity)
+ code = khm_krb5_renew_ident(identity);
+ kcdb_identity_release(identity);
+ }
+
+ return code;
+}
+
+int
+khm_krb5_renew_ident(khm_handle identity)
+{
+ krb5_error_code code = 0;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
+ krb5_principal me = NULL;
+ krb5_principal server = NULL;
+ krb5_creds my_creds;
+ krb5_data *realm = NULL;
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb;
+ khm_int32 k5_flags;
+
+ memset(&my_creds, 0, sizeof(krb5_creds));
+
+ if ( !pkrb5_init_context )
+ goto cleanup;
+
+ cb = sizeof(idname);
+ kcdb_identity_get_name(identity, idname, &cb);
+
+ if (khm_krb5_get_identity_flags(identity) & K5IDFLAG_IMPORTED) {
+#ifndef NO_REIMPORT_MSLSA_CREDS
+ /* we are trying to renew the identity that was imported from
+ MSLSA: */
+ BOOL imported;
+ BOOL retry_import = FALSE;
+ char cidname[KCDB_IDENT_MAXCCH_NAME];
+ khm_handle imported_id = NULL;
+ khm_size cb;
+ FILETIME ft_expire;
+ FILETIME ft_now;
+ FILETIME ft_threshold;
+ krb5_principal princ = NULL;
+
+ UnicodeStrToAnsi(cidname, sizeof(cidname), idname);
+
+ imported = khm_krb5_ms2mit(cidname, FALSE, TRUE, &imported_id);
+
+ if (imported == 0)
+ goto import_failed;
+
+ /* if the imported identity has already expired or will soon,
+ we clear the cache and try again. */
+ khm_krb5_list_tickets(&ctx);
+
+ cb = sizeof(ft_expire);
+ if (KHM_FAILED(kcdb_identity_get_attr(imported_id, KCDB_ATTR_EXPIRE,
+ NULL, &ft_expire, &cb)))
+ goto import_failed;
+
+ GetSystemTimeAsFileTime(&ft_now);
+ TimetToFileTimeInterval(5 * 60, &ft_threshold);
+
+ ft_now = FtAdd(&ft_now, &ft_threshold);
+
+ if (CompareFileTime(&ft_expire, &ft_now) < 0) {
+ /* the ticket lifetime is not long enough */
+
+ code = 0;
+
+ if (ctx == NULL)
+ code = pkrb5_init_context(&ctx);
+ if (code)
+ goto import_failed;
+
+ code = pkrb5_cc_resolve(ctx, "MSLSA:", &cc);
+ if (code)
+ goto import_failed;
+
+ code = pkrb5_cc_get_principal(ctx, cc, &princ);
+ if (code)
+ goto import_failed;
+
+ pkrb5_cc_initialize(ctx, cc, princ);
+
+ retry_import = TRUE;
+ }
+
+ import_failed:
+
+ if (imported_id) {
+ kcdb_identity_release(imported_id);
+ imported_id = NULL;
+ }
+
+ if (ctx) {
+ if (cc) {
+ pkrb5_cc_close(ctx, cc);
+ cc = NULL;
+ }
+
+ if (princ) {
+ pkrb5_free_principal(ctx, princ);
+ princ = NULL;
+ }
+
+ /* leave ctx so we can use it later */
+ }
+
+ if (retry_import)
+ imported = khm_krb5_ms2mit(cidname, FALSE, TRUE, NULL);
+
+ if (imported)
+ goto cleanup;
+
+ /* if the import failed, then we try to renew the identity via
+ the usual procedure. */
+
+#else
+ /* if we are suppressing further imports from MSLSA, we just
+ skip renewing this identity. */
+ goto cleanup;
+#endif
+ }
+
+ cb = sizeof(k5_flags);
+ if (KHM_SUCCEEDED(kcdb_identity_get_attr(identity,
+ attr_id_krb5_flags,
+ NULL,
+ &k5_flags,
+ &cb)) &&
+ !(k5_flags & TKT_FLG_RENEWABLE)) {
+
+ code = KRB5KDC_ERR_BADOPTION;
+ goto cleanup;
+ }
+
+ {
+ FILETIME ft_now;
+ FILETIME ft_exp;
+
+ cb = sizeof(ft_exp);
+ GetSystemTimeAsFileTime(&ft_now);
+ if (KHM_SUCCEEDED(kcdb_identity_get_attr(identity,
+ KCDB_ATTR_EXPIRE,
+ NULL,
+ &ft_exp,
+ &cb)) &&
+ CompareFileTime(&ft_exp, &ft_now) < 0) {
+
+ code = KRB5KRB_AP_ERR_TKT_EXPIRED;
+ goto cleanup;
+
+ }
+ }
+
+ code = khm_krb5_initialize(identity, &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)
+ khm_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 = NULL;
+ if (my_creds.server == server)
+ my_creds.server = NULL;
+
+ if (ctx) {
+ 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);
+ pkrb5_free_context(ctx);
+ }
+
+ return(code);
+}
+
+int
+khm_krb5_kinit(krb5_context alt_ctx,
+ char * principal_name,
+ char * password,
+ char * ccache,
+ krb5_deltat lifetime,
+ DWORD forwardable,
+ DWORD proxiable,
+ krb5_deltat renew_life,
+ DWORD addressless,
+ DWORD publicIP,
+ krb5_prompter_fct prompter,
+ void * p_data)
+{
+ krb5_error_code code = 0;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
+ krb5_principal me = NULL;
+ char* name = NULL;
+ krb5_creds my_creds;
+ krb5_get_init_creds_opt options;
+ krb5_address ** addrs = NULL;
+ int i = 0, addr_count = 0;
+
+ if (!pkrb5_init_context)
+ return 0;
+
+ _reportf(L"In khm_krb5_kinit");
+
+ pkrb5_get_init_creds_opt_init(&options);
+ pkrb5_get_init_creds_opt_set_change_password_prompt(&options, 0);
+
+ memset(&my_creds, 0, sizeof(my_creds));
+
+ if (alt_ctx) {
+ ctx = alt_ctx;
+ } else {
+ code = pkrb5_init_context(&ctx);
+ if (code)
+ goto cleanup;
+ }
+
+ if (ccache) {
+ _reportf(L"Using supplied ccache name %S", ccache);
+ code = pkrb5_cc_resolve(ctx, ccache, &cc);
+ } else {
+ khm_handle identity = NULL;
+ khm_handle csp_ident = NULL;
+ khm_handle csp_k5 = NULL;
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t wccname[MAX_PATH];
+ char ccname[MAX_PATH];
+ char * pccname = principal_name;
+ khm_size cb;
+
+ idname[0] = L'\0';
+ AnsiStrToUnicode(idname, sizeof(idname), principal_name);
+
+ cb = sizeof(wccname);
+
+ if (KHM_SUCCEEDED(kcdb_identity_create(idname, 0, &identity)) &&
+
+ KHM_SUCCEEDED(kcdb_identity_get_config(identity, 0, &csp_ident)) &&
+
+ KHM_SUCCEEDED(khc_open_space(csp_ident, CSNAME_KRB5CRED, 0,
+ &csp_k5)) &&
+
+ KHM_SUCCEEDED(khc_read_string(csp_k5, L"DefaultCCName",
+ wccname, &cb)) &&
+
+ cb > sizeof(wchar_t)) {
+
+ _reportf(L"Using DefaultCCName [%s] from identity", wccname);
+
+ UnicodeStrToAnsi(ccname, sizeof(ccname), wccname);
+ pccname = ccname;
+ }
+
+ if (csp_k5)
+ khc_close_space(csp_k5);
+ if (csp_ident)
+ khc_close_space(csp_ident);
+ if (identity)
+ kcdb_identity_release(identity);
+
+ code = pkrb5_cc_resolve(ctx, pccname, &cc);
+ }
+
+ _reportf(L"krb5_cc_resolve returns code %d", code);
+
+ if (code) goto cleanup;
+
+ code = pkrb5_parse_name(ctx, principal_name, &me);
+ if (code) goto cleanup;
+
+ code = pkrb5_unparse_name(ctx, me, &name);
+ if (code) goto cleanup;
+
+ if (lifetime == 0) {
+ khc_read_int32(csp_params, L"DefaultLifetime", &lifetime);
+ }
+
+ 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 {
+ krb5_address ** local_addrs=NULL;
+ DWORD netIPAddr;
+
+ pkrb5_os_localaddr(ctx, &local_addrs);
+ i = 0;
+ while ( local_addrs[i++] );
+ addr_count = i + 1;
+
+ addrs = (krb5_address **) PMALLOC((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 *)PMALLOC(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 *)PMALLOC(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);
+
+ if (publicIP) {
+ // we are going to add the public IP address specified by the user
+ // to the list provided by the operating system
+ addrs[i] = (krb5_address *)PMALLOC(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 *)PMALLOC(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_password(ctx,
+ &my_creds,
+ me,
+ password, // password
+ prompter, // prompter
+ p_data, // prompter data
+ 0, // start time
+ 0, // service name
+ &options);
+ _reportf(L"krb5_get_init_creds_password returns code %d", code);
+
+ if (code) goto cleanup;
+
+ code = pkrb5_cc_initialize(ctx, cc, me);
+ _reportf(L"krb5_cc_initialize returns code %d", code);
+ if (code) goto cleanup;
+
+ code = pkrb5_cc_store_cred(ctx, cc, &my_creds);
+ _reportf(L"krb5_cc_store_cred returns code %d", code);
+ if (code) goto cleanup;
+
+cleanup:
+ if ( addrs ) {
+ for ( i=0;i<addr_count;i++ ) {
+ if ( addrs[i] ) {
+ if ( addrs[i]->contents )
+ PFREE(addrs[i]->contents);
+ PFREE(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 (ctx && (ctx != alt_ctx))
+ pkrb5_free_context(ctx);
+ return(code);
+}
+
+long
+khm_krb5_copy_ccache_by_name(krb5_context in_ctx,
+ wchar_t * wscc_dest,
+ wchar_t * wscc_src) {
+ krb5_context ctx = NULL;
+ krb5_error_code code = 0;
+ khm_boolean free_ctx;
+ krb5_ccache cc_src = NULL;
+ krb5_ccache cc_dest = NULL;
+ krb5_principal princ_src = NULL;
+ char scc_dest[KRB5_MAXCCH_CCNAME];
+ char scc_src[KRB5_MAXCCH_CCNAME];
+ int t;
+
+ t = UnicodeStrToAnsi(scc_dest, sizeof(scc_dest), wscc_dest);
+ if (t == 0)
+ return KHM_ERROR_TOO_LONG;
+ t = UnicodeStrToAnsi(scc_src, sizeof(scc_src), wscc_src);
+ if (t == 0)
+ return KHM_ERROR_TOO_LONG;
+
+ if (in_ctx) {
+ ctx = in_ctx;
+ free_ctx = FALSE;
+ } else {
+ code = pkrb5_init_context(&ctx);
+ if (code) {
+ if (ctx)
+ pkrb5_free_context(ctx);
+ return code;
+ }
+ free_ctx = TRUE;
+ }
+
+ code = pkrb5_cc_resolve(ctx, scc_dest, &cc_dest);
+ if (code)
+ goto _cleanup;
+
+ code = pkrb5_cc_resolve(ctx, scc_src, &cc_src);
+ if (code)
+ goto _cleanup;
+
+ code = pkrb5_cc_get_principal(ctx, cc_src, &princ_src);
+ if (code)
+ goto _cleanup;
+
+ code = pkrb5_cc_initialize(ctx, cc_dest, princ_src);
+ if (code)
+ goto _cleanup;
+
+ code = pkrb5_cc_copy_creds(ctx, cc_src, cc_dest);
+
+ _cleanup:
+ if (princ_src)
+ pkrb5_free_principal(ctx, princ_src);
+
+ if (cc_dest)
+ pkrb5_cc_close(ctx, cc_dest);
+
+ if (cc_src)
+ pkrb5_cc_close(ctx, cc_src);
+
+ if (free_ctx && ctx)
+ pkrb5_free_context(ctx);
+
+ return code;
+}
+
+long
+khm_krb5_canon_cc_name(wchar_t * wcc_name,
+ size_t cb_cc_name) {
+ size_t cb_len;
+ wchar_t * colon;
+
+ if (FAILED(StringCbLength(wcc_name,
+ cb_cc_name,
+ &cb_len))) {
+#ifdef DEBUG
+ assert(FALSE);
+#else
+ return KHM_ERROR_TOO_LONG;
+#endif
+ }
+
+ cb_len += sizeof(wchar_t);
+
+ colon = wcschr(wcc_name, L':');
+
+ if (colon) {
+ /* if the colon is just 1 character away from the beginning,
+ it's a FILE: cc */
+ if (colon - wcc_name == 1) {
+ if (cb_len + 5 * sizeof(wchar_t) > cb_cc_name)
+ return KHM_ERROR_TOO_LONG;
+
+ memmove(&wcc_name[5], &wcc_name[0], cb_len);
+ memmove(&wcc_name[0], L"FILE:", sizeof(wchar_t) * 5);
+ }
+
+ return 0;
+ }
+
+ if (cb_len + 4 * sizeof(wchar_t) > cb_cc_name)
+ return KHM_ERROR_TOO_LONG;
+
+ memmove(&wcc_name[4], &wcc_name[0], cb_len);
+ memmove(&wcc_name[0], L"API:", sizeof(wchar_t) * 4);
+
+ return 0;
+}
+
+int
+khm_krb5_cc_name_cmp(const wchar_t * cc_name_1,
+ const wchar_t * cc_name_2) {
+ if (!wcsncmp(cc_name_1, L"API:", 4))
+ cc_name_1 += 4;
+
+ if (!wcsncmp(cc_name_2, L"API:", 4))
+ cc_name_2 += 4;
+
+ return wcscmp(cc_name_1, cc_name_2);
+}
+
+static khm_int32 KHMAPI
+khmint_location_comp_func(khm_handle cred1,
+ khm_handle cred2,
+ void * rock) {
+ return kcdb_creds_comp_attr(cred1, cred2, KCDB_ATTR_LOCATION);
+}
+
+struct khmint_location_check {
+ khm_handle credset;
+ khm_handle cred;
+ wchar_t * ccname;
+ khm_boolean success;
+};
+
+static khm_int32 KHMAPI
+khmint_find_matching_cred_func(khm_handle cred,
+ void * rock) {
+ struct khmint_location_check * lc;
+
+ lc = (struct khmint_location_check *) rock;
+
+ if (!kcdb_creds_is_equal(cred, lc->cred))
+ return KHM_ERROR_SUCCESS;
+ if (kcdb_creds_comp_attr(cred, lc->cred, KCDB_ATTR_LOCATION))
+ return KHM_ERROR_SUCCESS;
+
+ /* found it */
+ lc->success = TRUE;
+
+ /* break the search */
+ return !KHM_ERROR_SUCCESS;
+}
+
+static khm_int32 KHMAPI
+khmint_location_check_func(khm_handle cred,
+ void * rock) {
+ khm_int32 t;
+ khm_size cb;
+ wchar_t ccname[KRB5_MAXCCH_CCNAME];
+ struct khmint_location_check * lc;
+
+ lc = (struct khmint_location_check *) rock;
+
+ if (KHM_FAILED(kcdb_cred_get_type(cred, &t)))
+ return KHM_ERROR_SUCCESS;
+
+ if (t != credtype_id_krb5)
+ return KHM_ERROR_SUCCESS;
+
+ cb = sizeof(ccname);
+ if (KHM_FAILED(kcdb_cred_get_attr(cred,
+ KCDB_ATTR_LOCATION,
+ NULL,
+ ccname,
+ &cb)))
+ return KHM_ERROR_SUCCESS;
+
+ if(wcscmp(ccname, lc->ccname))
+ return KHM_ERROR_SUCCESS;
+
+ lc->cred = cred;
+
+ lc->success = FALSE;
+
+ kcdb_credset_apply(lc->credset,
+ khmint_find_matching_cred_func,
+ (void *) lc);
+
+ if (!lc->success)
+ return KHM_ERROR_NOT_FOUND;
+ else
+ return KHM_ERROR_SUCCESS;
+}
+
+static khm_int32 KHMAPI
+khmint_delete_location_func(khm_handle cred,
+ void * rock) {
+ wchar_t cc_cred[KRB5_MAXCCH_CCNAME];
+ struct khmint_location_check * lc;
+ khm_size cb;
+
+ lc = (struct khmint_location_check *) rock;
+
+ cb = sizeof(cc_cred);
+
+ if (KHM_FAILED(kcdb_cred_get_attr(cred,
+ KCDB_ATTR_LOCATION,
+ NULL,
+ cc_cred,
+ &cb)))
+ return KHM_ERROR_SUCCESS;
+
+ if (wcscmp(cc_cred, lc->ccname))
+ return KHM_ERROR_SUCCESS;
+
+ kcdb_credset_del_cred_ref(lc->credset,
+ cred);
+
+ return KHM_ERROR_SUCCESS;
+}
+
+int
+khm_krb5_destroy_by_credset(khm_handle p_cs)
+{
+ khm_handle d_cs = NULL;
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+ khm_size s, cb;
+ krb5_context ctx = NULL;
+ krb5_error_code code = 0;
+ int i;
+ wchar_t ccname[KRB5_MAXCCH_CCNAME];
+ struct khmint_location_check lc;
+
+ rv = kcdb_credset_create(&d_cs);
+
+ assert(KHM_SUCCEEDED(rv) && d_cs != NULL);
+
+ kcdb_credset_extract(d_cs, p_cs, NULL, credtype_id_krb5);
+
+ kcdb_credset_get_size(d_cs, &s);
+
+ if (s == 0) {
+ _reportf(L"No tickets to delete");
+
+ kcdb_credset_delete(d_cs);
+ return 0;
+ }
+
+ code = pkrb5_init_context(&ctx);
+ if (code != 0) {
+ rv = code;
+ goto _cleanup;
+ }
+
+ /* we should synchronize the credential lists before we attempt to
+ make any assumptions on the state of the root credset */
+ khm_krb5_list_tickets(&ctx);
+
+ /* so, we need to make a decision about whether to destroy entire
+ ccaches or just individual credentials. Therefore we first
+ sort them by ccache. */
+ kcdb_credset_sort(d_cs,
+ khmint_location_comp_func,
+ NULL);
+
+ /* now, for each ccache we encounter, we check if we have all the
+ credentials from that ccache in the to-be-deleted list. */
+ for (i=0; i < (int) s; i++) {
+ khm_handle cred;
+
+ if (KHM_FAILED(kcdb_credset_get_cred(d_cs,
+ i,
+ &cred)))
+ continue;
+
+ cb = sizeof(ccname);
+ rv = kcdb_cred_get_attr(cred,
+ KCDB_ATTR_LOCATION,
+ NULL,
+ ccname,
+ &cb);
+
+#ifdef DEBUG
+ assert(KHM_SUCCEEDED(rv));
+#endif
+ kcdb_cred_release(cred);
+
+ lc.credset = d_cs;
+ lc.cred = NULL;
+ lc.ccname = ccname;
+ lc.success = FALSE;
+
+ kcdb_credset_apply(NULL,
+ khmint_location_check_func,
+ (void *) &lc);
+
+ if (lc.success) {
+ /* ok the destroy the ccache */
+ char a_ccname[KRB5_MAXCCH_CCNAME];
+ krb5_ccache cc = NULL;
+
+ _reportf(L"Destroying ccache [%s]", ccname);
+
+ UnicodeStrToAnsi(a_ccname,
+ sizeof(a_ccname),
+ ccname);
+
+ code = pkrb5_cc_resolve(ctx,
+ a_ccname,
+ &cc);
+ if (code)
+ goto _delete_this_set;
+
+ code = pkrb5_cc_destroy(ctx, cc);
+
+ if (code) {
+ _reportf(L"krb5_cc_destroy returns code %d", code);
+ }
+
+ _delete_this_set:
+
+ lc.credset = d_cs;
+ lc.ccname = ccname;
+
+ /* note that although we are deleting credentials off the
+ credential set, the size of the credential set does not
+ decrease since we are doing it from inside
+ kcdb_credset_apply(). The deleted creds will simply be
+ marked as deleted until kcdb_credset_purge() is
+ called. */
+
+ kcdb_credset_apply(d_cs,
+ khmint_delete_location_func,
+ (void *) &lc);
+ }
+ }
+
+ kcdb_credset_purge(d_cs);
+
+ /* the remainder need to be deleted one by one */
+
+ kcdb_credset_get_size(d_cs, &s);
+
+ for (i=0; i < (int) s; ) {
+ khm_handle cred;
+ char a_ccname[KRB5_MAXCCH_CCNAME];
+ char a_srvname[KCDB_CRED_MAXCCH_NAME];
+ wchar_t srvname[KCDB_CRED_MAXCCH_NAME];
+ krb5_ccache cc;
+ krb5_creds in_cred, out_cred;
+ krb5_principal princ;
+ khm_int32 etype;
+
+ if (KHM_FAILED(kcdb_credset_get_cred(d_cs,
+ i,
+ &cred))) {
+ i++;
+ continue;
+ }
+
+ cb = sizeof(ccname);
+ if (KHM_FAILED(kcdb_cred_get_attr(cred,
+ KCDB_ATTR_LOCATION,
+ NULL,
+ ccname,
+ &cb)))
+ goto _done_with_this_cred;
+
+ _reportf(L"Looking at ccache [%s]", ccname);
+
+ UnicodeStrToAnsi(a_ccname,
+ sizeof(a_ccname),
+ ccname);
+
+ code = pkrb5_cc_resolve(ctx,
+ a_ccname,
+ &cc);
+
+ if (code)
+ goto _skip_similar;
+
+ code = pkrb5_cc_get_principal(ctx, cc, &princ);
+
+ if (code) {
+ pkrb5_cc_close(ctx, cc);
+ goto _skip_similar;
+ }
+
+ _del_this_cred:
+
+ cb = sizeof(etype);
+
+ if (KHM_FAILED(kcdb_cred_get_attr(cred,
+ attr_id_key_enctype,
+ NULL,
+ &etype,
+ &cb)))
+ goto _do_next_cred;
+
+ cb = sizeof(srvname);
+ if (KHM_FAILED(kcdb_cred_get_name(cred,
+ srvname,
+ &cb)))
+ goto _do_next_cred;
+
+ _reportf(L"Attempting to delete ticket %s", srvname);
+
+ UnicodeStrToAnsi(a_srvname, sizeof(a_srvname), srvname);
+
+ ZeroMemory(&in_cred, sizeof(in_cred));
+
+ code = pkrb5_parse_name(ctx, a_srvname, &in_cred.server);
+ if (code)
+ goto _do_next_cred;
+ in_cred.client = princ;
+ in_cred.keyblock.enctype = etype;
+
+ code = pkrb5_cc_retrieve_cred(ctx,
+ cc,
+ KRB5_TC_MATCH_SRV_NAMEONLY |
+ KRB5_TC_SUPPORTED_KTYPES,
+ &in_cred,
+ &out_cred);
+ if (code)
+ goto _do_next_cred_0;
+
+ code = pkrb5_cc_remove_cred(ctx, cc,
+ KRB5_TC_MATCH_SRV_NAMEONLY |
+ KRB5_TC_SUPPORTED_KTYPES |
+ KRB5_TC_MATCH_AUTHDATA,
+ &out_cred);
+
+ pkrb5_free_cred_contents(ctx, &out_cred);
+ _do_next_cred_0:
+ pkrb5_free_principal(ctx, in_cred.server);
+ _do_next_cred:
+
+ /* check if the next cred is also of the same ccache */
+ kcdb_cred_release(cred);
+
+ for (i++; i < (int) s; i++) {
+ if (KHM_FAILED(kcdb_credset_get_cred(d_cs,
+ i,
+ &cred)))
+ continue;
+ }
+
+ if (i < (int) s) {
+ wchar_t newcc[KRB5_MAXCCH_CCNAME];
+
+ cb = sizeof(newcc);
+ if (KHM_FAILED(kcdb_cred_get_attr(cred,
+ KCDB_ATTR_LOCATION,
+ NULL,
+ newcc,
+ &cb)) ||
+ wcscmp(newcc, ccname)) {
+ i--; /* we have to look at this again */
+ goto _done_with_this_set;
+ }
+ goto _del_this_cred;
+ }
+
+
+ _done_with_this_set:
+ pkrb5_free_principal(ctx, princ);
+
+ pkrb5_cc_close(ctx, cc);
+
+ _done_with_this_cred:
+ kcdb_cred_release(cred);
+ i++;
+ continue;
+
+ _skip_similar:
+ kcdb_cred_release(cred);
+
+ for (++i; i < (int) s; i++) {
+ wchar_t newcc[KRB5_MAXCCH_CCNAME];
+
+ if (KHM_FAILED(kcdb_credset_get_cred(d_cs,
+ i,
+ &cred)))
+ continue;
+
+ cb = sizeof(newcc);
+ if (KHM_FAILED(kcdb_cred_get_attr(cred,
+ KCDB_ATTR_LOCATION,
+ NULL,
+ &newcc,
+ &cb))) {
+ kcdb_cred_release(cred);
+ continue;
+ }
+
+ if (wcscmp(newcc, ccname)) {
+ kcdb_cred_release(cred);
+ break;
+ }
+ }
+ }
+
+ _cleanup:
+
+ if (d_cs)
+ kcdb_credset_delete(&d_cs);
+
+ if (ctx != NULL)
+ pkrb5_free_context(ctx);
+
+ return rv;
+}
+
+int
+khm_krb5_destroy_identity(khm_handle identity)
+{
+ krb5_context ctx;
+ krb5_ccache cache;
+ krb5_error_code rc;
+
+ ctx = NULL;
+ cache = NULL;
+
+ if (rc = khm_krb5_initialize(identity, &ctx, &cache))
+ return(rc);
+
+ rc = pkrb5_cc_destroy(ctx, cache);
+
+ if (ctx != NULL)
+ pkrb5_free_context(ctx);
+
+ return(rc);
+}
+
+static BOOL
+GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData)
+{
+ NTSTATUS Status = 0;
+ HANDLE TokenHandle;
+ TOKEN_STATISTICS Stats;
+ DWORD ReqLen;
+ BOOL Success;
+
+ if (!ppSessionData)
+ return FALSE;
+ *ppSessionData = NULL;
+
+ Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
+ if ( !Success )
+ return FALSE;
+
+ Success = GetTokenInformation( TokenHandle, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen );
+ CloseHandle( TokenHandle );
+ if ( !Success )
+ return FALSE;
+
+ Status = pLsaGetLogonSessionData( &Stats.AuthenticationId, ppSessionData );
+ if ( FAILED(Status) || !ppSessionData )
+ return FALSE;
+
+ return TRUE;
+}
+
+// IsKerberosLogon() does not validate whether or not there are valid
+// tickets in the cache. It validates whether or not it is reasonable
+// to assume that if we attempted to retrieve valid tickets we could
+// do so. Microsoft does not automatically renew expired tickets.
+// Therefore, the cache could contain expired or invalid tickets.
+// Microsoft also caches the user's password and will use it to
+// retrieve new TGTs if the cache is empty and tickets are requested.
+
+static BOOL
+IsKerberosLogon(VOID)
+{
+ PSECURITY_LOGON_SESSION_DATA pSessionData = NULL;
+ BOOL Success = FALSE;
+
+ if ( GetSecurityLogonSessionData(&pSessionData) ) {
+ if ( pSessionData->AuthenticationPackage.Buffer ) {
+ WCHAR buffer[256];
+ WCHAR *usBuffer;
+ int usLength;
+
+ Success = FALSE;
+ usBuffer = (pSessionData->AuthenticationPackage).Buffer;
+ usLength = (pSessionData->AuthenticationPackage).Length;
+ if (usLength < 256)
+ {
+ lstrcpynW (buffer, usBuffer, usLength);
+ StringCbCatW (buffer, sizeof(buffer), L"");
+ if ( !lstrcmpW(L"Kerberos",buffer) )
+ Success = TRUE;
+ }
+ }
+ pLsaFreeReturnBuffer(pSessionData);
+ }
+ return Success;
+}
+
+
+BOOL
+khm_krb5_ms2mit(char * match_princ, BOOL match_realm, BOOL save_creds,
+ khm_handle * ret_ident)
+{
+#ifdef NO_KRB5
+ return(FALSE);
+#else /* NO_KRB5 */
+ krb5_context kcontext = 0;
+ krb5_error_code code = 0;
+ krb5_ccache ccache=0;
+ krb5_ccache mslsa_ccache=0;
+ krb5_creds creds;
+ krb5_cc_cursor cursor=0;
+ krb5_principal princ = 0;
+ khm_handle ident = NULL;
+ wchar_t wname[KCDB_IDENT_MAXCCH_NAME];
+ char cname[KCDB_IDENT_MAXCCH_NAME];
+ char *cache_name = NULL;
+ char *princ_name = NULL;
+ BOOL rc = FALSE;
+
+ kherr_reportf(L"Begin : khm_krb5_ms2mit. save_cred=%d\n", (int) save_creds);
+
+ if ( !pkrb5_init_context )
+ goto cleanup;
+
+ if (code = pkrb5_init_context(&kcontext))
+ goto cleanup;
+
+ kherr_reportf(L"Resolving MSLSA\n");
+
+ if (code = pkrb5_cc_resolve(kcontext, "MSLSA:", &mslsa_ccache))
+ goto cleanup;
+
+ if ( save_creds ) {
+ kherr_reportf(L"Getting principal\n");
+ if (code = pkrb5_cc_get_principal(kcontext, mslsa_ccache, &princ))
+ goto cleanup;
+
+ kherr_reportf(L"Unparsing name\n");
+ if (code = pkrb5_unparse_name(kcontext, princ, &princ_name))
+ goto cleanup;
+
+ AnsiStrToUnicode(wname, sizeof(wname), princ_name);
+
+ kherr_reportf(L"Unparsed name [%s]", wname);
+
+ /* see if we have to match a specific principal */
+ if (match_princ != NULL) {
+ if (strcmp(princ_name, match_princ)) {
+ kherr_reportf(L"Principal mismatch. Wanted [%S], found [%S]",
+ match_princ, princ_name);
+ goto cleanup;
+ }
+ } else if (match_realm) {
+ wchar_t * wdefrealm;
+ char defrealm[256];
+ krb5_data * princ_realm;
+
+ wdefrealm = khm_krb5_get_default_realm();
+ if (wdefrealm == NULL) {
+ kherr_reportf(L"Can't determine default realm");
+ goto cleanup;
+ }
+
+ princ_realm = krb5_princ_realm(kcontext, princ);
+ UnicodeStrToAnsi(defrealm, sizeof(defrealm), wdefrealm);
+
+ if (strncmp(defrealm, princ_realm->data, princ_realm->length)) {
+ kherr_reportf(L"Realm mismatch. Wanted [%S], found [%*S]",
+ defrealm, princ_realm->length, princ_realm->data);
+ PFREE(wdefrealm);
+ goto cleanup;
+ }
+
+ PFREE(wdefrealm);
+ }
+
+ if (KHM_SUCCEEDED(kcdb_identity_create(wname,
+ KCDB_IDENT_FLAG_CREATE,
+ &ident))) {
+ khm_handle idconfig = NULL;
+ khm_handle k5config = NULL;
+ khm_size cb;
+
+ wname[0] = L'\0';
+
+ kcdb_identity_get_config(ident, KHM_FLAG_CREATE, &idconfig);
+ if (idconfig == NULL)
+ goto _done_checking_config;
+
+ khc_open_space(idconfig, CSNAME_KRB5CRED, KHM_FLAG_CREATE, &k5config);
+ if (k5config == NULL)
+ goto _done_checking_config;
+
+ cb = sizeof(wname);
+ khc_read_string(k5config,
+ L"DefaultCCName",
+ wname, &cb);
+
+ _done_checking_config:
+
+ if (idconfig)
+ khc_close_space(idconfig);
+ if (k5config)
+ khc_close_space(k5config);
+
+ if (wname[0]) {
+ UnicodeStrToAnsi(cname, sizeof(cname), wname);
+ } else {
+ StringCbPrintfA(cname, sizeof(cname), "API:%s", princ_name);
+ }
+
+ cache_name = cname;
+
+ } else {
+ /* the identity could not be created. we just use the
+ name of the principal as the ccache name. */
+ StringCbPrintfA(cname, sizeof(cname), "API:%s", princ_name);
+ cache_name = cname;
+ }
+
+ kherr_reportf(L"Resolving target cache [%S]\n", cache_name);
+
+ if (code = pkrb5_cc_resolve(kcontext, cache_name, &ccache)) {
+ kherr_reportf(L"Cannot resolve cache [%S] with code=%d. Trying default.\n", cache_name, code);
+
+ if (code = pkrb5_cc_default(kcontext, &ccache)) {
+ kherr_reportf(L"Failed to resolve default ccache. Code=%d", code);
+ goto cleanup;
+ }
+ }
+
+ kherr_reportf(L"Initializing ccache\n");
+ if (code = pkrb5_cc_initialize(kcontext, ccache, princ))
+ goto cleanup;
+
+ kherr_reportf(L"Copying credentials\n");
+ if (code = pkrb5_cc_copy_creds(kcontext, mslsa_ccache, ccache))
+ goto cleanup;
+
+ /* and mark the identity as having been imported */
+ if (ident) {
+ khm_krb5_set_identity_flags(ident, K5IDFLAG_IMPORTED, K5IDFLAG_IMPORTED);
+
+ if (ret_ident) {
+ *ret_ident = ident;
+ kcdb_identity_hold(*ret_ident);
+ }
+ }
+
+ 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:
+ kherr_reportf(L" Received code=%d", code);
+
+ if (princ_name)
+ pkrb5_free_unparsed_name(kcontext, princ_name);
+ 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);
+ if (ident)
+ kcdb_identity_release(ident);
+
+ return(rc);
+#endif /* NO_KRB5 */
+}
+
+#define KRB_FILE "KRB.CON"
+#define KRBREALM_FILE "KRBREALM.CON"
+#define KRB5_FILE "KRB5.INI"
+#define KRB5_TMP_FILE "KRB5.INI.TMP"
+
+BOOL
+khm_krb5_get_temp_profile_file(LPSTR confname, UINT szConfname)
+{
+ GetTempPathA(szConfname, confname);
+ confname[szConfname-1] = '\0';
+ StringCchCatA(confname, szConfname, KRB5_TMP_FILE);
+ confname[szConfname-1] = '\0';
+ return FALSE;
+}
+
+#ifdef NOT_QUITE_IMPLEMENTED_YET
+BOOL
+khm_krb5_set_profile_file(krb5_context ctx, LPSTR confname)
+{
+ char *conffiles[2];
+
+ if (confname == NULL ||
+ pkrb5_set_config_files == NULL ||
+ ctx == NULL)
+ return FALSE;
+
+ conffiles[0] = confname;
+ conffiles[1] = NULL;
+
+ if (pkrb5_set_config_files(ctx, conffiles))
+ return FALSE;
+ else
+ return TRUE;
+}
+#endif
+
+BOOL
+khm_krb5_get_profile_file(LPSTR confname, UINT szConfname)
+{
+ char **configFile = NULL;
+ if (pkrb5_get_default_config_files(&configFile))
+ {
+ GetWindowsDirectoryA(confname,szConfname);
+ confname[szConfname-1] = '\0';
+
+ StringCchCatA(confname, szConfname, "\\");
+ StringCchCatA(confname, szConfname, KRB5_FILE);
+
+ return FALSE;
+ }
+
+ *confname = 0;
+
+ if (configFile)
+ {
+ StringCchCopyA(confname, szConfname, *configFile);
+ pkrb5_free_config_files(configFile);
+ }
+
+ if (!*confname)
+ {
+ GetWindowsDirectoryA(confname,szConfname);
+ confname[szConfname-1] = '\0';
+ StringCchCatA(confname, szConfname, "\\");
+ StringCchCatA(confname, szConfname, KRB5_FILE);
+ }
+
+ return FALSE;
+}
+
+BOOL
+khm_get_krb4_con_file(LPSTR confname, UINT szConfname)
+{
+ if (hKrb5 && !hKrb4) { // hold krb.con where krb5.ini is located
+ CHAR krbConFile[MAX_PATH]="";
+ LPSTR pFind;
+
+ //strcpy(krbConFile, CLeashApp::m_krbv5_profile->first_file->filename);
+ if (khm_krb5_get_profile_file(krbConFile, sizeof(krbConFile))) {
+ GetWindowsDirectoryA(krbConFile,sizeof(krbConFile));
+ krbConFile[MAX_PATH-1] = '\0';
+ StringCchCatA(confname, szConfname, "\\");
+ }
+
+ pFind = strrchr(krbConFile, '\\');
+ if (pFind) {
+ *pFind = '\0';
+ StringCchCatA(krbConFile, ARRAYLENGTH(krbConFile), "\\");
+ StringCchCatA(krbConFile, ARRAYLENGTH(krbConFile), KRB_FILE);
+ }
+ else
+ krbConFile[0] = '\0';
+
+ StringCchCopyA(confname, szConfname, krbConFile);
+ }
+ else if (hKrb4) {
+ unsigned int size = szConfname;
+ memset(confname, '\0', szConfname);
+ if (!pkrb_get_krbconf2(confname, &size))
+ { // Error has happened
+ GetWindowsDirectoryA(confname,szConfname);
+ confname[szConfname-1] = '\0';
+ StringCchCatA(confname, szConfname, "\\");
+ StringCchCatA(confname, szConfname, KRB_FILE);
+ }
+ }
+ return FALSE;
+}
+
+int
+readstring(FILE * file, char * buf, int len)
+{
+ int c,i;
+ memset(buf, '\0', sizeof(buf));
+ for (i=0, c=fgetc(file); c != EOF ; c=fgetc(file), i++) {
+ if (i < sizeof(buf)) {
+ if (c == '\n') {
+ buf[i] = '\0';
+ return i;
+ } else {
+ buf[i] = c;
+ }
+ } else {
+ if (c == '\n') {
+ buf[len-1] = '\0';
+ return(i);
+ }
+ }
+ }
+ if (c == EOF) {
+ if (i > 0 && i < len) {
+ buf[i] = '\0';
+ return(i);
+ } else {
+ buf[len-1] = '\0';
+ return(-1);
+ }
+ }
+ return(-1);
+}
+
+/*! \internal
+ \brief Return a list of configured realms
+
+ The string that is returned is a set of null terminated unicode
+ strings, each of which denotes one realm. The set is terminated
+ by a zero length null terminated string.
+
+ The caller should free the returned string using free()
+
+ \return The string with the list of realms or NULL if the
+ operation fails.
+*/
+wchar_t *
+khm_krb5_get_realm_list(void)
+{
+ wchar_t * rlist = NULL;
+
+ if (pprofile_get_subsection_names && pprofile_free_list) {
+ const char* rootSection[] = {"realms", NULL};
+ const char** rootsec = rootSection;
+ char **sections = NULL, **cpp = NULL, *value = NULL;
+
+ char krb5_conf[MAX_PATH+1];
+
+ if (!khm_krb5_get_profile_file(krb5_conf,sizeof(krb5_conf))) {
+ profile_t profile;
+ long retval;
+ const char *filenames[2];
+ wchar_t * d;
+ size_t cbsize;
+ size_t t;
+
+ filenames[0] = krb5_conf;
+ filenames[1] = NULL;
+ retval = pprofile_init(filenames, &profile);
+ if (!retval) {
+ retval = pprofile_get_subsection_names(profile, rootsec,
+ &sections);
+
+ if (!retval)
+ {
+ /* first figure out how much space to allocate */
+ cbsize = 0;
+ for (cpp = sections; *cpp; cpp++)
+ {
+ cbsize += sizeof(wchar_t) * (strlen(*cpp) + 1);
+ }
+ cbsize += sizeof(wchar_t); /* double null terminated */
+
+ rlist = PMALLOC(cbsize);
+ d = rlist;
+ for (cpp = sections; *cpp; cpp++)
+ {
+ AnsiStrToUnicode(d, cbsize, *cpp);
+ t = wcslen(d) + 1;
+ d += t;
+ cbsize -= sizeof(wchar_t) * t;
+ }
+ *d = L'\0';
+ }
+
+ pprofile_free_list(sections);
+
+#if 0
+ retval = pprofile_get_string(profile, "libdefaults","noaddresses", 0, "true", &value);
+ if ( value ) {
+ disable_noaddresses = config_boolean_to_int(value);
+ pprofile_release_string(value);
+ }
+#endif
+ pprofile_release(profile);
+ }
+ }
+ } else {
+ FILE * file;
+ char krb_conf[MAX_PATH+1];
+ char * p;
+ size_t cbsize, t;
+ wchar_t * d;
+
+ if (!khm_get_krb4_con_file(krb_conf,sizeof(krb_conf)) &&
+#if _MSC_VER >= 1400
+ !fopen_s(&file, krb_conf, "rt")
+#else
+ (file = fopen(krb_conf, "rt"))
+#endif
+ )
+ {
+ char lineBuf[256];
+
+ /*TODO: compute the actual required buffer size instead of hardcoding */
+ cbsize = 16384; // arbitrary
+ rlist = PMALLOC(cbsize);
+ d = rlist;
+
+ // Skip the default realm
+ readstring(file,lineBuf,sizeof(lineBuf));
+
+ // Read the defined realms
+ while (TRUE)
+ {
+ if (readstring(file,lineBuf,sizeof(lineBuf)) < 0)
+ break;
+
+ if (*(lineBuf + strlen(lineBuf) - 1) == '\r')
+ *(lineBuf + strlen(lineBuf) - 1) = 0;
+
+ for (p=lineBuf; *p ; p++)
+ {
+ if (isspace(*p)) {
+ *p = 0;
+ break;
+ }
+ }
+
+ if ( strncmp(".KERBEROS.OPTION.",lineBuf,17) ) {
+ t = strlen(lineBuf) + 1;
+ if(cbsize > (1 + t*sizeof(wchar_t))) {
+ AnsiStrToUnicode(d, cbsize, lineBuf);
+ d += t;
+ cbsize -= t * sizeof(wchar_t);
+ } else
+ break;
+ }
+ }
+
+ *d = L'\0';
+
+ fclose(file);
+ }
+ }
+
+ return rlist;
+}
+
+/*! \internal
+ \brief Get the default realm
+
+ A string will be returned that specifies the default realm. The
+ caller should free the string using PFREE().
+
+ Returns NULL if the operation fails.
+*/
+wchar_t *
+khm_krb5_get_default_realm(void)
+{
+ wchar_t * realm;
+ size_t cch;
+ krb5_context ctx=0;
+ char * def = 0;
+
+ pkrb5_init_context(&ctx);
+
+ if (ctx == 0)
+ return NULL;
+
+ pkrb5_get_default_realm(ctx,&def);
+
+ if (def) {
+ cch = strlen(def) + 1;
+ realm = PMALLOC(sizeof(wchar_t) * cch);
+ AnsiStrToUnicode(realm, sizeof(wchar_t) * cch, def);
+ pkrb5_free_default_realm(ctx, def);
+ } else
+ realm = NULL;
+
+ pkrb5_free_context(ctx);
+
+ return realm;
+}
+
+long
+khm_krb5_set_default_realm(wchar_t * realm) {
+ krb5_context ctx=0;
+ char * def = 0;
+ long rv = 0;
+ char astr[K5_MAXCCH_REALM];
+
+ UnicodeStrToAnsi(astr, sizeof(astr), realm);
+
+ pkrb5_init_context(&ctx);
+ pkrb5_get_default_realm(ctx,&def);
+
+ if ((def && strcmp(def, astr)) ||
+ !def) {
+ rv = pkrb5_set_default_realm(ctx, astr);
+ }
+
+ if (def) {
+ pkrb5_free_default_realm(ctx, def);
+ }
+
+ pkrb5_free_context(ctx);
+
+ return rv;
+}
+
+wchar_t *
+khm_get_realm_from_princ(wchar_t * princ) {
+ wchar_t * t;
+
+ if(!princ)
+ return NULL;
+
+ for (t = princ; *t; t++) {
+ if(*t == L'\\') { /* escape */
+ t++;
+ if(! *t) /* malformed */
+ break;
+ } else if (*t == L'@')
+ break;
+ }
+
+ if (*t == '@' && *(t+1) != L'\0')
+ return (t+1);
+ else
+ return NULL;
+}
+
+long
+khm_krb5_changepwd(char * principal,
+ char * password,
+ char * newpassword,
+ char** error_str)
+{
+ krb5_error_code rc = 0;
+ int result_code = 0;
+ krb5_data result_code_string, result_string;
+ krb5_context context = 0;
+ krb5_principal princ = 0;
+ krb5_get_init_creds_opt opts;
+ krb5_creds creds;
+
+ result_string.data = 0;
+ result_code_string.data = 0;
+
+ if ( !pkrb5_init_context )
+ goto cleanup;
+
+ if (rc = pkrb5_init_context(&context)) {
+ goto cleanup;
+ }
+
+ if (rc = pkrb5_parse_name(context, principal, &princ)) {
+ goto cleanup;
+ }
+
+ pkrb5_get_init_creds_opt_init(&opts);
+ pkrb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
+ pkrb5_get_init_creds_opt_set_renew_life(&opts, 0);
+ pkrb5_get_init_creds_opt_set_forwardable(&opts, 0);
+ pkrb5_get_init_creds_opt_set_proxiable(&opts, 0);
+ pkrb5_get_init_creds_opt_set_address_list(&opts,NULL);
+
+ if (rc = pkrb5_get_init_creds_password(context, &creds, princ,
+ password, 0, 0, 0,
+ "kadmin/changepw", &opts)) {
+ if (rc == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+#if 0
+ com_err(argv[0], 0,
+ "Password incorrect while getting initial ticket");
+#endif
+ } else {
+#if 0
+ com_err(argv[0], ret, "getting initial ticket");
+#endif
+ }
+ goto cleanup;
+ }
+
+ if (rc = pkrb5_change_password(context, &creds, newpassword,
+ &result_code, &result_code_string,
+ &result_string)) {
+#if 0
+ com_err(argv[0], ret, "changing password");
+#endif
+ goto cleanup;
+ }
+
+ if (result_code) {
+ int len = result_code_string.length +
+ (result_string.length ? (sizeof(": ") - 1) : 0) +
+ result_string.length;
+ if (len && error_str) {
+ *error_str = PMALLOC(len + 1);
+ if (*error_str)
+ StringCchPrintfA(*error_str, len+1,
+ "%.*s%s%.*s",
+ result_code_string.length,
+ result_code_string.data,
+ result_string.length?": ":"",
+ result_string.length,
+ result_string.data);
+ }
+ rc = result_code;
+ goto cleanup;
+ }
+
+ cleanup:
+ if (result_string.data)
+ pkrb5_free_data_contents(context, &result_string);
+
+ if (result_code_string.data)
+ pkrb5_free_data_contents(context, &result_code_string);
+
+ if (princ)
+ pkrb5_free_principal(context, princ);
+
+ if (context)
+ pkrb5_free_context(context);
+
+ return rc;
+}
+
+khm_int32 KHMAPI
+khm_krb5_creds_is_equal(khm_handle vcred1, khm_handle vcred2, void * dummy) {
+ if (kcdb_creds_comp_attr(vcred1, vcred2, KCDB_ATTR_LOCATION) ||
+ kcdb_creds_comp_attr(vcred1, vcred2, attr_id_key_enctype) ||
+ kcdb_creds_comp_attr(vcred1, vcred2, attr_id_tkt_enctype) ||
+ kcdb_creds_comp_attr(vcred1, vcred2, attr_id_kvno))
+ return 1;
+ else
+ return 0;
+}
+
+void
+khm_krb5_set_identity_flags(khm_handle identity,
+ khm_int32 flag_mask,
+ khm_int32 flag_value) {
+
+ khm_int32 t = 0;
+ khm_size cb;
+
+ cb = sizeof(t);
+ if (KHM_FAILED(kcdb_identity_get_attr(identity,
+ attr_id_krb5_idflags,
+ NULL,
+ &t, &cb))) {
+ t = 0;
+ }
+
+ t &= ~flag_mask;
+ t |= (flag_value & flag_mask);
+
+ kcdb_identity_set_attr(identity,
+ attr_id_krb5_idflags,
+ &t, sizeof(t));
+}
+
+khm_int32
+khm_krb5_get_identity_flags(khm_handle identity) {
+ khm_int32 t = 0;
+ khm_size cb;
+
+ cb = sizeof(t);
+ kcdb_identity_get_attr(identity,
+ attr_id_krb5_idflags,
+ NULL, &t, &cb);
+
+ return t;
+}
+
+long
+khm_krb5_get_temp_ccache(krb5_context ctx,
+ krb5_ccache * prcc) {
+ int rnd = rand();
+ char ccname[MAX_PATH];
+ long code = 0;
+ krb5_ccache cc = 0;
+
+ StringCbPrintfA(ccname, sizeof(ccname), "MEMORY:TempCache%8x", rnd);
+
+ code = pkrb5_cc_resolve(ctx, ccname, &cc);
+
+ if (code == 0)
+ *prcc = cc;
+
+ return code;
+}
+
+/*
+
+ The configuration information for each identity comes from a
+ multitude of layers organized as follows. The ordering is
+ decreasing in priority. When looking up a value, the value will be
+ looked up in each layer in turn starting at level 0. The first
+ instance of the value found will be the effective value.
+
+ 0 : <identity configuration>\Krb5Cred
+
+ 0.1: per user
+
+ 0.2: per machine
+
+ 1 : <plugin configuration>\Parameters\Realms\<realm of identity>
+
+ 1.1: per user
+
+ 1.2: per machine
+
+ 2 : <plugin configuration>\Parameters
+
+ 2.1: per user
+
+ 2.2: per machine
+
+ 2.3: schema
+
+ */
+khm_int32
+khm_krb5_get_identity_config(khm_handle ident,
+ khm_int32 flags,
+ khm_handle * ret_csp) {
+
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+ khm_handle csp_i = NULL;
+ khm_handle csp_ik5 = NULL;
+ khm_handle csp_realms = NULL;
+ khm_handle csp_realm = NULL;
+ khm_handle csp_plugins = NULL;
+ khm_handle csp_krbcfg = NULL;
+ khm_handle csp_rv = NULL;
+ wchar_t realm[KCDB_IDENT_MAXCCH_NAME];
+
+ realm[0] = L'\0';
+
+ if (ident) {
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t * trealm;
+ khm_size cb_idname = sizeof(idname);
+
+ rv = kcdb_identity_get_name(ident, idname, &cb_idname);
+ if (KHM_SUCCEEDED(rv) &&
+ (trealm = khm_get_realm_from_princ(idname)) != NULL) {
+ StringCbCopy(realm, sizeof(realm), trealm);
+ }
+ }
+
+ if (ident) {
+ rv = kcdb_identity_get_config(ident, flags, &csp_i);
+ if (KHM_FAILED(rv))
+ goto try_realm;
+
+ rv = khc_open_space(csp_i, CSNAME_KRB5CRED, flags, &csp_ik5);
+ if (KHM_FAILED(rv))
+ goto try_realm;
+
+ try_realm:
+
+ if (realm[0] == L'\0')
+ goto done_shadow_realm;
+
+ rv = khc_open_space(csp_params, CSNAME_REALMS, flags, &csp_realms);
+ if (KHM_FAILED(rv))
+ goto done_shadow_realm;
+
+ rv = khc_open_space(csp_realms, realm, flags, &csp_realm);
+ if (KHM_FAILED(rv))
+ goto done_shadow_realm;
+
+ rv = khc_shadow_space(csp_realm, csp_params);
+
+ done_shadow_realm:
+
+ if (csp_ik5) {
+ if (csp_realm)
+ rv = khc_shadow_space(csp_ik5, csp_realm);
+ else
+ rv = khc_shadow_space(csp_ik5, csp_params);
+
+ csp_rv = csp_ik5;
+ } else {
+ if (csp_realm)
+ csp_rv = csp_realm;
+ }
+ }
+
+ if (csp_rv == NULL) {
+
+ /* No valid identity specified or the specified identity
+ doesn't have any configuration. We default to the
+ parameters key. */
+
+ /* we don't just return csp_params since that's a global
+ handle that we shouldn't close until the plugin is
+ unloaded. The caller is going to close the returned handle
+ when it is done. So we need to create a new csp_params
+ that can safely be closed. */
+
+ rv = kmm_get_plugins_config(0, &csp_plugins);
+ if (KHM_FAILED(rv))
+ goto done;
+
+ rv = khc_open_space(csp_plugins, CSNAME_KRB5CRED, flags, &csp_krbcfg);
+ if (KHM_FAILED(rv))
+ goto done;
+
+ rv = khc_open_space(csp_krbcfg, CSNAME_PARAMS, flags, &csp_rv);
+ }
+
+ done:
+
+ *ret_csp = csp_rv;
+
+ /* leave csp_ik5. If it's non-NULL, then it's the return value */
+ /* leave csp_rv. It's the return value. */
+ if (csp_i)
+ khc_close_space(csp_i);
+ if (csp_realms)
+ khc_close_space(csp_realms);
+
+ /* csp_realm can also be a return value if csp_ik5 was NULL */
+ if (csp_realm && csp_realm != csp_rv)
+ khc_close_space(csp_realm);
+
+ if (csp_plugins)
+ khc_close_space(csp_plugins);
+ if (csp_krbcfg)
+ khc_close_space(csp_krbcfg);
+
+ return rv;
+}
+
+/* from get_in_tkt.c */
+static krb5_error_code
+get_libdefault_string(profile_t profile, const char * realm,
+ const char * option, char ** ret_val) {
+ char realmstr[K5_MAXCCH_REALM];
+ char **nameval = NULL;
+ const char * names[4];
+ krb5_error_code code = 0;
+
+ names[0] = "libdefaults";
+
+ if (!realm || !realm[0])
+ goto try_number_two;
+
+ StringCbCopyA(realmstr, sizeof(realmstr), realm);
+
+ /*
+ * Try number one:
+ *
+ * [libdefaults]
+ * REALM = {
+ * option = <boolean>
+ * }
+ */
+
+ names[1] = realmstr;
+ names[2] = option;
+ names[3] = 0;
+ code = pprofile_get_values(profile, names, &nameval);
+ if (code == 0 && nameval && nameval[0])
+ goto goodbye;
+
+ try_number_two:
+
+ /*
+ * Try number two:
+ *
+ * [libdefaults]
+ * option = <boolean>
+ */
+
+ names[1] = option;
+ names[2] = 0;
+ code = pprofile_get_values(profile, names, &nameval);
+ if (code == 0 && nameval && nameval[0])
+ goto goodbye;
+
+ goodbye:
+ if (!nameval)
+ return(ENOENT);
+
+ if (!nameval[0]) {
+ code = ENOENT;
+ } else {
+ size_t cb;
+
+ if (FAILED(StringCbLengthA(nameval[0], K5_MAXCCH_REALM * sizeof(char), &cb))) {
+ code = ENOMEM;
+ } else {
+ cb += sizeof(char);
+ *ret_val = PMALLOC(cb);
+
+ if (!*ret_val)
+ code = ENOMEM;
+ else {
+ StringCbCopyA(*ret_val, cb, nameval[0]);
+ code = 0;
+ }
+ }
+ }
+
+ pprofile_free_list(nameval);
+
+ return code;
+}
+
+khm_int32
+khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {
+
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+ khm_handle csp_id = NULL;
+ khm_int32 regf = 0;
+ khm_int32 proff = 0;
+ khm_int32 e;
+ khm_int32 v;
+ CHAR confname[MAX_PATH];
+ CHAR realmname[K5_MAXCCH_REALM];
+
+ ZeroMemory(p, sizeof(*p));
+
+ rv = khm_krb5_get_identity_config(ident, 0, &csp_id);
+ if (KHM_FAILED(rv))
+ goto done_reg;
+
+
+#define GETVAL(vname, vfield, flag) \
+ do { \
+ e = khc_value_exists(csp_id, vname); \
+ rv = khc_read_int32(csp_id, vname, &v); \
+ if (KHM_FAILED(rv)) goto done_reg; \
+ p->vfield = v; \
+ if ((e & ~KCONF_FLAG_SCHEMA) != 0) regf |= flag; \
+ } while(FALSE)
+
+ /* Flags */
+ GETVAL(L"Renewable", renewable, K5PARAM_F_RENEW);
+ GETVAL(L"Forwardable", forwardable, K5PARAM_F_FORW);
+ GETVAL(L"Proxiable", proxiable, K5PARAM_F_PROX);
+ GETVAL(L"Addressless", addressless, K5PARAM_F_ADDL);
+ GETVAL(L"PublicIP", publicIP, K5PARAM_F_PUBIP);
+
+ /* Lifetime */
+ GETVAL(L"DefaultLifetime", lifetime, K5PARAM_F_LIFE);
+ GETVAL(L"MaxLifetime", lifetime_max, K5PARAM_F_LIFE_H);
+ GETVAL(L"MinLifetime", lifetime_min, K5PARAM_F_LIFE_L);
+
+ /* Renewable lifetime */
+ GETVAL(L"DefaultRenewLifetime", renew_life, K5PARAM_F_RLIFE);
+ GETVAL(L"MaxRenewLifetime", renew_life_max, K5PARAM_F_RLIFE_H);
+ GETVAL(L"MinRenewLifetime", renew_life_min, K5PARAM_F_RLIFE_L);
+
+#undef GETVAL
+
+ done_reg:
+
+ if (csp_id)
+ khc_close_space(csp_id);
+
+ /* if all the parameters were read from the registry, then we have
+ no reason to read from the profile file. */
+ if (regf == K5PARAM_FM_ALL) {
+ p->source_reg = regf;
+ return KHM_ERROR_SUCCESS;
+ }
+
+ if (rv)
+ return rv;
+
+ /* we need to figure out the realm name, since there might be
+ per-realm configuration in the profile file. */
+
+ realmname[0] = '\0';
+
+ if (ident) {
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb;
+
+ idname[0] = L'\0';
+ cb = sizeof(idname);
+ rv = kcdb_identity_get_name(ident, idname, &cb);
+ if (KHM_SUCCEEDED(rv)) {
+ wchar_t * wrealm;
+
+ wrealm = khm_get_realm_from_princ(idname);
+ if (wrealm) {
+ UnicodeStrToAnsi(realmname, sizeof(realmname), wrealm);
+ }
+ }
+ }
+
+ /* If we get here, then some of the settings we read from the
+ configuration actually came from the schema. In other words,
+ the values weren't really defined for this identity. So we now
+ have to read the values from the krb5 configuration file. */
+
+ if (!khm_krb5_get_profile_file(confname, sizeof(confname))) {
+ profile_t profile;
+ const char * filenames[2];
+ long retval;
+
+ filenames[0] = confname;
+ filenames[1] = NULL;
+
+ if (!pprofile_init(filenames, &profile)) {
+
+ /* default ticket lifetime */
+ if (!(regf & K5PARAM_F_LIFE)) {
+ char * value = NULL;
+ retval = get_libdefault_string(profile, realmname,
+ "ticket_lifetime", &value);
+
+ if (retval == 0 && value) {
+ krb5_deltat d;
+
+ retval = pkrb5_string_to_deltat(value, &d);
+ if (retval == KRB5_DELTAT_BADFORMAT) {
+ /* Historically some sites use relations of
+ the form 'ticket_lifetime = 24000' where
+ the unit is left out but is assumed to be
+ seconds. Then there are other sites which
+ use the form 'ticket_lifetime = 600' where
+ the unit is assumed to be minutes. While
+ these are technically wrong (a unit needs
+ to be specified), we try to accomodate for
+ this using the safe assumption that the
+ unit is seconds and tack an 's' to the end
+ and see if that works. */
+
+ size_t cch;
+ char tmpbuf[256];
+ char * buf;
+
+ do {
+ if (FAILED(StringCchLengthA(value, 1024 /* unresonably large size */,
+ &cch)))
+ break;
+
+ cch += sizeof(char) * 2; /* NULL and new 's' */
+ if (cch > ARRAYLENGTH(tmpbuf))
+ buf = PMALLOC(cch * sizeof(char));
+ else
+ buf = tmpbuf;
+
+ StringCchCopyA(buf, cch, value);
+ StringCchCatA(buf, cch, "s");
+
+ retval = pkrb5_string_to_deltat(buf, &d);
+ if (retval == 0) {
+ p->lifetime = d;
+ proff |= K5PARAM_F_LIFE;
+ }
+
+ if (buf != tmpbuf)
+ PFREE(buf);
+
+ } while(0);
+
+ } else if (retval == 0) {
+ p->lifetime = d;
+ proff |= K5PARAM_F_LIFE;
+ }
+
+ PFREE(value);
+ }
+ }
+
+ if (!(regf & K5PARAM_F_RLIFE)) {
+ char * value = NULL;
+ retval = get_libdefault_string(profile, realmname,
+ "renew_lifetime", &value);
+ if (retval == 0 && value) {
+ krb5_deltat d;
+
+ retval = pkrb5_string_to_deltat(value, &d);
+ if (retval == 0) {
+ p->renew_life = d;
+ proff |= K5PARAM_F_RLIFE;
+ }
+ PFREE(value);
+ }
+ }
+
+ if (!(regf & K5PARAM_F_FORW)) {
+ char * value = NULL;
+ retval = get_libdefault_string(profile, realmname,
+ "forwardable", &value);
+ if (retval == 0 && value) {
+ khm_boolean b;
+
+ if (!khm_krb5_parse_boolean(value, &b))
+ p->forwardable = b;
+ else
+ p->forwardable = FALSE;
+ PFREE(value);
+ proff |= K5PARAM_F_FORW;
+ }
+ }
+
+ if (!(regf & K5PARAM_F_RENEW)) {
+ char * value = NULL;
+ retval = get_libdefault_string(profile, realmname,
+ "renewable", &value);
+ if (retval == 0 && value) {
+ khm_boolean b;
+
+ if (!khm_krb5_parse_boolean(value, &b))
+ p->renewable = b;
+ else
+ p->renewable = TRUE;
+ PFREE(value);
+ proff |= K5PARAM_F_RENEW;
+ }
+ }
+
+ if (!(regf & K5PARAM_F_ADDL)) {
+ char * value = NULL;
+ retval = get_libdefault_string(profile, realmname,
+ "noaddresses", &value);
+ if (retval == 0 && value) {
+ khm_boolean b;
+
+ if (!khm_krb5_parse_boolean(value, &b))
+ p->addressless = b;
+ else
+ p->addressless = TRUE;
+ PFREE(value);
+ proff |= K5PARAM_F_ADDL;
+ }
+ }
+
+ if (!(regf & K5PARAM_F_PROX)) {
+ char * value = NULL;
+ retval = get_libdefault_string(profile, realmname,
+ "proxiable", &value);
+ if (retval == 0 && value) {
+ khm_boolean b;
+
+ if (!khm_krb5_parse_boolean(value, &b))
+ p->proxiable = b;
+ else
+ p->proxiable = FALSE;
+ PFREE(value);
+ proff |= K5PARAM_F_PROX;
+ }
+ }
+
+ pprofile_release(profile);
+ }
+ }
+
+ p->source_reg = regf;
+ p->source_prof = proff;
+
+ return rv;
+}
+
+/* Note that p->source_reg and p->source_prof is used in special ways
+ here. All fields that are flagged in source_reg will be written to
+ the configuration (if they are different from what
+ khm_krb5_get_identity_params() reports). All fields that are
+ flagged in source_prof will be removed from the configuration
+ (thereby exposing the value defined in the profile file). */
+khm_int32
+khm_krb5_set_identity_params(khm_handle ident, const k5_params * p) {
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+ khm_handle csp_id = NULL;
+ k5_params p_s;
+ khm_int32 source_reg = p->source_reg;
+ khm_int32 source_prof = p->source_prof;
+
+ rv = khm_krb5_get_identity_config(ident,
+ KHM_PERM_WRITE | KHM_FLAG_CREATE |
+ KCONF_FLAG_WRITEIFMOD,
+ &csp_id);
+ if (KHM_FAILED(rv))
+ goto done_reg;
+
+ khm_krb5_get_identity_params(ident, &p_s);
+
+ /* Remove any bits that don't make sense. Not all values can be
+ specified in the profile file. */
+ source_prof &= K5PARAM_FM_PROF;
+
+ /* if a flag appears in both source_prof and source_reg, remove
+ the flag from source_reg. */
+ source_reg &= ~source_prof;
+
+ /* we only write values that have changed, and that are flagged in
+ source_reg */
+
+ if ((source_reg & K5PARAM_F_RENEW) &&
+ !!p_s.renewable != !!p->renewable)
+ khc_write_int32(csp_id, L"Renewable", !!p->renewable);
+
+ if ((source_reg & K5PARAM_F_FORW) &&
+ !!p_s.forwardable != !!p->forwardable)
+ khc_write_int32(csp_id, L"Forwardable", !!p->forwardable);
+
+ if ((source_reg & K5PARAM_F_PROX) &&
+ !!p_s.proxiable != !!p->proxiable)
+ khc_write_int32(csp_id, L"Proxiable", !!p->proxiable);
+
+ if ((source_reg & K5PARAM_F_ADDL) &&
+ !!p_s.addressless != !!p->addressless)
+ khc_write_int32(csp_id, L"Addressless", !!p->addressless);
+
+ if ((source_reg & K5PARAM_F_PUBIP) &&
+ p_s.publicIP != p->publicIP)
+ khc_write_int32(csp_id, L"PublicIP", p->publicIP);
+
+ if ((source_reg & K5PARAM_F_LIFE) &&
+ p_s.lifetime != p->lifetime)
+ khc_write_int32(csp_id, L"DefaultLifetime", p->lifetime);
+
+ if ((source_reg & K5PARAM_F_LIFE_H) &&
+ p_s.lifetime_max != p->lifetime_max)
+ khc_write_int32(csp_id, L"MaxLifetime", p->lifetime_max);
+
+ if ((source_reg & K5PARAM_F_LIFE_L) &&
+ p_s.lifetime_min != p->lifetime_min)
+ khc_write_int32(csp_id, L"MinLifetime", p->lifetime_min);
+
+ if ((source_reg & K5PARAM_F_RLIFE) &&
+ p_s.renew_life != p->renew_life)
+ khc_write_int32(csp_id, L"DefaultRenewLifetime", p->renew_life);
+
+ if ((source_reg & K5PARAM_F_RLIFE_H) &&
+ p_s.renew_life_max != p->renew_life_max)
+ khc_write_int32(csp_id, L"MaxRenewLifetime", p->renew_life_max);
+
+ if ((source_reg & K5PARAM_F_RLIFE_L) &&
+ p_s.renew_life_min != p->renew_life_min)
+ khc_write_int32(csp_id, L"MinRenewLifetime", p->renew_life_min);
+
+ /* and now, remove the values that are present in source_prof.
+ Not all values are removed since not all values can be
+ specified in the profile file. */
+ if (source_prof & K5PARAM_F_RENEW)
+ khc_remove_value(csp_id, L"Renewable", 0);
+
+ if (source_prof & K5PARAM_F_FORW)
+ khc_remove_value(csp_id, L"Forwardable", 0);
+
+ if (source_prof & K5PARAM_F_PROX)
+ khc_remove_value(csp_id, L"Proxiable", 0);
+
+ if (source_prof & K5PARAM_F_ADDL)
+ khc_remove_value(csp_id, L"Addressless", 0);
+
+ if (source_prof & K5PARAM_F_LIFE)
+ khc_remove_value(csp_id, L"DefaultLifetime", 0);
+
+ if (source_prof & K5PARAM_F_RLIFE)
+ khc_remove_value(csp_id, L"DefaultRenewLifetime", 0);
+
+ done_reg:
+ if (csp_id != NULL)
+ khc_close_space(csp_id);
+
+ return rv;
+}
+
+static const char *const conf_yes[] = {
+ "y", "yes", "true", "t", "1", "on",
+ 0,
+};
+
+static const char *const conf_no[] = {
+ "n", "no", "false", "nil", "0", "off",
+ 0,
+};
+
+int
+khm_krb5_parse_boolean(const char *s, khm_boolean * b)
+{
+ const char *const *p;
+
+ for(p=conf_yes; *p; p++) {
+ if (!_stricmp(*p,s)) {
+ *b = TRUE;
+ return 0;
+ }
+ }
+
+ for(p=conf_no; *p; p++) {
+ if (!_stricmp(*p,s)) {
+ *b = FALSE;
+ return 0;
+ }
+ }
+
+ /* Default to "no" */
+ return KHM_ERROR_INVALID_PARAM;
+}
diff --git a/src/windows/identity/plugins/krb5/krb5funcs.h b/src/windows/identity/plugins/krb5/krb5funcs.h
index b4ab452b3..d2ec28b47 100644
--- a/src/windows/identity/plugins/krb5/krb5funcs.h
+++ b/src/windows/identity/plugins/krb5/krb5funcs.h
@@ -1,217 +1,217 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Adapted from multiple Leash header files */
-
-#ifndef __KHIMAIRA_KRB5FUNCS_H
-#define __KHIMAIRA_KRB5FUNCS_H
-
-#include<stdlib.h>
-#include<krb5.h>
-
-#include <windows.h>
-#define SECURITY_WIN32
-#include <security.h>
-
-#if _WIN32_WINNT < 0x0501
-#define KHM_SAVE_WIN32_WINNT _WIN32_WINNT
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-#include<ntsecapi.h>
-#ifdef KHM_SAVE_WIN32_WINNT
-#undef _WIN32_WINNT
-#define _WIN32_WINNT KHM_SAVE_WIN32_WINNT
-#undef KHM_SAVE_WIN32_WINNT
-#endif
-
-#include <krb5common.h>
-
-#define LEASH_DEBUG_CLASS_GENERIC 0
-#define LEASH_DEBUG_CLASS_KRB4 1
-#define LEASH_DEBUG_CLASS_KRB4_APP 2
-
-#define LEASH_PRIORITY_LOW 0
-#define LEASH_PRIORITY_HIGH 1
-
-#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
-
-#define KRB5_MAXCCH_CCNAME 1024
-
-#define KRB5_CONF_YES "yes"
-#define KRB5_CONF_NO "no"
-
-typedef struct tag_k5params {
-
- khm_int32 source_reg; /* flags indicating which fields were
- retrieved using the registry */
- khm_int32 source_prof; /* flags indicating which fields were
- retrieved using krb5.ini */
-
- khm_boolean renewable;
- khm_boolean forwardable;
- khm_boolean proxiable;
- khm_boolean addressless;
-
- khm_ui_4 publicIP;
-
- krb5_deltat lifetime;
- krb5_deltat lifetime_min;
- krb5_deltat lifetime_max;
-
- krb5_deltat renew_life;
- krb5_deltat renew_life_min;
- krb5_deltat renew_life_max;
-
-} k5_params;
-
-#define K5PARAM_F_RENEW 0x00000001
-#define K5PARAM_F_FORW 0x00000002
-#define K5PARAM_F_PROX 0x00000004
-#define K5PARAM_F_ADDL 0x00000008
-#define K5PARAM_F_PUBIP 0x00000010
-#define K5PARAM_F_LIFE 0x00000020
-#define K5PARAM_F_RLIFE 0x00000040
-#define K5PARAM_F_LIFE_L 0x00000080
-#define K5PARAM_F_LIFE_H 0x00000100
-#define K5PARAM_F_RLIFE_L 0x00000200
-#define K5PARAM_F_RLIFE_H 0x00000400
-
-#define K5PARAM_FM_ALL 0x000007ff
-#define K5PARAM_FM_PROF 0x0000007f
-
-/* Credential and principal operations */
-
-BOOL
-khm_krb5_ms2mit(char * match_princ,
- BOOL match_realm,
- BOOL save_creds,
- khm_handle * ret_ident);
-
-int
-khm_krb5_kinit(krb5_context alt_ctx,
- char * principal_name,
- char * password,
- char * ccache,
- krb5_deltat lifetime,
- DWORD forwardable,
- DWORD proxiable,
- krb5_deltat renew_life,
- DWORD addressless,
- DWORD publicIP,
- krb5_prompter_fct prompter,
- void * p_data);
-
-long
-khm_krb5_changepwd(char * principal,
- char * password,
- char * newpassword,
- char** error_str);
-
-int
-khm_krb5_destroy_by_credset(khm_handle p_cs);
-
-int
-khm_krb5_destroy_identity(khm_handle identity);
-
-long
-khm_convert524(krb5_context ctx);
-
-int
-khm_krb5_renew_cred(khm_handle cred);
-
-int
-khm_krb5_renew_ident(khm_handle identity);
-
-long
-khm_krb5_list_tickets(krb5_context *krbv5Context);
-
-long
-khm_krb5_copy_ccache_by_name(krb5_context in_ctx,
- wchar_t * wscc_dest,
- wchar_t * wscc_src);
-
-long
-khm_krb5_get_temp_ccache(krb5_context ctx,
- krb5_ccache * cc);
-
-khm_int32 KHMAPI
-khm_krb5_creds_is_equal(khm_handle vcred1, khm_handle vcred2, void * dummy);
-
-
-/* Configuration */
-
-BOOL
-khm_krb5_get_profile_file(LPSTR confname, UINT szConfname);
-
-BOOL
-khm_krb5_get_temp_profile_file(LPSTR confname, UINT szConfname);
-
-wchar_t *
-khm_krb5_get_default_realm(void);
-
-long
-khm_krb5_set_default_realm(wchar_t * realm);
-
-wchar_t *
-khm_krb5_get_realm_list(void);
-
-khm_int32
-khm_krb5_get_identity_config(khm_handle ident,
- khm_int32 flags,
- khm_handle * ret_csp);
-
-void
-khm_krb5_set_identity_flags(khm_handle identity,
- khm_int32 flag_mask,
- khm_int32 flag_value);
-
-khm_int32
-khm_krb5_get_identity_flags(khm_handle identity);
-
-khm_int32
-khm_krb5_set_identity_params(khm_handle ident, const k5_params * p);
-
-khm_int32
-khm_krb5_get_identity_params(khm_handle ident, k5_params * p);
-
-/* Utility */
-
-wchar_t *
-khm_get_realm_from_princ(wchar_t * princ);
-
-long
-khm_krb5_canon_cc_name(wchar_t * wcc_name,
- size_t cb_cc_name);
-
-int
-khm_krb5_cc_name_cmp(const wchar_t * cc_name_1,
- const wchar_t * cc_name_2);
-
-int
-khm_krb5_parse_boolean(const char *s, khm_boolean * b);
-
-#endif
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+/* Adapted from multiple Leash header files */
+
+#ifndef __KHIMAIRA_KRB5FUNCS_H
+#define __KHIMAIRA_KRB5FUNCS_H
+
+#include<stdlib.h>
+#include<krb5.h>
+
+#include <windows.h>
+#define SECURITY_WIN32
+#include <security.h>
+
+#if _WIN32_WINNT < 0x0501
+#define KHM_SAVE_WIN32_WINNT _WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
+#include<ntsecapi.h>
+#ifdef KHM_SAVE_WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT KHM_SAVE_WIN32_WINNT
+#undef KHM_SAVE_WIN32_WINNT
+#endif
+
+#include <krb5common.h>
+
+#define LEASH_DEBUG_CLASS_GENERIC 0
+#define LEASH_DEBUG_CLASS_KRB4 1
+#define LEASH_DEBUG_CLASS_KRB4_APP 2
+
+#define LEASH_PRIORITY_LOW 0
+#define LEASH_PRIORITY_HIGH 1
+
+#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
+
+#define KRB5_MAXCCH_CCNAME 1024
+
+#define KRB5_CONF_YES "yes"
+#define KRB5_CONF_NO "no"
+
+typedef struct tag_k5params {
+
+ khm_int32 source_reg; /* flags indicating which fields were
+ retrieved using the registry */
+ khm_int32 source_prof; /* flags indicating which fields were
+ retrieved using krb5.ini */
+
+ khm_boolean renewable;
+ khm_boolean forwardable;
+ khm_boolean proxiable;
+ khm_boolean addressless;
+
+ khm_ui_4 publicIP;
+
+ krb5_deltat lifetime;
+ krb5_deltat lifetime_min;
+ krb5_deltat lifetime_max;
+
+ krb5_deltat renew_life;
+ krb5_deltat renew_life_min;
+ krb5_deltat renew_life_max;
+
+} k5_params;
+
+#define K5PARAM_F_RENEW 0x00000001
+#define K5PARAM_F_FORW 0x00000002
+#define K5PARAM_F_PROX 0x00000004
+#define K5PARAM_F_ADDL 0x00000008
+#define K5PARAM_F_PUBIP 0x00000010
+#define K5PARAM_F_LIFE 0x00000020
+#define K5PARAM_F_RLIFE 0x00000040
+#define K5PARAM_F_LIFE_L 0x00000080
+#define K5PARAM_F_LIFE_H 0x00000100
+#define K5PARAM_F_RLIFE_L 0x00000200
+#define K5PARAM_F_RLIFE_H 0x00000400
+
+#define K5PARAM_FM_ALL 0x000007ff
+#define K5PARAM_FM_PROF 0x0000007f
+
+/* Credential and principal operations */
+
+BOOL
+khm_krb5_ms2mit(char * match_princ,
+ BOOL match_realm,
+ BOOL save_creds,
+ khm_handle * ret_ident);
+
+int
+khm_krb5_kinit(krb5_context alt_ctx,
+ char * principal_name,
+ char * password,
+ char * ccache,
+ krb5_deltat lifetime,
+ DWORD forwardable,
+ DWORD proxiable,
+ krb5_deltat renew_life,
+ DWORD addressless,
+ DWORD publicIP,
+ krb5_prompter_fct prompter,
+ void * p_data);
+
+long
+khm_krb5_changepwd(char * principal,
+ char * password,
+ char * newpassword,
+ char** error_str);
+
+int
+khm_krb5_destroy_by_credset(khm_handle p_cs);
+
+int
+khm_krb5_destroy_identity(khm_handle identity);
+
+long
+khm_convert524(krb5_context ctx);
+
+int
+khm_krb5_renew_cred(khm_handle cred);
+
+int
+khm_krb5_renew_ident(khm_handle identity);
+
+long
+khm_krb5_list_tickets(krb5_context *krbv5Context);
+
+long
+khm_krb5_copy_ccache_by_name(krb5_context in_ctx,
+ wchar_t * wscc_dest,
+ wchar_t * wscc_src);
+
+long
+khm_krb5_get_temp_ccache(krb5_context ctx,
+ krb5_ccache * cc);
+
+khm_int32 KHMAPI
+khm_krb5_creds_is_equal(khm_handle vcred1, khm_handle vcred2, void * dummy);
+
+
+/* Configuration */
+
+BOOL
+khm_krb5_get_profile_file(LPSTR confname, UINT szConfname);
+
+BOOL
+khm_krb5_get_temp_profile_file(LPSTR confname, UINT szConfname);
+
+wchar_t *
+khm_krb5_get_default_realm(void);
+
+long
+khm_krb5_set_default_realm(wchar_t * realm);
+
+wchar_t *
+khm_krb5_get_realm_list(void);
+
+khm_int32
+khm_krb5_get_identity_config(khm_handle ident,
+ khm_int32 flags,
+ khm_handle * ret_csp);
+
+void
+khm_krb5_set_identity_flags(khm_handle identity,
+ khm_int32 flag_mask,
+ khm_int32 flag_value);
+
+khm_int32
+khm_krb5_get_identity_flags(khm_handle identity);
+
+khm_int32
+khm_krb5_set_identity_params(khm_handle ident, const k5_params * p);
+
+khm_int32
+khm_krb5_get_identity_params(khm_handle ident, k5_params * p);
+
+/* Utility */
+
+wchar_t *
+khm_get_realm_from_princ(wchar_t * princ);
+
+long
+khm_krb5_canon_cc_name(wchar_t * wcc_name,
+ size_t cb_cc_name);
+
+int
+khm_krb5_cc_name_cmp(const wchar_t * cc_name_1,
+ const wchar_t * cc_name_2);
+
+int
+khm_krb5_parse_boolean(const char *s, khm_boolean * b);
+
+#endif
diff --git a/src/windows/identity/plugins/krb5/krb5identpro.c b/src/windows/identity/plugins/krb5/krb5identpro.c
index 0072b967d..4d1120f39 100644
--- a/src/windows/identity/plugins/krb5/krb5identpro.c
+++ b/src/windows/identity/plugins/krb5/krb5identpro.c
@@ -1,1881 +1,1881 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<kherror.h>
-#include<khmsgtypes.h>
-#include<commctrl.h>
-#include<strsafe.h>
-#include<krb5.h>
-#include<assert.h>
-
-#define K5_NCID_UN_LABEL (KHUI_CW_ID_MIN + 0)
-#define K5_NCID_UN (KHUI_CW_ID_MIN + 1)
-#define K5_NCID_REALM_LABEL (KHUI_CW_ID_MIN + 2)
-#define K5_NCID_REALM (KHUI_CW_ID_MIN + 3)
-
-#define NC_UNCHANGE_TIMEOUT 3000
-#define NC_UNCHANGE_TIMER 2
-#define NC_REALMCHANGE_TIMEOUT NC_UNCHANGE_TIMEOUT
-#define NC_REALMCHANGE_TIMER 3
-
-typedef struct tag_k5_new_cred_data {
- HWND hw_username_label;
- HWND hw_username;
- HWND hw_realm_label;
- HWND hw_realm;
-} k5_new_cred_data;
-
-static
-void
-trim_str(wchar_t * s, khm_size cch) {
- wchar_t * c, * last_ws;
-
- for (c = s; *c && iswspace(*c) && ((khm_size)(c - s)) < cch; c++);
-
- if (((khm_size)(c - s)) >= cch)
- return;
-
- if (c != s && ((khm_size)(c - s)) < cch) {
-#if _MSC_VER >= 1400
- wmemmove_s(s, cch, c, cch - ((khm_size)(c - s)));
-#else
- memmove(s, c, (cch - ((khm_size)(c - s))) * sizeof(wchar_t));
-#endif
- }
-
- last_ws = NULL;
- for (c = s; *c && ((khm_size)(c - s)) < cch; c++) {
- if (!iswspace(*c))
- last_ws = NULL;
- else if (last_ws == NULL)
- last_ws = c;
- }
-
- if (last_ws)
- *last_ws = L'\0';
-}
-
-/* Runs in the UI thread */
-int
-k5_get_realm_from_nc(khui_new_creds * nc,
- wchar_t * buf,
- khm_size cch_buf) {
- k5_new_cred_data * d;
- khm_size s;
-
- d = (k5_new_cred_data *) nc->ident_aux;
- buf[0] = L'\0';
- GetWindowText(d->hw_realm, buf, (int) cch_buf);
- trim_str(buf, cch_buf);
-
- StringCchLength(buf, cch_buf, &s);
-
- return (int) s;
-}
-
-/* set the primary identity of a new credentials dialog depending on
- the selection of the username and realm
-
- Runs in the UI thread
-*/
-static void
-set_identity_from_ui(khui_new_creds * nc,
- k5_new_cred_data * d) {
- wchar_t un[KCDB_IDENT_MAXCCH_NAME];
- wchar_t * realm;
- khm_size cch;
- khm_size cch_left;
- khm_handle ident;
- LRESULT idx = CB_ERR;
- khm_int32 rv = KHM_ERROR_SUCCESS;
-
- cch = GetWindowTextLength(d->hw_username);
-
- /* we already set the max length of the edit control to be this.
- shouldn't exceed it unless the edit control is confused. */
- assert(cch < KCDB_IDENT_MAXCCH_NAME - 1);
-
- GetWindowText(d->hw_username, un, ARRAYLENGTH(un));
- trim_str(un, ARRAYLENGTH(un));
-
- realm = khm_get_realm_from_princ(un);
- if (realm) /* realm was specified */
- goto _set_ident;
-
- /* the cch we got from GetWindowTextLength can not be trusted to
- be exact. For caveats see MSDN for GetWindowTextLength. */
- StringCchLength(un, KCDB_IDENT_MAXCCH_NAME, &cch);
-
- if (cch >= KCDB_IDENT_MAXCCH_NAME - 3) {
- /* has to allow space for the '@' and at least a single
- character realm, and the NULL terminator. */
- rv = KHM_ERROR_TOO_LONG;
- goto _set_null_ident;
- }
-
- realm = un + cch; /* now points at terminating NULL */
- cch_left = KCDB_IDENT_MAXCCH_NAME - cch;
-
- *realm++ = L'@';
- *realm = L'\0';
- cch_left--;
-
- cch = GetWindowTextLength(d->hw_realm);
- if (cch == 0 || cch >= cch_left) {
- rv = KHM_ERROR_INVALID_NAME;
- goto _set_null_ident;
- }
-
- GetWindowText(d->hw_realm, realm, (int) cch_left);
- trim_str(realm, cch_left);
-
- _set_ident:
- if (KHM_FAILED(rv = kcdb_identity_create(un,
- KCDB_IDENT_FLAG_CREATE,
- &ident))) {
- goto _set_null_ident;
- }
-
- khui_cw_set_primary_id(nc, ident);
-
- kcdb_identity_release(ident);
- return;
-
- _set_null_ident:
- {
- khui_new_creds_by_type * nct = NULL;
- wchar_t cmsg[256];
-
- khui_cw_find_type(nc, credtype_id_krb5, &nct);
- if (nct && nct->hwnd_panel) {
-
- switch(rv) {
- case KHM_ERROR_TOO_LONG:
- LoadString(hResModule, IDS_NCERR_IDENT_TOO_LONG,
- cmsg, ARRAYLENGTH(cmsg));
- break;
-
- case KHM_ERROR_INVALID_NAME:
- LoadString(hResModule, IDS_NCERR_IDENT_INVALID,
- cmsg, ARRAYLENGTH(cmsg));
- break;
-
- default:
- LoadString(hResModule, IDS_NCERR_IDENT_UNKNOWN,
- cmsg, ARRAYLENGTH(cmsg));
- }
-
- SendMessage(nct->hwnd_panel,
- KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, K5_SET_CRED_MSG),
- (LPARAM) cmsg);
- }
-
- khui_cw_set_primary_id(nc, NULL);
- }
- return;
-}
-
-/* runs in the UI thread */
-static BOOL
-update_crossfeed(khui_new_creds * nc,
- k5_new_cred_data * d,
- int ctrl_id_src) {
- wchar_t un[KCDB_IDENT_MAXCCH_NAME];
- wchar_t * un_realm;
- wchar_t realm[KCDB_IDENT_MAXCCH_NAME];
- khm_size cch;
- khm_size cch_left;
- int idx;
-
- cch = (khm_size) GetWindowTextLength(d->hw_username);
-#ifdef DEBUG
- assert(cch < KCDB_IDENT_MAXCCH_NAME);
-#endif
- if (cch == 0)
- return FALSE;
-
- GetWindowText(d->hw_username,
- un,
- ARRAYLENGTH(un));
- trim_str(un, ARRAYLENGTH(un));
-
- un_realm = khm_get_realm_from_princ(un);
-
- if (un_realm == NULL) {
- EnableWindow(d->hw_realm, TRUE);
- return FALSE;
- }
-
- if (ctrl_id_src == K5_NCID_UN) {
-
- idx = (int)SendMessage(d->hw_realm,
- CB_FINDSTRINGEXACT,
- (WPARAM) -1,
- (LPARAM) un_realm);
-
- if (idx != CB_ERR) {
- wchar_t srealm[KCDB_IDENT_MAXCCH_NAME];
-
- cch = SendMessage(d->hw_realm,
- CB_GETLBTEXTLEN,
- (WPARAM) idx,
- 0);
-
-#ifdef DEBUG
- assert(cch < ARRAYLENGTH(srealm) - 1);
-#endif
- SendMessage(d->hw_realm,
- CB_GETLBTEXT,
- (WPARAM) idx,
- (LPARAM) srealm);
-
- if (!_wcsicmp(srealm, un_realm) && wcscmp(srealm, un_realm)) {
- /* differ only by case */
-
- StringCchCopy(un_realm, ARRAYLENGTH(un) - (un_realm - un),
- srealm);
-
- SetWindowText(d->hw_username, un);
- }
- }
-
- SendMessage(d->hw_realm,
- CB_SELECTSTRING,
- (WPARAM) -1,
- (LPARAM) un_realm);
-
- SetWindowText(d->hw_realm,
- un_realm);
-
- if (GetFocus() == d->hw_realm) {
- HWND hw_next = GetNextDlgTabItem(nc->hwnd, d->hw_realm,
- FALSE);
- if (hw_next)
- SetFocus(hw_next);
- }
-
- EnableWindow(d->hw_realm, FALSE);
-
- return TRUE;
- }
- /* else... */
-
- cch_left = KCDB_IDENT_MAXCCH_NAME - (un_realm - un);
-
- cch = (khm_size) GetWindowTextLength(d->hw_realm);
-
-#ifdef DEBUG
- assert(cch < KCDB_IDENT_MAXCCH_NAME);
-#endif
- if (cch == 0)
- return FALSE;
-
- GetWindowText(d->hw_realm, realm,
- ARRAYLENGTH(realm));
- trim_str(realm, ARRAYLENGTH(realm));
-
- idx = (int)SendMessage(d->hw_realm,
- CB_FINDSTRINGEXACT,
- (WPARAM) -1,
- (LPARAM) realm);
-
- if (idx != CB_ERR) {
- wchar_t srealm[KCDB_IDENT_MAXCCH_NAME];
-
- SendMessage(d->hw_realm,
- CB_GETLBTEXT,
- (WPARAM) idx,
- (LPARAM) srealm);
-
- if (!_wcsicmp(srealm, realm) && wcscmp(srealm, realm)) {
- StringCbCopy(realm, sizeof(realm), srealm);
-
- SetWindowText(d->hw_realm, srealm);
- }
- }
-
- StringCchCopy(un_realm, cch_left, realm);
-
- SendMessage(d->hw_username,
- CB_SELECTSTRING,
- (WPARAM) -1,
- (LPARAM) un);
-
- SetWindowText(d->hw_username, un);
-
- return TRUE;
-}
-
-/* Handle window messages for the identity specifiers
-
- runs in UI thread */
-static LRESULT
-handle_wnd_msg(khui_new_creds * nc,
- HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
- k5_new_cred_data * d;
-
- d = (k5_new_cred_data *) nc->ident_aux;
-
- switch(uMsg) {
- case WM_COMMAND:
- switch(wParam) {
- case MAKEWPARAM(K5_NCID_UN, CBN_EDITCHANGE):
- /* the username has changed. Instead of handling this
- for every keystroke, set a timer that elapses some
- time afterwards and then handle the event. */
- SetTimer(hwnd, NC_UNCHANGE_TIMER,
- NC_UNCHANGE_TIMEOUT, NULL);
- return TRUE;
-
- case MAKEWPARAM(K5_NCID_UN, CBN_KILLFOCUS):
- case MAKEWPARAM(K5_NCID_UN, CBN_CLOSEUP):
- KillTimer(hwnd, NC_UNCHANGE_TIMER);
-
- update_crossfeed(nc,d,K5_NCID_UN);
- set_identity_from_ui(nc,d);
- return TRUE;
-
- case MAKEWPARAM(K5_NCID_REALM,CBN_EDITCHANGE):
- SetTimer(hwnd, NC_REALMCHANGE_TIMER,
- NC_REALMCHANGE_TIMEOUT, NULL);
- return TRUE;
-
- case MAKEWPARAM(K5_NCID_REALM,CBN_KILLFOCUS):
- case MAKEWPARAM(K5_NCID_REALM,CBN_CLOSEUP):
- KillTimer(hwnd, NC_REALMCHANGE_TIMER);
-
- update_crossfeed(nc,d,K5_NCID_REALM);
- set_identity_from_ui(nc, d);
- return TRUE;
- }
- break;
-
- case WM_TIMER:
- if(wParam == NC_UNCHANGE_TIMER) {
- KillTimer(hwnd, NC_UNCHANGE_TIMER);
-
- update_crossfeed(nc, d, K5_NCID_UN);
- set_identity_from_ui(nc,d);
- return TRUE;
- } else if (wParam == NC_REALMCHANGE_TIMER) {
- KillTimer(hwnd, NC_REALMCHANGE_TIMER);
-
- update_crossfeed(nc, d, K5_NCID_REALM);
- set_identity_from_ui(nc, d);
- return TRUE;
- }
- break;
- }
- return FALSE;
-}
-
-/* UI Callback
-
- runs in UI thread */
-static LRESULT KHMAPI
-ui_cb(khui_new_creds * nc,
- UINT cmd,
- HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
-
- k5_new_cred_data * d;
-
- d = (k5_new_cred_data *) nc->ident_aux;
-
- switch(cmd) {
- case WMNC_IDENT_INIT:
- {
- wchar_t defident[KCDB_IDENT_MAXCCH_NAME];
- wchar_t wbuf[1024];
- wchar_t * ms = NULL;
- wchar_t * t;
- wchar_t * defrealm = NULL;
- LRESULT lr;
- khm_size cb_ms;
- khm_size cb;
- HWND hw_parent;
- khm_int32 rv;
- khm_handle hident;
-
- hw_parent = (HWND) lParam;
- defident[0] = L'\0';
-
-#ifdef DEBUG
- assert(d == NULL);
- assert(hw_parent != NULL);
-#endif
-
- d = PMALLOC(sizeof(*d));
- assert(d);
- ZeroMemory(d, sizeof(*d));
-
- khui_cw_lock_nc(nc);
- nc->ident_aux = (LPARAM) d;
- khui_cw_unlock_nc(nc);
-
- LoadString(hResModule, IDS_NC_USERNAME,
- wbuf, ARRAYLENGTH(wbuf));
-
- d->hw_username_label = CreateWindow
- (L"STATIC",
- wbuf,
- SS_SIMPLE | WS_CHILD | WS_VISIBLE,
- 0, 0, 100, 100, /* bogus values */
- hw_parent,
- (HMENU) K5_NCID_UN_LABEL,
- hInstance,
- NULL);
- assert(d->hw_username_label != NULL);
-
- d->hw_username = CreateWindow
- (L"COMBOBOX",
- L"",
- CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT |
- WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL,
- 0, 0, 100, 100, /* bogus values */
- hw_parent,
- (HMENU) K5_NCID_UN,
- hInstance,
- NULL);
- assert(d->hw_username != NULL);
-
- SendMessage(d->hw_username,
- CB_LIMITTEXT,
- (WPARAM)(KCDB_IDENT_MAXCCH_NAME - 1),
- 0);
-
- SendMessage(d->hw_username,
- CB_SETEXTENDEDUI,
- (WPARAM) TRUE,
- 0);
-
- khui_cw_add_control_row(nc,
- d->hw_username_label,
- d->hw_username,
- KHUI_CTRLSIZE_SMALL);
-
- LoadString(hResModule, IDS_NC_REALM,
- wbuf, ARRAYLENGTH(wbuf));
-
- d->hw_realm_label = CreateWindow
- (L"STATIC",
- wbuf,
- SS_SIMPLE | WS_CHILD | WS_VISIBLE,
- 0, 0, 100, 100, /* bogus */
- hw_parent,
- (HMENU) K5_NCID_REALM_LABEL,
- hInstance,
- NULL);
- assert(d->hw_realm_label != NULL);
-
- d->hw_realm = CreateWindow
- (L"COMBOBOX",
- L"",
- CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT |
- WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL,
- 0, 0, 100, 100, /* bogus */
- hw_parent,
- (HMENU) K5_NCID_REALM,
- hInstance,
- NULL);
- assert(d->hw_realm != NULL);
-
- SendMessage(d->hw_realm,
- CB_LIMITTEXT,
- (WPARAM) (KCDB_IDENT_MAXCCH_NAME - 1),
- 0);
-
- SendMessage(d->hw_realm,
- CB_SETEXTENDEDUI,
- (WPARAM) TRUE,
- 0);
-
- khui_cw_add_control_row(nc,
- d->hw_realm_label,
- d->hw_realm,
- KHUI_CTRLSIZE_SMALL);
-
- /* add the LRU realms and principals to the dropdown
- lists */
- rv = khc_read_multi_string(csp_params,
- L"LRUPrincipals",
- NULL,
- &cb_ms);
-
- if (rv != KHM_ERROR_TOO_LONG || cb_ms <= sizeof(wchar_t) * 2)
- goto _add_lru_realms;
-
- ms = PMALLOC(cb_ms);
- assert(ms != NULL);
-
- cb = cb_ms;
- rv = khc_read_multi_string(csp_params,
- L"LRUPrincipals",
- ms,
- &cb);
-
- assert(KHM_SUCCEEDED(rv));
-
- /* the first of these is considered the default identity
- if no other default is known */
- StringCbCopy(defident, sizeof(defident), ms);
-
- t = ms;
- while(t && *t) {
- SendMessage(d->hw_username,
- CB_ADDSTRING,
- 0,
- (LPARAM) t);
-
- t = multi_string_next(t);
- }
-
- _add_lru_realms:
- /* add the default realm first */
- defrealm = khm_krb5_get_default_realm();
- if (defrealm) {
- SendMessage(d->hw_realm,
- CB_ADDSTRING,
- 0,
- (LPARAM) defrealm);
- }
-
- rv = khc_read_multi_string(csp_params,
- L"LRURealms",
- NULL,
- &cb);
-
- if (rv != KHM_ERROR_TOO_LONG)
- goto _done_adding_lru;
-
- if (ms != NULL) {
- if (cb_ms < cb) {
- PFREE(ms);
- ms = PMALLOC(cb);
- assert(ms);
- cb_ms = cb;
- }
- } else {
- ms = PMALLOC(cb);
- cb_ms = cb;
- }
-
- rv = khc_read_multi_string(csp_params,
- L"LRURealms",
- ms,
- &cb);
-
- assert(KHM_SUCCEEDED(rv));
-
- for (t = ms; t && *t; t = multi_string_next(t)) {
- lr = SendMessage(d->hw_realm,
- CB_FINDSTRINGEXACT,
- (WPARAM) -1,
- (LPARAM) t);
- if (lr != CB_ERR)
- continue;
-
- SendMessage(d->hw_realm,
- CB_ADDSTRING,
- 0,
- (LPARAM) t);
- }
- _done_adding_lru:
-
- {
- khm_int32 inc_realms = 0;
-
- if (KHM_FAILED(khc_read_int32(csp_params,
- L"UseFullRealmList",
- &inc_realms)) ||
- !inc_realms)
- goto _done_adding_all_realms;
- }
-
- if(ms)
- PFREE(ms);
-
- ms = khm_krb5_get_realm_list();
- if(ms) {
- for (t = ms; t && *t; t = multi_string_next(t)) {
- lr = SendMessage(d->hw_realm,
- CB_FINDSTRINGEXACT,
- (WPARAM) -1,
- (LPARAM) t);
- if (lr != CB_ERR)
- continue;
-
- SendMessage(d->hw_realm,
- CB_ADDSTRING,
- 0,
- (LPARAM) t);
- }
- }
- _done_adding_all_realms:
-
- /* set the current selection of the realms list */
- if (defrealm) {
- SendMessage(d->hw_realm,
- CB_SELECTSTRING,
- (WPARAM) -1,
- (LPARAM) defrealm);
- } else {
- SendMessage(d->hw_realm,
- CB_SETCURSEL,
- (WPARAM) 0,
- (LPARAM) 0);
- }
-
- if (defrealm)
- PFREE(defrealm);
-
- if (ms)
- PFREE(ms);
-
- /* now see about that default identity */
- if (nc->ctx.identity) {
- cb = sizeof(defident);
- kcdb_identity_get_name(nc->ctx.identity,
- defident,
- &cb);
- }
-
- if (defident[0] == L'\0' &&
- KHM_SUCCEEDED(kcdb_identity_get_default(&hident))) {
- cb = sizeof(defident);
- kcdb_identity_get_name(hident, defident, &cb);
- kcdb_identity_release(hident);
- }
-
- if (defident[0] == L'\0') {
- DWORD dw;
-
- dw = ARRAYLENGTH(defident);
- GetUserName(defident, &dw);
- }
-
- t = khm_get_realm_from_princ(defident);
- if (t) {
- /* there is a realm */
- assert(t != defident);
- *--t = L'\0';
- t++;
-
- SendMessage(d->hw_realm,
- CB_SELECTSTRING,
- (WPARAM) -1,
- (LPARAM) t);
-
- SendMessage(d->hw_realm,
- WM_SETTEXT,
- 0,
- (LPARAM) t);
- }
-
- if (defident[0] != L'\0') {
- /* there is a username */
- SendMessage(d->hw_username,
- CB_SELECTSTRING,
- (WPARAM) -1,
- (LPARAM) defident);
-
- SendMessage(d->hw_username,
- WM_SETTEXT,
- 0,
- (LPARAM) defident);
- }
-
- set_identity_from_ui(nc, d);
- }
- return TRUE;
-
- case WMNC_IDENT_WMSG:
- return handle_wnd_msg(nc, hwnd, uMsg, wParam, lParam);
-
- case WMNC_IDENT_EXIT:
- {
-#ifdef DEBUG
- assert(d != NULL);
-#endif
- khui_cw_lock_nc(nc);
- nc->ident_aux = 0;
- khui_cw_unlock_nc(nc);
-
- /* since we created all the windows as child windows of
- the new creds window, they will be destroyed when that
- window is destroyed. */
- PFREE(d);
- }
- return TRUE;
- }
- return FALSE;
-}
-
-static khm_int32
-k5_ident_validate_name(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam) {
- krb5_principal princ = NULL;
- char princ_name[KCDB_IDENT_MAXCCH_NAME];
- kcdb_ident_name_xfer * nx;
- krb5_error_code code;
- wchar_t * atsign;
-
- nx = (kcdb_ident_name_xfer *) vparam;
-
- if(UnicodeStrToAnsi(princ_name, sizeof(princ_name),
- nx->name_src) == 0) {
- nx->result = KHM_ERROR_INVALID_NAME;
- return KHM_ERROR_SUCCESS;
- }
-
- assert(k5_identpro_ctx != NULL);
-
- code = pkrb5_parse_name(k5_identpro_ctx,
- princ_name,
- &princ);
-
- if (code) {
- nx->result = KHM_ERROR_INVALID_NAME;
- return KHM_ERROR_SUCCESS;
- }
-
- if (princ != NULL)
- pkrb5_free_principal(k5_identpro_ctx,
- princ);
-
- /* krb5_parse_name() accepts principal names with no realm or an
- empty realm. We don't. */
- atsign = wcschr(nx->name_src, L'@');
- if (atsign == NULL || atsign[1] == L'\0') {
- nx->result = KHM_ERROR_INVALID_NAME;
- } else {
- nx->result = KHM_ERROR_SUCCESS;
- }
-
- return KHM_ERROR_SUCCESS;
-}
-
-static void
-k5_update_last_default_identity(khm_handle ident) {
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- khm_size cb;
-
- cb = sizeof(idname);
- if (KHM_FAILED(kcdb_identity_get_name(ident, idname, &cb)))
- return;
-
- assert(csp_params);
-
- khc_write_string(csp_params, L"LastDefaultIdent", idname);
-}
-
-static khm_int32
-k5_ident_set_default_int(khm_handle def_ident) {
- wchar_t id_ccname[KRB5_MAXCCH_CCNAME];
- khm_size cb;
- DWORD dw;
- LONG l;
- HKEY hk_ccname;
- DWORD dwType;
- DWORD dwSize;
- wchar_t reg_ccname[KRB5_MAXCCH_CCNAME];
-
-#ifdef DEBUG
- assert(def_ident != NULL);
-#endif
-
- cb = sizeof(id_ccname);
- if (KHM_FAILED(kcdb_identity_get_attr(def_ident, attr_id_krb5_ccname, NULL,
- id_ccname, &cb))) {
- khm_handle csp_ident = NULL;
- khm_handle csp_k5 = NULL;
-
- _reportf(L"The specified identity does not have the Krb5CCName property");
-
- cb = sizeof(id_ccname);
- if (KHM_SUCCEEDED(kcdb_identity_get_config(def_ident, 0, &csp_ident)) &&
- KHM_SUCCEEDED(khc_open_space(csp_ident, CSNAME_KRB5CRED, 0, &csp_k5)) &&
- KHM_SUCCEEDED(khc_read_string(csp_k5, L"DefaultCCName",
- id_ccname, &cb))) {
-
- _reportf(L"Found CC name in configuration [%s]", id_ccname);
- } else {
- /* last resort, use the name of the identity as the cc
- name */
- cb = sizeof(id_ccname);
- if (KHM_FAILED(kcdb_identity_get_name(def_ident, id_ccname, &cb))) {
- _reportf(L"Can't use name of identity as CCName");
- _end_task();
-
- id_ccname[0] = L'\0';
- }
- }
-
- if (csp_k5)
- khc_close_space(csp_k5);
- if (csp_ident)
- khc_close_space(csp_ident);
-
- if (id_ccname[0] == L'\0')
- return KHM_ERROR_INVALID_PARAM;
- }
-
- khm_krb5_canon_cc_name(id_ccname, sizeof(id_ccname));
-
- _reportf(L"Found Krb5CCName property : %s", id_ccname);
-
- StringCbLength(id_ccname, sizeof(id_ccname), &cb);
- cb += sizeof(wchar_t);
-
- _reportf(L"Setting default CC name in the registry");
-
- l = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\MIT\\kerberos5", 0,
- KEY_READ | KEY_WRITE, &hk_ccname);
-
- if (l != ERROR_SUCCESS)
- l = RegCreateKeyEx(HKEY_CURRENT_USER, L"Software\\MIT\\kerberos5", 0,
- NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE,
- NULL, &hk_ccname, &dw);
-
- if (l != ERROR_SUCCESS) {
- _reportf(L"Can't create registry key : %d", l);
- _end_task();
- return KHM_ERROR_UNKNOWN;
- }
-
- dwSize = sizeof(reg_ccname);
-
- l = RegQueryValueEx(hk_ccname, L"ccname", NULL, &dwType, (LPBYTE) reg_ccname,
- &dwSize);
-
- if (l != ERROR_SUCCESS ||
- dwType != REG_SZ ||
- khm_krb5_cc_name_cmp(reg_ccname, id_ccname)) {
-
- /* we have to write the new value in */
-
- l = RegSetValueEx(hk_ccname, L"ccname", 0, REG_SZ, (BYTE *) id_ccname,
- (DWORD) cb);
- }
-
- RegCloseKey(hk_ccname);
-
- if (l == ERROR_SUCCESS) {
- _reportf(L"Successfully set the default ccache");
- k5_update_last_default_identity(def_ident);
- return KHM_ERROR_SUCCESS;
- } else {
- _reportf(L"Can't set the registry value : %d", l);
- return KHM_ERROR_UNKNOWN;
- }
-}
-
-static khm_int32
-k5_ident_set_default(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam) {
-
- /*
- Currently, setting the default identity simply sets the
- "ccname" registry value at "Software\MIT\kerberos5".
- */
-
- if (uparam) {
- /* an identity is being made default */
- khm_handle def_ident = (khm_handle) vparam;
- khm_int32 rv;
-
-#ifdef DEBUG
- assert(def_ident != NULL);
-#endif
-
- {
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- khm_size cb;
-
- cb = sizeof(idname);
- kcdb_identity_get_name(def_ident, idname, &cb);
-
- _begin_task(0);
- _report_cs1(KHERR_DEBUG_1, L"Setting default identity [%1!s!]", _cstr(idname));
- _describe();
- }
-
- rv = k5_ident_set_default_int(def_ident);
-
- _end_task();
-
- return rv;
-
- } else {
- /* the default identity is being forgotten */
-
- /* we don't really do anything about this case */
- }
-
- return KHM_ERROR_SUCCESS;
-}
-
-static khm_int32
-k5_ident_get_ui_cb(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam) {
- khui_ident_new_creds_cb * cb;
-
- cb = (khui_ident_new_creds_cb *) vparam;
-
- *cb = ui_cb;
-
- return KHM_ERROR_SUCCESS;
-}
-
-static khm_int32
-k5_ident_notify_create(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam) {
-
- /* a new identity has been created. What we want to do at
- this point is to check if the identity belongs to krb5
- and to see if it is the default. */
-
- krb5_ccache cc = NULL;
- krb5_error_code code;
- krb5_principal princ = NULL;
- char * princ_nameA = NULL;
- wchar_t princ_nameW[KCDB_IDENT_MAXCCH_NAME];
- wchar_t id_nameW[KCDB_IDENT_MAXCCH_NAME];
- khm_size cb;
- khm_handle ident;
-
- /* if there is a default identity already, we assume we don't need
- to check this one. */
-
- khm_handle def_ident;
-
- if (KHM_SUCCEEDED(kcdb_identity_get_default(&def_ident))) {
- kcdb_identity_release(def_ident);
-
- return KHM_ERROR_SUCCESS;
- }
-
- ident = (khm_handle) vparam;
-
- assert(k5_identpro_ctx != NULL);
-
- code = pkrb5_cc_default(k5_identpro_ctx, &cc);
- if (code)
- goto _nc_cleanup;
-
- code = pkrb5_cc_get_principal(k5_identpro_ctx,
- cc,
- &princ);
- if (code)
- goto _nc_cleanup;
-
- code = pkrb5_unparse_name(k5_identpro_ctx,
- princ,
- &princ_nameA);
- if (code)
- goto _nc_cleanup;
-
- AnsiStrToUnicode(princ_nameW,
- sizeof(princ_nameW),
- princ_nameA);
-
- cb = sizeof(id_nameW);
-
- if (KHM_FAILED(kcdb_identity_get_name(ident,
- id_nameW,
- &cb)))
- goto _nc_cleanup;
-
- if (!wcscmp(id_nameW, princ_nameW)) {
- kcdb_identity_set_default_int(ident);
- }
-
- _nc_cleanup:
- if (princ_nameA)
- pkrb5_free_unparsed_name(k5_identpro_ctx,
- princ_nameA);
- if (princ)
- pkrb5_free_principal(k5_identpro_ctx,
- princ);
- if (cc)
- pkrb5_cc_close(k5_identpro_ctx, cc);
-
- return KHM_ERROR_SUCCESS;
-}
-
-struct k5_ident_update_data {
- khm_handle identity;
-
- FILETIME ft_expire; /* expiration */
- FILETIME ft_issue; /* issue */
- FILETIME ft_rexpire; /* renew expiration */
- wchar_t ccname[KRB5_MAXCCH_CCNAME];
- khm_int32 k5_flags;
-};
-
-/* The logic here has to reflect the logic in khm_krb5_list_tickets().
- We use this to handle an identity update request because some other
- plug-in or maybe NetIDMgr itself is about to do something
- important(tm) with the identity and needs to make sure that the
- properties of the identity are up-to-date. */
-static khm_int32 KHMAPI
-k5_ident_update_apply_proc(khm_handle cred,
- void * rock) {
- struct k5_ident_update_data * d = (struct k5_ident_update_data *) rock;
- khm_handle ident = NULL;
- khm_int32 t;
- khm_int32 flags;
- FILETIME t_cexpire;
- FILETIME t_rexpire;
- khm_size cb;
- khm_int32 rv = KHM_ERROR_SUCCESS;
-
- if (KHM_FAILED(kcdb_cred_get_type(cred, &t)) ||
- t != credtype_id_krb5 ||
- KHM_FAILED(kcdb_cred_get_identity(cred, &ident)))
-
- return KHM_ERROR_SUCCESS;
-
- if (!kcdb_identity_is_equal(ident,d->identity))
-
- goto _cleanup;
-
- if (KHM_FAILED(kcdb_cred_get_flags(cred, &flags)))
-
- flags = 0;
-
- if (flags & KCDB_CRED_FLAG_INITIAL) {
- cb = sizeof(t_cexpire);
- if (KHM_SUCCEEDED(kcdb_cred_get_attr(cred,
- KCDB_ATTR_EXPIRE,
- NULL,
- &t_cexpire,
- &cb))) {
- if ((d->ft_expire.dwLowDateTime == 0 &&
- d->ft_expire.dwHighDateTime == 0) ||
- CompareFileTime(&t_cexpire, &d->ft_expire) > 0) {
- goto update_identity;
- }
- }
- }
-
- goto _cleanup;
-
- update_identity:
-
- d->ft_expire = t_cexpire;
-
- cb = sizeof(d->ccname);
- if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_LOCATION, NULL, d->ccname, &cb))) {
- d->ccname[0] = L'\0';
- }
-
- cb = sizeof(d->k5_flags);
- if (KHM_FAILED(kcdb_cred_get_attr(cred, attr_id_krb5_flags, NULL,
- &d->k5_flags, &cb))) {
- d->k5_flags = 0;
- }
-
- cb = sizeof(d->ft_issue);
- if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_ISSUE, NULL, &d->ft_issue, &cb))) {
- ZeroMemory(&d->ft_issue, sizeof(d->ft_issue));
- }
-
- cb = sizeof(t_rexpire);
- if ((d->k5_flags & TKT_FLG_RENEWABLE) &&
- KHM_SUCCEEDED(kcdb_cred_get_attr(cred,
- KCDB_ATTR_RENEW_EXPIRE,
- NULL,
- &t_rexpire,
- &cb))) {
- d->ft_rexpire = t_rexpire;
- } else {
- ZeroMemory(&d->ft_rexpire, sizeof(d->ft_rexpire));
- }
-
- _cleanup:
- if (ident)
- kcdb_identity_release(ident);
-
- return rv;
-}
-
-static khm_int32
-k5_ident_update(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam) {
-
-#if 0
- struct k5_ident_update_data d;
-#endif
- khm_handle ident;
- khm_handle tident;
- krb5_ccache cc = NULL;
- char * ccname;
- krb5_error_code code;
- khm_size cb;
- wchar_t wid_ccname[MAX_PATH];
- wchar_t w_ccname[MAX_PATH];
-
- ident = (khm_handle) vparam;
- if (ident == NULL)
- return KHM_ERROR_SUCCESS;
-
-#if 0
- /* we are going to skip doing this here since
- khm_krb5_list_tickets() performs this function for us each time
- we enumerate tickets. Since it also gets run each time our
- list of tickets changes and since we are basing this operation
- on existing tickets, we are unlikely to find anything new
- here. */
- ZeroMemory(&d, sizeof(d));
- d.identity = ident;
-
- kcdb_credset_apply(NULL,
- k5_ident_update_apply_proc,
- (void *) &d);
-
- if (d.ft_expire.dwLowDateTime != 0 ||
- d.ft_expire.dwHighDateTime != 0) {
-
- /* we found a TGT */
-
- kcdb_identity_set_attr(ident, KCDB_ATTR_EXPIRE,
- &d.ft_expire, sizeof(d.ft_expire));
- if (d.ft_issue.dwLowDateTime != 0 ||
- d.ft_issue.dwHighDateTime != 0)
- kcdb_identity_set_attr(ident, KCDB_ATTR_ISSUE,
- &d.ft_issue, sizeof(d.ft_issue));
- else
- kcdb_identity_set_attr(ident, KCDB_ATTR_ISSUE, NULL, 0);
-
- if (d.ft_rexpire.dwLowDateTime != 0 ||
- d.ft_rexpire.dwHighDateTime != 0)
- kcdb_identity_set_attr(ident, KCDB_ATTR_RENEW_EXPIRE,
- &d.ft_rexpire, sizeof(d.ft_rexpire));
- else
- kcdb_identity_set_attr(ident, KCDB_ATTR_RENEW_EXPIRE, NULL, 0);
-
- kcdb_identity_set_attr(ident, attr_id_krb5_flags,
- &d.k5_flags, sizeof(d.k5_flags));
-
- if (d.ccname[0])
- kcdb_identity_set_attr(ident, attr_id_krb5_ccname,
- d.ccname, KCDB_CBSIZE_AUTO);
- else
- kcdb_identity_set_attr(ident, attr_id_krb5_ccname, NULL, 0);
-
- } else {
- /* Clear out the attributes. We don't have any information
- about this identity */
- kcdb_identity_set_attr(ident, KCDB_ATTR_EXPIRE, NULL, 0);
- kcdb_identity_set_attr(ident, KCDB_ATTR_ISSUE, NULL, 0);
- kcdb_identity_set_attr(ident, KCDB_ATTR_RENEW_EXPIRE, NULL, 0);
- kcdb_identity_set_attr(ident, attr_id_krb5_flags, NULL, 0);
- kcdb_identity_set_attr(ident, attr_id_krb5_ccname, NULL, 0);
- }
-#endif
-
- if (KHM_SUCCEEDED(kcdb_identity_get_default(&tident))) {
- kcdb_identity_release(tident);
- goto _iu_cleanup;
- }
-
- cb = sizeof(wid_ccname);
- if (KHM_FAILED(kcdb_identity_get_attr(ident,
- attr_id_krb5_ccname,
- NULL,
- wid_ccname,
- &cb)))
- goto _iu_cleanup;
-
- if(k5_identpro_ctx == NULL)
- goto _iu_cleanup;
-
- code = pkrb5_cc_default(k5_identpro_ctx, &cc);
- if (code)
- goto _iu_cleanup;
-
- ccname = pkrb5_cc_get_name(k5_identpro_ctx, cc);
- if (ccname == NULL)
- goto _iu_cleanup;
-
- AnsiStrToUnicode(w_ccname, sizeof(w_ccname), ccname);
-
- khm_krb5_canon_cc_name(w_ccname, sizeof(w_ccname));
- khm_krb5_canon_cc_name(wid_ccname, sizeof(wid_ccname));
-
- if (!_wcsicmp(w_ccname, wid_ccname))
- kcdb_identity_set_default_int(ident);
-
- _iu_cleanup:
- if (cc && k5_identpro_ctx)
- pkrb5_cc_close(k5_identpro_ctx, cc);
-
- return KHM_ERROR_SUCCESS;
-}
-
-static khm_boolean
-k5_refresh_default_identity(krb5_context ctx) {
- /* just like notify_create, except now we set the default identity
- based on what we find in the configuration */
- krb5_ccache cc = NULL;
- krb5_error_code code;
- krb5_principal princ = NULL;
- char * princ_nameA = NULL;
- wchar_t princ_nameW[KCDB_IDENT_MAXCCH_NAME];
- char * ccname = NULL;
- khm_handle ident = NULL;
- khm_boolean found_default = FALSE;
-
- assert(ctx != NULL);
-
- _begin_task(0);
- _report_cs0(KHERR_DEBUG_1, L"Refreshing default identity");
- _describe();
-
- code = pkrb5_cc_default(ctx, &cc);
- if (code) {
- _reportf(L"Can't open default ccache. code=%d", code);
- goto _nc_cleanup;
- }
-
- code = pkrb5_cc_get_principal(ctx, cc, &princ);
- if (code) {
- /* try to determine the identity from the ccache name */
- ccname = pkrb5_cc_get_name(ctx, cc);
-
- if (ccname) {
- char * namepart = strchr(ccname, ':');
-
- _reportf(L"CC name is [%S]", ccname);
-
- if (namepart == NULL)
- namepart = ccname;
- else
- namepart++;
-
- _reportf(L"Checking if [%S] is a valid identity name", namepart);
-
- AnsiStrToUnicode(princ_nameW, sizeof(princ_nameW), namepart);
- if (kcdb_identity_is_valid_name(princ_nameW)) {
- kcdb_identity_create(princ_nameW, KCDB_IDENT_FLAG_CREATE, &ident);
- if (ident) {
- _reportf(L"Setting [%S] as the default identity", namepart);
- kcdb_identity_set_default_int(ident);
- found_default = TRUE;
- }
- }
- } else {
- _reportf(L"Can't determine ccache name");
- }
-
- goto _nc_cleanup;
- }
-
- code = pkrb5_unparse_name(ctx, princ, &princ_nameA);
- if (code)
- goto _nc_cleanup;
-
- AnsiStrToUnicode(princ_nameW, sizeof(princ_nameW), princ_nameA);
-
- _reportf(L"Found principal [%s]", princ_nameW);
-
- if (KHM_FAILED(kcdb_identity_create(princ_nameW, KCDB_IDENT_FLAG_CREATE, &ident))) {
- _reportf(L"Failed to create identity");
- goto _nc_cleanup;
- }
-
- _reportf(L"Setting default identity to [%s]", princ_nameW);
- kcdb_identity_set_default_int(ident);
-
- found_default = TRUE;
-
- _nc_cleanup:
-
- _end_task();
-
- if (princ_nameA)
- pkrb5_free_unparsed_name(ctx, princ_nameA);
-
- if (princ)
- pkrb5_free_principal(ctx, princ);
-
- if (cc)
- pkrb5_cc_close(ctx, cc);
-
- if (ident)
- kcdb_identity_release(ident);
-
- return found_default;
-}
-
-static khm_int32
-k5_ident_init(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam) {
-
- khm_boolean found_default;
- khm_handle ident;
-
- found_default = k5_refresh_default_identity(k5_identpro_ctx);
-
- if (!found_default) {
- wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
- khm_size cb;
-
- cb = sizeof(widname);
-
- assert(csp_params);
-
- if (KHM_SUCCEEDED(khc_read_string(csp_params, L"LastDefaultIdent",
- widname, &cb))) {
- ident = NULL;
- kcdb_identity_create(widname, KCDB_IDENT_FLAG_CREATE, &ident);
- if (ident) {
- kcdb_identity_set_default_int(ident);
- kcdb_identity_release(ident);
-
- found_default = TRUE;
- }
- }
- }
-
- if (!found_default) {
-
- /* There was no default ccache and we don't have a
- "LastDefaultIdent" value. Next we see if there are any
- identities that have credentials which have a Krb5CCName
- property (i.e. an identity that has a Kerberos 5 TGT), and
- make it the default.
-
- Note that since the Krb5Ident plug-in has a dependency on
- Krb5Cred, by the time this code runs, we already have a
- listing of Kerberos 5 tickets and identities. */
-
- wchar_t * idlist = NULL;
- wchar_t * thisid;
- khm_size cb = 0;
- khm_size n_idents = 0;
- khm_int32 rv;
- wchar_t ccname[KRB5_MAXCCH_CCNAME];
- FILETIME ft_expire;
- FILETIME ft_now;
- FILETIME ft_threshold;
- BOOL match_all = FALSE;
-
- rv = kcdb_identity_enum(0, 0, NULL, &cb, &n_idents);
-
- TimetToFileTimeInterval(5 * 60, &ft_threshold);
- GetSystemTimeAsFileTime(&ft_now);
- ft_now = FtAdd(&ft_now, &ft_threshold);
-
- while (rv == KHM_ERROR_TOO_LONG && n_idents > 0) {
- if (idlist) {
- PFREE(idlist);
- idlist = NULL;
- }
-
- idlist = PMALLOC(cb);
-
- if (idlist == NULL)
- break;
-
- rv = kcdb_identity_enum(0, 0, idlist, &cb, &n_idents);
- }
-
- if (KHM_SUCCEEDED(rv)) {
-
- /* first we try to find an identity that has a valid TGT.
- If that fails, then we try to find an identity with
- *any* TGT. */
-
- try_again:
-
- for (thisid = idlist;
- thisid && *thisid && !found_default;
- thisid = multi_string_next(thisid)) {
-
- if (KHM_SUCCEEDED(kcdb_identity_create(thisid, 0, &ident))) {
- khm_size cb_ft = sizeof(FILETIME);
- cb = sizeof(ccname);
-
- if (KHM_SUCCEEDED(kcdb_identity_get_attr(ident, attr_id_krb5_ccname,
- NULL, ccname, &cb)) &&
- (match_all ||
- (KHM_SUCCEEDED(kcdb_identity_get_attr(ident, KCDB_ATTR_EXPIRE,
- NULL, &ft_expire, &cb_ft)) &&
- CompareFileTime(&ft_expire, &ft_now) > 0))) {
-
- /* found one */
- k5_ident_set_default_int(ident);
- kcdb_identity_set_default_int(ident);
- found_default = TRUE;
-
- }
-
- kcdb_identity_release(ident);
- ident = NULL;
- }
- }
-
- if (!found_default && !match_all) {
- match_all = TRUE;
- goto try_again;
- }
- }
-
- if (idlist) {
- PFREE(idlist);
- idlist = NULL;
- }
- }
-
- return KHM_ERROR_SUCCESS;
-}
-
-static khm_int32
-k5_ident_exit(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam) {
- /* don't really do anything */
- return KHM_ERROR_SUCCESS;
-}
-
-/* forward dcl */
-khm_int32 KHMAPI
-k5_ident_name_comp_func(const void * dl, khm_size cb_dl,
- const void * dr, khm_size cb_dr);
-
-static khm_int32
-k5_ident_compare_name(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam) {
- kcdb_ident_name_xfer *px;
-
- px = (kcdb_ident_name_xfer *) vparam;
-
- /* note that k5_ident_name_comp_func() ignores the size
- specifiers. So we can just pass in 0's. */
- px->result = k5_ident_name_comp_func(px->name_src, 0,
- px->name_alt, 0);
-
- return KHM_ERROR_SUCCESS;
-}
-
-#if 0
-/* copy and paste template for ident provider messages */
-static khm_int32
-k5_ident_(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam) {
-}
-#endif
-
-khm_int32 KHMAPI
-k5_msg_ident(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam)
-{
- switch(msg_subtype) {
- case KMSG_IDENT_INIT:
- return k5_ident_init(msg_type,
- msg_subtype,
- uparam,
- vparam);
-
- case KMSG_IDENT_EXIT:
- return k5_ident_exit(msg_type,
- msg_subtype,
- uparam,
- vparam);
-
- case KMSG_IDENT_VALIDATE_NAME:
- return k5_ident_validate_name(msg_type,
- msg_subtype,
- uparam,
- vparam);
-
- case KMSG_IDENT_VALIDATE_IDENTITY:
- /* TODO: handle KMSG_IDENT_VALIDATE_IDENTITY */
- break;
-
- case KMSG_IDENT_CANON_NAME:
- /* TODO: handle KMSG_IDENT_CANON_NAME */
- break;
-
- case KMSG_IDENT_COMPARE_NAME:
- return k5_ident_compare_name(msg_type,
- msg_subtype,
- uparam,
- vparam);
-
- case KMSG_IDENT_SET_DEFAULT:
- return k5_ident_set_default(msg_type,
- msg_subtype,
- uparam,
- vparam);
-
- case KMSG_IDENT_SET_SEARCHABLE:
- /* TODO: handle KMSG_IDENT_SET_SEARCHABLE */
- break;
-
- case KMSG_IDENT_GET_INFO:
- /* TODO: handle KMSG_IDENT_GET_INFO */
- break;
-
- case KMSG_IDENT_UPDATE:
- return k5_ident_update(msg_type,
- msg_subtype,
- uparam,
- vparam);
-
- case KMSG_IDENT_ENUM_KNOWN:
- /* TODO: handle KMSG_IDENT_ENUM_KNOWN */
- break;
-
- case KMSG_IDENT_GET_UI_CALLBACK:
- return k5_ident_get_ui_cb(msg_type,
- msg_subtype,
- uparam,
- vparam);
-
- case KMSG_IDENT_NOTIFY_CREATE:
- return k5_ident_notify_create(msg_type,
- msg_subtype,
- uparam,
- vparam);
- }
-
- return KHM_ERROR_SUCCESS;
-}
-
-/* note that we are ignoring the size specifiers. We can do that
- because we are guaranteed that dl and dr point to NULL terminated
- unicode strings when used with credential data buffers. We also
- use the fact that we are ignoring the size specifiers when we call
- this function from k5_ident_compare_name() to avoid calculating the
- length of the string. */
-khm_int32 KHMAPI
-k5_ident_name_comp_func(const void * dl, khm_size cb_dl,
- const void * dr, khm_size cb_dr) {
- wchar_t * idl = (wchar_t *) dl;
- wchar_t * idr = (wchar_t *) dr;
- wchar_t * rl;
- wchar_t * rr;
- khm_int32 r;
-
- rl = khm_get_realm_from_princ(idl);
- rr = khm_get_realm_from_princ(idr);
-
- if (rl == NULL && rr == NULL)
- return wcscmp(idl, idr);
- else if (rl == NULL)
- return 1;
- else if (rr == NULL)
- return -1;
-
- r = wcscmp(rl, rr);
- if (r == 0)
- return wcscmp(idl, idr);
- else
- return r;
-}
-
-
-/* Identity change notification thread */
-
-HANDLE h_ccname_exit_event;
-HANDLE h_ccname_thread;
-
-DWORD WINAPI k5_ccname_monitor_thread(LPVOID lpParameter) {
- krb5_context ctx = 0;
-
- HKEY hk_ccname;
- HANDLE h_notify;
- HANDLE h_waits[2];
-
- khm_int32 rv = KHM_ERROR_SUCCESS;
- DWORD dwType;
- DWORD dwSize;
- DWORD dwDisp;
- wchar_t reg_ccname[KRB5_MAXCCH_CCNAME];
- LONG l;
-
- PDESCTHREAD(L"Krb5 CCName Monitor", L"Krb5");
-
- l = RegOpenKeyEx(HKEY_CURRENT_USER,
- L"Software\\MIT\\kerberos5",
- 0,
- KEY_READ | KEY_WRITE,
- &hk_ccname);
-
- if (l != ERROR_SUCCESS)
- l = RegCreateKeyEx(HKEY_CURRENT_USER,
- L"Software\\MIT\\kerberos5",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_READ | KEY_WRITE,
- NULL,
- &hk_ccname,
- &dwDisp);
-
- if (l != ERROR_SUCCESS) {
- rv = KHM_ERROR_UNKNOWN;
- goto _exit;
- }
-
- dwSize = sizeof(reg_ccname);
-
- l = RegQueryValueEx(hk_ccname,
- L"ccname",
- NULL,
- &dwType,
- (LPBYTE) reg_ccname,
- &dwSize);
-
- if (l != ERROR_SUCCESS ||
- dwType != REG_SZ) {
-
- reg_ccname[0] = L'\0';
- }
-
- l = pkrb5_init_context(&ctx);
-
- if (l)
- goto _exit_0;
-
- h_notify = CreateEvent(NULL, FALSE, FALSE, L"Local\\Krb5CCNameChangeNotifier");
-
- if (h_notify == NULL)
- goto _exit_0;
-
- /* begin wait loop */
-
- h_waits[0] = h_ccname_exit_event;
- h_waits[1] = h_notify;
-
- do {
- DWORD dwrv;
-
- l = RegNotifyChangeKeyValue(hk_ccname, FALSE,
- REG_NOTIFY_CHANGE_LAST_SET,
- h_notify, TRUE);
-
- if (l != ERROR_SUCCESS) {
- rv = KHM_ERROR_UNKNOWN;
- break;
- }
-
- dwrv = WaitForMultipleObjects(2, h_waits, FALSE, INFINITE);
-
- if (dwrv == WAIT_OBJECT_0) {
- /* exit! */
- break;
-
- } else if (dwrv == WAIT_OBJECT_0 + 1) {
- /* change notify! */
- wchar_t new_ccname[KRB5_MAXCCH_CCNAME];
-
- dwSize = sizeof(new_ccname);
-
- l = RegQueryValueEx(hk_ccname,
- L"ccname",
- NULL,
- &dwType,
- (LPBYTE) new_ccname,
- &dwSize);
-
- if (l != ERROR_SUCCESS ||
- dwType != REG_SZ) {
- new_ccname[0] = L'\0';
- }
-
- if (_wcsicmp(new_ccname, reg_ccname)) {
- k5_refresh_default_identity(ctx);
- StringCbCopy(reg_ccname, sizeof(reg_ccname), new_ccname);
- }
-
- } else {
- /* something went wrong */
- rv = KHM_ERROR_UNKNOWN;
- break;
- }
-
- } while (TRUE);
-
- CloseHandle(h_notify);
-
- _exit_0:
-
- RegCloseKey(hk_ccname);
-
- if (ctx)
- pkrb5_free_context(ctx);
-
- _exit:
- ExitThread(rv);
-
- /* not reached */
- return rv;
-}
-
-khm_int32
-k5_msg_system_idpro(khm_int32 msg_type, khm_int32 msg_subtype,
- khm_ui_4 uparam, void * vparam) {
-
- switch(msg_subtype) {
- case KMSG_SYSTEM_INIT:
- {
-
- pkrb5_init_context(&k5_identpro_ctx);
- kcdb_identity_set_type(credtype_id_krb5);
-
- if (KHM_FAILED(kcdb_type_get_id(TYPENAME_KRB5_PRINC,
- &type_id_krb5_princ))) {
- kcdb_type dt;
- kcdb_type * pstr;
-
- kcdb_type_get_info(KCDB_TYPE_STRING, &pstr);
-
- ZeroMemory(&dt, sizeof(dt));
- dt.name = TYPENAME_KRB5_PRINC;
- dt.id = KCDB_TYPE_INVALID;
- dt.flags = KCDB_TYPE_FLAG_CB_AUTO;
- dt.cb_min = pstr->cb_min;
- dt.cb_max = pstr->cb_max;
- dt.toString = pstr->toString;
- dt.isValid = pstr->isValid;
- dt.comp = k5_ident_name_comp_func;
- dt.dup = pstr->dup;
-
- kcdb_type_register(&dt, &type_id_krb5_princ);
-
- type_regd_krb5_princ = TRUE;
-
- kcdb_type_release_info(pstr);
- }
-
- if (type_id_krb5_princ != -1) {
- kcdb_attrib * attr;
-
- kcdb_attrib_get_info(KCDB_ATTR_ID_NAME, &attr);
-
- attr->type = type_id_krb5_princ;
-
- kcdb_attrib_release_info(attr);
- }
-
- h_ccname_exit_event = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (h_ccname_exit_event) {
- h_ccname_thread = CreateThread(NULL,
- 200 * 1024,
- k5_ccname_monitor_thread,
- NULL,
- 0,
- NULL);
- } else {
- h_ccname_thread = NULL;
- }
- }
- break;
-
- case KMSG_SYSTEM_EXIT:
- {
-
- if (h_ccname_thread) {
- SetEvent(h_ccname_exit_event);
- WaitForSingleObject(h_ccname_thread, INFINITE);
- CloseHandle(h_ccname_thread);
- CloseHandle(h_ccname_exit_event);
-
- h_ccname_exit_event = NULL;
- h_ccname_thread = NULL;
- }
-
- if (k5_identpro_ctx) {
- pkrb5_free_context(k5_identpro_ctx);
- k5_identpro_ctx = NULL;
- }
-
- if (type_id_krb5_princ != -1) {
- kcdb_attrib * attr;
-
- kcdb_attrib_get_info(KCDB_ATTR_ID_NAME, &attr);
-
- attr->type = KCDB_TYPE_STRING;
-
- kcdb_attrib_release_info(attr);
- }
-
- /* allow a brief moment for any stale references to die */
- Sleep(100);
-
- if (type_regd_krb5_princ) {
- kcdb_type_unregister(type_id_krb5_princ);
- }
- }
- break;
- }
-
- return KHM_ERROR_SUCCESS;
-}
-
-khm_int32 KHMAPI
-k5_ident_callback(khm_int32 msg_type, khm_int32 msg_subtype,
- khm_ui_4 uparam, void * vparam) {
- switch(msg_type) {
- case KMSG_SYSTEM:
- return k5_msg_system_idpro(msg_type, msg_subtype, uparam, vparam);
-
- case KMSG_IDENT:
- return k5_msg_ident(msg_type, msg_subtype, uparam, vparam);
- }
-
- return KHM_ERROR_SUCCESS;
-}
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<kherror.h>
+#include<khmsgtypes.h>
+#include<commctrl.h>
+#include<strsafe.h>
+#include<krb5.h>
+#include<assert.h>
+
+#define K5_NCID_UN_LABEL (KHUI_CW_ID_MIN + 0)
+#define K5_NCID_UN (KHUI_CW_ID_MIN + 1)
+#define K5_NCID_REALM_LABEL (KHUI_CW_ID_MIN + 2)
+#define K5_NCID_REALM (KHUI_CW_ID_MIN + 3)
+
+#define NC_UNCHANGE_TIMEOUT 3000
+#define NC_UNCHANGE_TIMER 2
+#define NC_REALMCHANGE_TIMEOUT NC_UNCHANGE_TIMEOUT
+#define NC_REALMCHANGE_TIMER 3
+
+typedef struct tag_k5_new_cred_data {
+ HWND hw_username_label;
+ HWND hw_username;
+ HWND hw_realm_label;
+ HWND hw_realm;
+} k5_new_cred_data;
+
+static
+void
+trim_str(wchar_t * s, khm_size cch) {
+ wchar_t * c, * last_ws;
+
+ for (c = s; *c && iswspace(*c) && ((khm_size)(c - s)) < cch; c++);
+
+ if (((khm_size)(c - s)) >= cch)
+ return;
+
+ if (c != s && ((khm_size)(c - s)) < cch) {
+#if _MSC_VER >= 1400
+ wmemmove_s(s, cch, c, cch - ((khm_size)(c - s)));
+#else
+ memmove(s, c, (cch - ((khm_size)(c - s))) * sizeof(wchar_t));
+#endif
+ }
+
+ last_ws = NULL;
+ for (c = s; *c && ((khm_size)(c - s)) < cch; c++) {
+ if (!iswspace(*c))
+ last_ws = NULL;
+ else if (last_ws == NULL)
+ last_ws = c;
+ }
+
+ if (last_ws)
+ *last_ws = L'\0';
+}
+
+/* Runs in the UI thread */
+int
+k5_get_realm_from_nc(khui_new_creds * nc,
+ wchar_t * buf,
+ khm_size cch_buf) {
+ k5_new_cred_data * d;
+ khm_size s;
+
+ d = (k5_new_cred_data *) nc->ident_aux;
+ buf[0] = L'\0';
+ GetWindowText(d->hw_realm, buf, (int) cch_buf);
+ trim_str(buf, cch_buf);
+
+ StringCchLength(buf, cch_buf, &s);
+
+ return (int) s;
+}
+
+/* set the primary identity of a new credentials dialog depending on
+ the selection of the username and realm
+
+ Runs in the UI thread
+*/
+static void
+set_identity_from_ui(khui_new_creds * nc,
+ k5_new_cred_data * d) {
+ wchar_t un[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t * realm;
+ khm_size cch;
+ khm_size cch_left;
+ khm_handle ident;
+ LRESULT idx = CB_ERR;
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+
+ cch = GetWindowTextLength(d->hw_username);
+
+ /* we already set the max length of the edit control to be this.
+ shouldn't exceed it unless the edit control is confused. */
+ assert(cch < KCDB_IDENT_MAXCCH_NAME - 1);
+
+ GetWindowText(d->hw_username, un, ARRAYLENGTH(un));
+ trim_str(un, ARRAYLENGTH(un));
+
+ realm = khm_get_realm_from_princ(un);
+ if (realm) /* realm was specified */
+ goto _set_ident;
+
+ /* the cch we got from GetWindowTextLength can not be trusted to
+ be exact. For caveats see MSDN for GetWindowTextLength. */
+ StringCchLength(un, KCDB_IDENT_MAXCCH_NAME, &cch);
+
+ if (cch >= KCDB_IDENT_MAXCCH_NAME - 3) {
+ /* has to allow space for the '@' and at least a single
+ character realm, and the NULL terminator. */
+ rv = KHM_ERROR_TOO_LONG;
+ goto _set_null_ident;
+ }
+
+ realm = un + cch; /* now points at terminating NULL */
+ cch_left = KCDB_IDENT_MAXCCH_NAME - cch;
+
+ *realm++ = L'@';
+ *realm = L'\0';
+ cch_left--;
+
+ cch = GetWindowTextLength(d->hw_realm);
+ if (cch == 0 || cch >= cch_left) {
+ rv = KHM_ERROR_INVALID_NAME;
+ goto _set_null_ident;
+ }
+
+ GetWindowText(d->hw_realm, realm, (int) cch_left);
+ trim_str(realm, cch_left);
+
+ _set_ident:
+ if (KHM_FAILED(rv = kcdb_identity_create(un,
+ KCDB_IDENT_FLAG_CREATE,
+ &ident))) {
+ goto _set_null_ident;
+ }
+
+ khui_cw_set_primary_id(nc, ident);
+
+ kcdb_identity_release(ident);
+ return;
+
+ _set_null_ident:
+ {
+ khui_new_creds_by_type * nct = NULL;
+ wchar_t cmsg[256];
+
+ khui_cw_find_type(nc, credtype_id_krb5, &nct);
+ if (nct && nct->hwnd_panel) {
+
+ switch(rv) {
+ case KHM_ERROR_TOO_LONG:
+ LoadString(hResModule, IDS_NCERR_IDENT_TOO_LONG,
+ cmsg, ARRAYLENGTH(cmsg));
+ break;
+
+ case KHM_ERROR_INVALID_NAME:
+ LoadString(hResModule, IDS_NCERR_IDENT_INVALID,
+ cmsg, ARRAYLENGTH(cmsg));
+ break;
+
+ default:
+ LoadString(hResModule, IDS_NCERR_IDENT_UNKNOWN,
+ cmsg, ARRAYLENGTH(cmsg));
+ }
+
+ SendMessage(nct->hwnd_panel,
+ KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, K5_SET_CRED_MSG),
+ (LPARAM) cmsg);
+ }
+
+ khui_cw_set_primary_id(nc, NULL);
+ }
+ return;
+}
+
+/* runs in the UI thread */
+static BOOL
+update_crossfeed(khui_new_creds * nc,
+ k5_new_cred_data * d,
+ int ctrl_id_src) {
+ wchar_t un[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t * un_realm;
+ wchar_t realm[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cch;
+ khm_size cch_left;
+ int idx;
+
+ cch = (khm_size) GetWindowTextLength(d->hw_username);
+#ifdef DEBUG
+ assert(cch < KCDB_IDENT_MAXCCH_NAME);
+#endif
+ if (cch == 0)
+ return FALSE;
+
+ GetWindowText(d->hw_username,
+ un,
+ ARRAYLENGTH(un));
+ trim_str(un, ARRAYLENGTH(un));
+
+ un_realm = khm_get_realm_from_princ(un);
+
+ if (un_realm == NULL) {
+ EnableWindow(d->hw_realm, TRUE);
+ return FALSE;
+ }
+
+ if (ctrl_id_src == K5_NCID_UN) {
+
+ idx = (int)SendMessage(d->hw_realm,
+ CB_FINDSTRINGEXACT,
+ (WPARAM) -1,
+ (LPARAM) un_realm);
+
+ if (idx != CB_ERR) {
+ wchar_t srealm[KCDB_IDENT_MAXCCH_NAME];
+
+ cch = SendMessage(d->hw_realm,
+ CB_GETLBTEXTLEN,
+ (WPARAM) idx,
+ 0);
+
+#ifdef DEBUG
+ assert(cch < ARRAYLENGTH(srealm) - 1);
+#endif
+ SendMessage(d->hw_realm,
+ CB_GETLBTEXT,
+ (WPARAM) idx,
+ (LPARAM) srealm);
+
+ if (!_wcsicmp(srealm, un_realm) && wcscmp(srealm, un_realm)) {
+ /* differ only by case */
+
+ StringCchCopy(un_realm, ARRAYLENGTH(un) - (un_realm - un),
+ srealm);
+
+ SetWindowText(d->hw_username, un);
+ }
+ }
+
+ SendMessage(d->hw_realm,
+ CB_SELECTSTRING,
+ (WPARAM) -1,
+ (LPARAM) un_realm);
+
+ SetWindowText(d->hw_realm,
+ un_realm);
+
+ if (GetFocus() == d->hw_realm) {
+ HWND hw_next = GetNextDlgTabItem(nc->hwnd, d->hw_realm,
+ FALSE);
+ if (hw_next)
+ SetFocus(hw_next);
+ }
+
+ EnableWindow(d->hw_realm, FALSE);
+
+ return TRUE;
+ }
+ /* else... */
+
+ cch_left = KCDB_IDENT_MAXCCH_NAME - (un_realm - un);
+
+ cch = (khm_size) GetWindowTextLength(d->hw_realm);
+
+#ifdef DEBUG
+ assert(cch < KCDB_IDENT_MAXCCH_NAME);
+#endif
+ if (cch == 0)
+ return FALSE;
+
+ GetWindowText(d->hw_realm, realm,
+ ARRAYLENGTH(realm));
+ trim_str(realm, ARRAYLENGTH(realm));
+
+ idx = (int)SendMessage(d->hw_realm,
+ CB_FINDSTRINGEXACT,
+ (WPARAM) -1,
+ (LPARAM) realm);
+
+ if (idx != CB_ERR) {
+ wchar_t srealm[KCDB_IDENT_MAXCCH_NAME];
+
+ SendMessage(d->hw_realm,
+ CB_GETLBTEXT,
+ (WPARAM) idx,
+ (LPARAM) srealm);
+
+ if (!_wcsicmp(srealm, realm) && wcscmp(srealm, realm)) {
+ StringCbCopy(realm, sizeof(realm), srealm);
+
+ SetWindowText(d->hw_realm, srealm);
+ }
+ }
+
+ StringCchCopy(un_realm, cch_left, realm);
+
+ SendMessage(d->hw_username,
+ CB_SELECTSTRING,
+ (WPARAM) -1,
+ (LPARAM) un);
+
+ SetWindowText(d->hw_username, un);
+
+ return TRUE;
+}
+
+/* Handle window messages for the identity specifiers
+
+ runs in UI thread */
+static LRESULT
+handle_wnd_msg(khui_new_creds * nc,
+ HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+ k5_new_cred_data * d;
+
+ d = (k5_new_cred_data *) nc->ident_aux;
+
+ switch(uMsg) {
+ case WM_COMMAND:
+ switch(wParam) {
+ case MAKEWPARAM(K5_NCID_UN, CBN_EDITCHANGE):
+ /* the username has changed. Instead of handling this
+ for every keystroke, set a timer that elapses some
+ time afterwards and then handle the event. */
+ SetTimer(hwnd, NC_UNCHANGE_TIMER,
+ NC_UNCHANGE_TIMEOUT, NULL);
+ return TRUE;
+
+ case MAKEWPARAM(K5_NCID_UN, CBN_KILLFOCUS):
+ case MAKEWPARAM(K5_NCID_UN, CBN_CLOSEUP):
+ KillTimer(hwnd, NC_UNCHANGE_TIMER);
+
+ update_crossfeed(nc,d,K5_NCID_UN);
+ set_identity_from_ui(nc,d);
+ return TRUE;
+
+ case MAKEWPARAM(K5_NCID_REALM,CBN_EDITCHANGE):
+ SetTimer(hwnd, NC_REALMCHANGE_TIMER,
+ NC_REALMCHANGE_TIMEOUT, NULL);
+ return TRUE;
+
+ case MAKEWPARAM(K5_NCID_REALM,CBN_KILLFOCUS):
+ case MAKEWPARAM(K5_NCID_REALM,CBN_CLOSEUP):
+ KillTimer(hwnd, NC_REALMCHANGE_TIMER);
+
+ update_crossfeed(nc,d,K5_NCID_REALM);
+ set_identity_from_ui(nc, d);
+ return TRUE;
+ }
+ break;
+
+ case WM_TIMER:
+ if(wParam == NC_UNCHANGE_TIMER) {
+ KillTimer(hwnd, NC_UNCHANGE_TIMER);
+
+ update_crossfeed(nc, d, K5_NCID_UN);
+ set_identity_from_ui(nc,d);
+ return TRUE;
+ } else if (wParam == NC_REALMCHANGE_TIMER) {
+ KillTimer(hwnd, NC_REALMCHANGE_TIMER);
+
+ update_crossfeed(nc, d, K5_NCID_REALM);
+ set_identity_from_ui(nc, d);
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+/* UI Callback
+
+ runs in UI thread */
+static LRESULT KHMAPI
+ui_cb(khui_new_creds * nc,
+ UINT cmd,
+ HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+
+ k5_new_cred_data * d;
+
+ d = (k5_new_cred_data *) nc->ident_aux;
+
+ switch(cmd) {
+ case WMNC_IDENT_INIT:
+ {
+ wchar_t defident[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t wbuf[1024];
+ wchar_t * ms = NULL;
+ wchar_t * t;
+ wchar_t * defrealm = NULL;
+ LRESULT lr;
+ khm_size cb_ms;
+ khm_size cb;
+ HWND hw_parent;
+ khm_int32 rv;
+ khm_handle hident;
+
+ hw_parent = (HWND) lParam;
+ defident[0] = L'\0';
+
+#ifdef DEBUG
+ assert(d == NULL);
+ assert(hw_parent != NULL);
+#endif
+
+ d = PMALLOC(sizeof(*d));
+ assert(d);
+ ZeroMemory(d, sizeof(*d));
+
+ khui_cw_lock_nc(nc);
+ nc->ident_aux = (LPARAM) d;
+ khui_cw_unlock_nc(nc);
+
+ LoadString(hResModule, IDS_NC_USERNAME,
+ wbuf, ARRAYLENGTH(wbuf));
+
+ d->hw_username_label = CreateWindow
+ (L"STATIC",
+ wbuf,
+ SS_SIMPLE | WS_CHILD | WS_VISIBLE,
+ 0, 0, 100, 100, /* bogus values */
+ hw_parent,
+ (HMENU) K5_NCID_UN_LABEL,
+ hInstance,
+ NULL);
+ assert(d->hw_username_label != NULL);
+
+ d->hw_username = CreateWindow
+ (L"COMBOBOX",
+ L"",
+ CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT |
+ WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL,
+ 0, 0, 100, 100, /* bogus values */
+ hw_parent,
+ (HMENU) K5_NCID_UN,
+ hInstance,
+ NULL);
+ assert(d->hw_username != NULL);
+
+ SendMessage(d->hw_username,
+ CB_LIMITTEXT,
+ (WPARAM)(KCDB_IDENT_MAXCCH_NAME - 1),
+ 0);
+
+ SendMessage(d->hw_username,
+ CB_SETEXTENDEDUI,
+ (WPARAM) TRUE,
+ 0);
+
+ khui_cw_add_control_row(nc,
+ d->hw_username_label,
+ d->hw_username,
+ KHUI_CTRLSIZE_SMALL);
+
+ LoadString(hResModule, IDS_NC_REALM,
+ wbuf, ARRAYLENGTH(wbuf));
+
+ d->hw_realm_label = CreateWindow
+ (L"STATIC",
+ wbuf,
+ SS_SIMPLE | WS_CHILD | WS_VISIBLE,
+ 0, 0, 100, 100, /* bogus */
+ hw_parent,
+ (HMENU) K5_NCID_REALM_LABEL,
+ hInstance,
+ NULL);
+ assert(d->hw_realm_label != NULL);
+
+ d->hw_realm = CreateWindow
+ (L"COMBOBOX",
+ L"",
+ CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT |
+ WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL,
+ 0, 0, 100, 100, /* bogus */
+ hw_parent,
+ (HMENU) K5_NCID_REALM,
+ hInstance,
+ NULL);
+ assert(d->hw_realm != NULL);
+
+ SendMessage(d->hw_realm,
+ CB_LIMITTEXT,
+ (WPARAM) (KCDB_IDENT_MAXCCH_NAME - 1),
+ 0);
+
+ SendMessage(d->hw_realm,
+ CB_SETEXTENDEDUI,
+ (WPARAM) TRUE,
+ 0);
+
+ khui_cw_add_control_row(nc,
+ d->hw_realm_label,
+ d->hw_realm,
+ KHUI_CTRLSIZE_SMALL);
+
+ /* add the LRU realms and principals to the dropdown
+ lists */
+ rv = khc_read_multi_string(csp_params,
+ L"LRUPrincipals",
+ NULL,
+ &cb_ms);
+
+ if (rv != KHM_ERROR_TOO_LONG || cb_ms <= sizeof(wchar_t) * 2)
+ goto _add_lru_realms;
+
+ ms = PMALLOC(cb_ms);
+ assert(ms != NULL);
+
+ cb = cb_ms;
+ rv = khc_read_multi_string(csp_params,
+ L"LRUPrincipals",
+ ms,
+ &cb);
+
+ assert(KHM_SUCCEEDED(rv));
+
+ /* the first of these is considered the default identity
+ if no other default is known */
+ StringCbCopy(defident, sizeof(defident), ms);
+
+ t = ms;
+ while(t && *t) {
+ SendMessage(d->hw_username,
+ CB_ADDSTRING,
+ 0,
+ (LPARAM) t);
+
+ t = multi_string_next(t);
+ }
+
+ _add_lru_realms:
+ /* add the default realm first */
+ defrealm = khm_krb5_get_default_realm();
+ if (defrealm) {
+ SendMessage(d->hw_realm,
+ CB_ADDSTRING,
+ 0,
+ (LPARAM) defrealm);
+ }
+
+ rv = khc_read_multi_string(csp_params,
+ L"LRURealms",
+ NULL,
+ &cb);
+
+ if (rv != KHM_ERROR_TOO_LONG)
+ goto _done_adding_lru;
+
+ if (ms != NULL) {
+ if (cb_ms < cb) {
+ PFREE(ms);
+ ms = PMALLOC(cb);
+ assert(ms);
+ cb_ms = cb;
+ }
+ } else {
+ ms = PMALLOC(cb);
+ cb_ms = cb;
+ }
+
+ rv = khc_read_multi_string(csp_params,
+ L"LRURealms",
+ ms,
+ &cb);
+
+ assert(KHM_SUCCEEDED(rv));
+
+ for (t = ms; t && *t; t = multi_string_next(t)) {
+ lr = SendMessage(d->hw_realm,
+ CB_FINDSTRINGEXACT,
+ (WPARAM) -1,
+ (LPARAM) t);
+ if (lr != CB_ERR)
+ continue;
+
+ SendMessage(d->hw_realm,
+ CB_ADDSTRING,
+ 0,
+ (LPARAM) t);
+ }
+ _done_adding_lru:
+
+ {
+ khm_int32 inc_realms = 0;
+
+ if (KHM_FAILED(khc_read_int32(csp_params,
+ L"UseFullRealmList",
+ &inc_realms)) ||
+ !inc_realms)
+ goto _done_adding_all_realms;
+ }
+
+ if(ms)
+ PFREE(ms);
+
+ ms = khm_krb5_get_realm_list();
+ if(ms) {
+ for (t = ms; t && *t; t = multi_string_next(t)) {
+ lr = SendMessage(d->hw_realm,
+ CB_FINDSTRINGEXACT,
+ (WPARAM) -1,
+ (LPARAM) t);
+ if (lr != CB_ERR)
+ continue;
+
+ SendMessage(d->hw_realm,
+ CB_ADDSTRING,
+ 0,
+ (LPARAM) t);
+ }
+ }
+ _done_adding_all_realms:
+
+ /* set the current selection of the realms list */
+ if (defrealm) {
+ SendMessage(d->hw_realm,
+ CB_SELECTSTRING,
+ (WPARAM) -1,
+ (LPARAM) defrealm);
+ } else {
+ SendMessage(d->hw_realm,
+ CB_SETCURSEL,
+ (WPARAM) 0,
+ (LPARAM) 0);
+ }
+
+ if (defrealm)
+ PFREE(defrealm);
+
+ if (ms)
+ PFREE(ms);
+
+ /* now see about that default identity */
+ if (nc->ctx.identity) {
+ cb = sizeof(defident);
+ kcdb_identity_get_name(nc->ctx.identity,
+ defident,
+ &cb);
+ }
+
+ if (defident[0] == L'\0' &&
+ KHM_SUCCEEDED(kcdb_identity_get_default(&hident))) {
+ cb = sizeof(defident);
+ kcdb_identity_get_name(hident, defident, &cb);
+ kcdb_identity_release(hident);
+ }
+
+ if (defident[0] == L'\0') {
+ DWORD dw;
+
+ dw = ARRAYLENGTH(defident);
+ GetUserName(defident, &dw);
+ }
+
+ t = khm_get_realm_from_princ(defident);
+ if (t) {
+ /* there is a realm */
+ assert(t != defident);
+ *--t = L'\0';
+ t++;
+
+ SendMessage(d->hw_realm,
+ CB_SELECTSTRING,
+ (WPARAM) -1,
+ (LPARAM) t);
+
+ SendMessage(d->hw_realm,
+ WM_SETTEXT,
+ 0,
+ (LPARAM) t);
+ }
+
+ if (defident[0] != L'\0') {
+ /* there is a username */
+ SendMessage(d->hw_username,
+ CB_SELECTSTRING,
+ (WPARAM) -1,
+ (LPARAM) defident);
+
+ SendMessage(d->hw_username,
+ WM_SETTEXT,
+ 0,
+ (LPARAM) defident);
+ }
+
+ set_identity_from_ui(nc, d);
+ }
+ return TRUE;
+
+ case WMNC_IDENT_WMSG:
+ return handle_wnd_msg(nc, hwnd, uMsg, wParam, lParam);
+
+ case WMNC_IDENT_EXIT:
+ {
+#ifdef DEBUG
+ assert(d != NULL);
+#endif
+ khui_cw_lock_nc(nc);
+ nc->ident_aux = 0;
+ khui_cw_unlock_nc(nc);
+
+ /* since we created all the windows as child windows of
+ the new creds window, they will be destroyed when that
+ window is destroyed. */
+ PFREE(d);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static khm_int32
+k5_ident_validate_name(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam) {
+ krb5_principal princ = NULL;
+ char princ_name[KCDB_IDENT_MAXCCH_NAME];
+ kcdb_ident_name_xfer * nx;
+ krb5_error_code code;
+ wchar_t * atsign;
+
+ nx = (kcdb_ident_name_xfer *) vparam;
+
+ if(UnicodeStrToAnsi(princ_name, sizeof(princ_name),
+ nx->name_src) == 0) {
+ nx->result = KHM_ERROR_INVALID_NAME;
+ return KHM_ERROR_SUCCESS;
+ }
+
+ assert(k5_identpro_ctx != NULL);
+
+ code = pkrb5_parse_name(k5_identpro_ctx,
+ princ_name,
+ &princ);
+
+ if (code) {
+ nx->result = KHM_ERROR_INVALID_NAME;
+ return KHM_ERROR_SUCCESS;
+ }
+
+ if (princ != NULL)
+ pkrb5_free_principal(k5_identpro_ctx,
+ princ);
+
+ /* krb5_parse_name() accepts principal names with no realm or an
+ empty realm. We don't. */
+ atsign = wcschr(nx->name_src, L'@');
+ if (atsign == NULL || atsign[1] == L'\0') {
+ nx->result = KHM_ERROR_INVALID_NAME;
+ } else {
+ nx->result = KHM_ERROR_SUCCESS;
+ }
+
+ return KHM_ERROR_SUCCESS;
+}
+
+static void
+k5_update_last_default_identity(khm_handle ident) {
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb;
+
+ cb = sizeof(idname);
+ if (KHM_FAILED(kcdb_identity_get_name(ident, idname, &cb)))
+ return;
+
+ assert(csp_params);
+
+ khc_write_string(csp_params, L"LastDefaultIdent", idname);
+}
+
+static khm_int32
+k5_ident_set_default_int(khm_handle def_ident) {
+ wchar_t id_ccname[KRB5_MAXCCH_CCNAME];
+ khm_size cb;
+ DWORD dw;
+ LONG l;
+ HKEY hk_ccname;
+ DWORD dwType;
+ DWORD dwSize;
+ wchar_t reg_ccname[KRB5_MAXCCH_CCNAME];
+
+#ifdef DEBUG
+ assert(def_ident != NULL);
+#endif
+
+ cb = sizeof(id_ccname);
+ if (KHM_FAILED(kcdb_identity_get_attr(def_ident, attr_id_krb5_ccname, NULL,
+ id_ccname, &cb))) {
+ khm_handle csp_ident = NULL;
+ khm_handle csp_k5 = NULL;
+
+ _reportf(L"The specified identity does not have the Krb5CCName property");
+
+ cb = sizeof(id_ccname);
+ if (KHM_SUCCEEDED(kcdb_identity_get_config(def_ident, 0, &csp_ident)) &&
+ KHM_SUCCEEDED(khc_open_space(csp_ident, CSNAME_KRB5CRED, 0, &csp_k5)) &&
+ KHM_SUCCEEDED(khc_read_string(csp_k5, L"DefaultCCName",
+ id_ccname, &cb))) {
+
+ _reportf(L"Found CC name in configuration [%s]", id_ccname);
+ } else {
+ /* last resort, use the name of the identity as the cc
+ name */
+ cb = sizeof(id_ccname);
+ if (KHM_FAILED(kcdb_identity_get_name(def_ident, id_ccname, &cb))) {
+ _reportf(L"Can't use name of identity as CCName");
+ _end_task();
+
+ id_ccname[0] = L'\0';
+ }
+ }
+
+ if (csp_k5)
+ khc_close_space(csp_k5);
+ if (csp_ident)
+ khc_close_space(csp_ident);
+
+ if (id_ccname[0] == L'\0')
+ return KHM_ERROR_INVALID_PARAM;
+ }
+
+ khm_krb5_canon_cc_name(id_ccname, sizeof(id_ccname));
+
+ _reportf(L"Found Krb5CCName property : %s", id_ccname);
+
+ StringCbLength(id_ccname, sizeof(id_ccname), &cb);
+ cb += sizeof(wchar_t);
+
+ _reportf(L"Setting default CC name in the registry");
+
+ l = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\MIT\\kerberos5", 0,
+ KEY_READ | KEY_WRITE, &hk_ccname);
+
+ if (l != ERROR_SUCCESS)
+ l = RegCreateKeyEx(HKEY_CURRENT_USER, L"Software\\MIT\\kerberos5", 0,
+ NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE,
+ NULL, &hk_ccname, &dw);
+
+ if (l != ERROR_SUCCESS) {
+ _reportf(L"Can't create registry key : %d", l);
+ _end_task();
+ return KHM_ERROR_UNKNOWN;
+ }
+
+ dwSize = sizeof(reg_ccname);
+
+ l = RegQueryValueEx(hk_ccname, L"ccname", NULL, &dwType, (LPBYTE) reg_ccname,
+ &dwSize);
+
+ if (l != ERROR_SUCCESS ||
+ dwType != REG_SZ ||
+ khm_krb5_cc_name_cmp(reg_ccname, id_ccname)) {
+
+ /* we have to write the new value in */
+
+ l = RegSetValueEx(hk_ccname, L"ccname", 0, REG_SZ, (BYTE *) id_ccname,
+ (DWORD) cb);
+ }
+
+ RegCloseKey(hk_ccname);
+
+ if (l == ERROR_SUCCESS) {
+ _reportf(L"Successfully set the default ccache");
+ k5_update_last_default_identity(def_ident);
+ return KHM_ERROR_SUCCESS;
+ } else {
+ _reportf(L"Can't set the registry value : %d", l);
+ return KHM_ERROR_UNKNOWN;
+ }
+}
+
+static khm_int32
+k5_ident_set_default(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam) {
+
+ /*
+ Currently, setting the default identity simply sets the
+ "ccname" registry value at "Software\MIT\kerberos5".
+ */
+
+ if (uparam) {
+ /* an identity is being made default */
+ khm_handle def_ident = (khm_handle) vparam;
+ khm_int32 rv;
+
+#ifdef DEBUG
+ assert(def_ident != NULL);
+#endif
+
+ {
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb;
+
+ cb = sizeof(idname);
+ kcdb_identity_get_name(def_ident, idname, &cb);
+
+ _begin_task(0);
+ _report_cs1(KHERR_DEBUG_1, L"Setting default identity [%1!s!]", _cstr(idname));
+ _describe();
+ }
+
+ rv = k5_ident_set_default_int(def_ident);
+
+ _end_task();
+
+ return rv;
+
+ } else {
+ /* the default identity is being forgotten */
+
+ /* we don't really do anything about this case */
+ }
+
+ return KHM_ERROR_SUCCESS;
+}
+
+static khm_int32
+k5_ident_get_ui_cb(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam) {
+ khui_ident_new_creds_cb * cb;
+
+ cb = (khui_ident_new_creds_cb *) vparam;
+
+ *cb = ui_cb;
+
+ return KHM_ERROR_SUCCESS;
+}
+
+static khm_int32
+k5_ident_notify_create(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam) {
+
+ /* a new identity has been created. What we want to do at
+ this point is to check if the identity belongs to krb5
+ and to see if it is the default. */
+
+ krb5_ccache cc = NULL;
+ krb5_error_code code;
+ krb5_principal princ = NULL;
+ char * princ_nameA = NULL;
+ wchar_t princ_nameW[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t id_nameW[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb;
+ khm_handle ident;
+
+ /* if there is a default identity already, we assume we don't need
+ to check this one. */
+
+ khm_handle def_ident;
+
+ if (KHM_SUCCEEDED(kcdb_identity_get_default(&def_ident))) {
+ kcdb_identity_release(def_ident);
+
+ return KHM_ERROR_SUCCESS;
+ }
+
+ ident = (khm_handle) vparam;
+
+ assert(k5_identpro_ctx != NULL);
+
+ code = pkrb5_cc_default(k5_identpro_ctx, &cc);
+ if (code)
+ goto _nc_cleanup;
+
+ code = pkrb5_cc_get_principal(k5_identpro_ctx,
+ cc,
+ &princ);
+ if (code)
+ goto _nc_cleanup;
+
+ code = pkrb5_unparse_name(k5_identpro_ctx,
+ princ,
+ &princ_nameA);
+ if (code)
+ goto _nc_cleanup;
+
+ AnsiStrToUnicode(princ_nameW,
+ sizeof(princ_nameW),
+ princ_nameA);
+
+ cb = sizeof(id_nameW);
+
+ if (KHM_FAILED(kcdb_identity_get_name(ident,
+ id_nameW,
+ &cb)))
+ goto _nc_cleanup;
+
+ if (!wcscmp(id_nameW, princ_nameW)) {
+ kcdb_identity_set_default_int(ident);
+ }
+
+ _nc_cleanup:
+ if (princ_nameA)
+ pkrb5_free_unparsed_name(k5_identpro_ctx,
+ princ_nameA);
+ if (princ)
+ pkrb5_free_principal(k5_identpro_ctx,
+ princ);
+ if (cc)
+ pkrb5_cc_close(k5_identpro_ctx, cc);
+
+ return KHM_ERROR_SUCCESS;
+}
+
+struct k5_ident_update_data {
+ khm_handle identity;
+
+ FILETIME ft_expire; /* expiration */
+ FILETIME ft_issue; /* issue */
+ FILETIME ft_rexpire; /* renew expiration */
+ wchar_t ccname[KRB5_MAXCCH_CCNAME];
+ khm_int32 k5_flags;
+};
+
+/* The logic here has to reflect the logic in khm_krb5_list_tickets().
+ We use this to handle an identity update request because some other
+ plug-in or maybe NetIDMgr itself is about to do something
+ important(tm) with the identity and needs to make sure that the
+ properties of the identity are up-to-date. */
+static khm_int32 KHMAPI
+k5_ident_update_apply_proc(khm_handle cred,
+ void * rock) {
+ struct k5_ident_update_data * d = (struct k5_ident_update_data *) rock;
+ khm_handle ident = NULL;
+ khm_int32 t;
+ khm_int32 flags;
+ FILETIME t_cexpire;
+ FILETIME t_rexpire;
+ khm_size cb;
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+
+ if (KHM_FAILED(kcdb_cred_get_type(cred, &t)) ||
+ t != credtype_id_krb5 ||
+ KHM_FAILED(kcdb_cred_get_identity(cred, &ident)))
+
+ return KHM_ERROR_SUCCESS;
+
+ if (!kcdb_identity_is_equal(ident,d->identity))
+
+ goto _cleanup;
+
+ if (KHM_FAILED(kcdb_cred_get_flags(cred, &flags)))
+
+ flags = 0;
+
+ if (flags & KCDB_CRED_FLAG_INITIAL) {
+ cb = sizeof(t_cexpire);
+ if (KHM_SUCCEEDED(kcdb_cred_get_attr(cred,
+ KCDB_ATTR_EXPIRE,
+ NULL,
+ &t_cexpire,
+ &cb))) {
+ if ((d->ft_expire.dwLowDateTime == 0 &&
+ d->ft_expire.dwHighDateTime == 0) ||
+ CompareFileTime(&t_cexpire, &d->ft_expire) > 0) {
+ goto update_identity;
+ }
+ }
+ }
+
+ goto _cleanup;
+
+ update_identity:
+
+ d->ft_expire = t_cexpire;
+
+ cb = sizeof(d->ccname);
+ if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_LOCATION, NULL, d->ccname, &cb))) {
+ d->ccname[0] = L'\0';
+ }
+
+ cb = sizeof(d->k5_flags);
+ if (KHM_FAILED(kcdb_cred_get_attr(cred, attr_id_krb5_flags, NULL,
+ &d->k5_flags, &cb))) {
+ d->k5_flags = 0;
+ }
+
+ cb = sizeof(d->ft_issue);
+ if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_ISSUE, NULL, &d->ft_issue, &cb))) {
+ ZeroMemory(&d->ft_issue, sizeof(d->ft_issue));
+ }
+
+ cb = sizeof(t_rexpire);
+ if ((d->k5_flags & TKT_FLG_RENEWABLE) &&
+ KHM_SUCCEEDED(kcdb_cred_get_attr(cred,
+ KCDB_ATTR_RENEW_EXPIRE,
+ NULL,
+ &t_rexpire,
+ &cb))) {
+ d->ft_rexpire = t_rexpire;
+ } else {
+ ZeroMemory(&d->ft_rexpire, sizeof(d->ft_rexpire));
+ }
+
+ _cleanup:
+ if (ident)
+ kcdb_identity_release(ident);
+
+ return rv;
+}
+
+static khm_int32
+k5_ident_update(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam) {
+
+#if 0
+ struct k5_ident_update_data d;
+#endif
+ khm_handle ident;
+ khm_handle tident;
+ krb5_ccache cc = NULL;
+ char * ccname;
+ krb5_error_code code;
+ khm_size cb;
+ wchar_t wid_ccname[MAX_PATH];
+ wchar_t w_ccname[MAX_PATH];
+
+ ident = (khm_handle) vparam;
+ if (ident == NULL)
+ return KHM_ERROR_SUCCESS;
+
+#if 0
+ /* we are going to skip doing this here since
+ khm_krb5_list_tickets() performs this function for us each time
+ we enumerate tickets. Since it also gets run each time our
+ list of tickets changes and since we are basing this operation
+ on existing tickets, we are unlikely to find anything new
+ here. */
+ ZeroMemory(&d, sizeof(d));
+ d.identity = ident;
+
+ kcdb_credset_apply(NULL,
+ k5_ident_update_apply_proc,
+ (void *) &d);
+
+ if (d.ft_expire.dwLowDateTime != 0 ||
+ d.ft_expire.dwHighDateTime != 0) {
+
+ /* we found a TGT */
+
+ kcdb_identity_set_attr(ident, KCDB_ATTR_EXPIRE,
+ &d.ft_expire, sizeof(d.ft_expire));
+ if (d.ft_issue.dwLowDateTime != 0 ||
+ d.ft_issue.dwHighDateTime != 0)
+ kcdb_identity_set_attr(ident, KCDB_ATTR_ISSUE,
+ &d.ft_issue, sizeof(d.ft_issue));
+ else
+ kcdb_identity_set_attr(ident, KCDB_ATTR_ISSUE, NULL, 0);
+
+ if (d.ft_rexpire.dwLowDateTime != 0 ||
+ d.ft_rexpire.dwHighDateTime != 0)
+ kcdb_identity_set_attr(ident, KCDB_ATTR_RENEW_EXPIRE,
+ &d.ft_rexpire, sizeof(d.ft_rexpire));
+ else
+ kcdb_identity_set_attr(ident, KCDB_ATTR_RENEW_EXPIRE, NULL, 0);
+
+ kcdb_identity_set_attr(ident, attr_id_krb5_flags,
+ &d.k5_flags, sizeof(d.k5_flags));
+
+ if (d.ccname[0])
+ kcdb_identity_set_attr(ident, attr_id_krb5_ccname,
+ d.ccname, KCDB_CBSIZE_AUTO);
+ else
+ kcdb_identity_set_attr(ident, attr_id_krb5_ccname, NULL, 0);
+
+ } else {
+ /* Clear out the attributes. We don't have any information
+ about this identity */
+ kcdb_identity_set_attr(ident, KCDB_ATTR_EXPIRE, NULL, 0);
+ kcdb_identity_set_attr(ident, KCDB_ATTR_ISSUE, NULL, 0);
+ kcdb_identity_set_attr(ident, KCDB_ATTR_RENEW_EXPIRE, NULL, 0);
+ kcdb_identity_set_attr(ident, attr_id_krb5_flags, NULL, 0);
+ kcdb_identity_set_attr(ident, attr_id_krb5_ccname, NULL, 0);
+ }
+#endif
+
+ if (KHM_SUCCEEDED(kcdb_identity_get_default(&tident))) {
+ kcdb_identity_release(tident);
+ goto _iu_cleanup;
+ }
+
+ cb = sizeof(wid_ccname);
+ if (KHM_FAILED(kcdb_identity_get_attr(ident,
+ attr_id_krb5_ccname,
+ NULL,
+ wid_ccname,
+ &cb)))
+ goto _iu_cleanup;
+
+ if(k5_identpro_ctx == NULL)
+ goto _iu_cleanup;
+
+ code = pkrb5_cc_default(k5_identpro_ctx, &cc);
+ if (code)
+ goto _iu_cleanup;
+
+ ccname = pkrb5_cc_get_name(k5_identpro_ctx, cc);
+ if (ccname == NULL)
+ goto _iu_cleanup;
+
+ AnsiStrToUnicode(w_ccname, sizeof(w_ccname), ccname);
+
+ khm_krb5_canon_cc_name(w_ccname, sizeof(w_ccname));
+ khm_krb5_canon_cc_name(wid_ccname, sizeof(wid_ccname));
+
+ if (!_wcsicmp(w_ccname, wid_ccname))
+ kcdb_identity_set_default_int(ident);
+
+ _iu_cleanup:
+ if (cc && k5_identpro_ctx)
+ pkrb5_cc_close(k5_identpro_ctx, cc);
+
+ return KHM_ERROR_SUCCESS;
+}
+
+static khm_boolean
+k5_refresh_default_identity(krb5_context ctx) {
+ /* just like notify_create, except now we set the default identity
+ based on what we find in the configuration */
+ krb5_ccache cc = NULL;
+ krb5_error_code code;
+ krb5_principal princ = NULL;
+ char * princ_nameA = NULL;
+ wchar_t princ_nameW[KCDB_IDENT_MAXCCH_NAME];
+ char * ccname = NULL;
+ khm_handle ident = NULL;
+ khm_boolean found_default = FALSE;
+
+ assert(ctx != NULL);
+
+ _begin_task(0);
+ _report_cs0(KHERR_DEBUG_1, L"Refreshing default identity");
+ _describe();
+
+ code = pkrb5_cc_default(ctx, &cc);
+ if (code) {
+ _reportf(L"Can't open default ccache. code=%d", code);
+ goto _nc_cleanup;
+ }
+
+ code = pkrb5_cc_get_principal(ctx, cc, &princ);
+ if (code) {
+ /* try to determine the identity from the ccache name */
+ ccname = pkrb5_cc_get_name(ctx, cc);
+
+ if (ccname) {
+ char * namepart = strchr(ccname, ':');
+
+ _reportf(L"CC name is [%S]", ccname);
+
+ if (namepart == NULL)
+ namepart = ccname;
+ else
+ namepart++;
+
+ _reportf(L"Checking if [%S] is a valid identity name", namepart);
+
+ AnsiStrToUnicode(princ_nameW, sizeof(princ_nameW), namepart);
+ if (kcdb_identity_is_valid_name(princ_nameW)) {
+ kcdb_identity_create(princ_nameW, KCDB_IDENT_FLAG_CREATE, &ident);
+ if (ident) {
+ _reportf(L"Setting [%S] as the default identity", namepart);
+ kcdb_identity_set_default_int(ident);
+ found_default = TRUE;
+ }
+ }
+ } else {
+ _reportf(L"Can't determine ccache name");
+ }
+
+ goto _nc_cleanup;
+ }
+
+ code = pkrb5_unparse_name(ctx, princ, &princ_nameA);
+ if (code)
+ goto _nc_cleanup;
+
+ AnsiStrToUnicode(princ_nameW, sizeof(princ_nameW), princ_nameA);
+
+ _reportf(L"Found principal [%s]", princ_nameW);
+
+ if (KHM_FAILED(kcdb_identity_create(princ_nameW, KCDB_IDENT_FLAG_CREATE, &ident))) {
+ _reportf(L"Failed to create identity");
+ goto _nc_cleanup;
+ }
+
+ _reportf(L"Setting default identity to [%s]", princ_nameW);
+ kcdb_identity_set_default_int(ident);
+
+ found_default = TRUE;
+
+ _nc_cleanup:
+
+ _end_task();
+
+ if (princ_nameA)
+ pkrb5_free_unparsed_name(ctx, princ_nameA);
+
+ if (princ)
+ pkrb5_free_principal(ctx, princ);
+
+ if (cc)
+ pkrb5_cc_close(ctx, cc);
+
+ if (ident)
+ kcdb_identity_release(ident);
+
+ return found_default;
+}
+
+static khm_int32
+k5_ident_init(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam) {
+
+ khm_boolean found_default;
+ khm_handle ident;
+
+ found_default = k5_refresh_default_identity(k5_identpro_ctx);
+
+ if (!found_default) {
+ wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb;
+
+ cb = sizeof(widname);
+
+ assert(csp_params);
+
+ if (KHM_SUCCEEDED(khc_read_string(csp_params, L"LastDefaultIdent",
+ widname, &cb))) {
+ ident = NULL;
+ kcdb_identity_create(widname, KCDB_IDENT_FLAG_CREATE, &ident);
+ if (ident) {
+ kcdb_identity_set_default_int(ident);
+ kcdb_identity_release(ident);
+
+ found_default = TRUE;
+ }
+ }
+ }
+
+ if (!found_default) {
+
+ /* There was no default ccache and we don't have a
+ "LastDefaultIdent" value. Next we see if there are any
+ identities that have credentials which have a Krb5CCName
+ property (i.e. an identity that has a Kerberos 5 TGT), and
+ make it the default.
+
+ Note that since the Krb5Ident plug-in has a dependency on
+ Krb5Cred, by the time this code runs, we already have a
+ listing of Kerberos 5 tickets and identities. */
+
+ wchar_t * idlist = NULL;
+ wchar_t * thisid;
+ khm_size cb = 0;
+ khm_size n_idents = 0;
+ khm_int32 rv;
+ wchar_t ccname[KRB5_MAXCCH_CCNAME];
+ FILETIME ft_expire;
+ FILETIME ft_now;
+ FILETIME ft_threshold;
+ BOOL match_all = FALSE;
+
+ rv = kcdb_identity_enum(0, 0, NULL, &cb, &n_idents);
+
+ TimetToFileTimeInterval(5 * 60, &ft_threshold);
+ GetSystemTimeAsFileTime(&ft_now);
+ ft_now = FtAdd(&ft_now, &ft_threshold);
+
+ while (rv == KHM_ERROR_TOO_LONG && n_idents > 0) {
+ if (idlist) {
+ PFREE(idlist);
+ idlist = NULL;
+ }
+
+ idlist = PMALLOC(cb);
+
+ if (idlist == NULL)
+ break;
+
+ rv = kcdb_identity_enum(0, 0, idlist, &cb, &n_idents);
+ }
+
+ if (KHM_SUCCEEDED(rv)) {
+
+ /* first we try to find an identity that has a valid TGT.
+ If that fails, then we try to find an identity with
+ *any* TGT. */
+
+ try_again:
+
+ for (thisid = idlist;
+ thisid && *thisid && !found_default;
+ thisid = multi_string_next(thisid)) {
+
+ if (KHM_SUCCEEDED(kcdb_identity_create(thisid, 0, &ident))) {
+ khm_size cb_ft = sizeof(FILETIME);
+ cb = sizeof(ccname);
+
+ if (KHM_SUCCEEDED(kcdb_identity_get_attr(ident, attr_id_krb5_ccname,
+ NULL, ccname, &cb)) &&
+ (match_all ||
+ (KHM_SUCCEEDED(kcdb_identity_get_attr(ident, KCDB_ATTR_EXPIRE,
+ NULL, &ft_expire, &cb_ft)) &&
+ CompareFileTime(&ft_expire, &ft_now) > 0))) {
+
+ /* found one */
+ k5_ident_set_default_int(ident);
+ kcdb_identity_set_default_int(ident);
+ found_default = TRUE;
+
+ }
+
+ kcdb_identity_release(ident);
+ ident = NULL;
+ }
+ }
+
+ if (!found_default && !match_all) {
+ match_all = TRUE;
+ goto try_again;
+ }
+ }
+
+ if (idlist) {
+ PFREE(idlist);
+ idlist = NULL;
+ }
+ }
+
+ return KHM_ERROR_SUCCESS;
+}
+
+static khm_int32
+k5_ident_exit(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam) {
+ /* don't really do anything */
+ return KHM_ERROR_SUCCESS;
+}
+
+/* forward dcl */
+khm_int32 KHMAPI
+k5_ident_name_comp_func(const void * dl, khm_size cb_dl,
+ const void * dr, khm_size cb_dr);
+
+static khm_int32
+k5_ident_compare_name(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam) {
+ kcdb_ident_name_xfer *px;
+
+ px = (kcdb_ident_name_xfer *) vparam;
+
+ /* note that k5_ident_name_comp_func() ignores the size
+ specifiers. So we can just pass in 0's. */
+ px->result = k5_ident_name_comp_func(px->name_src, 0,
+ px->name_alt, 0);
+
+ return KHM_ERROR_SUCCESS;
+}
+
+#if 0
+/* copy and paste template for ident provider messages */
+static khm_int32
+k5_ident_(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam) {
+}
+#endif
+
+khm_int32 KHMAPI
+k5_msg_ident(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam)
+{
+ switch(msg_subtype) {
+ case KMSG_IDENT_INIT:
+ return k5_ident_init(msg_type,
+ msg_subtype,
+ uparam,
+ vparam);
+
+ case KMSG_IDENT_EXIT:
+ return k5_ident_exit(msg_type,
+ msg_subtype,
+ uparam,
+ vparam);
+
+ case KMSG_IDENT_VALIDATE_NAME:
+ return k5_ident_validate_name(msg_type,
+ msg_subtype,
+ uparam,
+ vparam);
+
+ case KMSG_IDENT_VALIDATE_IDENTITY:
+ /* TODO: handle KMSG_IDENT_VALIDATE_IDENTITY */
+ break;
+
+ case KMSG_IDENT_CANON_NAME:
+ /* TODO: handle KMSG_IDENT_CANON_NAME */
+ break;
+
+ case KMSG_IDENT_COMPARE_NAME:
+ return k5_ident_compare_name(msg_type,
+ msg_subtype,
+ uparam,
+ vparam);
+
+ case KMSG_IDENT_SET_DEFAULT:
+ return k5_ident_set_default(msg_type,
+ msg_subtype,
+ uparam,
+ vparam);
+
+ case KMSG_IDENT_SET_SEARCHABLE:
+ /* TODO: handle KMSG_IDENT_SET_SEARCHABLE */
+ break;
+
+ case KMSG_IDENT_GET_INFO:
+ /* TODO: handle KMSG_IDENT_GET_INFO */
+ break;
+
+ case KMSG_IDENT_UPDATE:
+ return k5_ident_update(msg_type,
+ msg_subtype,
+ uparam,
+ vparam);
+
+ case KMSG_IDENT_ENUM_KNOWN:
+ /* TODO: handle KMSG_IDENT_ENUM_KNOWN */
+ break;
+
+ case KMSG_IDENT_GET_UI_CALLBACK:
+ return k5_ident_get_ui_cb(msg_type,
+ msg_subtype,
+ uparam,
+ vparam);
+
+ case KMSG_IDENT_NOTIFY_CREATE:
+ return k5_ident_notify_create(msg_type,
+ msg_subtype,
+ uparam,
+ vparam);
+ }
+
+ return KHM_ERROR_SUCCESS;
+}
+
+/* note that we are ignoring the size specifiers. We can do that
+ because we are guaranteed that dl and dr point to NULL terminated
+ unicode strings when used with credential data buffers. We also
+ use the fact that we are ignoring the size specifiers when we call
+ this function from k5_ident_compare_name() to avoid calculating the
+ length of the string. */
+khm_int32 KHMAPI
+k5_ident_name_comp_func(const void * dl, khm_size cb_dl,
+ const void * dr, khm_size cb_dr) {
+ wchar_t * idl = (wchar_t *) dl;
+ wchar_t * idr = (wchar_t *) dr;
+ wchar_t * rl;
+ wchar_t * rr;
+ khm_int32 r;
+
+ rl = khm_get_realm_from_princ(idl);
+ rr = khm_get_realm_from_princ(idr);
+
+ if (rl == NULL && rr == NULL)
+ return wcscmp(idl, idr);
+ else if (rl == NULL)
+ return 1;
+ else if (rr == NULL)
+ return -1;
+
+ r = wcscmp(rl, rr);
+ if (r == 0)
+ return wcscmp(idl, idr);
+ else
+ return r;
+}
+
+
+/* Identity change notification thread */
+
+HANDLE h_ccname_exit_event;
+HANDLE h_ccname_thread;
+
+DWORD WINAPI k5_ccname_monitor_thread(LPVOID lpParameter) {
+ krb5_context ctx = 0;
+
+ HKEY hk_ccname;
+ HANDLE h_notify;
+ HANDLE h_waits[2];
+
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+ DWORD dwType;
+ DWORD dwSize;
+ DWORD dwDisp;
+ wchar_t reg_ccname[KRB5_MAXCCH_CCNAME];
+ LONG l;
+
+ PDESCTHREAD(L"Krb5 CCName Monitor", L"Krb5");
+
+ l = RegOpenKeyEx(HKEY_CURRENT_USER,
+ L"Software\\MIT\\kerberos5",
+ 0,
+ KEY_READ | KEY_WRITE,
+ &hk_ccname);
+
+ if (l != ERROR_SUCCESS)
+ l = RegCreateKeyEx(HKEY_CURRENT_USER,
+ L"Software\\MIT\\kerberos5",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ | KEY_WRITE,
+ NULL,
+ &hk_ccname,
+ &dwDisp);
+
+ if (l != ERROR_SUCCESS) {
+ rv = KHM_ERROR_UNKNOWN;
+ goto _exit;
+ }
+
+ dwSize = sizeof(reg_ccname);
+
+ l = RegQueryValueEx(hk_ccname,
+ L"ccname",
+ NULL,
+ &dwType,
+ (LPBYTE) reg_ccname,
+ &dwSize);
+
+ if (l != ERROR_SUCCESS ||
+ dwType != REG_SZ) {
+
+ reg_ccname[0] = L'\0';
+ }
+
+ l = pkrb5_init_context(&ctx);
+
+ if (l)
+ goto _exit_0;
+
+ h_notify = CreateEvent(NULL, FALSE, FALSE, L"Local\\Krb5CCNameChangeNotifier");
+
+ if (h_notify == NULL)
+ goto _exit_0;
+
+ /* begin wait loop */
+
+ h_waits[0] = h_ccname_exit_event;
+ h_waits[1] = h_notify;
+
+ do {
+ DWORD dwrv;
+
+ l = RegNotifyChangeKeyValue(hk_ccname, FALSE,
+ REG_NOTIFY_CHANGE_LAST_SET,
+ h_notify, TRUE);
+
+ if (l != ERROR_SUCCESS) {
+ rv = KHM_ERROR_UNKNOWN;
+ break;
+ }
+
+ dwrv = WaitForMultipleObjects(2, h_waits, FALSE, INFINITE);
+
+ if (dwrv == WAIT_OBJECT_0) {
+ /* exit! */
+ break;
+
+ } else if (dwrv == WAIT_OBJECT_0 + 1) {
+ /* change notify! */
+ wchar_t new_ccname[KRB5_MAXCCH_CCNAME];
+
+ dwSize = sizeof(new_ccname);
+
+ l = RegQueryValueEx(hk_ccname,
+ L"ccname",
+ NULL,
+ &dwType,
+ (LPBYTE) new_ccname,
+ &dwSize);
+
+ if (l != ERROR_SUCCESS ||
+ dwType != REG_SZ) {
+ new_ccname[0] = L'\0';
+ }
+
+ if (_wcsicmp(new_ccname, reg_ccname)) {
+ k5_refresh_default_identity(ctx);
+ StringCbCopy(reg_ccname, sizeof(reg_ccname), new_ccname);
+ }
+
+ } else {
+ /* something went wrong */
+ rv = KHM_ERROR_UNKNOWN;
+ break;
+ }
+
+ } while (TRUE);
+
+ CloseHandle(h_notify);
+
+ _exit_0:
+
+ RegCloseKey(hk_ccname);
+
+ if (ctx)
+ pkrb5_free_context(ctx);
+
+ _exit:
+ ExitThread(rv);
+
+ /* not reached */
+ return rv;
+}
+
+khm_int32
+k5_msg_system_idpro(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam) {
+
+ switch(msg_subtype) {
+ case KMSG_SYSTEM_INIT:
+ {
+
+ pkrb5_init_context(&k5_identpro_ctx);
+ kcdb_identity_set_type(credtype_id_krb5);
+
+ if (KHM_FAILED(kcdb_type_get_id(TYPENAME_KRB5_PRINC,
+ &type_id_krb5_princ))) {
+ kcdb_type dt;
+ kcdb_type * pstr;
+
+ kcdb_type_get_info(KCDB_TYPE_STRING, &pstr);
+
+ ZeroMemory(&dt, sizeof(dt));
+ dt.name = TYPENAME_KRB5_PRINC;
+ dt.id = KCDB_TYPE_INVALID;
+ dt.flags = KCDB_TYPE_FLAG_CB_AUTO;
+ dt.cb_min = pstr->cb_min;
+ dt.cb_max = pstr->cb_max;
+ dt.toString = pstr->toString;
+ dt.isValid = pstr->isValid;
+ dt.comp = k5_ident_name_comp_func;
+ dt.dup = pstr->dup;
+
+ kcdb_type_register(&dt, &type_id_krb5_princ);
+
+ type_regd_krb5_princ = TRUE;
+
+ kcdb_type_release_info(pstr);
+ }
+
+ if (type_id_krb5_princ != -1) {
+ kcdb_attrib * attr;
+
+ kcdb_attrib_get_info(KCDB_ATTR_ID_NAME, &attr);
+
+ attr->type = type_id_krb5_princ;
+
+ kcdb_attrib_release_info(attr);
+ }
+
+ h_ccname_exit_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (h_ccname_exit_event) {
+ h_ccname_thread = CreateThread(NULL,
+ 200 * 1024,
+ k5_ccname_monitor_thread,
+ NULL,
+ 0,
+ NULL);
+ } else {
+ h_ccname_thread = NULL;
+ }
+ }
+ break;
+
+ case KMSG_SYSTEM_EXIT:
+ {
+
+ if (h_ccname_thread) {
+ SetEvent(h_ccname_exit_event);
+ WaitForSingleObject(h_ccname_thread, INFINITE);
+ CloseHandle(h_ccname_thread);
+ CloseHandle(h_ccname_exit_event);
+
+ h_ccname_exit_event = NULL;
+ h_ccname_thread = NULL;
+ }
+
+ if (k5_identpro_ctx) {
+ pkrb5_free_context(k5_identpro_ctx);
+ k5_identpro_ctx = NULL;
+ }
+
+ if (type_id_krb5_princ != -1) {
+ kcdb_attrib * attr;
+
+ kcdb_attrib_get_info(KCDB_ATTR_ID_NAME, &attr);
+
+ attr->type = KCDB_TYPE_STRING;
+
+ kcdb_attrib_release_info(attr);
+ }
+
+ /* allow a brief moment for any stale references to die */
+ Sleep(100);
+
+ if (type_regd_krb5_princ) {
+ kcdb_type_unregister(type_id_krb5_princ);
+ }
+ }
+ break;
+ }
+
+ return KHM_ERROR_SUCCESS;
+}
+
+khm_int32 KHMAPI
+k5_ident_callback(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam) {
+ switch(msg_type) {
+ case KMSG_SYSTEM:
+ return k5_msg_system_idpro(msg_type, msg_subtype, uparam, vparam);
+
+ case KMSG_IDENT:
+ return k5_msg_ident(msg_type, msg_subtype, uparam, vparam);
+ }
+
+ return KHM_ERROR_SUCCESS;
+}
diff --git a/src/windows/identity/plugins/krb5/krb5main.c b/src/windows/identity/plugins/krb5/krb5main.c
index 3d2f2c0e9..befa7a980 100644
--- a/src/windows/identity/plugins/krb5/krb5main.c
+++ b/src/windows/identity/plugins/krb5/krb5main.c
@@ -1,497 +1,497 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<kherror.h>
-
-kmm_module h_khModule; /* KMM's handle to this module */
-HINSTANCE hInstance;
-HMODULE hResModule; /* HMODULE to the resource library */
-const wchar_t * k5_facility = L"Krb5Cred";
-
-khm_int32 type_id_enctype = -1;
-khm_int32 type_id_addr_list = -1;
-khm_int32 type_id_krb5_flags = -1;
-khm_int32 type_id_krb5_princ = -1;
-khm_int32 type_id_kvno = -1;
-
-BOOL type_regd_enctype = FALSE;
-BOOL type_regd_addr_list = FALSE;
-BOOL type_regd_krb5_flags = FALSE;
-BOOL type_regd_krb5_princ = FALSE;
-BOOL type_regd_kvno = FALSE;
-
-khm_int32 attr_id_key_enctype = -1;
-khm_int32 attr_id_tkt_enctype = -1;
-khm_int32 attr_id_addr_list = -1;
-khm_int32 attr_id_krb5_flags = -1;
-khm_int32 attr_id_krb5_ccname = -1;
-khm_int32 attr_id_kvno = -1;
-khm_int32 attr_id_krb5_idflags = -1;
-
-BOOL attr_regd_key_enctype = FALSE;
-BOOL attr_regd_tkt_enctype = FALSE;
-BOOL attr_regd_addr_list = FALSE;
-BOOL attr_regd_krb5_flags = FALSE;
-BOOL attr_regd_krb5_ccname = FALSE;
-BOOL attr_regd_kvno = FALSE;
-BOOL attr_regd_krb5_idflags = FALSE;
-
-khm_handle csp_plugins = NULL;
-khm_handle csp_krbcred = NULL;
-khm_handle csp_params = NULL;
-
-BOOL is_k5_identpro = TRUE;
-
-khm_ui_4 k5_commctl_version;
-
-kmm_module_locale locales[] = {
- LOCALE_DEF(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US), L"krb5cred_en_us.dll", KMM_MLOC_FLAG_DEFAULT)
-};
-int n_locales = ARRAYLENGTH(locales);
-
-/* These two should not do anything */
-void init_krb() {
-}
-
-void exit_krb() {
-}
-
-/* called by the NetIDMgr module manager */
-KHMEXP khm_int32 KHMAPI init_module(kmm_module h_module) {
- khm_int32 rv = KHM_ERROR_SUCCESS;
- kmm_plugin_reg pi;
- wchar_t buf[256];
-
- h_khModule = h_module;
-
- rv = kmm_set_locale_info(h_module, locales, n_locales);
- if(KHM_SUCCEEDED(rv)) {
- hResModule = kmm_get_resource_hmodule(h_module);
- } else
- goto _exit;
-
- k5_commctl_version = khm_get_commctl_version(NULL);
-
- /* register the plugin */
- ZeroMemory(&pi, sizeof(pi));
- pi.name = KRB5_PLUGIN_NAME;
- pi.type = KHM_PITYPE_CRED;
- pi.icon = LoadImage(hResModule, MAKEINTRESOURCE(IDI_PLUGIN),
- IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
- pi.flags = 0;
- pi.msg_proc = k5_msg_callback;
- pi.description = buf;
- pi.dependencies = NULL;
- LoadString(hResModule, IDS_PLUGIN_DESC,
- buf, ARRAYLENGTH(buf));
- kmm_provide_plugin(h_module, &pi);
-
- ZeroMemory(&pi, sizeof(pi));
- pi.name = KRB5_IDENTPRO_NAME;
- pi.type = KHM_PITYPE_IDENT;
- pi.icon = LoadImage(hResModule, MAKEINTRESOURCE(IDI_PLUGIN),
- IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
- pi.flags = 0;
- pi.msg_proc = k5_ident_callback;
- pi.description = buf;
- pi.dependencies = KRB5_PLUGIN_NAME L"\0";
- LoadString(hResModule, IDS_IDENTPRO_DESC,
- buf, ARRAYLENGTH(buf));
- kmm_provide_plugin(h_module, &pi);
-
- if(KHM_FAILED(rv = init_imports()))
- goto _exit;
-
- if(KHM_FAILED(rv = init_error_funcs()))
- goto _exit;
-
- /* Register common data types */
- if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ENCTYPE, &type_id_enctype))) {
- kcdb_type type;
- kcdb_type *t32;
-
- kcdb_type_get_info(KCDB_TYPE_INT32, &t32);
-
- type.id = KCDB_TYPE_INVALID;
- type.name = TYPENAME_ENCTYPE;
- type.flags = KCDB_TYPE_FLAG_CB_FIXED;
- type.cb_max = t32->cb_max;
- type.cb_min = t32->cb_min;
- type.isValid = t32->isValid;
- type.comp = t32->comp;
- type.dup = t32->dup;
- type.toString = enctype_toString;
-
- rv = kcdb_type_register(&type, &type_id_enctype);
- kcdb_type_release_info(t32);
-
- if(KHM_FAILED(rv))
- goto _exit;
- type_regd_enctype = TRUE;
- }
-
- if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ADDR_LIST, &type_id_addr_list))) {
- kcdb_type type;
- kcdb_type *tdata;
-
- kcdb_type_get_info(KCDB_TYPE_DATA, &tdata);
-
- type.id = KCDB_TYPE_INVALID;
- type.name = TYPENAME_ADDR_LIST;
- type.flags = KCDB_TYPE_FLAG_CB_MIN;
- type.cb_min = 0;
- type.cb_max = 0;
- type.isValid = tdata->isValid;
- type.comp = addr_list_comp;
- type.dup = tdata->dup;
- type.toString = addr_list_toString;
-
- rv = kcdb_type_register(&type, &type_id_addr_list);
- kcdb_type_release_info(tdata);
-
- if(KHM_FAILED(rv))
- goto _exit;
- type_regd_addr_list = TRUE;
- }
-
- if(KHM_FAILED(kcdb_type_get_id(TYPENAME_KRB5_FLAGS, &type_id_krb5_flags))) {
- kcdb_type type;
- kcdb_type *t32;
-
- kcdb_type_get_info(KCDB_TYPE_INT32, &t32);
-
- type.id = KCDB_TYPE_INVALID;
- type.name = TYPENAME_KRB5_FLAGS;
- type.flags = KCDB_TYPE_FLAG_CB_FIXED;
- type.cb_max = t32->cb_max;
- type.cb_min = t32->cb_min;
- type.isValid = t32->isValid;
- type.comp = t32->comp;
- type.dup = t32->dup;
- type.toString = krb5flags_toString;
-
- rv = kcdb_type_register(&type, &type_id_krb5_flags);
- kcdb_type_release_info(t32);
-
- if(KHM_FAILED(rv))
- goto _exit;
- type_regd_krb5_flags = TRUE;
- }
-
- if (KHM_FAILED(kcdb_type_get_id(TYPENAME_KVNO, &type_id_kvno))) {
- kcdb_type type;
- kcdb_type *t32;
-
- kcdb_type_get_info(KCDB_TYPE_INT32, &t32);
-
- type.id = KCDB_TYPE_INVALID;
- type.name = TYPENAME_KVNO;
- type.flags = KCDB_TYPE_FLAG_CB_FIXED;
- type.cb_max = t32->cb_max;
- type.cb_min = t32->cb_min;
- type.isValid = t32->isValid;
- type.comp = t32->comp;
- type.dup = t32->dup;
- type.toString = kvno_toString;
-
- rv = kcdb_type_register(&type, &type_id_kvno);
- kcdb_type_release_info(t32);
-
- if (KHM_FAILED(rv))
- goto _exit;
-
- type_regd_kvno = TRUE;
- }
-
- /* Register common attributes */
- if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KEY_ENCTYPE, &attr_id_key_enctype))) {
- kcdb_attrib attrib;
- wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
- wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC];
- /* although we are loading a long descriptoin, it still fits
- in the short descriptoin buffer */
-
- ZeroMemory(&attrib, sizeof(attrib));
-
- attrib.name = ATTRNAME_KEY_ENCTYPE;
- attrib.id = KCDB_ATTR_INVALID;
- attrib.type = type_id_enctype;
- attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
- LoadString(hResModule, IDS_KEY_ENCTYPE_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
- LoadString(hResModule, IDS_KEY_ENCTYPE_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
- attrib.short_desc = sbuf;
- attrib.long_desc = lbuf;
-
- rv = kcdb_attrib_register(&attrib, &attr_id_key_enctype);
-
- if(KHM_FAILED(rv))
- goto _exit;
-
- attr_regd_key_enctype = TRUE;
- }
-
- if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_TKT_ENCTYPE, &attr_id_tkt_enctype))) {
- kcdb_attrib attrib;
- wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
- wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC];
- /* although we are loading a long descriptoin, it still fits
- in the short descriptoin buffer */
-
- ZeroMemory(&attrib, sizeof(attrib));
-
- attrib.name = ATTRNAME_TKT_ENCTYPE;
- attrib.id = KCDB_ATTR_INVALID;
- attrib.type = type_id_enctype;
- attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
- LoadString(hResModule, IDS_TKT_ENCTYPE_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
- LoadString(hResModule, IDS_TKT_ENCTYPE_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
- attrib.short_desc = sbuf;
- attrib.long_desc = lbuf;
-
- rv = kcdb_attrib_register(&attrib, &attr_id_tkt_enctype);
-
- if(KHM_FAILED(rv))
- goto _exit;
-
- attr_regd_tkt_enctype = TRUE;
- }
-
- if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_ADDR_LIST, &attr_id_addr_list))) {
- kcdb_attrib attrib;
- wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
- wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC];
- /* although we are loading a long descriptoin, it still fits
- in the short descriptoin buffer */
-
- ZeroMemory(&attrib, sizeof(attrib));
-
- attrib.name = ATTRNAME_ADDR_LIST;
- attrib.id = KCDB_ATTR_INVALID;
- attrib.type = type_id_addr_list;
- attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
- LoadString(hResModule, IDS_ADDR_LIST_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
- LoadString(hResModule, IDS_ADDR_LIST_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
- attrib.short_desc = sbuf;
- attrib.long_desc = lbuf;
-
- rv = kcdb_attrib_register(&attrib, &attr_id_addr_list);
-
- if(KHM_FAILED(rv))
- goto _exit;
-
- attr_regd_addr_list = TRUE;
- }
-
- if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_FLAGS, &attr_id_krb5_flags))) {
- kcdb_attrib attrib;
- wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
-
- /* although we are loading a long descriptoin, it still fits
- in the short descriptoin buffer */
-
- ZeroMemory(&attrib, sizeof(attrib));
-
- attrib.name = ATTRNAME_KRB5_FLAGS;
- attrib.id = KCDB_ATTR_INVALID;
- attrib.type = type_id_krb5_flags;
- attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
- LoadString(hResModule, IDS_KRB5_FLAGS_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
- attrib.short_desc = sbuf;
- attrib.long_desc = NULL;
-
- rv = kcdb_attrib_register(&attrib, &attr_id_krb5_flags);
-
- if(KHM_FAILED(rv))
- goto _exit;
-
- attr_regd_krb5_flags = TRUE;
- }
-
- if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_CCNAME, &attr_id_krb5_ccname))) {
- kcdb_attrib attrib;
- wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
- wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC];
- /* although we are loading a long descriptoin, it still fits
- in the short descriptoin buffer */
-
- ZeroMemory(&attrib, sizeof(attrib));
-
- attrib.name = ATTRNAME_KRB5_CCNAME;
- attrib.id = KCDB_ATTR_INVALID;
- attrib.type = KCDB_TYPE_STRING;
- attrib.flags =
- KCDB_ATTR_FLAG_PROPERTY |
- KCDB_ATTR_FLAG_TRANSIENT;
- LoadString(hResModule, IDS_KRB5_CCNAME_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
- LoadString(hResModule, IDS_KRB5_CCNAME_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
- attrib.short_desc = sbuf;
- attrib.long_desc = lbuf;
-
- rv = kcdb_attrib_register(&attrib, &attr_id_krb5_ccname);
-
- if(KHM_FAILED(rv))
- goto _exit;
-
- attr_regd_krb5_ccname = TRUE;
- }
-
- if (KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KVNO, &attr_id_kvno))) {
- kcdb_attrib attrib;
- wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
- wchar_t lbuf[KCDB_MAXCCH_LONG_DESC];
- /* although we are loading a long description, it still fits
- in the short description buffer */
-
- ZeroMemory(&attrib, sizeof(attrib));
-
- attrib.name = ATTRNAME_KVNO;
- attrib.id = KCDB_ATTR_INVALID;
- attrib.type = type_id_kvno;
- attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
- LoadString(hResModule, IDS_KVNO_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
- LoadString(hResModule, IDS_KVNO_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
- attrib.short_desc = sbuf;
- attrib.long_desc = lbuf;
-
- rv = kcdb_attrib_register(&attrib, &attr_id_kvno);
-
- if (KHM_FAILED(rv))
- goto _exit;
-
- attr_regd_kvno = TRUE;
- }
-
- if (KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_IDFLAGS, &attr_id_krb5_idflags))) {
- kcdb_attrib attrib;
-
- ZeroMemory(&attrib, sizeof(attrib));
-
- attrib.name = ATTRNAME_KRB5_IDFLAGS;
- attrib.id = KCDB_ATTR_INVALID;
- attrib.type = KCDB_TYPE_INT32;
- attrib.flags = KCDB_ATTR_FLAG_PROPERTY |
- KCDB_ATTR_FLAG_HIDDEN;
- /* we don't bother localizing these strings since the
- attribute is hidden. The user will not see these
- descriptions anyway. */
- attrib.short_desc = L"Krb5 ID flags";
- attrib.long_desc = L"Kerberos 5 Identity Flags";
-
- rv = kcdb_attrib_register(&attrib, &attr_id_krb5_idflags);
-
- if (KHM_FAILED(rv))
- goto _exit;
-
- attr_regd_krb5_idflags = TRUE;
- }
-
- rv = kmm_get_plugins_config(0, &csp_plugins);
- if(KHM_FAILED(rv)) goto _exit;
-
- rv = khc_load_schema(csp_plugins, schema_krbconfig);
- if(KHM_FAILED(rv)) goto _exit;
-
- rv = khc_open_space(csp_plugins, CSNAME_KRB5CRED, 0, &csp_krbcred);
- if(KHM_FAILED(rv)) goto _exit;
-
- rv = khc_open_space(csp_krbcred, CSNAME_PARAMS, 0, &csp_params);
- if(KHM_FAILED(rv)) goto _exit;
-
-_exit:
- return rv;
-}
-
-/* called by the NetIDMgr module manager */
-KHMEXP khm_int32 KHMAPI exit_module(kmm_module h_module) {
- exit_imports();
- exit_error_funcs();
-
- if(attr_regd_key_enctype)
- kcdb_attrib_unregister(attr_id_key_enctype);
- if(attr_regd_tkt_enctype)
- kcdb_attrib_unregister(attr_id_tkt_enctype);
- if(attr_regd_addr_list)
- kcdb_attrib_unregister(attr_id_addr_list);
- if(attr_regd_krb5_flags)
- kcdb_attrib_unregister(attr_id_krb5_flags);
- if(attr_regd_krb5_ccname)
- kcdb_attrib_unregister(attr_id_krb5_ccname);
- if(attr_regd_kvno)
- kcdb_attrib_unregister(attr_id_kvno);
- if(attr_regd_krb5_idflags)
- kcdb_attrib_unregister(attr_id_krb5_idflags);
-
- if(type_regd_enctype)
- kcdb_type_unregister(type_id_enctype);
- if(type_regd_addr_list)
- kcdb_type_unregister(type_id_addr_list);
- if(type_regd_krb5_flags)
- kcdb_type_unregister(type_id_krb5_flags);
- if(type_regd_kvno)
- kcdb_type_unregister(type_id_kvno);
-
- if(csp_params) {
- khc_close_space(csp_params);
- csp_params = NULL;
- }
-
- if(csp_krbcred) {
- khc_close_space(csp_krbcred);
- csp_krbcred = NULL;
- }
-
- if(csp_plugins) {
- khc_unload_schema(csp_plugins, schema_krbconfig);
- khc_close_space(csp_plugins);
- csp_plugins = NULL;
- }
-
- return KHM_ERROR_SUCCESS; /* the return code is ignored */
-}
-
-BOOL WINAPI DllMain(
- HINSTANCE hinstDLL,
- DWORD fdwReason,
- LPVOID lpvReserved
-)
-{
- switch(fdwReason) {
- case DLL_PROCESS_ATTACH:
- hInstance = hinstDLL;
- init_krb();
- break;
- case DLL_PROCESS_DETACH:
- exit_krb();
- break;
- case DLL_THREAD_ATTACH:
- break;
- case DLL_THREAD_DETACH:
- break;
- }
-
- return TRUE;
-}
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<kherror.h>
+
+kmm_module h_khModule; /* KMM's handle to this module */
+HINSTANCE hInstance;
+HMODULE hResModule; /* HMODULE to the resource library */
+const wchar_t * k5_facility = L"Krb5Cred";
+
+khm_int32 type_id_enctype = -1;
+khm_int32 type_id_addr_list = -1;
+khm_int32 type_id_krb5_flags = -1;
+khm_int32 type_id_krb5_princ = -1;
+khm_int32 type_id_kvno = -1;
+
+BOOL type_regd_enctype = FALSE;
+BOOL type_regd_addr_list = FALSE;
+BOOL type_regd_krb5_flags = FALSE;
+BOOL type_regd_krb5_princ = FALSE;
+BOOL type_regd_kvno = FALSE;
+
+khm_int32 attr_id_key_enctype = -1;
+khm_int32 attr_id_tkt_enctype = -1;
+khm_int32 attr_id_addr_list = -1;
+khm_int32 attr_id_krb5_flags = -1;
+khm_int32 attr_id_krb5_ccname = -1;
+khm_int32 attr_id_kvno = -1;
+khm_int32 attr_id_krb5_idflags = -1;
+
+BOOL attr_regd_key_enctype = FALSE;
+BOOL attr_regd_tkt_enctype = FALSE;
+BOOL attr_regd_addr_list = FALSE;
+BOOL attr_regd_krb5_flags = FALSE;
+BOOL attr_regd_krb5_ccname = FALSE;
+BOOL attr_regd_kvno = FALSE;
+BOOL attr_regd_krb5_idflags = FALSE;
+
+khm_handle csp_plugins = NULL;
+khm_handle csp_krbcred = NULL;
+khm_handle csp_params = NULL;
+
+BOOL is_k5_identpro = TRUE;
+
+khm_ui_4 k5_commctl_version;
+
+kmm_module_locale locales[] = {
+ LOCALE_DEF(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US), L"krb5cred_en_us.dll", KMM_MLOC_FLAG_DEFAULT)
+};
+int n_locales = ARRAYLENGTH(locales);
+
+/* These two should not do anything */
+void init_krb() {
+}
+
+void exit_krb() {
+}
+
+/* called by the NetIDMgr module manager */
+KHMEXP khm_int32 KHMAPI init_module(kmm_module h_module) {
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+ kmm_plugin_reg pi;
+ wchar_t buf[256];
+
+ h_khModule = h_module;
+
+ rv = kmm_set_locale_info(h_module, locales, n_locales);
+ if(KHM_SUCCEEDED(rv)) {
+ hResModule = kmm_get_resource_hmodule(h_module);
+ } else
+ goto _exit;
+
+ k5_commctl_version = khm_get_commctl_version(NULL);
+
+ /* register the plugin */
+ ZeroMemory(&pi, sizeof(pi));
+ pi.name = KRB5_PLUGIN_NAME;
+ pi.type = KHM_PITYPE_CRED;
+ pi.icon = LoadImage(hResModule, MAKEINTRESOURCE(IDI_PLUGIN),
+ IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
+ pi.flags = 0;
+ pi.msg_proc = k5_msg_callback;
+ pi.description = buf;
+ pi.dependencies = NULL;
+ LoadString(hResModule, IDS_PLUGIN_DESC,
+ buf, ARRAYLENGTH(buf));
+ kmm_provide_plugin(h_module, &pi);
+
+ ZeroMemory(&pi, sizeof(pi));
+ pi.name = KRB5_IDENTPRO_NAME;
+ pi.type = KHM_PITYPE_IDENT;
+ pi.icon = LoadImage(hResModule, MAKEINTRESOURCE(IDI_PLUGIN),
+ IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
+ pi.flags = 0;
+ pi.msg_proc = k5_ident_callback;
+ pi.description = buf;
+ pi.dependencies = KRB5_PLUGIN_NAME L"\0";
+ LoadString(hResModule, IDS_IDENTPRO_DESC,
+ buf, ARRAYLENGTH(buf));
+ kmm_provide_plugin(h_module, &pi);
+
+ if(KHM_FAILED(rv = init_imports()))
+ goto _exit;
+
+ if(KHM_FAILED(rv = init_error_funcs()))
+ goto _exit;
+
+ /* Register common data types */
+ if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ENCTYPE, &type_id_enctype))) {
+ kcdb_type type;
+ kcdb_type *t32;
+
+ kcdb_type_get_info(KCDB_TYPE_INT32, &t32);
+
+ type.id = KCDB_TYPE_INVALID;
+ type.name = TYPENAME_ENCTYPE;
+ type.flags = KCDB_TYPE_FLAG_CB_FIXED;
+ type.cb_max = t32->cb_max;
+ type.cb_min = t32->cb_min;
+ type.isValid = t32->isValid;
+ type.comp = t32->comp;
+ type.dup = t32->dup;
+ type.toString = enctype_toString;
+
+ rv = kcdb_type_register(&type, &type_id_enctype);
+ kcdb_type_release_info(t32);
+
+ if(KHM_FAILED(rv))
+ goto _exit;
+ type_regd_enctype = TRUE;
+ }
+
+ if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ADDR_LIST, &type_id_addr_list))) {
+ kcdb_type type;
+ kcdb_type *tdata;
+
+ kcdb_type_get_info(KCDB_TYPE_DATA, &tdata);
+
+ type.id = KCDB_TYPE_INVALID;
+ type.name = TYPENAME_ADDR_LIST;
+ type.flags = KCDB_TYPE_FLAG_CB_MIN;
+ type.cb_min = 0;
+ type.cb_max = 0;
+ type.isValid = tdata->isValid;
+ type.comp = addr_list_comp;
+ type.dup = tdata->dup;
+ type.toString = addr_list_toString;
+
+ rv = kcdb_type_register(&type, &type_id_addr_list);
+ kcdb_type_release_info(tdata);
+
+ if(KHM_FAILED(rv))
+ goto _exit;
+ type_regd_addr_list = TRUE;
+ }
+
+ if(KHM_FAILED(kcdb_type_get_id(TYPENAME_KRB5_FLAGS, &type_id_krb5_flags))) {
+ kcdb_type type;
+ kcdb_type *t32;
+
+ kcdb_type_get_info(KCDB_TYPE_INT32, &t32);
+
+ type.id = KCDB_TYPE_INVALID;
+ type.name = TYPENAME_KRB5_FLAGS;
+ type.flags = KCDB_TYPE_FLAG_CB_FIXED;
+ type.cb_max = t32->cb_max;
+ type.cb_min = t32->cb_min;
+ type.isValid = t32->isValid;
+ type.comp = t32->comp;
+ type.dup = t32->dup;
+ type.toString = krb5flags_toString;
+
+ rv = kcdb_type_register(&type, &type_id_krb5_flags);
+ kcdb_type_release_info(t32);
+
+ if(KHM_FAILED(rv))
+ goto _exit;
+ type_regd_krb5_flags = TRUE;
+ }
+
+ if (KHM_FAILED(kcdb_type_get_id(TYPENAME_KVNO, &type_id_kvno))) {
+ kcdb_type type;
+ kcdb_type *t32;
+
+ kcdb_type_get_info(KCDB_TYPE_INT32, &t32);
+
+ type.id = KCDB_TYPE_INVALID;
+ type.name = TYPENAME_KVNO;
+ type.flags = KCDB_TYPE_FLAG_CB_FIXED;
+ type.cb_max = t32->cb_max;
+ type.cb_min = t32->cb_min;
+ type.isValid = t32->isValid;
+ type.comp = t32->comp;
+ type.dup = t32->dup;
+ type.toString = kvno_toString;
+
+ rv = kcdb_type_register(&type, &type_id_kvno);
+ kcdb_type_release_info(t32);
+
+ if (KHM_FAILED(rv))
+ goto _exit;
+
+ type_regd_kvno = TRUE;
+ }
+
+ /* Register common attributes */
+ if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KEY_ENCTYPE, &attr_id_key_enctype))) {
+ kcdb_attrib attrib;
+ wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
+ wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC];
+ /* although we are loading a long descriptoin, it still fits
+ in the short descriptoin buffer */
+
+ ZeroMemory(&attrib, sizeof(attrib));
+
+ attrib.name = ATTRNAME_KEY_ENCTYPE;
+ attrib.id = KCDB_ATTR_INVALID;
+ attrib.type = type_id_enctype;
+ attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
+ LoadString(hResModule, IDS_KEY_ENCTYPE_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
+ LoadString(hResModule, IDS_KEY_ENCTYPE_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
+ attrib.short_desc = sbuf;
+ attrib.long_desc = lbuf;
+
+ rv = kcdb_attrib_register(&attrib, &attr_id_key_enctype);
+
+ if(KHM_FAILED(rv))
+ goto _exit;
+
+ attr_regd_key_enctype = TRUE;
+ }
+
+ if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_TKT_ENCTYPE, &attr_id_tkt_enctype))) {
+ kcdb_attrib attrib;
+ wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
+ wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC];
+ /* although we are loading a long descriptoin, it still fits
+ in the short descriptoin buffer */
+
+ ZeroMemory(&attrib, sizeof(attrib));
+
+ attrib.name = ATTRNAME_TKT_ENCTYPE;
+ attrib.id = KCDB_ATTR_INVALID;
+ attrib.type = type_id_enctype;
+ attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
+ LoadString(hResModule, IDS_TKT_ENCTYPE_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
+ LoadString(hResModule, IDS_TKT_ENCTYPE_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
+ attrib.short_desc = sbuf;
+ attrib.long_desc = lbuf;
+
+ rv = kcdb_attrib_register(&attrib, &attr_id_tkt_enctype);
+
+ if(KHM_FAILED(rv))
+ goto _exit;
+
+ attr_regd_tkt_enctype = TRUE;
+ }
+
+ if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_ADDR_LIST, &attr_id_addr_list))) {
+ kcdb_attrib attrib;
+ wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
+ wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC];
+ /* although we are loading a long descriptoin, it still fits
+ in the short descriptoin buffer */
+
+ ZeroMemory(&attrib, sizeof(attrib));
+
+ attrib.name = ATTRNAME_ADDR_LIST;
+ attrib.id = KCDB_ATTR_INVALID;
+ attrib.type = type_id_addr_list;
+ attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
+ LoadString(hResModule, IDS_ADDR_LIST_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
+ LoadString(hResModule, IDS_ADDR_LIST_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
+ attrib.short_desc = sbuf;
+ attrib.long_desc = lbuf;
+
+ rv = kcdb_attrib_register(&attrib, &attr_id_addr_list);
+
+ if(KHM_FAILED(rv))
+ goto _exit;
+
+ attr_regd_addr_list = TRUE;
+ }
+
+ if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_FLAGS, &attr_id_krb5_flags))) {
+ kcdb_attrib attrib;
+ wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
+
+ /* although we are loading a long descriptoin, it still fits
+ in the short descriptoin buffer */
+
+ ZeroMemory(&attrib, sizeof(attrib));
+
+ attrib.name = ATTRNAME_KRB5_FLAGS;
+ attrib.id = KCDB_ATTR_INVALID;
+ attrib.type = type_id_krb5_flags;
+ attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
+ LoadString(hResModule, IDS_KRB5_FLAGS_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
+ attrib.short_desc = sbuf;
+ attrib.long_desc = NULL;
+
+ rv = kcdb_attrib_register(&attrib, &attr_id_krb5_flags);
+
+ if(KHM_FAILED(rv))
+ goto _exit;
+
+ attr_regd_krb5_flags = TRUE;
+ }
+
+ if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_CCNAME, &attr_id_krb5_ccname))) {
+ kcdb_attrib attrib;
+ wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
+ wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC];
+ /* although we are loading a long descriptoin, it still fits
+ in the short descriptoin buffer */
+
+ ZeroMemory(&attrib, sizeof(attrib));
+
+ attrib.name = ATTRNAME_KRB5_CCNAME;
+ attrib.id = KCDB_ATTR_INVALID;
+ attrib.type = KCDB_TYPE_STRING;
+ attrib.flags =
+ KCDB_ATTR_FLAG_PROPERTY |
+ KCDB_ATTR_FLAG_TRANSIENT;
+ LoadString(hResModule, IDS_KRB5_CCNAME_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
+ LoadString(hResModule, IDS_KRB5_CCNAME_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
+ attrib.short_desc = sbuf;
+ attrib.long_desc = lbuf;
+
+ rv = kcdb_attrib_register(&attrib, &attr_id_krb5_ccname);
+
+ if(KHM_FAILED(rv))
+ goto _exit;
+
+ attr_regd_krb5_ccname = TRUE;
+ }
+
+ if (KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KVNO, &attr_id_kvno))) {
+ kcdb_attrib attrib;
+ wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
+ wchar_t lbuf[KCDB_MAXCCH_LONG_DESC];
+ /* although we are loading a long description, it still fits
+ in the short description buffer */
+
+ ZeroMemory(&attrib, sizeof(attrib));
+
+ attrib.name = ATTRNAME_KVNO;
+ attrib.id = KCDB_ATTR_INVALID;
+ attrib.type = type_id_kvno;
+ attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
+ LoadString(hResModule, IDS_KVNO_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
+ LoadString(hResModule, IDS_KVNO_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
+ attrib.short_desc = sbuf;
+ attrib.long_desc = lbuf;
+
+ rv = kcdb_attrib_register(&attrib, &attr_id_kvno);
+
+ if (KHM_FAILED(rv))
+ goto _exit;
+
+ attr_regd_kvno = TRUE;
+ }
+
+ if (KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_IDFLAGS, &attr_id_krb5_idflags))) {
+ kcdb_attrib attrib;
+
+ ZeroMemory(&attrib, sizeof(attrib));
+
+ attrib.name = ATTRNAME_KRB5_IDFLAGS;
+ attrib.id = KCDB_ATTR_INVALID;
+ attrib.type = KCDB_TYPE_INT32;
+ attrib.flags = KCDB_ATTR_FLAG_PROPERTY |
+ KCDB_ATTR_FLAG_HIDDEN;
+ /* we don't bother localizing these strings since the
+ attribute is hidden. The user will not see these
+ descriptions anyway. */
+ attrib.short_desc = L"Krb5 ID flags";
+ attrib.long_desc = L"Kerberos 5 Identity Flags";
+
+ rv = kcdb_attrib_register(&attrib, &attr_id_krb5_idflags);
+
+ if (KHM_FAILED(rv))
+ goto _exit;
+
+ attr_regd_krb5_idflags = TRUE;
+ }
+
+ rv = kmm_get_plugins_config(0, &csp_plugins);
+ if(KHM_FAILED(rv)) goto _exit;
+
+ rv = khc_load_schema(csp_plugins, schema_krbconfig);
+ if(KHM_FAILED(rv)) goto _exit;
+
+ rv = khc_open_space(csp_plugins, CSNAME_KRB5CRED, 0, &csp_krbcred);
+ if(KHM_FAILED(rv)) goto _exit;
+
+ rv = khc_open_space(csp_krbcred, CSNAME_PARAMS, 0, &csp_params);
+ if(KHM_FAILED(rv)) goto _exit;
+
+_exit:
+ return rv;
+}
+
+/* called by the NetIDMgr module manager */
+KHMEXP khm_int32 KHMAPI exit_module(kmm_module h_module) {
+ exit_imports();
+ exit_error_funcs();
+
+ if(attr_regd_key_enctype)
+ kcdb_attrib_unregister(attr_id_key_enctype);
+ if(attr_regd_tkt_enctype)
+ kcdb_attrib_unregister(attr_id_tkt_enctype);
+ if(attr_regd_addr_list)
+ kcdb_attrib_unregister(attr_id_addr_list);
+ if(attr_regd_krb5_flags)
+ kcdb_attrib_unregister(attr_id_krb5_flags);
+ if(attr_regd_krb5_ccname)
+ kcdb_attrib_unregister(attr_id_krb5_ccname);
+ if(attr_regd_kvno)
+ kcdb_attrib_unregister(attr_id_kvno);
+ if(attr_regd_krb5_idflags)
+ kcdb_attrib_unregister(attr_id_krb5_idflags);
+
+ if(type_regd_enctype)
+ kcdb_type_unregister(type_id_enctype);
+ if(type_regd_addr_list)
+ kcdb_type_unregister(type_id_addr_list);
+ if(type_regd_krb5_flags)
+ kcdb_type_unregister(type_id_krb5_flags);
+ if(type_regd_kvno)
+ kcdb_type_unregister(type_id_kvno);
+
+ if(csp_params) {
+ khc_close_space(csp_params);
+ csp_params = NULL;
+ }
+
+ if(csp_krbcred) {
+ khc_close_space(csp_krbcred);
+ csp_krbcred = NULL;
+ }
+
+ if(csp_plugins) {
+ khc_unload_schema(csp_plugins, schema_krbconfig);
+ khc_close_space(csp_plugins);
+ csp_plugins = NULL;
+ }
+
+ return KHM_ERROR_SUCCESS; /* the return code is ignored */
+}
+
+BOOL WINAPI DllMain(
+ HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved
+)
+{
+ switch(fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ hInstance = hinstDLL;
+ init_krb();
+ break;
+ case DLL_PROCESS_DETACH:
+ exit_krb();
+ break;
+ case DLL_THREAD_ATTACH:
+ break;
+ case DLL_THREAD_DETACH:
+ break;
+ }
+
+ return TRUE;
+}
diff --git a/src/windows/identity/plugins/krb5/krb5newcreds.c b/src/windows/identity/plugins/krb5/krb5newcreds.c
index edd64725d..d2458fe50 100644
--- a/src/windows/identity/plugins/krb5/krb5newcreds.c
+++ b/src/windows/identity/plugins/krb5/krb5newcreds.c
@@ -1,2747 +1,2747 @@
-/*
- * Copyright (c) 2006 Secure Endpoints Inc.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<kherror.h>
-#include<khmsgtypes.h>
-#include<strsafe.h>
-#include<krb5.h>
-
-#include<commctrl.h>
-
-#include<assert.h>
-
-extern LPVOID k5_main_fiber;
-extern LPVOID k5_kinit_fiber;
-
-typedef struct k5_dlg_data_t {
- khui_new_creds * nc;
-
- khui_tracker tc_lifetime;
- khui_tracker tc_renew;
-
- BOOL dirty; /* is the data in sync with the
- configuration store? */
- BOOL sync; /* is the data in sync with the kinit
- request? */
- DWORD renewable;
- DWORD forwardable;
- DWORD proxiable;
- DWORD addressless;
- DWORD publicIP;
-
- wchar_t * cred_message; /* overrides the credential text, if
- non-NULL */
- BOOL pwd_change; /* force a password change */
-} k5_dlg_data;
-
-
-INT_PTR
-k5_handle_wm_initdialog(HWND hwnd,
- WPARAM wParam,
- LPARAM lParam)
-{
- HWND hw;
- k5_dlg_data * d;
- khui_new_creds_by_type * nct;
-
- d = PMALLOC(sizeof(*d));
- ZeroMemory(d, sizeof(*d));
- /* lParam is a pointer to a khui_new_creds structure */
- d->nc = (khui_new_creds *) lParam;
- khui_cw_find_type(d->nc, credtype_id_krb5, &nct);
-
-#pragma warning(push)
-#pragma warning(disable: 4244)
- SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) d);
-#pragma warning(pop)
-
- nct->aux = (LPARAM) d;
-
- if (d->nc->subtype == KMSG_CRED_NEW_CREDS) {
- khui_tracker_initialize(&d->tc_lifetime);
- khui_tracker_initialize(&d->tc_renew);
-
- hw = GetDlgItem(hwnd, IDC_NCK5_LIFETIME_EDIT);
- khui_tracker_install(hw, &d->tc_lifetime);
-
- hw = GetDlgItem(hwnd, IDC_NCK5_RENEW_EDIT);
- khui_tracker_install(hw, &d->tc_renew);
- }
- return TRUE;
-}
-
-INT_PTR
-k5_handle_wm_destroy(HWND hwnd,
- WPARAM wParam,
- LPARAM lParam)
-{
- k5_dlg_data * d;
- khui_new_creds_by_type * nct = NULL;
-
- d = (k5_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (!d)
- return TRUE;
-
- khui_cw_find_type(d->nc, credtype_id_krb5, &nct);
-
-#ifdef DEBUG
- assert(nct);
-#endif
-
- nct->aux = 0;
-
- if (d->nc->subtype == KMSG_CRED_NEW_CREDS) {
- khui_tracker_kill_controls(&d->tc_renew);
- khui_tracker_kill_controls(&d->tc_lifetime);
- }
-
- PFREE(d);
-
- return TRUE;
-}
-
-LRESULT
-k5_force_password_change(k5_dlg_data * d) {
- /* we are turning this dialog into a change password dialog... */
- wchar_t wbuf[KHUI_MAXCCH_BANNER];
-
- khui_cw_clear_prompts(d->nc);
-
- LoadString(hResModule, IDS_NC_PWD_BANNER,
- wbuf, ARRAYLENGTH(wbuf));
- khui_cw_begin_custom_prompts(d->nc, 3, NULL, wbuf);
-
- LoadString(hResModule, IDS_NC_PWD_PWD,
- wbuf, ARRAYLENGTH(wbuf));
- khui_cw_add_prompt(d->nc, KHUI_NCPROMPT_TYPE_PASSWORD,
- wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);
-
- LoadString(hResModule, IDS_NC_PWD_NPWD,
- wbuf, ARRAYLENGTH(wbuf));
- khui_cw_add_prompt(d->nc, KHUI_NCPROMPT_TYPE_NEW_PASSWORD,
- wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);
-
- LoadString(hResModule, IDS_NC_PWD_NPWD_AGAIN,
- wbuf, ARRAYLENGTH(wbuf));
- khui_cw_add_prompt(d->nc, KHUI_NCPROMPT_TYPE_NEW_PASSWORD_AGAIN,
- wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);
-
- d->pwd_change = TRUE;
-
- if (is_k5_identpro &&
- d->nc->n_identities > 0 &&
- d->nc->identities[0]) {
-
- kcdb_identity_set_flags(d->nc->identities[0],
- KCDB_IDENT_FLAG_VALID,
- KCDB_IDENT_FLAG_VALID);
-
- }
-
- PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT),
- (LPARAM) d->nc);
-
- return TRUE;
-}
-
-INT_PTR
-k5_handle_wmnc_notify(HWND hwnd,
- WPARAM wParam,
- LPARAM lParam)
-{
- switch(HIWORD(wParam)) {
- case WMNC_DIALOG_MOVE:
- {
- k5_dlg_data * d;
-
- d = (k5_dlg_data *)(LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (d->nc->subtype == KMSG_CRED_NEW_CREDS) {
- khui_tracker_reposition(&d->tc_lifetime);
- khui_tracker_reposition(&d->tc_renew);
- }
-
- return TRUE;
- }
- break;
-
- case WMNC_DIALOG_SETUP:
- {
- k5_dlg_data * d;
- BOOL old_sync;
-
- d = (k5_dlg_data *)(LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if (d->nc->subtype == KMSG_CRED_PASSWORD)
- return TRUE;
-
- /* we save the value of the 'sync' field here because some
- of the notifications that are generated while setting
- the controls overwrite the field. */
- old_sync = d->sync;
-
- /* need to update the controls with d->* */
- SendDlgItemMessage(hwnd, IDC_NCK5_RENEWABLE,
- BM_SETCHECK,
- (d->renewable? BST_CHECKED : BST_UNCHECKED),
- 0);
- EnableWindow(GetDlgItem(hwnd, IDC_NCK5_RENEW_EDIT),
- !!d->renewable);
-
- khui_tracker_refresh(&d->tc_lifetime);
- khui_tracker_refresh(&d->tc_renew);
-
- SendDlgItemMessage(hwnd, IDC_NCK5_FORWARDABLE,
- BM_SETCHECK,
- (d->forwardable ? BST_CHECKED : BST_UNCHECKED),
- 0);
-
- SendDlgItemMessage(hwnd, IDC_NCK5_ADDRESS,
- BM_SETCHECK,
- (d->addressless ? BST_CHECKED : BST_UNCHECKED),
- 0);
-
- SendDlgItemMessage(hwnd, IDC_NCK5_PUBLICIP,
- IPM_SETADDRESS,
- 0, d->publicIP);
-
- EnableWindow(GetDlgItem(hwnd, IDC_NCK5_PUBLICIP), !d->addressless);
-
- d->sync = old_sync;
- }
- break;
-
- case WMNC_CREDTEXT_LINK:
- {
- k5_dlg_data * d;
- khui_htwnd_link * l;
- khui_new_creds * nc;
- wchar_t linktext[128];
-
- d = (k5_dlg_data *)(LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
- nc = d->nc;
- l = (khui_htwnd_link *) lParam;
-
- if (!l)
- break;
-
- StringCchCopyN(linktext, ARRAYLENGTH(linktext),
- l->id, l->id_len);
-
- if (!wcscmp(linktext, L"Krb5Cred:!Passwd")) {
- return k5_force_password_change(d);
- }
- }
- break;
-
- case WMNC_UPDATE_CREDTEXT:
- {
- k5_dlg_data * d;
- khui_new_creds * nc;
- khui_new_creds_by_type * nct;
- wchar_t sbuf[1024];
- wchar_t fbuf[256];
- wchar_t tbuf[256];
- size_t cbsize;
- khm_int32 flags;
-
- d = (k5_dlg_data *)(LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
- nc = d->nc;
- khui_cw_find_type(nc, credtype_id_krb5, &nct);
-
- if(nct == NULL)
- break;
-
- if(nct->credtext)
- PFREE(nct->credtext);
- nct->credtext = NULL;
-
- tbuf[0] = L'\0';
-
- if (nc->n_identities > 0 &&
- KHM_SUCCEEDED(kcdb_identity_get_flags(nc->identities[0],
- &flags)) &&
- (flags & KCDB_IDENT_FLAG_VALID) &&
- nc->subtype == KMSG_CRED_NEW_CREDS &&
- !d->pwd_change) {
-
- if (is_k5_identpro)
- k5_get_realm_from_nc(nc, tbuf, ARRAYLENGTH(tbuf));
- else
- GetDlgItemText(hwnd, IDC_NCK5_REALM, tbuf,
- ARRAYLENGTH(tbuf));
-
- /*TODO: if additional realms were specified, then those
- must be listed as well */
- LoadString(hResModule, IDS_KRB5_CREDTEXT_0,
- fbuf, ARRAYLENGTH(fbuf));
- StringCbPrintf(sbuf, sizeof(sbuf), fbuf,
- tbuf);
-
- StringCbLength(sbuf, sizeof(sbuf), &cbsize);
- cbsize += sizeof(wchar_t);
-
- nct->credtext = PMALLOC(cbsize);
-
- StringCbCopy(nct->credtext, cbsize, sbuf);
- } else if (nc->n_identities > 0 &&
- (nc->subtype == KMSG_CRED_PASSWORD ||
- (nc->subtype == KMSG_CRED_NEW_CREDS && d->pwd_change))) {
- cbsize = sizeof(tbuf);
- kcdb_identity_get_name(nc->identities[0], tbuf, &cbsize);
-
- LoadString(hResModule, IDS_KRB5_CREDTEXT_P0,
- fbuf, ARRAYLENGTH(fbuf));
- StringCbPrintf(sbuf, sizeof(sbuf), fbuf, tbuf);
-
- StringCbLength(sbuf, sizeof(sbuf), &cbsize);
- cbsize += sizeof(wchar_t);
-
- nct->credtext = PMALLOC(cbsize);
-
- StringCbCopy(nct->credtext, cbsize, sbuf);
- } else {
- if (d->cred_message) {
- StringCbLength(d->cred_message, KHUI_MAXCB_BANNER,
- &cbsize);
- cbsize += sizeof(wchar_t);
-
- nct->credtext = PMALLOC(cbsize);
-
- StringCbCopy(nct->credtext, cbsize, d->cred_message);
- }
- }
- }
- break;
-
- case WMNC_IDENTITY_CHANGE:
- {
- /* There has been a change of identity */
- k5_dlg_data * d;
-
- d = (k5_dlg_data *)(LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- kmq_post_sub_msg(k5_sub, KMSG_CRED,
- KMSG_CRED_DIALOG_NEW_IDENTITY,
- 0, (void *) d->nc);
- }
- break;
-
- case WMNC_DIALOG_PREPROCESS:
- {
- k5_dlg_data * d;
-
- d = (k5_dlg_data *)(LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- if(!d->sync && d->nc->result == KHUI_NC_RESULT_PROCESS) {
- kmq_post_sub_msg(k5_sub, KMSG_CRED,
- KMSG_CRED_DIALOG_NEW_OPTIONS,
- 0, (void *) d->nc);
- }
- }
- break;
-
- case K5_SET_CRED_MSG:
- {
- k5_dlg_data * d;
- khm_size cb;
- wchar_t * msg;
-
- d = (k5_dlg_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- msg = (wchar_t *) lParam;
-
- if (d->cred_message) {
- PFREE(d->cred_message);
- d->cred_message = NULL;
- }
-
- if (msg &&
- SUCCEEDED(StringCbLength(msg,
- KHUI_MAXCB_MESSAGE,
- &cb))) {
- cb += sizeof(wchar_t);
- d->cred_message = PMALLOC(cb);
-#ifdef DEBUG
- assert(d->cred_message);
-#endif
- StringCbCopy(d->cred_message, cb, msg);
- }
- }
- break;
- }
-
- return 0;
-}
-
-INT_PTR
-k5_handle_wm_notify(HWND hwnd,
- WPARAM wParam,
- LPARAM lParam) {
- LPNMHDR pnmh;
- k5_dlg_data * d;
-
- pnmh = (LPNMHDR) lParam;
- if (pnmh->idFrom == IDC_NCK5_PUBLICIP &&
- pnmh->code == IPN_FIELDCHANGED) {
-
- d = (k5_dlg_data *) (LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
-
- SendDlgItemMessage(hwnd, IDC_NCK5_PUBLICIP,
- IPM_GETADDRESS,
- 0, (LPARAM) &d->publicIP);
-
- d->dirty = TRUE;
- d->sync = FALSE;
-
- return TRUE;
- }
-
- return 0;
-}
-
-INT_PTR
-k5_handle_wm_command(HWND hwnd,
- WPARAM wParam,
- LPARAM lParam)
-{
- int cid;
- int notif;
- k5_dlg_data * d;
-
- d = (k5_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
-
- cid = LOWORD(wParam);
- notif = HIWORD(wParam);
-
- if(notif == BN_CLICKED && cid == IDC_NCK5_RENEWABLE) {
- int c;
- c = (int) SendDlgItemMessage(hwnd, IDC_NCK5_RENEWABLE,
- BM_GETCHECK, 0, 0);
- if(c==BST_CHECKED) {
- EnableWindow(GetDlgItem(hwnd, IDC_NCK5_RENEW_EDIT), TRUE);
- d->renewable = TRUE;
- } else {
- EnableWindow(GetDlgItem(hwnd, IDC_NCK5_RENEW_EDIT), FALSE);
- d->renewable = FALSE;
- }
- d->dirty = TRUE;
- d->sync = FALSE;
- } else if(notif == BN_CLICKED && cid == IDC_NCK5_FORWARDABLE) {
- int c;
- c = (int) SendDlgItemMessage(hwnd, IDC_NCK5_FORWARDABLE,
- BM_GETCHECK, 0, 0);
- if(c==BST_CHECKED) {
- d->forwardable = TRUE;
- } else {
- d->forwardable = FALSE;
- }
- d->dirty = TRUE;
- d->sync = FALSE;
- } else if (notif == BN_CLICKED && cid == IDC_NCK5_ADDRESS) {
- int c;
-
- c = (int) SendDlgItemMessage(hwnd, IDC_NCK5_ADDRESS,
- BM_GETCHECK, 0, 0);
-
- if (c==BST_CHECKED) {
- d->addressless = TRUE;
- } else {
- d->addressless = FALSE;
- }
- d->dirty = TRUE;
- d->sync = FALSE;
-
- EnableWindow(GetDlgItem(hwnd, IDC_NCK5_PUBLICIP), !d->addressless);
- } else if (notif == EN_CHANGE && (cid == IDC_NCK5_RENEW_EDIT ||
- cid == IDC_NCK5_LIFETIME_EDIT)) {
- d->dirty = TRUE;
- d->sync = FALSE;
- } else if((notif == CBN_SELCHANGE ||
- notif == CBN_KILLFOCUS) &&
- cid == IDC_NCK5_REALM &&
- !is_k5_identpro) {
- /* find out what the realm of the current identity
- is, and if they are the same, then we don't do
- anything */
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- wchar_t realm[KCDB_IDENT_MAXCCH_NAME];
- wchar_t *r;
- khm_size cbsize;
- khm_handle ident;
- int idx;
-
- if(d->nc->n_identities > 0) {
- if(notif == CBN_SELCHANGE) {
- idx = (int) SendDlgItemMessage(hwnd, IDC_NCK5_REALM,
- CB_GETCURSEL, 0, 0);
- SendDlgItemMessage(hwnd, IDC_NCK5_REALM,
- CB_GETLBTEXT, idx, (LPARAM) realm);
- } else {
- GetDlgItemText(hwnd, IDC_NCK5_REALM,
- realm, ARRAYLENGTH(realm));
- }
- cbsize = sizeof(idname);
- if(KHM_SUCCEEDED(kcdb_identity_get_name(d->nc->identities[0],
- idname, &cbsize))) {
- r = wcschr(idname, L'@');
- if(r && !wcscmp(realm, r+1))
- return 0; /* nothing to do */
-
- if(!r) {
- r = idname + wcslen(idname);
- *r++ = L'@';
- *r++ = 0;
- }
-
- /* if we get here, we have a new user */
- StringCchCopy(r+1,
- ARRAYLENGTH(idname) - ((r+1) - idname),
- realm);
- if(KHM_SUCCEEDED(kcdb_identity_create(idname,
- KCDB_IDENT_FLAG_CREATE,
- &ident))) {
- khui_cw_set_primary_id(d->nc, ident);
- kcdb_identity_release(ident);
- }
- return 0;
- }
- }
-
- /* if we get here, we have a new realm, but there is no
- identity */
- PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
- }
-
- return 0;
-}
-
-
-/* Dialog procedure for the Krb5 credentials type panel.
-
- NOTE: Runs in the context of the UI thread
-*/
-INT_PTR CALLBACK
-k5_nc_dlg_proc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- switch(uMsg) {
- case WM_INITDIALOG:
- return k5_handle_wm_initdialog(hwnd, wParam, lParam);
-
- case WM_COMMAND:
- return k5_handle_wm_command(hwnd, wParam, lParam);
-
- case KHUI_WM_NC_NOTIFY:
- return k5_handle_wmnc_notify(hwnd, wParam, lParam);
-
- case WM_NOTIFY:
- return k5_handle_wm_notify(hwnd, wParam, lParam);
-
- case WM_DESTROY:
- return k5_handle_wm_destroy(hwnd, wParam, lParam);
- }
- return FALSE;
-}
-
-/* forward dcl */
-krb5_error_code KRB5_CALLCONV
-k5_kinit_prompter(krb5_context context,
- void *data,
- const char *name,
- const char *banner,
- int num_prompts,
- krb5_prompt prompts[]);
-
-
-
-fiber_job g_fjob; /* global fiber job object */
-
-static BOOL
-k5_cached_kinit_prompter(void);
-
-static BOOL
-k5_cp_check_continue(void);
-
-/*
- Runs in the context of the krb5 plugin's slave fiber
-*/
-VOID CALLBACK
-k5_kinit_fiber_proc(PVOID lpParameter)
-{
- while(TRUE)
- {
- if(g_fjob.command == FIBER_CMD_KINIT) {
- g_fjob.state = FIBER_STATE_KINIT;
-
- g_fjob.prompt_set = 0;
-
- if (k5_cached_kinit_prompter()) {
- SwitchToFiber(k5_main_fiber);
-
- if (g_fjob.command != FIBER_CMD_CONTINUE)
- goto _switch_to_main;
-
- if (!k5_cp_check_continue()) {
- g_fjob.code = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- goto _switch_to_main;
- }
- }
-
-#ifdef DEBUG
- /* log the state of g_fjob.* */
- _reportf(L"g_fjob state prior to calling khm_krb5_kinit() :");
- _reportf(L" g_fjob.principal = [%S]", g_fjob.principal);
- _reportf(L" g_fjob.code = %d", g_fjob.code);
- _reportf(L" g_fjob.state = %d", g_fjob.state);
- _reportf(L" g_fjob.prompt_set= %d", g_fjob.prompt_set);
- _reportf(L" g_fjob.valid_principal = %d", (int) g_fjob.valid_principal);
-#endif
-
- /* If we don't know if we have a valid principal, we
- restrict the options that are set when we call kinit.
- This way we will be able to use the response from the
- KDC to verify the principal. */
-
- g_fjob.retry_if_valid_principal = (g_fjob.forwardable ||
- g_fjob.proxiable ||
- g_fjob.renewable);
-
- retry_kinit:
- g_fjob.code =
- khm_krb5_kinit(0,
- g_fjob.principal,
- g_fjob.password,
- g_fjob.ccache,
- g_fjob.lifetime,
- g_fjob.valid_principal ? g_fjob.forwardable : 0,
- g_fjob.valid_principal ? g_fjob.proxiable : 0,
- (g_fjob.valid_principal && g_fjob.renewable ? g_fjob.renew_life : 0),
- g_fjob.addressless,
- g_fjob.publicIP,
- k5_kinit_prompter,
- &g_fjob);
-
- /* If the principal was found to be valid, and if we
- restricted the options that were being passed to kinit,
- then we need to retry the kinit call. This time we use
- the real options. */
- if (g_fjob.state == FIBER_STATE_RETRY_KINIT) {
-#ifdef DEBUG
- assert(g_fjob.valid_principal);
-#endif
- g_fjob.state = FIBER_STATE_KINIT;
- goto retry_kinit;
- }
- }
-
- _switch_to_main:
- g_fjob.state = FIBER_STATE_NONE;
-
- SwitchToFiber(k5_main_fiber);
- }
-}
-
-/* return TRUE if we should go ahead with creds acquisition */
-static BOOL
-k5_cp_check_continue(void) {
- khm_size i;
- khm_size n_p;
- khui_new_creds_prompt * p;
- size_t cch;
-
-#ifdef DEBUG
- assert(g_fjob.nc);
-#endif
-
- if (KHM_FAILED(khui_cw_get_prompt_count(g_fjob.nc, &n_p))) {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- return TRUE;
- }
-
- khui_cw_sync_prompt_values(g_fjob.nc);
-
- g_fjob.null_password = FALSE;
-
- /* we are just checking whether there was a password field that
- was left empty, in which case we can't continue with the
- credentials acquisition. */
- for (i=0; i < n_p; i++) {
- if(KHM_FAILED(khui_cw_get_prompt(g_fjob.nc,
- (int) i,
- &p)))
- continue;
- if(p->type == KHUI_NCPROMPT_TYPE_PASSWORD) {
- if (p->value == NULL ||
- FAILED(StringCchLength(p->value, KHUI_MAXCCH_PROMPT,
- &cch)) ||
- cch == 0) {
- g_fjob.null_password = TRUE;
- return FALSE;
- } else
- break;
- }
- }
-
- return TRUE;
-}
-
-/* returns true if we find cached prompts */
-static BOOL
-k5_cached_kinit_prompter(void) {
- BOOL rv = FALSE;
- khm_handle ident;
- khm_handle csp_idconfig = NULL;
- khm_handle csp_k5config = NULL;
- khm_handle csp_prcache = NULL;
- khm_size cb;
- khm_size n_cur_prompts;
- khm_int32 n_prompts;
- khm_int32 i;
- khm_int64 iexpiry;
- FILETIME expiry;
- FILETIME current;
-
-#ifdef DEBUG
- assert(g_fjob.nc);
-#endif
-
- ident = g_fjob.identity;
- if (!ident)
- return FALSE;
-
- /* don't need to hold ident, since it is already held in g_fjob
- and it doesn't change until we return */
-
- if (KHM_FAILED(kcdb_identity_get_config(ident, 0, &csp_idconfig)) ||
-
- KHM_FAILED(khc_open_space(csp_idconfig, CSNAME_KRB5CRED,
- 0, &csp_k5config)) ||
-
- KHM_FAILED(khc_open_space(csp_k5config, CSNAME_PROMPTCACHE,
- 0, &csp_prcache)) ||
-
- KHM_FAILED(khc_read_int32(csp_prcache, L"PromptCount",
- &n_prompts)) ||
- n_prompts == 0)
-
- goto _cleanup;
-
- if (KHM_SUCCEEDED(khc_read_int64(csp_prcache, L"ExpiresOn", &iexpiry))) {
- /* has the cache expired? */
- expiry = IntToFt(iexpiry);
- GetSystemTimeAsFileTime(&current);
-
- if (CompareFileTime(&expiry, &current) < 0)
- /* already expired */
- goto _cleanup;
- } else {
- /* if there is no value for ExpiresOn, we assume the prompts
- have already expired. */
- goto _cleanup;
- }
-
- /* we found a prompt cache. We take this to imply that the
- principal is valid. */
- g_fjob.valid_principal = TRUE;
-
- /* check if there are any prompts currently showing. If there are
- we check if they are the same as the ones we are going to show.
- In which case we just reuse the exisitng prompts */
- if (KHM_FAILED(khui_cw_get_prompt_count(g_fjob.nc,
- &n_cur_prompts)) ||
- n_prompts != (khm_int32) n_cur_prompts)
- goto _show_new_prompts;
-
- for(i = 0; i < n_prompts; i++) {
- wchar_t wsname[8];
- wchar_t wprompt[KHUI_MAXCCH_PROMPT];
- khm_handle csp_p = NULL;
- khm_int32 p_type;
- khm_int32 p_flags;
- khui_new_creds_prompt * p;
-
- if (KHM_FAILED(khui_cw_get_prompt(g_fjob.nc, i, &p)))
- break;
-
- StringCbPrintf(wsname, sizeof(wsname), L"%d", i);
-
- if (KHM_FAILED(khc_open_space(csp_prcache, wsname, 0, &csp_p)))
- break;
-
- cb = sizeof(wprompt);
- if (KHM_FAILED(khc_read_string(csp_p, L"Prompt",
- wprompt, &cb))) {
- khc_close_space(csp_p);
- break;
- }
-
- if (KHM_FAILED(khc_read_int32(csp_p, L"Type", &p_type)))
- p_type = 0;
-
- if (KHM_FAILED(khc_read_int32(csp_p, L"Flags", &p_flags)))
- p_flags = 0;
-
- if ( /* if we received a prompt string,
- then it should be the same as the
- one that is displayed */
- (wprompt[0] &&
- (p->prompt == NULL ||
- wcscmp(wprompt, p->prompt))) ||
-
- /* if we didn't receive one, then
- there shouldn't be one displayed.
- This case really shouldn't happen
- in reality, but we check anyway. */
- (!wprompt[0] &&
- p->prompt != NULL) ||
-
- /* the type should match */
- (p_type != p->type) ||
-
- /* if this prompt should be hidden,
- then it must also be so */
- (p_flags != p->flags)
- ) {
-
- khc_close_space(csp_p);
- break;
-
- }
-
-
- khc_close_space(csp_p);
- }
-
- if (i == n_prompts) {
- rv = TRUE;
- goto _cleanup;
- }
-
- _show_new_prompts:
-
- khui_cw_clear_prompts(g_fjob.nc);
-
- {
- wchar_t wbanner[KHUI_MAXCCH_BANNER];
- wchar_t wpname[KHUI_MAXCCH_PNAME];
-
- cb = sizeof(wbanner);
- if (KHM_FAILED(khc_read_string(csp_prcache, L"Banner",
- wbanner, &cb)))
- wbanner[0] = 0;
-
- cb = sizeof(wpname);
- if (KHM_FAILED(khc_read_string(csp_prcache, L"Name",
- wpname, &cb)))
- wpname[0] = 0;
-
- khui_cw_begin_custom_prompts(g_fjob.nc,
- n_prompts,
- (wbanner[0]? wbanner: NULL),
- (wpname[0]? wpname: NULL));
- }
-
- for(i = 0; i < n_prompts; i++) {
- wchar_t wsname[8];
- wchar_t wprompt[KHUI_MAXCCH_PROMPT];
- khm_handle csp_p = NULL;
- khm_int32 p_type;
- khm_int32 p_flags;
-
- StringCbPrintf(wsname, sizeof(wsname), L"%d", i);
-
- if (KHM_FAILED(khc_open_space(csp_prcache, wsname, 0, &csp_p)))
- break;
-
- cb = sizeof(wprompt);
- if (KHM_FAILED(khc_read_string(csp_p, L"Prompt",
- wprompt, &cb))) {
- khc_close_space(csp_p);
- break;
- }
-
- if (KHM_FAILED(khc_read_int32(csp_p, L"Type", &p_type)))
- p_type = 0;
-
- if (KHM_FAILED(khc_read_int32(csp_p, L"Flags", &p_flags)))
- p_flags = 0;
-
- khui_cw_add_prompt(g_fjob.nc, p_type, wprompt, NULL, p_flags);
-
- khc_close_space(csp_p);
- }
-
- if (i < n_prompts) {
- khui_cw_clear_prompts(g_fjob.nc);
- } else {
- rv = TRUE;
- }
-
- _cleanup:
-
- if (csp_prcache)
- khc_close_space(csp_prcache);
-
- if (csp_k5config)
- khc_close_space(csp_k5config);
-
- if (csp_idconfig)
- khc_close_space(csp_idconfig);
-
- return rv;
-}
-
-/* Runs in the context of the Krb5 plugin's slave fiber */
-krb5_error_code KRB5_CALLCONV
-k5_kinit_prompter(krb5_context context,
- void *data,
- const char *name,
- const char *banner,
- int num_prompts,
- krb5_prompt prompts[])
-{
- int i;
- khui_new_creds * nc;
- krb5_prompt_type * ptypes;
- khm_size ncp;
- krb5_error_code code = 0;
- BOOL new_prompts = TRUE;
- khm_handle csp_prcache = NULL;
-
-#ifdef DEBUG
- _reportf(L"k5_kinit_prompter() received %d prompts with name=[%S] banner=[%S]",
- num_prompts,
- name, banner);
- for (i=0; i < num_prompts; i++) {
- _reportf(L"Prompt[%d]: string[%S]", i, prompts[i].prompt);
- }
-#endif
-
- /* we got prompts? Then we assume that the principal is valid */
-
- if (!g_fjob.valid_principal) {
- g_fjob.valid_principal = TRUE;
-
- /* if the flags that were used to call kinit were restricted
- because we didn't know the validity of the principal, then
- we need to go back and retry the call with the correct
- flags. */
- if (g_fjob.retry_if_valid_principal) {
- _reportf(L"Retrying kinit call due to restricted flags on first call.");
- g_fjob.state = FIBER_STATE_RETRY_KINIT;
- return KRB5_LIBOS_PWDINTR;
- }
- }
-
- nc = g_fjob.nc;
-
- if(pkrb5_get_prompt_types)
- ptypes = pkrb5_get_prompt_types(context);
- else
- ptypes = NULL;
-
- /* check if we are already showing the right prompts */
- khui_cw_get_prompt_count(nc, &ncp);
-
- if (num_prompts != (int) ncp)
- goto _show_new_prompts;
-
- for (i=0; i < num_prompts; i++) {
- wchar_t wprompt[KHUI_MAXCCH_PROMPT];
- khui_new_creds_prompt * p;
-
- if(prompts[i].prompt) {
- AnsiStrToUnicode(wprompt, sizeof(wprompt),
- prompts[i].prompt);
- } else {
- wprompt[0] = 0;
- }
-
- if (KHM_FAILED(khui_cw_get_prompt(nc, i, &p)))
- break;
-
- if ( /* if we received a prompt string,
- then it should be the same as the
- one that is displayed */
- (wprompt[0] &&
- (p->prompt == NULL ||
- wcscmp(wprompt, p->prompt))) ||
- /* if we didn't receive one, then
- there shouldn't be one displayed.
- This case really shouldn't happen
- in reality, but we check anyway. */
- (!wprompt[0] &&
- p->prompt != NULL) ||
- /* the type should match */
- (ptypes &&
- ptypes[i] != p->type) ||
- (!ptypes &&
- p->type != 0) ||
- /* if this prompt should be hidden,
- then it must also be so */
- (prompts[i].hidden &&
- !(p->flags & KHUI_NCPROMPT_FLAG_HIDDEN)) ||
- (!prompts[i].hidden &&
- (p->flags & KHUI_NCPROMPT_FLAG_HIDDEN))
- )
- break;
- }
-
- if (i < num_prompts)
- goto _show_new_prompts;
-
- new_prompts = FALSE;
-
- /* ok. looks like we are already showing the same set of prompts
- that we were supposed to show. Sync up the values and go
- ahead. */
- khui_cw_sync_prompt_values(nc);
- goto _process_prompts;
-
- _show_new_prompts:
- /* special case. if there are no actual input controls involved,
- then we have to show an alerter window and pass through */
- if (num_prompts == 0) {
- wchar_t wbanner[KHUI_MAXCCH_BANNER];
- wchar_t wname[KHUI_MAXCCH_PNAME];
- wchar_t wident[KCDB_IDENT_MAXCCH_NAME];
- wchar_t wmsg[KHUI_MAXCCH_MESSAGE];
- wchar_t wfmt[KHUI_MAXCCH_BANNER];
- khm_size cb;
-
- if (!banner) {
- code = 0;
- g_fjob.null_password = FALSE;
- goto _exit;
- } else {
- AnsiStrToUnicode(wbanner, sizeof(wbanner), banner);
- }
-
- if (name) {
- AnsiStrToUnicode(wname, sizeof(wname), name);
- } else {
- LoadString(hResModule,
- IDS_KRB5_WARNING,
- wname,
- ARRAYLENGTH(wname));
- }
-
- cb = sizeof(wident);
- if (KHM_FAILED(kcdb_identity_get_name(g_fjob.identity, wident, &cb)))
- wident[0] = L'\0';
-
- LoadString(hResModule,
- IDS_KRB5_WARN_FMT,
- wfmt,
- ARRAYLENGTH(wfmt));
-
- StringCbPrintf(wmsg, sizeof(wmsg), wfmt, wident, wbanner);
-
- khui_alert_show_simple(wname, wmsg, KHERR_WARNING);
-
- code = 0;
- g_fjob.null_password = FALSE;
- goto _exit;
- }
-
- /* in addition to showing new prompts, we also cache the set of
- prompts. */
- if(g_fjob.prompt_set == 0) {
- khm_handle csp_idconfig = NULL;
- khm_handle csp_idk5 = NULL;
-
- kcdb_identity_get_config(g_fjob.identity,
- KHM_FLAG_CREATE,
- &csp_idconfig);
-
- if (csp_idconfig != NULL)
- khc_open_space(csp_idconfig,
- CSNAME_KRB5CRED,
- KHM_FLAG_CREATE,
- &csp_idk5);
-
- if (csp_idk5 != NULL)
- khc_open_space(csp_idk5,
- CSNAME_PROMPTCACHE,
- KHM_FLAG_CREATE,
- &csp_prcache);
-
- khc_close_space(csp_idconfig);
- khc_close_space(csp_idk5);
- }
-
- {
- wchar_t wbanner[KHUI_MAXCCH_BANNER];
- wchar_t wname[KHUI_MAXCCH_PNAME];
- FILETIME current;
- FILETIME lifetime;
- FILETIME expiry;
- khm_int64 iexpiry;
- khm_int32 t = 0;
-
- if(banner)
- AnsiStrToUnicode(wbanner, sizeof(wbanner), banner);
- if(name)
- AnsiStrToUnicode(wname, sizeof(wname), name);
-
- khui_cw_clear_prompts(nc);
-
- khui_cw_begin_custom_prompts(
- nc,
- num_prompts,
- (banner)?wbanner:NULL,
- (name)?wname:NULL);
-
- if (csp_prcache) {
-
- if (banner)
- khc_write_string(csp_prcache,
- L"Banner",
- wbanner);
- else
- khc_write_string(csp_prcache,
- L"Banner",
- L"");
-
- if (name)
- khc_write_string(csp_prcache,
- L"Name",
- wname);
- else if (csp_prcache)
- khc_write_string(csp_prcache,
- L"Name",
- L"");
-
- khc_write_int32(csp_prcache,
- L"PromptCount",
- (khm_int32) num_prompts);
-
- GetSystemTimeAsFileTime(&current);
-#ifdef USE_PROMPT_CACHE_LIFETIME
- khc_read_int32(csp_params, L"PromptCacheLifetime", &t);
- if (t == 0)
- t = 172800; /* 48 hours */
-#else
- khc_read_int32(csp_params, L"MaxRenewLifetime", &t);
- if (t == 0)
- t = 2592000; /* 30 days */
- t += 604800; /* + 7 days */
-#endif
- TimetToFileTimeInterval(t, &lifetime);
- expiry = FtAdd(&current, &lifetime);
- iexpiry = FtToInt(&expiry);
-
- khc_write_int64(csp_prcache, L"ExpiresOn", iexpiry);
- }
- }
-
- for(i=0; i < num_prompts; i++) {
- wchar_t wprompt[KHUI_MAXCCH_PROMPT];
-
- if(prompts[i].prompt) {
- AnsiStrToUnicode(wprompt, sizeof(wprompt),
- prompts[i].prompt);
- } else {
- wprompt[0] = 0;
- }
-
- khui_cw_add_prompt(
- nc,
- (ptypes?ptypes[i]:0),
- wprompt,
- NULL,
- (prompts[i].hidden?KHUI_NCPROMPT_FLAG_HIDDEN:0));
-
- if (csp_prcache) {
- khm_handle csp_p = NULL;
- wchar_t wnum[8]; /* should be enough for 10
- million prompts */
-
- wnum[0] = 0;
- StringCbPrintf(wnum, sizeof(wnum), L"%d", i);
-
- khc_open_space(csp_prcache, wnum,
- KHM_FLAG_CREATE, &csp_p);
-
- if (csp_p) {
- khc_write_string(csp_p, L"Prompt", wprompt);
- khc_write_int32(csp_p, L"Type", (ptypes?ptypes[i]:0));
- khc_write_int32(csp_p, L"Flags",
- (prompts[i].hidden?
- KHUI_NCPROMPT_FLAG_HIDDEN:0));
-
- khc_close_space(csp_p);
- }
- }
- }
-
- if (csp_prcache) {
- khc_close_space(csp_prcache);
- csp_prcache = NULL;
- }
-
- _process_prompts:
- /* switch back to main thread if we showed new prompts */
- if (new_prompts)
- SwitchToFiber(k5_main_fiber);
-
- /* we get here after the user selects an action that either
- cancles the credentials acquisition operation or triggers the
- actual acquisition of credentials. */
- if(g_fjob.command != FIBER_CMD_CONTINUE &&
- g_fjob.command != FIBER_CMD_KINIT) {
- code = KRB5_LIBOS_PWDINTR;
- goto _exit;
- }
-
- g_fjob.null_password = FALSE;
-
- /* otherwise, we need to get the data back from the UI and
- return 0 */
- for(i=0; i<num_prompts; i++) {
- krb5_data * d;
- wchar_t wbuf[512];
- khm_size cbbuf;
- size_t cch;
-
- d = prompts[i].reply;
-
- cbbuf = sizeof(wbuf);
- if(KHM_SUCCEEDED(khui_cw_get_prompt_value(nc, i, wbuf, &cbbuf))) {
- UnicodeStrToAnsi(d->data, d->length, wbuf);
- if(SUCCEEDED(StringCchLengthA(d->data, d->length, &cch)))
- d->length = (unsigned int) cch;
- else
- d->length = 0;
- } else {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- d->length = 0;
- }
-
- if (ptypes &&
- ptypes[i] == KRB5_PROMPT_TYPE_PASSWORD &&
- d->length == 0)
-
- g_fjob.null_password = TRUE;
- }
-
- _exit:
-
- g_fjob.prompt_set++;
-
- /* entering a NULL password is equivalent to cancelling out */
- if (g_fjob.null_password)
- return KRB5_LIBOS_PWDINTR;
- else
- return code;
-}
-
-
-void
-k5_read_dlg_params(k5_dlg_data * d, khm_handle identity)
-{
- k5_params p;
-
- khm_krb5_get_identity_params(identity, &p);
-
- d->renewable = p.renewable;
- d->forwardable = p.forwardable;
- d->proxiable = p.proxiable;
- d->addressless = p.addressless;
- d->publicIP = p.publicIP;
-
- d->tc_lifetime.current = p.lifetime;
- d->tc_lifetime.max = p.lifetime_max;
- d->tc_lifetime.min = p.lifetime_min;
-
- d->tc_renew.current = p.renew_life;
- d->tc_renew.max = p.renew_life_max;
- d->tc_renew.min = p.renew_life_min;
-
- /* however, if this has externally supplied defaults, we have to
- use them too. */
- if (d->nc && d->nc->ctx.vparam &&
- d->nc->ctx.cb_vparam == sizeof(NETID_DLGINFO)) {
- LPNETID_DLGINFO pdlginfo;
-
- pdlginfo = (LPNETID_DLGINFO) d->nc->ctx.vparam;
- if (pdlginfo->size == NETID_DLGINFO_V1_SZ &&
- pdlginfo->in.use_defaults == 0) {
- d->forwardable = pdlginfo->in.forwardable;
- d->addressless = pdlginfo->in.noaddresses;
- d->tc_lifetime.current = pdlginfo->in.lifetime;
- d->tc_renew.current = pdlginfo->in.renew_till;
-
- if (pdlginfo->in.renew_till == 0)
- d->renewable = FALSE;
- else
- d->renewable = TRUE;
-
- d->proxiable = pdlginfo->in.proxiable;
- d->publicIP = pdlginfo->in.publicip;
- }
- }
-
- /* once we read the new data, in, it is no longer considered
- dirty */
- d->dirty = FALSE;
- d->sync = FALSE;
-}
-
-void
-k5_write_dlg_params(k5_dlg_data * d, khm_handle identity)
-{
-
- k5_params p;
-
- ZeroMemory(&p, sizeof(p));
-
- p.source_reg = K5PARAM_FM_ALL; /* we want to write all the
- settings to the registry, if
- necessary. */
-
- p.renewable = d->renewable;
- p.forwardable = d->forwardable;
- p.proxiable = d->proxiable;
- p.addressless = d->addressless;
- p.publicIP = d->publicIP;
-
- p.lifetime = (krb5_deltat) d->tc_lifetime.current;
- p.lifetime_max = (krb5_deltat) d->tc_lifetime.max;
- p.lifetime_min = (krb5_deltat) d->tc_lifetime.min;
-
- p.renew_life = (krb5_deltat) d->tc_renew.current;
- p.renew_life_max = (krb5_deltat) d->tc_renew.max;
- p.renew_life_min = (krb5_deltat) d->tc_renew.min;
-
- khm_krb5_set_identity_params(identity, &p);
-
- /* as in k5_read_dlg_params, once we write the data in, the local
- data is no longer dirty */
- d->dirty = FALSE;
-}
-
-void
-k5_free_kinit_job(void)
-{
- if (g_fjob.principal)
- PFREE(g_fjob.principal);
-
- if (g_fjob.password)
- PFREE(g_fjob.password);
-
- if (g_fjob.identity)
- kcdb_identity_release(g_fjob.identity);
-
- if (g_fjob.ccache)
- PFREE(g_fjob.ccache);
-
- ZeroMemory(&g_fjob, sizeof(g_fjob));
-}
-
-void
-k5_prep_kinit_job(khui_new_creds * nc)
-{
- khui_new_creds_by_type * nct;
- k5_dlg_data * d;
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- khm_size cbbuf;
- size_t size;
- khm_handle ident;
- LPNETID_DLGINFO pdlginfo;
-
- khui_cw_find_type(nc, credtype_id_krb5, &nct);
- if (!nct)
- return;
-
- d = (k5_dlg_data *)(LONG_PTR)
- GetWindowLongPtr(nct->hwnd_panel, DWLP_USER);
-
- if (!d)
- return;
-
- khui_cw_lock_nc(nc);
- ident = nc->identities[0];
- kcdb_identity_hold(ident);
- khui_cw_unlock_nc(nc);
-
- cbbuf = sizeof(idname);
- kcdb_identity_get_name(ident, idname, &cbbuf);
- StringCchLength(idname, ARRAYLENGTH(idname), &size);
- size++;
-
- k5_free_kinit_job();
-
- g_fjob.command = FIBER_CMD_KINIT;
- g_fjob.nc = nc;
- g_fjob.nct = nct;
- g_fjob.dialog = nct->hwnd_panel;
- g_fjob.principal = PMALLOC(size);
- UnicodeStrToAnsi(g_fjob.principal, size, idname);
- g_fjob.password = NULL;
- g_fjob.lifetime = (krb5_deltat) d->tc_lifetime.current;
- g_fjob.forwardable = d->forwardable;
- g_fjob.proxiable = d->proxiable;
- g_fjob.renewable = d->renewable;
- g_fjob.renew_life = (krb5_deltat) d->tc_renew.current;
- g_fjob.addressless = d->addressless;
- g_fjob.publicIP = d->publicIP;
- g_fjob.code = 0;
- g_fjob.identity = ident;
- g_fjob.prompt_set = 0;
- g_fjob.valid_principal = FALSE;
- g_fjob.retry_if_valid_principal = FALSE;
-
- /* the value for
- retry_if_valid_principal is not
- necessarily the correct value here,
- but the correct value will be
- assigned k5_kinit_fiber_proc(). */
-
- /* if we have external parameters, we should use them as well */
- if (nc->ctx.cb_vparam == sizeof(NETID_DLGINFO) &&
- (pdlginfo = nc->ctx.vparam) &&
- pdlginfo->size == NETID_DLGINFO_V1_SZ) {
- wchar_t * t;
-
- if (pdlginfo->in.ccache[0] &&
- SUCCEEDED(StringCchLength(pdlginfo->in.ccache,
- NETID_CCACHE_NAME_SZ,
- &size))) {
- g_fjob.ccache = PMALLOC(sizeof(char) * (size + 1));
-#ifdef DEBUG
- assert(g_fjob.ccache);
-#endif
- UnicodeStrToAnsi(g_fjob.ccache, size + 1,
- pdlginfo->in.ccache);
-
- /* this is the same as the output cache */
-
- StringCbCopy(pdlginfo->out.ccache, sizeof(pdlginfo->out.ccache),
- pdlginfo->in.ccache);
- } else {
- g_fjob.ccache = NULL;
-
- StringCbCopy(pdlginfo->out.ccache, sizeof(pdlginfo->out.ccache),
- idname);
-
- khm_krb5_canon_cc_name(pdlginfo->out.ccache,
- sizeof(pdlginfo->out.ccache));
- }
-
- t = khm_get_realm_from_princ(idname);
-
- if (t) {
- StringCbCopy(pdlginfo->out.realm,
- sizeof(pdlginfo->out.realm),
- t);
-
- if ((t - idname) > 1) {
- StringCchCopyN(pdlginfo->out.username,
- ARRAYLENGTH(pdlginfo->out.username),
- idname,
- (t - idname) - 1);
- } else {
- StringCbCopy(pdlginfo->out.username,
- sizeof(pdlginfo->out.username),
- L"");
- }
- } else {
- StringCbCopy(pdlginfo->out.username,
- sizeof(pdlginfo->out.username),
- idname);
- StringCbCopy(pdlginfo->out.realm,
- sizeof(pdlginfo->out.realm),
- L"");
- }
- }
-
- /* leave identity held, since we added a reference above */
-}
-
-static khm_int32 KHMAPI
-k5_find_tgt_filter(khm_handle cred,
- khm_int32 flags,
- void * rock) {
- khm_handle ident = (khm_handle) rock;
- khm_handle cident = NULL;
- khm_int32 f;
- khm_int32 rv;
-
- if (KHM_SUCCEEDED(kcdb_cred_get_identity(cred,
- &cident)) &&
- cident == ident &&
- KHM_SUCCEEDED(kcdb_cred_get_flags(cred, &f)) &&
- (f & KCDB_CRED_FLAG_INITIAL) &&
- !(f & KCDB_CRED_FLAG_EXPIRED))
- rv = 1;
- else
- rv = 0;
-
- if (cident)
- kcdb_identity_release(cident);
-
- return rv;
-}
-
-khm_int32
-k5_remove_from_LRU(khm_handle identity)
-{
- wchar_t * wbuf = NULL;
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- khm_size cb;
- khm_size cb_ms;
- khm_int32 rv = KHM_ERROR_SUCCESS;
-
- cb = sizeof(idname);
- rv = kcdb_identity_get_name(identity, idname, &cb);
- assert(rv == KHM_ERROR_SUCCESS);
-
- rv = khc_read_multi_string(csp_params, L"LRUPrincipals", NULL, &cb_ms);
- if (rv != KHM_ERROR_TOO_LONG)
- cb_ms = sizeof(wchar_t) * 2;
-
- wbuf = PMALLOC(cb_ms);
- assert(wbuf);
-
- cb = cb_ms;
-
- if (rv == KHM_ERROR_TOO_LONG) {
- rv = khc_read_multi_string(csp_params, L"LRUPrincipals", wbuf, &cb);
- assert(KHM_SUCCEEDED(rv));
-
- if (multi_string_find(wbuf, idname, KHM_CASE_SENSITIVE) != NULL) {
- multi_string_delete(wbuf, idname, KHM_CASE_SENSITIVE);
- }
- } else {
- multi_string_init(wbuf, cb_ms);
- }
-
- rv = khc_write_multi_string(csp_params, L"LRUPrincipals", wbuf);
-
- if (wbuf)
- PFREE(wbuf);
-
- return rv;
-}
-
-khm_int32
-k5_update_LRU(khm_handle identity)
-{
- wchar_t * wbuf = NULL;
- wchar_t * idname = NULL;
- wchar_t * realm = NULL;
- khm_size cb;
- khm_size cb_ms;
- khm_int32 rv = KHM_ERROR_SUCCESS;
-
- rv = kcdb_identity_get_name(identity, NULL, &cb);
- assert(rv == KHM_ERROR_TOO_LONG);
-
- idname = PMALLOC(cb);
- assert(idname);
-
- rv = kcdb_identity_get_name(identity, idname, &cb);
- assert(KHM_SUCCEEDED(rv));
-
- rv = khc_read_multi_string(csp_params, L"LRUPrincipals", NULL, &cb_ms);
- if (rv != KHM_ERROR_TOO_LONG)
- cb_ms = cb + sizeof(wchar_t);
- else
- cb_ms += cb + sizeof(wchar_t);
-
- wbuf = PMALLOC(cb_ms);
- assert(wbuf);
-
- cb = cb_ms;
-
- if (rv == KHM_ERROR_TOO_LONG) {
- rv = khc_read_multi_string(csp_params, L"LRUPrincipals", wbuf, &cb);
- assert(KHM_SUCCEEDED(rv));
-
- if (multi_string_find(wbuf, idname, KHM_CASE_SENSITIVE) != NULL) {
- /* it's already there. We remove it here and add it at
- the top of the LRU list. */
- multi_string_delete(wbuf, idname, KHM_CASE_SENSITIVE);
- }
- } else {
- multi_string_init(wbuf, cb_ms);
- }
-
- cb = cb_ms;
- rv = multi_string_prepend(wbuf, &cb, idname);
- assert(KHM_SUCCEEDED(rv));
-
- rv = khc_write_multi_string(csp_params, L"LRUPrincipals", wbuf);
-
- realm = khm_get_realm_from_princ(idname);
- if (realm == NULL || *realm == L'\0')
- goto _done_with_LRU;
-
- cb = cb_ms;
- rv = khc_read_multi_string(csp_params, L"LRURealms", wbuf, &cb);
-
- if (rv == KHM_ERROR_TOO_LONG) {
- PFREE(wbuf);
- wbuf = PMALLOC(cb);
- assert(wbuf);
-
- cb_ms = cb;
-
- rv = khc_read_multi_string(csp_params, L"LRURealms", wbuf, &cb);
-
- assert(KHM_SUCCEEDED(rv));
- } else if (rv == KHM_ERROR_SUCCESS) {
- if (multi_string_find(wbuf, realm, KHM_CASE_SENSITIVE) != NULL) {
- /* remove the realm and add it at the top later. */
- multi_string_delete(wbuf, realm, KHM_CASE_SENSITIVE);
- }
- } else {
- multi_string_init(wbuf, cb_ms);
- }
-
- cb = cb_ms;
- rv = multi_string_prepend(wbuf, &cb, realm);
-
- if (rv == KHM_ERROR_TOO_LONG) {
- wbuf = PREALLOC(wbuf, cb);
-
- rv = multi_string_prepend(wbuf, &cb, realm);
-
- assert(KHM_SUCCEEDED(rv));
- }
-
- rv = khc_write_multi_string(csp_params, L"LRURealms", wbuf);
-
- assert(KHM_SUCCEEDED(rv));
-
- _done_with_LRU:
-
- if (wbuf)
- PFREE(wbuf);
- if (idname)
- PFREE(idname);
-
- return rv;
-}
-
-/* Handler for CRED type messages
-
- Runs in the context of the Krb5 plugin
-*/
-khm_int32 KHMAPI
-k5_msg_cred_dialog(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam)
-{
- khm_int32 rv = KHM_ERROR_SUCCESS;
-
- switch(msg_subtype) {
-
- case KMSG_CRED_PASSWORD:
- case KMSG_CRED_NEW_CREDS:
- {
- khui_new_creds * nc;
- khui_new_creds_by_type * nct;
- wchar_t wbuf[256];
- size_t cbsize;
-
- nc = (khui_new_creds *) vparam;
-
- nct = PMALLOC(sizeof(*nct));
- ZeroMemory(nct, sizeof(*nct));
-
- nct->type = credtype_id_krb5;
- nct->ordinal = 1;
-
- LoadString(hResModule, IDS_KRB5_NC_NAME,
- wbuf, ARRAYLENGTH(wbuf));
- StringCbLength(wbuf, sizeof(wbuf), &cbsize);
- cbsize += sizeof(wchar_t);
-
- nct->name = PMALLOC(cbsize);
- StringCbCopy(nct->name, cbsize, wbuf);
-
- nct->h_module = hResModule;
- nct->dlg_proc = k5_nc_dlg_proc;
- if (nc->subtype == KMSG_CRED_PASSWORD)
- nct->dlg_template = MAKEINTRESOURCE(IDD_NC_KRB5_PASSWORD);
- else
- nct->dlg_template = MAKEINTRESOURCE(IDD_NC_KRB5);
-
- khui_cw_add_type(nc, nct);
- }
- break;
-
- case KMSG_CRED_RENEW_CREDS:
- {
- khui_new_creds * nc;
- khui_new_creds_by_type * nct;
-
- nc = (khui_new_creds *) vparam;
-
- nct = PMALLOC(sizeof(*nct));
- ZeroMemory(nct, sizeof(*nct));
-
- nct->type = credtype_id_krb5;
-
- khui_cw_add_type(nc, nct);
- }
- break;
-
- case KMSG_CRED_DIALOG_PRESTART:
- {
- khui_new_creds * nc;
- khui_new_creds_by_type * nct;
- k5_dlg_data * d;
- HWND hwnd;
- wchar_t * realms;
- wchar_t * t;
- wchar_t * defrealm;
-
- nc = (khui_new_creds *) vparam;
-
- khui_cw_find_type(nc, credtype_id_krb5, &nct);
-
- if(!nct)
- break;
-
- hwnd = nct->hwnd_panel;
- d = (k5_dlg_data *)(LONG_PTR)
- GetWindowLongPtr(nct->hwnd_panel, DWLP_USER);
-
- /* this can be NULL if the dialog was closed while the
- plug-in thread was processing. */
- if (d == NULL)
- break;
-
- if (!is_k5_identpro) {
-
- /* enumerate all realms and place in realms combo box */
- SendDlgItemMessage(hwnd, IDC_NCK5_REALM,
- CB_RESETCONTENT,
- 0, 0);
-
- realms = khm_krb5_get_realm_list();
- if(realms) {
- for (t = realms; t && *t; t = multi_string_next(t)) {
- SendDlgItemMessage(hwnd, IDC_NCK5_REALM,
- CB_ADDSTRING,
- 0, (LPARAM) t);
- }
- PFREE(realms);
- }
-
- /* and set the default realm */
- defrealm = khm_krb5_get_default_realm();
- if(defrealm) {
- SendDlgItemMessage(hwnd, IDC_NCK5_REALM,
- CB_SELECTSTRING,
- (WPARAM) -1,
- (LPARAM) defrealm);
-
- SendDlgItemMessage(hwnd, IDC_NCK5_REALM,
- WM_SETTEXT,
- 0, (LPARAM) defrealm);
- PFREE(defrealm);
- }
- } else { /* if krb5 is the identity provider */
- HWND hw_realms;
-
- /* in this case, the realm selection is done by the
- identity provider prompts. */
-
- hw_realms = GetDlgItem(hwnd, IDC_NCK5_REALM);
-#ifdef DEBUG
- assert(hw_realms);
-#endif
- EnableWindow(hw_realms, FALSE);
- }
-
- if (nc->subtype == KMSG_CRED_NEW_CREDS) {
- k5_read_dlg_params(d, NULL);
- }
-
- PostMessage(hwnd, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0,WMNC_DIALOG_SETUP), 0);
- }
- break;
-
- case KMSG_CRED_DIALOG_NEW_IDENTITY:
- {
- khui_new_creds * nc;
- khui_new_creds_by_type * nct;
- k5_dlg_data * d;
-
- nc = (khui_new_creds *) vparam;
-
- khui_cw_find_type(nc, credtype_id_krb5, &nct);
- if (!nct)
- break;
-
- d = (k5_dlg_data *)(LONG_PTR)
- GetWindowLongPtr(nct->hwnd_panel, DWLP_USER);
-
- if (d == NULL)
- break;
-
- /* we only load the identity specific defaults if the user
- hasn't changed the options */
- khui_cw_lock_nc(nc);
-
- /* ?: It might be better to not load identity defaults if
- the user has already changed options in the dialog. */
- if(/* !d->dirty && */ nc->n_identities > 0 &&
- nc->subtype == KMSG_CRED_NEW_CREDS) {
-
- k5_read_dlg_params(d, nc->identities[0]);
-
- PostMessage(nct->hwnd_panel, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0,WMNC_DIALOG_SETUP), 0);
- }
-
- khui_cw_unlock_nc(nc);
-
- /* reset the force-password-change flag if this is a new
- identity. */
- d->pwd_change = FALSE;
- }
-
- /* fallthrough */
- case KMSG_CRED_DIALOG_NEW_OPTIONS:
- {
- khui_new_creds * nc;
- khui_new_creds_by_type * nct;
- k5_dlg_data * d;
-
- nc = (khui_new_creds *) vparam;
-
- khui_cw_find_type(nc, credtype_id_krb5, &nct);
- if (!nct)
- break;
-
- d = (k5_dlg_data *)(LONG_PTR)
- GetWindowLongPtr(nct->hwnd_panel, DWLP_USER);
- if (d == NULL)
- break;
-
- if (nc->subtype == KMSG_CRED_PASSWORD) {
- khm_size n_prompts = 0;
-
- khui_cw_get_prompt_count(nc, &n_prompts);
-
- if (nc->n_identities == 0) {
- if (n_prompts)
- khui_cw_clear_prompts(nc);
- } else if (n_prompts != 3) {
- wchar_t wbuf[KHUI_MAXCCH_BANNER];
-
- khui_cw_clear_prompts(nc);
-
- LoadString(hResModule, IDS_NC_PWD_BANNER,
- wbuf, ARRAYLENGTH(wbuf));
- khui_cw_begin_custom_prompts(nc, 3, NULL, wbuf);
-
- LoadString(hResModule, IDS_NC_PWD_PWD,
- wbuf, ARRAYLENGTH(wbuf));
- khui_cw_add_prompt(nc, KHUI_NCPROMPT_TYPE_PASSWORD,
- wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);
-
- LoadString(hResModule, IDS_NC_PWD_NPWD,
- wbuf, ARRAYLENGTH(wbuf));
- khui_cw_add_prompt(nc, KHUI_NCPROMPT_TYPE_NEW_PASSWORD,
- wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);
-
- LoadString(hResModule, IDS_NC_PWD_NPWD_AGAIN,
- wbuf, ARRAYLENGTH(wbuf));
- khui_cw_add_prompt(nc, KHUI_NCPROMPT_TYPE_NEW_PASSWORD_AGAIN,
- wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);
- }
-
- return KHM_ERROR_SUCCESS;
- }
- /* else; nc->subtype == KMSG_CRED_NEW_CREDS */
-
- assert(nc->subtype == KMSG_CRED_NEW_CREDS);
-
- /* If we are forcing a password change, then we don't do
- anything here. Note that if the identity changed, then
- this field would have been reset, so we would proceed
- as usual. */
- if (d->pwd_change)
- return KHM_ERROR_SUCCESS;
-
-#if 0
- /* Clearing the prompts at this point is a bad idea since
- the prompter depends on the prompts to know if this set
- of prompts is the same as the new set and if so, use
- the values entered in the old prompts as responses to
- the new one. */
- khui_cw_clear_prompts(nc);
-#endif
-
- /* if the fiber is already in a kinit, cancel it */
- if(g_fjob.state == FIBER_STATE_KINIT) {
- g_fjob.command = FIBER_CMD_CANCEL;
- SwitchToFiber(k5_kinit_fiber);
- /* we get here when the cancel operation completes */
- k5_free_kinit_job();
- }
-
- khui_cw_lock_nc(nc);
-
- if(nc->n_identities > 0) {
- khm_handle ident = nc->identities[0];
-
- kcdb_identity_hold(ident);
-
- k5_prep_kinit_job(nc);
-
- /* after the switch to the fiber, the dialog will be
- back in sync with the kinit thread. */
- d->sync = TRUE;
-
- khui_cw_unlock_nc(nc);
-
- SwitchToFiber(k5_kinit_fiber);
- /* we get here when the fiber switches back */
- if(g_fjob.state == FIBER_STATE_NONE) {
- wchar_t msg[KHUI_MAXCCH_BANNER];
- khm_size cb;
-
- /* Special case. If the users' password has
- expired, we force a password change dialog on
- top of the new credentials dialog using a set
- of custom prompts, but only if we are the
- identity provider. */
- if (g_fjob.code == KRB5KDC_ERR_KEY_EXP &&
- is_k5_identpro) {
-
- k5_force_password_change(d);
- goto done_with_bad_princ;
-
- }
-
- /* we can't possibly have succeeded without a
- password */
- if(g_fjob.code == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN &&
- is_k5_identpro) {
- kcdb_identity_set_flags(ident,
- KCDB_IDENT_FLAG_INVALID,
- KCDB_IDENT_FLAG_INVALID);
-
- khui_cw_clear_prompts(nc);
- }
-
- if (d->cred_message) {
- PFREE(d->cred_message);
- d->cred_message = NULL;
- }
-
- msg[0] = L'\0';
-
- switch(g_fjob.code) {
- case KRB5KDC_ERR_NAME_EXP:
- /* principal expired */
- LoadString(hResModule, IDS_K5ERR_NAME_EXPIRED,
- msg, ARRAYLENGTH(msg));
- break;
-
- case KRB5KDC_ERR_KEY_EXP:
- {
- /* password needs changing. */
- LoadString(hResModule, IDS_K5ERR_KEY_EXPIRED,
- msg, ARRAYLENGTH(msg));
- }
- break;
-
- default:
- {
- DWORD dw_dummy;
- kherr_suggestion sug_dummy;
- wchar_t fmt[KHUI_MAXCCH_BANNER];
- wchar_t desc[KHUI_MAXCCH_BANNER];
-
- LoadString(hResModule, IDS_K5ERR_FMT,
- fmt, ARRAYLENGTH(fmt));
-
- khm_err_describe(g_fjob.code,
- desc,
- sizeof(desc),
- &dw_dummy,
- &sug_dummy);
-
- StringCbPrintf(msg, sizeof(msg), fmt, desc);
- }
- }
-
- if (msg[0]) {
- StringCbLength(msg, sizeof(msg), &cb);
- cb += sizeof(wchar_t);
-
- d->cred_message = PMALLOC(cb);
- StringCbCopy(d->cred_message, cb, msg);
- }
-
- done_with_bad_princ:
-
- k5_free_kinit_job();
-
- if (is_k5_identpro)
- kcdb_identity_set_flags(ident,
- KCDB_IDENT_FLAG_UNKNOWN,
- KCDB_IDENT_FLAG_UNKNOWN);
-
-
- } else if(g_fjob.state == FIBER_STATE_KINIT) {
- /* this is what we want. Leave the fiber there. */
-
- if(is_k5_identpro)
- kcdb_identity_set_flags(ident,
- KCDB_IDENT_FLAG_VALID,
- KCDB_IDENT_FLAG_VALID);
- } else {
- /* huh?? */
-#ifdef DEBUG
- assert(FALSE);
-#endif
- }
-
- /* since the attributes of the identity have changed,
- we should update the cred text as well */
- kcdb_identity_release(ident);
- khui_cw_lock_nc(nc);
- PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
- } else {
- khui_cw_unlock_nc(nc);
- khui_cw_clear_prompts(nc);
- khui_cw_lock_nc(nc);
- }
-
- khui_cw_unlock_nc(nc);
- }
- break;
-
- case KMSG_CRED_PROCESS:
- {
- khui_new_creds * nc;
- khui_new_creds_by_type * nct;
- k5_dlg_data * d;
-
- khm_int32 r = 0;
-
- nc = (khui_new_creds *) vparam;
-
- khui_cw_find_type(nc, credtype_id_krb5, &nct);
-
- if(!nct)
- break;
-
- /* reset the null_password flag, just in case */
- g_fjob.null_password = FALSE;
-
- if (nc->subtype == KMSG_CRED_NEW_CREDS) {
- d = (k5_dlg_data *) nct->aux;
- if (d == NULL)
- break;
-
- if (d->pwd_change) {
- /* we are forcing a password change */
- goto change_password;
- }
-
- _begin_task(0);
- _report_mr0(KHERR_NONE, MSG_CTX_INITAL_CREDS);
- _describe();
-
- if (g_fjob.state == FIBER_STATE_KINIT) {
- if(nc->result == KHUI_NC_RESULT_CANCEL) {
- g_fjob.command = FIBER_CMD_CANCEL;
- SwitchToFiber(k5_kinit_fiber);
-
- /* if we cancelled out, then we shouldn't care
- about the return code. */
-#ifdef DEBUG
- assert(g_fjob.state == FIBER_STATE_NONE);
-#endif
- g_fjob.code = 0;
-
- _reportf(L"Cancelling");
- } else if (nc->result == KHUI_NC_RESULT_PROCESS) {
- khui_cw_sync_prompt_values(nc);
- g_fjob.command = FIBER_CMD_CONTINUE;
- SwitchToFiber(k5_kinit_fiber);
-
- /* We get back here once the fiber finishes
- processing */
- }
-#ifdef DEBUG
- else {
- assert(FALSE);
- }
-#endif
- } else {
- /* we weren't in a KINIT state */
- if (nc->result == KHUI_NC_RESULT_CANCEL) {
- /* nothing to report */
- g_fjob.code = 0;
- } else if (nc->result == KHUI_NC_RESULT_PROCESS) {
- /* g_fjob.code should have the result of the
- last kinit attempt. We should leave it
- as-is */
- }
-#ifdef DEBUG
- else {
- /* unknown result */
- assert(FALSE);
- }
-#endif
- }
-
- /* special case: if there was no password entered, and
- if there is a valid TGT we allow the credential
- acquisition to go through */
- if (g_fjob.state == FIBER_STATE_NONE &&
- g_fjob.code &&
- g_fjob.null_password &&
-
- (nc->n_identities == 0 ||
- nc->identities[0] == NULL ||
- KHM_SUCCEEDED(kcdb_credset_find_filtered
- (NULL,
- -1,
- k5_find_tgt_filter,
- nc->identities[0],
- NULL,
- NULL)))) {
- _reportf(L"No password entered, but a valid TGT exists. Continuing");
- g_fjob.code = 0;
- } else if (g_fjob.state == FIBER_STATE_NONE &&
- g_fjob.code == 0 &&
- nc->n_identities > 0 &&
- nc->identities[0] != NULL) {
-
- /* we had a password and we used it to get
- tickets. We should reset the IMPORTED flag now
- since the tickets are not imported. */
-
- khm_krb5_set_identity_flags(nc->identities[0],
- K5IDFLAG_IMPORTED,
- 0);
- }
-
- if(g_fjob.code != 0) {
- wchar_t tbuf[1024];
- DWORD suggestion;
- kherr_suggestion suggest_code;
-
- khm_err_describe(g_fjob.code, tbuf, sizeof(tbuf),
- &suggestion, &suggest_code);
-
- _report_cs0(KHERR_ERROR, tbuf);
- if (suggestion != 0)
- _suggest_mr(suggestion, suggest_code);
-
- _resolve();
-
- r = KHUI_NC_RESPONSE_FAILED;
-
- if (suggest_code == KHERR_SUGGEST_RETRY) {
- r |= KHUI_NC_RESPONSE_NOEXIT |
- KHUI_NC_RESPONSE_PENDING;
- }
-
-#ifdef DEBUG
- assert(g_fjob.state == FIBER_STATE_NONE);
-#endif
-
- if (g_fjob.valid_principal &&
- nc->n_identities > 0 &&
- nc->identities[0]) {
- /* the principal was valid, so we can go ahead
- and update the LRU */
- k5_update_LRU(nc->identities[0]);
- }
-
- } else if (nc->result == KHUI_NC_RESULT_PROCESS &&
- g_fjob.state == FIBER_STATE_NONE) {
- krb5_context ctx = NULL;
-
- _reportf(L"Tickets successfully acquired");
-
- r = KHUI_NC_RESPONSE_SUCCESS |
- KHUI_NC_RESPONSE_EXIT;
-
- /* if we successfully obtained credentials, we
- should save the current settings in the
- identity config space */
-
- assert(nc->n_identities > 0);
- assert(nc->identities[0]);
-
- k5_write_dlg_params(d, nc->identities[0]);
-
- /* We should also quickly refresh the credentials
- so that the identity flags and ccache
- properties reflect the current state of
- affairs. This has to be done here so that
- other credentials providers which depend on
- Krb5 can properly find the initial creds to
- obtain their respective creds. */
-
- khm_krb5_list_tickets(&ctx);
-
- if (nc->set_default) {
- _reportf(L"Setting default identity");
- kcdb_identity_set_default(nc->identities[0]);
- }
-
- /* If there is no default identity, then make this the default */
- kcdb_identity_refresh(nc->identities[0]);
- {
- khm_handle tdefault = NULL;
-
- if (KHM_SUCCEEDED(kcdb_identity_get_default(&tdefault))) {
- kcdb_identity_release(tdefault);
- } else {
- _reportf(L"There was no default identity. Setting default");
- kcdb_identity_set_default(nc->identities[0]);
- }
- }
-
- /* and update the LRU */
- k5_update_LRU(nc->identities[0]);
-
- if (ctx != NULL)
- pkrb5_free_context(ctx);
- } else if (g_fjob.state == FIBER_STATE_NONE) {
- /* the user cancelled the operation */
- r = KHUI_NC_RESPONSE_EXIT |
- KHUI_NC_RESPONSE_SUCCESS;
- }
-
- if(g_fjob.state == FIBER_STATE_NONE) {
- khui_cw_set_response(nc, credtype_id_krb5, r);
-
- if (r & KHUI_NC_RESPONSE_NOEXIT) {
- /* if we are retrying the call, we should
- restart the kinit fiber */
-#ifdef DEBUG
- assert(r & KHUI_NC_RESPONSE_PENDING);
-#endif
-
- k5_prep_kinit_job(nc);
- SwitchToFiber(k5_kinit_fiber);
- } else {
- /* free up the fiber data fields. */
- k5_free_kinit_job();
- }
- } else {
- khui_cw_set_response(nc, credtype_id_krb5,
- KHUI_NC_RESPONSE_NOEXIT |
- KHUI_NC_RESPONSE_PENDING | r);
- }
-
- _end_task();
- } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) {
-
- FILETIME ftidexp = {0,0};
- FILETIME ftcurrent;
- khm_size cb;
-
- GetSystemTimeAsFileTime(&ftcurrent);
-
- _begin_task(0);
- _report_mr0(KHERR_NONE, MSG_CTX_RENEW_CREDS);
- _describe();
-
- if (nc->ctx.scope == KHUI_SCOPE_IDENT ||
- (nc->ctx.scope == KHUI_SCOPE_CREDTYPE &&
- nc->ctx.cred_type == credtype_id_krb5) ||
- (nc->ctx.scope == KHUI_SCOPE_CRED &&
- nc->ctx.cred_type == credtype_id_krb5)) {
- int code;
-
- if (nc->ctx.scope == KHUI_SCOPE_CRED &&
- nc->ctx.cred != NULL) {
-
- /* get the expiration time for the identity first. */
- cb = sizeof(ftidexp);
-#ifdef DEBUG
- assert(nc->ctx.identity != NULL);
-#endif
- kcdb_identity_get_attr(nc->ctx.identity,
- KCDB_ATTR_EXPIRE,
- NULL,
- &ftidexp,
- &cb);
-
- code = khm_krb5_renew_cred(nc->ctx.cred);
-
- } else if (nc->ctx.scope == KHUI_SCOPE_IDENT &&
- nc->ctx.identity != 0) {
- /* get the current identity expiration time */
- cb = sizeof(ftidexp);
-
- kcdb_identity_get_attr(nc->ctx.identity,
- KCDB_ATTR_EXPIRE,
- NULL,
- &ftidexp,
- &cb);
-
- code = khm_krb5_renew_ident(nc->ctx.identity);
- } else {
-
- _reportf(L"No identity specified. Can't renew Kerberos tickets");
-
- code = 1; /* it just has to be non-zero */
- }
-
- if (code == 0) {
- _reportf(L"Tickets successfully renewed");
-
- khui_cw_set_response(nc, credtype_id_krb5,
- KHUI_NC_RESPONSE_EXIT |
- KHUI_NC_RESPONSE_SUCCESS);
- } else if (nc->ctx.identity == 0) {
-
- _report_mr0(KHERR_ERROR, MSG_ERR_NO_IDENTITY);
-
- khui_cw_set_response(nc, credtype_id_krb5,
- KHUI_NC_RESPONSE_EXIT |
- KHUI_NC_RESPONSE_FAILED);
- } else if (CompareFileTime(&ftcurrent, &ftidexp) < 0) {
- wchar_t tbuf[1024];
- DWORD suggestion;
- kherr_suggestion sug_id;
-
- /* if we failed to get new tickets, but the
- identity is still valid, then we assume that
- the current tickets are still good enough
- for other credential types to obtain their
- credentials. */
-
- khm_err_describe(code, tbuf, sizeof(tbuf),
- &suggestion, &sug_id);
-
- _report_cs0(KHERR_WARNING, tbuf);
- if (suggestion)
- _suggest_mr(suggestion, sug_id);
-
- _resolve();
-
- khui_cw_set_response(nc, credtype_id_krb5,
- KHUI_NC_RESPONSE_EXIT |
- KHUI_NC_RESPONSE_SUCCESS);
- } else {
- wchar_t tbuf[1024];
- DWORD suggestion;
- kherr_suggestion sug_id;
-
- khm_err_describe(code, tbuf, sizeof(tbuf),
- &suggestion, &sug_id);
-
- _report_cs0(KHERR_ERROR, tbuf);
- if (suggestion)
- _suggest_mr(suggestion, sug_id);
-
- _resolve();
-
- khui_cw_set_response(nc, credtype_id_krb5,
- ((sug_id == KHERR_SUGGEST_RETRY)?KHUI_NC_RESPONSE_NOEXIT:KHUI_NC_RESPONSE_EXIT) |
- KHUI_NC_RESPONSE_FAILED);
- }
- } else {
- khui_cw_set_response(nc, credtype_id_krb5,
- KHUI_NC_RESPONSE_EXIT |
- KHUI_NC_RESPONSE_SUCCESS);
- }
-
- _end_task();
- } else if (nc->subtype == KMSG_CRED_PASSWORD &&
- nc->result == KHUI_NC_RESULT_PROCESS) {
-
- change_password:
- /* we jump here if there was a password change forced */
-
- _begin_task(0);
- _report_mr0(KHERR_NONE, MSG_CTX_PASSWD);
- _describe();
-
- khui_cw_lock_nc(nc);
-
- if (nc->result == KHUI_NC_RESULT_CANCEL) {
-
- khui_cw_set_response(nc, credtype_id_krb5,
- KHUI_NC_RESPONSE_SUCCESS |
- KHUI_NC_RESPONSE_EXIT);
-
- } else if (nc->n_identities == 0 ||
- nc->identities[0] == NULL) {
- _report_mr0(KHERR_ERROR, MSG_PWD_NO_IDENTITY);
- _suggest_mr(MSG_PWD_S_NO_IDENTITY, KHERR_SUGGEST_RETRY);
-
- khui_cw_set_response(nc, credtype_id_krb5,
- KHUI_NC_RESPONSE_FAILED |
- KHUI_NC_RESPONSE_NOEXIT);
-
- } else {
- wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
- char idname[KCDB_IDENT_MAXCCH_NAME];
- wchar_t wpwd[KHUI_MAXCCH_PASSWORD];
- char pwd[KHUI_MAXCCH_PASSWORD];
- wchar_t wnpwd[KHUI_MAXCCH_PASSWORD];
- char npwd[KHUI_MAXCCH_PASSWORD];
- wchar_t wnpwd2[KHUI_MAXCCH_PASSWORD];
- wchar_t * wresult;
- char * result;
- khm_size n_prompts = 0;
- khm_size cb;
- khm_int32 rv = KHM_ERROR_SUCCESS;
- long code = 0;
- khm_handle ident;
-
- khui_cw_get_prompt_count(nc, &n_prompts);
- assert(n_prompts == 3);
-
- ident = nc->identities[0];
- cb = sizeof(widname);
- rv = kcdb_identity_get_name(ident, widname, &cb);
- if (KHM_FAILED(rv)) {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- _report_mr0(KHERR_ERROR, MSG_PWD_UNKNOWN);
- goto _pwd_exit;
- }
-
- cb = sizeof(wpwd);
- rv = khui_cw_get_prompt_value(nc, 0, wpwd, &cb);
- if (KHM_FAILED(rv)) {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- _report_mr0(KHERR_ERROR, MSG_PWD_UNKNOWN);
- goto _pwd_exit;
- }
-
- cb = sizeof(wnpwd);
- rv = khui_cw_get_prompt_value(nc, 1, wnpwd, &cb);
- if (KHM_FAILED(rv)) {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- _report_mr0(KHERR_ERROR, MSG_PWD_UNKNOWN);
- goto _pwd_exit;
- }
-
- cb = sizeof(wnpwd2);
- rv = khui_cw_get_prompt_value(nc, 2, wnpwd2, &cb);
- if (KHM_FAILED(rv)) {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- _report_mr0(KHERR_ERROR, MSG_PWD_UNKNOWN);
- goto _pwd_exit;
- }
-
- if (wcscmp(wnpwd, wnpwd2)) {
- rv = KHM_ERROR_INVALID_PARAM;
- _report_mr0(KHERR_ERROR, MSG_PWD_NOT_SAME);
- _suggest_mr(MSG_PWD_S_NOT_SAME, KHERR_SUGGEST_INTERACT);
- goto _pwd_exit;
- }
-
- if (!wcscmp(wpwd, wnpwd)) {
- rv = KHM_ERROR_INVALID_PARAM;
- _report_mr0(KHERR_ERROR, MSG_PWD_SAME);
- _suggest_mr(MSG_PWD_S_SAME, KHERR_SUGGEST_INTERACT);
- goto _pwd_exit;
- }
-
- UnicodeStrToAnsi(idname, sizeof(idname), widname);
- UnicodeStrToAnsi(pwd, sizeof(pwd), wpwd);
- UnicodeStrToAnsi(npwd, sizeof(npwd), wnpwd);
-
- result = NULL;
-
- code = khm_krb5_changepwd(idname,
- pwd,
- npwd,
- &result);
-
- if (code)
- rv = KHM_ERROR_UNKNOWN;
- else {
- khm_handle csp_idcfg = NULL;
- krb5_context ctx = NULL;
-
- /* we set a new password. now we need to get
- initial credentials. */
-
- d = (k5_dlg_data *) nct->aux;
-
- if (d == NULL) {
- rv = KHM_ERROR_UNKNOWN;
- goto _pwd_exit;
- }
-
- if (nc->subtype == KMSG_CRED_PASSWORD) {
- /* since this was just a password change,
- we need to load new credentials options
- from the configuration store. */
-
- k5_read_dlg_params(d, nc->identities[0]);
- }
-
- /* the password change phase is now done */
- d->pwd_change = FALSE;
-
-#ifdef DEBUG
- _reportf(L"Calling khm_krb5_kinit()");
-#endif
- code = khm_krb5_kinit(NULL, /* context (create one) */
- idname, /* principal_name */
- npwd, /* new password */
- NULL, /* ccache name (figure out the identity cc)*/
- (krb5_deltat) d->tc_lifetime.current,
- d->forwardable,
- d->proxiable,
- (krb5_deltat)((d->renewable)?d->tc_renew.current:0),
- d->addressless, /* addressless */
- d->publicIP, /* public IP */
- NULL, /* prompter */
- NULL /* prompter data */);
-
- if (code) {
- rv = KHM_ERROR_UNKNOWN;
- goto _pwd_exit;
- }
-
- /* save the settings that we used for
- obtaining the ticket. */
- if (nc->subtype == KMSG_CRED_NEW_CREDS) {
-
- k5_write_dlg_params(d, nc->identities[0]);
-
- /* and then update the LRU too */
- k5_update_LRU(nc->identities[0]);
- }
-
- /* and do a quick refresh of the krb5 tickets
- so that other plug-ins that depend on krb5
- can look up tickets inside NetIDMgr */
- khm_krb5_list_tickets(&ctx);
-
- /* if there was no default identity, we make
- this one the default. */
- kcdb_identity_refresh(nc->identities[0]);
- {
- khm_handle tdefault = NULL;
-
- if (KHM_SUCCEEDED(kcdb_identity_get_default(&tdefault))) {
- kcdb_identity_release(tdefault);
- } else {
- _reportf(L"There was no default identity. Setting defualt");
- kcdb_identity_set_default(nc->identities[0]);
- }
- }
-
- if (ctx != NULL)
- pkrb5_free_context(ctx);
-
- if (nc->subtype == KMSG_CRED_PASSWORD) {
- /* if we obtained new credentials as a
- result of successfully changing the
- password, we also schedule an identity
- renewal for this identity. This allows
- the other credential types to obtain
- credentials for this identity. */
- khui_action_context ctx;
-
- _reportf(L"Scheduling renewal of [%s] after password change",
- widname);
-
- khui_context_create(&ctx,
- KHUI_SCOPE_IDENT,
- nc->identities[0],
- KCDB_CREDTYPE_INVALID,
- NULL);
- khui_action_trigger(KHUI_ACTION_RENEW_CRED,
- &ctx);
-
- khui_context_release(&ctx);
- }
- }
-
- /* result is only set when code != 0 */
- if (code && result) {
- size_t len;
-
- StringCchLengthA(result, KHERR_MAXCCH_STRING,
- &len);
- wresult = PMALLOC((len + 1) * sizeof(wchar_t));
-#ifdef DEBUG
- assert(wresult);
-#endif
- AnsiStrToUnicode(wresult, (len + 1) * sizeof(wchar_t),
- result);
-
- _report_cs1(KHERR_ERROR, L"%1!s!", _cstr(wresult));
- _resolve();
-
- PFREE(result);
- PFREE(wresult);
-
- /* we don't need to report anything more */
- code = 0;
- }
-
- _pwd_exit:
- if (KHM_FAILED(rv)) {
- if (code) {
- wchar_t tbuf[1024];
- DWORD suggestion;
- kherr_suggestion sug_id;
-
- khm_err_describe(code, tbuf, sizeof(tbuf),
- &suggestion, &sug_id);
- _report_cs0(KHERR_ERROR, tbuf);
-
- if (suggestion)
- _suggest_mr(suggestion, sug_id);
-
- _resolve();
- }
-
- khui_cw_set_response(nc, credtype_id_krb5,
- KHUI_NC_RESPONSE_NOEXIT|
- KHUI_NC_RESPONSE_FAILED);
- } else {
- khui_cw_set_response(nc, credtype_id_krb5,
- KHUI_NC_RESPONSE_SUCCESS |
- KHUI_NC_RESPONSE_EXIT);
- }
- }
-
- khui_cw_unlock_nc(nc);
-
- _end_task();
- } /* KMSG_CRED_PASSWORD */
- }
- break;
-
- case KMSG_CRED_END:
- {
- khui_new_creds * nc;
- khui_new_creds_by_type * nct;
-
- nc = (khui_new_creds *) vparam;
- khui_cw_find_type(nc, credtype_id_krb5, &nct);
-
- if(!nct)
- break;
-
- khui_cw_del_type(nc, credtype_id_krb5);
-
- if (nct->name)
- PFREE(nct->name);
- if (nct->credtext)
- PFREE(nct->credtext);
-
- PFREE(nct);
-
- k5_free_kinit_job();
- }
- break;
-
- case KMSG_CRED_IMPORT:
- {
- khm_int32 t = 0;
-
-#ifdef DEBUG
- assert(csp_params);
-#endif
- khc_read_int32(csp_params, L"MsLsaImport", &t);
-
- if (t != K5_LSAIMPORT_NEVER) {
- krb5_context ctx = NULL;
- khm_handle id_default = NULL;
- khm_handle id_imported = NULL;
- BOOL imported;
-
- imported = khm_krb5_ms2mit(NULL, (t == K5_LSAIMPORT_MATCH), TRUE,
- &id_imported);
- if (imported) {
- khm_krb5_list_tickets(&ctx);
-
- if (ctx)
- pkrb5_free_context(ctx);
-
- kcdb_identity_refresh(id_imported);
-
- if (KHM_SUCCEEDED(kcdb_identity_get_default(&id_default))) {
- kcdb_identity_release(id_default);
- id_default = NULL;
- } else {
- _reportf(L"There was no default identity. Setting default");
- kcdb_identity_set_default(id_imported);
- }
-
- /* and update the LRU */
- k5_update_LRU(id_imported);
- }
-
- if (id_imported)
- kcdb_identity_release(id_imported);
- }
- }
- break;
- }
-
- return rv;
-}
+/*
+ * Copyright (c) 2006 Secure Endpoints Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<kherror.h>
+#include<khmsgtypes.h>
+#include<strsafe.h>
+#include<krb5.h>
+
+#include<commctrl.h>
+
+#include<assert.h>
+
+extern LPVOID k5_main_fiber;
+extern LPVOID k5_kinit_fiber;
+
+typedef struct k5_dlg_data_t {
+ khui_new_creds * nc;
+
+ khui_tracker tc_lifetime;
+ khui_tracker tc_renew;
+
+ BOOL dirty; /* is the data in sync with the
+ configuration store? */
+ BOOL sync; /* is the data in sync with the kinit
+ request? */
+ DWORD renewable;
+ DWORD forwardable;
+ DWORD proxiable;
+ DWORD addressless;
+ DWORD publicIP;
+
+ wchar_t * cred_message; /* overrides the credential text, if
+ non-NULL */
+ BOOL pwd_change; /* force a password change */
+} k5_dlg_data;
+
+
+INT_PTR
+k5_handle_wm_initdialog(HWND hwnd,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ HWND hw;
+ k5_dlg_data * d;
+ khui_new_creds_by_type * nct;
+
+ d = PMALLOC(sizeof(*d));
+ ZeroMemory(d, sizeof(*d));
+ /* lParam is a pointer to a khui_new_creds structure */
+ d->nc = (khui_new_creds *) lParam;
+ khui_cw_find_type(d->nc, credtype_id_krb5, &nct);
+
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) d);
+#pragma warning(pop)
+
+ nct->aux = (LPARAM) d;
+
+ if (d->nc->subtype == KMSG_CRED_NEW_CREDS) {
+ khui_tracker_initialize(&d->tc_lifetime);
+ khui_tracker_initialize(&d->tc_renew);
+
+ hw = GetDlgItem(hwnd, IDC_NCK5_LIFETIME_EDIT);
+ khui_tracker_install(hw, &d->tc_lifetime);
+
+ hw = GetDlgItem(hwnd, IDC_NCK5_RENEW_EDIT);
+ khui_tracker_install(hw, &d->tc_renew);
+ }
+ return TRUE;
+}
+
+INT_PTR
+k5_handle_wm_destroy(HWND hwnd,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ k5_dlg_data * d;
+ khui_new_creds_by_type * nct = NULL;
+
+ d = (k5_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (!d)
+ return TRUE;
+
+ khui_cw_find_type(d->nc, credtype_id_krb5, &nct);
+
+#ifdef DEBUG
+ assert(nct);
+#endif
+
+ nct->aux = 0;
+
+ if (d->nc->subtype == KMSG_CRED_NEW_CREDS) {
+ khui_tracker_kill_controls(&d->tc_renew);
+ khui_tracker_kill_controls(&d->tc_lifetime);
+ }
+
+ PFREE(d);
+
+ return TRUE;
+}
+
+LRESULT
+k5_force_password_change(k5_dlg_data * d) {
+ /* we are turning this dialog into a change password dialog... */
+ wchar_t wbuf[KHUI_MAXCCH_BANNER];
+
+ khui_cw_clear_prompts(d->nc);
+
+ LoadString(hResModule, IDS_NC_PWD_BANNER,
+ wbuf, ARRAYLENGTH(wbuf));
+ khui_cw_begin_custom_prompts(d->nc, 3, NULL, wbuf);
+
+ LoadString(hResModule, IDS_NC_PWD_PWD,
+ wbuf, ARRAYLENGTH(wbuf));
+ khui_cw_add_prompt(d->nc, KHUI_NCPROMPT_TYPE_PASSWORD,
+ wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);
+
+ LoadString(hResModule, IDS_NC_PWD_NPWD,
+ wbuf, ARRAYLENGTH(wbuf));
+ khui_cw_add_prompt(d->nc, KHUI_NCPROMPT_TYPE_NEW_PASSWORD,
+ wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);
+
+ LoadString(hResModule, IDS_NC_PWD_NPWD_AGAIN,
+ wbuf, ARRAYLENGTH(wbuf));
+ khui_cw_add_prompt(d->nc, KHUI_NCPROMPT_TYPE_NEW_PASSWORD_AGAIN,
+ wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);
+
+ d->pwd_change = TRUE;
+
+ if (is_k5_identpro &&
+ d->nc->n_identities > 0 &&
+ d->nc->identities[0]) {
+
+ kcdb_identity_set_flags(d->nc->identities[0],
+ KCDB_IDENT_FLAG_VALID,
+ KCDB_IDENT_FLAG_VALID);
+
+ }
+
+ PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT),
+ (LPARAM) d->nc);
+
+ return TRUE;
+}
+
+INT_PTR
+k5_handle_wmnc_notify(HWND hwnd,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ switch(HIWORD(wParam)) {
+ case WMNC_DIALOG_MOVE:
+ {
+ k5_dlg_data * d;
+
+ d = (k5_dlg_data *)(LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (d->nc->subtype == KMSG_CRED_NEW_CREDS) {
+ khui_tracker_reposition(&d->tc_lifetime);
+ khui_tracker_reposition(&d->tc_renew);
+ }
+
+ return TRUE;
+ }
+ break;
+
+ case WMNC_DIALOG_SETUP:
+ {
+ k5_dlg_data * d;
+ BOOL old_sync;
+
+ d = (k5_dlg_data *)(LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (d->nc->subtype == KMSG_CRED_PASSWORD)
+ return TRUE;
+
+ /* we save the value of the 'sync' field here because some
+ of the notifications that are generated while setting
+ the controls overwrite the field. */
+ old_sync = d->sync;
+
+ /* need to update the controls with d->* */
+ SendDlgItemMessage(hwnd, IDC_NCK5_RENEWABLE,
+ BM_SETCHECK,
+ (d->renewable? BST_CHECKED : BST_UNCHECKED),
+ 0);
+ EnableWindow(GetDlgItem(hwnd, IDC_NCK5_RENEW_EDIT),
+ !!d->renewable);
+
+ khui_tracker_refresh(&d->tc_lifetime);
+ khui_tracker_refresh(&d->tc_renew);
+
+ SendDlgItemMessage(hwnd, IDC_NCK5_FORWARDABLE,
+ BM_SETCHECK,
+ (d->forwardable ? BST_CHECKED : BST_UNCHECKED),
+ 0);
+
+ SendDlgItemMessage(hwnd, IDC_NCK5_ADDRESS,
+ BM_SETCHECK,
+ (d->addressless ? BST_CHECKED : BST_UNCHECKED),
+ 0);
+
+ SendDlgItemMessage(hwnd, IDC_NCK5_PUBLICIP,
+ IPM_SETADDRESS,
+ 0, d->publicIP);
+
+ EnableWindow(GetDlgItem(hwnd, IDC_NCK5_PUBLICIP), !d->addressless);
+
+ d->sync = old_sync;
+ }
+ break;
+
+ case WMNC_CREDTEXT_LINK:
+ {
+ k5_dlg_data * d;
+ khui_htwnd_link * l;
+ khui_new_creds * nc;
+ wchar_t linktext[128];
+
+ d = (k5_dlg_data *)(LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+ nc = d->nc;
+ l = (khui_htwnd_link *) lParam;
+
+ if (!l)
+ break;
+
+ StringCchCopyN(linktext, ARRAYLENGTH(linktext),
+ l->id, l->id_len);
+
+ if (!wcscmp(linktext, L"Krb5Cred:!Passwd")) {
+ return k5_force_password_change(d);
+ }
+ }
+ break;
+
+ case WMNC_UPDATE_CREDTEXT:
+ {
+ k5_dlg_data * d;
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct;
+ wchar_t sbuf[1024];
+ wchar_t fbuf[256];
+ wchar_t tbuf[256];
+ size_t cbsize;
+ khm_int32 flags;
+
+ d = (k5_dlg_data *)(LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+ nc = d->nc;
+ khui_cw_find_type(nc, credtype_id_krb5, &nct);
+
+ if(nct == NULL)
+ break;
+
+ if(nct->credtext)
+ PFREE(nct->credtext);
+ nct->credtext = NULL;
+
+ tbuf[0] = L'\0';
+
+ if (nc->n_identities > 0 &&
+ KHM_SUCCEEDED(kcdb_identity_get_flags(nc->identities[0],
+ &flags)) &&
+ (flags & KCDB_IDENT_FLAG_VALID) &&
+ nc->subtype == KMSG_CRED_NEW_CREDS &&
+ !d->pwd_change) {
+
+ if (is_k5_identpro)
+ k5_get_realm_from_nc(nc, tbuf, ARRAYLENGTH(tbuf));
+ else
+ GetDlgItemText(hwnd, IDC_NCK5_REALM, tbuf,
+ ARRAYLENGTH(tbuf));
+
+ /*TODO: if additional realms were specified, then those
+ must be listed as well */
+ LoadString(hResModule, IDS_KRB5_CREDTEXT_0,
+ fbuf, ARRAYLENGTH(fbuf));
+ StringCbPrintf(sbuf, sizeof(sbuf), fbuf,
+ tbuf);
+
+ StringCbLength(sbuf, sizeof(sbuf), &cbsize);
+ cbsize += sizeof(wchar_t);
+
+ nct->credtext = PMALLOC(cbsize);
+
+ StringCbCopy(nct->credtext, cbsize, sbuf);
+ } else if (nc->n_identities > 0 &&
+ (nc->subtype == KMSG_CRED_PASSWORD ||
+ (nc->subtype == KMSG_CRED_NEW_CREDS && d->pwd_change))) {
+ cbsize = sizeof(tbuf);
+ kcdb_identity_get_name(nc->identities[0], tbuf, &cbsize);
+
+ LoadString(hResModule, IDS_KRB5_CREDTEXT_P0,
+ fbuf, ARRAYLENGTH(fbuf));
+ StringCbPrintf(sbuf, sizeof(sbuf), fbuf, tbuf);
+
+ StringCbLength(sbuf, sizeof(sbuf), &cbsize);
+ cbsize += sizeof(wchar_t);
+
+ nct->credtext = PMALLOC(cbsize);
+
+ StringCbCopy(nct->credtext, cbsize, sbuf);
+ } else {
+ if (d->cred_message) {
+ StringCbLength(d->cred_message, KHUI_MAXCB_BANNER,
+ &cbsize);
+ cbsize += sizeof(wchar_t);
+
+ nct->credtext = PMALLOC(cbsize);
+
+ StringCbCopy(nct->credtext, cbsize, d->cred_message);
+ }
+ }
+ }
+ break;
+
+ case WMNC_IDENTITY_CHANGE:
+ {
+ /* There has been a change of identity */
+ k5_dlg_data * d;
+
+ d = (k5_dlg_data *)(LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ kmq_post_sub_msg(k5_sub, KMSG_CRED,
+ KMSG_CRED_DIALOG_NEW_IDENTITY,
+ 0, (void *) d->nc);
+ }
+ break;
+
+ case WMNC_DIALOG_PREPROCESS:
+ {
+ k5_dlg_data * d;
+
+ d = (k5_dlg_data *)(LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if(!d->sync && d->nc->result == KHUI_NC_RESULT_PROCESS) {
+ kmq_post_sub_msg(k5_sub, KMSG_CRED,
+ KMSG_CRED_DIALOG_NEW_OPTIONS,
+ 0, (void *) d->nc);
+ }
+ }
+ break;
+
+ case K5_SET_CRED_MSG:
+ {
+ k5_dlg_data * d;
+ khm_size cb;
+ wchar_t * msg;
+
+ d = (k5_dlg_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ msg = (wchar_t *) lParam;
+
+ if (d->cred_message) {
+ PFREE(d->cred_message);
+ d->cred_message = NULL;
+ }
+
+ if (msg &&
+ SUCCEEDED(StringCbLength(msg,
+ KHUI_MAXCB_MESSAGE,
+ &cb))) {
+ cb += sizeof(wchar_t);
+ d->cred_message = PMALLOC(cb);
+#ifdef DEBUG
+ assert(d->cred_message);
+#endif
+ StringCbCopy(d->cred_message, cb, msg);
+ }
+ }
+ break;
+ }
+
+ return 0;
+}
+
+INT_PTR
+k5_handle_wm_notify(HWND hwnd,
+ WPARAM wParam,
+ LPARAM lParam) {
+ LPNMHDR pnmh;
+ k5_dlg_data * d;
+
+ pnmh = (LPNMHDR) lParam;
+ if (pnmh->idFrom == IDC_NCK5_PUBLICIP &&
+ pnmh->code == IPN_FIELDCHANGED) {
+
+ d = (k5_dlg_data *) (LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
+
+ SendDlgItemMessage(hwnd, IDC_NCK5_PUBLICIP,
+ IPM_GETADDRESS,
+ 0, (LPARAM) &d->publicIP);
+
+ d->dirty = TRUE;
+ d->sync = FALSE;
+
+ return TRUE;
+ }
+
+ return 0;
+}
+
+INT_PTR
+k5_handle_wm_command(HWND hwnd,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ int cid;
+ int notif;
+ k5_dlg_data * d;
+
+ d = (k5_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
+
+ cid = LOWORD(wParam);
+ notif = HIWORD(wParam);
+
+ if(notif == BN_CLICKED && cid == IDC_NCK5_RENEWABLE) {
+ int c;
+ c = (int) SendDlgItemMessage(hwnd, IDC_NCK5_RENEWABLE,
+ BM_GETCHECK, 0, 0);
+ if(c==BST_CHECKED) {
+ EnableWindow(GetDlgItem(hwnd, IDC_NCK5_RENEW_EDIT), TRUE);
+ d->renewable = TRUE;
+ } else {
+ EnableWindow(GetDlgItem(hwnd, IDC_NCK5_RENEW_EDIT), FALSE);
+ d->renewable = FALSE;
+ }
+ d->dirty = TRUE;
+ d->sync = FALSE;
+ } else if(notif == BN_CLICKED && cid == IDC_NCK5_FORWARDABLE) {
+ int c;
+ c = (int) SendDlgItemMessage(hwnd, IDC_NCK5_FORWARDABLE,
+ BM_GETCHECK, 0, 0);
+ if(c==BST_CHECKED) {
+ d->forwardable = TRUE;
+ } else {
+ d->forwardable = FALSE;
+ }
+ d->dirty = TRUE;
+ d->sync = FALSE;
+ } else if (notif == BN_CLICKED && cid == IDC_NCK5_ADDRESS) {
+ int c;
+
+ c = (int) SendDlgItemMessage(hwnd, IDC_NCK5_ADDRESS,
+ BM_GETCHECK, 0, 0);
+
+ if (c==BST_CHECKED) {
+ d->addressless = TRUE;
+ } else {
+ d->addressless = FALSE;
+ }
+ d->dirty = TRUE;
+ d->sync = FALSE;
+
+ EnableWindow(GetDlgItem(hwnd, IDC_NCK5_PUBLICIP), !d->addressless);
+ } else if (notif == EN_CHANGE && (cid == IDC_NCK5_RENEW_EDIT ||
+ cid == IDC_NCK5_LIFETIME_EDIT)) {
+ d->dirty = TRUE;
+ d->sync = FALSE;
+ } else if((notif == CBN_SELCHANGE ||
+ notif == CBN_KILLFOCUS) &&
+ cid == IDC_NCK5_REALM &&
+ !is_k5_identpro) {
+ /* find out what the realm of the current identity
+ is, and if they are the same, then we don't do
+ anything */
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t realm[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t *r;
+ khm_size cbsize;
+ khm_handle ident;
+ int idx;
+
+ if(d->nc->n_identities > 0) {
+ if(notif == CBN_SELCHANGE) {
+ idx = (int) SendDlgItemMessage(hwnd, IDC_NCK5_REALM,
+ CB_GETCURSEL, 0, 0);
+ SendDlgItemMessage(hwnd, IDC_NCK5_REALM,
+ CB_GETLBTEXT, idx, (LPARAM) realm);
+ } else {
+ GetDlgItemText(hwnd, IDC_NCK5_REALM,
+ realm, ARRAYLENGTH(realm));
+ }
+ cbsize = sizeof(idname);
+ if(KHM_SUCCEEDED(kcdb_identity_get_name(d->nc->identities[0],
+ idname, &cbsize))) {
+ r = wcschr(idname, L'@');
+ if(r && !wcscmp(realm, r+1))
+ return 0; /* nothing to do */
+
+ if(!r) {
+ r = idname + wcslen(idname);
+ *r++ = L'@';
+ *r++ = 0;
+ }
+
+ /* if we get here, we have a new user */
+ StringCchCopy(r+1,
+ ARRAYLENGTH(idname) - ((r+1) - idname),
+ realm);
+ if(KHM_SUCCEEDED(kcdb_identity_create(idname,
+ KCDB_IDENT_FLAG_CREATE,
+ &ident))) {
+ khui_cw_set_primary_id(d->nc, ident);
+ kcdb_identity_release(ident);
+ }
+ return 0;
+ }
+ }
+
+ /* if we get here, we have a new realm, but there is no
+ identity */
+ PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
+ }
+
+ return 0;
+}
+
+
+/* Dialog procedure for the Krb5 credentials type panel.
+
+ NOTE: Runs in the context of the UI thread
+*/
+INT_PTR CALLBACK
+k5_nc_dlg_proc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ switch(uMsg) {
+ case WM_INITDIALOG:
+ return k5_handle_wm_initdialog(hwnd, wParam, lParam);
+
+ case WM_COMMAND:
+ return k5_handle_wm_command(hwnd, wParam, lParam);
+
+ case KHUI_WM_NC_NOTIFY:
+ return k5_handle_wmnc_notify(hwnd, wParam, lParam);
+
+ case WM_NOTIFY:
+ return k5_handle_wm_notify(hwnd, wParam, lParam);
+
+ case WM_DESTROY:
+ return k5_handle_wm_destroy(hwnd, wParam, lParam);
+ }
+ return FALSE;
+}
+
+/* forward dcl */
+krb5_error_code KRB5_CALLCONV
+k5_kinit_prompter(krb5_context context,
+ void *data,
+ const char *name,
+ const char *banner,
+ int num_prompts,
+ krb5_prompt prompts[]);
+
+
+
+fiber_job g_fjob; /* global fiber job object */
+
+static BOOL
+k5_cached_kinit_prompter(void);
+
+static BOOL
+k5_cp_check_continue(void);
+
+/*
+ Runs in the context of the krb5 plugin's slave fiber
+*/
+VOID CALLBACK
+k5_kinit_fiber_proc(PVOID lpParameter)
+{
+ while(TRUE)
+ {
+ if(g_fjob.command == FIBER_CMD_KINIT) {
+ g_fjob.state = FIBER_STATE_KINIT;
+
+ g_fjob.prompt_set = 0;
+
+ if (k5_cached_kinit_prompter()) {
+ SwitchToFiber(k5_main_fiber);
+
+ if (g_fjob.command != FIBER_CMD_CONTINUE)
+ goto _switch_to_main;
+
+ if (!k5_cp_check_continue()) {
+ g_fjob.code = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ goto _switch_to_main;
+ }
+ }
+
+#ifdef DEBUG
+ /* log the state of g_fjob.* */
+ _reportf(L"g_fjob state prior to calling khm_krb5_kinit() :");
+ _reportf(L" g_fjob.principal = [%S]", g_fjob.principal);
+ _reportf(L" g_fjob.code = %d", g_fjob.code);
+ _reportf(L" g_fjob.state = %d", g_fjob.state);
+ _reportf(L" g_fjob.prompt_set= %d", g_fjob.prompt_set);
+ _reportf(L" g_fjob.valid_principal = %d", (int) g_fjob.valid_principal);
+#endif
+
+ /* If we don't know if we have a valid principal, we
+ restrict the options that are set when we call kinit.
+ This way we will be able to use the response from the
+ KDC to verify the principal. */
+
+ g_fjob.retry_if_valid_principal = (g_fjob.forwardable ||
+ g_fjob.proxiable ||
+ g_fjob.renewable);
+
+ retry_kinit:
+ g_fjob.code =
+ khm_krb5_kinit(0,
+ g_fjob.principal,
+ g_fjob.password,
+ g_fjob.ccache,
+ g_fjob.lifetime,
+ g_fjob.valid_principal ? g_fjob.forwardable : 0,
+ g_fjob.valid_principal ? g_fjob.proxiable : 0,
+ (g_fjob.valid_principal && g_fjob.renewable ? g_fjob.renew_life : 0),
+ g_fjob.addressless,
+ g_fjob.publicIP,
+ k5_kinit_prompter,
+ &g_fjob);
+
+ /* If the principal was found to be valid, and if we
+ restricted the options that were being passed to kinit,
+ then we need to retry the kinit call. This time we use
+ the real options. */
+ if (g_fjob.state == FIBER_STATE_RETRY_KINIT) {
+#ifdef DEBUG
+ assert(g_fjob.valid_principal);
+#endif
+ g_fjob.state = FIBER_STATE_KINIT;
+ goto retry_kinit;
+ }
+ }
+
+ _switch_to_main:
+ g_fjob.state = FIBER_STATE_NONE;
+
+ SwitchToFiber(k5_main_fiber);
+ }
+}
+
+/* return TRUE if we should go ahead with creds acquisition */
+static BOOL
+k5_cp_check_continue(void) {
+ khm_size i;
+ khm_size n_p;
+ khui_new_creds_prompt * p;
+ size_t cch;
+
+#ifdef DEBUG
+ assert(g_fjob.nc);
+#endif
+
+ if (KHM_FAILED(khui_cw_get_prompt_count(g_fjob.nc, &n_p))) {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ return TRUE;
+ }
+
+ khui_cw_sync_prompt_values(g_fjob.nc);
+
+ g_fjob.null_password = FALSE;
+
+ /* we are just checking whether there was a password field that
+ was left empty, in which case we can't continue with the
+ credentials acquisition. */
+ for (i=0; i < n_p; i++) {
+ if(KHM_FAILED(khui_cw_get_prompt(g_fjob.nc,
+ (int) i,
+ &p)))
+ continue;
+ if(p->type == KHUI_NCPROMPT_TYPE_PASSWORD) {
+ if (p->value == NULL ||
+ FAILED(StringCchLength(p->value, KHUI_MAXCCH_PROMPT,
+ &cch)) ||
+ cch == 0) {
+ g_fjob.null_password = TRUE;
+ return FALSE;
+ } else
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* returns true if we find cached prompts */
+static BOOL
+k5_cached_kinit_prompter(void) {
+ BOOL rv = FALSE;
+ khm_handle ident;
+ khm_handle csp_idconfig = NULL;
+ khm_handle csp_k5config = NULL;
+ khm_handle csp_prcache = NULL;
+ khm_size cb;
+ khm_size n_cur_prompts;
+ khm_int32 n_prompts;
+ khm_int32 i;
+ khm_int64 iexpiry;
+ FILETIME expiry;
+ FILETIME current;
+
+#ifdef DEBUG
+ assert(g_fjob.nc);
+#endif
+
+ ident = g_fjob.identity;
+ if (!ident)
+ return FALSE;
+
+ /* don't need to hold ident, since it is already held in g_fjob
+ and it doesn't change until we return */
+
+ if (KHM_FAILED(kcdb_identity_get_config(ident, 0, &csp_idconfig)) ||
+
+ KHM_FAILED(khc_open_space(csp_idconfig, CSNAME_KRB5CRED,
+ 0, &csp_k5config)) ||
+
+ KHM_FAILED(khc_open_space(csp_k5config, CSNAME_PROMPTCACHE,
+ 0, &csp_prcache)) ||
+
+ KHM_FAILED(khc_read_int32(csp_prcache, L"PromptCount",
+ &n_prompts)) ||
+ n_prompts == 0)
+
+ goto _cleanup;
+
+ if (KHM_SUCCEEDED(khc_read_int64(csp_prcache, L"ExpiresOn", &iexpiry))) {
+ /* has the cache expired? */
+ expiry = IntToFt(iexpiry);
+ GetSystemTimeAsFileTime(&current);
+
+ if (CompareFileTime(&expiry, &current) < 0)
+ /* already expired */
+ goto _cleanup;
+ } else {
+ /* if there is no value for ExpiresOn, we assume the prompts
+ have already expired. */
+ goto _cleanup;
+ }
+
+ /* we found a prompt cache. We take this to imply that the
+ principal is valid. */
+ g_fjob.valid_principal = TRUE;
+
+ /* check if there are any prompts currently showing. If there are
+ we check if they are the same as the ones we are going to show.
+ In which case we just reuse the exisitng prompts */
+ if (KHM_FAILED(khui_cw_get_prompt_count(g_fjob.nc,
+ &n_cur_prompts)) ||
+ n_prompts != (khm_int32) n_cur_prompts)
+ goto _show_new_prompts;
+
+ for(i = 0; i < n_prompts; i++) {
+ wchar_t wsname[8];
+ wchar_t wprompt[KHUI_MAXCCH_PROMPT];
+ khm_handle csp_p = NULL;
+ khm_int32 p_type;
+ khm_int32 p_flags;
+ khui_new_creds_prompt * p;
+
+ if (KHM_FAILED(khui_cw_get_prompt(g_fjob.nc, i, &p)))
+ break;
+
+ StringCbPrintf(wsname, sizeof(wsname), L"%d", i);
+
+ if (KHM_FAILED(khc_open_space(csp_prcache, wsname, 0, &csp_p)))
+ break;
+
+ cb = sizeof(wprompt);
+ if (KHM_FAILED(khc_read_string(csp_p, L"Prompt",
+ wprompt, &cb))) {
+ khc_close_space(csp_p);
+ break;
+ }
+
+ if (KHM_FAILED(khc_read_int32(csp_p, L"Type", &p_type)))
+ p_type = 0;
+
+ if (KHM_FAILED(khc_read_int32(csp_p, L"Flags", &p_flags)))
+ p_flags = 0;
+
+ if ( /* if we received a prompt string,
+ then it should be the same as the
+ one that is displayed */
+ (wprompt[0] &&
+ (p->prompt == NULL ||
+ wcscmp(wprompt, p->prompt))) ||
+
+ /* if we didn't receive one, then
+ there shouldn't be one displayed.
+ This case really shouldn't happen
+ in reality, but we check anyway. */
+ (!wprompt[0] &&
+ p->prompt != NULL) ||
+
+ /* the type should match */
+ (p_type != p->type) ||
+
+ /* if this prompt should be hidden,
+ then it must also be so */
+ (p_flags != p->flags)
+ ) {
+
+ khc_close_space(csp_p);
+ break;
+
+ }
+
+
+ khc_close_space(csp_p);
+ }
+
+ if (i == n_prompts) {
+ rv = TRUE;
+ goto _cleanup;
+ }
+
+ _show_new_prompts:
+
+ khui_cw_clear_prompts(g_fjob.nc);
+
+ {
+ wchar_t wbanner[KHUI_MAXCCH_BANNER];
+ wchar_t wpname[KHUI_MAXCCH_PNAME];
+
+ cb = sizeof(wbanner);
+ if (KHM_FAILED(khc_read_string(csp_prcache, L"Banner",
+ wbanner, &cb)))
+ wbanner[0] = 0;
+
+ cb = sizeof(wpname);
+ if (KHM_FAILED(khc_read_string(csp_prcache, L"Name",
+ wpname, &cb)))
+ wpname[0] = 0;
+
+ khui_cw_begin_custom_prompts(g_fjob.nc,
+ n_prompts,
+ (wbanner[0]? wbanner: NULL),
+ (wpname[0]? wpname: NULL));
+ }
+
+ for(i = 0; i < n_prompts; i++) {
+ wchar_t wsname[8];
+ wchar_t wprompt[KHUI_MAXCCH_PROMPT];
+ khm_handle csp_p = NULL;
+ khm_int32 p_type;
+ khm_int32 p_flags;
+
+ StringCbPrintf(wsname, sizeof(wsname), L"%d", i);
+
+ if (KHM_FAILED(khc_open_space(csp_prcache, wsname, 0, &csp_p)))
+ break;
+
+ cb = sizeof(wprompt);
+ if (KHM_FAILED(khc_read_string(csp_p, L"Prompt",
+ wprompt, &cb))) {
+ khc_close_space(csp_p);
+ break;
+ }
+
+ if (KHM_FAILED(khc_read_int32(csp_p, L"Type", &p_type)))
+ p_type = 0;
+
+ if (KHM_FAILED(khc_read_int32(csp_p, L"Flags", &p_flags)))
+ p_flags = 0;
+
+ khui_cw_add_prompt(g_fjob.nc, p_type, wprompt, NULL, p_flags);
+
+ khc_close_space(csp_p);
+ }
+
+ if (i < n_prompts) {
+ khui_cw_clear_prompts(g_fjob.nc);
+ } else {
+ rv = TRUE;
+ }
+
+ _cleanup:
+
+ if (csp_prcache)
+ khc_close_space(csp_prcache);
+
+ if (csp_k5config)
+ khc_close_space(csp_k5config);
+
+ if (csp_idconfig)
+ khc_close_space(csp_idconfig);
+
+ return rv;
+}
+
+/* Runs in the context of the Krb5 plugin's slave fiber */
+krb5_error_code KRB5_CALLCONV
+k5_kinit_prompter(krb5_context context,
+ void *data,
+ const char *name,
+ const char *banner,
+ int num_prompts,
+ krb5_prompt prompts[])
+{
+ int i;
+ khui_new_creds * nc;
+ krb5_prompt_type * ptypes;
+ khm_size ncp;
+ krb5_error_code code = 0;
+ BOOL new_prompts = TRUE;
+ khm_handle csp_prcache = NULL;
+
+#ifdef DEBUG
+ _reportf(L"k5_kinit_prompter() received %d prompts with name=[%S] banner=[%S]",
+ num_prompts,
+ name, banner);
+ for (i=0; i < num_prompts; i++) {
+ _reportf(L"Prompt[%d]: string[%S]", i, prompts[i].prompt);
+ }
+#endif
+
+ /* we got prompts? Then we assume that the principal is valid */
+
+ if (!g_fjob.valid_principal) {
+ g_fjob.valid_principal = TRUE;
+
+ /* if the flags that were used to call kinit were restricted
+ because we didn't know the validity of the principal, then
+ we need to go back and retry the call with the correct
+ flags. */
+ if (g_fjob.retry_if_valid_principal) {
+ _reportf(L"Retrying kinit call due to restricted flags on first call.");
+ g_fjob.state = FIBER_STATE_RETRY_KINIT;
+ return KRB5_LIBOS_PWDINTR;
+ }
+ }
+
+ nc = g_fjob.nc;
+
+ if(pkrb5_get_prompt_types)
+ ptypes = pkrb5_get_prompt_types(context);
+ else
+ ptypes = NULL;
+
+ /* check if we are already showing the right prompts */
+ khui_cw_get_prompt_count(nc, &ncp);
+
+ if (num_prompts != (int) ncp)
+ goto _show_new_prompts;
+
+ for (i=0; i < num_prompts; i++) {
+ wchar_t wprompt[KHUI_MAXCCH_PROMPT];
+ khui_new_creds_prompt * p;
+
+ if(prompts[i].prompt) {
+ AnsiStrToUnicode(wprompt, sizeof(wprompt),
+ prompts[i].prompt);
+ } else {
+ wprompt[0] = 0;
+ }
+
+ if (KHM_FAILED(khui_cw_get_prompt(nc, i, &p)))
+ break;
+
+ if ( /* if we received a prompt string,
+ then it should be the same as the
+ one that is displayed */
+ (wprompt[0] &&
+ (p->prompt == NULL ||
+ wcscmp(wprompt, p->prompt))) ||
+ /* if we didn't receive one, then
+ there shouldn't be one displayed.
+ This case really shouldn't happen
+ in reality, but we check anyway. */
+ (!wprompt[0] &&
+ p->prompt != NULL) ||
+ /* the type should match */
+ (ptypes &&
+ ptypes[i] != p->type) ||
+ (!ptypes &&
+ p->type != 0) ||
+ /* if this prompt should be hidden,
+ then it must also be so */
+ (prompts[i].hidden &&
+ !(p->flags & KHUI_NCPROMPT_FLAG_HIDDEN)) ||
+ (!prompts[i].hidden &&
+ (p->flags & KHUI_NCPROMPT_FLAG_HIDDEN))
+ )
+ break;
+ }
+
+ if (i < num_prompts)
+ goto _show_new_prompts;
+
+ new_prompts = FALSE;
+
+ /* ok. looks like we are already showing the same set of prompts
+ that we were supposed to show. Sync up the values and go
+ ahead. */
+ khui_cw_sync_prompt_values(nc);
+ goto _process_prompts;
+
+ _show_new_prompts:
+ /* special case. if there are no actual input controls involved,
+ then we have to show an alerter window and pass through */
+ if (num_prompts == 0) {
+ wchar_t wbanner[KHUI_MAXCCH_BANNER];
+ wchar_t wname[KHUI_MAXCCH_PNAME];
+ wchar_t wident[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t wmsg[KHUI_MAXCCH_MESSAGE];
+ wchar_t wfmt[KHUI_MAXCCH_BANNER];
+ khm_size cb;
+
+ if (!banner) {
+ code = 0;
+ g_fjob.null_password = FALSE;
+ goto _exit;
+ } else {
+ AnsiStrToUnicode(wbanner, sizeof(wbanner), banner);
+ }
+
+ if (name) {
+ AnsiStrToUnicode(wname, sizeof(wname), name);
+ } else {
+ LoadString(hResModule,
+ IDS_KRB5_WARNING,
+ wname,
+ ARRAYLENGTH(wname));
+ }
+
+ cb = sizeof(wident);
+ if (KHM_FAILED(kcdb_identity_get_name(g_fjob.identity, wident, &cb)))
+ wident[0] = L'\0';
+
+ LoadString(hResModule,
+ IDS_KRB5_WARN_FMT,
+ wfmt,
+ ARRAYLENGTH(wfmt));
+
+ StringCbPrintf(wmsg, sizeof(wmsg), wfmt, wident, wbanner);
+
+ khui_alert_show_simple(wname, wmsg, KHERR_WARNING);
+
+ code = 0;
+ g_fjob.null_password = FALSE;
+ goto _exit;
+ }
+
+ /* in addition to showing new prompts, we also cache the set of
+ prompts. */
+ if(g_fjob.prompt_set == 0) {
+ khm_handle csp_idconfig = NULL;
+ khm_handle csp_idk5 = NULL;
+
+ kcdb_identity_get_config(g_fjob.identity,
+ KHM_FLAG_CREATE,
+ &csp_idconfig);
+
+ if (csp_idconfig != NULL)
+ khc_open_space(csp_idconfig,
+ CSNAME_KRB5CRED,
+ KHM_FLAG_CREATE,
+ &csp_idk5);
+
+ if (csp_idk5 != NULL)
+ khc_open_space(csp_idk5,
+ CSNAME_PROMPTCACHE,
+ KHM_FLAG_CREATE,
+ &csp_prcache);
+
+ khc_close_space(csp_idconfig);
+ khc_close_space(csp_idk5);
+ }
+
+ {
+ wchar_t wbanner[KHUI_MAXCCH_BANNER];
+ wchar_t wname[KHUI_MAXCCH_PNAME];
+ FILETIME current;
+ FILETIME lifetime;
+ FILETIME expiry;
+ khm_int64 iexpiry;
+ khm_int32 t = 0;
+
+ if(banner)
+ AnsiStrToUnicode(wbanner, sizeof(wbanner), banner);
+ if(name)
+ AnsiStrToUnicode(wname, sizeof(wname), name);
+
+ khui_cw_clear_prompts(nc);
+
+ khui_cw_begin_custom_prompts(
+ nc,
+ num_prompts,
+ (banner)?wbanner:NULL,
+ (name)?wname:NULL);
+
+ if (csp_prcache) {
+
+ if (banner)
+ khc_write_string(csp_prcache,
+ L"Banner",
+ wbanner);
+ else
+ khc_write_string(csp_prcache,
+ L"Banner",
+ L"");
+
+ if (name)
+ khc_write_string(csp_prcache,
+ L"Name",
+ wname);
+ else if (csp_prcache)
+ khc_write_string(csp_prcache,
+ L"Name",
+ L"");
+
+ khc_write_int32(csp_prcache,
+ L"PromptCount",
+ (khm_int32) num_prompts);
+
+ GetSystemTimeAsFileTime(&current);
+#ifdef USE_PROMPT_CACHE_LIFETIME
+ khc_read_int32(csp_params, L"PromptCacheLifetime", &t);
+ if (t == 0)
+ t = 172800; /* 48 hours */
+#else
+ khc_read_int32(csp_params, L"MaxRenewLifetime", &t);
+ if (t == 0)
+ t = 2592000; /* 30 days */
+ t += 604800; /* + 7 days */
+#endif
+ TimetToFileTimeInterval(t, &lifetime);
+ expiry = FtAdd(&current, &lifetime);
+ iexpiry = FtToInt(&expiry);
+
+ khc_write_int64(csp_prcache, L"ExpiresOn", iexpiry);
+ }
+ }
+
+ for(i=0; i < num_prompts; i++) {
+ wchar_t wprompt[KHUI_MAXCCH_PROMPT];
+
+ if(prompts[i].prompt) {
+ AnsiStrToUnicode(wprompt, sizeof(wprompt),
+ prompts[i].prompt);
+ } else {
+ wprompt[0] = 0;
+ }
+
+ khui_cw_add_prompt(
+ nc,
+ (ptypes?ptypes[i]:0),
+ wprompt,
+ NULL,
+ (prompts[i].hidden?KHUI_NCPROMPT_FLAG_HIDDEN:0));
+
+ if (csp_prcache) {
+ khm_handle csp_p = NULL;
+ wchar_t wnum[8]; /* should be enough for 10
+ million prompts */
+
+ wnum[0] = 0;
+ StringCbPrintf(wnum, sizeof(wnum), L"%d", i);
+
+ khc_open_space(csp_prcache, wnum,
+ KHM_FLAG_CREATE, &csp_p);
+
+ if (csp_p) {
+ khc_write_string(csp_p, L"Prompt", wprompt);
+ khc_write_int32(csp_p, L"Type", (ptypes?ptypes[i]:0));
+ khc_write_int32(csp_p, L"Flags",
+ (prompts[i].hidden?
+ KHUI_NCPROMPT_FLAG_HIDDEN:0));
+
+ khc_close_space(csp_p);
+ }
+ }
+ }
+
+ if (csp_prcache) {
+ khc_close_space(csp_prcache);
+ csp_prcache = NULL;
+ }
+
+ _process_prompts:
+ /* switch back to main thread if we showed new prompts */
+ if (new_prompts)
+ SwitchToFiber(k5_main_fiber);
+
+ /* we get here after the user selects an action that either
+ cancles the credentials acquisition operation or triggers the
+ actual acquisition of credentials. */
+ if(g_fjob.command != FIBER_CMD_CONTINUE &&
+ g_fjob.command != FIBER_CMD_KINIT) {
+ code = KRB5_LIBOS_PWDINTR;
+ goto _exit;
+ }
+
+ g_fjob.null_password = FALSE;
+
+ /* otherwise, we need to get the data back from the UI and
+ return 0 */
+ for(i=0; i<num_prompts; i++) {
+ krb5_data * d;
+ wchar_t wbuf[512];
+ khm_size cbbuf;
+ size_t cch;
+
+ d = prompts[i].reply;
+
+ cbbuf = sizeof(wbuf);
+ if(KHM_SUCCEEDED(khui_cw_get_prompt_value(nc, i, wbuf, &cbbuf))) {
+ UnicodeStrToAnsi(d->data, d->length, wbuf);
+ if(SUCCEEDED(StringCchLengthA(d->data, d->length, &cch)))
+ d->length = (unsigned int) cch;
+ else
+ d->length = 0;
+ } else {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ d->length = 0;
+ }
+
+ if (ptypes &&
+ ptypes[i] == KRB5_PROMPT_TYPE_PASSWORD &&
+ d->length == 0)
+
+ g_fjob.null_password = TRUE;
+ }
+
+ _exit:
+
+ g_fjob.prompt_set++;
+
+ /* entering a NULL password is equivalent to cancelling out */
+ if (g_fjob.null_password)
+ return KRB5_LIBOS_PWDINTR;
+ else
+ return code;
+}
+
+
+void
+k5_read_dlg_params(k5_dlg_data * d, khm_handle identity)
+{
+ k5_params p;
+
+ khm_krb5_get_identity_params(identity, &p);
+
+ d->renewable = p.renewable;
+ d->forwardable = p.forwardable;
+ d->proxiable = p.proxiable;
+ d->addressless = p.addressless;
+ d->publicIP = p.publicIP;
+
+ d->tc_lifetime.current = p.lifetime;
+ d->tc_lifetime.max = p.lifetime_max;
+ d->tc_lifetime.min = p.lifetime_min;
+
+ d->tc_renew.current = p.renew_life;
+ d->tc_renew.max = p.renew_life_max;
+ d->tc_renew.min = p.renew_life_min;
+
+ /* however, if this has externally supplied defaults, we have to
+ use them too. */
+ if (d->nc && d->nc->ctx.vparam &&
+ d->nc->ctx.cb_vparam == sizeof(NETID_DLGINFO)) {
+ LPNETID_DLGINFO pdlginfo;
+
+ pdlginfo = (LPNETID_DLGINFO) d->nc->ctx.vparam;
+ if (pdlginfo->size == NETID_DLGINFO_V1_SZ &&
+ pdlginfo->in.use_defaults == 0) {
+ d->forwardable = pdlginfo->in.forwardable;
+ d->addressless = pdlginfo->in.noaddresses;
+ d->tc_lifetime.current = pdlginfo->in.lifetime;
+ d->tc_renew.current = pdlginfo->in.renew_till;
+
+ if (pdlginfo->in.renew_till == 0)
+ d->renewable = FALSE;
+ else
+ d->renewable = TRUE;
+
+ d->proxiable = pdlginfo->in.proxiable;
+ d->publicIP = pdlginfo->in.publicip;
+ }
+ }
+
+ /* once we read the new data, in, it is no longer considered
+ dirty */
+ d->dirty = FALSE;
+ d->sync = FALSE;
+}
+
+void
+k5_write_dlg_params(k5_dlg_data * d, khm_handle identity)
+{
+
+ k5_params p;
+
+ ZeroMemory(&p, sizeof(p));
+
+ p.source_reg = K5PARAM_FM_ALL; /* we want to write all the
+ settings to the registry, if
+ necessary. */
+
+ p.renewable = d->renewable;
+ p.forwardable = d->forwardable;
+ p.proxiable = d->proxiable;
+ p.addressless = d->addressless;
+ p.publicIP = d->publicIP;
+
+ p.lifetime = (krb5_deltat) d->tc_lifetime.current;
+ p.lifetime_max = (krb5_deltat) d->tc_lifetime.max;
+ p.lifetime_min = (krb5_deltat) d->tc_lifetime.min;
+
+ p.renew_life = (krb5_deltat) d->tc_renew.current;
+ p.renew_life_max = (krb5_deltat) d->tc_renew.max;
+ p.renew_life_min = (krb5_deltat) d->tc_renew.min;
+
+ khm_krb5_set_identity_params(identity, &p);
+
+ /* as in k5_read_dlg_params, once we write the data in, the local
+ data is no longer dirty */
+ d->dirty = FALSE;
+}
+
+void
+k5_free_kinit_job(void)
+{
+ if (g_fjob.principal)
+ PFREE(g_fjob.principal);
+
+ if (g_fjob.password)
+ PFREE(g_fjob.password);
+
+ if (g_fjob.identity)
+ kcdb_identity_release(g_fjob.identity);
+
+ if (g_fjob.ccache)
+ PFREE(g_fjob.ccache);
+
+ ZeroMemory(&g_fjob, sizeof(g_fjob));
+}
+
+void
+k5_prep_kinit_job(khui_new_creds * nc)
+{
+ khui_new_creds_by_type * nct;
+ k5_dlg_data * d;
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cbbuf;
+ size_t size;
+ khm_handle ident;
+ LPNETID_DLGINFO pdlginfo;
+
+ khui_cw_find_type(nc, credtype_id_krb5, &nct);
+ if (!nct)
+ return;
+
+ d = (k5_dlg_data *)(LONG_PTR)
+ GetWindowLongPtr(nct->hwnd_panel, DWLP_USER);
+
+ if (!d)
+ return;
+
+ khui_cw_lock_nc(nc);
+ ident = nc->identities[0];
+ kcdb_identity_hold(ident);
+ khui_cw_unlock_nc(nc);
+
+ cbbuf = sizeof(idname);
+ kcdb_identity_get_name(ident, idname, &cbbuf);
+ StringCchLength(idname, ARRAYLENGTH(idname), &size);
+ size++;
+
+ k5_free_kinit_job();
+
+ g_fjob.command = FIBER_CMD_KINIT;
+ g_fjob.nc = nc;
+ g_fjob.nct = nct;
+ g_fjob.dialog = nct->hwnd_panel;
+ g_fjob.principal = PMALLOC(size);
+ UnicodeStrToAnsi(g_fjob.principal, size, idname);
+ g_fjob.password = NULL;
+ g_fjob.lifetime = (krb5_deltat) d->tc_lifetime.current;
+ g_fjob.forwardable = d->forwardable;
+ g_fjob.proxiable = d->proxiable;
+ g_fjob.renewable = d->renewable;
+ g_fjob.renew_life = (krb5_deltat) d->tc_renew.current;
+ g_fjob.addressless = d->addressless;
+ g_fjob.publicIP = d->publicIP;
+ g_fjob.code = 0;
+ g_fjob.identity = ident;
+ g_fjob.prompt_set = 0;
+ g_fjob.valid_principal = FALSE;
+ g_fjob.retry_if_valid_principal = FALSE;
+
+ /* the value for
+ retry_if_valid_principal is not
+ necessarily the correct value here,
+ but the correct value will be
+ assigned k5_kinit_fiber_proc(). */
+
+ /* if we have external parameters, we should use them as well */
+ if (nc->ctx.cb_vparam == sizeof(NETID_DLGINFO) &&
+ (pdlginfo = nc->ctx.vparam) &&
+ pdlginfo->size == NETID_DLGINFO_V1_SZ) {
+ wchar_t * t;
+
+ if (pdlginfo->in.ccache[0] &&
+ SUCCEEDED(StringCchLength(pdlginfo->in.ccache,
+ NETID_CCACHE_NAME_SZ,
+ &size))) {
+ g_fjob.ccache = PMALLOC(sizeof(char) * (size + 1));
+#ifdef DEBUG
+ assert(g_fjob.ccache);
+#endif
+ UnicodeStrToAnsi(g_fjob.ccache, size + 1,
+ pdlginfo->in.ccache);
+
+ /* this is the same as the output cache */
+
+ StringCbCopy(pdlginfo->out.ccache, sizeof(pdlginfo->out.ccache),
+ pdlginfo->in.ccache);
+ } else {
+ g_fjob.ccache = NULL;
+
+ StringCbCopy(pdlginfo->out.ccache, sizeof(pdlginfo->out.ccache),
+ idname);
+
+ khm_krb5_canon_cc_name(pdlginfo->out.ccache,
+ sizeof(pdlginfo->out.ccache));
+ }
+
+ t = khm_get_realm_from_princ(idname);
+
+ if (t) {
+ StringCbCopy(pdlginfo->out.realm,
+ sizeof(pdlginfo->out.realm),
+ t);
+
+ if ((t - idname) > 1) {
+ StringCchCopyN(pdlginfo->out.username,
+ ARRAYLENGTH(pdlginfo->out.username),
+ idname,
+ (t - idname) - 1);
+ } else {
+ StringCbCopy(pdlginfo->out.username,
+ sizeof(pdlginfo->out.username),
+ L"");
+ }
+ } else {
+ StringCbCopy(pdlginfo->out.username,
+ sizeof(pdlginfo->out.username),
+ idname);
+ StringCbCopy(pdlginfo->out.realm,
+ sizeof(pdlginfo->out.realm),
+ L"");
+ }
+ }
+
+ /* leave identity held, since we added a reference above */
+}
+
+static khm_int32 KHMAPI
+k5_find_tgt_filter(khm_handle cred,
+ khm_int32 flags,
+ void * rock) {
+ khm_handle ident = (khm_handle) rock;
+ khm_handle cident = NULL;
+ khm_int32 f;
+ khm_int32 rv;
+
+ if (KHM_SUCCEEDED(kcdb_cred_get_identity(cred,
+ &cident)) &&
+ cident == ident &&
+ KHM_SUCCEEDED(kcdb_cred_get_flags(cred, &f)) &&
+ (f & KCDB_CRED_FLAG_INITIAL) &&
+ !(f & KCDB_CRED_FLAG_EXPIRED))
+ rv = 1;
+ else
+ rv = 0;
+
+ if (cident)
+ kcdb_identity_release(cident);
+
+ return rv;
+}
+
+khm_int32
+k5_remove_from_LRU(khm_handle identity)
+{
+ wchar_t * wbuf = NULL;
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb;
+ khm_size cb_ms;
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+
+ cb = sizeof(idname);
+ rv = kcdb_identity_get_name(identity, idname, &cb);
+ assert(rv == KHM_ERROR_SUCCESS);
+
+ rv = khc_read_multi_string(csp_params, L"LRUPrincipals", NULL, &cb_ms);
+ if (rv != KHM_ERROR_TOO_LONG)
+ cb_ms = sizeof(wchar_t) * 2;
+
+ wbuf = PMALLOC(cb_ms);
+ assert(wbuf);
+
+ cb = cb_ms;
+
+ if (rv == KHM_ERROR_TOO_LONG) {
+ rv = khc_read_multi_string(csp_params, L"LRUPrincipals", wbuf, &cb);
+ assert(KHM_SUCCEEDED(rv));
+
+ if (multi_string_find(wbuf, idname, KHM_CASE_SENSITIVE) != NULL) {
+ multi_string_delete(wbuf, idname, KHM_CASE_SENSITIVE);
+ }
+ } else {
+ multi_string_init(wbuf, cb_ms);
+ }
+
+ rv = khc_write_multi_string(csp_params, L"LRUPrincipals", wbuf);
+
+ if (wbuf)
+ PFREE(wbuf);
+
+ return rv;
+}
+
+khm_int32
+k5_update_LRU(khm_handle identity)
+{
+ wchar_t * wbuf = NULL;
+ wchar_t * idname = NULL;
+ wchar_t * realm = NULL;
+ khm_size cb;
+ khm_size cb_ms;
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+
+ rv = kcdb_identity_get_name(identity, NULL, &cb);
+ assert(rv == KHM_ERROR_TOO_LONG);
+
+ idname = PMALLOC(cb);
+ assert(idname);
+
+ rv = kcdb_identity_get_name(identity, idname, &cb);
+ assert(KHM_SUCCEEDED(rv));
+
+ rv = khc_read_multi_string(csp_params, L"LRUPrincipals", NULL, &cb_ms);
+ if (rv != KHM_ERROR_TOO_LONG)
+ cb_ms = cb + sizeof(wchar_t);
+ else
+ cb_ms += cb + sizeof(wchar_t);
+
+ wbuf = PMALLOC(cb_ms);
+ assert(wbuf);
+
+ cb = cb_ms;
+
+ if (rv == KHM_ERROR_TOO_LONG) {
+ rv = khc_read_multi_string(csp_params, L"LRUPrincipals", wbuf, &cb);
+ assert(KHM_SUCCEEDED(rv));
+
+ if (multi_string_find(wbuf, idname, KHM_CASE_SENSITIVE) != NULL) {
+ /* it's already there. We remove it here and add it at
+ the top of the LRU list. */
+ multi_string_delete(wbuf, idname, KHM_CASE_SENSITIVE);
+ }
+ } else {
+ multi_string_init(wbuf, cb_ms);
+ }
+
+ cb = cb_ms;
+ rv = multi_string_prepend(wbuf, &cb, idname);
+ assert(KHM_SUCCEEDED(rv));
+
+ rv = khc_write_multi_string(csp_params, L"LRUPrincipals", wbuf);
+
+ realm = khm_get_realm_from_princ(idname);
+ if (realm == NULL || *realm == L'\0')
+ goto _done_with_LRU;
+
+ cb = cb_ms;
+ rv = khc_read_multi_string(csp_params, L"LRURealms", wbuf, &cb);
+
+ if (rv == KHM_ERROR_TOO_LONG) {
+ PFREE(wbuf);
+ wbuf = PMALLOC(cb);
+ assert(wbuf);
+
+ cb_ms = cb;
+
+ rv = khc_read_multi_string(csp_params, L"LRURealms", wbuf, &cb);
+
+ assert(KHM_SUCCEEDED(rv));
+ } else if (rv == KHM_ERROR_SUCCESS) {
+ if (multi_string_find(wbuf, realm, KHM_CASE_SENSITIVE) != NULL) {
+ /* remove the realm and add it at the top later. */
+ multi_string_delete(wbuf, realm, KHM_CASE_SENSITIVE);
+ }
+ } else {
+ multi_string_init(wbuf, cb_ms);
+ }
+
+ cb = cb_ms;
+ rv = multi_string_prepend(wbuf, &cb, realm);
+
+ if (rv == KHM_ERROR_TOO_LONG) {
+ wbuf = PREALLOC(wbuf, cb);
+
+ rv = multi_string_prepend(wbuf, &cb, realm);
+
+ assert(KHM_SUCCEEDED(rv));
+ }
+
+ rv = khc_write_multi_string(csp_params, L"LRURealms", wbuf);
+
+ assert(KHM_SUCCEEDED(rv));
+
+ _done_with_LRU:
+
+ if (wbuf)
+ PFREE(wbuf);
+ if (idname)
+ PFREE(idname);
+
+ return rv;
+}
+
+/* Handler for CRED type messages
+
+ Runs in the context of the Krb5 plugin
+*/
+khm_int32 KHMAPI
+k5_msg_cred_dialog(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam)
+{
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+
+ switch(msg_subtype) {
+
+ case KMSG_CRED_PASSWORD:
+ case KMSG_CRED_NEW_CREDS:
+ {
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct;
+ wchar_t wbuf[256];
+ size_t cbsize;
+
+ nc = (khui_new_creds *) vparam;
+
+ nct = PMALLOC(sizeof(*nct));
+ ZeroMemory(nct, sizeof(*nct));
+
+ nct->type = credtype_id_krb5;
+ nct->ordinal = 1;
+
+ LoadString(hResModule, IDS_KRB5_NC_NAME,
+ wbuf, ARRAYLENGTH(wbuf));
+ StringCbLength(wbuf, sizeof(wbuf), &cbsize);
+ cbsize += sizeof(wchar_t);
+
+ nct->name = PMALLOC(cbsize);
+ StringCbCopy(nct->name, cbsize, wbuf);
+
+ nct->h_module = hResModule;
+ nct->dlg_proc = k5_nc_dlg_proc;
+ if (nc->subtype == KMSG_CRED_PASSWORD)
+ nct->dlg_template = MAKEINTRESOURCE(IDD_NC_KRB5_PASSWORD);
+ else
+ nct->dlg_template = MAKEINTRESOURCE(IDD_NC_KRB5);
+
+ khui_cw_add_type(nc, nct);
+ }
+ break;
+
+ case KMSG_CRED_RENEW_CREDS:
+ {
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct;
+
+ nc = (khui_new_creds *) vparam;
+
+ nct = PMALLOC(sizeof(*nct));
+ ZeroMemory(nct, sizeof(*nct));
+
+ nct->type = credtype_id_krb5;
+
+ khui_cw_add_type(nc, nct);
+ }
+ break;
+
+ case KMSG_CRED_DIALOG_PRESTART:
+ {
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct;
+ k5_dlg_data * d;
+ HWND hwnd;
+ wchar_t * realms;
+ wchar_t * t;
+ wchar_t * defrealm;
+
+ nc = (khui_new_creds *) vparam;
+
+ khui_cw_find_type(nc, credtype_id_krb5, &nct);
+
+ if(!nct)
+ break;
+
+ hwnd = nct->hwnd_panel;
+ d = (k5_dlg_data *)(LONG_PTR)
+ GetWindowLongPtr(nct->hwnd_panel, DWLP_USER);
+
+ /* this can be NULL if the dialog was closed while the
+ plug-in thread was processing. */
+ if (d == NULL)
+ break;
+
+ if (!is_k5_identpro) {
+
+ /* enumerate all realms and place in realms combo box */
+ SendDlgItemMessage(hwnd, IDC_NCK5_REALM,
+ CB_RESETCONTENT,
+ 0, 0);
+
+ realms = khm_krb5_get_realm_list();
+ if(realms) {
+ for (t = realms; t && *t; t = multi_string_next(t)) {
+ SendDlgItemMessage(hwnd, IDC_NCK5_REALM,
+ CB_ADDSTRING,
+ 0, (LPARAM) t);
+ }
+ PFREE(realms);
+ }
+
+ /* and set the default realm */
+ defrealm = khm_krb5_get_default_realm();
+ if(defrealm) {
+ SendDlgItemMessage(hwnd, IDC_NCK5_REALM,
+ CB_SELECTSTRING,
+ (WPARAM) -1,
+ (LPARAM) defrealm);
+
+ SendDlgItemMessage(hwnd, IDC_NCK5_REALM,
+ WM_SETTEXT,
+ 0, (LPARAM) defrealm);
+ PFREE(defrealm);
+ }
+ } else { /* if krb5 is the identity provider */
+ HWND hw_realms;
+
+ /* in this case, the realm selection is done by the
+ identity provider prompts. */
+
+ hw_realms = GetDlgItem(hwnd, IDC_NCK5_REALM);
+#ifdef DEBUG
+ assert(hw_realms);
+#endif
+ EnableWindow(hw_realms, FALSE);
+ }
+
+ if (nc->subtype == KMSG_CRED_NEW_CREDS) {
+ k5_read_dlg_params(d, NULL);
+ }
+
+ PostMessage(hwnd, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0,WMNC_DIALOG_SETUP), 0);
+ }
+ break;
+
+ case KMSG_CRED_DIALOG_NEW_IDENTITY:
+ {
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct;
+ k5_dlg_data * d;
+
+ nc = (khui_new_creds *) vparam;
+
+ khui_cw_find_type(nc, credtype_id_krb5, &nct);
+ if (!nct)
+ break;
+
+ d = (k5_dlg_data *)(LONG_PTR)
+ GetWindowLongPtr(nct->hwnd_panel, DWLP_USER);
+
+ if (d == NULL)
+ break;
+
+ /* we only load the identity specific defaults if the user
+ hasn't changed the options */
+ khui_cw_lock_nc(nc);
+
+ /* ?: It might be better to not load identity defaults if
+ the user has already changed options in the dialog. */
+ if(/* !d->dirty && */ nc->n_identities > 0 &&
+ nc->subtype == KMSG_CRED_NEW_CREDS) {
+
+ k5_read_dlg_params(d, nc->identities[0]);
+
+ PostMessage(nct->hwnd_panel, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0,WMNC_DIALOG_SETUP), 0);
+ }
+
+ khui_cw_unlock_nc(nc);
+
+ /* reset the force-password-change flag if this is a new
+ identity. */
+ d->pwd_change = FALSE;
+ }
+
+ /* fallthrough */
+ case KMSG_CRED_DIALOG_NEW_OPTIONS:
+ {
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct;
+ k5_dlg_data * d;
+
+ nc = (khui_new_creds *) vparam;
+
+ khui_cw_find_type(nc, credtype_id_krb5, &nct);
+ if (!nct)
+ break;
+
+ d = (k5_dlg_data *)(LONG_PTR)
+ GetWindowLongPtr(nct->hwnd_panel, DWLP_USER);
+ if (d == NULL)
+ break;
+
+ if (nc->subtype == KMSG_CRED_PASSWORD) {
+ khm_size n_prompts = 0;
+
+ khui_cw_get_prompt_count(nc, &n_prompts);
+
+ if (nc->n_identities == 0) {
+ if (n_prompts)
+ khui_cw_clear_prompts(nc);
+ } else if (n_prompts != 3) {
+ wchar_t wbuf[KHUI_MAXCCH_BANNER];
+
+ khui_cw_clear_prompts(nc);
+
+ LoadString(hResModule, IDS_NC_PWD_BANNER,
+ wbuf, ARRAYLENGTH(wbuf));
+ khui_cw_begin_custom_prompts(nc, 3, NULL, wbuf);
+
+ LoadString(hResModule, IDS_NC_PWD_PWD,
+ wbuf, ARRAYLENGTH(wbuf));
+ khui_cw_add_prompt(nc, KHUI_NCPROMPT_TYPE_PASSWORD,
+ wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);
+
+ LoadString(hResModule, IDS_NC_PWD_NPWD,
+ wbuf, ARRAYLENGTH(wbuf));
+ khui_cw_add_prompt(nc, KHUI_NCPROMPT_TYPE_NEW_PASSWORD,
+ wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);
+
+ LoadString(hResModule, IDS_NC_PWD_NPWD_AGAIN,
+ wbuf, ARRAYLENGTH(wbuf));
+ khui_cw_add_prompt(nc, KHUI_NCPROMPT_TYPE_NEW_PASSWORD_AGAIN,
+ wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);
+ }
+
+ return KHM_ERROR_SUCCESS;
+ }
+ /* else; nc->subtype == KMSG_CRED_NEW_CREDS */
+
+ assert(nc->subtype == KMSG_CRED_NEW_CREDS);
+
+ /* If we are forcing a password change, then we don't do
+ anything here. Note that if the identity changed, then
+ this field would have been reset, so we would proceed
+ as usual. */
+ if (d->pwd_change)
+ return KHM_ERROR_SUCCESS;
+
+#if 0
+ /* Clearing the prompts at this point is a bad idea since
+ the prompter depends on the prompts to know if this set
+ of prompts is the same as the new set and if so, use
+ the values entered in the old prompts as responses to
+ the new one. */
+ khui_cw_clear_prompts(nc);
+#endif
+
+ /* if the fiber is already in a kinit, cancel it */
+ if(g_fjob.state == FIBER_STATE_KINIT) {
+ g_fjob.command = FIBER_CMD_CANCEL;
+ SwitchToFiber(k5_kinit_fiber);
+ /* we get here when the cancel operation completes */
+ k5_free_kinit_job();
+ }
+
+ khui_cw_lock_nc(nc);
+
+ if(nc->n_identities > 0) {
+ khm_handle ident = nc->identities[0];
+
+ kcdb_identity_hold(ident);
+
+ k5_prep_kinit_job(nc);
+
+ /* after the switch to the fiber, the dialog will be
+ back in sync with the kinit thread. */
+ d->sync = TRUE;
+
+ khui_cw_unlock_nc(nc);
+
+ SwitchToFiber(k5_kinit_fiber);
+ /* we get here when the fiber switches back */
+ if(g_fjob.state == FIBER_STATE_NONE) {
+ wchar_t msg[KHUI_MAXCCH_BANNER];
+ khm_size cb;
+
+ /* Special case. If the users' password has
+ expired, we force a password change dialog on
+ top of the new credentials dialog using a set
+ of custom prompts, but only if we are the
+ identity provider. */
+ if (g_fjob.code == KRB5KDC_ERR_KEY_EXP &&
+ is_k5_identpro) {
+
+ k5_force_password_change(d);
+ goto done_with_bad_princ;
+
+ }
+
+ /* we can't possibly have succeeded without a
+ password */
+ if(g_fjob.code == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN &&
+ is_k5_identpro) {
+ kcdb_identity_set_flags(ident,
+ KCDB_IDENT_FLAG_INVALID,
+ KCDB_IDENT_FLAG_INVALID);
+
+ khui_cw_clear_prompts(nc);
+ }
+
+ if (d->cred_message) {
+ PFREE(d->cred_message);
+ d->cred_message = NULL;
+ }
+
+ msg[0] = L'\0';
+
+ switch(g_fjob.code) {
+ case KRB5KDC_ERR_NAME_EXP:
+ /* principal expired */
+ LoadString(hResModule, IDS_K5ERR_NAME_EXPIRED,
+ msg, ARRAYLENGTH(msg));
+ break;
+
+ case KRB5KDC_ERR_KEY_EXP:
+ {
+ /* password needs changing. */
+ LoadString(hResModule, IDS_K5ERR_KEY_EXPIRED,
+ msg, ARRAYLENGTH(msg));
+ }
+ break;
+
+ default:
+ {
+ DWORD dw_dummy;
+ kherr_suggestion sug_dummy;
+ wchar_t fmt[KHUI_MAXCCH_BANNER];
+ wchar_t desc[KHUI_MAXCCH_BANNER];
+
+ LoadString(hResModule, IDS_K5ERR_FMT,
+ fmt, ARRAYLENGTH(fmt));
+
+ khm_err_describe(g_fjob.code,
+ desc,
+ sizeof(desc),
+ &dw_dummy,
+ &sug_dummy);
+
+ StringCbPrintf(msg, sizeof(msg), fmt, desc);
+ }
+ }
+
+ if (msg[0]) {
+ StringCbLength(msg, sizeof(msg), &cb);
+ cb += sizeof(wchar_t);
+
+ d->cred_message = PMALLOC(cb);
+ StringCbCopy(d->cred_message, cb, msg);
+ }
+
+ done_with_bad_princ:
+
+ k5_free_kinit_job();
+
+ if (is_k5_identpro)
+ kcdb_identity_set_flags(ident,
+ KCDB_IDENT_FLAG_UNKNOWN,
+ KCDB_IDENT_FLAG_UNKNOWN);
+
+
+ } else if(g_fjob.state == FIBER_STATE_KINIT) {
+ /* this is what we want. Leave the fiber there. */
+
+ if(is_k5_identpro)
+ kcdb_identity_set_flags(ident,
+ KCDB_IDENT_FLAG_VALID,
+ KCDB_IDENT_FLAG_VALID);
+ } else {
+ /* huh?? */
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ }
+
+ /* since the attributes of the identity have changed,
+ we should update the cred text as well */
+ kcdb_identity_release(ident);
+ khui_cw_lock_nc(nc);
+ PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
+ } else {
+ khui_cw_unlock_nc(nc);
+ khui_cw_clear_prompts(nc);
+ khui_cw_lock_nc(nc);
+ }
+
+ khui_cw_unlock_nc(nc);
+ }
+ break;
+
+ case KMSG_CRED_PROCESS:
+ {
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct;
+ k5_dlg_data * d;
+
+ khm_int32 r = 0;
+
+ nc = (khui_new_creds *) vparam;
+
+ khui_cw_find_type(nc, credtype_id_krb5, &nct);
+
+ if(!nct)
+ break;
+
+ /* reset the null_password flag, just in case */
+ g_fjob.null_password = FALSE;
+
+ if (nc->subtype == KMSG_CRED_NEW_CREDS) {
+ d = (k5_dlg_data *) nct->aux;
+ if (d == NULL)
+ break;
+
+ if (d->pwd_change) {
+ /* we are forcing a password change */
+ goto change_password;
+ }
+
+ _begin_task(0);
+ _report_mr0(KHERR_NONE, MSG_CTX_INITAL_CREDS);
+ _describe();
+
+ if (g_fjob.state == FIBER_STATE_KINIT) {
+ if(nc->result == KHUI_NC_RESULT_CANCEL) {
+ g_fjob.command = FIBER_CMD_CANCEL;
+ SwitchToFiber(k5_kinit_fiber);
+
+ /* if we cancelled out, then we shouldn't care
+ about the return code. */
+#ifdef DEBUG
+ assert(g_fjob.state == FIBER_STATE_NONE);
+#endif
+ g_fjob.code = 0;
+
+ _reportf(L"Cancelling");
+ } else if (nc->result == KHUI_NC_RESULT_PROCESS) {
+ khui_cw_sync_prompt_values(nc);
+ g_fjob.command = FIBER_CMD_CONTINUE;
+ SwitchToFiber(k5_kinit_fiber);
+
+ /* We get back here once the fiber finishes
+ processing */
+ }
+#ifdef DEBUG
+ else {
+ assert(FALSE);
+ }
+#endif
+ } else {
+ /* we weren't in a KINIT state */
+ if (nc->result == KHUI_NC_RESULT_CANCEL) {
+ /* nothing to report */
+ g_fjob.code = 0;
+ } else if (nc->result == KHUI_NC_RESULT_PROCESS) {
+ /* g_fjob.code should have the result of the
+ last kinit attempt. We should leave it
+ as-is */
+ }
+#ifdef DEBUG
+ else {
+ /* unknown result */
+ assert(FALSE);
+ }
+#endif
+ }
+
+ /* special case: if there was no password entered, and
+ if there is a valid TGT we allow the credential
+ acquisition to go through */
+ if (g_fjob.state == FIBER_STATE_NONE &&
+ g_fjob.code &&
+ g_fjob.null_password &&
+
+ (nc->n_identities == 0 ||
+ nc->identities[0] == NULL ||
+ KHM_SUCCEEDED(kcdb_credset_find_filtered
+ (NULL,
+ -1,
+ k5_find_tgt_filter,
+ nc->identities[0],
+ NULL,
+ NULL)))) {
+ _reportf(L"No password entered, but a valid TGT exists. Continuing");
+ g_fjob.code = 0;
+ } else if (g_fjob.state == FIBER_STATE_NONE &&
+ g_fjob.code == 0 &&
+ nc->n_identities > 0 &&
+ nc->identities[0] != NULL) {
+
+ /* we had a password and we used it to get
+ tickets. We should reset the IMPORTED flag now
+ since the tickets are not imported. */
+
+ khm_krb5_set_identity_flags(nc->identities[0],
+ K5IDFLAG_IMPORTED,
+ 0);
+ }
+
+ if(g_fjob.code != 0) {
+ wchar_t tbuf[1024];
+ DWORD suggestion;
+ kherr_suggestion suggest_code;
+
+ khm_err_describe(g_fjob.code, tbuf, sizeof(tbuf),
+ &suggestion, &suggest_code);
+
+ _report_cs0(KHERR_ERROR, tbuf);
+ if (suggestion != 0)
+ _suggest_mr(suggestion, suggest_code);
+
+ _resolve();
+
+ r = KHUI_NC_RESPONSE_FAILED;
+
+ if (suggest_code == KHERR_SUGGEST_RETRY) {
+ r |= KHUI_NC_RESPONSE_NOEXIT |
+ KHUI_NC_RESPONSE_PENDING;
+ }
+
+#ifdef DEBUG
+ assert(g_fjob.state == FIBER_STATE_NONE);
+#endif
+
+ if (g_fjob.valid_principal &&
+ nc->n_identities > 0 &&
+ nc->identities[0]) {
+ /* the principal was valid, so we can go ahead
+ and update the LRU */
+ k5_update_LRU(nc->identities[0]);
+ }
+
+ } else if (nc->result == KHUI_NC_RESULT_PROCESS &&
+ g_fjob.state == FIBER_STATE_NONE) {
+ krb5_context ctx = NULL;
+
+ _reportf(L"Tickets successfully acquired");
+
+ r = KHUI_NC_RESPONSE_SUCCESS |
+ KHUI_NC_RESPONSE_EXIT;
+
+ /* if we successfully obtained credentials, we
+ should save the current settings in the
+ identity config space */
+
+ assert(nc->n_identities > 0);
+ assert(nc->identities[0]);
+
+ k5_write_dlg_params(d, nc->identities[0]);
+
+ /* We should also quickly refresh the credentials
+ so that the identity flags and ccache
+ properties reflect the current state of
+ affairs. This has to be done here so that
+ other credentials providers which depend on
+ Krb5 can properly find the initial creds to
+ obtain their respective creds. */
+
+ khm_krb5_list_tickets(&ctx);
+
+ if (nc->set_default) {
+ _reportf(L"Setting default identity");
+ kcdb_identity_set_default(nc->identities[0]);
+ }
+
+ /* If there is no default identity, then make this the default */
+ kcdb_identity_refresh(nc->identities[0]);
+ {
+ khm_handle tdefault = NULL;
+
+ if (KHM_SUCCEEDED(kcdb_identity_get_default(&tdefault))) {
+ kcdb_identity_release(tdefault);
+ } else {
+ _reportf(L"There was no default identity. Setting default");
+ kcdb_identity_set_default(nc->identities[0]);
+ }
+ }
+
+ /* and update the LRU */
+ k5_update_LRU(nc->identities[0]);
+
+ if (ctx != NULL)
+ pkrb5_free_context(ctx);
+ } else if (g_fjob.state == FIBER_STATE_NONE) {
+ /* the user cancelled the operation */
+ r = KHUI_NC_RESPONSE_EXIT |
+ KHUI_NC_RESPONSE_SUCCESS;
+ }
+
+ if(g_fjob.state == FIBER_STATE_NONE) {
+ khui_cw_set_response(nc, credtype_id_krb5, r);
+
+ if (r & KHUI_NC_RESPONSE_NOEXIT) {
+ /* if we are retrying the call, we should
+ restart the kinit fiber */
+#ifdef DEBUG
+ assert(r & KHUI_NC_RESPONSE_PENDING);
+#endif
+
+ k5_prep_kinit_job(nc);
+ SwitchToFiber(k5_kinit_fiber);
+ } else {
+ /* free up the fiber data fields. */
+ k5_free_kinit_job();
+ }
+ } else {
+ khui_cw_set_response(nc, credtype_id_krb5,
+ KHUI_NC_RESPONSE_NOEXIT |
+ KHUI_NC_RESPONSE_PENDING | r);
+ }
+
+ _end_task();
+ } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) {
+
+ FILETIME ftidexp = {0,0};
+ FILETIME ftcurrent;
+ khm_size cb;
+
+ GetSystemTimeAsFileTime(&ftcurrent);
+
+ _begin_task(0);
+ _report_mr0(KHERR_NONE, MSG_CTX_RENEW_CREDS);
+ _describe();
+
+ if (nc->ctx.scope == KHUI_SCOPE_IDENT ||
+ (nc->ctx.scope == KHUI_SCOPE_CREDTYPE &&
+ nc->ctx.cred_type == credtype_id_krb5) ||
+ (nc->ctx.scope == KHUI_SCOPE_CRED &&
+ nc->ctx.cred_type == credtype_id_krb5)) {
+ int code;
+
+ if (nc->ctx.scope == KHUI_SCOPE_CRED &&
+ nc->ctx.cred != NULL) {
+
+ /* get the expiration time for the identity first. */
+ cb = sizeof(ftidexp);
+#ifdef DEBUG
+ assert(nc->ctx.identity != NULL);
+#endif
+ kcdb_identity_get_attr(nc->ctx.identity,
+ KCDB_ATTR_EXPIRE,
+ NULL,
+ &ftidexp,
+ &cb);
+
+ code = khm_krb5_renew_cred(nc->ctx.cred);
+
+ } else if (nc->ctx.scope == KHUI_SCOPE_IDENT &&
+ nc->ctx.identity != 0) {
+ /* get the current identity expiration time */
+ cb = sizeof(ftidexp);
+
+ kcdb_identity_get_attr(nc->ctx.identity,
+ KCDB_ATTR_EXPIRE,
+ NULL,
+ &ftidexp,
+ &cb);
+
+ code = khm_krb5_renew_ident(nc->ctx.identity);
+ } else {
+
+ _reportf(L"No identity specified. Can't renew Kerberos tickets");
+
+ code = 1; /* it just has to be non-zero */
+ }
+
+ if (code == 0) {
+ _reportf(L"Tickets successfully renewed");
+
+ khui_cw_set_response(nc, credtype_id_krb5,
+ KHUI_NC_RESPONSE_EXIT |
+ KHUI_NC_RESPONSE_SUCCESS);
+ } else if (nc->ctx.identity == 0) {
+
+ _report_mr0(KHERR_ERROR, MSG_ERR_NO_IDENTITY);
+
+ khui_cw_set_response(nc, credtype_id_krb5,
+ KHUI_NC_RESPONSE_EXIT |
+ KHUI_NC_RESPONSE_FAILED);
+ } else if (CompareFileTime(&ftcurrent, &ftidexp) < 0) {
+ wchar_t tbuf[1024];
+ DWORD suggestion;
+ kherr_suggestion sug_id;
+
+ /* if we failed to get new tickets, but the
+ identity is still valid, then we assume that
+ the current tickets are still good enough
+ for other credential types to obtain their
+ credentials. */
+
+ khm_err_describe(code, tbuf, sizeof(tbuf),
+ &suggestion, &sug_id);
+
+ _report_cs0(KHERR_WARNING, tbuf);
+ if (suggestion)
+ _suggest_mr(suggestion, sug_id);
+
+ _resolve();
+
+ khui_cw_set_response(nc, credtype_id_krb5,
+ KHUI_NC_RESPONSE_EXIT |
+ KHUI_NC_RESPONSE_SUCCESS);
+ } else {
+ wchar_t tbuf[1024];
+ DWORD suggestion;
+ kherr_suggestion sug_id;
+
+ khm_err_describe(code, tbuf, sizeof(tbuf),
+ &suggestion, &sug_id);
+
+ _report_cs0(KHERR_ERROR, tbuf);
+ if (suggestion)
+ _suggest_mr(suggestion, sug_id);
+
+ _resolve();
+
+ khui_cw_set_response(nc, credtype_id_krb5,
+ ((sug_id == KHERR_SUGGEST_RETRY)?KHUI_NC_RESPONSE_NOEXIT:KHUI_NC_RESPONSE_EXIT) |
+ KHUI_NC_RESPONSE_FAILED);
+ }
+ } else {
+ khui_cw_set_response(nc, credtype_id_krb5,
+ KHUI_NC_RESPONSE_EXIT |
+ KHUI_NC_RESPONSE_SUCCESS);
+ }
+
+ _end_task();
+ } else if (nc->subtype == KMSG_CRED_PASSWORD &&
+ nc->result == KHUI_NC_RESULT_PROCESS) {
+
+ change_password:
+ /* we jump here if there was a password change forced */
+
+ _begin_task(0);
+ _report_mr0(KHERR_NONE, MSG_CTX_PASSWD);
+ _describe();
+
+ khui_cw_lock_nc(nc);
+
+ if (nc->result == KHUI_NC_RESULT_CANCEL) {
+
+ khui_cw_set_response(nc, credtype_id_krb5,
+ KHUI_NC_RESPONSE_SUCCESS |
+ KHUI_NC_RESPONSE_EXIT);
+
+ } else if (nc->n_identities == 0 ||
+ nc->identities[0] == NULL) {
+ _report_mr0(KHERR_ERROR, MSG_PWD_NO_IDENTITY);
+ _suggest_mr(MSG_PWD_S_NO_IDENTITY, KHERR_SUGGEST_RETRY);
+
+ khui_cw_set_response(nc, credtype_id_krb5,
+ KHUI_NC_RESPONSE_FAILED |
+ KHUI_NC_RESPONSE_NOEXIT);
+
+ } else {
+ wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
+ char idname[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t wpwd[KHUI_MAXCCH_PASSWORD];
+ char pwd[KHUI_MAXCCH_PASSWORD];
+ wchar_t wnpwd[KHUI_MAXCCH_PASSWORD];
+ char npwd[KHUI_MAXCCH_PASSWORD];
+ wchar_t wnpwd2[KHUI_MAXCCH_PASSWORD];
+ wchar_t * wresult;
+ char * result;
+ khm_size n_prompts = 0;
+ khm_size cb;
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+ long code = 0;
+ khm_handle ident;
+
+ khui_cw_get_prompt_count(nc, &n_prompts);
+ assert(n_prompts == 3);
+
+ ident = nc->identities[0];
+ cb = sizeof(widname);
+ rv = kcdb_identity_get_name(ident, widname, &cb);
+ if (KHM_FAILED(rv)) {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ _report_mr0(KHERR_ERROR, MSG_PWD_UNKNOWN);
+ goto _pwd_exit;
+ }
+
+ cb = sizeof(wpwd);
+ rv = khui_cw_get_prompt_value(nc, 0, wpwd, &cb);
+ if (KHM_FAILED(rv)) {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ _report_mr0(KHERR_ERROR, MSG_PWD_UNKNOWN);
+ goto _pwd_exit;
+ }
+
+ cb = sizeof(wnpwd);
+ rv = khui_cw_get_prompt_value(nc, 1, wnpwd, &cb);
+ if (KHM_FAILED(rv)) {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ _report_mr0(KHERR_ERROR, MSG_PWD_UNKNOWN);
+ goto _pwd_exit;
+ }
+
+ cb = sizeof(wnpwd2);
+ rv = khui_cw_get_prompt_value(nc, 2, wnpwd2, &cb);
+ if (KHM_FAILED(rv)) {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ _report_mr0(KHERR_ERROR, MSG_PWD_UNKNOWN);
+ goto _pwd_exit;
+ }
+
+ if (wcscmp(wnpwd, wnpwd2)) {
+ rv = KHM_ERROR_INVALID_PARAM;
+ _report_mr0(KHERR_ERROR, MSG_PWD_NOT_SAME);
+ _suggest_mr(MSG_PWD_S_NOT_SAME, KHERR_SUGGEST_INTERACT);
+ goto _pwd_exit;
+ }
+
+ if (!wcscmp(wpwd, wnpwd)) {
+ rv = KHM_ERROR_INVALID_PARAM;
+ _report_mr0(KHERR_ERROR, MSG_PWD_SAME);
+ _suggest_mr(MSG_PWD_S_SAME, KHERR_SUGGEST_INTERACT);
+ goto _pwd_exit;
+ }
+
+ UnicodeStrToAnsi(idname, sizeof(idname), widname);
+ UnicodeStrToAnsi(pwd, sizeof(pwd), wpwd);
+ UnicodeStrToAnsi(npwd, sizeof(npwd), wnpwd);
+
+ result = NULL;
+
+ code = khm_krb5_changepwd(idname,
+ pwd,
+ npwd,
+ &result);
+
+ if (code)
+ rv = KHM_ERROR_UNKNOWN;
+ else {
+ khm_handle csp_idcfg = NULL;
+ krb5_context ctx = NULL;
+
+ /* we set a new password. now we need to get
+ initial credentials. */
+
+ d = (k5_dlg_data *) nct->aux;
+
+ if (d == NULL) {
+ rv = KHM_ERROR_UNKNOWN;
+ goto _pwd_exit;
+ }
+
+ if (nc->subtype == KMSG_CRED_PASSWORD) {
+ /* since this was just a password change,
+ we need to load new credentials options
+ from the configuration store. */
+
+ k5_read_dlg_params(d, nc->identities[0]);
+ }
+
+ /* the password change phase is now done */
+ d->pwd_change = FALSE;
+
+#ifdef DEBUG
+ _reportf(L"Calling khm_krb5_kinit()");
+#endif
+ code = khm_krb5_kinit(NULL, /* context (create one) */
+ idname, /* principal_name */
+ npwd, /* new password */
+ NULL, /* ccache name (figure out the identity cc)*/
+ (krb5_deltat) d->tc_lifetime.current,
+ d->forwardable,
+ d->proxiable,
+ (krb5_deltat)((d->renewable)?d->tc_renew.current:0),
+ d->addressless, /* addressless */
+ d->publicIP, /* public IP */
+ NULL, /* prompter */
+ NULL /* prompter data */);
+
+ if (code) {
+ rv = KHM_ERROR_UNKNOWN;
+ goto _pwd_exit;
+ }
+
+ /* save the settings that we used for
+ obtaining the ticket. */
+ if (nc->subtype == KMSG_CRED_NEW_CREDS) {
+
+ k5_write_dlg_params(d, nc->identities[0]);
+
+ /* and then update the LRU too */
+ k5_update_LRU(nc->identities[0]);
+ }
+
+ /* and do a quick refresh of the krb5 tickets
+ so that other plug-ins that depend on krb5
+ can look up tickets inside NetIDMgr */
+ khm_krb5_list_tickets(&ctx);
+
+ /* if there was no default identity, we make
+ this one the default. */
+ kcdb_identity_refresh(nc->identities[0]);
+ {
+ khm_handle tdefault = NULL;
+
+ if (KHM_SUCCEEDED(kcdb_identity_get_default(&tdefault))) {
+ kcdb_identity_release(tdefault);
+ } else {
+ _reportf(L"There was no default identity. Setting defualt");
+ kcdb_identity_set_default(nc->identities[0]);
+ }
+ }
+
+ if (ctx != NULL)
+ pkrb5_free_context(ctx);
+
+ if (nc->subtype == KMSG_CRED_PASSWORD) {
+ /* if we obtained new credentials as a
+ result of successfully changing the
+ password, we also schedule an identity
+ renewal for this identity. This allows
+ the other credential types to obtain
+ credentials for this identity. */
+ khui_action_context ctx;
+
+ _reportf(L"Scheduling renewal of [%s] after password change",
+ widname);
+
+ khui_context_create(&ctx,
+ KHUI_SCOPE_IDENT,
+ nc->identities[0],
+ KCDB_CREDTYPE_INVALID,
+ NULL);
+ khui_action_trigger(KHUI_ACTION_RENEW_CRED,
+ &ctx);
+
+ khui_context_release(&ctx);
+ }
+ }
+
+ /* result is only set when code != 0 */
+ if (code && result) {
+ size_t len;
+
+ StringCchLengthA(result, KHERR_MAXCCH_STRING,
+ &len);
+ wresult = PMALLOC((len + 1) * sizeof(wchar_t));
+#ifdef DEBUG
+ assert(wresult);
+#endif
+ AnsiStrToUnicode(wresult, (len + 1) * sizeof(wchar_t),
+ result);
+
+ _report_cs1(KHERR_ERROR, L"%1!s!", _cstr(wresult));
+ _resolve();
+
+ PFREE(result);
+ PFREE(wresult);
+
+ /* we don't need to report anything more */
+ code = 0;
+ }
+
+ _pwd_exit:
+ if (KHM_FAILED(rv)) {
+ if (code) {
+ wchar_t tbuf[1024];
+ DWORD suggestion;
+ kherr_suggestion sug_id;
+
+ khm_err_describe(code, tbuf, sizeof(tbuf),
+ &suggestion, &sug_id);
+ _report_cs0(KHERR_ERROR, tbuf);
+
+ if (suggestion)
+ _suggest_mr(suggestion, sug_id);
+
+ _resolve();
+ }
+
+ khui_cw_set_response(nc, credtype_id_krb5,
+ KHUI_NC_RESPONSE_NOEXIT|
+ KHUI_NC_RESPONSE_FAILED);
+ } else {
+ khui_cw_set_response(nc, credtype_id_krb5,
+ KHUI_NC_RESPONSE_SUCCESS |
+ KHUI_NC_RESPONSE_EXIT);
+ }
+ }
+
+ khui_cw_unlock_nc(nc);
+
+ _end_task();
+ } /* KMSG_CRED_PASSWORD */
+ }
+ break;
+
+ case KMSG_CRED_END:
+ {
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct;
+
+ nc = (khui_new_creds *) vparam;
+ khui_cw_find_type(nc, credtype_id_krb5, &nct);
+
+ if(!nct)
+ break;
+
+ khui_cw_del_type(nc, credtype_id_krb5);
+
+ if (nct->name)
+ PFREE(nct->name);
+ if (nct->credtext)
+ PFREE(nct->credtext);
+
+ PFREE(nct);
+
+ k5_free_kinit_job();
+ }
+ break;
+
+ case KMSG_CRED_IMPORT:
+ {
+ khm_int32 t = 0;
+
+#ifdef DEBUG
+ assert(csp_params);
+#endif
+ khc_read_int32(csp_params, L"MsLsaImport", &t);
+
+ if (t != K5_LSAIMPORT_NEVER) {
+ krb5_context ctx = NULL;
+ khm_handle id_default = NULL;
+ khm_handle id_imported = NULL;
+ BOOL imported;
+
+ imported = khm_krb5_ms2mit(NULL, (t == K5_LSAIMPORT_MATCH), TRUE,
+ &id_imported);
+ if (imported) {
+ khm_krb5_list_tickets(&ctx);
+
+ if (ctx)
+ pkrb5_free_context(ctx);
+
+ kcdb_identity_refresh(id_imported);
+
+ if (KHM_SUCCEEDED(kcdb_identity_get_default(&id_default))) {
+ kcdb_identity_release(id_default);
+ id_default = NULL;
+ } else {
+ _reportf(L"There was no default identity. Setting default");
+ kcdb_identity_set_default(id_imported);
+ }
+
+ /* and update the LRU */
+ k5_update_LRU(id_imported);
+ }
+
+ if (id_imported)
+ kcdb_identity_release(id_imported);
+ }
+ }
+ break;
+ }
+
+ return rv;
+}
diff --git a/src/windows/identity/plugins/krb5/krb5plugin.c b/src/windows/identity/plugins/krb5/krb5plugin.c
index bb481e0fb..61331f384 100644
--- a/src/windows/identity/plugins/krb5/krb5plugin.c
+++ b/src/windows/identity/plugins/krb5/krb5plugin.c
@@ -1,265 +1,265 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<kherror.h>
-#include<khmsgtypes.h>
-#include<commctrl.h>
-#include<strsafe.h>
-#include<krb5.h>
-
-#ifdef DEBUG
-#include<assert.h>
-#endif
-
-khm_int32 credtype_id_krb5 = KCDB_CREDTYPE_INVALID;
-khm_boolean krb5_initialized = FALSE;
-khm_handle krb5_credset = NULL;
-
-khm_handle k5_sub = NULL;
-
-LPVOID k5_main_fiber = NULL;
-LPVOID k5_kinit_fiber = NULL;
-
-VOID CALLBACK k5_kinit_fiber_proc(PVOID lpParameter);
-
-krb5_context k5_identpro_ctx = NULL;
-
-/* The system message handler.
-
- Runs in the context of the plugin thread */
-khm_int32 KHMAPI
-k5_msg_system(khm_int32 msg_type, khm_int32 msg_subtype,
- khm_ui_4 uparam, void * vparam)
-{
- khm_int32 rv = KHM_ERROR_SUCCESS;
-
- switch(msg_subtype) {
- case KMSG_SYSTEM_INIT:
- {
- kcdb_credtype ct;
- wchar_t buf[KCDB_MAXCCH_SHORT_DESC];
- size_t cbsize;
-
- /* perform critical registrations and initialization
- stuff */
- ZeroMemory(&ct, sizeof(ct));
- ct.id = KCDB_CREDTYPE_AUTO;
- ct.name = KRB5_CREDTYPE_NAME;
-
- if(LoadString(hResModule, IDS_KRB5_SHORT_DESC,
- buf, ARRAYLENGTH(buf))) {
- StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize);
- cbsize += sizeof(wchar_t);
- ct.short_desc = PMALLOC(cbsize);
- StringCbCopy(ct.short_desc, cbsize, buf);
- }
-
- /* even though ideally we should be setting limits
- based KCDB_MAXCB_LONG_DESC, our long description
- actually fits nicely in KCDB_MAXCB_SHORT_DESC */
- if(LoadString(hResModule, IDS_KRB5_LONG_DESC,
- buf, ARRAYLENGTH(buf))) {
- StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize);
- cbsize += sizeof(wchar_t);
- ct.long_desc = PMALLOC(cbsize);
- StringCbCopy(ct.long_desc, cbsize, buf);
- }
-
- ct.icon = NULL; /* TODO: set a proper icon */
-
- kmq_create_subscription(k5_msg_callback, &ct.sub);
-
- ct.is_equal = khm_krb5_creds_is_equal;
-
- rv = kcdb_credtype_register(&ct, &credtype_id_krb5);
-
- if(KHM_SUCCEEDED(rv))
- rv = kcdb_credset_create(&krb5_credset);
-
- if(ct.short_desc)
- PFREE(ct.short_desc);
-
- if(ct.long_desc)
- PFREE(ct.long_desc);
-
- if(KHM_SUCCEEDED(rv)) {
- krb5_context ctx = NULL;
-
- krb5_initialized = TRUE;
-
- /* now convert this thread to a fiber and create a
- separate fiber to do kinit stuff */
- k5_main_fiber = ConvertThreadToFiber(NULL);
- k5_kinit_fiber = CreateFiber(0,k5_kinit_fiber_proc,NULL);
-
- ZeroMemory(&g_fjob, sizeof(g_fjob));
-
- kmq_create_subscription(k5_msg_callback, &k5_sub);
-
- k5_register_config_panels();
-
- khm_krb5_list_tickets(&ctx);
-
- if(ctx != NULL)
- pkrb5_free_context(ctx);
- }
- }
- break;
-
- case KMSG_SYSTEM_EXIT:
-
- k5_unregister_config_panels();
-
- if(credtype_id_krb5 >= 0) {
- /* basically just unregister the credential type */
- kcdb_credtype_unregister(credtype_id_krb5);
-
- /* kcdb knows how to deal with bad handles */
- kcdb_credset_delete(krb5_credset);
- krb5_credset = NULL;
- }
-
- if(k5_main_fiber != NULL) {
- if (k5_kinit_fiber) {
-#ifdef DEBUG
- assert(k5_kinit_fiber != GetCurrentFiber());
-#endif
-#ifdef CLEANUP_FIBERS_ON_EXIT
- DeleteFiber(k5_kinit_fiber);
- CloseHandle(k5_kinit_fiber);
-#endif
- k5_kinit_fiber = NULL;
- }
-
- k5_main_fiber = NULL;
- }
-
- if(k5_sub != NULL) {
- kmq_delete_subscription(k5_sub);
- k5_sub = NULL;
- }
-
- break;
- }
-
- return rv;
-}
-
-khm_int32 KHMAPI
-k5_msg_kcdb(khm_int32 msg_type, khm_int32 msg_subtype,
- khm_ui_4 uparam, void * vparam)
-{
- khm_int32 rv = KHM_ERROR_SUCCESS;
-
- switch(msg_subtype) {
- case KMSG_KCDB_IDENT:
- if (uparam == KCDB_OP_DELCONFIG) {
- k5_remove_from_LRU((khm_handle) vparam);
- }
- break;
- }
-
- return rv;
-}
-
-
-/* Handler for CRED type messages
-
- Runs in the context of the Krb5 plugin
-*/
-khm_int32 KHMAPI
-k5_msg_cred(khm_int32 msg_type, khm_int32 msg_subtype,
- khm_ui_4 uparam, void * vparam)
-{
- khm_int32 rv = KHM_ERROR_SUCCESS;
-
- switch(msg_subtype) {
- case KMSG_CRED_REFRESH:
- {
- krb5_context ctx = NULL;
-
- khm_krb5_list_tickets(&ctx);
-
- if(ctx != NULL)
- pkrb5_free_context(ctx);
- }
- break;
-
- case KMSG_CRED_DESTROY_CREDS:
- {
- khui_action_context * ctx;
-
- ctx = (khui_action_context *) vparam;
-
- if (ctx->credset) {
- _begin_task(0);
- _report_mr0(KHERR_INFO, MSG_ERR_CTX_DESTROY_CREDS);
- _describe();
-
- khm_krb5_destroy_by_credset(ctx->credset);
-
- _end_task();
- }
- }
- break;
-
- case KMSG_CRED_PP_BEGIN:
- k5_pp_begin((khui_property_sheet *) vparam);
- break;
-
- case KMSG_CRED_PP_END:
- k5_pp_end((khui_property_sheet *) vparam);
- break;
-
- default:
- if(IS_CRED_ACQ_MSG(msg_subtype))
- return k5_msg_cred_dialog(msg_type, msg_subtype,
- uparam, vparam);
- }
-
- return rv;
-}
-
-/* The main message handler. We don't do much here, except delegate
- to other message handlers
-
- Runs in the context of the Krb5 plugin
-*/
-khm_int32 KHMAPI
-k5_msg_callback(khm_int32 msg_type, khm_int32 msg_subtype,
- khm_ui_4 uparam, void * vparam)
-{
- switch(msg_type) {
- case KMSG_SYSTEM:
- return k5_msg_system(msg_type, msg_subtype, uparam, vparam);
- case KMSG_CRED:
- return k5_msg_cred(msg_type, msg_subtype, uparam, vparam);
- case KMSG_KCDB:
- return k5_msg_kcdb(msg_type, msg_subtype, uparam, vparam);
- }
- return KHM_ERROR_SUCCESS;
-}
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<kherror.h>
+#include<khmsgtypes.h>
+#include<commctrl.h>
+#include<strsafe.h>
+#include<krb5.h>
+
+#ifdef DEBUG
+#include<assert.h>
+#endif
+
+khm_int32 credtype_id_krb5 = KCDB_CREDTYPE_INVALID;
+khm_boolean krb5_initialized = FALSE;
+khm_handle krb5_credset = NULL;
+
+khm_handle k5_sub = NULL;
+
+LPVOID k5_main_fiber = NULL;
+LPVOID k5_kinit_fiber = NULL;
+
+VOID CALLBACK k5_kinit_fiber_proc(PVOID lpParameter);
+
+krb5_context k5_identpro_ctx = NULL;
+
+/* The system message handler.
+
+ Runs in the context of the plugin thread */
+khm_int32 KHMAPI
+k5_msg_system(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam)
+{
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+
+ switch(msg_subtype) {
+ case KMSG_SYSTEM_INIT:
+ {
+ kcdb_credtype ct;
+ wchar_t buf[KCDB_MAXCCH_SHORT_DESC];
+ size_t cbsize;
+
+ /* perform critical registrations and initialization
+ stuff */
+ ZeroMemory(&ct, sizeof(ct));
+ ct.id = KCDB_CREDTYPE_AUTO;
+ ct.name = KRB5_CREDTYPE_NAME;
+
+ if(LoadString(hResModule, IDS_KRB5_SHORT_DESC,
+ buf, ARRAYLENGTH(buf))) {
+ StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize);
+ cbsize += sizeof(wchar_t);
+ ct.short_desc = PMALLOC(cbsize);
+ StringCbCopy(ct.short_desc, cbsize, buf);
+ }
+
+ /* even though ideally we should be setting limits
+ based KCDB_MAXCB_LONG_DESC, our long description
+ actually fits nicely in KCDB_MAXCB_SHORT_DESC */
+ if(LoadString(hResModule, IDS_KRB5_LONG_DESC,
+ buf, ARRAYLENGTH(buf))) {
+ StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize);
+ cbsize += sizeof(wchar_t);
+ ct.long_desc = PMALLOC(cbsize);
+ StringCbCopy(ct.long_desc, cbsize, buf);
+ }
+
+ ct.icon = NULL; /* TODO: set a proper icon */
+
+ kmq_create_subscription(k5_msg_callback, &ct.sub);
+
+ ct.is_equal = khm_krb5_creds_is_equal;
+
+ rv = kcdb_credtype_register(&ct, &credtype_id_krb5);
+
+ if(KHM_SUCCEEDED(rv))
+ rv = kcdb_credset_create(&krb5_credset);
+
+ if(ct.short_desc)
+ PFREE(ct.short_desc);
+
+ if(ct.long_desc)
+ PFREE(ct.long_desc);
+
+ if(KHM_SUCCEEDED(rv)) {
+ krb5_context ctx = NULL;
+
+ krb5_initialized = TRUE;
+
+ /* now convert this thread to a fiber and create a
+ separate fiber to do kinit stuff */
+ k5_main_fiber = ConvertThreadToFiber(NULL);
+ k5_kinit_fiber = CreateFiber(0,k5_kinit_fiber_proc,NULL);
+
+ ZeroMemory(&g_fjob, sizeof(g_fjob));
+
+ kmq_create_subscription(k5_msg_callback, &k5_sub);
+
+ k5_register_config_panels();
+
+ khm_krb5_list_tickets(&ctx);
+
+ if(ctx != NULL)
+ pkrb5_free_context(ctx);
+ }
+ }
+ break;
+
+ case KMSG_SYSTEM_EXIT:
+
+ k5_unregister_config_panels();
+
+ if(credtype_id_krb5 >= 0) {
+ /* basically just unregister the credential type */
+ kcdb_credtype_unregister(credtype_id_krb5);
+
+ /* kcdb knows how to deal with bad handles */
+ kcdb_credset_delete(krb5_credset);
+ krb5_credset = NULL;
+ }
+
+ if(k5_main_fiber != NULL) {
+ if (k5_kinit_fiber) {
+#ifdef DEBUG
+ assert(k5_kinit_fiber != GetCurrentFiber());
+#endif
+#ifdef CLEANUP_FIBERS_ON_EXIT
+ DeleteFiber(k5_kinit_fiber);
+ CloseHandle(k5_kinit_fiber);
+#endif
+ k5_kinit_fiber = NULL;
+ }
+
+ k5_main_fiber = NULL;
+ }
+
+ if(k5_sub != NULL) {
+ kmq_delete_subscription(k5_sub);
+ k5_sub = NULL;
+ }
+
+ break;
+ }
+
+ return rv;
+}
+
+khm_int32 KHMAPI
+k5_msg_kcdb(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam)
+{
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+
+ switch(msg_subtype) {
+ case KMSG_KCDB_IDENT:
+ if (uparam == KCDB_OP_DELCONFIG) {
+ k5_remove_from_LRU((khm_handle) vparam);
+ }
+ break;
+ }
+
+ return rv;
+}
+
+
+/* Handler for CRED type messages
+
+ Runs in the context of the Krb5 plugin
+*/
+khm_int32 KHMAPI
+k5_msg_cred(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam)
+{
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+
+ switch(msg_subtype) {
+ case KMSG_CRED_REFRESH:
+ {
+ krb5_context ctx = NULL;
+
+ khm_krb5_list_tickets(&ctx);
+
+ if(ctx != NULL)
+ pkrb5_free_context(ctx);
+ }
+ break;
+
+ case KMSG_CRED_DESTROY_CREDS:
+ {
+ khui_action_context * ctx;
+
+ ctx = (khui_action_context *) vparam;
+
+ if (ctx->credset) {
+ _begin_task(0);
+ _report_mr0(KHERR_INFO, MSG_ERR_CTX_DESTROY_CREDS);
+ _describe();
+
+ khm_krb5_destroy_by_credset(ctx->credset);
+
+ _end_task();
+ }
+ }
+ break;
+
+ case KMSG_CRED_PP_BEGIN:
+ k5_pp_begin((khui_property_sheet *) vparam);
+ break;
+
+ case KMSG_CRED_PP_END:
+ k5_pp_end((khui_property_sheet *) vparam);
+ break;
+
+ default:
+ if(IS_CRED_ACQ_MSG(msg_subtype))
+ return k5_msg_cred_dialog(msg_type, msg_subtype,
+ uparam, vparam);
+ }
+
+ return rv;
+}
+
+/* The main message handler. We don't do much here, except delegate
+ to other message handlers
+
+ Runs in the context of the Krb5 plugin
+*/
+khm_int32 KHMAPI
+k5_msg_callback(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam)
+{
+ switch(msg_type) {
+ case KMSG_SYSTEM:
+ return k5_msg_system(msg_type, msg_subtype, uparam, vparam);
+ case KMSG_CRED:
+ return k5_msg_cred(msg_type, msg_subtype, uparam, vparam);
+ case KMSG_KCDB:
+ return k5_msg_kcdb(msg_type, msg_subtype, uparam, vparam);
+ }
+ return KHM_ERROR_SUCCESS;
+}
diff --git a/src/windows/identity/plugins/krb5/krb5props.c b/src/windows/identity/plugins/krb5/krb5props.c
index 0d8d27276..312b576fd 100644
--- a/src/windows/identity/plugins/krb5/krb5props.c
+++ b/src/windows/identity/plugins/krb5/krb5props.c
@@ -1,176 +1,176 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<krbcred.h>
-#include<kherror.h>
-#include<khmsgtypes.h>
-#include<commctrl.h>
-#include<strsafe.h>
-#include<krb5.h>
-#ifdef DEBUG
-#include<assert.h>
-#endif
-
-/* Property page
-
- Runs in the context of the UI thread.
- */
-INT_PTR CALLBACK krb5_pp_proc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam
- )
-{
- switch(uMsg) {
- case WM_INITDIALOG:
- {
- khui_property_sheet * s;
- PROPSHEETPAGE * p;
- wchar_t buf[512];
- wchar_t unavailable[64];
- khm_size cbsize;
- khm_int32 rv;
- khm_int32 tflags;
-
- p = (PROPSHEETPAGE *) lParam;
- s = (khui_property_sheet *) p->lParam;
-
-#pragma warning(push)
-#pragma warning(disable: 4244)
- SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) s);
-#pragma warning(pop)
-
- LoadString(hResModule, IDS_UNAVAILABLE,
- unavailable, ARRAYLENGTH(unavailable));
-
- if(s->cred) {
- cbsize = sizeof(buf);
- kcdb_cred_get_name(s->cred, buf, &cbsize);
- SetDlgItemText(hwnd, IDC_PPK5_NAME, buf);
-
- cbsize = sizeof(buf);
- rv = kcdb_cred_get_attr_string(s->cred,
- KCDB_ATTR_ISSUE,
- buf, &cbsize, 0);
- if (KHM_SUCCEEDED(rv))
- SetDlgItemText(hwnd, IDC_PPK5_ISSUE, buf);
- else
- SetDlgItemText(hwnd, IDC_PPK5_ISSUE, unavailable);
-
- cbsize = sizeof(buf);
- rv = kcdb_cred_get_attr_string(s->cred,
- KCDB_ATTR_EXPIRE,
- buf, &cbsize, 0);
- if (KHM_SUCCEEDED(rv))
- SetDlgItemText(hwnd, IDC_PPK5_VALID, buf);
- else
- SetDlgItemText(hwnd, IDC_PPK5_VALID, unavailable);
-
- cbsize = sizeof(buf);
- rv = kcdb_cred_get_attr_string(s->cred,
- KCDB_ATTR_RENEW_EXPIRE,
- buf, &cbsize, 0);
- if (KHM_SUCCEEDED(rv))
- SetDlgItemText(hwnd, IDC_PPK5_RENEW, buf);
- else
- SetDlgItemText(hwnd, IDC_PPK5_RENEW, unavailable);
-
- tflags = 0;
- cbsize = sizeof(tflags);
- rv = kcdb_cred_get_attr(s->cred,
- attr_id_krb5_flags,
- NULL,
- &tflags,
- &cbsize);
- if (KHM_SUCCEEDED(rv)) {
-
-#define ADDBITFLAG(f,s) \
- if (tflags & f) { \
- LoadString(hResModule, s, buf, ARRAYLENGTH(buf)); \
- SendDlgItemMessage(hwnd, IDC_PPK5_FLAGS, LB_ADDSTRING, 0, (LPARAM) buf); \
- }
-
- ADDBITFLAG(TKT_FLG_FORWARDABLE, IDS_FLG_FORWARDABLE);
- ADDBITFLAG(TKT_FLG_FORWARDED, IDS_FLG_FORWARDED);
- ADDBITFLAG(TKT_FLG_PROXIABLE, IDS_FLG_PROXIABLE);
- ADDBITFLAG(TKT_FLG_PROXY, IDS_FLG_PROXY);
- ADDBITFLAG(TKT_FLG_MAY_POSTDATE, IDS_FLG_MAY_POSTDATE);
- ADDBITFLAG(TKT_FLG_POSTDATED, IDS_FLG_POSTDATED);
- ADDBITFLAG(TKT_FLG_INVALID, IDS_FLG_INVALID);
- ADDBITFLAG(TKT_FLG_RENEWABLE, IDS_FLG_RENEWABLE);
- ADDBITFLAG(TKT_FLG_INITIAL, IDS_FLG_INITIAL);
- ADDBITFLAG(TKT_FLG_PRE_AUTH, IDS_FLG_PRE_AUTH);
- ADDBITFLAG(TKT_FLG_HW_AUTH, IDS_FLG_HW_AUTH);
- ADDBITFLAG(TKT_FLG_TRANSIT_POLICY_CHECKED, IDS_FLG_TRANSIT_POL);
- ADDBITFLAG(TKT_FLG_OK_AS_DELEGATE, IDS_FLG_OK_DELEGATE);
- ADDBITFLAG(TKT_FLG_ANONYMOUS, IDS_FLG_ANONYMOUS);
-
-#undef ADDBITFLAG
-
- }
- } else {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- }
- }
- return FALSE;
- }
-
- return FALSE;
-}
-
-void k5_pp_begin(khui_property_sheet * s)
-{
- PROPSHEETPAGE *p;
-
- if(s->credtype == credtype_id_krb5 &&
- s->cred) {
- p = PMALLOC(sizeof(*p));
- ZeroMemory(p, sizeof(*p));
-
- p->dwSize = sizeof(*p);
- p->dwFlags = 0;
- p->hInstance = hResModule;
- p->pszTemplate = MAKEINTRESOURCE(IDD_PP_KRB5C);
- p->pfnDlgProc = krb5_pp_proc;
- p->lParam = (LPARAM) s;
- khui_ps_add_page(s, credtype_id_krb5, 0, p, NULL);
- }
-}
-
-void k5_pp_end(khui_property_sheet * s)
-{
- khui_property_page * p = NULL;
-
- khui_ps_find_page(s, credtype_id_krb5, &p);
- if(p) {
- if(p->p_page)
- PFREE(p->p_page);
- p->p_page = NULL;
- }
-}
-
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<krbcred.h>
+#include<kherror.h>
+#include<khmsgtypes.h>
+#include<commctrl.h>
+#include<strsafe.h>
+#include<krb5.h>
+#ifdef DEBUG
+#include<assert.h>
+#endif
+
+/* Property page
+
+ Runs in the context of the UI thread.
+ */
+INT_PTR CALLBACK krb5_pp_proc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam
+ )
+{
+ switch(uMsg) {
+ case WM_INITDIALOG:
+ {
+ khui_property_sheet * s;
+ PROPSHEETPAGE * p;
+ wchar_t buf[512];
+ wchar_t unavailable[64];
+ khm_size cbsize;
+ khm_int32 rv;
+ khm_int32 tflags;
+
+ p = (PROPSHEETPAGE *) lParam;
+ s = (khui_property_sheet *) p->lParam;
+
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) s);
+#pragma warning(pop)
+
+ LoadString(hResModule, IDS_UNAVAILABLE,
+ unavailable, ARRAYLENGTH(unavailable));
+
+ if(s->cred) {
+ cbsize = sizeof(buf);
+ kcdb_cred_get_name(s->cred, buf, &cbsize);
+ SetDlgItemText(hwnd, IDC_PPK5_NAME, buf);
+
+ cbsize = sizeof(buf);
+ rv = kcdb_cred_get_attr_string(s->cred,
+ KCDB_ATTR_ISSUE,
+ buf, &cbsize, 0);
+ if (KHM_SUCCEEDED(rv))
+ SetDlgItemText(hwnd, IDC_PPK5_ISSUE, buf);
+ else
+ SetDlgItemText(hwnd, IDC_PPK5_ISSUE, unavailable);
+
+ cbsize = sizeof(buf);
+ rv = kcdb_cred_get_attr_string(s->cred,
+ KCDB_ATTR_EXPIRE,
+ buf, &cbsize, 0);
+ if (KHM_SUCCEEDED(rv))
+ SetDlgItemText(hwnd, IDC_PPK5_VALID, buf);
+ else
+ SetDlgItemText(hwnd, IDC_PPK5_VALID, unavailable);
+
+ cbsize = sizeof(buf);
+ rv = kcdb_cred_get_attr_string(s->cred,
+ KCDB_ATTR_RENEW_EXPIRE,
+ buf, &cbsize, 0);
+ if (KHM_SUCCEEDED(rv))
+ SetDlgItemText(hwnd, IDC_PPK5_RENEW, buf);
+ else
+ SetDlgItemText(hwnd, IDC_PPK5_RENEW, unavailable);
+
+ tflags = 0;
+ cbsize = sizeof(tflags);
+ rv = kcdb_cred_get_attr(s->cred,
+ attr_id_krb5_flags,
+ NULL,
+ &tflags,
+ &cbsize);
+ if (KHM_SUCCEEDED(rv)) {
+
+#define ADDBITFLAG(f,s) \
+ if (tflags & f) { \
+ LoadString(hResModule, s, buf, ARRAYLENGTH(buf)); \
+ SendDlgItemMessage(hwnd, IDC_PPK5_FLAGS, LB_ADDSTRING, 0, (LPARAM) buf); \
+ }
+
+ ADDBITFLAG(TKT_FLG_FORWARDABLE, IDS_FLG_FORWARDABLE);
+ ADDBITFLAG(TKT_FLG_FORWARDED, IDS_FLG_FORWARDED);
+ ADDBITFLAG(TKT_FLG_PROXIABLE, IDS_FLG_PROXIABLE);
+ ADDBITFLAG(TKT_FLG_PROXY, IDS_FLG_PROXY);
+ ADDBITFLAG(TKT_FLG_MAY_POSTDATE, IDS_FLG_MAY_POSTDATE);
+ ADDBITFLAG(TKT_FLG_POSTDATED, IDS_FLG_POSTDATED);
+ ADDBITFLAG(TKT_FLG_INVALID, IDS_FLG_INVALID);
+ ADDBITFLAG(TKT_FLG_RENEWABLE, IDS_FLG_RENEWABLE);
+ ADDBITFLAG(TKT_FLG_INITIAL, IDS_FLG_INITIAL);
+ ADDBITFLAG(TKT_FLG_PRE_AUTH, IDS_FLG_PRE_AUTH);
+ ADDBITFLAG(TKT_FLG_HW_AUTH, IDS_FLG_HW_AUTH);
+ ADDBITFLAG(TKT_FLG_TRANSIT_POLICY_CHECKED, IDS_FLG_TRANSIT_POL);
+ ADDBITFLAG(TKT_FLG_OK_AS_DELEGATE, IDS_FLG_OK_DELEGATE);
+ ADDBITFLAG(TKT_FLG_ANONYMOUS, IDS_FLG_ANONYMOUS);
+
+#undef ADDBITFLAG
+
+ }
+ } else {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ }
+ }
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+void k5_pp_begin(khui_property_sheet * s)
+{
+ PROPSHEETPAGE *p;
+
+ if(s->credtype == credtype_id_krb5 &&
+ s->cred) {
+ p = PMALLOC(sizeof(*p));
+ ZeroMemory(p, sizeof(*p));
+
+ p->dwSize = sizeof(*p);
+ p->dwFlags = 0;
+ p->hInstance = hResModule;
+ p->pszTemplate = MAKEINTRESOURCE(IDD_PP_KRB5C);
+ p->pfnDlgProc = krb5_pp_proc;
+ p->lParam = (LPARAM) s;
+ khui_ps_add_page(s, credtype_id_krb5, 0, p, NULL);
+ }
+}
+
+void k5_pp_end(khui_property_sheet * s)
+{
+ khui_property_page * p = NULL;
+
+ khui_ps_find_page(s, credtype_id_krb5, &p);
+ if(p) {
+ if(p->p_page)
+ PFREE(p->p_page);
+ p->p_page = NULL;
+ }
+}
+
diff --git a/src/windows/identity/plugins/krb5/krbcred.h b/src/windows/identity/plugins/krb5/krbcred.h
index d552fd0c8..0048f7185 100644
--- a/src/windows/identity/plugins/krb5/krbcred.h
+++ b/src/windows/identity/plugins/krb5/krbcred.h
@@ -1,244 +1,244 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef __KHIMAIRA_KRBAFSCRED_H
-#define __KHIMAIRA_KRBAFSCRED_H
-
-#include<windows.h>
-
-/* While we generally pull resources out of hResModule, the message
- strings for all the languages are kept in the main DLL. */
-#define KHERR_HMODULE hInstance
-#define KHERR_FACILITY k5_facility
-#define KHERR_FACILITY_ID 64
-
-#include<netidmgr.h>
-
-#include<krb5funcs.h>
-#include<krb5common.h>
-#include<errorfuncs.h>
-#include<dynimport.h>
-
-#include<langres.h>
-#include<datarep.h>
-#include<krb5_msgs.h>
-
-typedef enum tag_k5_lsa_import {
- K5_LSAIMPORT_NEVER = 0,
- K5_LSAIMPORT_ALWAYS = 1,
- K5_LSAIMPORT_MATCH = 2, /* only when the principal name matches */
-} k5_lsa_import;
-
-#define TYPENAME_ENCTYPE L"EncType"
-#define TYPENAME_ADDR_LIST L"AddrList"
-#define TYPENAME_KRB5_FLAGS L"Krb5Flags"
-#define TYPENAME_KRB5_PRINC L"Krb5Principal"
-#define TYPENAME_KVNO L"Kvno"
-
-#define ATTRNAME_KEY_ENCTYPE L"KeyEncType"
-#define ATTRNAME_TKT_ENCTYPE L"TktEncType"
-#define ATTRNAME_ADDR_LIST L"AddrList"
-#define ATTRNAME_KRB5_FLAGS L"Krb5Flags"
-#define ATTRNAME_KRB5_CCNAME L"Krb5CCName"
-#define ATTRNAME_KVNO L"Kvno"
-#define ATTRNAME_KRB5_IDFLAGS L"Krb5IDFlags"
-
-/* Flag bits for Krb5IDFlags property */
-
-/* identity was imported from MSLSA: */
-#define K5IDFLAG_IMPORTED 0x00000001
-
-void init_krb();
-void exit_krb();
-KHMEXP khm_int32 KHMAPI init_module(kmm_module h_module);
-KHMEXP khm_int32 KHMAPI exit_module(kmm_module h_module);
-
-/* globals */
-extern kmm_module h_khModule;
-extern HMODULE hResModule;
-extern HINSTANCE hInstance;
-extern const wchar_t * k5_facility;
-
-extern khm_int32 type_id_enctype;
-extern khm_int32 type_id_addr_list;
-extern khm_int32 type_id_krb5_flags;
-extern khm_int32 type_id_krb5_princ;
-extern khm_int32 type_id_kvno;
-
-extern BOOL type_regd_krb5_princ;
-
-extern khm_int32 attr_id_key_enctype;
-extern khm_int32 attr_id_tkt_enctype;
-extern khm_int32 attr_id_addr_list;
-extern khm_int32 attr_id_krb5_flags;
-extern khm_int32 attr_id_krb5_ccname;
-extern khm_int32 attr_id_kvno;
-extern khm_int32 attr_id_krb5_idflags;
-
-extern khm_ui_4 k5_commctl_version;
-
-#define IS_COMMCTL6() (k5_commctl_version >= 0x60000)
-
-/* Configuration spaces */
-#define CSNAME_KRB5CRED L"Krb5Cred"
-#define CSNAME_PARAMS L"Parameters"
-#define CSNAME_PROMPTCACHE L"PromptCache"
-#define CSNAME_REALMS L"Realms"
-
-/* plugin constants */
-#define KRB5_PLUGIN_NAME L"Krb5Cred"
-#define KRB5_IDENTPRO_NAME L"Krb5Ident"
-
-#define KRB5_CREDTYPE_NAME L"Krb5Cred"
-
-/* limits */
-/* maximum number of characters in a realm name */
-#define K5_MAXCCH_REALM 256
-
-/* maximum number of characters in a host name */
-#define K5_MAXCCH_HOST 128
-
-/* maximum number of KDC's per realm */
-#define K5_MAX_KDC 64
-
-/* maximum number of domains that map to a realm */
-#define K5_MAX_DOMAIN_MAPPINGS 32
-
-extern khm_handle csp_plugins;
-extern khm_handle csp_krbcred;
-extern khm_handle csp_params;
-
-extern kconf_schema schema_krbconfig[];
-
-/* other globals */
-extern khm_int32 credtype_id_krb5;
-
-extern khm_boolean krb5_initialized;
-
-extern khm_handle krb5_credset;
-
-extern khm_handle k5_sub;
-
-extern krb5_context k5_identpro_ctx;
-
-extern BOOL is_k5_identpro;
-
-/* plugin callbacks */
-khm_int32 KHMAPI k5_msg_callback(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam);
-khm_int32 KHMAPI k5_ident_callback(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam);
-
-/* kinit fiber */
-typedef struct _fiber_job_t {
- int command;
-
- khui_new_creds * nc;
- khui_new_creds_by_type * nct;
- HWND dialog;
-
- khm_handle identity;
- char * principal;
- char * password;
- char * ccache;
- krb5_deltat lifetime;
- DWORD forwardable;
- DWORD proxiable;
- DWORD renewable;
- krb5_deltat renew_life;
- DWORD addressless;
- DWORD publicIP;
-
- int code;
- int state;
- int prompt_set;
-
- BOOL null_password;
- BOOL valid_principal;
- BOOL retry_if_valid_principal;
-} fiber_job;
-
-extern fiber_job g_fjob; /* global fiber job object */
-
-#define FIBER_CMD_KINIT 1
-#define FIBER_CMD_CANCEL 2
-#define FIBER_CMD_CONTINUE 3
-
-#define FIBER_STATE_NONE 0
-#define FIBER_STATE_KINIT 1
-#define FIBER_STATE_RETRY_KINIT 2
-
-#define K5_SET_CRED_MSG WMNC_USER
-
-void
-k5_pp_begin(khui_property_sheet * s);
-
-void
-k5_pp_end(khui_property_sheet * s);
-
-khm_int32 KHMAPI
-k5_msg_cred_dialog(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam);
-
-khm_int32 KHMAPI
-k5_msg_ident(khm_int32 msg_type,
- khm_int32 msg_subtype,
- khm_ui_4 uparam,
- void * vparam);
-
-khm_int32
-k5_remove_from_LRU(khm_handle identity);
-
-int
-k5_get_realm_from_nc(khui_new_creds * nc,
- wchar_t * buf,
- khm_size cch_buf);
-
-void
-k5_register_config_panels(void);
-
-void
-k5_unregister_config_panels(void);
-
-INT_PTR CALLBACK
-k5_ccconfig_dlgproc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam);
-
-INT_PTR CALLBACK
-k5_id_tab_dlgproc(HWND hwndDlg,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam);
-
-INT_PTR CALLBACK
-k5_ids_tab_dlgproc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam);
-
-#endif
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef __KHIMAIRA_KRBAFSCRED_H
+#define __KHIMAIRA_KRBAFSCRED_H
+
+#include<windows.h>
+
+/* While we generally pull resources out of hResModule, the message
+ strings for all the languages are kept in the main DLL. */
+#define KHERR_HMODULE hInstance
+#define KHERR_FACILITY k5_facility
+#define KHERR_FACILITY_ID 64
+
+#include<netidmgr.h>
+
+#include<krb5funcs.h>
+#include<krb5common.h>
+#include<errorfuncs.h>
+#include<dynimport.h>
+
+#include<langres.h>
+#include<datarep.h>
+#include<krb5_msgs.h>
+
+typedef enum tag_k5_lsa_import {
+ K5_LSAIMPORT_NEVER = 0,
+ K5_LSAIMPORT_ALWAYS = 1,
+ K5_LSAIMPORT_MATCH = 2, /* only when the principal name matches */
+} k5_lsa_import;
+
+#define TYPENAME_ENCTYPE L"EncType"
+#define TYPENAME_ADDR_LIST L"AddrList"
+#define TYPENAME_KRB5_FLAGS L"Krb5Flags"
+#define TYPENAME_KRB5_PRINC L"Krb5Principal"
+#define TYPENAME_KVNO L"Kvno"
+
+#define ATTRNAME_KEY_ENCTYPE L"KeyEncType"
+#define ATTRNAME_TKT_ENCTYPE L"TktEncType"
+#define ATTRNAME_ADDR_LIST L"AddrList"
+#define ATTRNAME_KRB5_FLAGS L"Krb5Flags"
+#define ATTRNAME_KRB5_CCNAME L"Krb5CCName"
+#define ATTRNAME_KVNO L"Kvno"
+#define ATTRNAME_KRB5_IDFLAGS L"Krb5IDFlags"
+
+/* Flag bits for Krb5IDFlags property */
+
+/* identity was imported from MSLSA: */
+#define K5IDFLAG_IMPORTED 0x00000001
+
+void init_krb();
+void exit_krb();
+KHMEXP khm_int32 KHMAPI init_module(kmm_module h_module);
+KHMEXP khm_int32 KHMAPI exit_module(kmm_module h_module);
+
+/* globals */
+extern kmm_module h_khModule;
+extern HMODULE hResModule;
+extern HINSTANCE hInstance;
+extern const wchar_t * k5_facility;
+
+extern khm_int32 type_id_enctype;
+extern khm_int32 type_id_addr_list;
+extern khm_int32 type_id_krb5_flags;
+extern khm_int32 type_id_krb5_princ;
+extern khm_int32 type_id_kvno;
+
+extern BOOL type_regd_krb5_princ;
+
+extern khm_int32 attr_id_key_enctype;
+extern khm_int32 attr_id_tkt_enctype;
+extern khm_int32 attr_id_addr_list;
+extern khm_int32 attr_id_krb5_flags;
+extern khm_int32 attr_id_krb5_ccname;
+extern khm_int32 attr_id_kvno;
+extern khm_int32 attr_id_krb5_idflags;
+
+extern khm_ui_4 k5_commctl_version;
+
+#define IS_COMMCTL6() (k5_commctl_version >= 0x60000)
+
+/* Configuration spaces */
+#define CSNAME_KRB5CRED L"Krb5Cred"
+#define CSNAME_PARAMS L"Parameters"
+#define CSNAME_PROMPTCACHE L"PromptCache"
+#define CSNAME_REALMS L"Realms"
+
+/* plugin constants */
+#define KRB5_PLUGIN_NAME L"Krb5Cred"
+#define KRB5_IDENTPRO_NAME L"Krb5Ident"
+
+#define KRB5_CREDTYPE_NAME L"Krb5Cred"
+
+/* limits */
+/* maximum number of characters in a realm name */
+#define K5_MAXCCH_REALM 256
+
+/* maximum number of characters in a host name */
+#define K5_MAXCCH_HOST 128
+
+/* maximum number of KDC's per realm */
+#define K5_MAX_KDC 64
+
+/* maximum number of domains that map to a realm */
+#define K5_MAX_DOMAIN_MAPPINGS 32
+
+extern khm_handle csp_plugins;
+extern khm_handle csp_krbcred;
+extern khm_handle csp_params;
+
+extern kconf_schema schema_krbconfig[];
+
+/* other globals */
+extern khm_int32 credtype_id_krb5;
+
+extern khm_boolean krb5_initialized;
+
+extern khm_handle krb5_credset;
+
+extern khm_handle k5_sub;
+
+extern krb5_context k5_identpro_ctx;
+
+extern BOOL is_k5_identpro;
+
+/* plugin callbacks */
+khm_int32 KHMAPI k5_msg_callback(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam);
+khm_int32 KHMAPI k5_ident_callback(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam);
+
+/* kinit fiber */
+typedef struct _fiber_job_t {
+ int command;
+
+ khui_new_creds * nc;
+ khui_new_creds_by_type * nct;
+ HWND dialog;
+
+ khm_handle identity;
+ char * principal;
+ char * password;
+ char * ccache;
+ krb5_deltat lifetime;
+ DWORD forwardable;
+ DWORD proxiable;
+ DWORD renewable;
+ krb5_deltat renew_life;
+ DWORD addressless;
+ DWORD publicIP;
+
+ int code;
+ int state;
+ int prompt_set;
+
+ BOOL null_password;
+ BOOL valid_principal;
+ BOOL retry_if_valid_principal;
+} fiber_job;
+
+extern fiber_job g_fjob; /* global fiber job object */
+
+#define FIBER_CMD_KINIT 1
+#define FIBER_CMD_CANCEL 2
+#define FIBER_CMD_CONTINUE 3
+
+#define FIBER_STATE_NONE 0
+#define FIBER_STATE_KINIT 1
+#define FIBER_STATE_RETRY_KINIT 2
+
+#define K5_SET_CRED_MSG WMNC_USER
+
+void
+k5_pp_begin(khui_property_sheet * s);
+
+void
+k5_pp_end(khui_property_sheet * s);
+
+khm_int32 KHMAPI
+k5_msg_cred_dialog(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam);
+
+khm_int32 KHMAPI
+k5_msg_ident(khm_int32 msg_type,
+ khm_int32 msg_subtype,
+ khm_ui_4 uparam,
+ void * vparam);
+
+khm_int32
+k5_remove_from_LRU(khm_handle identity);
+
+int
+k5_get_realm_from_nc(khui_new_creds * nc,
+ wchar_t * buf,
+ khm_size cch_buf);
+
+void
+k5_register_config_panels(void);
+
+void
+k5_unregister_config_panels(void);
+
+INT_PTR CALLBACK
+k5_ccconfig_dlgproc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam);
+
+INT_PTR CALLBACK
+k5_id_tab_dlgproc(HWND hwndDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam);
+
+INT_PTR CALLBACK
+k5_ids_tab_dlgproc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam);
+
+#endif
diff --git a/src/windows/identity/plugins/krb5/langres.h b/src/windows/identity/plugins/krb5/langres.h
index 0e62ecda1..117754b3e 100644
--- a/src/windows/identity/plugins/krb5/langres.h
+++ b/src/windows/identity/plugins/krb5/langres.h
@@ -1,216 +1,216 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by C:\work\pismere\athena\auth\krb5\src\windows\identity\plugins\krb5\lang\en_us\langres.rc
-//
-#define IDS_UNK_ADDR_FMT 101
-#define IDD_NC_KRB5 102
-#define IDS_KRB5_CREDTEXT_0 102
-#define IDS_KRB5_CCNAME_SHORT_DESC 103
-#define IDS_KEY_ENCTYPE_SHORT_DESC 104
-#define IDD_CONFIG 104
-#define IDS_TKT_ENCTYPE_SHORT_DESC 105
-#define IDD_CFG_REALMS 105
-#define IDS_KEY_ENCTYPE_LONG_DESC 106
-#define IDD_CFG_IDS_TAB 106
-#define IDS_TKT_ENCTYPE_LONG_DESC 107
-#define IDD_PP_KRB5C 107
-#define IDS_ADDR_LIST_SHORT_DESC 108
-#define IDD_PP_KRB5 108
-#define IDS_ADDR_LIST_LONG_DESC 109
-#define IDD_CFG_ID_TAB 109
-#define IDS_ETYPE_NULL 110
-#define IDD_NC_KRB5_PASSWORD 110
-#define IDS_ETYPE_DES_CBC_CRC 111
-#define IDD_CFG_CACHES 111
-#define IDS_ETYPE_DES_CBC_MD4 112
-#define IDI_PLUGIN 112
-#define IDS_ETYPE_DES_CBC_MD5 113
-#define IDI_DELETED 113
-#define IDS_ETYPE_DES_CBC_RAW 114
-#define IDI_NEW 114
-#define IDS_ETYPE_DES3_CBC_SHA 115
-#define IDI_NORMAL 115
-#define IDS_ETYPE_DES3_CBC_RAW 116
-#define IDI_MODIFIED 116
-#define IDS_ETYPE_DES_HMAC_SHA1 117
-#define IDS_ETYPE_DES3_CBC_SHA1 118
-#define IDS_ETYPE_AES128_CTS_HMAC_SHA1_96 119
-#define IDS_ETYPE_AES256_CTS_HMAC_SHA1_96 120
-#define IDS_ETYPE_ARCFOUR_HMAC 121
-#define IDS_ETYPE_ARCFOUR_HMAC_EXP 122
-#define IDS_ETYPE_UNKNOWN 123
-#define IDS_ETYPE_LOCAL_DES3_HMAC_SHA1 124
-#define IDS_ETYPE_LOCAL_RC4_MD4 125
-#define IDS_KRB5_SHORT_DESC 126
-#define IDS_KRB5_LONG_DESC 127
-#define IDS_KRB4_SHORT_DESC 128
-#define IDS_KRB4_LONG_DESC 129
-#define IDS_KRB5_FLAGS_SHORT_DESC 130
-#define IDS_RENEW_TILL_SHORT_DESC 131
-#define IDS_RENEW_TILL_LONG_DESC 132
-#define IDS_RENEW_FOR_SHORT_DESC 133
-#define IDS_RENEW_FOR_LONG_DESC 134
-#define IDS_KRB5_CCNAME_LONG_DESC 135
-#define IDS_NC_USERNAME 136
-#define IDS_NC_REALM 137
-#define IDS_KRB5_WARNING 138
-#define IDS_K5ERR_NAME_EXPIRED 139
-#define IDS_K5ERR_KEY_EXPIRED 140
-#define IDS_KRB5_WARN_FMT 141
-#define IDS_K5ERR_FMT 142
-#define IDS_K5CFG_SHORT_DESC 143
-#define IDS_K5CFG_LONG_DESC 144
-#define IDS_K5RLM_SHORT_DESC 145
-#define IDS_K5RLM_LONG_DESC 146
-#define IDS_K5CFG_IDS_SHORT_DESC 147
-#define IDS_K5CFG_IDS_LONG_DESC 148
-#define IDS_K5CFG_ID_SHORT_DESC 149
-#define IDS_K5CFG_ID_LONG_DESC 150
-#define IDS_PLUGIN_DESC 151
-#define IDS_NC_PWD_BANNER 152
-#define IDS_NC_PWD_PWD 153
-#define IDS_NC_PWD_NPWD 154
-#define IDS_NC_PWD_NPWD_AGAIN 155
-#define IDS_KRB5_CREDTEXT_P0 156
-#define IDS_K5CFG_IMPORT_OPTIONS 157
-#define IDS_IDENTPRO_DESC 158
-#define IDS_K5CCC_SHORT_DESC 159
-#define IDS_K5CCC_LONG_DESC 160
-#define IDS_CFG_FCTITLE 161
-#define IDS_CFG_FCN_WARNING 162
-#define IDS_CFG_FCN_W_NOTFOUND 163
-#define IDS_CFG_FCN_W_RELATIVE 164
-#define IDS_CFG_FCOPENTITLE 165
-#define IDS_UNAVAILABLE 166
-#define IDS_FLG_FORWARDABLE 167
-#define IDS_FLG_FORWARDED 168
-#define IDS_FLG_PROXIABLE 169
-#define IDS_FLG_PROXY 170
-#define IDS_FLG_MAY_POSTDATE 171
-#define IDS_FLG_POSTDATED 172
-#define IDS_FLG_INVALID 173
-#define IDS_FLG_RENEWABLE 174
-#define IDS_FLG_INITIAL 175
-#define IDS_FLG_PRE_AUTH 176
-#define IDS_FLG_HW_AUTH 177
-#define IDS_FLG_TRANSIT_POL 178
-#define IDS_FLG_OK_DELEGATE 179
-#define IDS_FLG_ANONYMOUS 180
-#define IDS_K5ERR_CANTWRITEPROFILE 181
-#define IDS_K5ERR_PROFNOWRITE 182
-#define IDS_K5ERR_PROFUSETEMP 183
-#define IDS_K5ERR_PROFSUGGEST 184
-#define IDS_CFG_RE_REALMS 185
-#define IDS_CFG_RE_KDCS 186
-#define IDS_CFG_RE_DMAPS 187
-#define IDS_CFG_RE_KDCS_R 188
-#define IDS_CFG_RE_DMAPS_R 189
-#define IDS_CFG_RE_HEAD_SVR 190
-#define IDS_CFG_RE_HEAD_ADMIN 191
-#define IDS_CFG_RE_HEAD_MASTER 192
-#define IDS_CFG_RE_HEAD_DOMAIN 193
-#define IDS_CFG_RE_NEWREALM 194
-#define IDS_YES 195
-#define IDS_NO 196
-#define IDS_CFG_RE_NEWSERVER 197
-#define IDS_CFG_RE_NEWDMAP 198
-#define IDS_KRB5_NC_NAME 199
-#define IDS_NCERR_IDENT_TOO_LONG 200
-#define IDS_NCERR_IDENT_INVALID 201
-#define IDS_NCERR_IDENT_UNKNOWN 202
-#define IDS_CFG_RE_ARNUT 203
-#define IDS_CFG_RE_ARNUM 204
-#define IDS_CFG_RE_ASNUT 205
-#define IDS_CFG_RE_ASNUM 206
-#define IDS_CFG_RE_DMNUT 207
-#define IDS_CFG_RE_DMNUM 208
-#define IDS_CFG_RE_MNR 209
-#define IDS_CFG_RE_MDR 210
-#define IDS_CFG_RE_MNK 211
-#define IDS_CFG_RE_MDK 212
-#define IDS_CFG_RE_MAK 213
-#define IDS_CFG_RE_MMK 214
-#define IDS_CFG_RE_MND 215
-#define IDS_CFG_RE_MDD 216
-#define IDS_KVNO_SHORT_DESC 217
-#define IDS_KVNO_LONG_DESC 218
-#define IDC_NCK5_RENEWABLE 1002
-#define IDC_NCK5_FORWARDABLE 1004
-#define IDC_NCK5_REALM 1005
-#define IDC_NCK5_ADD_REALMS 1006
-#define IDC_NCK5_LIFETIME_EDIT 1008
-#define IDC_NCK5_RENEW_EDIT 1009
-#define IDC_PPK5_CRENEW 1014
-#define IDC_PPK5_CFORWARD 1015
-#define IDC_PPK5_CPROXY 1016
-#define IDC_PPK5_NAME 1017
-#define IDC_PPK5_ISSUE 1018
-#define IDC_PPK5_VALID 1019
-#define IDC_PPK5_RENEW 1020
-#define IDC_CHECK2 1022
-#define IDC_CHECK4 1024
-#define IDC_PPK5_LIFETIME 1024
-#define IDC_CHECK5 1025
-#define IDC_CFG_LBL_REALM 1025
-#define IDC_CFG_DEFREALM 1026
-#define IDC_CFG_LBL_CFGFILE 1029
-#define IDC_CFG_CFGFILE 1030
-#define IDC_CFG_WINGRP 1031
-#define IDC_LBL_IMPORT 1032
-#define IDC_CFG_IMPORT 1033
-#define IDC_CFG_LBL_HOSTNAME 1034
-#define IDC_CFG_HOSTNAME 1035
-#define IDC_CFG_LBL_DOMAIN 1036
-#define IDC_CFG_DOMAIN 1037
-#define IDC_CFG_CREATECONFIG 1038
-#define IDC_CFG_BROWSE 1039
-#define IDC_CFG_CFGFILEGRP 1040
-#define IDC_CFG_CFGREALMS 1041
-#define IDC_CFG_BROWSE2 1042
-#define IDC_CFG_REALMS 1044
-#define IDC_CFG_DOMAINGRP 1045
-#define IDC_CFG_SERVERSGRP 1046
-#define IDC_LIST3 1047
-#define IDC_CFG_KDC 1047
-#define IDC_LIST4 1048
-#define IDC_CFG_DMAP 1048
-#define IDC_CFG_LBL_DEFLIFE 1049
-#define IDC_CFG_DEFLIFE 1050
-#define IDC_CFG_LBL_DEFRLIFE 1051
-#define IDC_CFG_DEFRLIFE 1052
-#define IDC_CFG_LIFEGRP 1053
-#define IDC_CFG_LRNG_MIN 1054
-#define IDC_CFG_LRNG_MAX 1055
-#define IDC_CFG_RLRNG_MIN 1056
-#define IDC_CFG_RLRNG_MAX 1057
-#define IDC_CFG_CCACHE 1058
-#define IDC_CFG_FCGRP 1059
-#define IDC_CFG_FCLIST 1060
-#define IDC_CFG_FCNAME 1062
-#define IDC_CFG_ADD 1064
-#define IDC_CFG_REMOVE 1065
-#define IDC_CFG_INCAPI 1066
-#define IDC_CFG_INCMSLSA 1067
-#define IDC_PPK5_FLAGS 1072
-#define IDC_CFG_INCREALMS 1073
-#define IDC_NCK5_ADDRESS 1074
-#define IDC_IPADDRESS1 1075
-#define IDC_NCK5_PUBLICIP 1075
-#define IDC_CFG_PUBLICIP 1075
-#define IDC_CFG_RENEW 1076
-#define IDC_CHECK3 1077
-#define IDC_CFG_ADDRESSLESS 1077
-#define IDC_CFG_FORWARD 1078
-#define IDC_CHECK1 1079
-#define ID_FOO_BAR 40001
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 219
-#define _APS_NEXT_COMMAND_VALUE 40002
-#define _APS_NEXT_CONTROL_VALUE 1080
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by C:\work\pismere\athena\auth\krb5\src\windows\identity\plugins\krb5\lang\en_us\langres.rc
+//
+#define IDS_UNK_ADDR_FMT 101
+#define IDD_NC_KRB5 102
+#define IDS_KRB5_CREDTEXT_0 102
+#define IDS_KRB5_CCNAME_SHORT_DESC 103
+#define IDS_KEY_ENCTYPE_SHORT_DESC 104
+#define IDD_CONFIG 104
+#define IDS_TKT_ENCTYPE_SHORT_DESC 105
+#define IDD_CFG_REALMS 105
+#define IDS_KEY_ENCTYPE_LONG_DESC 106
+#define IDD_CFG_IDS_TAB 106
+#define IDS_TKT_ENCTYPE_LONG_DESC 107
+#define IDD_PP_KRB5C 107
+#define IDS_ADDR_LIST_SHORT_DESC 108
+#define IDD_PP_KRB5 108
+#define IDS_ADDR_LIST_LONG_DESC 109
+#define IDD_CFG_ID_TAB 109
+#define IDS_ETYPE_NULL 110
+#define IDD_NC_KRB5_PASSWORD 110
+#define IDS_ETYPE_DES_CBC_CRC 111
+#define IDD_CFG_CACHES 111
+#define IDS_ETYPE_DES_CBC_MD4 112
+#define IDI_PLUGIN 112
+#define IDS_ETYPE_DES_CBC_MD5 113
+#define IDI_DELETED 113
+#define IDS_ETYPE_DES_CBC_RAW 114
+#define IDI_NEW 114
+#define IDS_ETYPE_DES3_CBC_SHA 115
+#define IDI_NORMAL 115
+#define IDS_ETYPE_DES3_CBC_RAW 116
+#define IDI_MODIFIED 116
+#define IDS_ETYPE_DES_HMAC_SHA1 117
+#define IDS_ETYPE_DES3_CBC_SHA1 118
+#define IDS_ETYPE_AES128_CTS_HMAC_SHA1_96 119
+#define IDS_ETYPE_AES256_CTS_HMAC_SHA1_96 120
+#define IDS_ETYPE_ARCFOUR_HMAC 121
+#define IDS_ETYPE_ARCFOUR_HMAC_EXP 122
+#define IDS_ETYPE_UNKNOWN 123
+#define IDS_ETYPE_LOCAL_DES3_HMAC_SHA1 124
+#define IDS_ETYPE_LOCAL_RC4_MD4 125
+#define IDS_KRB5_SHORT_DESC 126
+#define IDS_KRB5_LONG_DESC 127
+#define IDS_KRB4_SHORT_DESC 128
+#define IDS_KRB4_LONG_DESC 129
+#define IDS_KRB5_FLAGS_SHORT_DESC 130
+#define IDS_RENEW_TILL_SHORT_DESC 131
+#define IDS_RENEW_TILL_LONG_DESC 132
+#define IDS_RENEW_FOR_SHORT_DESC 133
+#define IDS_RENEW_FOR_LONG_DESC 134
+#define IDS_KRB5_CCNAME_LONG_DESC 135
+#define IDS_NC_USERNAME 136
+#define IDS_NC_REALM 137
+#define IDS_KRB5_WARNING 138
+#define IDS_K5ERR_NAME_EXPIRED 139
+#define IDS_K5ERR_KEY_EXPIRED 140
+#define IDS_KRB5_WARN_FMT 141
+#define IDS_K5ERR_FMT 142
+#define IDS_K5CFG_SHORT_DESC 143
+#define IDS_K5CFG_LONG_DESC 144
+#define IDS_K5RLM_SHORT_DESC 145
+#define IDS_K5RLM_LONG_DESC 146
+#define IDS_K5CFG_IDS_SHORT_DESC 147
+#define IDS_K5CFG_IDS_LONG_DESC 148
+#define IDS_K5CFG_ID_SHORT_DESC 149
+#define IDS_K5CFG_ID_LONG_DESC 150
+#define IDS_PLUGIN_DESC 151
+#define IDS_NC_PWD_BANNER 152
+#define IDS_NC_PWD_PWD 153
+#define IDS_NC_PWD_NPWD 154
+#define IDS_NC_PWD_NPWD_AGAIN 155
+#define IDS_KRB5_CREDTEXT_P0 156
+#define IDS_K5CFG_IMPORT_OPTIONS 157
+#define IDS_IDENTPRO_DESC 158
+#define IDS_K5CCC_SHORT_DESC 159
+#define IDS_K5CCC_LONG_DESC 160
+#define IDS_CFG_FCTITLE 161
+#define IDS_CFG_FCN_WARNING 162
+#define IDS_CFG_FCN_W_NOTFOUND 163
+#define IDS_CFG_FCN_W_RELATIVE 164
+#define IDS_CFG_FCOPENTITLE 165
+#define IDS_UNAVAILABLE 166
+#define IDS_FLG_FORWARDABLE 167
+#define IDS_FLG_FORWARDED 168
+#define IDS_FLG_PROXIABLE 169
+#define IDS_FLG_PROXY 170
+#define IDS_FLG_MAY_POSTDATE 171
+#define IDS_FLG_POSTDATED 172
+#define IDS_FLG_INVALID 173
+#define IDS_FLG_RENEWABLE 174
+#define IDS_FLG_INITIAL 175
+#define IDS_FLG_PRE_AUTH 176
+#define IDS_FLG_HW_AUTH 177
+#define IDS_FLG_TRANSIT_POL 178
+#define IDS_FLG_OK_DELEGATE 179
+#define IDS_FLG_ANONYMOUS 180
+#define IDS_K5ERR_CANTWRITEPROFILE 181
+#define IDS_K5ERR_PROFNOWRITE 182
+#define IDS_K5ERR_PROFUSETEMP 183
+#define IDS_K5ERR_PROFSUGGEST 184
+#define IDS_CFG_RE_REALMS 185
+#define IDS_CFG_RE_KDCS 186
+#define IDS_CFG_RE_DMAPS 187
+#define IDS_CFG_RE_KDCS_R 188
+#define IDS_CFG_RE_DMAPS_R 189
+#define IDS_CFG_RE_HEAD_SVR 190
+#define IDS_CFG_RE_HEAD_ADMIN 191
+#define IDS_CFG_RE_HEAD_MASTER 192
+#define IDS_CFG_RE_HEAD_DOMAIN 193
+#define IDS_CFG_RE_NEWREALM 194
+#define IDS_YES 195
+#define IDS_NO 196
+#define IDS_CFG_RE_NEWSERVER 197
+#define IDS_CFG_RE_NEWDMAP 198
+#define IDS_KRB5_NC_NAME 199
+#define IDS_NCERR_IDENT_TOO_LONG 200
+#define IDS_NCERR_IDENT_INVALID 201
+#define IDS_NCERR_IDENT_UNKNOWN 202
+#define IDS_CFG_RE_ARNUT 203
+#define IDS_CFG_RE_ARNUM 204
+#define IDS_CFG_RE_ASNUT 205
+#define IDS_CFG_RE_ASNUM 206
+#define IDS_CFG_RE_DMNUT 207
+#define IDS_CFG_RE_DMNUM 208
+#define IDS_CFG_RE_MNR 209
+#define IDS_CFG_RE_MDR 210
+#define IDS_CFG_RE_MNK 211
+#define IDS_CFG_RE_MDK 212
+#define IDS_CFG_RE_MAK 213
+#define IDS_CFG_RE_MMK 214
+#define IDS_CFG_RE_MND 215
+#define IDS_CFG_RE_MDD 216
+#define IDS_KVNO_SHORT_DESC 217
+#define IDS_KVNO_LONG_DESC 218
+#define IDC_NCK5_RENEWABLE 1002
+#define IDC_NCK5_FORWARDABLE 1004
+#define IDC_NCK5_REALM 1005
+#define IDC_NCK5_ADD_REALMS 1006
+#define IDC_NCK5_LIFETIME_EDIT 1008
+#define IDC_NCK5_RENEW_EDIT 1009
+#define IDC_PPK5_CRENEW 1014
+#define IDC_PPK5_CFORWARD 1015
+#define IDC_PPK5_CPROXY 1016
+#define IDC_PPK5_NAME 1017
+#define IDC_PPK5_ISSUE 1018
+#define IDC_PPK5_VALID 1019
+#define IDC_PPK5_RENEW 1020
+#define IDC_CHECK2 1022
+#define IDC_CHECK4 1024
+#define IDC_PPK5_LIFETIME 1024
+#define IDC_CHECK5 1025
+#define IDC_CFG_LBL_REALM 1025
+#define IDC_CFG_DEFREALM 1026
+#define IDC_CFG_LBL_CFGFILE 1029
+#define IDC_CFG_CFGFILE 1030
+#define IDC_CFG_WINGRP 1031
+#define IDC_LBL_IMPORT 1032
+#define IDC_CFG_IMPORT 1033
+#define IDC_CFG_LBL_HOSTNAME 1034
+#define IDC_CFG_HOSTNAME 1035
+#define IDC_CFG_LBL_DOMAIN 1036
+#define IDC_CFG_DOMAIN 1037
+#define IDC_CFG_CREATECONFIG 1038
+#define IDC_CFG_BROWSE 1039
+#define IDC_CFG_CFGFILEGRP 1040
+#define IDC_CFG_CFGREALMS 1041
+#define IDC_CFG_BROWSE2 1042
+#define IDC_CFG_REALMS 1044
+#define IDC_CFG_DOMAINGRP 1045
+#define IDC_CFG_SERVERSGRP 1046
+#define IDC_LIST3 1047
+#define IDC_CFG_KDC 1047
+#define IDC_LIST4 1048
+#define IDC_CFG_DMAP 1048
+#define IDC_CFG_LBL_DEFLIFE 1049
+#define IDC_CFG_DEFLIFE 1050
+#define IDC_CFG_LBL_DEFRLIFE 1051
+#define IDC_CFG_DEFRLIFE 1052
+#define IDC_CFG_LIFEGRP 1053
+#define IDC_CFG_LRNG_MIN 1054
+#define IDC_CFG_LRNG_MAX 1055
+#define IDC_CFG_RLRNG_MIN 1056
+#define IDC_CFG_RLRNG_MAX 1057
+#define IDC_CFG_CCACHE 1058
+#define IDC_CFG_FCGRP 1059
+#define IDC_CFG_FCLIST 1060
+#define IDC_CFG_FCNAME 1062
+#define IDC_CFG_ADD 1064
+#define IDC_CFG_REMOVE 1065
+#define IDC_CFG_INCAPI 1066
+#define IDC_CFG_INCMSLSA 1067
+#define IDC_PPK5_FLAGS 1072
+#define IDC_CFG_INCREALMS 1073
+#define IDC_NCK5_ADDRESS 1074
+#define IDC_IPADDRESS1 1075
+#define IDC_NCK5_PUBLICIP 1075
+#define IDC_CFG_PUBLICIP 1075
+#define IDC_CFG_RENEW 1076
+#define IDC_CHECK3 1077
+#define IDC_CFG_ADDRESSLESS 1077
+#define IDC_CFG_FORWARD 1078
+#define IDC_CHECK1 1079
+#define ID_FOO_BAR 40001
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 219
+#define _APS_NEXT_COMMAND_VALUE 40002
+#define _APS_NEXT_CONTROL_VALUE 1080
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif