From 4a1a867562bbc20ef769e3f556a69767b236433f Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 29 Mar 2007 21:19:43 +0000 Subject: [PATCH] more bug fixes for NIM 1.2 (KFW 3.2) netidmgr.exe - Credentials display : - If an outline is marked as KHUI_CW_O_STICKY | KHUI_CW_O_RELIDENT, release the identity when deleting the outline node. - Correctly determine the location of UI widgets using the column specifier of the outline node instead of the column specifier of the row. - Do not recompute the extents of a row. - If there is a default identity and it has no credentials and it is not pinned, display it anyway. krb5common.obj - Import profile_rename_section() krb5cred.dll - In the realm editor: - When writing realm data, keep track of whether any updates were performed. - Reset the dirty bits for each element whose changes were written to the profile. - Use profile_rename_section() correctly to delete sections. - Check if any changes were applied before setting the 'applied' bit for the configuration node. - Don't assume that the Kerberos 5 General configuration panel has received WMCFG_APPLY before the realm editor. It will not receive the notification if it hasn't indicated that there are changes to be applied. - New credentials : - If there is no "ExpiresOn" value for a cached prompt set, assume that it has already expired. - Set the lifetime for a new prompt set to be 7 days longer than then maximum renewable lifetime. ticket: new component: windows tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19307 dc483132-0cff-0310-8789-dd5450dbe970 --- .../identity/plugins/common/dynimport.c | 2 + .../identity/plugins/common/dynimport.h | 1 + .../identity/plugins/krb5/krb5configdlg.c | 69 ++++++-- .../identity/plugins/krb5/krb5newcreds.c | 23 ++- src/windows/identity/ui/credwnd.c | 157 +++++++++--------- src/windows/identity/ui/credwnd.h | 1 + 6 files changed, 143 insertions(+), 110 deletions(-) diff --git a/src/windows/identity/plugins/common/dynimport.c b/src/windows/identity/plugins/common/dynimport.c index d891af122..f49987ca7 100644 --- a/src/windows/identity/plugins/common/dynimport.c +++ b/src/windows/identity/plugins/common/dynimport.c @@ -168,6 +168,7 @@ DECL_FUNC_PTR(profile_clear_relation); DECL_FUNC_PTR(profile_add_relation); DECL_FUNC_PTR(profile_update_relation); DECL_FUNC_PTR(profile_release_string); +DECL_FUNC_PTR(profile_rename_section); // Service functions DECL_FUNC_PTR(OpenSCManagerA); @@ -315,6 +316,7 @@ FUNC_INFO profile_fi[] = { MAKE_FUNC_INFO(profile_add_relation), MAKE_FUNC_INFO(profile_update_relation), MAKE_FUNC_INFO(profile_release_string), + MAKE_FUNC_INFO(profile_rename_section), END_FUNC_INFO }; diff --git a/src/windows/identity/plugins/common/dynimport.h b/src/windows/identity/plugins/common/dynimport.h index 0f2cc237d..7f3f598b0 100644 --- a/src/windows/identity/plugins/common/dynimport.h +++ b/src/windows/identity/plugins/common/dynimport.h @@ -291,6 +291,7 @@ extern DECL_FUNC_PTR(profile_clear_relation); extern DECL_FUNC_PTR(profile_add_relation); extern DECL_FUNC_PTR(profile_update_relation); extern DECL_FUNC_PTR(profile_release_string); +extern DECL_FUNC_PTR(profile_rename_section); // Service functions extern DECL_FUNC_PTR(OpenSCManagerA); diff --git a/src/windows/identity/plugins/krb5/krb5configdlg.c b/src/windows/identity/plugins/krb5/krb5configdlg.c index 2d1e3259c..36936cdea 100644 --- a/src/windows/identity/plugins/krb5/krb5configdlg.c +++ b/src/windows/identity/plugins/krb5/krb5configdlg.c @@ -234,6 +234,7 @@ k5_is_profile_loaded(void) { assert(pprofile_add_relation); assert(pprofile_update_relation); assert(pprofile_flush); + assert(pprofile_rename_section); #endif if (!pprofile_init || @@ -247,7 +248,8 @@ k5_is_profile_loaded(void) { !pprofile_clear_relation || !pprofile_add_relation || !pprofile_update_relation || - !pprofile_flush) + !pprofile_flush || + !pprofile_rename_section) return FALSE; @@ -529,7 +531,7 @@ k5_read_config_data(k5_config_data * d) { d->flags = 0; } -void +int k5_write_config_data(k5_config_data * d) { char astr[MAX_PATH * 2]; char config_file[MAX_PATH]; @@ -537,22 +539,25 @@ k5_write_config_data(k5_config_data * d) { const char *filenames[2]; long rv; khm_size s; + int applied = FALSE; if (d->flags == 0) - return; + return FALSE; if (!k5_is_profile_loaded()) - return; + return FALSE; /* write the MSLSA import setting */ if (d->flags & K5_CDFLAG_MOD_LSA_IMPORT) { khc_write_int32(csp_params, L"MsLsaImport", d->lsa_import); d->flags &= ~K5_CDFLAG_MOD_LSA_IMPORT; + applied = TRUE; } if (d->flags & K5_CDFLAG_MOD_INC_REALMS) { khc_write_int32(csp_params, L"UseFullRealmList", d->inc_realms); d->flags &= ~K5_CDFLAG_MOD_INC_REALMS; + applied = TRUE; } if (!(d->flags & @@ -566,7 +571,7 @@ k5_write_config_data(k5_config_data * d) { K5_CDFLAG_MOD_REALMS))) { d->flags = 0; - return; + return applied; } khm_krb5_get_profile_file(config_file, ARRAYLENGTH(config_file)); @@ -620,6 +625,7 @@ k5_write_config_data(k5_config_data * d) { rv = pprofile_add_relation(profile, sec_libdefaults, defrealm); + applied = TRUE; } d->flags &= ~K5_CDFLAG_MOD_DEF_REALM; } @@ -635,6 +641,7 @@ k5_write_config_data(k5_config_data * d) { KRB5_CONF_YES: KRB5_CONF_NO); d->flags &= ~K5_CDFLAG_MOD_DNS_LOOKUP_KDC; + applied = TRUE; } if (d->flags & K5_CDFLAG_MOD_DNS_LOOKUP_RLM) { @@ -649,6 +656,7 @@ k5_write_config_data(k5_config_data * d) { KRB5_CONF_NO); d->flags &= ~K5_CDFLAG_MOD_DNS_LOOKUP_RLM; + applied = TRUE; } if (d->flags & K5_CDFLAG_MOD_DNS_FALLBACK) { @@ -663,6 +671,7 @@ k5_write_config_data(k5_config_data * d) { KRB5_CONF_NO); d->flags &= ~K5_CDFLAG_MOD_DNS_FALLBACK; + applied = TRUE; } if (d->flags & K5_CDFLAG_MOD_NOADDRESSES) { @@ -677,6 +686,7 @@ k5_write_config_data(k5_config_data * d) { KRB5_CONF_NO); d->flags &= ~K5_CDFLAG_MOD_NOADDRESSES; + applied = TRUE; } /* now we look at the [realms] section */ @@ -726,7 +736,10 @@ k5_write_config_data(k5_config_data * d) { pprofile_add_relation(profile, sec_admin, host); - d->realms[r].kdcs[k].flags &= ~K5_RKFLAG_NEW; + d->realms[r].kdcs[k].flags &= ~ (K5_RKFLAG_NEW | + K5_RKFLAG_MOD_MASTER | + K5_RKFLAG_MOD_ADMIN); + applied = TRUE; } } @@ -745,6 +758,7 @@ k5_write_config_data(k5_config_data * d) { is deleted and not in the profile file anymore. */ d->realms[r].domain_maps[m].flags |= K5_DMFLAG_NEW; + applied = TRUE; } else if (!(d->realms[r].domain_maps[m].flags & K5_DMFLAG_DELETED) && (d->realms[r].domain_maps[m].flags & @@ -753,10 +767,12 @@ k5_write_config_data(k5_config_data * d) { realm); d->realms[r].domain_maps[m].flags &= ~K5_DMFLAG_NEW; + applied = TRUE; } } - d->realms[r].flags &= ~K5_RDFLAG_NEW; + d->realms[r].flags &= ~(K5_RDFLAG_NEW | + K5_RDFLAG_MODIFED); } else if ((d->realms[r].flags & K5_RDFLAG_DELETED) && !(d->realms[r].flags & K5_RDFLAG_NEW)) { @@ -774,7 +790,10 @@ k5_write_config_data(k5_config_data * d) { sec_all[2] = values[v]; pprofile_clear_relation(profile, sec_all); } + sec_all[2] = NULL; + pprofile_rename_section(profile, sec_all, NULL); pprofile_free_list(values); + applied = TRUE; } rv = pprofile_get_relation_names(profile, sec_domain_realm, @@ -794,6 +813,7 @@ k5_write_config_data(k5_config_data * d) { values[v]); pprofile_clear_relation(profile, sec_domain_map); + applied = TRUE; } pprofile_release_string(maprealm); } @@ -806,7 +826,8 @@ k5_write_config_data(k5_config_data * d) { deleted and is not in the profile file. */ d->realms[r].flags |= K5_RDFLAG_NEW; - } else if (!(d->realms[r].flags & K5_RDFLAG_DELETED)) { + } else if (!(d->realms[r].flags & K5_RDFLAG_DELETED) && + (d->realms[r].flags & K5_RDFLAG_MODIFED)) { khm_size k; khm_size m; @@ -830,6 +851,8 @@ k5_write_config_data(k5_config_data * d) { pprofile_update_relation(profile, sec_master, host, NULL); + applied = TRUE; + /* as above, setting 'new' flag to indicate that the item does not exist in the profile file. */ @@ -849,7 +872,10 @@ k5_write_config_data(k5_config_data * d) { pprofile_add_relation(profile, sec_admin, host); - d->realms[r].kdcs[k].flags &= ~K5_RKFLAG_NEW; + d->realms[r].kdcs[k].flags &= ~(K5_RKFLAG_NEW | + K5_RKFLAG_MOD_ADMIN | + K5_RKFLAG_MOD_MASTER); + applied = TRUE; continue; } @@ -864,6 +890,7 @@ k5_write_config_data(k5_config_data * d) { host); } + applied = TRUE; d->realms[r].kdcs[k].flags &= ~K5_RKFLAG_MOD_MASTER; } @@ -878,6 +905,7 @@ k5_write_config_data(k5_config_data * d) { host, NULL); } + applied = TRUE; d->realms[r].kdcs[k].flags &= ~K5_RKFLAG_MOD_ADMIN; } } @@ -895,6 +923,7 @@ k5_write_config_data(k5_config_data * d) { pprofile_clear_relation(profile, sec_domain_map); d->realms[r].domain_maps[m].flags |= K5_DMFLAG_NEW; + applied = TRUE; } else if (!(d->realms[r].domain_maps[m].flags & K5_DMFLAG_DELETED) && @@ -905,6 +934,8 @@ k5_write_config_data(k5_config_data * d) { pprofile_add_relation(profile, sec_domain_map, realm); d->realms[r].domain_maps[m].flags &= ~K5_DMFLAG_NEW; + applied = TRUE; + } } @@ -945,6 +976,8 @@ k5_write_config_data(k5_config_data * d) { } d->flags = 0; + + return applied; } /* actual dialog stuff */ @@ -1199,13 +1232,14 @@ k5_config_dlgproc(HWND hwnd, if (HIWORD(wParam) == WMCFG_APPLY) { khm_int32 oflags; + int applied; oflags = d->flags; - k5_write_config_data(d); + applied = k5_write_config_data(d); if (d->flags != oflags) { khui_cfg_set_flags(d->node_main, - KHUI_CNFLAG_APPLIED, + (applied ? KHUI_CNFLAG_APPLIED : 0), KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED); } @@ -2664,12 +2698,11 @@ k5_realms_dlgproc(HWND hwnd, case KHUI_WM_CFG_NOTIFY: /* the realms dialog receives this notification after the top - level krb5 configuration panel has received it. Therefore, - we assume that any changes have already been applied. When - applying changes, we switch the mod bits off to indicate - that the changes have been written. We just have to - repaint the screen at this point. */ + level krb5 configuration panel has received it. */ if (HIWORD(wParam) == WMCFG_APPLY) { + int applied; + + applied = k5_write_config_data(d); k5_purge_config_data(d, TRUE, TRUE, TRUE); k5_update_realms_display(GetDlgItem(hwnd, IDC_CFG_REALMS), d); if (d->c_realm != -1) { @@ -2679,6 +2712,10 @@ k5_realms_dlgproc(HWND hwnd, k5_update_kdcs_display(GetDlgItem(hwnd, IDC_CFG_KDC), NULL, 0); k5_update_dmap_display(GetDlgItem(hwnd, IDC_CFG_DMAP), NULL, 0); } + khui_cfg_set_flags(d->node_realm, + (applied ? KHUI_CNFLAG_APPLIED : 0), + KHUI_CNFLAG_APPLIED); + } break; } diff --git a/src/windows/identity/plugins/krb5/krb5newcreds.c b/src/windows/identity/plugins/krb5/krb5newcreds.c index d52e934cc..b9f0c075e 100644 --- a/src/windows/identity/plugins/krb5/krb5newcreds.c +++ b/src/windows/identity/plugins/krb5/krb5newcreds.c @@ -775,19 +775,9 @@ k5_cached_kinit_prompter(void) { /* already expired */ goto _cleanup; } else { - FILETIME lifetime; - khm_int32 t; - - /* make the cache expire at some point */ - GetSystemTimeAsFileTime(¤t); - khc_read_int32(csp_params, L"PromptCacheLifetime", &t); - if (t == 0) - t = 172800; /* 48 hours */ - TimetToFileTimeInterval(t, &lifetime); - expiry = FtAdd(¤t, &lifetime); - iexpiry = FtToInt(&expiry); - - khc_write_int64(csp_prcache, L"ExpiresOn", iexpiry); + /* if there is no value for ExpiresOn, we assume the prompts + have already expired. */ + goto _cleanup; } /* we found a prompt cache. We take this to imply that the @@ -1167,9 +1157,16 @@ k5_kinit_prompter(krb5_context context, (khm_int32) num_prompts); GetSystemTimeAsFileTime(¤t); +#ifdef USE_PROMPT_CACHE_LIFETIME khc_read_int32(csp_params, L"PromptCacheLifetime", &t); if (t == 0) t = 172800; /* 48 hours */ +#else + khc_read_int32(csp_params, L"MaxRenewLifetime", &t); + if (t == 0) + t = 2592000; /* 30 days */ + t += 604800; /* + 7 days */ +#endif TimetToFileTimeInterval(t, &lifetime); expiry = FtAdd(¤t, &lifetime); iexpiry = FtToInt(&expiry); diff --git a/src/windows/identity/ui/credwnd.c b/src/windows/identity/ui/credwnd.c index b4982218e..4ed45e6d9 100644 --- a/src/windows/identity/ui/credwnd.c +++ b/src/windows/identity/ui/credwnd.c @@ -1037,7 +1037,8 @@ cw_del_outline(khui_credwnd_outline *o) { o->data) PFREE(o->data); - if ((o->flags & KHUI_CW_O_STICKY) && + if (((o->flags & KHUI_CW_O_STICKY) || + (o->flags & KHUI_CW_O_RELIDENT)) && o->data) kcdb_identity_release((khm_handle) o->data); @@ -1666,7 +1667,8 @@ cw_update_outline(khui_credwnd_tbl * tbl) prevcred = NULL; } - /* Add any sticky identities that we haven't seen yet */ + /* Add any default identities with no credentials and sticky + identities that we haven't seen yet */ if (n_grouping > 0 && tbl->cols[grouping[0]].attr_id == KCDB_ATTR_ID_NAME) { @@ -1678,6 +1680,56 @@ cw_update_outline(khui_credwnd_tbl * tbl) wchar_t ** idarray = NULL; int i; + /* see if the defualt identity is in the list */ + { + khm_handle id_def = NULL; + wchar_t idname[KCDB_IDENT_MAXCCH_NAME]; + khm_size cb; + khm_int32 flags; + + if (KHM_FAILED(kcdb_identity_get_default(&id_def))) { + goto done_with_defident; + } + + kcdb_identity_get_flags(id_def, &flags); + cb = sizeof(idname); + kcdb_identity_get_name(id_def, idname, &cb); + + for (o = tbl->outline; o; o = LNEXT(o)) { + if (!wcscmp(idname, o->header)) + break; + } + + if (o == NULL) { + o = cw_new_outline_node(idname); + LPUSH(&tbl->outline, o); + o->flags = KHUI_CW_O_VISIBLE | KHUI_CW_O_RELIDENT; + o->level = 0; + o->col = grouping[0]; + o->data = id_def; + o->attr_id = KCDB_ATTR_ID; + + if (flags & KCDB_IDENT_FLAG_STICKY) + o->flags |= KHUI_CW_O_STICKY; + + o->start = n_rows; + o->length = 1; + o->idx_start = -1; + + if (grouping[0] == tbl->n_cols - 1) + o->flags |= KHUI_CW_O_NOOUTLINE; + + cw_set_tbl_row_header(tbl, n_rows, grouping[0], o); + + n_rows ++; + } else { + kcdb_identity_release(id_def); + } + + done_with_defident: + ; + } + if (kcdb_identity_enum(KCDB_IDENT_FLAG_STICKY, KCDB_IDENT_FLAG_STICKY, NULL, @@ -1728,10 +1780,15 @@ cw_update_outline(khui_credwnd_tbl * tbl) } else { /* not found. create */ o = cw_new_outline_node(idarray[i]); + LPUSH(&tbl->outline, o); o->flags = KHUI_CW_O_VISIBLE; o->level = 0; o->col = grouping[0]; o->data = (void *) h; + o->attr_id = KCDB_ATTR_ID; + + if (grouping[0] == tbl->n_cols - 1) + o->flags |= KHUI_CW_O_NOOUTLINE; } if (o->flags & KHUI_CW_O_STICKY) @@ -3963,22 +4020,14 @@ cw_wm_mouse(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) x += tbl->scr_left; y += tbl->scr_top - tbl->header_height; - if (tbl->flags & KHUI_CW_TBL_EXPIDENT) { - int ty = 0; - - for (i=0; i < tbl->n_rows; i++) { - if (tbl->rows[i].flags & KHUI_CW_ROW_EXPVIEW) - ty += tbl->cell_height * CW_EXP_ROW_MULT; - else - ty += tbl->cell_height; + row = -1; - if (ty > y) - break; + for (i=0; i < tbl->n_rows; i++) { + if (y >= tbl->rows[i].r_ext.top && + y < tbl->rows[i].r_ext.bottom) { + row = i; + break; } - - row = i; - } else { - row = y / tbl->cell_height; } col = -1; @@ -4006,7 +4055,7 @@ cw_wm_mouse(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) o = (khui_credwnd_outline *) tbl->rows[row].data; /* are we on a widget then? */ - x -= tbl->cols[tbl->rows[row].col].x; + x -= tbl->cols[o->col].x; if (!(o->flags & KHUI_CW_O_NOOUTLINE)) { if(x >= 0 && x < KHUI_SMICON_CX) /* hit */ { @@ -4116,41 +4165,14 @@ cw_wm_mouse(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } if(tbl->mouse_state & CW_MOUSE_WSTICKY) { if (tbl->flags & KHUI_CW_TBL_EXPIDENT) { - int ty = 0; - for (i=0; i < tbl->n_rows && i < tbl->mouse_row; i++) { - if (tbl->rows[i].flags & KHUI_CW_ROW_EXPVIEW) - ty += tbl->cell_height * CW_EXP_ROW_MULT; - else - ty += tbl->cell_height; - } - - r.top = ty; - - if (tbl->mouse_row < tbl->n_rows && - (tbl->rows[tbl->mouse_row].flags & KHUI_CW_ROW_EXPVIEW)) { - r.bottom = r.top + tbl->cell_height * CW_EXP_ROW_MULT; - } else { - r.bottom = r.top + tbl->cell_height; - } - - if (tbl->mouse_row < tbl->n_rows && - (tbl->rows[tbl->mouse_row].flags & KHUI_CW_ROW_HEADER)) { - khui_credwnd_outline * o; - - o = (khui_credwnd_outline *) tbl->rows[tbl->mouse_row].data; - - if (o->flags & KHUI_CW_O_NOOUTLINE) { - r.left = tbl->cols[tbl->mouse_col].x - tbl->scr_left; - } else { - r.left = KHUI_SMICON_CX * 3 / 2 + tbl->cols[tbl->mouse_col].x - tbl->scr_left; - } + if (tbl->mouse_row >= 0 && tbl->mouse_row < tbl->n_rows) { + r = tbl->rows[tbl->mouse_row].r_ext; + OffsetRect(&r, -tbl->scr_left, tbl->header_height - tbl->scr_top); r.right = r.left + KHUI_SMICON_CX; - } else { -#ifdef DEBUG - assert(FALSE); -#endif + InvalidateRect(tbl->hwnd, &r, TRUE); } + } else { r.left = KHUI_SMICON_CX * 3 / 2 + tbl->cols[tbl->mouse_col].x - tbl->scr_left; @@ -4182,41 +4204,14 @@ cw_wm_mouse(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } if(tbl->mouse_state & CW_MOUSE_WSTICKY) { if (tbl->flags & KHUI_CW_TBL_EXPIDENT) { - int ty = 0; - - for (i=0; i < tbl->n_rows && i < tbl->mouse_row; i++) { - if (tbl->rows[i].flags & KHUI_CW_ROW_EXPVIEW) - ty += tbl->cell_height * CW_EXP_ROW_MULT; - else - ty += tbl->cell_height; - } - - r.top = ty; - - if (tbl->mouse_row < tbl->n_rows && - (tbl->rows[tbl->mouse_row].flags & KHUI_CW_ROW_EXPVIEW)) { - r.bottom = r.top + tbl->cell_height * CW_EXP_ROW_MULT; - } else { - r.bottom = r.top + tbl->cell_height; - } - if (tbl->mouse_row < tbl->n_rows && - (tbl->rows[tbl->mouse_row].flags & KHUI_CW_ROW_HEADER)) { - khui_credwnd_outline * o; - - o = (khui_credwnd_outline *) tbl->rows[tbl->mouse_row].data; - - if (o->flags & KHUI_CW_O_NOOUTLINE) { - r.left = tbl->cols[tbl->mouse_col].x - tbl->scr_left; - } else { - r.left = KHUI_SMICON_CX * 3 / 2 + tbl->cols[tbl->mouse_col].x - tbl->scr_left; - } + if (tbl->mouse_row >= 0 && tbl->mouse_row < tbl->n_rows) { + r = tbl->rows[tbl->mouse_row].r_ext; + OffsetRect(&r, -tbl->scr_left, tbl->header_height - tbl->scr_top); r.right = r.left + KHUI_SMICON_CX; - } else { -#ifdef DEBUG - assert(FALSE); -#endif + InvalidateRect(tbl->hwnd, &r, TRUE); } + } else { r.left = KHUI_SMICON_CX * 3 / 2 + tbl->cols[tbl->mouse_col].x - tbl->scr_left; diff --git a/src/windows/identity/ui/credwnd.h b/src/windows/identity/ui/credwnd.h index 42edf2842..7e7e63cba 100644 --- a/src/windows/identity/ui/credwnd.h +++ b/src/windows/identity/ui/credwnd.h @@ -68,6 +68,7 @@ typedef struct khui_credwnd_outline_t { #define KHUI_CW_O_SELECTED 0x00000010 #define KHUI_CW_O_DATAALLOC 0x00000020 #define KHUI_CW_O_NOOUTLINE 0x00000040 +#define KHUI_CW_O_RELIDENT 0x00000080 typedef struct khui_credwnd_row_t { khm_int32 flags; -- 2.26.2