$(ECHO) -- Done with $@\r
!endif\r
\r
-finale: krb5plugin doc\r
+!ifdef NODOCBUILD\r
+doctarget=\r
+!else\r
+doctarget=doc\r
+!endif\r
+\r
+finale: krb5plugin $(doctarget)\r
$(ECHO) -- Done.\r
\r
pdoc:\r
# Version info\r
NETIDMGR_VERSION_MAJOR=1\r
NETIDMGR_VERSION_MINOR=1\r
-NETIDMGR_VERSION_PATCH=2\r
+NETIDMGR_VERSION_PATCH=4\r
NETIDMGR_VERSION_AUX=0\r
NETIDMGR_RELEASEDESC=\r
\r
# Version info\r
NETIDMGR_VERSION_MAJOR=1\r
NETIDMGR_VERSION_MINOR=1\r
-NETIDMGR_VERSION_PATCH=2\r
+NETIDMGR_VERSION_PATCH=4\r
NETIDMGR_VERSION_AUX=0\r
NETIDMGR_RELEASEDESC=\r
\r
NetIDMgr was developed at the Massachusetts Institute of\r
Technology.\r
\r
- (Contributor list goes here)\r
-\r
- At the moment, no contributers have come forward to accept\r
- responsibility.\r
-\r
<a href="http://web.mit.edu/is">Information Services and\r
Technology</a> at <a href="http://web.mit.edu">Massachusetts\r
Institute of Technology</a>\r
\r
end = wcschr(str, L'\\'); /* safe because cspace was\r
validated above */\r
-#if 0\r
- if(!end)\r
- end = wcschr(str, L'/'); /* safe because cspace was\r
- validated above */\r
-#endif\r
}\r
\r
if(!end) {\r
\r
rv = khcint_open_space(p, str, end - str, flags, &c);\r
\r
- if(KHM_SUCCEEDED(rv) && (*end == L'\\'\r
-#if 0\r
- || *end == L'/'\r
-#endif\r
- )) {\r
+ if(KHM_SUCCEEDED(rv) && (*end == L'\\')) {\r
khcint_space_release(p);\r
p = c;\r
c = NULL;\r
\r
int i;\r
\r
- if(wcschr(pvalue, L'\\')\r
-#if 0\r
- || wcschr(pvalue, L'/')\r
-#endif\r
- ) {\r
+ if((value = wcsrchr(pvalue, L'\\')) != NULL) {\r
\r
if(KHM_FAILED(khc_open_space(\r
pconf, \r
goto _shadow;\r
\r
free_space = 1;\r
-#if 0\r
- const wchar_t * back, * forward;\r
-\r
- back = wcsrchr(pvalue, L'\\');\r
- forward = wcsrchr(pvalue, L'/');\r
- value = (back > forward)?back:forward; /* works for nulls too */\r
-#else\r
- value = wcsrchr(pvalue, L'\\');\r
+\r
+ if (value) {\r
+ value++;\r
+ } else {\r
+#ifdef DEBUG\r
+ assert(FALSE);\r
#endif\r
+ }\r
} else {\r
value = pvalue;\r
conf = pconf;\r
\r
int i;\r
\r
- if(wcschr(pvalue, L'\\')\r
-#if 0\r
- || wcschr(pvalue, L'/')\r
-#endif\r
- ) {\r
+ if((value = wcsrchr(pvalue, L'\\')) != NULL) {\r
if(KHM_FAILED(khc_open_space(\r
pconf, \r
pvalue, \r
&conf)))\r
goto _shadow;\r
free_space = 1;\r
-#if 0\r
- const wchar_t * back, * forward;\r
-\r
- back = wcsrchr(pvalue, L'\\');\r
- forward = wcsrchr(pvalue, L'/');\r
- value = (back > forward)?back:forward;\r
-#else\r
- value = wcsrchr(pvalue, L'\\');\r
+\r
+ if (value) {\r
+ value++;\r
+ } else {\r
+#ifdef DEBUG\r
+ assert(FALSE);\r
#endif\r
+ }\r
} else {\r
value = pvalue;\r
conf = pconf;\r
\r
int i;\r
\r
- if(wcschr(pvalue, L'\\')\r
-#if 0\r
- || wcschr(pvalue, L'/')\r
-#endif\r
- ) {\r
+ if((value = wcsrchr(pvalue, L'\\')) != NULL) {\r
if(KHM_FAILED(khc_open_space(\r
pconf, \r
pvalue, \r
&conf)))\r
goto _shadow;\r
free_space = 1;\r
-#if 0\r
- const wchar_t * back, *forward;\r
-\r
- back = wcsrchr(pvalue, L'\\');\r
- forward = wcsrchr(pvalue, L'/');\r
- value = (back > forward)?back:forward;\r
-#else\r
- value = wcsrchr(pvalue, L'\\');\r
+\r
+ if (value) {\r
+ value++;\r
+ } else {\r
+#ifdef DEBUG\r
+ assert(FALSE);\r
#endif\r
+ }\r
} else {\r
value = pvalue;\r
conf = pconf;\r
int free_space = 0;\r
khm_handle conf = NULL;\r
\r
- if(wcschr(pvalue, L'\\')\r
-#if 0\r
- || wcschr(pvalue, L'/')\r
-#endif\r
- ) {\r
+ if((value = wcsrchr(pvalue, L'\\')) != NULL) {\r
if(KHM_FAILED(khc_open_space(\r
pconf, \r
pvalue, \r
&conf)))\r
goto _shadow;\r
free_space = 1;\r
-#if 0\r
- const wchar_t * back, *forward;\r
-\r
- back = wcsrchr(pvalue, L'\\');\r
- forward = wcsrchr(pvalue, L'/');\r
- value = (back > forward)?back:forward;\r
-#else\r
- value = wcsrchr(pvalue, L'\\');\r
+\r
+ if (value) {\r
+ value++;\r
+ } else {\r
+#ifdef DEBUG\r
+ assert(FALSE);\r
#endif\r
+ }\r
} else {\r
value = pvalue;\r
conf = pconf;\r
}\r
}\r
\r
- if(wcschr(pvalue, L'\\')\r
-#if 0\r
- || wcschr(pvalue, L'/')\r
-#endif\r
- ) {\r
+ if((value = wcsrchr(pvalue, L'\\')) != NULL) {\r
if(KHM_FAILED(khc_open_space(pconf, pvalue, \r
KCONF_FLAG_TRAILINGVALUE | (pconf?khc_handle_flags(pconf):0), \r
&conf)))\r
return KHM_ERROR_INVALID_PARAM;\r
free_space = 1;\r
-#if 0\r
- const wchar_t * back, *forward;\r
-\r
- back = wcsrchr(pvalue, L'\\');\r
- forward = wcsrchr(pvalue, L'/');\r
- value = (back > forward)?back:forward;\r
-#else\r
- value = wcsrchr(pvalue, L'\\');\r
+\r
+ if (value) {\r
+ value ++;\r
+ } else {\r
+#ifdef DEBUG\r
+ assert(FALSE);\r
#endif\r
+ }\r
} else {\r
value = pvalue;\r
conf = pconf;\r
}\r
}\r
\r
- if(wcschr(pvalue, L'\\')\r
-#if 0\r
- || wcschr(pvalue, L'/')\r
-#endif\r
- ) {\r
+ if((value = wcsrchr(pvalue, L'\\')) != NULL) {\r
if(KHM_FAILED(khc_open_space(\r
pconf, \r
pvalue, \r
&conf)))\r
return KHM_ERROR_INVALID_PARAM;\r
free_space = 1;\r
-#if 0\r
- const wchar_t * back, *forward;\r
-\r
- back = wcsrchr(pvalue, L'\\');\r
- forward = wcsrchr(pvalue, L'/');\r
- value = (back > forward)?back:forward;\r
-#else\r
- value = wcsrchr(pvalue, L'\\');\r
+\r
+ if (value) {\r
+ value ++;\r
+ } else {\r
+#ifdef DEBUG\r
+ assert(FALSE);\r
#endif\r
+ }\r
} else {\r
value = pvalue;\r
conf = pconf;\r
}\r
}\r
\r
- if(wcschr(pvalue, L'\\')\r
-#if 0\r
- || wcschr(pvalue, L'/')\r
-#endif\r
- ) {\r
+ if((value = wcsrchr(pvalue, L'\\')) != NULL) {\r
if(KHM_FAILED(khc_open_space(\r
pconf, \r
pvalue, \r
&conf)))\r
return KHM_ERROR_INVALID_PARAM;\r
free_space = 1;\r
-#if 0\r
- const wchar_t * back, *forward;\r
-\r
- back = wcsrchr(pvalue, L'\\');\r
- forward = wcsrchr(pvalue, L'/');\r
- value = (back > forward)?back:forward;\r
-#else\r
- value = wcsrchr(pvalue, L'\\');\r
+\r
+ if (value) {\r
+ value ++;\r
+ } else {\r
+#ifdef DEBUG\r
+ assert(FALSE);\r
#endif\r
+ }\r
} else {\r
value = pvalue;\r
conf = pconf;\r
if(pconf && !khc_is_machine_handle(pconf) && !khc_is_user_handle(pconf))\r
return KHM_ERROR_INVALID_OPERATION;\r
\r
- if(wcschr(pvalue, L'\\')\r
-#if 0\r
- || wcschr(pvalue, L'/')\r
-#endif\r
- ) {\r
+ if((value = wcsrchr(pvalue, L'\\')) != NULL) {\r
if(KHM_FAILED(khc_open_space(\r
pconf, \r
pvalue, \r
&conf)))\r
return KHM_ERROR_INVALID_PARAM;\r
free_space = 1;\r
-#if 0\r
- const wchar_t * back, *forward;\r
-\r
- back = wcsrchr(pvalue, L'\\');\r
- forward = wcsrchr(pvalue, L'/');\r
- value = (back > forward)?back:forward;\r
-#else\r
- value = wcsrchr(pvalue, L'\\');\r
+\r
+ if (value) {\r
+ value ++;\r
+ } else {\r
+#ifdef DEBUG\r
+ assert(FALSE);\r
#endif\r
+ }\r
} else {\r
value = pvalue;\r
conf = pconf;\r
are freed. Once they are released, kcdb_identity_delete() will\r
be called again. */\r
\r
-#if 0\r
- EnterCriticalSection(&cs_ident);\r
- if(id->refcount == 0) {\r
- /*TODO: free up the identity */\r
- }\r
-#endif\r
_exit:\r
LeaveCriticalSection(&cs_ident);\r
\r
ident != NULL;\r
ident = next) {\r
\r
- next = LNEXT(ident);\r
-\r
if (!kcdb_is_active_identity(ident) ||\r
- ident->refresh_cycle == kcdb_ident_refresh_cycle)\r
+ ident->refresh_cycle == kcdb_ident_refresh_cycle) {\r
+ next = LNEXT(ident);\r
continue;\r
+ }\r
\r
kcdb_identity_hold((khm_handle) ident);\r
\r
\r
EnterCriticalSection(&cs_ident);\r
\r
+ next = LNEXT(ident);\r
kcdb_identity_release((khm_handle) ident);\r
\r
hit_count++;\r
/*\r
- * Copyright (c) 2005 Massachusetts Institute of Technology\r
+ * Copyright (c) 2006 Secure Endpoints Inc.\r
*\r
* Permission is hereby granted, free of charge, to any person\r
* obtaining a copy of this software and associated documentation\r
return TRUE;\r
}\r
\r
+LRESULT\r
+k5_force_password_change(k5_dlg_data * d) {\r
+ /* we are turning this dialog into a change password dialog... */\r
+ wchar_t wbuf[KHUI_MAXCCH_BANNER];\r
+\r
+ khui_cw_clear_prompts(d->nc);\r
+\r
+ LoadString(hResModule, IDS_NC_PWD_BANNER,\r
+ wbuf, ARRAYLENGTH(wbuf));\r
+ khui_cw_begin_custom_prompts(d->nc, 3, NULL, wbuf);\r
+\r
+ LoadString(hResModule, IDS_NC_PWD_PWD,\r
+ wbuf, ARRAYLENGTH(wbuf));\r
+ khui_cw_add_prompt(d->nc, KHUI_NCPROMPT_TYPE_PASSWORD,\r
+ wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);\r
+\r
+ LoadString(hResModule, IDS_NC_PWD_NPWD,\r
+ wbuf, ARRAYLENGTH(wbuf));\r
+ khui_cw_add_prompt(d->nc, KHUI_NCPROMPT_TYPE_NEW_PASSWORD,\r
+ wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);\r
+\r
+ LoadString(hResModule, IDS_NC_PWD_NPWD_AGAIN,\r
+ wbuf, ARRAYLENGTH(wbuf));\r
+ khui_cw_add_prompt(d->nc, KHUI_NCPROMPT_TYPE_NEW_PASSWORD_AGAIN,\r
+ wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);\r
+\r
+ d->pwd_change = TRUE;\r
+\r
+ if (is_k5_identpro &&\r
+ d->nc->n_identities > 0 &&\r
+ d->nc->identities[0]) {\r
+\r
+ kcdb_identity_set_flags(d->nc->identities[0],\r
+ KCDB_IDENT_FLAG_VALID,\r
+ KCDB_IDENT_FLAG_VALID);\r
+\r
+ }\r
+\r
+ PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,\r
+ MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT),\r
+ (LPARAM) d->nc);\r
+\r
+ return TRUE;\r
+}\r
+\r
INT_PTR\r
k5_handle_wmnc_notify(HWND hwnd,\r
WPARAM wParam, \r
case WMNC_DIALOG_SETUP:\r
{\r
k5_dlg_data * d;\r
+ BOOL old_sync;\r
\r
d = (k5_dlg_data *)(LONG_PTR) \r
GetWindowLongPtr(hwnd, DWLP_USER);\r
if (d->nc->subtype == KMSG_CRED_PASSWORD)\r
return TRUE;\r
\r
+ /* we save the value of the 'sync' field here because some\r
+ of the notifications that are generated while setting\r
+ the controls overwrite the field. */\r
+ old_sync = d->sync;\r
+\r
/* need to update the controls with d->* */\r
SendDlgItemMessage(hwnd, IDC_NCK5_RENEWABLE, \r
BM_SETCHECK,\r
0, d->publicIP);\r
\r
EnableWindow(GetDlgItem(hwnd, IDC_NCK5_PUBLICIP), !d->addressless);\r
+\r
+ d->sync = old_sync;\r
}\r
break;\r
\r
l->id, l->id_len);\r
\r
if (!wcscmp(linktext, L"Krb5Cred:!Passwd")) {\r
- /* we are turning this dialog into a change password dialog... */\r
- wchar_t wbuf[KHUI_MAXCCH_BANNER];\r
-\r
- khui_cw_clear_prompts(nc);\r
-\r
- LoadString(hResModule, IDS_NC_PWD_BANNER,\r
- wbuf, ARRAYLENGTH(wbuf));\r
- khui_cw_begin_custom_prompts(nc, 3, NULL, wbuf);\r
-\r
- LoadString(hResModule, IDS_NC_PWD_PWD,\r
- wbuf, ARRAYLENGTH(wbuf));\r
- khui_cw_add_prompt(nc, KHUI_NCPROMPT_TYPE_PASSWORD,\r
- wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);\r
-\r
- LoadString(hResModule, IDS_NC_PWD_NPWD,\r
- wbuf, ARRAYLENGTH(wbuf));\r
- khui_cw_add_prompt(nc, KHUI_NCPROMPT_TYPE_NEW_PASSWORD,\r
- wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);\r
-\r
- LoadString(hResModule, IDS_NC_PWD_NPWD_AGAIN,\r
- wbuf, ARRAYLENGTH(wbuf));\r
- khui_cw_add_prompt(nc, KHUI_NCPROMPT_TYPE_NEW_PASSWORD_AGAIN,\r
- wbuf, NULL, KHUI_NCPROMPT_FLAG_HIDDEN);\r
-\r
- d->pwd_change = TRUE;\r
-\r
- if (is_k5_identpro &&\r
- d->nc->n_identities > 0 &&\r
- d->nc->identities[0]) {\r
-\r
- kcdb_identity_set_flags(d->nc->identities[0],\r
- KCDB_IDENT_FLAG_VALID,\r
- KCDB_IDENT_FLAG_VALID);\r
-\r
- }\r
-\r
- PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,\r
- MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT),\r
- (LPARAM) d->nc);\r
-\r
- return TRUE;\r
+ return k5_force_password_change(d);\r
}\r
}\r
break;\r
d = (k5_dlg_data *)(LONG_PTR) \r
GetWindowLongPtr(hwnd, DWLP_USER);\r
\r
- if(!d->sync) {\r
+ if(!d->sync && d->nc->result == KHUI_NC_RESULT_PROCESS) {\r
kmq_post_sub_msg(k5_sub, KMSG_CRED, \r
KMSG_CRED_DIALOG_NEW_OPTIONS, \r
0, (void *) d->nc);\r
-\r
- /* the above notification effectively takes all our\r
- changes into account. The data we have is no\r
- longer out of sync */\r
- d->sync = TRUE;\r
}\r
}\r
break;\r
}\r
}\r
\r
+#ifdef DEBUG\r
+ /* log the state of g_fjob.* */\r
+ _reportf(L"g_fjob state prior to calling khm_krb5_kinit() :");\r
+ _reportf(L" g_fjob.principal = [%S]", g_fjob.principal);\r
+ _reportf(L" g_fjob.code = %d", g_fjob.code);\r
+ _reportf(L" g_fjob.state = %d", g_fjob.state);\r
+ _reportf(L" g_fjob.prompt_set= %d", g_fjob.prompt_set);\r
+ _reportf(L" g_fjob.valid_principal = %d", (int) g_fjob.valid_principal);\r
+#endif\r
+\r
g_fjob.code =\r
khm_krb5_kinit(0,\r
g_fjob.principal,\r
khm_size ncp;\r
krb5_error_code code = 0;\r
BOOL new_prompts = TRUE;\r
-\r
khm_handle csp_prcache = NULL;\r
\r
+#ifdef DEBUG\r
+ _reportf(L"k5_kinit_prompter() received %d prompts with name=[%S] banner=[%S]",\r
+ num_prompts,\r
+ name, banner);\r
+ for (i=0; i < num_prompts; i++) {\r
+ _reportf(L"Prompt[%d]: string[%S]", i, prompts[i].prompt);\r
+ }\r
+#endif\r
+\r
/* we got prompts? Then we assume that the principal is valid */\r
g_fjob.valid_principal = TRUE;\r
\r
/* once we read the new data, in, it is no longer considered\r
dirty */\r
d->dirty = FALSE;\r
+ d->sync = FALSE;\r
}\r
\r
void \r
d = (k5_dlg_data *)(LONG_PTR) \r
GetWindowLongPtr(nct->hwnd_panel, DWLP_USER);\r
\r
+ /* this can be NULL if the dialog was closed while the\r
+ plug-in thread was processing. */\r
+ if (d == NULL)\r
+ break;\r
+\r
if (!is_k5_identpro) {\r
\r
/* enumerate all realms and place in realms combo box */\r
d = (k5_dlg_data *)(LONG_PTR) \r
GetWindowLongPtr(nct->hwnd_panel, DWLP_USER);\r
\r
+ if (d == NULL)\r
+ break;\r
+\r
/* we only load the identity specific defaults if the user\r
hasn't changed the options */\r
khui_cw_lock_nc(nc);\r
\r
d = (k5_dlg_data *)(LONG_PTR) \r
GetWindowLongPtr(nct->hwnd_panel, DWLP_USER);\r
+ if (d == NULL)\r
+ break;\r
\r
if (nc->subtype == KMSG_CRED_PASSWORD) {\r
khm_size n_prompts = 0;\r
kcdb_identity_hold(ident);\r
\r
k5_prep_kinit_job(nc);\r
+\r
+ /* after the switch to the fiber, the dialog will be\r
+ back in sync with the kinit thread. */\r
+ d->sync = TRUE;\r
+\r
khui_cw_unlock_nc(nc);\r
\r
SwitchToFiber(k5_kinit_fiber);\r
wchar_t msg[KHUI_MAXCCH_BANNER];\r
khm_size cb;\r
\r
+ /* Special case. If the users' password has\r
+ expired, we force a password change dialog on\r
+ top of the new credentials dialog using a set\r
+ of custom prompts, but only if we are the\r
+ identity provider. */\r
+ if (g_fjob.code == KRB5KDC_ERR_KEY_EXP &&\r
+ is_k5_identpro) {\r
+\r
+ k5_force_password_change(d);\r
+ goto done_with_bad_princ;\r
+\r
+ }\r
+\r
/* we can't possibly have succeeded without a\r
password */\r
- if(g_fjob.code) {\r
- if (is_k5_identpro)\r
- kcdb_identity_set_flags(ident,\r
- KCDB_IDENT_FLAG_INVALID,\r
- KCDB_IDENT_FLAG_INVALID);\r
+ if(g_fjob.code && is_k5_identpro) {\r
+ kcdb_identity_set_flags(ident,\r
+ KCDB_IDENT_FLAG_INVALID,\r
+ KCDB_IDENT_FLAG_INVALID);\r
\r
khui_cw_clear_prompts(nc);\r
}\r
break;\r
\r
case KRB5KDC_ERR_KEY_EXP:\r
- /* password needs changing. */\r
- LoadString(hResModule, IDS_K5ERR_KEY_EXPIRED,\r
- msg, ARRAYLENGTH(msg));\r
+ {\r
+ /* password needs changing. */\r
+ LoadString(hResModule, IDS_K5ERR_KEY_EXPIRED,\r
+ msg, ARRAYLENGTH(msg));\r
+ }\r
break;\r
\r
default:\r
StringCbCopy(d->cred_message, cb, msg);\r
}\r
\r
+ done_with_bad_princ:\r
+\r
k5_free_kinit_job();\r
\r
} else if(g_fjob.state == FIBER_STATE_KINIT) {\r
\r
if (nc->subtype == KMSG_CRED_NEW_CREDS) {\r
d = (k5_dlg_data *) nct->aux;\r
+ if (d == NULL)\r
+ break;\r
\r
if (d->pwd_change) {\r
/* we are forcing a password change */\r
\r
if (code)\r
rv = KHM_ERROR_UNKNOWN;\r
- else if (nc->subtype == KMSG_CRED_NEW_CREDS) {\r
+ else {\r
khm_handle csp_idcfg = NULL;\r
krb5_context ctx = NULL;\r
\r
- /* we forced a password change. now we need\r
- to get the initial credentials. */\r
+ /* we set a new password. now we need to get\r
+ initial credentials. */\r
\r
d = (k5_dlg_data *) nct->aux;\r
\r
goto _pwd_exit;\r
}\r
\r
+ if (nc->subtype == KMSG_CRED_PASSWORD) {\r
+ /* since this was just a password change,\r
+ we need to load new credentials options\r
+ from the configuration store. */\r
+ \r
+ if (KHM_SUCCEEDED\r
+ (k5_open_config_handle(nc->identities[0],\r
+ KHM_FLAG_CREATE |\r
+ KCONF_FLAG_WRITEIFMOD,\r
+ &csp_idcfg))) {\r
+ k5_read_dlg_params(csp_idcfg, d);\r
+ khc_close_space(csp_idcfg);\r
+ csp_idcfg = NULL;\r
+ }\r
+ }\r
+\r
/* the password change phase is now done */\r
d->pwd_change = FALSE;\r
\r
+#ifdef DEBUG\r
+ _reportf(L"Calling khm_krb5_kinit()");\r
+#endif\r
code = khm_krb5_kinit(NULL, /* context (create one) */\r
idname, /* principal_name */\r
npwd, /* new password */\r
\r
/* save the settings that we used for\r
obtaining the ticket. */\r
- if (KHM_SUCCEEDED\r
+ if (nc->subtype == KMSG_CRED_NEW_CREDS &&\r
+ KHM_SUCCEEDED\r
(k5_open_config_handle(nc->identities[0],\r
KHM_FLAG_CREATE |\r
KCONF_FLAG_WRITEIFMOD,\r
&csp_idcfg))) {\r
k5_write_dlg_params(csp_idcfg, d);\r
khc_close_space(csp_idcfg);\r
+\r
+ /* and then update the LRU too */\r
+ k5_update_LRU(nc->identities[0]);\r
}\r
\r
/* and do a quick refresh of the krb5 tickets\r
}\r
}\r
\r
- /* and then update the LRU too */\r
- k5_update_LRU(nc->identities[0]);\r
-\r
if (ctx != NULL)\r
pkrb5_free_context(ctx);\r
+\r
+ if (nc->subtype == KMSG_CRED_PASSWORD) {\r
+ /* if we obtained new credentials as a\r
+ result of successfully changing the\r
+ password, we also schedule an identity\r
+ renewal for this identity. This allows\r
+ the other credential types to obtain\r
+ credentials for this identity. */\r
+ khui_action_context ctx;\r
+\r
+ _reportf(L"Scheduling renewal of [%s] after password change",\r
+ widname);\r
+\r
+ khui_context_create(&ctx,\r
+ KHUI_SCOPE_IDENT,\r
+ nc->identities[0],\r
+ KCDB_CREDTYPE_INVALID,\r
+ NULL);\r
+ khui_action_trigger(KHUI_ACTION_RENEW_CRED,\r
+ &ctx);\r
+\r
+ khui_context_release(&ctx);\r
+ }\r
}\r
\r
/* result is only set when code != 0 */\r
PFREE(result);\r
PFREE(wresult);\r
\r
- /* leave wresult. It will get freed when the\r
- reported event is freed. */\r
-\r
/* we don't need to report anything more */\r
code = 0;\r
}\r
khm_cred_destroy_creds(khm_boolean sync,\r
khm_boolean quiet);\r
\r
+void\r
+khm_cred_destroy_identity(khm_handle identity);\r
+\r
void \r
khm_cred_renew_identity(khm_handle identity);\r
\r
BOOL rie;\r
HBRUSH hbr;\r
\r
- if(RectVisible(hdc, r_erase)) {\r
-\r
- switch(type) {\r
- case CW_ER_BLANK:\r
- hbr = tbl->hb_normal;\r
- break;\r
-\r
- case CW_ER_GREY:\r
- hbr = tbl->hb_grey;\r
- break;\r
+ switch(type) {\r
+ case CW_ER_BLANK:\r
+ hbr = tbl->hb_normal;\r
+ break;\r
\r
- case CW_ER_SEL:\r
- hbr = tbl->hb_sel;\r
- break;\r
+ case CW_ER_GREY:\r
+ hbr = tbl->hb_grey;\r
+ break;\r
\r
- default:\r
- return;\r
- }\r
+ case CW_ER_SEL:\r
+ hbr = tbl->hb_sel;\r
+ break;\r
\r
- if(tbl->kbm_logo_shade.cx != -1 && type == CW_ER_BLANK) {\r
- rlogo.left = r_wnd->right - tbl->kbm_logo_shade.cx;\r
- rlogo.right = r_wnd->right;\r
- rlogo.top = r_wnd->bottom - tbl->kbm_logo_shade.cy;\r
- rlogo.bottom = r_wnd->bottom;\r
- rie = IntersectRect(&ri, r_erase, &rlogo);\r
- } else {\r
- ZeroMemory(&rlogo, sizeof(rlogo));\r
- ZeroMemory(&ri, sizeof(ri));\r
- rie = FALSE;\r
- }\r
+ default:\r
+ return;\r
+ }\r
\r
- if(!rie) {\r
- FillRect(hdc, r_erase, hbr);\r
- } else {\r
- HDC hdcb = CreateCompatibleDC(hdc);\r
- HBITMAP hbmold = SelectObject(hdcb, tbl->kbm_logo_shade.hbmp);\r
+ if(tbl->kbm_logo_shade.cx != -1 && type == CW_ER_BLANK) {\r
+ rlogo.left = r_wnd->right - tbl->kbm_logo_shade.cx;\r
+ rlogo.right = r_wnd->right;\r
+ rlogo.top = r_wnd->bottom - tbl->kbm_logo_shade.cy;\r
+ rlogo.bottom = r_wnd->bottom;\r
+ rie = IntersectRect(&ri, r_erase, &rlogo);\r
+ } else {\r
+ ZeroMemory(&rlogo, sizeof(rlogo));\r
+ ZeroMemory(&ri, sizeof(ri));\r
+ rie = FALSE;\r
+ }\r
\r
- BitBlt(hdc, ri.left, ri.top, ri.right - ri.left, ri.bottom - ri.top,\r
- hdcb, ri.left - rlogo.left, ri.top - rlogo.top, SRCCOPY);\r
+ if(!rie) {\r
+ FillRect(hdc, r_erase, hbr);\r
+ } else {\r
+ HDC hdcb = CreateCompatibleDC(hdc);\r
+ HBITMAP hbmold = SelectObject(hdcb, tbl->kbm_logo_shade.hbmp);\r
+ \r
+ BitBlt(hdc, ri.left, ri.top, ri.right - ri.left, ri.bottom - ri.top,\r
+ hdcb, ri.left - rlogo.left, ri.top - rlogo.top, SRCCOPY);\r
\r
- SelectObject(hdcb, hbmold);\r
- DeleteDC(hdcb);\r
-\r
- if(r_erase->top < ri.top && r_erase->left < ri.left) {\r
- t.left = r_erase->left;\r
- t.top = r_erase->top;\r
- t.right = ri.left;\r
- t.bottom = ri.top;\r
- FillRect(hdc, &t, hbr);\r
- }\r
+ SelectObject(hdcb, hbmold);\r
+ DeleteDC(hdcb);\r
+\r
+ if(r_erase->top < ri.top && r_erase->left < ri.left) {\r
+ t.left = r_erase->left;\r
+ t.top = r_erase->top;\r
+ t.right = ri.left;\r
+ t.bottom = ri.top;\r
+ FillRect(hdc, &t, hbr);\r
+ }\r
\r
- if(r_erase->left < ri.left) {\r
- t.left = r_erase->left;\r
- t.top = ri.top;\r
- t.right = ri.left;\r
- t.bottom = ri.bottom;\r
- FillRect(hdc, &t, hbr);\r
- }\r
+ if(r_erase->left < ri.left) {\r
+ t.left = r_erase->left;\r
+ t.top = ri.top;\r
+ t.right = ri.left;\r
+ t.bottom = ri.bottom;\r
+ FillRect(hdc, &t, hbr);\r
+ }\r
\r
- if(r_erase->top < ri.top) {\r
- t.left = ri.left;\r
- t.top = r_erase->top;\r
- t.right = ri.right;\r
- t.bottom = ri.top;\r
- FillRect(hdc, &t, hbr);\r
- }\r
+ if(r_erase->top < ri.top) {\r
+ t.left = ri.left;\r
+ t.top = r_erase->top;\r
+ t.right = ri.right;\r
+ t.bottom = ri.top;\r
+ FillRect(hdc, &t, hbr);\r
}\r
}\r
}\r
return DefWindowProc(hwnd, uMsg, wParam, lParam);\r
}\r
\r
+/* handles WM_PAINT and WM_PRINTCLIENT */\r
LRESULT \r
cw_wm_paint(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
{\r
int flag_col = -1;\r
int d_x = -1;\r
int selected = 0;\r
+ BOOL has_dc = FALSE;\r
\r
tbl = (khui_credwnd_tbl *)(LONG_PTR) GetWindowLongPtr(hwnd, 0);\r
\r
- if(!GetUpdateRect(hwnd, &r, FALSE))\r
+ if (wParam != 0) {\r
+ /* we assume that if wParam != 0, then that contains a device\r
+ context for us to draw in. Otherwise, we have to call\r
+ BeginPaint() to get one. */\r
+ hdc = (HDC) wParam;\r
+ has_dc = TRUE;\r
+ }\r
+\r
+ if(!has_dc && !GetUpdateRect(hwnd, &r, FALSE)) {\r
+#ifdef DEBUG\r
+ assert(FALSE);\r
+#endif\r
goto _exit;\r
+ }\r
+\r
+ if (!has_dc)\r
+ hdc = BeginPaint(hwnd, &ps);\r
\r
- hdc = BeginPaint(hwnd, &ps);\r
if(tbl->hf_normal)\r
hf_old = SelectFont(hdc, tbl->hf_normal);\r
SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);\r
rh.left = x;\r
rh.right = x + tbl->cols[j].width;\r
\r
- if(!RectVisible(hdc, &rh))\r
- continue;\r
-\r
if(!cw_is_custom_attr(tbl->cols[j].attr_id)) {\r
if(!(tbl->rows[i].flags & KHUI_CW_ROW_HEADER)) {\r
cw_erase_rect(hdc, tbl, &r, &rh, (selected)?CW_ER_SEL:CW_ER_BLANK);\r
SetTextAlign(hdc, 0);\r
DrawText(hdc, buf, (int)((cbbuf / sizeof(wchar_t)) - 1), &rh,\r
DT_LEFT | DT_VCENTER | DT_NOCLIP | DT_SINGLELINE | DT_END_ELLIPSIS);\r
- //TextOut(hdc, x, y + tbl->vpad, buf, (cbbuf / sizeof(wchar_t)) - 1);\r
}\r
}\r
} else {\r
if(tbl->hf_normal)\r
SelectFont(hdc, hf_old);\r
\r
- EndPaint(hwnd,&ps);\r
-_exit:\r
- return DefWindowProc(hwnd, uMsg, wParam, lParam);\r
+ if (!has_dc)\r
+ EndPaint(hwnd,&ps);\r
+\r
+ _exit:\r
+ return TRUE;\r
}\r
\r
LRESULT \r
/* we don't bother wasting cycles erasing the background\r
because the foreground elements completely cover the\r
client area */\r
- return TRUE;\r
+ return FALSE;\r
\r
case WM_PAINT:\r
return cw_wm_paint(hwnd, uMsg, wParam, lParam);\r
\r
+ case WM_PRINTCLIENT:\r
+ return cw_wm_paint(hwnd, uMsg, wParam, lParam);\r
+\r
case WM_SIZE:\r
return cw_wm_size(hwnd, uMsg, wParam, lParam);\r
\r
khm_nCmdShow = SW_RESTORE;\r
}\r
\r
+void\r
+khm_activate_main_window(void) {\r
+\r
+ if (!SetForegroundWindow(khm_hwnd_main)) {\r
+ FLASHWINFO finfo;\r
+\r
+ SetActiveWindow(khm_hwnd_main);\r
+\r
+ ZeroMemory(&finfo, sizeof(finfo));\r
+ finfo.cbSize = sizeof(finfo);\r
+ finfo.hwnd = khm_hwnd_main;\r
+ finfo.dwFlags = FLASHW_ALL;\r
+ finfo.uCount = 3;\r
+ finfo.dwTimeout = 0;\r
+\r
+ FlashWindowEx(&finfo);\r
+ }\r
+}\r
+\r
void \r
khm_close_main_window(void) {\r
khm_handle csp_cw;\r
void khm_unregister_main_wnd_class(void);\r
void khm_create_main_window_controls(HWND);\r
void khm_create_main_window(void);\r
+void khm_activate_main_window(void);\r
void khm_show_main_window(void);\r
void khm_close_main_window(void);\r
void khm_hide_main_window(void);\r
&t)) &&\r
t != 0) {\r
\r
+ /* if the main window is not visible, then the SetWindowPos()\r
+ call is sufficient to bring the new creds window to the\r
+ top. However, if the main window is visible but not\r
+ active, the main window needs to be activated before a\r
+ child window can be activated. */\r
+ khm_activate_main_window();\r
+\r
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,\r
(SWP_NOMOVE | SWP_NOSIZE));\r
\r
HWND hw, hw_prev;\r
HFONT hf, hfold;\r
HDC hdc;\r
+ BOOL use_large_lables = FALSE;\r
\r
/* we assume that WMNC_CLEAR_PROMPTS has already been\r
received */\r
hdc = GetWindowDC(d->dlg_main);\r
hfold = SelectObject(hdc,hf);\r
\r
+ /* first do a trial run and see if we should use the\r
+ larger text labels or not. This is so that all the\r
+ labels and input controls align properly. */\r
+ for (i=0; i < d->nc->n_prompts; i++) {\r
+ if (d->nc->prompts[i]->prompt != NULL) {\r
+ SIZE s;\r
+\r
+ GetTextExtentPoint32(hdc, \r
+ d->nc->prompts[i]->prompt, \r
+ (int) wcslen(d->nc->prompts[i]->prompt),\r
+ &s);\r
+\r
+ if(s.cx >= d->r_n_label.right - d->r_n_label.left) {\r
+ use_large_lables = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
for(i=0; i<d->nc->n_prompts; i++) {\r
RECT pr, er;\r
SIZE s;\r
d->nc->prompts[i]->prompt, \r
(int) wcslen(d->nc->prompts[i]->prompt),\r
&s);\r
- if(s.cx < d->r_n_label.right - d->r_n_label.left) {\r
+ if(s.cx < d->r_n_label.right - d->r_n_label.left &&\r
+ !use_large_lables) {\r
CopyRect(&pr, &d->r_n_label);\r
CopyRect(&er, &d->r_n_input);\r
dy = d->r_row.bottom;\r
- } else if(s.cx < \r
+ } else if(s.cx <\r
d->r_e_label.right - d->r_e_label.left) {\r
CopyRect(&pr, &d->r_e_label);\r
CopyRect(&er, &d->r_e_input);\r
KHMEXP void KHMAPI\r
khui_menu_remove_action(khui_menu_def * d, khm_size idx) {\r
\r
+ if (!(d->state & KHUI_MENUSTATE_ALLOCD))\r
+ menu_const_to_allocd(d);\r
+\r
assert(d->state & KHUI_MENUSTATE_ALLOCD);\r
\r
if (idx < 0 || idx >= d->n_items)\r
NULL,\r
0};\r
\r
+khm_int32 KHMAPI\r
+set_cred_select_flag(khm_handle cred, void * rock) {\r
+ kcdb_cred_set_flags(cred, KCDB_CRED_FLAG_SELECTED,\r
+ KCDB_CRED_FLAG_SELECTED);\r
+ return KHM_ERROR_SUCCESS;\r
+}\r
+\r
KHMEXP void KHMAPI\r
khui_context_create(khui_action_context * ctx,\r
khui_scope scope,\r
tctx.cred_type = cred_type;\r
tctx.cred = cred;\r
\r
+ /* fill up the credset based on the scope */\r
+ if (scope != KHUI_SCOPE_NONE) {\r
+ if (tctx.credset == NULL)\r
+ kcdb_credset_create(&tctx.credset);\r
+ else\r
+ kcdb_credset_flush(tctx.credset);\r
+\r
+ if (scope == KHUI_SCOPE_IDENT) {\r
+ kcdb_credset_extract(tctx.credset,\r
+ NULL,\r
+ tctx.identity,\r
+ KCDB_CREDTYPE_INVALID);\r
+ } else if (scope == KHUI_SCOPE_CREDTYPE) {\r
+ kcdb_credset_extract(tctx.credset,\r
+ NULL,\r
+ tctx.identity,\r
+ tctx.cred_type);\r
+ } else if (scope == KHUI_SCOPE_CRED) {\r
+ khm_handle dupcred = NULL;\r
+ kcdb_cred_dup(cred, &dupcred);\r
+\r
+ kcdb_credset_add_cred(tctx.credset, dupcred, -1);\r
+ } else {\r
+#ifdef DEBUG\r
+ /* KHUI_SCOPE_GROUP is not used with\r
+ khui_context_create() */\r
+ assert(FALSE);\r
+#endif\r
+ }\r
+\r
+ kcdb_credset_apply(tctx.credset, set_cred_select_flag,\r
+ NULL);\r
+\r
+ kcdb_credset_seal(tctx.credset);\r
+ }\r
+\r
khuiint_copy_context(ctx, &tctx);\r
}\r
\r
+++ /dev/null
-/*\r
- * Copyright (c) 2005 Massachusetts Institute of Technology\r
- *\r
- * Permission is hereby granted, free of charge, to any person\r
- * obtaining a copy of this software and associated documentation\r
- * files (the "Software"), to deal in the Software without\r
- * restriction, including without limitation the rights to use, copy,\r
- * modify, merge, publish, distribute, sublicense, and/or sell copies\r
- * of the Software, and to permit persons to whom the Software is\r
- * furnished to do so, subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be\r
- * included in all copies or substantial portions of the Software.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- * SOFTWARE.\r
- */\r
-\r
-/* $Id$ */\r
-\r
-#ifndef __KHIMAIRA_KHUIDEFS_H\r
-#define __KHIMAIRA_KHUIDEFS_H\r
-\r
-\r
-\r
-#endif\r