2 * Copyright (c) 2005,2006 Secure Endpoints Inc.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 #include<netidmgr_version.h>
32 #include<help/afsplhlp.h>
36 #define WMNC_AFS_UPDATE_ROWS (WMNC_USER + 1)
38 typedef struct tag_afs_ident_token_set {
42 khm_boolean update_info;
43 } afs_ident_token_set;
47 afs_cred_flush_rows(afs_cred_list * l) {
50 for(i=0; i<l->n_rows; i++) {
52 PFREE(l->rows[i].cell);
54 PFREE(l->rows[i].realm);
58 ZeroMemory(l->rows, sizeof(l->rows[0]) * l->nc_rows);
65 afs_cred_free_rows(afs_cred_list * l) {
67 afs_cred_flush_rows(l);
77 afs_cred_assert_rows(afs_cred_list * l, int n) {
81 l->nc_rows = UBOUNDSS(n, AFS_DLG_ROW_ALLOC, AFS_DLG_ROW_ALLOC);
82 rows = PMALLOC(sizeof(afs_cred_row) * l->nc_rows);
83 ZeroMemory(rows, sizeof(afs_cred_row) * l->nc_rows);
87 memcpy(rows, l->rows, sizeof(afs_cred_row) * l->n_rows);
95 afs_cred_delete_row(afs_cred_list * l, int i) {
96 if (i < 0 || i >= l->n_rows)
99 if(i < (l->n_rows - 1)) {
101 PFREE(l->rows[i].cell);
103 PFREE(l->rows[i].realm);
104 memmove(&(l->rows[i]),
106 ((l->n_rows - (i+1)) *
107 sizeof(l->rows[0])));
113 afs_cred_get_new_row(afs_cred_list * l) {
116 afs_cred_assert_rows(l, l->n_rows + 1);
117 r = &(l->rows[l->n_rows]);
120 ZeroMemory(r, sizeof(*r));
126 afs_cred_add_row_from_cred(afs_cred_list * l,
131 wchar_t cell[MAXCELLCHARS];
135 rv = kcdb_cred_get_attr(cred,
141 assert(rv == KHM_ERROR_SUCCESS && cb != 0);
144 /* check if we already have the cell listed. */
145 for (i=0; i<l->n_rows; i++) {
146 if (!_wcsicmp(l->rows[i].cell, cell))
150 row = afs_cred_get_new_row(l);
152 row->cell = PMALLOC(cb);
153 StringCbCopy(row->cell, cb, cell);
155 cb = sizeof(row->method);
156 rv = kcdb_cred_get_attr(cred,
162 if (KHM_FAILED(rv)) {
163 row->method = AFS_TOKEN_AUTO;
168 rv = kcdb_cred_get_attr(cred,
174 if (rv == KHM_ERROR_TOO_LONG && cb > sizeof(wchar_t)) {
175 row->realm = PMALLOC(cb);
179 rv = kcdb_cred_get_attr(cred,
185 if (KHM_FAILED(rv)) {
198 afs_cred_add_cred_proc(khm_handle cred, void * rock) {
199 afs_cred_list * l = (afs_cred_list *) rock;
202 if (KHM_FAILED(kcdb_cred_get_type(cred, &t)) ||
203 t != afs_credtype_id)
204 return KHM_ERROR_SUCCESS;
206 afs_cred_add_row_from_cred(l, cred);
208 return KHM_ERROR_SUCCESS;
212 afs_cred_get_context_creds(afs_cred_list *l,
213 khui_action_context * ctx) {
214 khm_handle credset = NULL;
216 if (KHM_FAILED(kcdb_credset_create(&credset)))
219 if (KHM_FAILED(kcdb_credset_extract_filtered(credset,
221 khui_context_cursor_filter,
225 kcdb_credset_apply(credset,
226 afs_cred_add_cred_proc,
231 kcdb_credset_delete(credset);
235 afs_get_id_creds_apply_proc(khm_handle cred, void * rock) {
237 afs_ident_token_set * ts;
240 wchar_t cell[MAXCELLCHARS];
243 khm_int32 cflags = 0;
245 ts = (afs_ident_token_set *) rock;
248 kcdb_cred_get_type(cred, &t);
249 if (t != afs_credtype_id)
250 return KHM_ERROR_SUCCESS;
253 if (KHM_FAILED(kcdb_cred_get_attr(cred, afs_attr_cell,
256 return KHM_ERROR_SUCCESS;
258 kcdb_cred_get_flags(cred, &cflags);
260 kcdb_cred_get_identity(cred, &ident);
262 if (kcdb_identity_is_equal(ident, ts->ident)) {
264 for (i=0; i < l->n_rows; i++) {
265 if (!_wcsicmp(l->rows[i].cell, cell)) {
268 /* if the token exists, then these are implied */
271 DLGROW_FLAG_CHECKED |
274 if (cflags & KCDB_CRED_FLAG_EXPIRED)
275 l->rows[i].flags |= DLGROW_FLAG_EXPIRED;
277 if (ts->update_info) {
278 wchar_t realm[KHUI_MAXCCH_NAME];
282 (kcdb_cred_get_attr(cred, afs_attr_method,
285 afs_is_valid_method_id(method))
286 l->rows[i].method = method;
290 (kcdb_cred_get_attr(cred, afs_attr_realm,
293 cb > sizeof(wchar_t)) {
295 if (l->rows[i].realm)
296 PFREE(l->rows[i].realm);
297 l->rows[i].realm = PMALLOC(cb);
298 StringCbCopy(l->rows[i].realm,
307 /* not found? add! */
308 if (i >= l->n_rows && ts->add_new) {
311 r = afs_cred_add_row_from_cred(l, cred);
313 r->flags = DLGROW_FLAG_VALID | DLGROW_FLAG_CHECKED |
316 if (cflags & KCDB_CRED_FLAG_EXPIRED)
317 r->flags |= DLGROW_FLAG_EXPIRED;
320 } else { /* different identities */
322 for (i=0; i < l->n_rows; i++) {
323 if (!_wcsicmp(l->rows[i].cell, cell)) {
325 DLGROW_FLAG_NOTOWNED | DLGROW_FLAG_EXISTS |
326 DLGROW_FLAG_VALID | DLGROW_FLAG_CHECKED;
327 if (cflags & KCDB_CRED_FLAG_EXPIRED)
328 l->rows[i].flags |= DLGROW_FLAG_EXPIRED;
334 kcdb_identity_release(ident);
336 return KHM_ERROR_SUCCESS;
340 afs_remove_token_from_identities(wchar_t * cell) {
341 wchar_t * idents = NULL;
347 if (kcdb_identity_enum(KCDB_IDENT_FLAG_CONFIG,
348 KCDB_IDENT_FLAG_CONFIG,
351 &n_id) != KHM_ERROR_TOO_LONG ||
360 idents = PMALLOC(cb_id);
362 if (kcdb_identity_enum(KCDB_IDENT_FLAG_CONFIG,
363 KCDB_IDENT_FLAG_CONFIG,
366 &n_id) == KHM_ERROR_SUCCESS)
372 t = multi_string_next(t)) {
374 khm_handle h_id = NULL;
375 khm_handle csp_ident = NULL;
376 khm_handle csp_afs = NULL;
379 wchar_t * tbuf = NULL;
380 khm_int32 enabled = 0;
382 kcdb_identity_create(t, 0, &h_id);
390 if (KHM_FAILED(kcdb_identity_get_config(h_id, 0, &csp_ident)))
393 if (KHM_FAILED(khc_open_space(csp_ident, CSNAME_AFSCRED,
397 if (KHM_SUCCEEDED(khc_read_int32(csp_afs, L"AFSEnabled", &enabled)) &&
401 if (khc_read_multi_string(csp_afs, L"Cells", NULL, &cb)
402 != KHM_ERROR_TOO_LONG)
405 if (cb < sizeof(vbuf))
410 if (khc_read_multi_string(csp_afs, L"Cells", tbuf, &cb)
411 != KHM_ERROR_SUCCESS)
414 if (multi_string_find(tbuf, cell, 0) == NULL)
417 multi_string_delete(tbuf, cell, 0);
419 khc_write_multi_string(csp_afs, L"Cells", tbuf);
422 kcdb_identity_release(h_id);
424 khc_close_space(csp_ident);
426 khc_close_space(csp_afs);
427 if (tbuf && tbuf != vbuf)
436 afs_check_add_token_to_identity(wchar_t * cell, khm_handle ident,
437 khm_handle * ident_conflict) {
438 wchar_t * idents = NULL;
442 khm_boolean ok_to_add = TRUE;
444 /* check if this cell is listed for any other identity. */
447 if (kcdb_identity_enum(KCDB_IDENT_FLAG_CONFIG,
448 KCDB_IDENT_FLAG_CONFIG,
451 &n_id) != KHM_ERROR_TOO_LONG ||
460 idents = PMALLOC(cb_id);
462 if (kcdb_identity_enum(KCDB_IDENT_FLAG_CONFIG,
463 KCDB_IDENT_FLAG_CONFIG,
466 &n_id) == KHM_ERROR_SUCCESS)
471 ok_to_add && t && *t;
472 t = multi_string_next(t)) {
474 khm_handle h_id = NULL;
475 khm_handle csp_ident = NULL;
476 khm_handle csp_afs = NULL;
479 wchar_t * tbuf = NULL;
480 khm_int32 enabled = 0;
482 kcdb_identity_create(t, 0, &h_id);
490 if (kcdb_identity_is_equal(h_id, ident)) {
491 kcdb_identity_release(h_id);
495 if (KHM_FAILED(kcdb_identity_get_config(h_id, 0, &csp_ident)))
498 if (KHM_FAILED(khc_open_space(csp_ident, CSNAME_AFSCRED,
502 if (KHM_SUCCEEDED(khc_read_int32(csp_afs, L"AFSEnabled", &enabled)) &&
506 if (khc_read_multi_string(csp_afs, L"Cells", NULL, &cb)
507 != KHM_ERROR_TOO_LONG)
510 if (cb < sizeof(vbuf))
515 if (khc_read_multi_string(csp_afs, L"Cells", tbuf, &cb)
516 != KHM_ERROR_SUCCESS)
519 if (multi_string_find(tbuf, cell, 0) == NULL)
522 /* we found another identity which gets tokens for the
527 if (ident_conflict) {
528 *ident_conflict = h_id;
529 kcdb_identity_hold(h_id);
533 kcdb_identity_release(h_id);
535 khc_close_space(csp_ident);
537 khc_close_space(csp_afs);
538 if (tbuf && tbuf != vbuf)
550 afs_cred_get_identity_creds(afs_cred_list * l,
552 khm_boolean * penabled) {
553 khm_handle h_id = NULL;
554 khm_handle h_afs = NULL;
555 khm_handle h_cells = NULL; /* per identity cells space */
556 khm_handle h_gcells = NULL; /* global cells space */
557 khm_boolean load_defs = TRUE;
561 afs_ident_token_set ts;
567 afs_cred_flush_rows(l);
569 kcdb_identity_get_config(ident, 0, &h_id);
573 if(KHM_FAILED(khc_open_space(h_id, CSNAME_AFSCRED,
579 if (KHM_FAILED(khc_read_int32(h_afs, L"AFSEnabled", &t)))
580 khc_read_int32(csp_params, L"AFSEnabled", &t);
584 if(KHM_FAILED(khc_open_space(h_afs, L"Cells",
588 if(khc_read_multi_string(h_afs, L"Cells", NULL, &cbi) !=
597 khc_read_multi_string(h_afs, L"Cells", ms, &cbi);
600 for(s = ms; s && *s; s = multi_string_next(s)) {
603 khm_handle h_cell = NULL;
605 /* is this a valid cell name? */
606 if(FAILED(StringCbLength(s, MAXCELLCHARS, &cb)))
608 cb += sizeof(wchar_t);
610 r = afs_cred_get_new_row(l);
612 r->cell = PMALLOC(cb);
613 StringCbCopy(r->cell, cb, s);
616 r->method = AFS_TOKEN_AUTO;
617 r->flags = DLGROW_FLAG_CONFIG;
619 if(KHM_SUCCEEDED(khc_open_space(h_cells, s,
622 wchar_t wname[KHUI_MAXCCH_NAME];
625 if(khc_read_string(h_cell, L"Realm",
627 KHM_ERROR_TOO_LONG &&
628 cbi > sizeof(wchar_t)) {
630 r->realm = PMALLOC(cbi);
631 khc_read_string(h_cell, L"Realm", r->realm, &cbi);
637 if (KHM_SUCCEEDED(khc_read_string(h_cell, L"MethodName",
640 r->method = afs_get_method_id(wname);
642 /* remove the deprecated value if it is present. */
643 khc_remove_value(h_cell, L"Method", 0);
645 } else if (KHM_SUCCEEDED(khc_read_int32(h_cell,
647 /* the Method property is deprecated. We detect and
648 correct this whenever possible. */
650 if (!afs_is_valid_method_id(i))
655 afs_get_method_name(i, wname, sizeof(wname));
657 khc_write_string(h_cell, L"MethodName",
660 khc_remove_value(h_cell, L"Method", 0);
663 khc_close_space(h_cell);
675 /* We want to load defaults */
676 char buf[MAXCELLCHARS];
677 wchar_t wbuf[MAXCELLCHARS];
678 wchar_t wmethod[KHUI_MAXCCH_NAME];
680 khm_size cb_defcells;
684 khc_open_space(csp_params, L"Cells", 0, &h_gcells);
686 if (!cm_GetRootCellName(buf) &&
687 afs_check_for_cell_realm_match(ident, buf)) {
688 AnsiStrToUnicode(wbuf, sizeof(wbuf), buf);
690 if (afs_check_add_token_to_identity(wbuf, ident, NULL)) {
691 khm_handle h_cell = NULL;
693 r = afs_cred_get_new_row(l);
695 StringCbLength(wbuf, sizeof(wbuf), &sz);
696 sz += sizeof(wchar_t);
698 r->cell = PMALLOC(sz);
699 StringCbCopy(r->cell, sz, wbuf);
702 KHM_SUCCEEDED(khc_open_space(h_gcells, wbuf, 0, &h_cell))) {
705 cb = sizeof(wmethod);
706 if (KHM_SUCCEEDED(khc_read_string(h_cell, L"MethodName", wmethod, &cb))) {
707 r->method = afs_get_method_id(wmethod);
709 r->method = AFS_TOKEN_AUTO;
713 if (KHM_SUCCEEDED(khc_read_string(h_cell, L"Realm", wbuf, &cb))) {
714 r->realm = PMALLOC(cb);
715 StringCbCopy(r->realm, cb, wbuf);
720 khc_close_space(h_cell);
724 r->method = AFS_TOKEN_AUTO;
731 if (khc_read_multi_string(csp_params, L"DefaultCells",
732 NULL, &cb_defcells) == KHM_ERROR_TOO_LONG &&
733 cb_defcells > sizeof(wchar_t) * 2) {
736 defcells = PMALLOC(cb_defcells);
737 if (defcells == NULL)
740 if (KHM_FAILED(khc_read_multi_string(csp_params, L"DefaultCells",
741 defcells, &cb_defcells))) {
746 for (c_cell = defcells;
748 c_cell = multi_string_next(c_cell)) {
752 khm_handle h_cell = NULL;
755 if (FAILED(StringCbLength(c_cell, (MAXCELLCHARS + 1) * sizeof(wchar_t),
758 cb += sizeof(wchar_t);
760 for (i=0; i < l->n_rows; i++) {
761 if (!_wcsicmp(l->rows[i].cell, c_cell))
769 char cell[MAXCELLCHARS];
771 UnicodeStrToAnsi(cell, sizeof(cell), c_cell);
773 if (!afs_check_for_cell_realm_match(ident, cell))
777 r = afs_cred_get_new_row(l);
779 r->cell = PMALLOC(cb);
780 StringCbCopy(r->cell, cb, c_cell);
783 KHM_SUCCEEDED(khc_open_space(h_gcells, c_cell, 0, &h_cell))) {
785 cb = sizeof(wmethod);
786 if (KHM_SUCCEEDED(khc_read_string(h_cell, L"MethodName", wmethod, &cb))) {
787 r->method = afs_get_method_id(wmethod);
789 r->method = AFS_TOKEN_AUTO;
793 if (KHM_SUCCEEDED(khc_read_string(h_cell, L"Realm", wbuf, &cb))) {
794 r->realm = PMALLOC(cb);
795 StringCbCopy(r->realm, cb, wbuf);
800 khc_close_space(h_cell);
803 r->method = AFS_TOKEN_AUTO;
818 ts.update_info = FALSE;
820 kcdb_credset_apply(NULL, afs_get_id_creds_apply_proc,
824 khc_close_space(h_id);
826 khc_close_space(h_afs);
828 khc_close_space(h_cells);
830 khc_close_space(h_gcells);
834 nc_dlg_enable(HWND hwnd, BOOL enable) {
836 SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN, BM_SETCHECK,
839 SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN, BM_SETCHECK,
843 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_CELL), enable);
844 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_REALM), enable);
845 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_METHOD), enable);
846 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_TOKENLIST), enable);
847 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_ADD_TOKEN), enable);
848 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_DELETE_TOKEN), enable);
852 nc_dlg_show_tooltip(HWND hwnd,
863 d = (afs_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
868 ZeroMemory(&ti, sizeof(ti));
869 ti.cbSize = sizeof(ti);
872 SendMessage(d->tooltip, TTM_GETTOOLINFO, 0, (LPARAM) &ti);
874 ti.hinst = hResModule;
877 SendMessage(d->tooltip, TTM_SETTOOLINFO, 0, (LPARAM) &ti);
879 if(IS_INTRESOURCE(title)) {
883 resid = (UINT)(UINT_PTR) title;
885 LoadString(hResModule, resid, wbuf, ARRAYLENGTH(wbuf));
886 SendMessage(d->tooltip, TTM_SETTITLE, type, (LPARAM) wbuf);
888 SendMessage(d->tooltip, TTM_SETTITLE, type, (LPARAM) title);
890 SendMessage(d->tooltip, TTM_TRACKACTIVATE, TRUE, (LPARAM) &ti);
891 SendMessage(d->tooltip, TTM_TRACKPOSITION, 0, (LPARAM) MAKELONG(x,y));
893 d->tooltip_visible = TRUE;
895 SetTimer(hwnd, DLG_TOOLTIP_TIMER_ID, DLG_TOOLTIP_TIMEOUT, NULL);
899 nc_dlg_hide_tooltip(HWND hwnd, UINT_PTR id)
904 d = (afs_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
909 if(!d->tooltip_visible)
912 ZeroMemory(&ti, sizeof(ti));
913 ti.cbSize = sizeof(ti);
917 SendMessage(d->tooltip, TTM_TRACKACTIVATE, FALSE, (LPARAM) &ti);
918 d->tooltip_visible = FALSE;
922 afs_dlg_update_rows(HWND hwnd, afs_dlg_data * d) {
928 CheckDlgButton(hwnd, IDC_NCAFS_OBTAIN,
929 (d->afs_enabled)? BST_CHECKED: BST_UNCHECKED);
931 hwlist = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
933 ListView_DeleteAllItems(hwlist);
935 if(d->creds.n_rows == 0)
938 LoadString(hResModule, IDS_NC_AUTO, wauto, ARRAYLENGTH(wauto));
940 for(i=0; i < d->creds.n_rows; i++) {
944 ZeroMemory(&lvi, sizeof(lvi));
946 lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
947 lvi.iItem = d->creds.n_rows + 1;
949 lvi.stateMask = LVIS_STATEIMAGEMASK;
950 flags = d->creds.rows[i].flags;
951 if ((flags & DLGROW_FLAG_EXISTS) &&
952 (flags & DLGROW_FLAG_NOTOWNED)) {
953 lvi.state = INDEXTOSTATEIMAGEMASK(d->idx_bad_token);
954 } else if ((flags & DLGROW_FLAG_EXISTS)) {
955 lvi.state = INDEXTOSTATEIMAGEMASK(d->idx_existing_token);
957 lvi.state = INDEXTOSTATEIMAGEMASK(d->idx_new_token);
960 lvi.lParam = (LPARAM) i;
962 lvi.iSubItem = NCAFS_IDX_CELL;
963 lvi.pszText = d->creds.rows[i].cell;
965 lvi.iItem = ListView_InsertItem(hwlist, &lvi);
967 lvi.mask = LVIF_TEXT; /* subitems dislike lParam */
968 lvi.iSubItem = NCAFS_IDX_REALM;
969 if(d->creds.rows[i].realm != NULL)
970 lvi.pszText = d->creds.rows[i].realm;
973 ListView_SetItem(hwlist, &lvi);
975 lvi.iSubItem = NCAFS_IDX_METHOD;
976 afs_method_describe(d->creds.rows[i].method,
981 ListView_SetItem(hwlist, &lvi);
986 nc_dlg_del_token(HWND hwnd) {
988 khui_new_creds_by_type * nct;
990 d = (afs_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
996 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
998 if(ListView_GetSelectedCount(GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST)) == 0) {
999 wchar_t cell[KCDB_MAXCCH_NAME];
1002 /* nothing is selected in the list view */
1003 /* we delete the row that matches the current contents of the
1004 cell edit control */
1006 GetDlgItemText(hwnd, IDC_NCAFS_CELL, cell, ARRAYLENGTH(cell));
1007 for(i=0; i<d->creds.n_rows; i++) {
1008 if(!_wcsicmp(d->creds.rows[i].cell, cell)) {
1010 afs_cred_delete_row(&d->creds, i);
1011 afs_dlg_update_rows(hwnd, d);
1017 /* something is selected in the token list view */
1018 /* we delete that */
1023 BOOL deleted = FALSE;
1025 hw = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
1028 idx = ListView_GetNextItem(hw, idx, LVNI_SELECTED);
1030 ZeroMemory(&lvi, sizeof(lvi));
1033 lvi.mask = LVIF_PARAM;
1034 if(!ListView_GetItem(hw, &lvi))
1036 row = (int) lvi.lParam;
1037 if(row >= 0 && row < d->creds.n_rows) {
1038 d->creds.rows[row].flags |= DLGROW_FLAG_DELETED;
1045 for(idx = 0; idx < d->creds.n_rows; idx ++) {
1046 if(d->creds.rows[idx].flags & DLGROW_FLAG_DELETED) {
1047 afs_cred_delete_row(&d->creds, idx);
1048 idx--; /* we have to look at the current item again */
1053 afs_dlg_update_rows(hwnd, d);
1058 SendMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
1059 MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
1060 else if (d->config_dlg && d->dirty)
1061 khui_cfg_set_flags_inst(&d->cfg, KHUI_CNFLAG_MODIFIED,
1062 KHUI_CNFLAG_MODIFIED);
1066 nc_dlg_add_token(HWND hwnd) {
1068 afs_cred_row * prow;
1070 khui_new_creds_by_type * nct;
1076 BOOL new_row = FALSE;
1077 khm_handle ident = NULL;
1079 d = (afs_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
1085 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1089 if((n = SendDlgItemMessage(hwnd, IDC_NCAFS_CELL, WM_GETTEXT,
1090 (WPARAM) ARRAYLENGTH(buf), (LPARAM) buf))
1093 /* probably should indicate that user should type something */
1095 GetWindowRect(GetDlgItem(hwnd, IDC_NCAFS_CELL), &r);
1096 nc_dlg_show_tooltip(hwnd,
1098 MAKEINTRESOURCE(IDS_NC_TT_NO_CELL),
1099 MAKEINTRESOURCE(IDS_NC_TT_CANT_ADD),
1100 2, (r.left + r.right)/ 2, r.bottom);
1104 if(n != wcsspn(buf, AFS_VALID_CELL_CHARS)) {
1106 GetWindowRect(GetDlgItem(hwnd, IDC_NCAFS_CELL), &r);
1107 nc_dlg_show_tooltip(hwnd,
1109 MAKEINTRESOURCE(IDS_NC_TT_MALFORMED_CELL),
1110 MAKEINTRESOURCE(IDS_NC_TT_CANT_ADD),
1111 2, (r.left + r.right)/2, r.bottom);
1115 /* check if this is already listed */
1116 for(i=0;i<d->creds.n_rows;i++) {
1117 if(!_wcsicmp(buf, d->creds.rows[i].cell))
1121 if(i < d->creds.n_rows) {
1124 prow = &(d->creds.rows[i]);
1130 ZeroMemory(&trow, sizeof(trow));
1132 cb = (n+1) * sizeof(wchar_t);
1133 trow.cell = PMALLOC(cb);
1134 StringCbCopy(trow.cell, cb, buf);
1136 /* now for the realm */
1138 idx = (int) SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1139 CB_GETCURSEL, 0, 0);
1142 lp = (int) SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1143 CB_GETITEMDATA, idx, 0);
1144 if(lp != CB_ERR && lp) /* this is the 'determine realm
1145 automatically' item */
1152 if((n = SendDlgItemMessage(hwnd, IDC_NCAFS_REALM, WM_GETTEXT,
1153 ARRAYLENGTH(buf), (LPARAM) buf)) == 0) {
1155 GetWindowRect(GetDlgItem(hwnd, IDC_NCAFS_REALM), &r);
1156 nc_dlg_show_tooltip(hwnd,
1158 MAKEINTRESOURCE(IDS_NC_TT_NO_REALM),
1159 MAKEINTRESOURCE((new_row)?
1161 IDS_NC_TT_CANT_UPDATE),
1162 2, (r.left + r.right)/2, r.bottom);
1166 if(n != wcsspn(buf, AFS_VALID_REALM_CHARS)) {
1168 GetWindowRect(GetDlgItem(hwnd, IDC_NCAFS_REALM), &r);
1169 nc_dlg_show_tooltip(hwnd,
1171 MAKEINTRESOURCE(IDS_NC_TT_MALFORMED_REALM),
1172 MAKEINTRESOURCE((new_row)?
1174 IDS_NC_TT_CANT_UPDATE),
1175 2, (r.left + r.right)/2, r.bottom);
1179 cb = (n+1) * sizeof(wchar_t);
1180 trow.realm = PMALLOC(cb);
1181 StringCbCopy(trow.realm, cb, buf);
1185 idx = (int)SendDlgItemMessage(hwnd, IDC_NCAFS_METHOD,
1186 CB_GETCURSEL, 0, 0);
1187 if (idx != CB_ERR) {
1188 trow.method = (afs_tk_method)
1189 SendDlgItemMessage(hwnd, IDC_NCAFS_METHOD, CB_GETITEMDATA,
1192 trow.method = AFS_TOKEN_AUTO;
1196 d->nc->n_identities > 0 &&
1197 d->nc->identities[0]) {
1199 ident = d->nc->identities[0];
1201 } else if (d->ident) {
1208 khm_boolean ok_to_add = TRUE;
1211 khm_handle id_conf = NULL;
1214 afs_check_add_token_to_identity(trow.cell,
1219 #if KH_VERSION_API >= 5
1223 wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
1229 khui_alert_create_empty(&a);
1231 cb = sizeof(widname);
1232 kcdb_identity_get_name(id_conf, widname, &cb);
1234 LoadString(hResModule, IDS_NC_TT_CONFLICT,
1235 wfmt, ARRAYLENGTH(wfmt));
1236 StringCbPrintf(wbuf, sizeof(wbuf),
1237 wfmt, trow.cell, widname);
1238 khui_alert_set_message(a, wbuf);
1240 LoadString(hResModule, IDS_NC_TT_PROBLEM,
1241 wbuf, ARRAYLENGTH(wbuf));
1242 khui_alert_set_title(a, wbuf);
1244 khui_alert_add_command(a, KHUI_PACTION_KEEP);
1245 khui_alert_add_command(a, KHUI_PACTION_REMOVE);
1246 khui_alert_add_command(a, KHUI_PACTION_CANCEL);
1248 khui_alert_set_severity(a, KHERR_INFO);
1250 khui_alert_show_modal(a);
1254 if (a->response == KHUI_PACTION_REMOVE) {
1255 afs_remove_token_from_identities(trow.cell);
1256 } else if (a->response == KHUI_PACTION_CANCEL) {
1260 khui_alert_release(a);
1262 wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
1273 cb = sizeof(widname);
1274 kcdb_identity_get_name(id_conf, widname, &cb);
1275 LoadString(hResModule, IDS_NC_TT_PROBLEM,
1276 wtitle, ARRAYLENGTH(wtitle));
1277 LoadString(hResModule, IDS_NC_TT_CONFLICTM,
1278 wfmt, ARRAYLENGTH(wfmt));
1279 StringCbPrintf(wmsg, sizeof(wmsg), wfmt,
1280 trow.cell, widname);
1281 r = MessageBox(NULL, wmsg, wtitle,
1282 MB_YESNOCANCEL | MB_ICONWARNING |
1287 afs_remove_token_from_identities(trow.cell);
1288 } else if (r == IDCANCEL) {
1293 kcdb_identity_release(id_conf);
1300 prow = afs_cred_get_new_row(&d->creds);
1308 ZeroMemory(prow, sizeof(*prow));
1314 afs_ident_token_set ts;
1319 ts.update_info = FALSE;
1321 kcdb_credset_apply(NULL, afs_get_id_creds_apply_proc,
1325 afs_dlg_update_rows(hwnd, d);
1330 SendMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
1331 MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
1332 else if (d->config_dlg) {
1333 khui_cfg_set_flags_inst(&d->cfg,
1334 KHUI_CNFLAG_MODIFIED,
1335 KHUI_CNFLAG_MODIFIED);
1347 /* this is shared between the new credentials window and the AFS per
1348 identity configuration dialog. */
1350 afs_dlg_proc(HWND hwnd,
1359 HIMAGELIST hw_ilist;
1361 khui_new_creds_by_type * nct = NULL;
1364 d = PMALLOC(sizeof(*d));
1365 ZeroMemory(d, sizeof(*d));
1367 InitializeCriticalSection(&d->cs);
1369 /* lParam is a pointer to a khui_new_creds structure */
1370 d->nc = (khui_new_creds *) lParam;
1373 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1375 #pragma warning(push)
1376 #pragma warning(disable: 4244)
1377 SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) d);
1378 #pragma warning(pop)
1380 EnterCriticalSection(&d->cs);
1383 nct->aux = (LPARAM) d;
1385 /* create the tooltip window */
1387 CreateWindowEx(WS_EX_TOPMOST,
1390 WS_POPUP | TTS_BALLOON | TTS_ALWAYSTIP,
1391 CW_USEDEFAULT, CW_USEDEFAULT,
1392 CW_USEDEFAULT, CW_USEDEFAULT,
1393 hwnd, /* make this an owned window, so
1394 we don't have to worry about
1400 SetWindowPos(d->tooltip,
1406 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
1411 ZeroMemory(&ti, sizeof(ti));
1412 ti.cbSize = sizeof(ti);
1413 ti.uFlags = TTF_TRACK;
1416 ti.hinst = hResModule;
1418 GetClientRect(hwnd, &(ti.rect));
1420 SendMessage(d->tooltip, TTM_ADDTOOL, 0, (LPARAM) &ti);
1423 /* we only initialize the constant bits here. */
1424 hw = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
1426 GetClientRect(hw, &r);
1428 /* set the list view status icons */
1429 hw_ilist = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
1430 GetSystemMetrics(SM_CYSMICON),
1431 ILC_COLOR8 | ILC_MASK,
1439 hi = LoadImage(hResModule, MAKEINTRESOURCE(IDI_NC_NEW),
1441 GetSystemMetrics(SM_CXSMICON),
1442 GetSystemMetrics(SM_CYSMICON),
1445 d->idx_new_token = ImageList_AddIcon(hw_ilist, hi) + 1;
1449 hi = LoadImage(hResModule, MAKEINTRESOURCE(IDI_NC_EXIST),
1451 GetSystemMetrics(SM_CXSMICON),
1452 GetSystemMetrics(SM_CYSMICON),
1454 d->idx_existing_token = ImageList_AddIcon(hw_ilist, hi) + 1;
1458 hi = LoadImage(hResModule,
1459 MAKEINTRESOURCE(IDI_NC_NOTOWNED),
1461 GetSystemMetrics(SM_CXSMICON),
1462 GetSystemMetrics(SM_CYSMICON),
1464 d->idx_bad_token = ImageList_AddIcon(hw_ilist, hi) + 1 ;
1469 ListView_SetImageList(hw, hw_ilist, LVSIL_STATE);
1471 ListView_DeleteAllItems(hw);
1473 /* set the columns */
1478 lc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
1479 lc.fmt = LVCFMT_LEFT;
1480 lc.cx = ((r.right - r.left) * 2) / 5;
1481 LoadString(hResModule, IDS_NCAFS_COL_CELL,
1482 wbuf, ARRAYLENGTH(wbuf));
1485 ListView_InsertColumn(hw, 0, &lc);
1487 lc.mask |= LVCF_SUBITEM;
1488 //lc.cx is the same as above
1489 lc.iSubItem = NCAFS_IDX_REALM;
1490 LoadString(hResModule, IDS_NCAFS_COL_REALM,
1491 wbuf, ARRAYLENGTH(wbuf));
1493 ListView_InsertColumn(hw, 1, &lc);
1495 lc.cx = ((r.right - r.left) * 1) / 5;
1496 lc.iSubItem = NCAFS_IDX_METHOD;
1497 LoadString(hResModule, IDS_NCAFS_COL_METHOD,
1498 wbuf, ARRAYLENGTH(wbuf));
1500 ListView_InsertColumn(hw, 2, &lc);
1503 /* Set the items for the 'method' combo box */
1504 hw = GetDlgItem(hwnd, IDC_NCAFS_METHOD);
1507 wchar_t wbuf[KHUI_MAXCB_SHORT_DESC];
1508 afs_tk_method method = -1;
1511 SendMessage(hw, CB_RESETCONTENT, 0, 0);
1513 while((method = afs_get_next_method_id(method)) >= 0) {
1514 afs_method_describe(method, KCDB_TS_SHORT,
1515 wbuf, sizeof(wbuf));
1516 idx = (int)SendMessage(hw, CB_INSERTSTRING,
1517 (WPARAM) -1, (LPARAM) wbuf);
1519 assert(idx != CB_ERR);
1521 SendMessage(hw, CB_SETITEMDATA, (WPARAM) idx,
1525 /* finally, set the current selection to auto, which
1526 is the first method returned by
1527 afs_get_next_method_id() */
1528 SendMessage(hw, CB_SETCURSEL, 0, 0);
1531 d->afs_enabled = TRUE;
1532 SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN,
1533 BM_SETCHECK, BST_CHECKED, 0);
1535 LeaveCriticalSection(&d->cs);
1537 /* the cells and realms combo boxes need to be filled
1538 in the plugin thread since that requires making
1539 potentially blocking and non-thread safe calls */
1546 khui_new_creds_by_type * nct;
1548 d = (afs_dlg_data *)(LONG_PTR)
1549 GetWindowLongPtr(hwnd, DWLP_USER);
1554 EnterCriticalSection(&d->cs);
1557 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1559 nct->aux = (LPARAM) NULL;
1562 afs_cred_free_rows(&d->creds);
1564 LeaveCriticalSection(&d->cs);
1565 DeleteCriticalSection(&d->cs);
1569 SetWindowLongPtr(hwnd, DWLP_USER, 0);
1576 khui_new_creds_by_type * nct;
1578 d = (afs_dlg_data *)(LONG_PTR)
1579 GetWindowLongPtr(hwnd, DWLP_USER);
1584 EnterCriticalSection(&d->cs);
1587 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1591 nc_dlg_hide_tooltip(hwnd, 0);
1593 /* Handle WM_COMMAND */
1595 case MAKEWPARAM(IDC_NCAFS_OBTAIN, BN_CLICKED):
1598 c = (SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN,
1604 khui_cw_enable_type(d->nc, afs_credtype_id, c);
1605 else if (d->config_dlg)
1606 khui_cfg_set_flags_inst(&d->cfg,
1607 KHUI_CNFLAG_MODIFIED,
1608 KHUI_CNFLAG_MODIFIED);
1609 nc_dlg_enable(hwnd, c);
1613 case MAKEWPARAM(IDC_NCAFS_ADD_TOKEN, BN_CLICKED):
1615 nc_dlg_add_token(hwnd);
1619 case MAKEWPARAM(IDC_NCAFS_DELETE_TOKEN, BN_CLICKED):
1621 nc_dlg_del_token(hwnd);
1626 LeaveCriticalSection(&d->cs);
1630 case KHUI_WM_NC_NOTIFY:
1633 khui_new_creds_by_type * nct;
1635 d = (afs_dlg_data *)(LONG_PTR)
1636 GetWindowLongPtr(hwnd, DWLP_USER);
1641 EnterCriticalSection(&d->cs);
1644 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1648 switch(HIWORD(wParam)) {
1649 case WMNC_DIALOG_SETUP:
1651 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL,
1652 CB_RESETCONTENT, 0, 0);
1654 /* load the LRU cells */
1660 if(khc_read_multi_string(csp_params, L"LRUCells",
1662 KHM_ERROR_TOO_LONG) {
1663 buf = PMALLOC(cbbuf);
1664 khc_read_multi_string(csp_params, L"LRUCells",
1668 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL,
1669 CB_ADDSTRING, 0, (LPARAM) s);
1676 /* now, if the root cell is not in the LRU, add it */
1681 if(!cm_GetRootCellName(buf)) {
1682 AnsiStrToUnicode(wbuf, sizeof(wbuf), buf);
1683 if(SendDlgItemMessage(hwnd,
1687 (LPARAM) wbuf) == CB_ERR) {
1688 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL,
1692 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL,
1694 (WPARAM)-1, (LPARAM) wbuf);
1698 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1699 CB_RESETCONTENT, 0, 0);
1701 /* as for the realms, we have a special one here */
1706 LoadString(hResModule, IDS_NC_REALM_AUTO, wbuf,
1707 (int) ARRAYLENGTH(wbuf));
1708 idx = (int) SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1711 /* item data for the realm strings is the
1712 answer to the question, "is this the
1713 'determine realm automatically' item?" */
1714 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1715 CB_SETITEMDATA, idx, TRUE);
1716 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1718 (WPARAM)-1, (LPARAM) wbuf);
1721 /* load the LRU realms */
1728 if(khc_read_multi_string(csp_params, L"LRURealms",
1730 KHM_ERROR_TOO_LONG) {
1731 buf = PMALLOC(cbbuf);
1732 khc_read_multi_string(csp_params, L"LRURealms",
1736 if(SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1739 (LPARAM) s) == CB_ERR) {
1742 SendDlgItemMessage(hwnd,
1746 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1758 khui_cw_enable_type(d->nc, afs_credtype_id,
1761 nc_dlg_enable(hwnd, d->afs_enabled);
1763 afs_dlg_update_rows(hwnd, d);
1767 case WMNC_UPDATE_CREDTEXT:
1769 wchar_t wformat[256];
1774 PFREE(nct->credtext);
1775 nct->credtext = NULL;
1782 if (d->nc->n_identities == 0 ||
1783 KHM_FAILED(kcdb_identity_get_flags(d->nc->identities[0],
1785 !(flags & KCDB_IDENT_FLAG_VALID))
1786 /* in this case, we don't show any credential text */
1791 if(!d->afs_enabled) {
1792 LoadString(hResModule, IDS_AFS_CREDTEXT_DIS,
1793 wstr, ARRAYLENGTH(wstr));
1795 if(d->creds.n_rows == 0) {
1796 LoadString(hResModule, IDS_AFS_CREDTEXT_0,
1797 wstr, ARRAYLENGTH(wstr));
1798 } else if(d->creds.n_rows == 1) {
1799 LoadString(hResModule, IDS_AFS_CREDTEXT_1,
1800 wformat, ARRAYLENGTH(wformat));
1801 StringCbPrintf(wstr, sizeof(wstr), wformat,
1802 d->creds.rows[0].cell);
1805 wchar_t wcells[1024];
1807 LoadString(hResModule, IDS_AFS_CREDTEXT_N,
1808 wformat, ARRAYLENGTH(wformat));
1810 for(i=0; i<d->creds.n_rows; i++) {
1812 StringCbCat(wcells, sizeof(wcells),
1814 if(FAILED(StringCbCat(wcells,
1816 d->creds.rows[i].cell))) {
1818 /* looks like we overflowed */
1819 /* add an ellipsis at the end */
1820 StringCchLength(wcells, ARRAYLENGTH(wcells), &cch);
1821 cch = min(ARRAYLENGTH(wcells) - 4, cch);
1822 StringCchCopy(wcells + cch, 4, L"...");
1828 StringCbPrintf(wstr, sizeof(wstr), wformat, wcells);
1834 StringCbLength(wstr, sizeof(wstr), &cbs);
1835 cbs += sizeof(wchar_t);
1836 assert(nct->credtext == NULL);
1837 nct->credtext = PMALLOC(cbs);
1838 StringCbCopy(nct->credtext, cbs, wstr);
1840 /* something went wrong */
1841 nct->credtext = NULL;
1846 case WMNC_CREDTEXT_LINK:
1848 khui_htwnd_link * l;
1849 wchar_t wid[KHUI_MAXCCH_HTLINK_FIELD];
1852 l = (khui_htwnd_link *) lParam;
1854 StringCchCopyN(wid, ARRAYLENGTH(wid), l->id, l->id_len);
1855 wids = wcschr(wid, L':');
1866 if(!wcscmp(wids, L"Enable")) {
1867 SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN,
1868 BM_SETCHECK, BST_CHECKED, 0);
1869 d->afs_enabled = TRUE;
1870 khui_cw_enable_type(d->nc, afs_credtype_id, TRUE);
1871 nc_dlg_enable(hwnd, TRUE);
1876 case WMNC_IDENTITY_CHANGE:
1877 kmq_post_sub_msg(afs_sub, KMSG_CRED,
1878 KMSG_CRED_DIALOG_NEW_IDENTITY, 0,
1882 case WMNC_AFS_UPDATE_ROWS:
1883 afs_dlg_update_rows(hwnd, d);
1889 PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
1890 MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
1894 LeaveCriticalSection(&d->cs);
1899 if(wParam == IDC_NCAFS_TOKENLIST) {
1900 LPNMHDR lpnmh = (LPNMHDR) lParam;
1902 if(lpnmh->code == LVN_ITEMCHANGED) {
1903 /* when an item in the list view is clicked, we
1904 load the corresponding values into the edit and
1906 NMLISTVIEW *lpnmlv = (NMLISTVIEW *) lpnmh;
1913 if (!(lpnmlv->uChanged & LVIF_STATE) ||
1914 !(lpnmlv->uNewState & LVIS_SELECTED) ||
1915 (lpnmlv->iItem == -1))
1919 d = (afs_dlg_data *)(LONG_PTR)
1920 GetWindowLongPtr(hwnd, DWLP_USER);
1925 EnterCriticalSection(&d->cs);
1927 hw = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
1929 idx = lpnmlv->iItem;
1931 ZeroMemory(&lvi, sizeof(lvi));
1934 lvi.mask = LVIF_PARAM;
1936 if(!ListView_GetItem(hw, &lvi))
1937 goto _done_notify_select;
1939 /* ok, now lvi.lParam should be the row of the token */
1940 row = (int) lvi.lParam;
1941 if(row < 0 || row >= d->creds.n_rows)
1942 goto _done_notify_select;
1944 SetDlgItemText(hwnd, IDC_NCAFS_CELL,
1945 d->creds.rows[row].cell);
1946 if(d->creds.rows[row].realm != NULL) {
1947 SetDlgItemText(hwnd, IDC_NCAFS_REALM,
1948 d->creds.rows[row].realm);
1953 LoadString(hResModule, IDS_NC_REALM_AUTO, wbuf,
1955 idx = (int) SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1959 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM, CB_SETCURSEL,
1962 SendDlgItemMessage(hwnd, IDC_NCAFS_METHOD, CB_SETCURSEL,
1963 d->creds.rows[row].method, 0);
1964 _done_notify_select:
1965 LeaveCriticalSection(&d->cs);
1967 } else if (lpnmh->code == NM_DBLCLK) {
1969 LPNMITEMACTIVATE pnmi;
1977 d = (afs_dlg_data *)(LONG_PTR)
1978 GetWindowLongPtr(hwnd, DWLP_USER);
1983 EnterCriticalSection(&d->cs);
1985 pnmi = (LPNMITEMACTIVATE) lpnmh;
1987 hw = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
1989 ZeroMemory(&lvi, sizeof(lvi));
1990 lvi.iItem = pnmi->iItem;
1992 lvi.mask = LVIF_PARAM;
1994 if (!ListView_GetItem(hw, &lvi))
1995 goto _done_notify_click;
1997 row = (int) lvi.lParam;
1998 if(row < 0 || row >= d->creds.n_rows)
1999 goto _done_notify_click;
2001 ListView_GetItemRect(hw, pnmi->iItem, &r, LVIR_SELECTBOUNDS);
2002 x = (r.left + r.right) / 2;
2005 GetWindowRect(hw, &r);
2009 if (d->creds.rows[row].flags & DLGROW_FLAG_NOTOWNED) {
2010 nc_dlg_show_tooltip(hwnd, 0,
2011 MAKEINTRESOURCE(IDS_NC_TT_CONFLICTD),
2012 MAKEINTRESOURCE(IDS_NC_TT_PROBLEM),
2015 } else if (d->creds.rows[row].flags &
2016 DLGROW_FLAG_EXPIRED) {
2017 nc_dlg_show_tooltip(hwnd, 0,
2018 MAKEINTRESOURCE(IDS_NC_TT_EXPIRED),
2019 MAKEINTRESOURCE(IDS_NC_TT_DETAILS),
2022 } else if (d->creds.rows[row].flags &
2023 DLGROW_FLAG_EXISTS) {
2024 nc_dlg_show_tooltip(hwnd, 0,
2025 MAKEINTRESOURCE(IDS_NC_TT_EXISTS),
2026 MAKEINTRESOURCE(IDS_NC_TT_DETAILS),
2029 nc_dlg_show_tooltip(hwnd, 0,
2030 MAKEINTRESOURCE(IDS_NC_TT_NEW),
2031 MAKEINTRESOURCE(IDS_NC_TT_DETAILS),
2036 LeaveCriticalSection(&d->cs);
2043 if(wParam == DLG_TOOLTIP_TIMER_ID) {
2044 KillTimer(hwnd, DLG_TOOLTIP_TIMER_ID);
2045 nc_dlg_hide_tooltip(hwnd, 0);
2052 static const DWORD ctx_help[] = {
2053 IDC_NCAFS_OBTAIN, IDH_OBTAIN,
2054 IDC_NCAFS_CELL, IDH_CELL,
2055 IDC_NCAFS_REALM, IDH_REALM,
2056 IDC_NCAFS_METHOD, IDH_METHOD,
2057 IDC_NCAFS_ADD_TOKEN, IDH_ADD,
2058 IDC_NCAFS_DELETE_TOKEN, IDH_DELETE,
2059 IDC_NCAFS_TOKENLIST, IDH_TOKENLIST,
2065 hlp = (LPHELPINFO) lParam;
2067 if (hlp->iContextType != HELPINFO_WINDOW)
2070 afs_html_help(hlp->hItemHandle, L"::/popups_newcred.txt",
2071 HH_TP_HELP_WM_HELP, (DWORD_PTR) ctx_help);
2074 } /* switch(uMsg) */
2080 /* passed in to kcdb_credset_apply along with the afs_credset to adjust
2081 newly acquired credentials to include informatino derived from the
2082 new creds operation */
2084 afs_adjust_token_ident_proc(khm_handle cred, void * vd)
2086 wchar_t cell[MAXCELLCHARS];
2087 afs_ident_token_set * b = (afs_ident_token_set *) vd;
2094 /* ASSUMPTION: for each user, there can be tokens for only one
2097 cbbuf = sizeof(cell);
2099 if(KHM_FAILED(kcdb_cred_get_attr(cred, afs_attr_cell, NULL, cell, &cbbuf)))
2100 return KHM_ERROR_SUCCESS; /* remember, kcdb doesn't care if
2101 this run succeeded or not. all
2102 it wants to know if whether or
2103 not we want to continue the
2106 for(i=0; i<l->n_rows; i++) {
2107 if((l->rows[i].flags & DLGROW_FLAG_DONE) &&
2108 !_wcsicmp(cell, l->rows[i].cell)) {
2111 kcdb_cred_set_identity(cred, b->ident);
2112 if(l->rows[i].realm)
2113 kcdb_cred_set_attr(cred, afs_attr_realm, l->rows[i].realm,
2114 (khm_size)KCDB_CBSIZE_AUTO);
2116 kcdb_cred_set_attr(cred, afs_attr_realm, NULL, 0);
2118 method = l->rows[i].method;
2119 kcdb_cred_set_attr(cred, afs_attr_method, &method,
2120 (khm_size)KCDB_CBSIZE_AUTO);
2126 return KHM_ERROR_SUCCESS;
2130 afs_cred_write_ident_data(afs_dlg_data * d) {
2131 wchar_t * lru_cell = NULL;
2132 wchar_t * lru_realm = NULL;
2133 wchar_t * id_cell = NULL;
2139 khm_handle h_idc = NULL;
2140 khm_handle h_afs = NULL;
2141 khm_handle h_acells = NULL;
2142 khm_handle h_cellmap = NULL;
2143 wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
2144 khm_handle ident = NULL;
2151 d->nc->n_identities > 0 &&
2152 d->nc->identities[0])
2154 ident = d->nc->identities[0];
2156 else if (d->config_dlg)
2163 cbt = sizeof(idname);
2164 kcdb_identity_get_name(ident, idname, &cbt);
2166 khc_open_space(csp_afscred, L"Cells", 0, &h_cellmap);
2169 if(KHM_SUCCEEDED(kcdb_identity_get_config(ident,
2172 khc_open_space(h_idc, CSNAME_AFSCRED,
2173 KHM_FLAG_CREATE, &h_afs);
2177 khc_open_space(h_afs, L"Cells", KHM_FLAG_CREATE,
2183 khc_write_int32(h_afs, L"AFSEnabled",
2187 if(khc_read_multi_string(csp_params,
2190 &cbcell) == KHM_ERROR_TOO_LONG) {
2191 cbcell += MAXCELLCHARS * sizeof(wchar_t) *
2193 lru_cell = PMALLOC(cbcell);
2194 ZeroMemory(lru_cell, cbcell);
2197 khc_read_multi_string(csp_params,
2202 cbcell = MAXCELLCHARS * sizeof(wchar_t) * l->n_rows + sizeof(wchar_t);
2203 if (l->n_rows > 0) {
2204 lru_cell = PMALLOC(cbcell);
2205 ZeroMemory(lru_cell, cbcell);
2212 if(khc_read_multi_string(csp_params,
2215 &cbrealm) == KHM_ERROR_TOO_LONG) {
2216 cbrealm += MAXCELLCHARS * sizeof(wchar_t) * l->n_rows;
2217 lru_realm = PMALLOC(cbrealm);
2218 ZeroMemory(lru_realm, cbrealm);
2221 khc_read_multi_string(csp_params,
2226 cbrealm = MAXCELLCHARS * sizeof(wchar_t) * l->n_rows + sizeof(wchar_t);
2227 if (l->n_rows > 0) {
2228 lru_realm = PMALLOC(cbrealm);
2229 ZeroMemory(lru_realm, cbrealm);
2236 cbidcell = MAXCELLCHARS * sizeof(wchar_t) * l->n_rows + sizeof(wchar_t);
2237 if (l->n_rows > 0) {
2238 id_cell = PMALLOC(cbidcell);
2239 ZeroMemory(id_cell, cbidcell);
2245 for(i=0; i < l->n_rows; i++)
2246 if(!(l->rows[i].flags & DLGROW_FLAG_DELETED)) {
2247 khm_handle h_acell = NULL;
2249 if(!multi_string_find(lru_cell,
2250 l->rows[i].cell, 0)) {
2252 multi_string_append(lru_cell, &cbz,
2256 if(l->rows[i].realm &&
2257 !multi_string_find(lru_realm,
2258 l->rows[i].realm, 0)) {
2260 multi_string_append(lru_realm, &cbz,
2265 multi_string_append(id_cell, &cbz,
2269 KHM_SUCCEEDED(khc_open_space(h_acells,
2273 wchar_t methodname[KHUI_MAXCCH_NAME];
2275 afs_get_method_name(l->rows[i].method,
2277 sizeof(methodname));
2279 khc_write_string(h_acell, L"MethodName",
2282 if(l->rows[i].realm)
2283 khc_write_string(h_acell, L"Realm",
2286 khc_write_string(h_acell, L"Realm", L"");
2287 khc_close_space(h_acell);
2290 if (l->rows[i].flags & DLGROW_FLAG_DONE) {
2292 khc_write_string(h_cellmap,
2300 khc_write_multi_string(csp_params,
2301 L"LRUCells", lru_cell);
2303 khc_write_multi_string(csp_params,
2304 L"LRURealms", lru_realm);
2306 khc_write_multi_string(h_afs, L"Cells",
2309 khc_write_multi_string(h_afs, L"Cells", L"\0");
2311 if (d->config_dlg) {
2313 khui_cfg_set_flags_inst(&d->cfg, KHUI_CNFLAG_APPLIED,
2314 KHUI_CNFLAG_APPLIED |
2315 KHUI_CNFLAG_MODIFIED);
2317 khui_cfg_set_flags_inst(&d->cfg, 0,
2318 KHUI_CNFLAG_MODIFIED);
2324 khc_close_space(h_cellmap);
2326 khc_close_space(h_idc);
2328 khc_close_space(h_afs);
2330 khc_close_space(h_acells);
2340 afs_msg_newcred(khm_int32 msg_subtype,
2344 switch(msg_subtype) {
2345 case KMSG_CRED_NEW_CREDS:
2347 khui_new_creds * nc;
2348 khui_new_creds_by_type * nct;
2352 nc = (khui_new_creds *) vparam;
2354 nct = PMALLOC(sizeof(*nct));
2355 ZeroMemory(nct, sizeof(*nct));
2357 nct->type = afs_credtype_id;
2360 LoadString(hResModule, IDS_AFS_NAME, wbuf, ARRAYLENGTH(wbuf));
2361 StringCbLength(wbuf, sizeof(wbuf), &cbsize);
2362 cbsize += sizeof(wchar_t);
2364 nct->name = PMALLOC(cbsize);
2365 StringCbCopy(nct->name, cbsize, wbuf);
2367 nct->h_module = hResModule;
2368 nct->dlg_proc = afs_dlg_proc;
2369 nct->dlg_template = MAKEINTRESOURCE(IDD_NC_AFS);
2370 nct->type_deps[nct->n_type_deps++] = krb5_credtype_id;
2372 if (krb4_credtype_id < 0) {
2373 kcdb_credtype_get_id(KRB4_CREDTYPE_NAME,
2376 if (krb4_credtype_id >= 0) {
2377 nct->type_deps[nct->n_type_deps++] =
2381 khui_cw_add_type(nc, nct);
2385 case KMSG_CRED_RENEW_CREDS:
2387 khui_new_creds * nc;
2388 khui_new_creds_by_type * nct;
2390 nc = (khui_new_creds *) vparam;
2392 nct = PMALLOC(sizeof(*nct));
2393 ZeroMemory(nct, sizeof(*nct));
2395 nct->type = afs_credtype_id;
2396 nct->type_deps[nct->n_type_deps++] = krb5_credtype_id;
2397 if (krb4_credtype_id < 0) {
2398 kcdb_credtype_get_id(KRB4_CREDTYPE_NAME,
2401 if (krb4_credtype_id >= 0) {
2402 nct->type_deps[nct->n_type_deps++] =
2406 khui_cw_add_type(nc, nct);
2410 case KMSG_CRED_DIALOG_PRESTART:
2412 khui_new_creds * nc;
2413 khui_new_creds_by_type * nct = NULL;
2416 nc = (khui_new_creds *) vparam;
2417 khui_cw_find_type(nc, afs_credtype_id, &nct);
2422 hwnd = nct->hwnd_panel;
2426 PostMessage(hwnd, KHUI_WM_NC_NOTIFY,
2427 MAKEWPARAM(0,WMNC_DIALOG_SETUP), 0);
2431 case KMSG_CRED_DIALOG_NEW_IDENTITY:
2433 khui_new_creds * nc;
2434 khui_new_creds_by_type * nct = NULL;
2437 nc = (khui_new_creds *) vparam;
2438 khui_cw_find_type(nc, afs_credtype_id, &nct);
2443 d = (afs_dlg_data *) nct->aux;
2448 EnterCriticalSection(&d->cs);
2450 if (nct->aux == 0) {
2451 LeaveCriticalSection(&d->cs);
2455 /* we should load up the selected tokens for this
2457 if(nc->n_identities == 0) {
2458 LeaveCriticalSection(&d->cs);
2459 /* no identities selected. nothing to do */
2463 afs_cred_get_identity_creds(&d->creds, nc->identities[0],
2466 LeaveCriticalSection(&d->cs);
2468 PostMessage(nct->hwnd_panel, KHUI_WM_NC_NOTIFY,
2469 MAKEWPARAM(0, WMNC_AFS_UPDATE_ROWS), 0);
2473 case KMSG_CRED_PROCESS:
2475 khui_new_creds * nc;
2476 khui_new_creds_by_type * nct = NULL;
2477 afs_cred_list tlist;
2480 BOOL failed = FALSE; /* one or more cells failed */
2481 BOOL succeeded = FALSE; /* one or more cells succeeded */
2482 BOOL free_tlist = FALSE;
2483 khm_handle ident = NULL;
2484 afs_dlg_data * d = NULL;
2485 BOOL get_tokens = TRUE;
2486 BOOL ident_renew_triggered = TRUE;
2487 khm_handle csp_afscred = NULL;
2488 khm_handle csp_cells = NULL;
2490 nc = (khui_new_creds *) vparam;
2491 khui_cw_find_type(nc, afs_credtype_id, &nct);
2497 _report_cs0(KHERR_INFO,
2498 L"Getting AFS tokens...");
2501 if(nc->result != KHUI_NC_RESULT_PROCESS &&
2502 nc->subtype != KMSG_CRED_RENEW_CREDS) {
2504 khui_cw_set_response(nc, afs_credtype_id,
2505 KHUI_NC_RESPONSE_SUCCESS);
2507 _report_cs0(KHERR_INFO,
2513 /* we can't proceed if Kerberos 5 has failed */
2514 if(!khui_cw_type_succeeded(nc, krb5_credtype_id)) {
2515 khui_cw_set_response(nc, afs_credtype_id,
2516 KHUI_NC_RESPONSE_FAILED);
2518 _report_cs0(KHERR_INFO,
2519 L"Kerberos 5 plugin failed to process credentials request. Aborting");
2524 if (nc->subtype == KMSG_CRED_RENEW_CREDS) {
2526 if (nc->ctx.scope == KHUI_SCOPE_IDENT ||
2528 (nc->ctx.scope == KHUI_SCOPE_CREDTYPE &&
2529 nc->ctx.cred_type == afs_credtype_id) ||
2531 (nc->ctx.scope == KHUI_SCOPE_CRED &&
2532 nc->ctx.cred_type == afs_credtype_id)) {
2534 _report_cs1(KHERR_INFO,
2535 L"AFS Renew Creds :: ident %1!p!",
2536 _cptr(nc->ctx.identity));
2540 _report_cs0(KHERR_INFO,
2541 L"Renew request not applicable to AFS");
2547 if (nc->ctx.identity != NULL) {
2548 ident = nc->ctx.identity;
2550 khui_cw_set_response(nc, afs_credtype_id,
2551 KHUI_NC_RESPONSE_FAILED);
2553 _report_cs0(KHERR_INFO,
2554 L"No identity specified. Aborting");
2559 ZeroMemory(&tlist, sizeof(tlist));
2563 afs_cred_get_identity_creds(l, ident, NULL);
2565 /* if the identity has any tokens associated with it
2566 that aren't persistent, we should renew those as
2568 afs_cred_get_context_creds(l, &nc->ctx);
2570 if (nc->ctx.scope == KHUI_SCOPE_CREDTYPE ||
2571 nc->ctx.scope == KHUI_SCOPE_CRED) {
2573 ident_renew_triggered = FALSE;
2578 _report_cs1(KHERR_INFO,
2579 L"AFS New Creds :: ident %1!p!",
2580 _cptr(nc->identities[0]));
2582 d = (afs_dlg_data *) nct->aux;
2584 _report_cs0(KHERR_INFO,
2585 L"No dialog data found. Aborting");
2587 khui_cw_set_response(nc, afs_credtype_id,
2588 KHUI_NC_RESPONSE_FAILED);
2593 EnterCriticalSection(&d->cs);
2597 ident = nc->identities[0];
2599 LeaveCriticalSection(&d->cs);
2601 _report_cs0(KHERR_INFO,
2602 L"No identity specified. Aborting");
2604 khui_cw_set_response(nc, afs_credtype_id,
2605 KHUI_NC_RESPONSE_FAILED);
2611 get_tokens = d->afs_enabled;
2617 if (KHM_SUCCEEDED(kmm_get_plugin_config(AFS_PLUGIN_NAME, 0,
2619 khc_open_space(csp_afscred, L"Cells", 0, &csp_cells);
2621 /* looks like k5 worked. Now see about getting those
2623 for(i=0; i<l->n_rows; i++) {
2625 char cell[MAXCELLCHARS];
2626 char realm[MAXCELLCHARS];
2632 khm_int32 method = AFS_TOKEN_AUTO;
2633 khm_handle csp_cell = NULL;
2635 if (l->rows[i].flags &
2636 (DLGROW_FLAG_DONE | DLGROW_FLAG_DELETED))
2640 ZeroMemory(cell, sizeof(cell));
2641 ZeroMemory(realm, sizeof(realm));
2643 UnicodeStrToAnsi(cell, sizeof(cell), l->rows[i].cell);
2644 if (l->rows[i].realm != NULL)
2645 UnicodeStrToAnsi(realm, sizeof(realm),
2648 ZeroMemory(&ft_old, sizeof(ft_old));
2650 if (!ident_renew_triggered &&
2651 (ctoken = afs_find_token(NULL, l->rows[i].cell))) {
2653 cb = sizeof(ft_old);
2654 kcdb_cred_get_attr(ctoken, KCDB_ATTR_EXPIRE,
2655 NULL, &ft_old, &cb);
2657 kcdb_cred_release(ctoken);
2660 if (l->rows[i].method == AFS_TOKEN_AUTO && csp_cells &&
2661 KHM_SUCCEEDED(khc_open_space(csp_cells,
2665 if (KHM_FAILED(khc_read_int32(csp_cell, L"Method", &method))) {
2666 method = l->rows[i].method;
2668 _report_cs3(KHERR_INFO,
2669 L"Overriding method %1!d! with global default %2!d! for cell %3!s!",
2670 _int32(l->rows[i].method),
2672 _cstr(l->rows[i].cell));
2676 khc_close_space(csp_cell);
2678 method = l->rows[i].method;
2681 _report_cs3(KHERR_INFO,
2682 L"Getting tokens for cell %1!S! with realm %2!S! using method %3!d!",
2689 code = afs_klog(ident, "", cell, realm, 0,
2692 _report_cs1(KHERR_INFO,
2693 L"klog returns code %1!d!",
2698 l->rows[i].flags &= ~DLGROW_FLAG_DONE;
2700 if (!kherr_is_error()) {
2701 /* failed to get tokens, but no error was reported */
2702 _report_sr1(KHERR_ERROR, IDS_ERR_GENERAL,
2708 l->rows[i].flags |= DLGROW_FLAG_DONE;
2712 !ident_renew_triggered) {
2713 TimetToFileTime(new_exp, &ft_new);
2715 if (CompareFileTime(&ft_old, &ft_new) >= 0) {
2716 /* getting a new token didn't improve the
2717 situation much. We only get here if we
2718 were trying to renew tokens. So we try
2719 to trigger an identity renewal. Doing
2720 so should get us new initial tickets
2721 which will allow us to get a better
2724 khui_action_context ctx;
2726 _reportf(L"Renewal of AFS tokens for cell %s failed to get a longer token. Triggering identity renewal", l->rows[i].cell);
2728 khui_context_create(&ctx,
2731 KCDB_CREDTYPE_INVALID,
2733 khui_action_trigger(KHUI_ACTION_RENEW_CRED,
2736 khui_context_release(&ctx);
2738 ident_renew_triggered = TRUE;
2747 /* we should indicate errors if anything went wrong */
2748 khui_cw_set_response(nc, afs_credtype_id,
2749 KHUI_NC_RESPONSE_FAILED);
2751 khui_cw_set_response(nc, afs_credtype_id,
2752 KHUI_NC_RESPONSE_SUCCESS);
2755 if (succeeded && nc->subtype == KMSG_CRED_RENEW_CREDS) {
2756 afs_ident_token_set b;
2758 afs_list_tokens_internal();
2760 /* the tokens that we just acquired need adjusting to
2761 include the realm, method and identity information
2762 derived from the new creds operation. this is done
2763 in afs_adjust_token_ident_proc */
2767 b.update_info = FALSE;
2769 kcdb_credset_apply(afs_credset, afs_adjust_token_ident_proc,
2772 kcdb_credset_collect(NULL, afs_credset, NULL,
2773 afs_credtype_id, NULL);
2775 } else if (nc->subtype == KMSG_CRED_NEW_CREDS) {
2776 afs_ident_token_set b;
2778 afs_list_tokens_internal();
2780 /* the tokens that we just acquired need adjusting to
2781 include the realm, method and identity information
2782 derived from the new creds operation. this is done
2783 in afs_adjust_token_ident_proc */
2787 b.update_info = FALSE;
2789 kcdb_credset_apply(afs_credset, afs_adjust_token_ident_proc,
2792 kcdb_credset_collect(NULL, afs_credset, NULL,
2793 afs_credtype_id, NULL);
2795 afs_cred_write_ident_data(d);
2799 LeaveCriticalSection(&d->cs);
2802 afs_cred_free_rows(&tlist);
2806 khc_close_space(csp_afscred);
2809 khc_close_space(csp_cells);
2817 khui_new_creds * nc;
2818 khui_new_creds_by_type * nct;
2820 nc = (khui_new_creds *) vparam;
2821 khui_cw_find_type(nc, afs_credtype_id, &nct);
2826 khui_cw_del_type(nc, afs_credtype_id);
2831 PFREE(nct->credtext);
2838 return KHM_ERROR_SUCCESS;