summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2012-10-21 16:14:59 -0400
committerGreg Hudson <ghudson@mit.edu>2012-12-19 12:45:11 -0500
commit9d411fc71fa25b05de0031238ebb084dd60a846c (patch)
tree9e02aaad73a7dbe5460196a14a2a4c90f394668a
parent26245eed626245255c980efdfe69ca1f65186338 (diff)
downloadkrb5-9d411fc71fa25b05de0031238ebb084dd60a846c.tar.gz
krb5-9d411fc71fa25b05de0031238ebb084dd60a846c.tar.xz
krb5-9d411fc71fa25b05de0031238ebb084dd60a846c.zip
Save extended messages across fallback to master
In krb5_get_init_creds_password and krb5_get_init_creds_keytab, save the extended error before retrying against the master KDC, and restore that state if returning the error from the original request.
-rw-r--r--src/lib/krb5/krb/gic_keytab.c30
-rw-r--r--src/lib/krb5/krb/gic_pwd.c31
2 files changed, 28 insertions, 33 deletions
diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c
index 0fd1034a3..3dca07385 100644
--- a/src/lib/krb5/krb/gic_keytab.c
+++ b/src/lib/krb5/krb/gic_keytab.c
@@ -263,9 +263,10 @@ krb5_get_init_creds_keytab(krb5_context context,
const char *in_tkt_service,
krb5_get_init_creds_opt *options)
{
- krb5_error_code ret, ret2;
+ krb5_error_code ret;
int use_master;
krb5_keytab keytab;
+ struct errinfo errsave = EMPTY_ERRINFO;
if (arg_keytab == NULL) {
if ((ret = krb5_kt_default(context, &keytab)))
@@ -297,24 +298,18 @@ krb5_get_init_creds_keytab(krb5_context context,
if (!use_master) {
use_master = 1;
- ret2 = get_init_creds_keytab(context, creds, client, keytab,
- start_time, in_tkt_service, options,
- &use_master);
-
- if (ret2 == 0) {
- ret = 0;
- goto cleanup;
- }
-
- /* if the master is unreachable, return the error from the
- slave we were able to contact */
-
- if ((ret2 == KRB5_KDC_UNREACH) ||
- (ret2 == KRB5_REALM_CANT_RESOLVE) ||
- (ret2 == KRB5_REALM_UNKNOWN))
+ k5_save_ctx_error(context, ret, &errsave);
+ ret = get_init_creds_keytab(context, creds, client, keytab,
+ start_time, in_tkt_service, options,
+ &use_master);
+ if (ret == 0)
goto cleanup;
- ret = ret2;
+ /* If the master is unreachable, return the error from the slave we
+ * were able to contact. */
+ if (ret == KRB5_KDC_UNREACH || ret == KRB5_REALM_CANT_RESOLVE ||
+ ret == KRB5_REALM_UNKNOWN)
+ ret = k5_restore_ctx_error(context, &errsave);
}
/* at this point, we have a response from the master. Since we don't
@@ -323,6 +318,7 @@ krb5_get_init_creds_keytab(krb5_context context,
cleanup:
if (arg_keytab == NULL)
krb5_kt_close(context, keytab);
+ k5_clear_error(&errsave);
return(ret);
}
diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c
index 30da8c9b3..32b376f50 100644
--- a/src/lib/krb5/krb/gic_pwd.c
+++ b/src/lib/krb5/krb/gic_pwd.c
@@ -250,7 +250,7 @@ krb5_get_init_creds_password(krb5_context context,
const char *in_tkt_service,
krb5_get_init_creds_opt *options)
{
- krb5_error_code ret, ret2;
+ krb5_error_code ret;
int use_master;
krb5_kdc_rep *as_reply;
int tries;
@@ -260,6 +260,7 @@ krb5_get_init_creds_password(krb5_context context,
char banner[1024], pw0array[1024], pw1array[1024];
krb5_prompt prompt[2];
krb5_prompt_type prompt_types[sizeof(prompt)/sizeof(prompt[0])];
+ struct errinfo errsave = EMPTY_ERRINFO;
char *message;
use_master = 0;
@@ -310,29 +311,26 @@ krb5_get_init_creds_password(krb5_context context,
TRACE_GIC_PWD_MASTER(context);
use_master = 1;
+ k5_save_ctx_error(context, ret, &errsave);
if (as_reply) {
krb5_free_kdc_rep( context, as_reply);
as_reply = NULL;
}
- ret2 = krb5int_get_init_creds(context, creds, client, prompter, data,
- start_time, in_tkt_service, options,
- krb5_get_as_key_password, (void *) &pw0,
- &use_master, &as_reply);
+ ret = krb5int_get_init_creds(context, creds, client, prompter, data,
+ start_time, in_tkt_service, options,
+ krb5_get_as_key_password, (void *) &pw0,
+ &use_master, &as_reply);
- if (ret2 == 0) {
- ret = 0;
+ if (ret == 0)
goto cleanup;
- }
- /* if the master is unreachable, return the error from the
- slave we were able to contact or reset the use_master flag */
-
- if ((ret2 != KRB5_KDC_UNREACH) &&
- (ret2 != KRB5_REALM_CANT_RESOLVE) &&
- (ret2 != KRB5_REALM_UNKNOWN))
- ret = ret2;
- else
+ /* If the master is unreachable, return the error from the slave we
+ * were able to contact and reset the use_master flag. */
+ if (ret == KRB5_KDC_UNREACH || ret == KRB5_REALM_CANT_RESOLVE ||
+ ret == KRB5_REALM_UNKNOWN) {
+ ret = k5_restore_ctx_error(context, &errsave);
use_master = 0;
+ }
}
/* at this point, we have an error from the master. if the error
@@ -481,6 +479,7 @@ cleanup:
krb5_free_cred_contents(context, &chpw_creds);
if (as_reply)
krb5_free_kdc_rep(context, as_reply);
+ k5_clear_error(&errsave);
return(ret);
}