2 * Copyright (c) 2005,2006,2007,2008 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
27 #include <afsconfig.h>
28 #include <afs/param.h>
34 #include<netidmgr_version.h>
36 #include<help/afsplhlp.h>
40 #define WMNC_AFS_UPDATE_ROWS (WMNC_USER + 1)
42 typedef struct tag_afs_ident_token_set {
46 khm_boolean update_info;
47 } afs_ident_token_set;
51 afs_cred_flush_rows(afs_cred_list * l) {
54 for(i=0; i<l->n_rows; i++) {
56 PFREE(l->rows[i].cell);
58 PFREE(l->rows[i].realm);
62 ZeroMemory(l->rows, sizeof(l->rows[0]) * l->nc_rows);
69 afs_cred_free_rows(afs_cred_list * l) {
71 afs_cred_flush_rows(l);
81 afs_cred_assert_rows(afs_cred_list * l, int n) {
85 l->nc_rows = UBOUNDSS(n, AFS_DLG_ROW_ALLOC, AFS_DLG_ROW_ALLOC);
86 rows = PMALLOC(sizeof(afs_cred_row) * l->nc_rows);
87 ZeroMemory(rows, sizeof(afs_cred_row) * l->nc_rows);
91 memcpy(rows, l->rows, sizeof(afs_cred_row) * l->n_rows);
99 afs_cred_delete_row(afs_cred_list * l, int i) {
100 if (i < 0 || i >= l->n_rows)
103 if(i < (l->n_rows - 1)) {
105 PFREE(l->rows[i].cell);
107 PFREE(l->rows[i].realm);
108 memmove(&(l->rows[i]),
110 ((l->n_rows - (i+1)) *
111 sizeof(l->rows[0])));
117 afs_cred_get_new_row(afs_cred_list * l) {
120 afs_cred_assert_rows(l, l->n_rows + 1);
121 r = &(l->rows[l->n_rows]);
124 ZeroMemory(r, sizeof(*r));
130 afs_cred_add_row_from_cred(afs_cred_list * l,
135 wchar_t cell[MAXCELLCHARS];
139 rv = kcdb_cred_get_attr(cred,
145 assert(rv == KHM_ERROR_SUCCESS && cb != 0);
148 /* check if we already have the cell listed. */
149 for (i=0; i<l->n_rows; i++) {
150 if (!_wcsicmp(l->rows[i].cell, cell))
154 row = afs_cred_get_new_row(l);
156 row->cell = PMALLOC(cb);
157 StringCbCopy(row->cell, cb, cell);
159 cb = sizeof(row->method);
160 rv = kcdb_cred_get_attr(cred,
166 if (KHM_FAILED(rv)) {
167 row->method = AFS_TOKEN_AUTO;
172 rv = kcdb_cred_get_attr(cred,
178 if (rv == KHM_ERROR_TOO_LONG && cb > sizeof(wchar_t)) {
179 row->realm = PMALLOC(cb);
183 rv = kcdb_cred_get_attr(cred,
189 if (KHM_FAILED(rv)) {
202 afs_cred_add_cred_proc(khm_handle cred, void * rock) {
203 afs_cred_list * l = (afs_cred_list *) rock;
206 if (KHM_FAILED(kcdb_cred_get_type(cred, &t)) ||
207 t != afs_credtype_id)
208 return KHM_ERROR_SUCCESS;
210 afs_cred_add_row_from_cred(l, cred);
212 return KHM_ERROR_SUCCESS;
216 afs_cred_get_context_creds(afs_cred_list *l,
217 khui_action_context * ctx) {
218 khm_handle credset = NULL;
220 if (KHM_FAILED(kcdb_credset_create(&credset)))
223 if (KHM_FAILED(kcdb_credset_extract_filtered(credset,
225 khui_context_cursor_filter,
229 kcdb_credset_apply(credset,
230 afs_cred_add_cred_proc,
235 kcdb_credset_delete(credset);
239 afs_get_id_creds_apply_proc(khm_handle cred, void * rock) {
241 afs_ident_token_set * ts;
244 wchar_t cell[MAXCELLCHARS];
247 khm_int32 cflags = 0;
249 ts = (afs_ident_token_set *) rock;
252 kcdb_cred_get_type(cred, &t);
253 if (t != afs_credtype_id)
254 return KHM_ERROR_SUCCESS;
257 if (KHM_FAILED(kcdb_cred_get_attr(cred, afs_attr_cell,
260 return KHM_ERROR_SUCCESS;
262 kcdb_cred_get_flags(cred, &cflags);
264 kcdb_cred_get_identity(cred, &ident);
266 if (kcdb_identity_is_equal(ident, ts->ident)) {
268 for (i=0; i < l->n_rows; i++) {
269 if (!_wcsicmp(l->rows[i].cell, cell)) {
272 /* if the token exists, then these are implied */
275 DLGROW_FLAG_CHECKED |
278 if (cflags & KCDB_CRED_FLAG_EXPIRED)
279 l->rows[i].flags |= DLGROW_FLAG_EXPIRED;
281 if (ts->update_info) {
282 wchar_t realm[KHUI_MAXCCH_NAME];
286 (kcdb_cred_get_attr(cred, afs_attr_method,
289 afs_is_valid_method_id(method))
290 l->rows[i].method = method;
294 (kcdb_cred_get_attr(cred, afs_attr_realm,
297 cb > sizeof(wchar_t)) {
299 if (l->rows[i].realm)
300 PFREE(l->rows[i].realm);
301 l->rows[i].realm = PMALLOC(cb);
302 StringCbCopy(l->rows[i].realm,
311 /* not found? add! */
312 if (i >= l->n_rows && ts->add_new) {
315 r = afs_cred_add_row_from_cred(l, cred);
317 r->flags = DLGROW_FLAG_VALID | DLGROW_FLAG_CHECKED |
320 if (cflags & KCDB_CRED_FLAG_EXPIRED)
321 r->flags |= DLGROW_FLAG_EXPIRED;
324 } else { /* different identities */
326 for (i=0; i < l->n_rows; i++) {
327 if (!_wcsicmp(l->rows[i].cell, cell)) {
329 DLGROW_FLAG_NOTOWNED | DLGROW_FLAG_EXISTS |
330 DLGROW_FLAG_VALID | DLGROW_FLAG_CHECKED;
331 if (cflags & KCDB_CRED_FLAG_EXPIRED)
332 l->rows[i].flags |= DLGROW_FLAG_EXPIRED;
338 kcdb_identity_release(ident);
340 return KHM_ERROR_SUCCESS;
344 afs_remove_token_from_identities(wchar_t * cell) {
345 wchar_t * idents = NULL;
351 if (kcdb_identity_enum(KCDB_IDENT_FLAG_CONFIG,
352 KCDB_IDENT_FLAG_CONFIG,
355 &n_id) != KHM_ERROR_TOO_LONG ||
364 idents = PMALLOC(cb_id);
366 if (kcdb_identity_enum(KCDB_IDENT_FLAG_CONFIG,
367 KCDB_IDENT_FLAG_CONFIG,
370 &n_id) == KHM_ERROR_SUCCESS)
376 t = multi_string_next(t)) {
378 khm_handle h_id = NULL;
379 khm_handle csp_ident = NULL;
380 khm_handle csp_afs = NULL;
383 wchar_t * tbuf = NULL;
384 khm_int32 enabled = 0;
386 kcdb_identity_create(t, 0, &h_id);
394 if (KHM_FAILED(kcdb_identity_get_config(h_id, 0, &csp_ident)))
397 if (KHM_FAILED(khc_open_space(csp_ident, CSNAME_AFSCRED,
401 if (KHM_SUCCEEDED(khc_read_int32(csp_afs, L"AFSEnabled", &enabled)) &&
405 if (khc_read_multi_string(csp_afs, L"Cells", NULL, &cb)
406 != KHM_ERROR_TOO_LONG)
409 if (cb < sizeof(vbuf))
414 if (khc_read_multi_string(csp_afs, L"Cells", tbuf, &cb)
415 != KHM_ERROR_SUCCESS)
418 if (multi_string_find(tbuf, cell, 0) == NULL)
421 multi_string_delete(tbuf, cell, 0);
423 khc_write_multi_string(csp_afs, L"Cells", tbuf);
426 kcdb_identity_release(h_id);
428 khc_close_space(csp_ident);
430 khc_close_space(csp_afs);
431 if (tbuf && tbuf != vbuf)
440 afs_check_add_token_to_identity(wchar_t * cell, khm_handle ident,
441 khm_handle * ident_conflict) {
442 wchar_t * idents = NULL;
446 khm_boolean ok_to_add = TRUE;
448 /* check if this cell is listed for any other identity. */
451 if (kcdb_identity_enum(KCDB_IDENT_FLAG_CONFIG,
452 KCDB_IDENT_FLAG_CONFIG,
455 &n_id) != KHM_ERROR_TOO_LONG ||
464 idents = PMALLOC(cb_id);
466 if (kcdb_identity_enum(KCDB_IDENT_FLAG_CONFIG,
467 KCDB_IDENT_FLAG_CONFIG,
470 &n_id) == KHM_ERROR_SUCCESS)
475 ok_to_add && t && *t;
476 t = multi_string_next(t)) {
478 khm_handle h_id = NULL;
479 khm_handle csp_ident = NULL;
480 khm_handle csp_afs = NULL;
483 wchar_t * tbuf = NULL;
484 khm_int32 enabled = 0;
486 kcdb_identity_create(t, 0, &h_id);
494 if (kcdb_identity_is_equal(h_id, ident)) {
495 kcdb_identity_release(h_id);
499 if (KHM_FAILED(kcdb_identity_get_config(h_id, 0, &csp_ident)))
502 if (KHM_FAILED(khc_open_space(csp_ident, CSNAME_AFSCRED,
506 if (KHM_SUCCEEDED(khc_read_int32(csp_afs, L"AFSEnabled", &enabled)) &&
510 if (khc_read_multi_string(csp_afs, L"Cells", NULL, &cb)
511 != KHM_ERROR_TOO_LONG)
514 if (cb < sizeof(vbuf))
519 if (khc_read_multi_string(csp_afs, L"Cells", tbuf, &cb)
520 != KHM_ERROR_SUCCESS)
523 if (multi_string_find(tbuf, cell, 0) == NULL)
526 /* we found another identity which gets tokens for the
531 if (ident_conflict) {
532 *ident_conflict = h_id;
533 kcdb_identity_hold(h_id);
537 kcdb_identity_release(h_id);
539 khc_close_space(csp_ident);
541 khc_close_space(csp_afs);
542 if (tbuf && tbuf != vbuf)
553 add_token_to_list(afs_cred_list * l,
556 const wchar_t * c_cell)
561 khm_handle h_cell = NULL;
563 wchar_t wbuf[MAXCELLCHARS];
564 wchar_t wmethod[KHUI_MAXCCH_NAME];
566 if (FAILED(StringCbLength(c_cell, (MAXCELLCHARS + 1) * sizeof(wchar_t),
569 cb += sizeof(wchar_t);
571 for (i=0; i < l->n_rows; i++) {
572 if (!_wcsicmp(l->rows[i].cell, c_cell))
579 r = afs_cred_get_new_row(l);
581 r->cell = PMALLOC(cb);
582 StringCbCopy(r->cell, cb, c_cell);
585 KHM_SUCCEEDED(khc_open_space(h_gcells, c_cell, 0, &h_cell))) {
587 cb = sizeof(wmethod);
588 if (KHM_SUCCEEDED(khc_read_string(h_cell, L"MethodName",
591 r->method = afs_get_method_id(wmethod);
593 /* remove the deprecated value if it is present. */
594 khc_remove_value(h_cell, L"Method", 0);
596 } else if (KHM_SUCCEEDED(khc_read_int32(h_cell,
598 /* the Method property is deprecated. We detect and
599 correct this whenever possible. */
601 if (!afs_is_valid_method_id(i))
606 afs_get_method_name(i, wmethod, sizeof(wmethod));
608 khc_write_string(h_cell, L"MethodName", wmethod);
610 khc_remove_value(h_cell, L"Method", 0);
612 r->method = AFS_TOKEN_AUTO;
616 if (KHM_SUCCEEDED(khc_read_string(h_cell, L"Realm", wbuf, &cb)) &&
617 cb > sizeof(wchar_t)) {
618 r->realm = PMALLOC(cb);
619 StringCbCopy(r->realm, cb, wbuf);
624 khc_close_space(h_cell);
626 } else if (hk_gcells &&
627 RegOpenKeyEx(hk_gcells, c_cell, 0, KEY_READ, &hk_cell) == ERROR_SUCCESS) {
631 cbd = sizeof(wmethod);
632 if (RegQueryValueEx(hk_cell, L"MethodName", NULL, NULL, (LPBYTE) wmethod, &cbd) == ERROR_SUCCESS) {
633 r->method = afs_get_method_id(wmethod);
635 r->method = AFS_TOKEN_AUTO;
639 if (RegQueryValueEx(hk_cell, L"Realm", NULL, NULL, (LPBYTE) wbuf, &cbd) == ERROR_SUCCESS) {
640 cbd += sizeof(wchar_t);
641 r->realm = PMALLOC(cbd);
642 ZeroMemory(r->realm, cbd);
643 StringCbCopy(r->realm, cbd, wbuf);
648 RegCloseKey(hk_cell);
652 r->method = AFS_TOKEN_AUTO;
660 afs_cred_get_identity_creds(afs_cred_list * l,
662 khm_boolean * penabled) {
663 khm_handle h_id = NULL;
664 khm_handle h_afs = NULL;
665 khm_handle h_cells = NULL; /* per identity cells space */
666 khm_handle h_gcells = NULL; /* global cells space */
667 khm_boolean load_defs = TRUE;
671 afs_ident_token_set ts;
677 afs_cred_flush_rows(l);
679 kcdb_identity_get_config(ident, 0, &h_id);
683 if(KHM_FAILED(khc_open_space(h_id, CSNAME_AFSCRED,
689 if (KHM_FAILED(khc_read_int32(h_afs, L"AFSEnabled", &t)))
690 khc_read_int32(csp_params, L"AFSEnabled", &t);
694 if(KHM_FAILED(khc_open_space(h_afs, L"Cells",
698 if(khc_read_multi_string(h_afs, L"Cells", NULL, &cbi) !=
707 khc_read_multi_string(h_afs, L"Cells", ms, &cbi);
710 for(s = ms; s && *s; s = multi_string_next(s)) {
711 add_token_to_list(l, h_cells, NULL, s);
722 /* We want to load defaults */
723 char buf[MAXCELLCHARS];
724 wchar_t wbuf[MAXCELLCHARS];
726 khm_size cb_defcells;
728 khc_open_space(csp_params, L"Cells", 0, &h_gcells);
730 if (!cm_GetRootCellName(buf) &&
731 afs_check_for_cell_realm_match(ident, buf)) {
732 AnsiStrToUnicode(wbuf, sizeof(wbuf), buf);
734 if (afs_check_add_token_to_identity(wbuf, ident, NULL)) {
735 add_token_to_list(l, h_gcells, NULL, wbuf);
739 if (khc_read_multi_string(csp_params, L"DefaultCells",
740 NULL, &cb_defcells) == KHM_ERROR_TOO_LONG &&
741 cb_defcells > sizeof(wchar_t) * 2) {
744 defcells = PMALLOC(cb_defcells);
745 if (defcells == NULL)
748 if (KHM_FAILED(khc_read_multi_string(csp_params, L"DefaultCells",
749 defcells, &cb_defcells))) {
754 for (c_cell = defcells;
756 c_cell = multi_string_next(c_cell)) {
757 char cell[MAXCELLCHARS];
759 UnicodeStrToAnsi(cell, sizeof(cell), c_cell);
761 if (!afs_check_for_cell_realm_match(ident, cell))
764 add_token_to_list(l, h_gcells, NULL, c_cell);
770 /* Check HKLM\Software\OpenAFS\Client\Realms\<Realm> registry key as well */
772 wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
776 HKEY hk_realms = NULL, hk_realm = NULL;
779 kcdb_identity_get_name(ident, idname, &cb);
781 realm = wcsrchr(idname, L'@');
782 if (realm == NULL || realm[1] == L'\0')
787 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\OpenAFS\\Client\\Realms", 0, KEY_READ, &hk_realms) != ERROR_SUCCESS)
790 if (RegOpenKeyEx(hk_realms, realm, 0, KEY_READ, &hk_realm) != ERROR_SUCCESS)
797 cbd = sizeof(enabled);
799 if (RegQueryValueEx(hk_realm, L"AFSEnabled",
800 NULL, NULL, (LPBYTE) &enabled, &cbd) == ERROR_SUCCESS) {
801 *penabled = !!enabled;
806 DWORD dwNumCells=0, dwMaxCellLen=0, dwIndex, dwCellBufSz;
808 RegQueryInfoKey( hk_realm,
811 NULL, /* lpReserved */
812 &dwNumCells, /* lpcSubKeys */
813 &dwMaxCellLen, /* lpcMaxSubKeyLen */
814 NULL, /* lpcMaxClassLen */
815 NULL, /* lpcValues */
816 NULL, /* lpcMaxValueNameLen */
817 NULL, /* lpcMaxValueLen */
818 NULL, /* lpcbSecurityDescriptor */
819 NULL /* lpftLastWriteTime */
822 dwCellBufSz = (dwMaxCellLen + 1) * sizeof(wchar_t);
823 cell = PMALLOC(dwCellBufSz);
824 ZeroMemory(cell, dwCellBufSz);
826 for ( dwIndex=0; dwIndex < dwNumCells; dwIndex++ ) {
827 if (RegEnumKey( hk_realm, dwIndex, cell, dwCellBufSz) != ERROR_SUCCESS)
830 if (afs_check_add_token_to_identity(cell, ident, NULL))
831 add_token_to_list(l, NULL, hk_realm, cell);
838 RegCloseKey(hk_realm);
841 RegCloseKey(hk_realms);
853 ts.update_info = FALSE;
855 kcdb_credset_apply(NULL, afs_get_id_creds_apply_proc,
859 khc_close_space(h_id);
861 khc_close_space(h_afs);
863 khc_close_space(h_cells);
865 khc_close_space(h_gcells);
869 nc_dlg_enable(HWND hwnd, BOOL enable) {
871 SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN, BM_SETCHECK,
874 SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN, BM_SETCHECK,
878 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_CELL), enable);
879 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_REALM), enable);
880 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_METHOD), enable);
881 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_TOKENLIST), enable);
882 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_ADD_TOKEN), enable);
883 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_DELETE_TOKEN), enable);
887 nc_dlg_show_tooltip(HWND hwnd,
898 d = (afs_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
903 ZeroMemory(&ti, sizeof(ti));
904 ti.cbSize = sizeof(ti);
907 SendMessage(d->tooltip, TTM_GETTOOLINFO, 0, (LPARAM) &ti);
909 ti.hinst = hResModule;
912 SendMessage(d->tooltip, TTM_SETTOOLINFO, 0, (LPARAM) &ti);
914 if(IS_INTRESOURCE(title)) {
918 resid = (UINT)(UINT_PTR) title;
920 LoadString(hResModule, resid, wbuf, ARRAYLENGTH(wbuf));
921 SendMessage(d->tooltip, TTM_SETTITLE, type, (LPARAM) wbuf);
923 SendMessage(d->tooltip, TTM_SETTITLE, type, (LPARAM) title);
925 SendMessage(d->tooltip, TTM_TRACKACTIVATE, TRUE, (LPARAM) &ti);
926 SendMessage(d->tooltip, TTM_TRACKPOSITION, 0, (LPARAM) MAKELONG(x,y));
928 d->tooltip_visible = TRUE;
930 SetTimer(hwnd, DLG_TOOLTIP_TIMER_ID, DLG_TOOLTIP_TIMEOUT, NULL);
934 nc_dlg_hide_tooltip(HWND hwnd, UINT_PTR id)
939 d = (afs_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
944 if(!d->tooltip_visible)
947 ZeroMemory(&ti, sizeof(ti));
948 ti.cbSize = sizeof(ti);
952 SendMessage(d->tooltip, TTM_TRACKACTIVATE, FALSE, (LPARAM) &ti);
953 d->tooltip_visible = FALSE;
957 afs_dlg_update_rows(HWND hwnd, afs_dlg_data * d) {
963 CheckDlgButton(hwnd, IDC_NCAFS_OBTAIN,
964 (d->afs_enabled)? BST_CHECKED: BST_UNCHECKED);
966 hwlist = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
968 ListView_DeleteAllItems(hwlist);
970 if(d->creds.n_rows == 0)
973 LoadString(hResModule, IDS_NC_AUTO, wauto, ARRAYLENGTH(wauto));
975 for(i=0; i < d->creds.n_rows; i++) {
979 ZeroMemory(&lvi, sizeof(lvi));
981 lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
982 lvi.iItem = d->creds.n_rows + 1;
984 lvi.stateMask = LVIS_STATEIMAGEMASK;
985 flags = d->creds.rows[i].flags;
986 if ((flags & DLGROW_FLAG_EXISTS) &&
987 (flags & DLGROW_FLAG_NOTOWNED)) {
988 lvi.state = INDEXTOSTATEIMAGEMASK(d->idx_bad_token);
989 } else if ((flags & DLGROW_FLAG_EXISTS)) {
990 lvi.state = INDEXTOSTATEIMAGEMASK(d->idx_existing_token);
992 lvi.state = INDEXTOSTATEIMAGEMASK(d->idx_new_token);
995 lvi.lParam = (LPARAM) i;
997 lvi.iSubItem = NCAFS_IDX_CELL;
998 lvi.pszText = d->creds.rows[i].cell;
1000 lvi.iItem = ListView_InsertItem(hwlist, &lvi);
1002 lvi.mask = LVIF_TEXT; /* subitems dislike lParam */
1003 lvi.iSubItem = NCAFS_IDX_REALM;
1004 if(d->creds.rows[i].realm != NULL)
1005 lvi.pszText = d->creds.rows[i].realm;
1007 lvi.pszText = wauto;
1008 ListView_SetItem(hwlist, &lvi);
1010 lvi.iSubItem = NCAFS_IDX_METHOD;
1011 afs_method_describe(d->creds.rows[i].method,
1013 wbuf, sizeof(wbuf));
1016 ListView_SetItem(hwlist, &lvi);
1021 nc_dlg_del_token(HWND hwnd) {
1023 khui_new_creds_by_type * nct;
1025 d = (afs_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
1031 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1033 if(ListView_GetSelectedCount(GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST)) == 0) {
1034 wchar_t cell[KCDB_MAXCCH_NAME];
1037 /* nothing is selected in the list view */
1038 /* we delete the row that matches the current contents of the
1039 cell edit control */
1041 GetDlgItemText(hwnd, IDC_NCAFS_CELL, cell, ARRAYLENGTH(cell));
1042 for(i=0; i<d->creds.n_rows; i++) {
1043 if(!_wcsicmp(d->creds.rows[i].cell, cell)) {
1045 afs_cred_delete_row(&d->creds, i);
1046 afs_dlg_update_rows(hwnd, d);
1052 /* something is selected in the token list view */
1053 /* we delete that */
1058 BOOL deleted = FALSE;
1060 hw = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
1063 idx = ListView_GetNextItem(hw, idx, LVNI_SELECTED);
1065 ZeroMemory(&lvi, sizeof(lvi));
1068 lvi.mask = LVIF_PARAM;
1069 if(!ListView_GetItem(hw, &lvi))
1071 row = (int) lvi.lParam;
1072 if(row >= 0 && row < d->creds.n_rows) {
1073 d->creds.rows[row].flags |= DLGROW_FLAG_DELETED;
1080 for(idx = 0; idx < d->creds.n_rows; idx ++) {
1081 if(d->creds.rows[idx].flags & DLGROW_FLAG_DELETED) {
1082 afs_cred_delete_row(&d->creds, idx);
1083 idx--; /* we have to look at the current item again */
1088 afs_dlg_update_rows(hwnd, d);
1093 SendMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
1094 MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
1095 else if (d->config_dlg && d->dirty)
1096 khui_cfg_set_flags_inst(&d->cfg, KHUI_CNFLAG_MODIFIED,
1097 KHUI_CNFLAG_MODIFIED);
1101 nc_dlg_add_token(HWND hwnd) {
1103 afs_cred_row * prow;
1105 khui_new_creds_by_type * nct;
1111 BOOL new_row = FALSE;
1112 khm_handle ident = NULL;
1114 d = (afs_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
1120 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1124 if((n = SendDlgItemMessage(hwnd, IDC_NCAFS_CELL, WM_GETTEXT,
1125 (WPARAM) ARRAYLENGTH(buf), (LPARAM) buf))
1128 /* probably should indicate that user should type something */
1130 GetWindowRect(GetDlgItem(hwnd, IDC_NCAFS_CELL), &r);
1131 nc_dlg_show_tooltip(hwnd,
1133 MAKEINTRESOURCE(IDS_NC_TT_NO_CELL),
1134 MAKEINTRESOURCE(IDS_NC_TT_CANT_ADD),
1135 2, (r.left + r.right)/ 2, r.bottom);
1139 if(n != wcsspn(buf, AFS_VALID_CELL_CHARS)) {
1141 GetWindowRect(GetDlgItem(hwnd, IDC_NCAFS_CELL), &r);
1142 nc_dlg_show_tooltip(hwnd,
1144 MAKEINTRESOURCE(IDS_NC_TT_MALFORMED_CELL),
1145 MAKEINTRESOURCE(IDS_NC_TT_CANT_ADD),
1146 2, (r.left + r.right)/2, r.bottom);
1150 /* check if this is already listed */
1151 for(i=0;i<d->creds.n_rows;i++) {
1152 if(!_wcsicmp(buf, d->creds.rows[i].cell))
1156 if(i < d->creds.n_rows) {
1159 prow = &(d->creds.rows[i]);
1165 ZeroMemory(&trow, sizeof(trow));
1167 cb = (n+1) * sizeof(wchar_t);
1168 trow.cell = PMALLOC(cb);
1169 StringCbCopy(trow.cell, cb, buf);
1171 /* now for the realm */
1173 idx = (int) SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1174 CB_GETCURSEL, 0, 0);
1177 lp = (int) SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1178 CB_GETITEMDATA, idx, 0);
1179 if(lp != CB_ERR && lp) /* this is the 'determine realm
1180 automatically' item */
1187 if((n = SendDlgItemMessage(hwnd, IDC_NCAFS_REALM, WM_GETTEXT,
1188 ARRAYLENGTH(buf), (LPARAM) buf)) == 0) {
1190 GetWindowRect(GetDlgItem(hwnd, IDC_NCAFS_REALM), &r);
1191 nc_dlg_show_tooltip(hwnd,
1193 MAKEINTRESOURCE(IDS_NC_TT_NO_REALM),
1194 MAKEINTRESOURCE((new_row)?
1196 IDS_NC_TT_CANT_UPDATE),
1197 2, (r.left + r.right)/2, r.bottom);
1201 if(n != wcsspn(buf, AFS_VALID_REALM_CHARS)) {
1203 GetWindowRect(GetDlgItem(hwnd, IDC_NCAFS_REALM), &r);
1204 nc_dlg_show_tooltip(hwnd,
1206 MAKEINTRESOURCE(IDS_NC_TT_MALFORMED_REALM),
1207 MAKEINTRESOURCE((new_row)?
1209 IDS_NC_TT_CANT_UPDATE),
1210 2, (r.left + r.right)/2, r.bottom);
1214 cb = (n+1) * sizeof(wchar_t);
1215 trow.realm = PMALLOC(cb);
1216 StringCbCopy(trow.realm, cb, buf);
1220 idx = (int)SendDlgItemMessage(hwnd, IDC_NCAFS_METHOD,
1221 CB_GETCURSEL, 0, 0);
1222 if (idx != CB_ERR) {
1223 trow.method = (afs_tk_method)
1224 SendDlgItemMessage(hwnd, IDC_NCAFS_METHOD, CB_GETITEMDATA,
1227 trow.method = AFS_TOKEN_AUTO;
1231 d->nc->n_identities > 0 &&
1232 d->nc->identities[0]) {
1234 ident = d->nc->identities[0];
1236 } else if (d->ident) {
1243 khm_boolean ok_to_add = TRUE;
1246 khm_handle id_conf = NULL;
1249 afs_check_add_token_to_identity(trow.cell,
1254 #if KH_VERSION_API >= 5
1258 wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
1264 khui_alert_create_empty(&a);
1266 cb = sizeof(widname);
1267 kcdb_identity_get_name(id_conf, widname, &cb);
1269 LoadString(hResModule, IDS_NC_TT_CONFLICT,
1270 wfmt, ARRAYLENGTH(wfmt));
1271 StringCbPrintf(wbuf, sizeof(wbuf),
1272 wfmt, trow.cell, widname);
1273 khui_alert_set_message(a, wbuf);
1275 LoadString(hResModule, IDS_NC_TT_PROBLEM,
1276 wbuf, ARRAYLENGTH(wbuf));
1277 khui_alert_set_title(a, wbuf);
1279 khui_alert_add_command(a, KHUI_PACTION_KEEP);
1280 khui_alert_add_command(a, KHUI_PACTION_REMOVE);
1281 khui_alert_add_command(a, KHUI_PACTION_CANCEL);
1283 khui_alert_set_severity(a, KHERR_INFO);
1285 khui_alert_show_modal(a);
1289 if (a->response == KHUI_PACTION_REMOVE) {
1290 afs_remove_token_from_identities(trow.cell);
1291 } else if (a->response == KHUI_PACTION_CANCEL) {
1295 khui_alert_release(a);
1297 wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
1308 cb = sizeof(widname);
1309 kcdb_identity_get_name(id_conf, widname, &cb);
1310 LoadString(hResModule, IDS_NC_TT_PROBLEM,
1311 wtitle, ARRAYLENGTH(wtitle));
1312 LoadString(hResModule, IDS_NC_TT_CONFLICTM,
1313 wfmt, ARRAYLENGTH(wfmt));
1314 StringCbPrintf(wmsg, sizeof(wmsg), wfmt,
1315 trow.cell, widname);
1316 r = MessageBox(NULL, wmsg, wtitle,
1317 MB_YESNOCANCEL | MB_ICONWARNING |
1322 afs_remove_token_from_identities(trow.cell);
1323 } else if (r == IDCANCEL) {
1328 kcdb_identity_release(id_conf);
1335 prow = afs_cred_get_new_row(&d->creds);
1343 ZeroMemory(prow, sizeof(*prow));
1349 afs_ident_token_set ts;
1354 ts.update_info = FALSE;
1356 kcdb_credset_apply(NULL, afs_get_id_creds_apply_proc,
1360 afs_dlg_update_rows(hwnd, d);
1365 SendMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
1366 MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
1367 else if (d->config_dlg) {
1368 khui_cfg_set_flags_inst(&d->cfg,
1369 KHUI_CNFLAG_MODIFIED,
1370 KHUI_CNFLAG_MODIFIED);
1382 /* this is shared between the new credentials window and the AFS per
1383 identity configuration dialog. */
1385 afs_dlg_proc(HWND hwnd,
1394 HIMAGELIST hw_ilist;
1396 khui_new_creds_by_type * nct = NULL;
1399 d = PMALLOC(sizeof(*d));
1400 ZeroMemory(d, sizeof(*d));
1402 InitializeCriticalSection(&d->cs);
1404 /* lParam is a pointer to a khui_new_creds structure */
1405 d->nc = (khui_new_creds *) lParam;
1408 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1410 #pragma warning(push)
1411 #pragma warning(disable: 4244)
1412 SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) d);
1413 #pragma warning(pop)
1415 EnterCriticalSection(&d->cs);
1418 nct->aux = (LPARAM) d;
1420 /* create the tooltip window */
1422 CreateWindowEx(WS_EX_TOPMOST,
1425 WS_POPUP | TTS_BALLOON | TTS_ALWAYSTIP,
1426 CW_USEDEFAULT, CW_USEDEFAULT,
1427 CW_USEDEFAULT, CW_USEDEFAULT,
1428 hwnd, /* make this an owned window, so
1429 we don't have to worry about
1435 SetWindowPos(d->tooltip,
1441 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
1446 ZeroMemory(&ti, sizeof(ti));
1447 ti.cbSize = sizeof(ti);
1448 ti.uFlags = TTF_TRACK;
1451 ti.hinst = hResModule;
1453 GetClientRect(hwnd, &(ti.rect));
1455 SendMessage(d->tooltip, TTM_ADDTOOL, 0, (LPARAM) &ti);
1458 /* we only initialize the constant bits here. */
1459 hw = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
1461 GetClientRect(hw, &r);
1463 /* set the list view status icons */
1464 hw_ilist = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
1465 GetSystemMetrics(SM_CYSMICON),
1466 ILC_COLOR8 | ILC_MASK,
1474 hi = LoadImage(hResModule, MAKEINTRESOURCE(IDI_NC_NEW),
1476 GetSystemMetrics(SM_CXSMICON),
1477 GetSystemMetrics(SM_CYSMICON),
1480 d->idx_new_token = ImageList_AddIcon(hw_ilist, hi) + 1;
1484 hi = LoadImage(hResModule, MAKEINTRESOURCE(IDI_NC_EXIST),
1486 GetSystemMetrics(SM_CXSMICON),
1487 GetSystemMetrics(SM_CYSMICON),
1489 d->idx_existing_token = ImageList_AddIcon(hw_ilist, hi) + 1;
1493 hi = LoadImage(hResModule,
1494 MAKEINTRESOURCE(IDI_NC_NOTOWNED),
1496 GetSystemMetrics(SM_CXSMICON),
1497 GetSystemMetrics(SM_CYSMICON),
1499 d->idx_bad_token = ImageList_AddIcon(hw_ilist, hi) + 1 ;
1504 ListView_SetImageList(hw, hw_ilist, LVSIL_STATE);
1506 ListView_DeleteAllItems(hw);
1508 /* set the columns */
1513 lc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
1514 lc.fmt = LVCFMT_LEFT;
1515 lc.cx = ((r.right - r.left) * 2) / 5;
1516 LoadString(hResModule, IDS_NCAFS_COL_CELL,
1517 wbuf, ARRAYLENGTH(wbuf));
1520 ListView_InsertColumn(hw, 0, &lc);
1522 lc.mask |= LVCF_SUBITEM;
1523 //lc.cx is the same as above
1524 lc.iSubItem = NCAFS_IDX_REALM;
1525 LoadString(hResModule, IDS_NCAFS_COL_REALM,
1526 wbuf, ARRAYLENGTH(wbuf));
1528 ListView_InsertColumn(hw, 1, &lc);
1530 lc.cx = ((r.right - r.left) * 1) / 5;
1531 lc.iSubItem = NCAFS_IDX_METHOD;
1532 LoadString(hResModule, IDS_NCAFS_COL_METHOD,
1533 wbuf, ARRAYLENGTH(wbuf));
1535 ListView_InsertColumn(hw, 2, &lc);
1538 /* Set the items for the 'method' combo box */
1539 hw = GetDlgItem(hwnd, IDC_NCAFS_METHOD);
1542 wchar_t wbuf[KHUI_MAXCB_SHORT_DESC];
1543 afs_tk_method method = -1;
1546 SendMessage(hw, CB_RESETCONTENT, 0, 0);
1548 while((method = afs_get_next_method_id(method)) >= 0) {
1549 afs_method_describe(method, KCDB_TS_SHORT,
1550 wbuf, sizeof(wbuf));
1551 idx = (int)SendMessage(hw, CB_INSERTSTRING,
1552 (WPARAM) -1, (LPARAM) wbuf);
1554 assert(idx != CB_ERR);
1556 SendMessage(hw, CB_SETITEMDATA, (WPARAM) idx,
1560 /* finally, set the current selection to auto, which
1561 is the first method returned by
1562 afs_get_next_method_id() */
1563 SendMessage(hw, CB_SETCURSEL, 0, 0);
1566 d->afs_enabled = TRUE;
1567 SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN,
1568 BM_SETCHECK, BST_CHECKED, 0);
1570 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL, CB_LIMITTEXT, MAXCELLCHARS-1, 0);
1571 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM, CB_LIMITTEXT, MAXKTCREALMLEN-1, 0);
1572 SendDlgItemMessage(hwnd, IDC_NCAFS_METHOD, CB_LIMITTEXT, KCDB_MAXCCH_NAME-1, 0);
1574 LeaveCriticalSection(&d->cs);
1576 /* the cells and realms combo boxes need to be filled
1577 in the plugin thread since that requires making
1578 potentially blocking and non-thread safe calls */
1585 khui_new_creds_by_type * nct;
1587 d = (afs_dlg_data *)(LONG_PTR)
1588 GetWindowLongPtr(hwnd, DWLP_USER);
1593 EnterCriticalSection(&d->cs);
1596 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1598 nct->aux = (LPARAM) NULL;
1601 afs_cred_free_rows(&d->creds);
1603 LeaveCriticalSection(&d->cs);
1604 DeleteCriticalSection(&d->cs);
1608 SetWindowLongPtr(hwnd, DWLP_USER, 0);
1615 khui_new_creds_by_type * nct;
1617 d = (afs_dlg_data *)(LONG_PTR)
1618 GetWindowLongPtr(hwnd, DWLP_USER);
1623 EnterCriticalSection(&d->cs);
1626 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1630 nc_dlg_hide_tooltip(hwnd, 0);
1632 /* Handle WM_COMMAND */
1634 case MAKEWPARAM(IDC_NCAFS_OBTAIN, BN_CLICKED):
1637 c = (SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN,
1643 khui_cw_enable_type(d->nc, afs_credtype_id, c);
1644 else if (d->config_dlg)
1645 khui_cfg_set_flags_inst(&d->cfg,
1646 KHUI_CNFLAG_MODIFIED,
1647 KHUI_CNFLAG_MODIFIED);
1648 nc_dlg_enable(hwnd, c);
1652 case MAKEWPARAM(IDC_NCAFS_ADD_TOKEN, BN_CLICKED):
1654 nc_dlg_add_token(hwnd);
1658 case MAKEWPARAM(IDC_NCAFS_DELETE_TOKEN, BN_CLICKED):
1660 nc_dlg_del_token(hwnd);
1665 LeaveCriticalSection(&d->cs);
1669 case KHUI_WM_NC_NOTIFY:
1672 khui_new_creds_by_type * nct;
1674 d = (afs_dlg_data *)(LONG_PTR)
1675 GetWindowLongPtr(hwnd, DWLP_USER);
1680 EnterCriticalSection(&d->cs);
1683 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1687 switch(HIWORD(wParam)) {
1688 case WMNC_DIALOG_SETUP:
1690 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL,
1691 CB_RESETCONTENT, 0, 0);
1693 /* load the LRU cells */
1699 if(khc_read_multi_string(csp_params, L"LRUCells",
1701 KHM_ERROR_TOO_LONG) {
1702 buf = PMALLOC(cbbuf);
1703 khc_read_multi_string(csp_params, L"LRUCells",
1707 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL,
1708 CB_ADDSTRING, 0, (LPARAM) s);
1715 /* now, if the root cell is not in the LRU, add it */
1720 if(!cm_GetRootCellName(buf)) {
1721 AnsiStrToUnicode(wbuf, sizeof(wbuf), buf);
1722 if(SendDlgItemMessage(hwnd,
1726 (LPARAM) wbuf) == CB_ERR) {
1727 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL,
1731 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL,
1733 (WPARAM)-1, (LPARAM) wbuf);
1737 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1738 CB_RESETCONTENT, 0, 0);
1740 /* as for the realms, we have a special one here */
1745 LoadString(hResModule, IDS_NC_REALM_AUTO, wbuf,
1746 (int) ARRAYLENGTH(wbuf));
1747 idx = (int) SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1750 /* item data for the realm strings is the
1751 answer to the question, "is this the
1752 'determine realm automatically' item?" */
1753 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1754 CB_SETITEMDATA, idx, TRUE);
1755 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1757 (WPARAM)-1, (LPARAM) wbuf);
1760 /* load the LRU realms */
1767 if(khc_read_multi_string(csp_params, L"LRURealms",
1769 KHM_ERROR_TOO_LONG) {
1770 buf = PMALLOC(cbbuf);
1771 khc_read_multi_string(csp_params, L"LRURealms",
1775 if(SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1778 (LPARAM) s) == CB_ERR) {
1781 SendDlgItemMessage(hwnd,
1785 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1797 khui_cw_enable_type(d->nc, afs_credtype_id,
1800 nc_dlg_enable(hwnd, d->afs_enabled);
1802 afs_dlg_update_rows(hwnd, d);
1806 case WMNC_UPDATE_CREDTEXT:
1808 wchar_t wformat[256];
1813 PFREE(nct->credtext);
1814 nct->credtext = NULL;
1821 if (d->nc->n_identities == 0 ||
1822 KHM_FAILED(kcdb_identity_get_flags(d->nc->identities[0],
1824 !(flags & KCDB_IDENT_FLAG_VALID))
1825 /* in this case, we don't show any credential text */
1830 if(!d->afs_enabled) {
1831 LoadString(hResModule, IDS_AFS_CREDTEXT_DIS,
1832 wstr, ARRAYLENGTH(wstr));
1834 if(d->creds.n_rows == 0) {
1835 LoadString(hResModule, IDS_AFS_CREDTEXT_0,
1836 wstr, ARRAYLENGTH(wstr));
1837 } else if(d->creds.n_rows == 1) {
1838 LoadString(hResModule, IDS_AFS_CREDTEXT_1,
1839 wformat, ARRAYLENGTH(wformat));
1840 StringCbPrintf(wstr, sizeof(wstr), wformat,
1841 d->creds.rows[0].cell);
1844 wchar_t wcells[1024];
1846 LoadString(hResModule, IDS_AFS_CREDTEXT_N,
1847 wformat, ARRAYLENGTH(wformat));
1849 for(i=0; i<d->creds.n_rows; i++) {
1851 StringCbCat(wcells, sizeof(wcells),
1853 if(FAILED(StringCbCat(wcells,
1855 d->creds.rows[i].cell))) {
1857 /* looks like we overflowed */
1858 /* add an ellipsis at the end */
1859 StringCchLength(wcells, ARRAYLENGTH(wcells), &cch);
1860 cch = min(ARRAYLENGTH(wcells) - 4, cch);
1861 StringCchCopy(wcells + cch, 4, L"...");
1867 StringCbPrintf(wstr, sizeof(wstr), wformat, wcells);
1873 StringCbLength(wstr, sizeof(wstr), &cbs);
1874 cbs += sizeof(wchar_t);
1875 assert(nct->credtext == NULL);
1876 nct->credtext = PMALLOC(cbs);
1877 StringCbCopy(nct->credtext, cbs, wstr);
1879 /* something went wrong */
1880 nct->credtext = NULL;
1885 case WMNC_CREDTEXT_LINK:
1887 khui_htwnd_link * l;
1888 wchar_t wid[KHUI_MAXCCH_HTLINK_FIELD];
1891 l = (khui_htwnd_link *) lParam;
1893 StringCchCopyN(wid, ARRAYLENGTH(wid), l->id, l->id_len);
1894 wids = wcschr(wid, L':');
1905 if(!wcscmp(wids, L"Enable")) {
1906 SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN,
1907 BM_SETCHECK, BST_CHECKED, 0);
1908 d->afs_enabled = TRUE;
1909 khui_cw_enable_type(d->nc, afs_credtype_id, TRUE);
1910 nc_dlg_enable(hwnd, TRUE);
1915 case WMNC_IDENTITY_CHANGE:
1916 kmq_post_sub_msg(afs_sub, KMSG_CRED,
1917 KMSG_CRED_DIALOG_NEW_IDENTITY, 0,
1921 case WMNC_AFS_UPDATE_ROWS:
1922 afs_dlg_update_rows(hwnd, d);
1928 PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
1929 MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
1933 LeaveCriticalSection(&d->cs);
1938 if(wParam == IDC_NCAFS_TOKENLIST) {
1939 LPNMHDR lpnmh = (LPNMHDR) lParam;
1941 if(lpnmh->code == LVN_ITEMCHANGED) {
1942 /* when an item in the list view is clicked, we
1943 load the corresponding values into the edit and
1945 NMLISTVIEW *lpnmlv = (NMLISTVIEW *) lpnmh;
1952 if (!(lpnmlv->uChanged & LVIF_STATE) ||
1953 !(lpnmlv->uNewState & LVIS_SELECTED) ||
1954 (lpnmlv->iItem == -1))
1958 d = (afs_dlg_data *)(LONG_PTR)
1959 GetWindowLongPtr(hwnd, DWLP_USER);
1964 EnterCriticalSection(&d->cs);
1966 hw = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
1968 idx = lpnmlv->iItem;
1970 ZeroMemory(&lvi, sizeof(lvi));
1973 lvi.mask = LVIF_PARAM;
1975 if(!ListView_GetItem(hw, &lvi))
1976 goto _done_notify_select;
1978 /* ok, now lvi.lParam should be the row of the token */
1979 row = (int) lvi.lParam;
1980 if(row < 0 || row >= d->creds.n_rows)
1981 goto _done_notify_select;
1983 SetDlgItemText(hwnd, IDC_NCAFS_CELL,
1984 d->creds.rows[row].cell);
1985 if(d->creds.rows[row].realm != NULL) {
1986 SetDlgItemText(hwnd, IDC_NCAFS_REALM,
1987 d->creds.rows[row].realm);
1992 LoadString(hResModule, IDS_NC_REALM_AUTO, wbuf,
1994 idx = (int) SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1998 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM, CB_SETCURSEL,
2001 SendDlgItemMessage(hwnd, IDC_NCAFS_METHOD, CB_SETCURSEL,
2002 d->creds.rows[row].method, 0);
2003 _done_notify_select:
2004 LeaveCriticalSection(&d->cs);
2006 } else if (lpnmh->code == NM_DBLCLK) {
2008 LPNMITEMACTIVATE pnmi;
2016 d = (afs_dlg_data *)(LONG_PTR)
2017 GetWindowLongPtr(hwnd, DWLP_USER);
2022 EnterCriticalSection(&d->cs);
2024 pnmi = (LPNMITEMACTIVATE) lpnmh;
2026 hw = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
2028 ZeroMemory(&lvi, sizeof(lvi));
2029 lvi.iItem = pnmi->iItem;
2031 lvi.mask = LVIF_PARAM;
2033 if (!ListView_GetItem(hw, &lvi))
2034 goto _done_notify_click;
2036 row = (int) lvi.lParam;
2037 if(row < 0 || row >= d->creds.n_rows)
2038 goto _done_notify_click;
2040 ListView_GetItemRect(hw, pnmi->iItem, &r, LVIR_SELECTBOUNDS);
2041 x = (r.left + r.right) / 2;
2044 GetWindowRect(hw, &r);
2048 if (d->creds.rows[row].flags & DLGROW_FLAG_NOTOWNED) {
2049 nc_dlg_show_tooltip(hwnd, 0,
2050 MAKEINTRESOURCE(IDS_NC_TT_CONFLICTD),
2051 MAKEINTRESOURCE(IDS_NC_TT_PROBLEM),
2054 } else if (d->creds.rows[row].flags &
2055 DLGROW_FLAG_EXPIRED) {
2056 nc_dlg_show_tooltip(hwnd, 0,
2057 MAKEINTRESOURCE(IDS_NC_TT_EXPIRED),
2058 MAKEINTRESOURCE(IDS_NC_TT_DETAILS),
2061 } else if (d->creds.rows[row].flags &
2062 DLGROW_FLAG_EXISTS) {
2063 nc_dlg_show_tooltip(hwnd, 0,
2064 MAKEINTRESOURCE(IDS_NC_TT_EXISTS),
2065 MAKEINTRESOURCE(IDS_NC_TT_DETAILS),
2068 nc_dlg_show_tooltip(hwnd, 0,
2069 MAKEINTRESOURCE(IDS_NC_TT_NEW),
2070 MAKEINTRESOURCE(IDS_NC_TT_DETAILS),
2075 LeaveCriticalSection(&d->cs);
2082 if(wParam == DLG_TOOLTIP_TIMER_ID) {
2083 KillTimer(hwnd, DLG_TOOLTIP_TIMER_ID);
2084 nc_dlg_hide_tooltip(hwnd, 0);
2091 static const DWORD ctx_help[] = {
2092 IDC_NCAFS_OBTAIN, IDH_OBTAIN,
2093 IDC_NCAFS_CELL, IDH_CELL,
2094 IDC_NCAFS_REALM, IDH_REALM,
2095 IDC_NCAFS_METHOD, IDH_METHOD,
2096 IDC_NCAFS_ADD_TOKEN, IDH_ADD,
2097 IDC_NCAFS_DELETE_TOKEN, IDH_DELETE,
2098 IDC_NCAFS_TOKENLIST, IDH_TOKENLIST,
2104 hlp = (LPHELPINFO) lParam;
2106 if (hlp->iContextType != HELPINFO_WINDOW)
2109 afs_html_help(hlp->hItemHandle, L"::/popups_newcred.txt",
2110 HH_TP_HELP_WM_HELP, (DWORD_PTR) ctx_help);
2113 } /* switch(uMsg) */
2119 /* passed in to kcdb_credset_apply along with the afs_credset to adjust
2120 newly acquired credentials to include informatino derived from the
2121 new creds operation */
2123 afs_adjust_token_ident_proc(khm_handle cred, void * vd)
2125 wchar_t cell[MAXCELLCHARS];
2126 afs_ident_token_set * b = (afs_ident_token_set *) vd;
2133 /* ASSUMPTION: for each user, there can be tokens for only one
2136 cbbuf = sizeof(cell);
2138 if(KHM_FAILED(kcdb_cred_get_attr(cred, afs_attr_cell, NULL, cell, &cbbuf)))
2139 return KHM_ERROR_SUCCESS; /* remember, kcdb doesn't care if
2140 this run succeeded or not. all
2141 it wants to know if whether or
2142 not we want to continue the
2145 for(i=0; i<l->n_rows; i++) {
2146 if((l->rows[i].flags & DLGROW_FLAG_DONE) &&
2147 !_wcsicmp(cell, l->rows[i].cell)) {
2150 kcdb_cred_set_identity(cred, b->ident);
2151 if(l->rows[i].realm)
2152 kcdb_cred_set_attr(cred, afs_attr_realm, l->rows[i].realm,
2153 (khm_size)KCDB_CBSIZE_AUTO);
2155 kcdb_cred_set_attr(cred, afs_attr_realm, NULL, 0);
2157 method = l->rows[i].method;
2158 kcdb_cred_set_attr(cred, afs_attr_method, &method,
2159 (khm_size)KCDB_CBSIZE_AUTO);
2165 return KHM_ERROR_SUCCESS;
2169 afs_cred_write_ident_data(afs_dlg_data * d) {
2170 wchar_t * lru_cell = NULL;
2171 wchar_t * lru_realm = NULL;
2172 wchar_t * id_cell = NULL;
2178 khm_handle h_idc = NULL;
2179 khm_handle h_afs = NULL;
2180 khm_handle h_acells = NULL;
2181 khm_handle h_cellmap = NULL;
2182 wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
2183 khm_handle ident = NULL;
2190 d->nc->n_identities > 0 &&
2191 d->nc->identities[0])
2193 ident = d->nc->identities[0];
2195 else if (d->config_dlg)
2202 cbt = sizeof(idname);
2203 kcdb_identity_get_name(ident, idname, &cbt);
2205 khc_open_space(csp_afscred, L"Cells", 0, &h_cellmap);
2208 if(KHM_SUCCEEDED(kcdb_identity_get_config(ident,
2211 khc_open_space(h_idc, CSNAME_AFSCRED,
2212 KHM_FLAG_CREATE, &h_afs);
2216 khc_open_space(h_afs, L"Cells", KHM_FLAG_CREATE,
2222 khc_write_int32(h_afs, L"AFSEnabled",
2226 if(khc_read_multi_string(csp_params,
2229 &cbcell) == KHM_ERROR_TOO_LONG) {
2230 cbcell += MAXCELLCHARS * sizeof(wchar_t) *
2232 lru_cell = PMALLOC(cbcell);
2233 ZeroMemory(lru_cell, cbcell);
2236 khc_read_multi_string(csp_params,
2241 cbcell = MAXCELLCHARS * sizeof(wchar_t) * l->n_rows + sizeof(wchar_t);
2242 if (l->n_rows > 0) {
2243 lru_cell = PMALLOC(cbcell);
2244 ZeroMemory(lru_cell, cbcell);
2251 if(khc_read_multi_string(csp_params,
2254 &cbrealm) == KHM_ERROR_TOO_LONG) {
2255 cbrealm += MAXCELLCHARS * sizeof(wchar_t) * l->n_rows;
2256 lru_realm = PMALLOC(cbrealm);
2257 ZeroMemory(lru_realm, cbrealm);
2260 khc_read_multi_string(csp_params,
2265 cbrealm = MAXCELLCHARS * sizeof(wchar_t) * l->n_rows + sizeof(wchar_t);
2266 if (l->n_rows > 0) {
2267 lru_realm = PMALLOC(cbrealm);
2268 ZeroMemory(lru_realm, cbrealm);
2275 cbidcell = MAXCELLCHARS * sizeof(wchar_t) * l->n_rows + sizeof(wchar_t);
2276 if (l->n_rows > 0) {
2277 id_cell = PMALLOC(cbidcell);
2278 ZeroMemory(id_cell, cbidcell);
2284 for(i=0; i < l->n_rows; i++)
2285 if(!(l->rows[i].flags & DLGROW_FLAG_DELETED)) {
2286 khm_handle h_acell = NULL;
2288 if(!multi_string_find(lru_cell,
2289 l->rows[i].cell, 0)) {
2291 multi_string_append(lru_cell, &cbz,
2295 if(l->rows[i].realm &&
2296 !multi_string_find(lru_realm,
2297 l->rows[i].realm, 0)) {
2299 multi_string_append(lru_realm, &cbz,
2304 multi_string_append(id_cell, &cbz,
2308 KHM_SUCCEEDED(khc_open_space(h_acells,
2312 wchar_t methodname[KHUI_MAXCCH_NAME];
2314 afs_get_method_name(l->rows[i].method,
2316 sizeof(methodname));
2318 khc_write_string(h_acell, L"MethodName",
2321 if(l->rows[i].realm)
2322 khc_write_string(h_acell, L"Realm",
2325 khc_write_string(h_acell, L"Realm", L"");
2326 khc_close_space(h_acell);
2329 if (l->rows[i].flags & DLGROW_FLAG_DONE) {
2331 khc_write_string(h_cellmap,
2339 khc_write_multi_string(csp_params,
2340 L"LRUCells", lru_cell);
2342 khc_write_multi_string(csp_params,
2343 L"LRURealms", lru_realm);
2345 khc_write_multi_string(h_afs, L"Cells",
2348 khc_write_multi_string(h_afs, L"Cells", L"\0");
2350 if (d->config_dlg) {
2352 khui_cfg_set_flags_inst(&d->cfg, KHUI_CNFLAG_APPLIED,
2353 KHUI_CNFLAG_APPLIED |
2354 KHUI_CNFLAG_MODIFIED);
2356 khui_cfg_set_flags_inst(&d->cfg, 0,
2357 KHUI_CNFLAG_MODIFIED);
2363 khc_close_space(h_cellmap);
2365 khc_close_space(h_idc);
2367 khc_close_space(h_afs);
2369 khc_close_space(h_acells);
2379 afs_msg_newcred(khm_int32 msg_subtype,
2383 switch(msg_subtype) {
2384 case KMSG_CRED_NEW_CREDS:
2386 khui_new_creds * nc;
2387 khui_new_creds_by_type * nct;
2391 nc = (khui_new_creds *) vparam;
2393 nct = PMALLOC(sizeof(*nct));
2394 ZeroMemory(nct, sizeof(*nct));
2396 nct->type = afs_credtype_id;
2399 LoadString(hResModule, IDS_AFS_NAME, wbuf, ARRAYLENGTH(wbuf));
2400 StringCbLength(wbuf, sizeof(wbuf), &cbsize);
2401 cbsize += sizeof(wchar_t);
2403 nct->name = PMALLOC(cbsize);
2404 StringCbCopy(nct->name, cbsize, wbuf);
2406 nct->h_module = hResModule;
2407 nct->dlg_proc = afs_dlg_proc;
2408 nct->dlg_template = MAKEINTRESOURCE(IDD_NC_AFS);
2409 nct->type_deps[nct->n_type_deps++] = krb5_credtype_id;
2411 if (krb4_credtype_id < 0) {
2412 kcdb_credtype_get_id(KRB4_CREDTYPE_NAME,
2415 if (krb4_credtype_id >= 0) {
2416 nct->type_deps[nct->n_type_deps++] =
2420 khui_cw_add_type(nc, nct);
2424 case KMSG_CRED_RENEW_CREDS:
2426 khui_new_creds * nc;
2427 khui_new_creds_by_type * nct;
2429 nc = (khui_new_creds *) vparam;
2431 nct = PMALLOC(sizeof(*nct));
2432 ZeroMemory(nct, sizeof(*nct));
2434 nct->type = afs_credtype_id;
2435 nct->type_deps[nct->n_type_deps++] = krb5_credtype_id;
2436 if (krb4_credtype_id < 0) {
2437 kcdb_credtype_get_id(KRB4_CREDTYPE_NAME,
2440 if (krb4_credtype_id >= 0) {
2441 nct->type_deps[nct->n_type_deps++] =
2445 khui_cw_add_type(nc, nct);
2449 case KMSG_CRED_DIALOG_PRESTART:
2451 khui_new_creds * nc;
2452 khui_new_creds_by_type * nct = NULL;
2455 nc = (khui_new_creds *) vparam;
2456 khui_cw_find_type(nc, afs_credtype_id, &nct);
2461 hwnd = nct->hwnd_panel;
2465 PostMessage(hwnd, KHUI_WM_NC_NOTIFY,
2466 MAKEWPARAM(0,WMNC_DIALOG_SETUP), 0);
2470 case KMSG_CRED_DIALOG_NEW_IDENTITY:
2472 khui_new_creds * nc;
2473 khui_new_creds_by_type * nct = NULL;
2476 nc = (khui_new_creds *) vparam;
2477 khui_cw_find_type(nc, afs_credtype_id, &nct);
2482 d = (afs_dlg_data *) nct->aux;
2487 EnterCriticalSection(&d->cs);
2489 if (nct->aux == 0) {
2490 LeaveCriticalSection(&d->cs);
2494 /* we should load up the selected tokens for this
2496 if(nc->n_identities == 0) {
2497 LeaveCriticalSection(&d->cs);
2498 /* no identities selected. nothing to do */
2502 afs_cred_get_identity_creds(&d->creds, nc->identities[0],
2505 LeaveCriticalSection(&d->cs);
2507 PostMessage(nct->hwnd_panel, KHUI_WM_NC_NOTIFY,
2508 MAKEWPARAM(0, WMNC_AFS_UPDATE_ROWS), 0);
2512 case KMSG_CRED_PROCESS:
2514 khui_new_creds * nc;
2515 khui_new_creds_by_type * nct = NULL;
2516 afs_cred_list tlist;
2519 BOOL failed = FALSE; /* one or more cells failed */
2520 BOOL succeeded = FALSE; /* one or more cells succeeded */
2521 BOOL free_tlist = FALSE;
2522 khm_handle ident = NULL;
2523 afs_dlg_data * d = NULL;
2524 BOOL get_tokens = TRUE;
2525 BOOL ident_renew_triggered = TRUE;
2526 khm_handle csp_afscred = NULL;
2527 khm_handle csp_cells = NULL;
2529 nc = (khui_new_creds *) vparam;
2530 khui_cw_find_type(nc, afs_credtype_id, &nct);
2536 _report_cs0(KHERR_INFO,
2537 L"Getting AFS tokens...");
2540 if(nc->result != KHUI_NC_RESULT_PROCESS &&
2541 nc->subtype != KMSG_CRED_RENEW_CREDS) {
2543 khui_cw_set_response(nc, afs_credtype_id,
2544 KHUI_NC_RESPONSE_SUCCESS);
2546 _report_cs0(KHERR_INFO,
2552 /* we can't proceed if Kerberos 5 has failed */
2553 if(!khui_cw_type_succeeded(nc, krb5_credtype_id)) {
2554 khui_cw_set_response(nc, afs_credtype_id,
2555 KHUI_NC_RESPONSE_FAILED);
2557 _report_cs0(KHERR_INFO,
2558 L"Kerberos 5 plugin failed to process credentials request. Aborting");
2563 if (nc->subtype == KMSG_CRED_RENEW_CREDS) {
2565 if (nc->ctx.scope == KHUI_SCOPE_IDENT ||
2567 (nc->ctx.scope == KHUI_SCOPE_CREDTYPE &&
2568 nc->ctx.cred_type == afs_credtype_id) ||
2570 (nc->ctx.scope == KHUI_SCOPE_CRED &&
2571 nc->ctx.cred_type == afs_credtype_id)) {
2573 _report_cs1(KHERR_INFO,
2574 L"AFS Renew Creds :: ident %1!p!",
2575 _cptr(nc->ctx.identity));
2579 _report_cs0(KHERR_INFO,
2580 L"Renew request not applicable to AFS");
2586 if (nc->ctx.identity != NULL) {
2587 ident = nc->ctx.identity;
2589 khui_cw_set_response(nc, afs_credtype_id,
2590 KHUI_NC_RESPONSE_FAILED);
2592 _report_cs0(KHERR_INFO,
2593 L"No identity specified. Aborting");
2598 ZeroMemory(&tlist, sizeof(tlist));
2602 afs_cred_get_identity_creds(l, ident, NULL);
2604 /* if the identity has any tokens associated with it
2605 that aren't persistent, we should renew those as
2607 afs_cred_get_context_creds(l, &nc->ctx);
2609 if (nc->ctx.scope == KHUI_SCOPE_CREDTYPE ||
2610 nc->ctx.scope == KHUI_SCOPE_CRED) {
2612 ident_renew_triggered = FALSE;
2617 _report_cs1(KHERR_INFO,
2618 L"AFS New Creds :: ident %1!p!",
2619 _cptr(nc->identities[0]));
2621 d = (afs_dlg_data *) nct->aux;
2623 _report_cs0(KHERR_INFO,
2624 L"No dialog data found. Aborting");
2626 khui_cw_set_response(nc, afs_credtype_id,
2627 KHUI_NC_RESPONSE_FAILED);
2632 EnterCriticalSection(&d->cs);
2636 ident = nc->identities[0];
2638 LeaveCriticalSection(&d->cs);
2640 _report_cs0(KHERR_INFO,
2641 L"No identity specified. Aborting");
2643 khui_cw_set_response(nc, afs_credtype_id,
2644 KHUI_NC_RESPONSE_FAILED);
2650 get_tokens = d->afs_enabled;
2656 if (KHM_SUCCEEDED(kmm_get_plugin_config(AFS_PLUGIN_NAME, 0,
2658 khc_open_space(csp_afscred, L"Cells", 0, &csp_cells);
2660 /* looks like k5 worked. Now see about getting those
2662 for(i=0; i<l->n_rows; i++) {
2664 char cell[MAXCELLCHARS];
2665 char realm[MAXKTCREALMLEN];
2666 char linkedCell[MAXCELLCHARS]="";
2672 khm_int32 method = AFS_TOKEN_AUTO;
2673 khm_handle csp_cell = NULL;
2674 BOOL bgetLinked = 0;
2676 _progress(i, l->n_rows);
2678 if (l->rows[i].flags &
2679 (DLGROW_FLAG_DONE | DLGROW_FLAG_DELETED))
2683 ZeroMemory(cell, sizeof(cell));
2684 ZeroMemory(realm, sizeof(realm));
2686 UnicodeStrToAnsi(cell, sizeof(cell), l->rows[i].cell);
2687 if (l->rows[i].realm != NULL)
2688 UnicodeStrToAnsi(realm, sizeof(realm),
2691 ZeroMemory(&ft_old, sizeof(ft_old));
2693 if (!ident_renew_triggered &&
2694 (ctoken = afs_find_token(NULL, l->rows[i].cell))) {
2696 cb = sizeof(ft_old);
2697 kcdb_cred_get_attr(ctoken, KCDB_ATTR_EXPIRE,
2698 NULL, &ft_old, &cb);
2700 kcdb_cred_release(ctoken);
2703 if (l->rows[i].method == AFS_TOKEN_AUTO && csp_cells &&
2704 KHM_SUCCEEDED(khc_open_space(csp_cells,
2708 if (KHM_FAILED(khc_read_int32(csp_cell, L"Method", &method))) {
2709 method = l->rows[i].method;
2711 _report_cs3(KHERR_INFO,
2712 L"Overriding method %1!d! with global default %2!d! for cell %3!s!",
2713 _int32(l->rows[i].method),
2715 _cstr(l->rows[i].cell));
2719 khc_close_space(csp_cell);
2721 method = l->rows[i].method;
2725 _report_cs3(KHERR_INFO,
2726 L"Getting tokens for cell %1!S! with realm %2!S! using method %3!d!",
2727 _cstr((bgetLinked ? linkedCell: cell)),
2733 code = afs_klog(ident, "",
2734 bgetLinked ? linkedCell : cell,
2737 bgetLinked ? NULL :linkedCell);
2739 _report_cs1(KHERR_INFO,
2740 L"klog returns code %1!d!",
2745 l->rows[i].flags &= ~DLGROW_FLAG_DONE;
2747 if (!kherr_is_error()) {
2748 /* failed to get tokens, but no error was reported */
2749 _report_sr1(KHERR_ERROR, IDS_ERR_GENERAL,
2755 l->rows[i].flags |= DLGROW_FLAG_DONE;
2759 !ident_renew_triggered) {
2760 TimetToFileTime(new_exp, &ft_new);
2762 if (CompareFileTime(&ft_old, &ft_new) >= 0) {
2763 /* getting a new token didn't improve the
2764 situation much. We only get here if we
2765 were trying to renew tokens. So we try
2766 to trigger an identity renewal. Doing
2767 so should get us new initial tickets
2768 which will allow us to get a better
2771 khui_action_context ctx;
2773 _reportf(L"Renewal of AFS tokens for cell %s failed to get a longer token. Triggering identity renewal", l->rows[i].cell);
2775 khui_context_create(&ctx,
2778 KCDB_CREDTYPE_INVALID,
2780 khui_action_trigger(KHUI_ACTION_RENEW_CRED,
2783 khui_context_release(&ctx);
2785 ident_renew_triggered = TRUE;
2789 if ( !bgetLinked && linkedCell[0] ) {
2801 /* we should indicate errors if anything went wrong */
2802 khui_cw_set_response(nc, afs_credtype_id,
2803 KHUI_NC_RESPONSE_FAILED);
2805 khui_cw_set_response(nc, afs_credtype_id,
2806 KHUI_NC_RESPONSE_SUCCESS);
2809 if (succeeded && nc->subtype == KMSG_CRED_RENEW_CREDS) {
2810 afs_ident_token_set b;
2812 afs_list_tokens_internal();
2814 /* the tokens that we just acquired need adjusting to
2815 include the realm, method and identity information
2816 derived from the new creds operation. this is done
2817 in afs_adjust_token_ident_proc */
2821 b.update_info = FALSE;
2823 kcdb_credset_apply(afs_credset, afs_adjust_token_ident_proc,
2826 kcdb_credset_collect(NULL, afs_credset, NULL,
2827 afs_credtype_id, NULL);
2829 } else if (nc->subtype == KMSG_CRED_NEW_CREDS) {
2830 afs_ident_token_set b;
2832 afs_list_tokens_internal();
2834 /* the tokens that we just acquired need adjusting to
2835 include the realm, method and identity information
2836 derived from the new creds operation. this is done
2837 in afs_adjust_token_ident_proc */
2841 b.update_info = FALSE;
2843 kcdb_credset_apply(afs_credset, afs_adjust_token_ident_proc,
2846 kcdb_credset_collect(NULL, afs_credset, NULL,
2847 afs_credtype_id, NULL);
2849 afs_cred_write_ident_data(d);
2853 LeaveCriticalSection(&d->cs);
2856 afs_cred_free_rows(&tlist);
2860 khc_close_space(csp_afscred);
2863 khc_close_space(csp_cells);
2871 khui_new_creds * nc;
2872 khui_new_creds_by_type * nct;
2874 nc = (khui_new_creds *) vparam;
2875 khui_cw_find_type(nc, afs_credtype_id, &nct);
2880 khui_cw_del_type(nc, afs_credtype_id);
2885 PFREE(nct->credtext);
2892 return KHM_ERROR_SUCCESS;