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
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)
549 add_token_to_list(afs_cred_list * l,
552 const wchar_t * c_cell)
557 khm_handle h_cell = NULL;
559 wchar_t wbuf[MAXCELLCHARS];
560 wchar_t wmethod[KHUI_MAXCCH_NAME];
562 if (FAILED(StringCbLength(c_cell, (MAXCELLCHARS + 1) * sizeof(wchar_t),
565 cb += sizeof(wchar_t);
567 for (i=0; i < l->n_rows; i++) {
568 if (!_wcsicmp(l->rows[i].cell, c_cell))
575 r = afs_cred_get_new_row(l);
577 r->cell = PMALLOC(cb);
578 StringCbCopy(r->cell, cb, c_cell);
581 KHM_SUCCEEDED(khc_open_space(h_gcells, c_cell, 0, &h_cell))) {
583 cb = sizeof(wmethod);
584 if (KHM_SUCCEEDED(khc_read_string(h_cell, L"MethodName",
587 r->method = afs_get_method_id(wmethod);
589 /* remove the deprecated value if it is present. */
590 khc_remove_value(h_cell, L"Method", 0);
592 } else if (KHM_SUCCEEDED(khc_read_int32(h_cell,
594 /* the Method property is deprecated. We detect and
595 correct this whenever possible. */
597 if (!afs_is_valid_method_id(i))
602 afs_get_method_name(i, wmethod, sizeof(wmethod));
604 khc_write_string(h_cell, L"MethodName", wmethod);
606 khc_remove_value(h_cell, L"Method", 0);
608 r->method = AFS_TOKEN_AUTO;
612 if (KHM_SUCCEEDED(khc_read_string(h_cell, L"Realm", wbuf, &cb)) &&
613 cb > sizeof(wchar_t)) {
614 r->realm = PMALLOC(cb);
615 StringCbCopy(r->realm, cb, wbuf);
620 khc_close_space(h_cell);
622 } else if (hk_gcells &&
623 RegOpenKeyEx(hk_gcells, c_cell, 0, KEY_READ, &hk_cell) == ERROR_SUCCESS) {
627 cbd = sizeof(wmethod);
628 if (RegQueryValueEx(hk_cell, L"MethodName", NULL, NULL, (LPBYTE) wmethod, &cbd) == ERROR_SUCCESS) {
629 r->method = afs_get_method_id(wmethod);
631 r->method = AFS_TOKEN_AUTO;
635 if (RegQueryValueEx(hk_cell, L"Realm", NULL, NULL, (LPBYTE) wbuf, &cbd) == ERROR_SUCCESS) {
636 cbd += sizeof(wchar_t);
637 r->realm = PMALLOC(cbd);
638 ZeroMemory(r->realm, cbd);
639 StringCbCopy(r->realm, cbd, wbuf);
644 RegCloseKey(hk_cell);
648 r->method = AFS_TOKEN_AUTO;
656 afs_cred_get_identity_creds(afs_cred_list * l,
658 khm_boolean * penabled) {
659 khm_handle h_id = NULL;
660 khm_handle h_afs = NULL;
661 khm_handle h_cells = NULL; /* per identity cells space */
662 khm_handle h_gcells = NULL; /* global cells space */
663 khm_boolean load_defs = TRUE;
667 afs_ident_token_set ts;
673 afs_cred_flush_rows(l);
675 kcdb_identity_get_config(ident, 0, &h_id);
679 if(KHM_FAILED(khc_open_space(h_id, CSNAME_AFSCRED,
685 if (KHM_FAILED(khc_read_int32(h_afs, L"AFSEnabled", &t)))
686 khc_read_int32(csp_params, L"AFSEnabled", &t);
690 if(KHM_FAILED(khc_open_space(h_afs, L"Cells",
694 if(khc_read_multi_string(h_afs, L"Cells", NULL, &cbi) !=
703 khc_read_multi_string(h_afs, L"Cells", ms, &cbi);
706 for(s = ms; s && *s; s = multi_string_next(s)) {
707 add_token_to_list(l, h_cells, NULL, s);
718 /* We want to load defaults */
719 char buf[MAXCELLCHARS];
720 wchar_t wbuf[MAXCELLCHARS];
722 khm_size cb_defcells;
724 khc_open_space(csp_params, L"Cells", 0, &h_gcells);
726 if (!cm_GetRootCellName(buf) &&
727 afs_check_for_cell_realm_match(ident, buf)) {
728 AnsiStrToUnicode(wbuf, sizeof(wbuf), buf);
730 if (afs_check_add_token_to_identity(wbuf, ident, NULL)) {
731 add_token_to_list(l, h_gcells, NULL, wbuf);
735 if (khc_read_multi_string(csp_params, L"DefaultCells",
736 NULL, &cb_defcells) == KHM_ERROR_TOO_LONG &&
737 cb_defcells > sizeof(wchar_t) * 2) {
740 defcells = PMALLOC(cb_defcells);
741 if (defcells == NULL)
744 if (KHM_FAILED(khc_read_multi_string(csp_params, L"DefaultCells",
745 defcells, &cb_defcells))) {
750 for (c_cell = defcells;
752 c_cell = multi_string_next(c_cell)) {
753 char cell[MAXCELLCHARS];
755 UnicodeStrToAnsi(cell, sizeof(cell), c_cell);
757 if (!afs_check_for_cell_realm_match(ident, cell))
760 add_token_to_list(l, h_gcells, NULL, c_cell);
766 /* Check HKLM\Software\OpenAFS\Client\Realms\<Realm> registry key as well */
768 wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
772 HKEY hk_realms = NULL, hk_realm = NULL;
775 kcdb_identity_get_name(ident, idname, &cb);
777 realm = wcsrchr(idname, L'@');
778 if (realm == NULL || realm[1] == L'\0')
783 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\OpenAFS\\Client\\Realms", 0, KEY_READ, &hk_realms) != ERROR_SUCCESS)
786 if (RegOpenKeyEx(hk_realms, realm, 0, KEY_READ, &hk_realm) != ERROR_SUCCESS)
793 cbd = sizeof(enabled);
795 if (RegQueryValueEx(hk_realm, L"AFSEnabled",
796 NULL, NULL, (LPBYTE) &enabled, &cbd) == ERROR_SUCCESS) {
797 *penabled = !!enabled;
802 DWORD dwNumCells=0, dwMaxCellLen=0, dwIndex, dwCellBufSz;
804 RegQueryInfoKey( hk_realm,
807 NULL, /* lpReserved */
808 &dwNumCells, /* lpcSubKeys */
809 &dwMaxCellLen, /* lpcMaxSubKeyLen */
810 NULL, /* lpcMaxClassLen */
811 NULL, /* lpcValues */
812 NULL, /* lpcMaxValueNameLen */
813 NULL, /* lpcMaxValueLen */
814 NULL, /* lpcbSecurityDescriptor */
815 NULL /* lpftLastWriteTime */
818 dwCellBufSz = (dwMaxCellLen + 1) * sizeof(wchar_t);
819 cell = PMALLOC(dwCellBufSz);
820 ZeroMemory(cell, dwCellBufSz);
822 for ( dwIndex=0; dwIndex < dwNumCells; dwIndex++ ) {
823 if (RegEnumKey( hk_realm, dwIndex, cell, dwCellBufSz) != ERROR_SUCCESS)
826 if (afs_check_add_token_to_identity(cell, ident, NULL))
827 add_token_to_list(l, NULL, hk_realm, cell);
834 RegCloseKey(hk_realm);
837 RegCloseKey(hk_realms);
849 ts.update_info = FALSE;
851 kcdb_credset_apply(NULL, afs_get_id_creds_apply_proc,
855 khc_close_space(h_id);
857 khc_close_space(h_afs);
859 khc_close_space(h_cells);
861 khc_close_space(h_gcells);
865 nc_dlg_enable(HWND hwnd, BOOL enable) {
867 SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN, BM_SETCHECK,
870 SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN, BM_SETCHECK,
874 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_CELL), enable);
875 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_REALM), enable);
876 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_METHOD), enable);
877 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_TOKENLIST), enable);
878 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_ADD_TOKEN), enable);
879 EnableWindow(GetDlgItem(hwnd,IDC_NCAFS_DELETE_TOKEN), enable);
883 nc_dlg_show_tooltip(HWND hwnd,
894 d = (afs_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
899 ZeroMemory(&ti, sizeof(ti));
900 ti.cbSize = sizeof(ti);
903 SendMessage(d->tooltip, TTM_GETTOOLINFO, 0, (LPARAM) &ti);
905 ti.hinst = hResModule;
908 SendMessage(d->tooltip, TTM_SETTOOLINFO, 0, (LPARAM) &ti);
910 if(IS_INTRESOURCE(title)) {
914 resid = (UINT)(UINT_PTR) title;
916 LoadString(hResModule, resid, wbuf, ARRAYLENGTH(wbuf));
917 SendMessage(d->tooltip, TTM_SETTITLE, type, (LPARAM) wbuf);
919 SendMessage(d->tooltip, TTM_SETTITLE, type, (LPARAM) title);
921 SendMessage(d->tooltip, TTM_TRACKACTIVATE, TRUE, (LPARAM) &ti);
922 SendMessage(d->tooltip, TTM_TRACKPOSITION, 0, (LPARAM) MAKELONG(x,y));
924 d->tooltip_visible = TRUE;
926 SetTimer(hwnd, DLG_TOOLTIP_TIMER_ID, DLG_TOOLTIP_TIMEOUT, NULL);
930 nc_dlg_hide_tooltip(HWND hwnd, UINT_PTR id)
935 d = (afs_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
940 if(!d->tooltip_visible)
943 ZeroMemory(&ti, sizeof(ti));
944 ti.cbSize = sizeof(ti);
948 SendMessage(d->tooltip, TTM_TRACKACTIVATE, FALSE, (LPARAM) &ti);
949 d->tooltip_visible = FALSE;
953 afs_dlg_update_rows(HWND hwnd, afs_dlg_data * d) {
959 CheckDlgButton(hwnd, IDC_NCAFS_OBTAIN,
960 (d->afs_enabled)? BST_CHECKED: BST_UNCHECKED);
962 hwlist = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
964 ListView_DeleteAllItems(hwlist);
966 if(d->creds.n_rows == 0)
969 LoadString(hResModule, IDS_NC_AUTO, wauto, ARRAYLENGTH(wauto));
971 for(i=0; i < d->creds.n_rows; i++) {
975 ZeroMemory(&lvi, sizeof(lvi));
977 lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
978 lvi.iItem = d->creds.n_rows + 1;
980 lvi.stateMask = LVIS_STATEIMAGEMASK;
981 flags = d->creds.rows[i].flags;
982 if ((flags & DLGROW_FLAG_EXISTS) &&
983 (flags & DLGROW_FLAG_NOTOWNED)) {
984 lvi.state = INDEXTOSTATEIMAGEMASK(d->idx_bad_token);
985 } else if ((flags & DLGROW_FLAG_EXISTS)) {
986 lvi.state = INDEXTOSTATEIMAGEMASK(d->idx_existing_token);
988 lvi.state = INDEXTOSTATEIMAGEMASK(d->idx_new_token);
991 lvi.lParam = (LPARAM) i;
993 lvi.iSubItem = NCAFS_IDX_CELL;
994 lvi.pszText = d->creds.rows[i].cell;
996 lvi.iItem = ListView_InsertItem(hwlist, &lvi);
998 lvi.mask = LVIF_TEXT; /* subitems dislike lParam */
999 lvi.iSubItem = NCAFS_IDX_REALM;
1000 if(d->creds.rows[i].realm != NULL)
1001 lvi.pszText = d->creds.rows[i].realm;
1003 lvi.pszText = wauto;
1004 ListView_SetItem(hwlist, &lvi);
1006 lvi.iSubItem = NCAFS_IDX_METHOD;
1007 afs_method_describe(d->creds.rows[i].method,
1009 wbuf, sizeof(wbuf));
1012 ListView_SetItem(hwlist, &lvi);
1017 nc_dlg_del_token(HWND hwnd) {
1019 khui_new_creds_by_type * nct;
1021 d = (afs_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
1027 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1029 if(ListView_GetSelectedCount(GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST)) == 0) {
1030 wchar_t cell[KCDB_MAXCCH_NAME];
1033 /* nothing is selected in the list view */
1034 /* we delete the row that matches the current contents of the
1035 cell edit control */
1037 GetDlgItemText(hwnd, IDC_NCAFS_CELL, cell, ARRAYLENGTH(cell));
1038 for(i=0; i<d->creds.n_rows; i++) {
1039 if(!_wcsicmp(d->creds.rows[i].cell, cell)) {
1041 afs_cred_delete_row(&d->creds, i);
1042 afs_dlg_update_rows(hwnd, d);
1048 /* something is selected in the token list view */
1049 /* we delete that */
1054 BOOL deleted = FALSE;
1056 hw = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
1059 idx = ListView_GetNextItem(hw, idx, LVNI_SELECTED);
1061 ZeroMemory(&lvi, sizeof(lvi));
1064 lvi.mask = LVIF_PARAM;
1065 if(!ListView_GetItem(hw, &lvi))
1067 row = (int) lvi.lParam;
1068 if(row >= 0 && row < d->creds.n_rows) {
1069 d->creds.rows[row].flags |= DLGROW_FLAG_DELETED;
1076 for(idx = 0; idx < d->creds.n_rows; idx ++) {
1077 if(d->creds.rows[idx].flags & DLGROW_FLAG_DELETED) {
1078 afs_cred_delete_row(&d->creds, idx);
1079 idx--; /* we have to look at the current item again */
1084 afs_dlg_update_rows(hwnd, d);
1089 SendMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
1090 MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
1091 else if (d->config_dlg && d->dirty)
1092 khui_cfg_set_flags_inst(&d->cfg, KHUI_CNFLAG_MODIFIED,
1093 KHUI_CNFLAG_MODIFIED);
1097 nc_dlg_add_token(HWND hwnd) {
1099 afs_cred_row * prow;
1101 khui_new_creds_by_type * nct;
1107 BOOL new_row = FALSE;
1108 khm_handle ident = NULL;
1110 d = (afs_dlg_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
1116 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1120 if((n = SendDlgItemMessage(hwnd, IDC_NCAFS_CELL, WM_GETTEXT,
1121 (WPARAM) ARRAYLENGTH(buf), (LPARAM) buf))
1124 /* probably should indicate that user should type something */
1126 GetWindowRect(GetDlgItem(hwnd, IDC_NCAFS_CELL), &r);
1127 nc_dlg_show_tooltip(hwnd,
1129 MAKEINTRESOURCE(IDS_NC_TT_NO_CELL),
1130 MAKEINTRESOURCE(IDS_NC_TT_CANT_ADD),
1131 2, (r.left + r.right)/ 2, r.bottom);
1135 if(n != wcsspn(buf, AFS_VALID_CELL_CHARS)) {
1137 GetWindowRect(GetDlgItem(hwnd, IDC_NCAFS_CELL), &r);
1138 nc_dlg_show_tooltip(hwnd,
1140 MAKEINTRESOURCE(IDS_NC_TT_MALFORMED_CELL),
1141 MAKEINTRESOURCE(IDS_NC_TT_CANT_ADD),
1142 2, (r.left + r.right)/2, r.bottom);
1146 /* check if this is already listed */
1147 for(i=0;i<d->creds.n_rows;i++) {
1148 if(!_wcsicmp(buf, d->creds.rows[i].cell))
1152 if(i < d->creds.n_rows) {
1155 prow = &(d->creds.rows[i]);
1161 ZeroMemory(&trow, sizeof(trow));
1163 cb = (n+1) * sizeof(wchar_t);
1164 trow.cell = PMALLOC(cb);
1165 StringCbCopy(trow.cell, cb, buf);
1167 /* now for the realm */
1169 idx = (int) SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1170 CB_GETCURSEL, 0, 0);
1173 lp = (int) SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1174 CB_GETITEMDATA, idx, 0);
1175 if(lp != CB_ERR && lp) /* this is the 'determine realm
1176 automatically' item */
1183 if((n = SendDlgItemMessage(hwnd, IDC_NCAFS_REALM, WM_GETTEXT,
1184 ARRAYLENGTH(buf), (LPARAM) buf)) == 0) {
1186 GetWindowRect(GetDlgItem(hwnd, IDC_NCAFS_REALM), &r);
1187 nc_dlg_show_tooltip(hwnd,
1189 MAKEINTRESOURCE(IDS_NC_TT_NO_REALM),
1190 MAKEINTRESOURCE((new_row)?
1192 IDS_NC_TT_CANT_UPDATE),
1193 2, (r.left + r.right)/2, r.bottom);
1197 if(n != wcsspn(buf, AFS_VALID_REALM_CHARS)) {
1199 GetWindowRect(GetDlgItem(hwnd, IDC_NCAFS_REALM), &r);
1200 nc_dlg_show_tooltip(hwnd,
1202 MAKEINTRESOURCE(IDS_NC_TT_MALFORMED_REALM),
1203 MAKEINTRESOURCE((new_row)?
1205 IDS_NC_TT_CANT_UPDATE),
1206 2, (r.left + r.right)/2, r.bottom);
1210 cb = (n+1) * sizeof(wchar_t);
1211 trow.realm = PMALLOC(cb);
1212 StringCbCopy(trow.realm, cb, buf);
1216 idx = (int)SendDlgItemMessage(hwnd, IDC_NCAFS_METHOD,
1217 CB_GETCURSEL, 0, 0);
1218 if (idx != CB_ERR) {
1219 trow.method = (afs_tk_method)
1220 SendDlgItemMessage(hwnd, IDC_NCAFS_METHOD, CB_GETITEMDATA,
1223 trow.method = AFS_TOKEN_AUTO;
1227 d->nc->n_identities > 0 &&
1228 d->nc->identities[0]) {
1230 ident = d->nc->identities[0];
1232 } else if (d->ident) {
1239 khm_boolean ok_to_add = TRUE;
1242 khm_handle id_conf = NULL;
1245 afs_check_add_token_to_identity(trow.cell,
1250 #if KH_VERSION_API >= 5
1254 wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
1260 khui_alert_create_empty(&a);
1262 cb = sizeof(widname);
1263 kcdb_identity_get_name(id_conf, widname, &cb);
1265 LoadString(hResModule, IDS_NC_TT_CONFLICT,
1266 wfmt, ARRAYLENGTH(wfmt));
1267 StringCbPrintf(wbuf, sizeof(wbuf),
1268 wfmt, trow.cell, widname);
1269 khui_alert_set_message(a, wbuf);
1271 LoadString(hResModule, IDS_NC_TT_PROBLEM,
1272 wbuf, ARRAYLENGTH(wbuf));
1273 khui_alert_set_title(a, wbuf);
1275 khui_alert_add_command(a, KHUI_PACTION_KEEP);
1276 khui_alert_add_command(a, KHUI_PACTION_REMOVE);
1277 khui_alert_add_command(a, KHUI_PACTION_CANCEL);
1279 khui_alert_set_severity(a, KHERR_INFO);
1281 khui_alert_show_modal(a);
1285 if (a->response == KHUI_PACTION_REMOVE) {
1286 afs_remove_token_from_identities(trow.cell);
1287 } else if (a->response == KHUI_PACTION_CANCEL) {
1291 khui_alert_release(a);
1293 wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
1304 cb = sizeof(widname);
1305 kcdb_identity_get_name(id_conf, widname, &cb);
1306 LoadString(hResModule, IDS_NC_TT_PROBLEM,
1307 wtitle, ARRAYLENGTH(wtitle));
1308 LoadString(hResModule, IDS_NC_TT_CONFLICTM,
1309 wfmt, ARRAYLENGTH(wfmt));
1310 StringCbPrintf(wmsg, sizeof(wmsg), wfmt,
1311 trow.cell, widname);
1312 r = MessageBox(NULL, wmsg, wtitle,
1313 MB_YESNOCANCEL | MB_ICONWARNING |
1318 afs_remove_token_from_identities(trow.cell);
1319 } else if (r == IDCANCEL) {
1324 kcdb_identity_release(id_conf);
1331 prow = afs_cred_get_new_row(&d->creds);
1339 ZeroMemory(prow, sizeof(*prow));
1345 afs_ident_token_set ts;
1350 ts.update_info = FALSE;
1352 kcdb_credset_apply(NULL, afs_get_id_creds_apply_proc,
1356 afs_dlg_update_rows(hwnd, d);
1361 SendMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
1362 MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
1363 else if (d->config_dlg) {
1364 khui_cfg_set_flags_inst(&d->cfg,
1365 KHUI_CNFLAG_MODIFIED,
1366 KHUI_CNFLAG_MODIFIED);
1378 /* this is shared between the new credentials window and the AFS per
1379 identity configuration dialog. */
1381 afs_dlg_proc(HWND hwnd,
1390 HIMAGELIST hw_ilist;
1392 khui_new_creds_by_type * nct = NULL;
1395 d = PMALLOC(sizeof(*d));
1396 ZeroMemory(d, sizeof(*d));
1398 InitializeCriticalSection(&d->cs);
1400 /* lParam is a pointer to a khui_new_creds structure */
1401 d->nc = (khui_new_creds *) lParam;
1404 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1406 #pragma warning(push)
1407 #pragma warning(disable: 4244)
1408 SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) d);
1409 #pragma warning(pop)
1411 EnterCriticalSection(&d->cs);
1414 nct->aux = (LPARAM) d;
1416 /* create the tooltip window */
1418 CreateWindowEx(WS_EX_TOPMOST,
1421 WS_POPUP | TTS_BALLOON | TTS_ALWAYSTIP,
1422 CW_USEDEFAULT, CW_USEDEFAULT,
1423 CW_USEDEFAULT, CW_USEDEFAULT,
1424 hwnd, /* make this an owned window, so
1425 we don't have to worry about
1431 SetWindowPos(d->tooltip,
1437 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
1442 ZeroMemory(&ti, sizeof(ti));
1443 ti.cbSize = sizeof(ti);
1444 ti.uFlags = TTF_TRACK;
1447 ti.hinst = hResModule;
1449 GetClientRect(hwnd, &(ti.rect));
1451 SendMessage(d->tooltip, TTM_ADDTOOL, 0, (LPARAM) &ti);
1454 /* we only initialize the constant bits here. */
1455 hw = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
1457 GetClientRect(hw, &r);
1459 /* set the list view status icons */
1460 hw_ilist = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
1461 GetSystemMetrics(SM_CYSMICON),
1462 ILC_COLOR8 | ILC_MASK,
1470 hi = LoadImage(hResModule, MAKEINTRESOURCE(IDI_NC_NEW),
1472 GetSystemMetrics(SM_CXSMICON),
1473 GetSystemMetrics(SM_CYSMICON),
1476 d->idx_new_token = ImageList_AddIcon(hw_ilist, hi) + 1;
1480 hi = LoadImage(hResModule, MAKEINTRESOURCE(IDI_NC_EXIST),
1482 GetSystemMetrics(SM_CXSMICON),
1483 GetSystemMetrics(SM_CYSMICON),
1485 d->idx_existing_token = ImageList_AddIcon(hw_ilist, hi) + 1;
1489 hi = LoadImage(hResModule,
1490 MAKEINTRESOURCE(IDI_NC_NOTOWNED),
1492 GetSystemMetrics(SM_CXSMICON),
1493 GetSystemMetrics(SM_CYSMICON),
1495 d->idx_bad_token = ImageList_AddIcon(hw_ilist, hi) + 1 ;
1500 ListView_SetImageList(hw, hw_ilist, LVSIL_STATE);
1502 ListView_DeleteAllItems(hw);
1504 /* set the columns */
1509 lc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
1510 lc.fmt = LVCFMT_LEFT;
1511 lc.cx = ((r.right - r.left) * 2) / 5;
1512 LoadString(hResModule, IDS_NCAFS_COL_CELL,
1513 wbuf, ARRAYLENGTH(wbuf));
1516 ListView_InsertColumn(hw, 0, &lc);
1518 lc.mask |= LVCF_SUBITEM;
1519 //lc.cx is the same as above
1520 lc.iSubItem = NCAFS_IDX_REALM;
1521 LoadString(hResModule, IDS_NCAFS_COL_REALM,
1522 wbuf, ARRAYLENGTH(wbuf));
1524 ListView_InsertColumn(hw, 1, &lc);
1526 lc.cx = ((r.right - r.left) * 1) / 5;
1527 lc.iSubItem = NCAFS_IDX_METHOD;
1528 LoadString(hResModule, IDS_NCAFS_COL_METHOD,
1529 wbuf, ARRAYLENGTH(wbuf));
1531 ListView_InsertColumn(hw, 2, &lc);
1534 /* Set the items for the 'method' combo box */
1535 hw = GetDlgItem(hwnd, IDC_NCAFS_METHOD);
1538 wchar_t wbuf[KHUI_MAXCB_SHORT_DESC];
1539 afs_tk_method method = -1;
1542 SendMessage(hw, CB_RESETCONTENT, 0, 0);
1544 while((method = afs_get_next_method_id(method)) >= 0) {
1545 afs_method_describe(method, KCDB_TS_SHORT,
1546 wbuf, sizeof(wbuf));
1547 idx = (int)SendMessage(hw, CB_INSERTSTRING,
1548 (WPARAM) -1, (LPARAM) wbuf);
1550 assert(idx != CB_ERR);
1552 SendMessage(hw, CB_SETITEMDATA, (WPARAM) idx,
1556 /* finally, set the current selection to auto, which
1557 is the first method returned by
1558 afs_get_next_method_id() */
1559 SendMessage(hw, CB_SETCURSEL, 0, 0);
1562 d->afs_enabled = TRUE;
1563 SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN,
1564 BM_SETCHECK, BST_CHECKED, 0);
1566 LeaveCriticalSection(&d->cs);
1568 /* the cells and realms combo boxes need to be filled
1569 in the plugin thread since that requires making
1570 potentially blocking and non-thread safe calls */
1577 khui_new_creds_by_type * nct;
1579 d = (afs_dlg_data *)(LONG_PTR)
1580 GetWindowLongPtr(hwnd, DWLP_USER);
1585 EnterCriticalSection(&d->cs);
1588 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1590 nct->aux = (LPARAM) NULL;
1593 afs_cred_free_rows(&d->creds);
1595 LeaveCriticalSection(&d->cs);
1596 DeleteCriticalSection(&d->cs);
1600 SetWindowLongPtr(hwnd, DWLP_USER, 0);
1607 khui_new_creds_by_type * nct;
1609 d = (afs_dlg_data *)(LONG_PTR)
1610 GetWindowLongPtr(hwnd, DWLP_USER);
1615 EnterCriticalSection(&d->cs);
1618 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1622 nc_dlg_hide_tooltip(hwnd, 0);
1624 /* Handle WM_COMMAND */
1626 case MAKEWPARAM(IDC_NCAFS_OBTAIN, BN_CLICKED):
1629 c = (SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN,
1635 khui_cw_enable_type(d->nc, afs_credtype_id, c);
1636 else if (d->config_dlg)
1637 khui_cfg_set_flags_inst(&d->cfg,
1638 KHUI_CNFLAG_MODIFIED,
1639 KHUI_CNFLAG_MODIFIED);
1640 nc_dlg_enable(hwnd, c);
1644 case MAKEWPARAM(IDC_NCAFS_ADD_TOKEN, BN_CLICKED):
1646 nc_dlg_add_token(hwnd);
1650 case MAKEWPARAM(IDC_NCAFS_DELETE_TOKEN, BN_CLICKED):
1652 nc_dlg_del_token(hwnd);
1657 LeaveCriticalSection(&d->cs);
1661 case KHUI_WM_NC_NOTIFY:
1664 khui_new_creds_by_type * nct;
1666 d = (afs_dlg_data *)(LONG_PTR)
1667 GetWindowLongPtr(hwnd, DWLP_USER);
1672 EnterCriticalSection(&d->cs);
1675 khui_cw_find_type(d->nc, afs_credtype_id, &nct);
1679 switch(HIWORD(wParam)) {
1680 case WMNC_DIALOG_SETUP:
1682 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL,
1683 CB_RESETCONTENT, 0, 0);
1685 /* load the LRU cells */
1691 if(khc_read_multi_string(csp_params, L"LRUCells",
1693 KHM_ERROR_TOO_LONG) {
1694 buf = PMALLOC(cbbuf);
1695 khc_read_multi_string(csp_params, L"LRUCells",
1699 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL,
1700 CB_ADDSTRING, 0, (LPARAM) s);
1707 /* now, if the root cell is not in the LRU, add it */
1712 if(!cm_GetRootCellName(buf)) {
1713 AnsiStrToUnicode(wbuf, sizeof(wbuf), buf);
1714 if(SendDlgItemMessage(hwnd,
1718 (LPARAM) wbuf) == CB_ERR) {
1719 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL,
1723 SendDlgItemMessage(hwnd, IDC_NCAFS_CELL,
1725 (WPARAM)-1, (LPARAM) wbuf);
1729 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1730 CB_RESETCONTENT, 0, 0);
1732 /* as for the realms, we have a special one here */
1737 LoadString(hResModule, IDS_NC_REALM_AUTO, wbuf,
1738 (int) ARRAYLENGTH(wbuf));
1739 idx = (int) SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1742 /* item data for the realm strings is the
1743 answer to the question, "is this the
1744 'determine realm automatically' item?" */
1745 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1746 CB_SETITEMDATA, idx, TRUE);
1747 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1749 (WPARAM)-1, (LPARAM) wbuf);
1752 /* load the LRU realms */
1759 if(khc_read_multi_string(csp_params, L"LRURealms",
1761 KHM_ERROR_TOO_LONG) {
1762 buf = PMALLOC(cbbuf);
1763 khc_read_multi_string(csp_params, L"LRURealms",
1767 if(SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1770 (LPARAM) s) == CB_ERR) {
1773 SendDlgItemMessage(hwnd,
1777 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1789 khui_cw_enable_type(d->nc, afs_credtype_id,
1792 nc_dlg_enable(hwnd, d->afs_enabled);
1794 afs_dlg_update_rows(hwnd, d);
1798 case WMNC_UPDATE_CREDTEXT:
1800 wchar_t wformat[256];
1805 PFREE(nct->credtext);
1806 nct->credtext = NULL;
1813 if (d->nc->n_identities == 0 ||
1814 KHM_FAILED(kcdb_identity_get_flags(d->nc->identities[0],
1816 !(flags & KCDB_IDENT_FLAG_VALID))
1817 /* in this case, we don't show any credential text */
1822 if(!d->afs_enabled) {
1823 LoadString(hResModule, IDS_AFS_CREDTEXT_DIS,
1824 wstr, ARRAYLENGTH(wstr));
1826 if(d->creds.n_rows == 0) {
1827 LoadString(hResModule, IDS_AFS_CREDTEXT_0,
1828 wstr, ARRAYLENGTH(wstr));
1829 } else if(d->creds.n_rows == 1) {
1830 LoadString(hResModule, IDS_AFS_CREDTEXT_1,
1831 wformat, ARRAYLENGTH(wformat));
1832 StringCbPrintf(wstr, sizeof(wstr), wformat,
1833 d->creds.rows[0].cell);
1836 wchar_t wcells[1024];
1838 LoadString(hResModule, IDS_AFS_CREDTEXT_N,
1839 wformat, ARRAYLENGTH(wformat));
1841 for(i=0; i<d->creds.n_rows; i++) {
1843 StringCbCat(wcells, sizeof(wcells),
1845 if(FAILED(StringCbCat(wcells,
1847 d->creds.rows[i].cell))) {
1849 /* looks like we overflowed */
1850 /* add an ellipsis at the end */
1851 StringCchLength(wcells, ARRAYLENGTH(wcells), &cch);
1852 cch = min(ARRAYLENGTH(wcells) - 4, cch);
1853 StringCchCopy(wcells + cch, 4, L"...");
1859 StringCbPrintf(wstr, sizeof(wstr), wformat, wcells);
1865 StringCbLength(wstr, sizeof(wstr), &cbs);
1866 cbs += sizeof(wchar_t);
1867 assert(nct->credtext == NULL);
1868 nct->credtext = PMALLOC(cbs);
1869 StringCbCopy(nct->credtext, cbs, wstr);
1871 /* something went wrong */
1872 nct->credtext = NULL;
1877 case WMNC_CREDTEXT_LINK:
1879 khui_htwnd_link * l;
1880 wchar_t wid[KHUI_MAXCCH_HTLINK_FIELD];
1883 l = (khui_htwnd_link *) lParam;
1885 StringCchCopyN(wid, ARRAYLENGTH(wid), l->id, l->id_len);
1886 wids = wcschr(wid, L':');
1897 if(!wcscmp(wids, L"Enable")) {
1898 SendDlgItemMessage(hwnd, IDC_NCAFS_OBTAIN,
1899 BM_SETCHECK, BST_CHECKED, 0);
1900 d->afs_enabled = TRUE;
1901 khui_cw_enable_type(d->nc, afs_credtype_id, TRUE);
1902 nc_dlg_enable(hwnd, TRUE);
1907 case WMNC_IDENTITY_CHANGE:
1908 kmq_post_sub_msg(afs_sub, KMSG_CRED,
1909 KMSG_CRED_DIALOG_NEW_IDENTITY, 0,
1913 case WMNC_AFS_UPDATE_ROWS:
1914 afs_dlg_update_rows(hwnd, d);
1920 PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
1921 MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);
1925 LeaveCriticalSection(&d->cs);
1930 if(wParam == IDC_NCAFS_TOKENLIST) {
1931 LPNMHDR lpnmh = (LPNMHDR) lParam;
1933 if(lpnmh->code == LVN_ITEMCHANGED) {
1934 /* when an item in the list view is clicked, we
1935 load the corresponding values into the edit and
1937 NMLISTVIEW *lpnmlv = (NMLISTVIEW *) lpnmh;
1944 if (!(lpnmlv->uChanged & LVIF_STATE) ||
1945 !(lpnmlv->uNewState & LVIS_SELECTED) ||
1946 (lpnmlv->iItem == -1))
1950 d = (afs_dlg_data *)(LONG_PTR)
1951 GetWindowLongPtr(hwnd, DWLP_USER);
1956 EnterCriticalSection(&d->cs);
1958 hw = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
1960 idx = lpnmlv->iItem;
1962 ZeroMemory(&lvi, sizeof(lvi));
1965 lvi.mask = LVIF_PARAM;
1967 if(!ListView_GetItem(hw, &lvi))
1968 goto _done_notify_select;
1970 /* ok, now lvi.lParam should be the row of the token */
1971 row = (int) lvi.lParam;
1972 if(row < 0 || row >= d->creds.n_rows)
1973 goto _done_notify_select;
1975 SetDlgItemText(hwnd, IDC_NCAFS_CELL,
1976 d->creds.rows[row].cell);
1977 if(d->creds.rows[row].realm != NULL) {
1978 SetDlgItemText(hwnd, IDC_NCAFS_REALM,
1979 d->creds.rows[row].realm);
1984 LoadString(hResModule, IDS_NC_REALM_AUTO, wbuf,
1986 idx = (int) SendDlgItemMessage(hwnd, IDC_NCAFS_REALM,
1990 SendDlgItemMessage(hwnd, IDC_NCAFS_REALM, CB_SETCURSEL,
1993 SendDlgItemMessage(hwnd, IDC_NCAFS_METHOD, CB_SETCURSEL,
1994 d->creds.rows[row].method, 0);
1995 _done_notify_select:
1996 LeaveCriticalSection(&d->cs);
1998 } else if (lpnmh->code == NM_DBLCLK) {
2000 LPNMITEMACTIVATE pnmi;
2008 d = (afs_dlg_data *)(LONG_PTR)
2009 GetWindowLongPtr(hwnd, DWLP_USER);
2014 EnterCriticalSection(&d->cs);
2016 pnmi = (LPNMITEMACTIVATE) lpnmh;
2018 hw = GetDlgItem(hwnd, IDC_NCAFS_TOKENLIST);
2020 ZeroMemory(&lvi, sizeof(lvi));
2021 lvi.iItem = pnmi->iItem;
2023 lvi.mask = LVIF_PARAM;
2025 if (!ListView_GetItem(hw, &lvi))
2026 goto _done_notify_click;
2028 row = (int) lvi.lParam;
2029 if(row < 0 || row >= d->creds.n_rows)
2030 goto _done_notify_click;
2032 ListView_GetItemRect(hw, pnmi->iItem, &r, LVIR_SELECTBOUNDS);
2033 x = (r.left + r.right) / 2;
2036 GetWindowRect(hw, &r);
2040 if (d->creds.rows[row].flags & DLGROW_FLAG_NOTOWNED) {
2041 nc_dlg_show_tooltip(hwnd, 0,
2042 MAKEINTRESOURCE(IDS_NC_TT_CONFLICTD),
2043 MAKEINTRESOURCE(IDS_NC_TT_PROBLEM),
2046 } else if (d->creds.rows[row].flags &
2047 DLGROW_FLAG_EXPIRED) {
2048 nc_dlg_show_tooltip(hwnd, 0,
2049 MAKEINTRESOURCE(IDS_NC_TT_EXPIRED),
2050 MAKEINTRESOURCE(IDS_NC_TT_DETAILS),
2053 } else if (d->creds.rows[row].flags &
2054 DLGROW_FLAG_EXISTS) {
2055 nc_dlg_show_tooltip(hwnd, 0,
2056 MAKEINTRESOURCE(IDS_NC_TT_EXISTS),
2057 MAKEINTRESOURCE(IDS_NC_TT_DETAILS),
2060 nc_dlg_show_tooltip(hwnd, 0,
2061 MAKEINTRESOURCE(IDS_NC_TT_NEW),
2062 MAKEINTRESOURCE(IDS_NC_TT_DETAILS),
2067 LeaveCriticalSection(&d->cs);
2074 if(wParam == DLG_TOOLTIP_TIMER_ID) {
2075 KillTimer(hwnd, DLG_TOOLTIP_TIMER_ID);
2076 nc_dlg_hide_tooltip(hwnd, 0);
2083 static const DWORD ctx_help[] = {
2084 IDC_NCAFS_OBTAIN, IDH_OBTAIN,
2085 IDC_NCAFS_CELL, IDH_CELL,
2086 IDC_NCAFS_REALM, IDH_REALM,
2087 IDC_NCAFS_METHOD, IDH_METHOD,
2088 IDC_NCAFS_ADD_TOKEN, IDH_ADD,
2089 IDC_NCAFS_DELETE_TOKEN, IDH_DELETE,
2090 IDC_NCAFS_TOKENLIST, IDH_TOKENLIST,
2096 hlp = (LPHELPINFO) lParam;
2098 if (hlp->iContextType != HELPINFO_WINDOW)
2101 afs_html_help(hlp->hItemHandle, L"::/popups_newcred.txt",
2102 HH_TP_HELP_WM_HELP, (DWORD_PTR) ctx_help);
2105 } /* switch(uMsg) */
2111 /* passed in to kcdb_credset_apply along with the afs_credset to adjust
2112 newly acquired credentials to include informatino derived from the
2113 new creds operation */
2115 afs_adjust_token_ident_proc(khm_handle cred, void * vd)
2117 wchar_t cell[MAXCELLCHARS];
2118 afs_ident_token_set * b = (afs_ident_token_set *) vd;
2125 /* ASSUMPTION: for each user, there can be tokens for only one
2128 cbbuf = sizeof(cell);
2130 if(KHM_FAILED(kcdb_cred_get_attr(cred, afs_attr_cell, NULL, cell, &cbbuf)))
2131 return KHM_ERROR_SUCCESS; /* remember, kcdb doesn't care if
2132 this run succeeded or not. all
2133 it wants to know if whether or
2134 not we want to continue the
2137 for(i=0; i<l->n_rows; i++) {
2138 if((l->rows[i].flags & DLGROW_FLAG_DONE) &&
2139 !_wcsicmp(cell, l->rows[i].cell)) {
2142 kcdb_cred_set_identity(cred, b->ident);
2143 if(l->rows[i].realm)
2144 kcdb_cred_set_attr(cred, afs_attr_realm, l->rows[i].realm,
2145 (khm_size)KCDB_CBSIZE_AUTO);
2147 kcdb_cred_set_attr(cred, afs_attr_realm, NULL, 0);
2149 method = l->rows[i].method;
2150 kcdb_cred_set_attr(cred, afs_attr_method, &method,
2151 (khm_size)KCDB_CBSIZE_AUTO);
2157 return KHM_ERROR_SUCCESS;
2161 afs_cred_write_ident_data(afs_dlg_data * d) {
2162 wchar_t * lru_cell = NULL;
2163 wchar_t * lru_realm = NULL;
2164 wchar_t * id_cell = NULL;
2170 khm_handle h_idc = NULL;
2171 khm_handle h_afs = NULL;
2172 khm_handle h_acells = NULL;
2173 khm_handle h_cellmap = NULL;
2174 wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
2175 khm_handle ident = NULL;
2182 d->nc->n_identities > 0 &&
2183 d->nc->identities[0])
2185 ident = d->nc->identities[0];
2187 else if (d->config_dlg)
2194 cbt = sizeof(idname);
2195 kcdb_identity_get_name(ident, idname, &cbt);
2197 khc_open_space(csp_afscred, L"Cells", 0, &h_cellmap);
2200 if(KHM_SUCCEEDED(kcdb_identity_get_config(ident,
2203 khc_open_space(h_idc, CSNAME_AFSCRED,
2204 KHM_FLAG_CREATE, &h_afs);
2208 khc_open_space(h_afs, L"Cells", KHM_FLAG_CREATE,
2214 khc_write_int32(h_afs, L"AFSEnabled",
2218 if(khc_read_multi_string(csp_params,
2221 &cbcell) == KHM_ERROR_TOO_LONG) {
2222 cbcell += MAXCELLCHARS * sizeof(wchar_t) *
2224 lru_cell = PMALLOC(cbcell);
2225 ZeroMemory(lru_cell, cbcell);
2228 khc_read_multi_string(csp_params,
2233 cbcell = MAXCELLCHARS * sizeof(wchar_t) * l->n_rows + sizeof(wchar_t);
2234 if (l->n_rows > 0) {
2235 lru_cell = PMALLOC(cbcell);
2236 ZeroMemory(lru_cell, cbcell);
2243 if(khc_read_multi_string(csp_params,
2246 &cbrealm) == KHM_ERROR_TOO_LONG) {
2247 cbrealm += MAXCELLCHARS * sizeof(wchar_t) * l->n_rows;
2248 lru_realm = PMALLOC(cbrealm);
2249 ZeroMemory(lru_realm, cbrealm);
2252 khc_read_multi_string(csp_params,
2257 cbrealm = MAXCELLCHARS * sizeof(wchar_t) * l->n_rows + sizeof(wchar_t);
2258 if (l->n_rows > 0) {
2259 lru_realm = PMALLOC(cbrealm);
2260 ZeroMemory(lru_realm, cbrealm);
2267 cbidcell = MAXCELLCHARS * sizeof(wchar_t) * l->n_rows + sizeof(wchar_t);
2268 if (l->n_rows > 0) {
2269 id_cell = PMALLOC(cbidcell);
2270 ZeroMemory(id_cell, cbidcell);
2276 for(i=0; i < l->n_rows; i++)
2277 if(!(l->rows[i].flags & DLGROW_FLAG_DELETED)) {
2278 khm_handle h_acell = NULL;
2280 if(!multi_string_find(lru_cell,
2281 l->rows[i].cell, 0)) {
2283 multi_string_append(lru_cell, &cbz,
2287 if(l->rows[i].realm &&
2288 !multi_string_find(lru_realm,
2289 l->rows[i].realm, 0)) {
2291 multi_string_append(lru_realm, &cbz,
2296 multi_string_append(id_cell, &cbz,
2300 KHM_SUCCEEDED(khc_open_space(h_acells,
2304 wchar_t methodname[KHUI_MAXCCH_NAME];
2306 afs_get_method_name(l->rows[i].method,
2308 sizeof(methodname));
2310 khc_write_string(h_acell, L"MethodName",
2313 if(l->rows[i].realm)
2314 khc_write_string(h_acell, L"Realm",
2317 khc_write_string(h_acell, L"Realm", L"");
2318 khc_close_space(h_acell);
2321 if (l->rows[i].flags & DLGROW_FLAG_DONE) {
2323 khc_write_string(h_cellmap,
2331 khc_write_multi_string(csp_params,
2332 L"LRUCells", lru_cell);
2334 khc_write_multi_string(csp_params,
2335 L"LRURealms", lru_realm);
2337 khc_write_multi_string(h_afs, L"Cells",
2340 khc_write_multi_string(h_afs, L"Cells", L"\0");
2342 if (d->config_dlg) {
2344 khui_cfg_set_flags_inst(&d->cfg, KHUI_CNFLAG_APPLIED,
2345 KHUI_CNFLAG_APPLIED |
2346 KHUI_CNFLAG_MODIFIED);
2348 khui_cfg_set_flags_inst(&d->cfg, 0,
2349 KHUI_CNFLAG_MODIFIED);
2355 khc_close_space(h_cellmap);
2357 khc_close_space(h_idc);
2359 khc_close_space(h_afs);
2361 khc_close_space(h_acells);
2371 afs_msg_newcred(khm_int32 msg_subtype,
2375 switch(msg_subtype) {
2376 case KMSG_CRED_NEW_CREDS:
2378 khui_new_creds * nc;
2379 khui_new_creds_by_type * nct;
2383 nc = (khui_new_creds *) vparam;
2385 nct = PMALLOC(sizeof(*nct));
2386 ZeroMemory(nct, sizeof(*nct));
2388 nct->type = afs_credtype_id;
2391 LoadString(hResModule, IDS_AFS_NAME, wbuf, ARRAYLENGTH(wbuf));
2392 StringCbLength(wbuf, sizeof(wbuf), &cbsize);
2393 cbsize += sizeof(wchar_t);
2395 nct->name = PMALLOC(cbsize);
2396 StringCbCopy(nct->name, cbsize, wbuf);
2398 nct->h_module = hResModule;
2399 nct->dlg_proc = afs_dlg_proc;
2400 nct->dlg_template = MAKEINTRESOURCE(IDD_NC_AFS);
2401 nct->type_deps[nct->n_type_deps++] = krb5_credtype_id;
2403 if (krb4_credtype_id < 0) {
2404 kcdb_credtype_get_id(KRB4_CREDTYPE_NAME,
2407 if (krb4_credtype_id >= 0) {
2408 nct->type_deps[nct->n_type_deps++] =
2412 khui_cw_add_type(nc, nct);
2416 case KMSG_CRED_RENEW_CREDS:
2418 khui_new_creds * nc;
2419 khui_new_creds_by_type * nct;
2421 nc = (khui_new_creds *) vparam;
2423 nct = PMALLOC(sizeof(*nct));
2424 ZeroMemory(nct, sizeof(*nct));
2426 nct->type = afs_credtype_id;
2427 nct->type_deps[nct->n_type_deps++] = krb5_credtype_id;
2428 if (krb4_credtype_id < 0) {
2429 kcdb_credtype_get_id(KRB4_CREDTYPE_NAME,
2432 if (krb4_credtype_id >= 0) {
2433 nct->type_deps[nct->n_type_deps++] =
2437 khui_cw_add_type(nc, nct);
2441 case KMSG_CRED_DIALOG_PRESTART:
2443 khui_new_creds * nc;
2444 khui_new_creds_by_type * nct = NULL;
2447 nc = (khui_new_creds *) vparam;
2448 khui_cw_find_type(nc, afs_credtype_id, &nct);
2453 hwnd = nct->hwnd_panel;
2457 PostMessage(hwnd, KHUI_WM_NC_NOTIFY,
2458 MAKEWPARAM(0,WMNC_DIALOG_SETUP), 0);
2462 case KMSG_CRED_DIALOG_NEW_IDENTITY:
2464 khui_new_creds * nc;
2465 khui_new_creds_by_type * nct = NULL;
2468 nc = (khui_new_creds *) vparam;
2469 khui_cw_find_type(nc, afs_credtype_id, &nct);
2474 d = (afs_dlg_data *) nct->aux;
2479 EnterCriticalSection(&d->cs);
2481 if (nct->aux == 0) {
2482 LeaveCriticalSection(&d->cs);
2486 /* we should load up the selected tokens for this
2488 if(nc->n_identities == 0) {
2489 LeaveCriticalSection(&d->cs);
2490 /* no identities selected. nothing to do */
2494 afs_cred_get_identity_creds(&d->creds, nc->identities[0],
2497 LeaveCriticalSection(&d->cs);
2499 PostMessage(nct->hwnd_panel, KHUI_WM_NC_NOTIFY,
2500 MAKEWPARAM(0, WMNC_AFS_UPDATE_ROWS), 0);
2504 case KMSG_CRED_PROCESS:
2506 khui_new_creds * nc;
2507 khui_new_creds_by_type * nct = NULL;
2508 afs_cred_list tlist;
2511 BOOL failed = FALSE; /* one or more cells failed */
2512 BOOL succeeded = FALSE; /* one or more cells succeeded */
2513 BOOL free_tlist = FALSE;
2514 khm_handle ident = NULL;
2515 afs_dlg_data * d = NULL;
2516 BOOL get_tokens = TRUE;
2517 BOOL ident_renew_triggered = TRUE;
2518 khm_handle csp_afscred = NULL;
2519 khm_handle csp_cells = NULL;
2521 nc = (khui_new_creds *) vparam;
2522 khui_cw_find_type(nc, afs_credtype_id, &nct);
2528 _report_cs0(KHERR_INFO,
2529 L"Getting AFS tokens...");
2532 if(nc->result != KHUI_NC_RESULT_PROCESS &&
2533 nc->subtype != KMSG_CRED_RENEW_CREDS) {
2535 khui_cw_set_response(nc, afs_credtype_id,
2536 KHUI_NC_RESPONSE_SUCCESS);
2538 _report_cs0(KHERR_INFO,
2544 /* we can't proceed if Kerberos 5 has failed */
2545 if(!khui_cw_type_succeeded(nc, krb5_credtype_id)) {
2546 khui_cw_set_response(nc, afs_credtype_id,
2547 KHUI_NC_RESPONSE_FAILED);
2549 _report_cs0(KHERR_INFO,
2550 L"Kerberos 5 plugin failed to process credentials request. Aborting");
2555 if (nc->subtype == KMSG_CRED_RENEW_CREDS) {
2557 if (nc->ctx.scope == KHUI_SCOPE_IDENT ||
2559 (nc->ctx.scope == KHUI_SCOPE_CREDTYPE &&
2560 nc->ctx.cred_type == afs_credtype_id) ||
2562 (nc->ctx.scope == KHUI_SCOPE_CRED &&
2563 nc->ctx.cred_type == afs_credtype_id)) {
2565 _report_cs1(KHERR_INFO,
2566 L"AFS Renew Creds :: ident %1!p!",
2567 _cptr(nc->ctx.identity));
2571 _report_cs0(KHERR_INFO,
2572 L"Renew request not applicable to AFS");
2578 if (nc->ctx.identity != NULL) {
2579 ident = nc->ctx.identity;
2581 khui_cw_set_response(nc, afs_credtype_id,
2582 KHUI_NC_RESPONSE_FAILED);
2584 _report_cs0(KHERR_INFO,
2585 L"No identity specified. Aborting");
2590 ZeroMemory(&tlist, sizeof(tlist));
2594 afs_cred_get_identity_creds(l, ident, NULL);
2596 /* if the identity has any tokens associated with it
2597 that aren't persistent, we should renew those as
2599 afs_cred_get_context_creds(l, &nc->ctx);
2601 if (nc->ctx.scope == KHUI_SCOPE_CREDTYPE ||
2602 nc->ctx.scope == KHUI_SCOPE_CRED) {
2604 ident_renew_triggered = FALSE;
2609 _report_cs1(KHERR_INFO,
2610 L"AFS New Creds :: ident %1!p!",
2611 _cptr(nc->identities[0]));
2613 d = (afs_dlg_data *) nct->aux;
2615 _report_cs0(KHERR_INFO,
2616 L"No dialog data found. Aborting");
2618 khui_cw_set_response(nc, afs_credtype_id,
2619 KHUI_NC_RESPONSE_FAILED);
2624 EnterCriticalSection(&d->cs);
2628 ident = nc->identities[0];
2630 LeaveCriticalSection(&d->cs);
2632 _report_cs0(KHERR_INFO,
2633 L"No identity specified. Aborting");
2635 khui_cw_set_response(nc, afs_credtype_id,
2636 KHUI_NC_RESPONSE_FAILED);
2642 get_tokens = d->afs_enabled;
2648 if (KHM_SUCCEEDED(kmm_get_plugin_config(AFS_PLUGIN_NAME, 0,
2650 khc_open_space(csp_afscred, L"Cells", 0, &csp_cells);
2652 /* looks like k5 worked. Now see about getting those
2654 for(i=0; i<l->n_rows; i++) {
2656 char cell[MAXCELLCHARS];
2657 char realm[MAXCELLCHARS];
2658 char linkedCell[MAXCELLCHARS]="";
2664 khm_int32 method = AFS_TOKEN_AUTO;
2665 khm_handle csp_cell = NULL;
2666 BOOL bgetLinked = 0;
2668 if (l->rows[i].flags &
2669 (DLGROW_FLAG_DONE | DLGROW_FLAG_DELETED))
2673 ZeroMemory(cell, sizeof(cell));
2674 ZeroMemory(realm, sizeof(realm));
2676 UnicodeStrToAnsi(cell, sizeof(cell), l->rows[i].cell);
2677 if (l->rows[i].realm != NULL)
2678 UnicodeStrToAnsi(realm, sizeof(realm),
2681 ZeroMemory(&ft_old, sizeof(ft_old));
2683 if (!ident_renew_triggered &&
2684 (ctoken = afs_find_token(NULL, l->rows[i].cell))) {
2686 cb = sizeof(ft_old);
2687 kcdb_cred_get_attr(ctoken, KCDB_ATTR_EXPIRE,
2688 NULL, &ft_old, &cb);
2690 kcdb_cred_release(ctoken);
2693 if (l->rows[i].method == AFS_TOKEN_AUTO && csp_cells &&
2694 KHM_SUCCEEDED(khc_open_space(csp_cells,
2698 if (KHM_FAILED(khc_read_int32(csp_cell, L"Method", &method))) {
2699 method = l->rows[i].method;
2701 _report_cs3(KHERR_INFO,
2702 L"Overriding method %1!d! with global default %2!d! for cell %3!s!",
2703 _int32(l->rows[i].method),
2705 _cstr(l->rows[i].cell));
2709 khc_close_space(csp_cell);
2711 method = l->rows[i].method;
2715 _report_cs3(KHERR_INFO,
2716 L"Getting tokens for cell %1!S! with realm %2!S! using method %3!d!",
2717 _cstr(bgetLinked ? linkedCell: cell),
2723 code = afs_klog(ident, "",
2724 bgetLinked ? linkedCell : cell,
2727 bgetLinked ? NULL :linkedCell);
2729 _report_cs1(KHERR_INFO,
2730 L"klog returns code %1!d!",
2735 l->rows[i].flags &= ~DLGROW_FLAG_DONE;
2737 if (!kherr_is_error()) {
2738 /* failed to get tokens, but no error was reported */
2739 _report_sr1(KHERR_ERROR, IDS_ERR_GENERAL,
2745 l->rows[i].flags |= DLGROW_FLAG_DONE;
2749 !ident_renew_triggered) {
2750 TimetToFileTime(new_exp, &ft_new);
2752 if (CompareFileTime(&ft_old, &ft_new) >= 0) {
2753 /* getting a new token didn't improve the
2754 situation much. We only get here if we
2755 were trying to renew tokens. So we try
2756 to trigger an identity renewal. Doing
2757 so should get us new initial tickets
2758 which will allow us to get a better
2761 khui_action_context ctx;
2763 _reportf(L"Renewal of AFS tokens for cell %s failed to get a longer token. Triggering identity renewal", l->rows[i].cell);
2765 khui_context_create(&ctx,
2768 KCDB_CREDTYPE_INVALID,
2770 khui_action_trigger(KHUI_ACTION_RENEW_CRED,
2773 khui_context_release(&ctx);
2775 ident_renew_triggered = TRUE;
2779 if ( !bgetLinked && linkedCell[0] ) {
2789 /* we should indicate errors if anything went wrong */
2790 khui_cw_set_response(nc, afs_credtype_id,
2791 KHUI_NC_RESPONSE_FAILED);
2793 khui_cw_set_response(nc, afs_credtype_id,
2794 KHUI_NC_RESPONSE_SUCCESS);
2797 if (succeeded && nc->subtype == KMSG_CRED_RENEW_CREDS) {
2798 afs_ident_token_set b;
2800 afs_list_tokens_internal();
2802 /* the tokens that we just acquired need adjusting to
2803 include the realm, method and identity information
2804 derived from the new creds operation. this is done
2805 in afs_adjust_token_ident_proc */
2809 b.update_info = FALSE;
2811 kcdb_credset_apply(afs_credset, afs_adjust_token_ident_proc,
2814 kcdb_credset_collect(NULL, afs_credset, NULL,
2815 afs_credtype_id, NULL);
2817 } else if (nc->subtype == KMSG_CRED_NEW_CREDS) {
2818 afs_ident_token_set b;
2820 afs_list_tokens_internal();
2822 /* the tokens that we just acquired need adjusting to
2823 include the realm, method and identity information
2824 derived from the new creds operation. this is done
2825 in afs_adjust_token_ident_proc */
2829 b.update_info = FALSE;
2831 kcdb_credset_apply(afs_credset, afs_adjust_token_ident_proc,
2834 kcdb_credset_collect(NULL, afs_credset, NULL,
2835 afs_credtype_id, NULL);
2837 afs_cred_write_ident_data(d);
2841 LeaveCriticalSection(&d->cs);
2844 afs_cred_free_rows(&tlist);
2848 khc_close_space(csp_afscred);
2851 khc_close_space(csp_cells);
2859 khui_new_creds * nc;
2860 khui_new_creds_by_type * nct;
2862 nc = (khui_new_creds *) vparam;
2863 khui_cw_find_type(nc, afs_credtype_id, &nct);
2868 khui_cw_del_type(nc, afs_credtype_id);
2873 PFREE(nct->credtext);
2880 return KHM_ERROR_SUCCESS;