diff options
| author | Jeffrey Altman <jaltman@secure-endpoints.com> | 2007-03-20 20:41:52 +0000 |
|---|---|---|
| committer | Jeffrey Altman <jaltman@secure-endpoints.com> | 2007-03-20 20:41:52 +0000 |
| commit | 25e6fa5ec31981a3ec7d732fad6e46a997d29654 (patch) | |
| tree | f732ebb7d679cab5fdb9fe9e22a1f35a08be417c /src/windows/identity/plugins | |
| parent | 6c634e12b354258537c1d8e263605cba07e4c5d7 (diff) | |
NIM: New Default View and miscellaneous fixes
================================
KfW 3.1 Alpha (NetIDMgr 1.1.11.0)
-- nidmgr32.dll
- Only one action in a menu is allowed to have KHUI_ACTIONREF_DEFAULT
flag set. This marks the action as being the default action for the
menu and will be rendered as such.
- Newly created identities start off with the KCDB_IDENT_FLAG_EMPTY
flag set. Once credentials are associated with the identity and the
identity is refreshed, the flag will be cleared.
- When creating actions, enforce the name length.
- khm_value_exists() now handles shadowed configuration spaces.
- Add new action KHUI_ACTION_LAYOUT_MINI which toggles between
'Advanced' and 'Basic' views.
- Add support for F11 and F12 keys in khui_get_cmd_accel_string().
- New option for alerts to indicate that instead of just setting the
response field in the alert, the UI should dispatch the command
that the user has selected.
-- krb5common.obj
- khm_krb5_initialize() can return a handle to a krb5_ccache that has
already been closed. Now it doesn't.
- Also import 'krb5_string_to_deltat()'.
- Work around conditioned symbol definitions in ntsecapi.h in the
Vista Platform SDK that affect Win 2000.
-- krb5cred.dll
- Don't clear the prompts when the options for an identity changes.
The prompter code relies on the prompts being around so that the
values that the user has entered can be retained if the new set of
prompts is the same as the old one.
- Use the same code in the new credentials acquisition and the
identity configuration code to obtain krb5 parameters for an
identity.
- Reset the 'IMPORTED' flag when we get new credentials using a
password.
- If the validity of a principal is not known, then we restrict the
options that can be specified when calling
krb5_get_init_creds_password() so that we can reliably determine if
the principal is valid. If we need to get new credentials for the
principal, we need to make another call using the correct options.
- The return codes from the prompter need to indicate that the
password read operation was cancelled instead of arbiraty non-zero
values.
- When reading identity settings, if a particular setting is not
defined in the registry, then default to reading the settings out of
krb5.ini.
- Refer to credentials as 'credentials' or 'tickets' instead of
'creds'.
- If an identity has imported credentials, don't import for the same
identity again.
- When importing an identity, create the identity configuration in the
registry if we don't already have any settings there.
- Work around conditioned symbol definitions in ntsecapi.h in the
Vista Platform SDK that affect Win 2000.
- Rearrange declarations for clarity.
- Use the correct APIs to parse configuration values from krb5.ini.
-- krb4cred.dll
- The dialog layout was updated to accomodate a localized string that
no longer fit in its control.
- Remove a spurious inclusion of ntsecapi.h and work around
conditioned symbol definition in the Vista Platform SDK.
-- netidmgr.exe
- Fix the menu creation code to correctly tag the default action so
that it will be rendered properly.
- Update the menu enumeration code to use documented functions instead
of accessing acton lists directly.
- Pool of per-identity actions now include a set of actions for
obtaining credentials for specific identities.
- The default action performed when the notification icon is clicked
is now configurable. When displaying the context menu in the
notification area, the default action is highlighted.
- Remove unnecessary handlers from the notifcation event handler.
- Only handle NIN_SELECT instead of both NIN_SELECT and WM_LBUTTONUP
in the notification event handler. When the user clicks the
notication icon, both events are generated. NIN_SELECT is canonical.
- When the handling NIN_BALLOONUSERCLICK in the notification event
handler, reset balloon_alert before displaying any new alerts so
that we won't overwrite it later.
- Reset the notification alert icon after displaying an alert.
- If a renewal fails, the displayed alert contains a button that the
user can click to initiate the process of acquiring new credentials
for the identity.
- Alerts can optionally dispatch the commands that were added to it
using the KHUI_ALERT_FLAG_DISPATCH_CMD flag.
- Increase the size of the About dialog.
- Correct the action text for the IDS_ACTION_OPEN_APP and
IDS_ACTION_CLOSE_APP to say 'Show' and 'Hide' instead of 'Open' and
'Close'. These actions only control the visible state of the NIM
window.
- Add additional notification which signals that the commandline has
finished processing.
- Add an 'acquire' action to the per-identity actions.
- The per identity actions (renew, destroy, acquire) now have useful
captions, names and tooltips.
- Use WM_NEXTDLGCTL message when changing the focus of dialog
controls. SetFocus() is insufficient.
- If we get a request to show a new credential acquisition dialog and
we are already showing one, bring that one to the foreground instead
of trying to display a new one or waiting quietly.
- New configuration schema for the UI that include definitions for the
new default view.
- The alerter window can now show more than one alert at once.
- If we are about to show queued alerts, then check if the alerts that
are waiting are related and if they can be grouped together. If so,
show them in a single alert window instead of multiple ones.
- If new alerts are issued while a set of alerts are being displayed
and if the new alert is related to the alerts that are being
displayed, then add the new alert to the list being displayed.
- Make sure we have a lock on the alert when we are manipulating or
accessing it.
- Set the focus to the correct control when displaying an alert.
- When adding alerts from the alert queue, make sure we iterate
through the queue properly.
- Allow keyboard navigation inside the alert window and support scroll
bars.
- Check if we have a valid code pointer before invoking a UI callback.
- Make sure the main window is in the normal configuration before
switching to a layout that rquires it.
- When moving the main window around, if it comes close to an edge of
the working area of the display, snap to it.
- Maintain two sets of settings for the main window placement. One
for the mini mode and one for the normal mode.
- When processing saved window placement information from the
configuration, handle docking hints which note which edges of the
screen the main window should be adjacent to, if any.
- Switching to the 'Basic' view disables the layout and column
selection menus.
- Position the new credentials dialog above the main window if the
main window is visible.
- The alert that is displayed to indicate that an identity has
expired, now contains a command button that can be used to invoke
the new credentials dialog for that identity.
-- source
- Update the documentation to reflect the change in behavior regarding
KHUI_ACTIONREF_DEFAULT in khui_menu_insert_action() and
khui_menu_insert_paction().
- Remove notes about menu access functions being not thread safe.
This is no longer true.
- Update the documentation for khui_alert_show() to document new
behavior regarding KHUI_ALERT_FLAG_DISPATCH_CMD.
- Update documentation to indicate which KHUI_ALERT_FLAG_* flags are
internal and document the new KHUI_ALERT_FLAG_DISPATCH_CMD flag.
- Augment the queue handling macros to support additional operations.
Also add new tree data structure with an ordered list of children.
- Code reorganization to reuse code for obtaining the caption and
tooltip for a system defined action in netidmgr.exe.
ticket: new
component: windows
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19238 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/windows/identity/plugins')
| -rw-r--r-- | src/windows/identity/plugins/common/dynimport.c | 4 | ||||
| -rw-r--r-- | src/windows/identity/plugins/common/dynimport.h | 13 | ||||
| -rw-r--r-- | src/windows/identity/plugins/common/krb5common.c | 4 | ||||
| -rw-r--r-- | src/windows/identity/plugins/krb4/krb4funcs.c | 1 | ||||
| -rw-r--r-- | src/windows/identity/plugins/krb4/krb4funcs.h | 13 | ||||
| -rw-r--r-- | src/windows/identity/plugins/krb4/lang/en_us/langres.rc | 2 | ||||
| -rw-r--r-- | src/windows/identity/plugins/krb5/krb5configdlg.c | 73 | ||||
| -rw-r--r-- | src/windows/identity/plugins/krb5/krb5funcs.c | 497 | ||||
| -rw-r--r-- | src/windows/identity/plugins/krb5/krb5funcs.h | 122 | ||||
| -rw-r--r-- | src/windows/identity/plugins/krb5/krb5newcreds.c | 343 | ||||
| -rw-r--r-- | src/windows/identity/plugins/krb5/krbcred.h | 6 | ||||
| -rw-r--r-- | src/windows/identity/plugins/krb5/lang/en_us/langres.rc | 3 |
12 files changed, 778 insertions, 303 deletions
diff --git a/src/windows/identity/plugins/common/dynimport.c b/src/windows/identity/plugins/common/dynimport.c index b3d764476..d891af122 100644 --- a/src/windows/identity/plugins/common/dynimport.c +++ b/src/windows/identity/plugins/common/dynimport.c @@ -144,6 +144,7 @@ DECL_FUNC_PTR(krb5_free_host_realm); DECL_FUNC_PTR(krb5_c_random_make_octets);
DECL_FUNC_PTR(krb5_free_addresses);
DECL_FUNC_PTR(krb5_free_default_realm);
+DECL_FUNC_PTR(krb5_string_to_deltat);
// Krb524 functions
DECL_FUNC_PTR(krb524_init_ets);
@@ -160,6 +161,7 @@ DECL_FUNC_PTR(profile_release); DECL_FUNC_PTR(profile_get_subsection_names);
DECL_FUNC_PTR(profile_free_list);
DECL_FUNC_PTR(profile_get_string);
+DECL_FUNC_PTR(profile_get_integer);
DECL_FUNC_PTR(profile_get_values);
DECL_FUNC_PTR(profile_get_relation_names);
DECL_FUNC_PTR(profile_clear_relation);
@@ -289,6 +291,7 @@ FUNC_INFO k5_fi[] = { MAKE_FUNC_INFO(krb5_free_host_realm),
MAKE_FUNC_INFO(krb5_c_random_make_octets),
MAKE_FUNC_INFO(krb5_free_default_realm),
+ MAKE_FUNC_INFO(krb5_string_to_deltat),
END_FUNC_INFO
};
@@ -305,6 +308,7 @@ FUNC_INFO profile_fi[] = { MAKE_FUNC_INFO(profile_get_subsection_names),
MAKE_FUNC_INFO(profile_free_list),
MAKE_FUNC_INFO(profile_get_string),
+ MAKE_FUNC_INFO(profile_get_integer),
MAKE_FUNC_INFO(profile_get_values),
MAKE_FUNC_INFO(profile_get_relation_names),
MAKE_FUNC_INFO(profile_clear_relation),
diff --git a/src/windows/identity/plugins/common/dynimport.h b/src/windows/identity/plugins/common/dynimport.h index a9561bc86..0f2cc237d 100644 --- a/src/windows/identity/plugins/common/dynimport.h +++ b/src/windows/identity/plugins/common/dynimport.h @@ -30,7 +30,18 @@ /* Dynamic imports */
#include<khdefs.h>
#include<tlhelp32.h>
+
+#if _WIN32_WINNT < 0x0501
+#define KHM_SAVE_WIN32_WINNT _WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
#include<ntsecapi.h>
+#ifdef KHM_SAVE_WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT KHM_SAVE_WIN32_WINNT
+#undef KHM_SAVE_WIN32_WINNT
+#endif
extern HINSTANCE hKrb4;
extern HINSTANCE hKrb5;
@@ -256,6 +267,7 @@ extern DECL_FUNC_PTR(krb5_get_host_realm); extern DECL_FUNC_PTR(krb5_free_host_realm);
extern DECL_FUNC_PTR(krb5_c_random_make_octets);
extern DECL_FUNC_PTR(krb5_free_default_realm);
+extern DECL_FUNC_PTR(krb5_string_to_deltat);
// Krb524 functions
extern DECL_FUNC_PTR(krb524_init_ets);
@@ -272,6 +284,7 @@ extern DECL_FUNC_PTR(profile_release); extern DECL_FUNC_PTR(profile_get_subsection_names);
extern DECL_FUNC_PTR(profile_free_list);
extern DECL_FUNC_PTR(profile_get_string);
+extern DECL_FUNC_PTR(profile_get_integer);
extern DECL_FUNC_PTR(profile_get_values);
extern DECL_FUNC_PTR(profile_get_relation_names);
extern DECL_FUNC_PTR(profile_clear_relation);
diff --git a/src/windows/identity/plugins/common/krb5common.c b/src/windows/identity/plugins/common/krb5common.c index 5ba59df4e..759641ff7 100644 --- a/src/windows/identity/plugins/common/krb5common.c +++ b/src/windows/identity/plugins/common/krb5common.c @@ -164,8 +164,10 @@ khm_krb5_initialize(khm_handle ident, khm_krb5_error(rc, "krb5_cc_set_flags()", 0, ctx,
cache);
else if ((rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) && *ctx != NULL) {
- if (*cache != NULL)
+ if (*cache != NULL) {
(*pkrb5_cc_close)(*ctx, *cache);
+ *cache = NULL;
+ }
}
return rc;
}
diff --git a/src/windows/identity/plugins/krb4/krb4funcs.c b/src/windows/identity/plugins/krb4/krb4funcs.c index 306437a00..b2b5fef4e 100644 --- a/src/windows/identity/plugins/krb4/krb4funcs.c +++ b/src/windows/identity/plugins/krb4/krb4funcs.c @@ -32,7 +32,6 @@ modified and adapted for NetIDMgr */ #define SECURITY_WIN32
#include <security.h>
-#include <ntsecapi.h>
#include <string.h>
#include <time.h>
diff --git a/src/windows/identity/plugins/krb4/krb4funcs.h b/src/windows/identity/plugins/krb4/krb4funcs.h index 742d13626..5ec11cc63 100644 --- a/src/windows/identity/plugins/krb4/krb4funcs.h +++ b/src/windows/identity/plugins/krb4/krb4funcs.h @@ -35,7 +35,18 @@ #include <windows.h>
#define SECURITY_WIN32
#include <security.h>
-#include <ntsecapi.h>
+
+#if _WIN32_WINNT < 0x0501
+#define KHM_SAVE_WIN32_WINNT _WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
+#include<ntsecapi.h>
+#ifdef KHM_SAVE_WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT KHM_SAVE_WIN32_WINNT
+#undef KHM_SAVE_WIN32_WINNT
+#endif
#include <krb5common.h>
diff --git a/src/windows/identity/plugins/krb4/lang/en_us/langres.rc b/src/windows/identity/plugins/krb4/lang/en_us/langres.rc index 374f6ced5..f7a849e24 100644 --- a/src/windows/identity/plugins/krb4/lang/en_us/langres.rc +++ b/src/windows/identity/plugins/krb4/lang/en_us/langres.rc @@ -95,7 +95,7 @@ EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "Obtain Kerberos v4 credentials for this identity",IDC_CFG_GETTIX,
- "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,7,7,147,10
+ "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,7,7,165,10
END
diff --git a/src/windows/identity/plugins/krb5/krb5configdlg.c b/src/windows/identity/plugins/krb5/krb5configdlg.c index 9c8af5dc4..2d1e3259c 100644 --- a/src/windows/identity/plugins/krb5/krb5configdlg.c +++ b/src/windows/identity/plugins/krb5/krb5configdlg.c @@ -120,35 +120,6 @@ typedef struct tag_k5_config_data { #define K5_CDFLAG_MOD_INC_REALMS 0x00000100 #define K5_CDFLAG_MOD_REALMS 0x00001000 -static const char *const conf_yes[] = { - "y", "yes", "true", "t", "1", "on", - 0, -}; - -static const char *const conf_no[] = { - "n", "no", "false", "nil", "0", "off", - 0, -}; - -int -k5_parse_boolean(const char *s) -{ - const char *const *p; - - for(p=conf_yes; *p; p++) { - if (!_stricmp(*p,s)) - return 1; - } - - for(p=conf_no; *p; p++) { - if (!_stricmp(*p,s)) - return 0; - } - - /* Default to "no" */ - return 0; -} - void k5_init_config_data(k5_config_data * d) { ZeroMemory(d, sizeof(*d)); @@ -325,7 +296,12 @@ k5_read_config_data(k5_config_data * d) { rv = pprofile_get_string(profile, "libdefaults", "dns_lookup_kdc", NULL, NULL, &boolv); if (!rv && boolv) { - d->dns_lookup_kdc = k5_parse_boolean(boolv); + khm_boolean b; + + if (!khm_krb5_parse_boolean(boolv, &b)) + d->dns_lookup_kdc = b; + else + d->dns_lookup_kdc = FALSE; pprofile_release_string(boolv); } else d->dns_lookup_kdc = FALSE; @@ -333,7 +309,12 @@ k5_read_config_data(k5_config_data * d) { rv = pprofile_get_string(profile, "libdefaults", "dns_lookup_realm", NULL, NULL, &boolv); if (!rv && boolv) { - d->dns_lookup_realm = k5_parse_boolean(boolv); + khm_boolean b; + + if (!khm_krb5_parse_boolean(boolv, &b)) + d->dns_lookup_realm = b; + else + d->dns_lookup_realm = FALSE; pprofile_release_string(boolv); } else d->dns_lookup_realm = FALSE; @@ -341,7 +322,12 @@ k5_read_config_data(k5_config_data * d) { rv = pprofile_get_string(profile, "libdefaults", "dns_fallback", NULL, NULL, &boolv); if (!rv && boolv) { - d->dns_fallback = k5_parse_boolean(boolv); + khm_boolean b; + + if (!khm_krb5_parse_boolean(boolv, &b)) + d->dns_fallback = b; + else + d->dns_fallback = FALSE; pprofile_release_string(boolv); } else d->dns_fallback = FALSE; @@ -349,7 +335,12 @@ k5_read_config_data(k5_config_data * d) { rv = pprofile_get_string(profile, "libdefaults", "noaddresses", NULL, NULL, &boolv); if (!rv && boolv) { - d->noaddresses = k5_parse_boolean(boolv); + khm_boolean b; + + if (!khm_krb5_parse_boolean(boolv, &b)) + d->noaddresses = b; + else + d->noaddresses = TRUE; pprofile_release_string(boolv); } else d->noaddresses = TRUE; @@ -641,8 +632,8 @@ k5_write_config_data(k5_config_data * d) { rv = pprofile_add_relation(profile, sec_libdefaults, (d->dns_lookup_kdc)? - conf_yes[0]: - conf_no[0]); + KRB5_CONF_YES: + KRB5_CONF_NO); d->flags &= ~K5_CDFLAG_MOD_DNS_LOOKUP_KDC; } @@ -654,8 +645,8 @@ k5_write_config_data(k5_config_data * d) { rv = pprofile_add_relation(profile, sec_libdefaults, (d->dns_lookup_realm)? - conf_yes[0]: - conf_no[0]); + KRB5_CONF_YES: + KRB5_CONF_NO); d->flags &= ~K5_CDFLAG_MOD_DNS_LOOKUP_RLM; } @@ -668,8 +659,8 @@ k5_write_config_data(k5_config_data * d) { rv = pprofile_add_relation(profile, sec_libdefaults, (d->dns_fallback)? - conf_yes[0]: - conf_no[0]); + KRB5_CONF_YES: + KRB5_CONF_NO); d->flags &= ~K5_CDFLAG_MOD_DNS_FALLBACK; } @@ -682,8 +673,8 @@ k5_write_config_data(k5_config_data * d) { rv = pprofile_add_relation(profile, sec_libdefaults, (d->noaddresses)? - conf_yes[0]: - conf_no[0]); + KRB5_CONF_YES: + KRB5_CONF_NO); d->flags &= ~K5_CDFLAG_MOD_NOADDRESSES; } diff --git a/src/windows/identity/plugins/krb5/krb5funcs.c b/src/windows/identity/plugins/krb5/krb5funcs.c index 8cf2b86fd..bab9ba4cd 100644 --- a/src/windows/identity/plugins/krb5/krb5funcs.c +++ b/src/windows/identity/plugins/krb5/krb5funcs.c @@ -33,7 +33,6 @@ #define SECURITY_WIN32
#include <security.h>
-#include <ntsecapi.h>
#include <string.h>
#include <time.h>
@@ -1004,7 +1003,6 @@ khm_krb5_renew_ident(khm_handle identity) krb5_creds my_creds;
krb5_data *realm = NULL;
wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- char cidname[KCDB_IDENT_MAXCCH_NAME];
khm_size cb;
memset(&my_creds, 0, sizeof(krb5_creds));
@@ -1016,9 +1014,11 @@ khm_krb5_renew_ident(khm_handle identity) kcdb_identity_get_name(identity, idname, &cb);
if (khm_krb5_get_identity_flags(identity) & K5IDFLAG_IMPORTED) {
+#ifdef REIMPORT_MSLSA_CREDS
/* we are trying to renew the identity that was imported from
MSLSA: */
BOOL imported;
+ char cidname[KCDB_IDENT_MAXCCH_NAME];
UnicodeStrToAnsi(cidname, sizeof(cidname), idname);
@@ -1029,6 +1029,11 @@ khm_krb5_renew_ident(khm_handle identity) /* if the import failed, then we try to renew the identity via
the usual procedure. */
+#else
+ /* if we are suppressing further imports from MSLSA, we just
+ skip renewing this identity. */
+ goto cleanup;
+#endif
}
code = khm_krb5_initialize(identity, &ctx, &cc);
@@ -2002,11 +2007,11 @@ khm_krb5_ms2mit(char * match_princ, BOOL match_realm, BOOL save_creds) wname[0] = L'\0';
- kcdb_identity_get_config(ident, 0, &idconfig);
+ kcdb_identity_get_config(ident, KHM_FLAG_CREATE, &idconfig);
if (idconfig == NULL)
goto _done_checking_config;
- khc_open_space(idconfig, CSNAME_KRB5CRED, 0, &k5config);
+ khc_open_space(idconfig, CSNAME_KRB5CRED, KHM_FLAG_CREATE, &k5config);
if (k5config == NULL)
goto _done_checking_config;
@@ -2612,3 +2617,487 @@ khm_krb5_get_temp_ccache(krb5_context ctx, return code;
}
+
+/*
+
+ The configuration information for each identity comes from a
+ multitude of layers organized as follows. The ordering is
+ decreasing in priority. When looking up a value, the value will be
+ looked up in each layer in turn starting at level 0. The first
+ instance of the value found will be the effective value.
+
+ 0 : <identity configuration>\Krb5Cred
+
+ 0.1: per user
+
+ 0.2: per machine
+
+ 1 : <plugin configuration>\Parameters\Realms\<realm of identity>
+
+ 1.1: per user
+
+ 1.2: per machine
+
+ 2 : <plugin configuration>\Parameters
+
+ 2.1: per user
+
+ 2.2: per machine
+
+ 2.3: schema
+
+ */
+khm_int32
+khm_krb5_get_identity_config(khm_handle ident,
+ khm_int32 flags,
+ khm_handle * ret_csp) {
+
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+ khm_handle csp_i = NULL;
+ khm_handle csp_ik5 = NULL;
+ khm_handle csp_realms = NULL;
+ khm_handle csp_realm = NULL;
+ khm_handle csp_plugins = NULL;
+ khm_handle csp_krbcfg = NULL;
+ khm_handle csp_rv = NULL;
+ wchar_t realm[KCDB_IDENT_MAXCCH_NAME];
+
+ realm[0] = L'\0';
+
+ if (ident) {
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t * trealm;
+ khm_size cb_idname = sizeof(idname);
+
+ rv = kcdb_identity_get_name(ident, idname, &cb_idname);
+ if (KHM_SUCCEEDED(rv) &&
+ (trealm = khm_get_realm_from_princ(idname)) != NULL) {
+ StringCbCopy(realm, sizeof(realm), trealm);
+ }
+ }
+
+ if (ident) {
+ rv = kcdb_identity_get_config(ident, flags, &csp_i);
+ if (KHM_FAILED(rv))
+ goto done;
+
+ rv = khc_open_space(csp_i, CSNAME_KRB5CRED, flags, &csp_ik5);
+ if (KHM_FAILED(rv))
+ goto done;
+
+ if (realm[0] == L'\0')
+ goto done_shadow_realm;
+
+ rv = khc_open_space(csp_params, CSNAME_REALMS, flags, &csp_realms);
+ if (KHM_FAILED(rv))
+ goto done_shadow_realm;
+
+ rv = khc_open_space(csp_realms, realm, flags, &csp_realm);
+ if (KHM_FAILED(rv))
+ goto done_shadow_realm;
+
+ rv = khc_shadow_space(csp_realm, csp_params);
+
+ done_shadow_realm:
+
+ if (csp_realm)
+ rv = khc_shadow_space(csp_ik5, csp_realm);
+ else
+ rv = khc_shadow_space(csp_ik5, csp_params);
+
+ csp_rv = csp_ik5;
+
+ } else {
+
+ /* No valid identity specified. We default to the parameters key. */
+ rv = kmm_get_plugins_config(0, &csp_plugins);
+ if (KHM_FAILED(rv))
+ goto done;
+
+ rv = khc_open_space(csp_plugins, CSNAME_KRB5CRED, flags, &csp_krbcfg);
+ if (KHM_FAILED(rv))
+ goto done;
+
+ rv = khc_open_space(csp_krbcfg, CSNAME_PARAMS, flags, &csp_rv);
+ }
+
+ done:
+
+ *ret_csp = csp_rv;
+
+ /* leave csp_ik5. If it's non-NULL, then it's the return value */
+ /* leave csp_rv. It's the return value. */
+ if (csp_i)
+ khc_close_space(csp_i);
+ if (csp_realms)
+ khc_close_space(csp_realms);
+ if (csp_realm)
+ khc_close_space(csp_realm);
+ if (csp_plugins)
+ khc_close_space(csp_plugins);
+ if (csp_krbcfg)
+ khc_close_space(csp_krbcfg);
+
+ return rv;
+}
+
+khm_int32
+khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {
+
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+ khm_handle csp_id = NULL;
+ khm_int32 regf = 0;
+ khm_int32 proff = 0;
+ khm_int32 e;
+ khm_int32 v;
+ CHAR confname[MAX_PATH];
+
+ ZeroMemory(p, sizeof(*p));
+
+ rv = khm_krb5_get_identity_config(ident, 0, &csp_id);
+ if (KHM_FAILED(rv))
+ goto done_reg;
+
+
+#define GETVAL(vname, vfield, flag) \
+ do { \
+ e = khc_value_exists(csp_id, vname); \
+ rv = khc_read_int32(csp_id, vname, &v); \
+ if (KHM_FAILED(rv)) goto done_reg; \
+ p->vfield = v; \
+ if ((e & ~KCONF_FLAG_SCHEMA) != 0) regf |= flag; \
+ } while(FALSE)
+
+ /* Flags */
+ GETVAL(L"Renewable", renewable, K5PARAM_F_RENEW);
+ GETVAL(L"Forwardable", forwardable, K5PARAM_F_FORW);
+ GETVAL(L"Proxiable", proxiable, K5PARAM_F_PROX);
+ GETVAL(L"Addressless", addressless, K5PARAM_F_ADDL);
+ GETVAL(L"PublicIP", publicIP, K5PARAM_F_PUBIP);
+
+ /* Lifetime */
+ GETVAL(L"DefaultLifetime", lifetime, K5PARAM_F_LIFE);
+ GETVAL(L"MaxLifetime", lifetime_max, K5PARAM_F_LIFE_H);
+ GETVAL(L"MinLifetime", lifetime_min, K5PARAM_F_LIFE_L);
+
+ /* Renewable lifetime */
+ GETVAL(L"DefaultRenewLifetime", renew_life, K5PARAM_F_RLIFE);
+ GETVAL(L"MaxRenewLifetime", renew_life_max, K5PARAM_F_RLIFE_H);
+ GETVAL(L"MinRenewLifetime", renew_life_min, K5PARAM_F_RLIFE_L);
+
+#undef GETVAL
+
+ done_reg:
+
+ if (csp_id)
+ khc_close_space(csp_id);
+
+ /* if all the parameters were read from the registry, then we have
+ no reason to read from the profile file. */
+ if (regf == K5PARAM_FM_ALL) {
+ p->source_reg = regf;
+ return KHM_ERROR_SUCCESS;
+ }
+
+ if (rv)
+ return rv;
+
+ /* If we get here, then some of the settings we read from the
+ configuration actually came from the schema. In other words,
+ the values weren't really defined for this identity. So we now
+ have to read the values from the krb5 configuration file. */
+
+ if (!khm_krb5_get_profile_file(confname, sizeof(confname))) {
+ profile_t profile;
+ const char * filenames[2];
+ long retval;
+
+ filenames[0] = confname;
+ filenames[1] = NULL;
+
+ if (!pprofile_init(filenames, &profile)) {
+
+ /* default ticket lifetime */
+ if (!(regf & K5PARAM_F_LIFE)) {
+ char * value = NULL;
+ retval = pprofile_get_string(profile, "libdefaults", "ticket_lifetime", 0, 0, &value);
+ if (retval == 0 && value) {
+ krb5_deltat d;
+
+ retval = pkrb5_string_to_deltat(value, &d);
+ if (retval == KRB5_DELTAT_BADFORMAT) {
+ /* Historically some sites use relations of
+ the form 'ticket_lifetime = 24000' where
+ the unit is left out but is assumed to be
+ seconds. Then there are other sites which
+ use the form 'ticket_lifetime = 600' where
+ the unit is assumed to be minutes. While
+ these are technically wrong (a unit needs
+ to be specified), we try to accomodate for
+ this using the safe assumption that the
+ unit is seconds and tack an 's' to the end
+ and see if that works. */
+
+ size_t cch;
+ char tmpbuf[256];
+ char * buf;
+
+ do {
+ if (FAILED(StringCchLengthA(value, 1024 /* unresonably large size */,
+ &cch)))
+ break;
+
+ cch += sizeof(char) * 2; /* NULL and new 's' */
+ if (cch > ARRAYLENGTH(tmpbuf))
+ buf = PMALLOC(cch * sizeof(char));
+ else
+ buf = tmpbuf;
+
+ StringCchCopyA(buf, cch, value);
+ StringCchCatA(buf, cch, "s");
+
+ retval = pkrb5_string_to_deltat(buf, &d);
+ if (retval == 0) {
+ p->lifetime = d;
+ proff |= K5PARAM_F_LIFE;
+ }
+
+ if (buf != tmpbuf)
+ PFREE(buf);
+
+ } while(0);
+
+ } else if (retval == 0) {
+ p->lifetime = d;
+ proff |= K5PARAM_F_LIFE;
+ }
+ pprofile_release_string(value);
+ }
+ }
+
+ if (!(regf & K5PARAM_F_RLIFE)) {
+ char * value = NULL;
+ retval = pprofile_get_string(profile, "libdefaults", "renew_lifetime", 0, 0, &value);
+ if (retval == 0 && value) {
+ krb5_deltat d;
+
+ retval = pkrb5_string_to_deltat(value, &d);
+ if (retval == 0) {
+ p->renew_life = d;
+ proff |= K5PARAM_F_RLIFE;
+ }
+ pprofile_release_string(value);
+ }
+ }
+
+ if (!(regf & K5PARAM_F_FORW)) {
+ char * value = NULL;
+ retval = pprofile_get_string(profile, "libdefaults", "forwardable", 0, 0, &value);
+ if (retval == 0 && value) {
+ khm_boolean b;
+
+ if (!khm_krb5_parse_boolean(value, &b))
+ p->forwardable = b;
+ else
+ p->forwardable = FALSE;
+ pprofile_release_string(value);
+ proff |= K5PARAM_F_FORW;
+ }
+ }
+
+ if (!(regf & K5PARAM_F_RENEW)) {
+ char * value = NULL;
+ retval = pprofile_get_string(profile, "libdefaults", "renewable", 0, 0, &value);
+
+ if (retval == 0 && value) {
+ khm_boolean b;
+
+ if (!khm_krb5_parse_boolean(value, &b))
+ p->renewable = b;
+ else
+ p->renewable = TRUE;
+ pprofile_release_string(value);
+ proff |= K5PARAM_F_RENEW;
+ }
+ }
+
+ if (!(regf & K5PARAM_F_ADDL)) {
+ char * value = NULL;
+ retval = pprofile_get_string(profile, "libdefaults", "noaddresses", 0, 0, &value);
+
+ if (retval == 0 && value) {
+ khm_boolean b;
+
+ if (!khm_krb5_parse_boolean(value, &b))
+ p->addressless = b;
+ else
+ p->addressless = TRUE;
+ pprofile_release_string(value);
+ proff |= K5PARAM_F_ADDL;
+ }
+ }
+
+ if (!(regf & K5PARAM_F_PROX)) {
+ char * value = NULL;
+ retval = pprofile_get_string(profile, "libdefaults", "proxiable", 0, 0, &value);
+
+ if (retval == 0 && value) {
+ khm_boolean b;
+
+ if (!khm_krb5_parse_boolean(value, &b))
+ p->proxiable = b;
+ else
+ p->proxiable = FALSE;
+ pprofile_release_string(value);
+ proff |= K5PARAM_F_PROX;
+ }
+ }
+
+ pprofile_release(profile);
+ }
+ }
+
+ p->source_reg = regf;
+ p->source_prof = proff;
+
+ return rv;
+}
+
+/* Note that p->source_reg and p->source_prof is used in special ways
+ here. All fields that are flagged in source_reg will be written to
+ the configuration (if they are different from what
+ khm_krb5_get_identity_params() reports). All fields that are
+ flagged in source_prof will be removed from the configuration
+ (thereby exposing the value defined in the profile file). */
+khm_int32
+khm_krb5_set_identity_params(khm_handle ident, const k5_params * p) {
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+ khm_handle csp_id = NULL;
+ k5_params p_s;
+ khm_int32 source_reg = p->source_reg;
+ khm_int32 source_prof = p->source_prof;
+
+ rv = khm_krb5_get_identity_config(ident,
+ KHM_PERM_WRITE | KHM_FLAG_CREATE |
+ KCONF_FLAG_WRITEIFMOD,
+ &csp_id);
+ if (KHM_FAILED(rv))
+ goto done_reg;
+
+ khm_krb5_get_identity_params(ident, &p_s);
+
+ /* Remove any bits that don't make sense. Not all values can be
+ specified in the profile file. */
+ source_prof &= K5PARAM_FM_PROF;
+
+ /* if a flag appears in both source_prof and source_reg, remove
+ the flag from source_reg. */
+ source_reg &= ~source_prof;
+
+ /* we only write values that have changed, and that are flagged in
+ source_reg */
+
+ if ((source_reg & K5PARAM_F_RENEW) &&
+ !!p_s.renewable != !!p->renewable)
+ khc_write_int32(csp_id, L"Renewable", !!p->renewable);
+
+ if ((source_reg & K5PARAM_F_FORW) &&
+ !!p_s.forwardable != !!p->forwardable)
+ khc_write_int32(csp_id, L"Forwardable", !!p->forwardable);
+
+ if ((source_reg & K5PARAM_F_PROX) &&
+ !!p_s.proxiable != !!p->proxiable)
+ khc_write_int32(csp_id, L"Proxiable", !!p->proxiable);
+
+ if ((source_reg & K5PARAM_F_ADDL) &&
+ !!p_s.addressless != !!p->addressless)
+ khc_write_int32(csp_id, L"Addressless", !!p->addressless);
+
+ if ((source_reg & K5PARAM_F_PUBIP) &&
+ p_s.publicIP != p->publicIP)
+ khc_write_int32(csp_id, L"PublicIP", p->publicIP);
+
+ if ((source_reg & K5PARAM_F_LIFE) &&
+ p_s.lifetime != p->lifetime)
+ khc_write_int32(csp_id, L"DefaultLifetime", p->lifetime);
+
+ if ((source_reg & K5PARAM_F_LIFE_H) &&
+ p_s.lifetime_max != p->lifetime_max)
+ khc_write_int32(csp_id, L"MaxLifetime", p->lifetime_max);
+
+ if ((source_reg & K5PARAM_F_LIFE_L) &&
+ p_s.lifetime_min != p->lifetime_min)
+ khc_write_int32(csp_id, L"MinLifetime", p->lifetime_min);
+
+ if ((source_reg & K5PARAM_F_RLIFE) &&
+ p_s.renew_life != p->renew_life)
+ khc_write_int32(csp_id, L"DefaultRenewLifetime", p->renew_life);
+
+ if ((source_reg & K5PARAM_F_RLIFE_H) &&
+ p_s.renew_life_max != p->renew_life_max)
+ khc_write_int32(csp_id, L"MaxRenewLifetime", p->renew_life_max);
+
+ if ((source_reg & K5PARAM_F_RLIFE_L) &&
+ p_s.renew_life_min != p->renew_life_min)
+ khc_write_int32(csp_id, L"MinRenewLifetime", p->renew_life_min);
+
+ /* and now, remove the values that are present in source_prof.
+ Not all values are removed since not all values can be
+ specified in the profile file. */
+ if (source_prof & K5PARAM_F_RENEW)
+ khc_remove_value(csp_id, L"Renewable", 0);
+
+ if (source_prof & K5PARAM_F_FORW)
+ khc_remove_value(csp_id, L"Forwardable", 0);
+
+ if (source_prof & K5PARAM_F_PROX)
+ khc_remove_value(csp_id, L"Proxiable", 0);
+
+ if (source_prof & K5PARAM_F_ADDL)
+ khc_remove_value(csp_id, L"Addressless", 0);
+
+ if (source_prof & K5PARAM_F_LIFE)
+ khc_remove_value(csp_id, L"DefaultLifetime", 0);
+
+ if (source_prof & K5PARAM_F_RLIFE)
+ khc_remove_value(csp_id, L"DefaultRenewLifetime", 0);
+
+ done_reg:
+ if (csp_id != NULL)
+ khc_close_space(csp_id);
+
+ return rv;
+}
+
+static const char *const conf_yes[] = {
+ "y", "yes", "true", "t", "1", "on",
+ 0,
+};
+
+static const char *const conf_no[] = {
+ "n", "no", "false", "nil", "0", "off",
+ 0,
+};
+
+int
+khm_krb5_parse_boolean(const char *s, khm_boolean * b)
+{
+ const char *const *p;
+
+ for(p=conf_yes; *p; p++) {
+ if (!_stricmp(*p,s)) {
+ *b = TRUE;
+ return 0;
+ }
+ }
+
+ for(p=conf_no; *p; p++) {
+ if (!_stricmp(*p,s)) {
+ *b = FALSE;
+ return 0;
+ }
+ }
+
+ /* Default to "no" */
+ return KHM_ERROR_INVALID_PARAM;
+}
diff --git a/src/windows/identity/plugins/krb5/krb5funcs.h b/src/windows/identity/plugins/krb5/krb5funcs.h index ece4f7908..ce3989682 100644 --- a/src/windows/identity/plugins/krb5/krb5funcs.h +++ b/src/windows/identity/plugins/krb5/krb5funcs.h @@ -35,7 +35,18 @@ #include <windows.h>
#define SECURITY_WIN32
#include <security.h>
-#include <ntsecapi.h>
+
+#if _WIN32_WINNT < 0x0501
+#define KHM_SAVE_WIN32_WINNT _WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
+#include<ntsecapi.h>
+#ifdef KHM_SAVE_WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT KHM_SAVE_WIN32_WINNT
+#undef KHM_SAVE_WIN32_WINNT
+#endif
#include <krb5common.h>
@@ -50,7 +61,49 @@ #define KRB5_MAXCCH_CCNAME 1024
-// Function Prototypes.
+#define KRB5_CONF_YES "yes"
+#define KRB5_CONF_NO "no"
+
+typedef struct tag_k5params {
+
+ khm_int32 source_reg; /* flags indicating which fields were
+ retrieved using the registry */
+ khm_int32 source_prof; /* flags indicating which fields were
+ retrieved using krb5.ini */
+
+ khm_boolean renewable;
+ khm_boolean forwardable;
+ khm_boolean proxiable;
+ khm_boolean addressless;
+
+ khm_ui_4 publicIP;
+
+ krb5_deltat lifetime;
+ krb5_deltat lifetime_min;
+ krb5_deltat lifetime_max;
+
+ krb5_deltat renew_life;
+ krb5_deltat renew_life_min;
+ krb5_deltat renew_life_max;
+
+} k5_params;
+
+#define K5PARAM_F_RENEW 0x00000001
+#define K5PARAM_F_FORW 0x00000002
+#define K5PARAM_F_PROX 0x00000004
+#define K5PARAM_F_ADDL 0x00000008
+#define K5PARAM_F_PUBIP 0x00000010
+#define K5PARAM_F_LIFE 0x00000020
+#define K5PARAM_F_RLIFE 0x00000040
+#define K5PARAM_F_LIFE_L 0x00000080
+#define K5PARAM_F_LIFE_H 0x00000100
+#define K5PARAM_F_RLIFE_L 0x00000200
+#define K5PARAM_F_RLIFE_H 0x00000400
+
+#define K5PARAM_FM_ALL 0x000007ff
+#define K5PARAM_FM_PROF 0x0000007f
+
+/* Credential and principal operations */
BOOL
khm_krb5_ms2mit(char * match_princ,
@@ -92,36 +145,23 @@ khm_krb5_renew_cred(khm_handle cred); int
khm_krb5_renew_ident(khm_handle identity);
-wchar_t *
-khm_krb5_get_default_realm(void);
-
-long
-khm_krb5_set_default_realm(wchar_t * realm);
-
-wchar_t *
-khm_krb5_get_realm_list(void);
-
long
khm_krb5_list_tickets(krb5_context *krbv5Context);
-long
-khm_krb4_list_tickets(void);
-
-wchar_t *
-khm_get_realm_from_princ(wchar_t * princ);
-
long
khm_krb5_copy_ccache_by_name(krb5_context in_ctx,
wchar_t * wscc_dest,
wchar_t * wscc_src);
long
-khm_krb5_canon_cc_name(wchar_t * wcc_name,
- size_t cb_cc_name);
+khm_krb5_get_temp_ccache(krb5_context ctx,
+ krb5_ccache * cc);
-int
-khm_krb5_cc_name_cmp(const wchar_t * cc_name_1,
- const wchar_t * cc_name_2);
+khm_int32 KHMAPI
+khm_krb5_creds_is_equal(khm_handle vcred1, khm_handle vcred2, void * dummy);
+
+
+/* Configuration */
BOOL
khm_krb5_get_profile_file(LPSTR confname, UINT szConfname);
@@ -129,8 +169,19 @@ khm_krb5_get_profile_file(LPSTR confname, UINT szConfname); BOOL
khm_krb5_get_temp_profile_file(LPSTR confname, UINT szConfname);
-khm_int32 KHMAPI
-khm_krb5_creds_is_equal(khm_handle vcred1, khm_handle vcred2, void * dummy);
+wchar_t *
+khm_krb5_get_default_realm(void);
+
+long
+khm_krb5_set_default_realm(wchar_t * realm);
+
+wchar_t *
+khm_krb5_get_realm_list(void);
+
+khm_int32
+khm_krb5_get_identity_config(khm_handle ident,
+ khm_int32 flags,
+ khm_handle * ret_csp);
void
khm_krb5_set_identity_flags(khm_handle identity,
@@ -140,7 +191,26 @@ khm_krb5_set_identity_flags(khm_handle identity, khm_int32
khm_krb5_get_identity_flags(khm_handle identity);
+khm_int32
+khm_krb5_set_identity_params(khm_handle ident, const k5_params * p);
+
+khm_int32
+khm_krb5_get_identity_params(khm_handle ident, k5_params * p);
+
+/* Utility */
+
+wchar_t *
+khm_get_realm_from_princ(wchar_t * princ);
+
long
-khm_krb5_get_temp_ccache(krb5_context ctx,
- krb5_ccache * cc);
+khm_krb5_canon_cc_name(wchar_t * wcc_name,
+ size_t cb_cc_name);
+
+int
+khm_krb5_cc_name_cmp(const wchar_t * cc_name_1,
+ const wchar_t * cc_name_2);
+
+int
+khm_krb5_parse_boolean(const char *s, khm_boolean * b);
+
#endif
diff --git a/src/windows/identity/plugins/krb5/krb5newcreds.c b/src/windows/identity/plugins/krb5/krb5newcreds.c index 34cc8bd20..d52e934cc 100644 --- a/src/windows/identity/plugins/krb5/krb5newcreds.c +++ b/src/windows/identity/plugins/krb5/krb5newcreds.c @@ -635,19 +635,41 @@ k5_kinit_fiber_proc(PVOID lpParameter) _reportf(L" g_fjob.valid_principal = %d", (int) g_fjob.valid_principal);
#endif
+ /* If we don't know if we have a valid principal, we
+ restrict the options that are set when we call kinit.
+ This way we will be able to use the response from the
+ KDC to verify the principal. */
+
+ g_fjob.retry_if_valid_principal = (g_fjob.forwardable ||
+ g_fjob.proxiable ||
+ g_fjob.renewable);
+
+ retry_kinit:
g_fjob.code =
khm_krb5_kinit(0,
g_fjob.principal,
g_fjob.password,
g_fjob.ccache,
g_fjob.lifetime,
- g_fjob.valid_principal ? g_fjob.forwardable : 0,
- g_fjob.valid_principal ? g_fjob.proxiable : 0,
+ g_fjob.valid_principal ? g_fjob.forwardable : 0,
+ g_fjob.valid_principal ? g_fjob.proxiable : 0,
(g_fjob.valid_principal && g_fjob.renewable ? g_fjob.renew_life : 0),
g_fjob.addressless,
g_fjob.publicIP,
k5_kinit_prompter,
&g_fjob);
+
+ /* If the principal was found to be valid, and if we
+ restricted the options that were being passed to kinit,
+ then we need to retry the kinit call. This time we use
+ the real options. */
+ if (g_fjob.state == FIBER_STATE_RETRY_KINIT) {
+#ifdef DEBUG
+ assert(g_fjob.valid_principal);
+#endif
+ g_fjob.state = FIBER_STATE_KINIT;
+ goto retry_kinit;
+ }
}
_switch_to_main:
@@ -946,7 +968,20 @@ k5_kinit_prompter(krb5_context context, #endif
/* we got prompts? Then we assume that the principal is valid */
- g_fjob.valid_principal = TRUE;
+
+ if (!g_fjob.valid_principal) {
+ g_fjob.valid_principal = TRUE;
+
+ /* if the flags that were used to call kinit were restricted
+ because we didn't know the validity of the principal, then
+ we need to go back and retry the call with the correct
+ flags. */
+ if (g_fjob.retry_if_valid_principal) {
+ _reportf(L"Retrying kinit call due to restricted flags on first call.");
+ g_fjob.state = FIBER_STATE_RETRY_KINIT;
+ return KRB5_LIBOS_PWDINTR;
+ }
+ }
nc = g_fjob.nc;
@@ -1198,7 +1233,7 @@ k5_kinit_prompter(krb5_context context, actual acquisition of credentials. */
if(g_fjob.command != FIBER_CMD_CONTINUE &&
g_fjob.command != FIBER_CMD_KINIT) {
- code = -2;
+ code = KRB5_LIBOS_PWDINTR;
goto _exit;
}
@@ -1241,164 +1276,32 @@ k5_kinit_prompter(krb5_context context, /* entering a NULL password is equivalent to cancelling out */
if (g_fjob.null_password)
- return -2;
+ return KRB5_LIBOS_PWDINTR;
else
return code;
}
-/*
-
- The configuration information for each identity comes from a
- multitude of layers organized as follows. The ordering is
- decreasing in priority. When looking up a value, the value will be
- looked up in each layer in turn starting at level 0. The first
- instance of the value found will be the effective value.
-
- 0 : <identity configuration>\Krb5Cred
-
- 0.1: per user
-
- 0.2: per machine
-
- 1 : <plugin configuration>\Parameters\Realms\<realm of identity>
-
- 1.1: per user
-
- 1.2: per machine
-
- 2 : <plugin configuration>\Parameters
-
- 2.1: per user
-
- 2.2: per machine
-
- 2.3: schema
-
- */
-khm_int32
-k5_open_config_handle(khm_handle ident,
- khm_int32 flags,
- khm_handle * ret_csp) {
-
- khm_int32 rv = KHM_ERROR_SUCCESS;
- khm_handle csp_i = NULL;
- khm_handle csp_ik5 = NULL;
- khm_handle csp_realms = NULL;
- khm_handle csp_realm = NULL;
- khm_handle csp_plugins = NULL;
- khm_handle csp_krbcfg = NULL;
- khm_handle csp_rv = NULL;
- wchar_t realm[KCDB_IDENT_MAXCCH_NAME];
-
- realm[0] = L'\0';
-
- if (ident) {
- wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- wchar_t * trealm;
- khm_size cb_idname = sizeof(idname);
-
- rv = kcdb_identity_get_name(ident, idname, &cb_idname);
- if (KHM_SUCCEEDED(rv) &&
- (trealm = khm_get_realm_from_princ(idname)) != NULL) {
- StringCbCopy(realm, sizeof(realm), trealm);
- }
- }
-
- if (ident) {
- rv = kcdb_identity_get_config(ident, flags, &csp_i);
- if (KHM_FAILED(rv))
- goto done;
-
- rv = khc_open_space(csp_i, CSNAME_KRB5CRED, flags, &csp_ik5);
- if (KHM_FAILED(rv))
- goto done;
-
- if (realm[0] == L'\0')
- goto done_shadow_realm;
-
- rv = khc_open_space(csp_params, CSNAME_REALMS, flags, &csp_realms);
- if (KHM_FAILED(rv))
- goto done_shadow_realm;
-
- rv = khc_open_space(csp_realms, realm, flags, &csp_realm);
- if (KHM_FAILED(rv))
- goto done_shadow_realm;
-
- rv = khc_shadow_space(csp_realm, csp_params);
- done_shadow_realm:
-
- if (csp_realm)
- rv = khc_shadow_space(csp_ik5, csp_realm);
- else
- rv = khc_shadow_space(csp_ik5, csp_params);
-
- csp_rv = csp_ik5;
-
- } else {
-
- /* No valid identity specified. We default to the parameters key. */
- rv = kmm_get_plugins_config(0, &csp_plugins);
- if (KHM_FAILED(rv))
- goto done;
-
- rv = khc_open_space(csp_plugins, CSNAME_KRB5CRED, flags, &csp_krbcfg);
- if (KHM_FAILED(rv))
- goto done;
-
- rv = khc_open_space(csp_krbcfg, CSNAME_PARAMS, flags, &csp_rv);
- }
-
- done:
+void
+k5_read_dlg_params(k5_dlg_data * d, khm_handle identity)
+{
+ k5_params p;
- *ret_csp = csp_rv;
+ khm_krb5_get_identity_params(identity, &p);
- /* leave csp_ik5. If it's non-NULL, then it's the return value */
- /* leave csp_rv. It's the return value. */
- if (csp_i)
- khc_close_space(csp_i);
- if (csp_realms)
- khc_close_space(csp_realms);
- if (csp_realm)
- khc_close_space(csp_realm);
- if (csp_plugins)
- khc_close_space(csp_plugins);
- if (csp_krbcfg)
- khc_close_space(csp_krbcfg);
+ d->renewable = p.renewable;
+ d->forwardable = p.forwardable;
+ d->proxiable = p.proxiable;
+ d->addressless = p.addressless;
+ d->publicIP = p.publicIP;
- return rv;
-}
+ d->tc_lifetime.current = p.lifetime;
+ d->tc_lifetime.max = p.lifetime_max;
+ d->tc_lifetime.min = p.lifetime_min;
-void
-k5_read_dlg_params(khm_handle conf,
- k5_dlg_data * d)
-{
- khm_int32 i;
-
- khc_read_int32(conf, L"Renewable", &i);
- d->renewable = i;
- khc_read_int32(conf, L"Forwardable", &i);
- d->forwardable = i;
- khc_read_int32(conf, L"Proxiable", &i);
- d->proxiable = i;
- khc_read_int32(conf, L"Addressless", &i);
- d->addressless = i;
- khc_read_int32(conf, L"PublicIP", &i);
- d->publicIP = i;
-
- khc_read_int32(conf, L"DefaultLifetime", &i);
- d->tc_lifetime.current = i;
- khc_read_int32(conf, L"MaxLifetime", &i);
- d->tc_lifetime.max = i;
- khc_read_int32(conf, L"MinLifetime", &i);
- d->tc_lifetime.min = i;
-
- khc_read_int32(conf, L"DefaultRenewLifetime", &i);
- d->tc_renew.current = i;
- khc_read_int32(conf, L"MaxRenewLifetime", &i);
- d->tc_renew.max = i;
- khc_read_int32(conf, L"MinRenewLifetime", &i);
- d->tc_renew.min = i;
+ d->tc_renew.current = p.renew_life;
+ d->tc_renew.max = p.renew_life_max;
+ d->tc_renew.min = p.renew_life_min;
/* however, if this has externally supplied defaults, we have to
use them too. */
@@ -1431,28 +1334,32 @@ k5_read_dlg_params(khm_handle conf, }
void
-k5_write_dlg_params(khm_handle conf,
- k5_dlg_data * d)
+k5_write_dlg_params(k5_dlg_data * d, khm_handle identity)
{
- khc_write_int32(conf, L"Renewable", d->renewable);
- khc_write_int32(conf, L"Forwardable", d->forwardable);
- khc_write_int32(conf, L"Proxiable", d->proxiable);
- khc_write_int32(conf, L"Addressless", d->addressless);
- khc_write_int32(conf, L"PublicIP", d->publicIP);
-
- khc_write_int32(conf, L"DefaultLifetime",
- (khm_int32) d->tc_lifetime.current);
- khc_write_int32(conf, L"MaxLifetime",
- (khm_int32) d->tc_lifetime.max);
- khc_write_int32(conf, L"MinLifetime",
- (khm_int32) d->tc_lifetime.min);
-
- khc_write_int32(conf, L"DefaultRenewLifetime",
- (khm_int32) d->tc_renew.current);
- khc_write_int32(conf, L"MaxRenewLifetime",
- (khm_int32) d->tc_renew.max);
- khc_write_int32(conf, L"MinRenewLifetime",
- (khm_int32) d->tc_renew.min);
+
+ k5_params p;
+
+ ZeroMemory(&p, sizeof(p));
+
+ p.source_reg = K5PARAM_FM_ALL; /* we want to write all the
+ settings to the registry, if
+ necessary. */
+
+ p.renewable = d->renewable;
+ p.forwardable = d->forwardable;
+ p.proxiable = d->proxiable;
+ p.addressless = d->addressless;
+ p.publicIP = d->publicIP;
+
+ p.lifetime = (krb5_deltat) d->tc_lifetime.current;
+ p.lifetime_max = (krb5_deltat) d->tc_lifetime.max;
+ p.lifetime_min = (krb5_deltat) d->tc_lifetime.min;
+
+ p.renew_life = (krb5_deltat) d->tc_renew.current;
+ p.renew_life_max = (krb5_deltat) d->tc_renew.max;
+ p.renew_life_min = (krb5_deltat) d->tc_renew.min;
+
+ khm_krb5_set_identity_params(identity, &p);
/* as in k5_read_dlg_params, once we write the data in, the local
data is no longer dirty */
@@ -1528,6 +1435,13 @@ k5_prep_kinit_job(khui_new_creds * nc) g_fjob.identity = ident;
g_fjob.prompt_set = 0;
g_fjob.valid_principal = FALSE;
+ g_fjob.retry_if_valid_principal = FALSE;
+
+ /* the value for
+ retry_if_valid_principal is not
+ necessarily the correct value here,
+ but the correct value will be
+ assigned k5_kinit_fiber_proc(). */
/* if we have external parameters, we should use them as well */
if (nc->ctx.cb_vparam == sizeof(NETID_DLGINFO) &&
@@ -1891,7 +1805,7 @@ k5_msg_cred_dialog(khm_int32 msg_type, }
if (nc->subtype == KMSG_CRED_NEW_CREDS) {
- k5_read_dlg_params(csp_params, d);
+ k5_read_dlg_params(d, NULL);
}
PostMessage(hwnd, KHUI_WM_NC_NOTIFY,
@@ -1926,22 +1840,10 @@ k5_msg_cred_dialog(khm_int32 msg_type, if(/* !d->dirty && */ nc->n_identities > 0 &&
nc->subtype == KMSG_CRED_NEW_CREDS) {
- khm_handle h_idcfg = NULL;
-
- do {
- if (KHM_FAILED
- (k5_open_config_handle(nc->identities[0],
- 0, &h_idcfg)))
- break;
-
- k5_read_dlg_params(h_idcfg, d);
-
- PostMessage(nct->hwnd_panel, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0,WMNC_DIALOG_SETUP), 0);
- } while(FALSE);
+ k5_read_dlg_params(d, nc->identities[0]);
- if(h_idcfg)
- khc_close_space(h_idcfg);
+ PostMessage(nct->hwnd_panel, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0,WMNC_DIALOG_SETUP), 0);
}
khui_cw_unlock_nc(nc);
@@ -2015,12 +1917,14 @@ k5_msg_cred_dialog(khm_int32 msg_type, if (d->pwd_change)
return KHM_ERROR_SUCCESS;
- /* At this point, we assume that the current set of
- prompts is no longer valid. And since we might not be
- able to come up with a set of prompts until the KDC
- replies (unless we have cached prompts), we remove the
- ones that are already shown. */
+#if 0
+ /* Clearing the prompts at this point is a bad idea since
+ the prompter depends on the prompts to know if this set
+ of prompts is the same as the new set and if so, use
+ the values entered in the old prompts as responses to
+ the new one. */
khui_cw_clear_prompts(nc);
+#endif
/* if the fiber is already in a kinit, cancel it */
if(g_fjob.state == FIBER_STATE_KINIT) {
@@ -2259,7 +2163,19 @@ k5_msg_cred_dialog(khm_int32 msg_type, NULL)))) {
_reportf(L"No password entered, but a valid TGT exists. Continuing");
g_fjob.code = 0;
- }
+ } else if (g_fjob.state == FIBER_STATE_NONE &&
+ g_fjob.code == 0 &&
+ nc->n_identities > 0 &&
+ nc->identities[0] != NULL) {
+
+ /* we had a password and we used it to get
+ tickets. We should reset the IMPORTED flag now
+ since the tickets are not imported. */
+
+ khm_krb5_set_identity_flags(nc->identities[0],
+ K5IDFLAG_IMPORTED,
+ 0);
+ }
if(g_fjob.code != 0) {
wchar_t tbuf[1024];
@@ -2296,7 +2212,6 @@ k5_msg_cred_dialog(khm_int32 msg_type, } else if (nc->result == KHUI_NC_RESULT_PROCESS &&
g_fjob.state == FIBER_STATE_NONE) {
- khm_handle csp_idcfg = NULL;
krb5_context ctx = NULL;
_reportf(L"Tickets successfully acquired");
@@ -2311,16 +2226,7 @@ k5_msg_cred_dialog(khm_int32 msg_type, assert(nc->n_identities > 0);
assert(nc->identities[0]);
- if (KHM_SUCCEEDED
- (k5_open_config_handle(nc->identities[0],
- KHM_FLAG_CREATE |
- KCONF_FLAG_WRITEIFMOD,
- &csp_idcfg))) {
- k5_write_dlg_params(csp_idcfg, d);
- }
-
- if(csp_idcfg != NULL)
- khc_close_space(csp_idcfg);
+ k5_write_dlg_params(d, nc->identities[0]);
/* We should also quickly refresh the credentials
so that the identity flags and ccache
@@ -2631,16 +2537,8 @@ k5_msg_cred_dialog(khm_int32 msg_type, /* since this was just a password change,
we need to load new credentials options
from the configuration store. */
-
- if (KHM_SUCCEEDED
- (k5_open_config_handle(nc->identities[0],
- KHM_FLAG_CREATE |
- KCONF_FLAG_WRITEIFMOD,
- &csp_idcfg))) {
- k5_read_dlg_params(csp_idcfg, d);
- khc_close_space(csp_idcfg);
- csp_idcfg = NULL;
- }
+
+ k5_read_dlg_params(d, nc->identities[0]);
}
/* the password change phase is now done */
@@ -2669,14 +2567,9 @@ k5_msg_cred_dialog(khm_int32 msg_type, /* save the settings that we used for
obtaining the ticket. */
- if (nc->subtype == KMSG_CRED_NEW_CREDS &&
- KHM_SUCCEEDED
- (k5_open_config_handle(nc->identities[0],
- KHM_FLAG_CREATE |
- KCONF_FLAG_WRITEIFMOD,
- &csp_idcfg))) {
- k5_write_dlg_params(csp_idcfg, d);
- khc_close_space(csp_idcfg);
+ if (nc->subtype == KMSG_CRED_NEW_CREDS) {
+
+ k5_write_dlg_params(d, nc->identities[0]);
/* and then update the LRU too */
k5_update_LRU(nc->identities[0]);
diff --git a/src/windows/identity/plugins/krb5/krbcred.h b/src/windows/identity/plugins/krb5/krbcred.h index 44b7733e3..d552fd0c8 100644 --- a/src/windows/identity/plugins/krb5/krbcred.h +++ b/src/windows/identity/plugins/krb5/krbcred.h @@ -176,6 +176,7 @@ typedef struct _fiber_job_t { BOOL null_password;
BOOL valid_principal;
+ BOOL retry_if_valid_principal;
} fiber_job;
extern fiber_job g_fjob; /* global fiber job object */
@@ -184,8 +185,9 @@ extern fiber_job g_fjob; /* global fiber job object */ #define FIBER_CMD_CANCEL 2
#define FIBER_CMD_CONTINUE 3
-#define FIBER_STATE_NONE 0
-#define FIBER_STATE_KINIT 1
+#define FIBER_STATE_NONE 0
+#define FIBER_STATE_KINIT 1
+#define FIBER_STATE_RETRY_KINIT 2
#define K5_SET_CRED_MSG WMNC_USER
diff --git a/src/windows/identity/plugins/krb5/lang/en_us/langres.rc b/src/windows/identity/plugins/krb5/lang/en_us/langres.rc index d93b4415e..4d98fd314 100644 --- a/src/windows/identity/plugins/krb5/lang/en_us/langres.rc +++ b/src/windows/identity/plugins/krb5/lang/en_us/langres.rc @@ -338,7 +338,7 @@ IDI_MODIFIED ICON "..\\..\\images\\modified.ico" STRINGTABLE
BEGIN
IDS_UNK_ADDR_FMT "Unknown address type %d"
- IDS_KRB5_CREDTEXT_0 "<p><a id=""SwitchPanel"" param=""Krb5Cred""><b>Krb5</b></a><tab>: Creds for realm %s</p>"
+ IDS_KRB5_CREDTEXT_0 "<p><a id=""SwitchPanel"" param=""Krb5Cred""><b>Krb5</b></a><tab>: Tickets for realm %s</p>"
IDS_KRB5_CCNAME_SHORT_DESC "Kerberos v5 CCache"
IDS_KEY_ENCTYPE_SHORT_DESC "Session EncType"
IDS_TKT_ENCTYPE_SHORT_DESC "Service EncType"
@@ -501,3 +501,4 @@ END /////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
+
|
