aboutsummaryrefslogtreecommitdiff
path: root/src/kdc/kdc_authdata.c
diff options
context:
space:
mode:
authorSam Hartman <hartmans@mit.edu>2009-01-03 23:19:42 +0000
committerSam Hartman <hartmans@mit.edu>2009-01-03 23:19:42 +0000
commit0ba5ccd7bb3ea15e44a87f84ca6feed8890f657d (patch)
tree2049c9c2cb135fe36b14c0a171711259258d18ec /src/kdc/kdc_authdata.c
parentff0a6514c9f4230938c29922d69cbd4e83691adf (diff)
downloadkrb5-0ba5ccd7bb3ea15e44a87f84ca6feed8890f657d.zip
krb5-0ba5ccd7bb3ea15e44a87f84ca6feed8890f657d.tar.gz
krb5-0ba5ccd7bb3ea15e44a87f84ca6feed8890f657d.tar.bz2
Merge mskrb-integ onto trunk
The mskrb-integ branch includes support for the following projects: Projects/Aliases * Projects/PAC and principal APIs * Projects/AEAD encryption API * Projects/GSSAPI DCE * Projects/RFC 3244 In addition, it includes support for enctype negotiation, and a variety of GSS-API extensions. In the KDC it includes support for protocol transition, constrained delegation and a new authorization data interface. The old authorization data interface is also supported. This commit merges the mskrb-integ branch on to the trunk. Additional review and testing is required. Merge commit 'mskrb-integ' into trunk ticket: new status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@21690 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/kdc/kdc_authdata.c')
-rw-r--r--src/kdc/kdc_authdata.c539
1 files changed, 427 insertions, 112 deletions
diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c
index 9fd37f2..315269c 100644
--- a/src/kdc/kdc_authdata.c
+++ b/src/kdc/kdc_authdata.c
@@ -2,6 +2,7 @@
* kdc/kdc_authdata.c
*
* Copyright (C) 2007 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 by the Massachusetts Institute of Technology.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
@@ -42,109 +43,95 @@ static const char *objdirs[] = { KRB5_AUTHDATA_PLUGIN_BUNDLE_DIR, LIBDIR "/krb5/
static const char *objdirs[] = { LIBDIR "/krb5/plugins/authdata", NULL };
#endif
-typedef krb5_error_code (*authdata_proc)
+/* MIT Kerberos 1.6 (V0) authdata plugin callback */
+typedef krb5_error_code (*authdata_proc_0)
(krb5_context, krb5_db_entry *client,
krb5_data *req_pkt,
krb5_kdc_req *request,
krb5_enc_tkt_part * enc_tkt_reply);
-
+/* MIT Kerberos 1.7 (V1) authdata plugin callback */
+typedef krb5_error_code (*authdata_proc_1)
+ (krb5_context, unsigned int flags,
+ krb5_db_entry *client, krb5_db_entry *server,
+ krb5_db_entry *krbtgt,
+ krb5_keyblock *client_key,
+ krb5_keyblock *server_key,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request,
+ krb5_const_principal for_user_princ,
+ krb5_enc_tkt_part *enc_tkt_request,
+ krb5_enc_tkt_part *enc_tkt_reply);
typedef krb5_error_code (*init_proc)
(krb5_context, void **);
typedef void (*fini_proc)
(krb5_context, void *);
+/* Internal authdata system for copying TGS-REQ authdata to ticket */
+static krb5_error_code handle_request_authdata
+ (krb5_context context,
+ unsigned int flags,
+ krb5_db_entry *client,
+ krb5_db_entry *server,
+ krb5_db_entry *krbtgt,
+ krb5_keyblock *client_key,
+ krb5_keyblock *server_key,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request,
+ krb5_const_principal for_user_princ,
+ krb5_enc_tkt_part *enc_tkt_request,
+ krb5_enc_tkt_part *enc_tkt_reply);
+
+/* Internal authdata system for handling KDC-issued authdata */
+static krb5_error_code handle_tgt_authdata
+ (krb5_context context,
+ unsigned int flags,
+ krb5_db_entry *client,
+ krb5_db_entry *server,
+ krb5_db_entry *krbtgt,
+ krb5_keyblock *client_key,
+ krb5_keyblock *server_key,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request,
+ krb5_const_principal for_user_princ,
+ krb5_enc_tkt_part *enc_tkt_request,
+ krb5_enc_tkt_part *enc_tkt_reply);
+
typedef struct _krb5_authdata_systems {
const char *name;
+#define AUTHDATA_SYSTEM_UNKNOWN -1
+#define AUTHDATA_SYSTEM_V0 0
+#define AUTHDATA_SYSTEM_V1 1
int type;
+#define AUTHDATA_FLAG_CRITICAL 0x1
int flags;
void *plugin_context;
init_proc init;
fini_proc fini;
- authdata_proc handle_authdata;
+ union {
+ authdata_proc_1 v1;
+ authdata_proc_0 v0;
+ } handle_authdata;
} krb5_authdata_systems;
-#undef GREET_PREAUTH
-
-#ifdef GREET_PREAUTH
-static krb5_error_code
-greet_init(krb5_context ctx, void **blob)
-{
- *blob = "hello";
- return 0;
-}
-
-static void
-greet_fini(krb5_context ctx, void *blob)
-{
-}
-
-static krb5_error_code
-greet_authdata(krb5_context ctx, krb5_db_entry *client,
- krb5_data *req_pkt,
- krb5_kdc_req *request,
- krb5_enc_tkt_part * enc_tkt_reply)
-{
-#define GREET_SIZE (20)
-
- char *p;
- krb5_authdata *a;
- size_t count;
- krb5_authdata **new_ad;
-
- krb5_klog_syslog (LOG_DEBUG, "in greet_authdata");
-
- p = calloc(1, GREET_SIZE);
- a = calloc(1, sizeof(*a));
-
- if (p == NULL || a == NULL) {
- free(p);
- free(a);
- return ENOMEM;
- }
- strlcpy(p, "hello", GREET_SIZE);
- a->magic = KV5M_AUTHDATA;
- a->ad_type = -42;
- a->length = GREET_SIZE;
- a->contents = p;
- if (enc_tkt_reply->authorization_data == 0) {
- count = 0;
- } else {
- for (count = 0; enc_tkt_reply->authorization_data[count] != 0; count++)
- ;
- }
- new_ad = realloc(enc_tkt_reply->authorization_data,
- (count+2) * sizeof(krb5_authdata *));
- if (new_ad == NULL) {
- free(p);
- free(a);
- return ENOMEM;
- }
- enc_tkt_reply->authorization_data = new_ad;
- new_ad[count] = a;
- new_ad[count+1] = NULL;
- return 0;
-}
-#endif
-
static krb5_authdata_systems static_authdata_systems[] = {
-#ifdef GREET_PREAUTH
- { "greeting", 0, 0, 0, greet_init, greet_fini, greet_authdata },
-#endif
- { "[end]", -1,}
+ { "tgs_req", AUTHDATA_SYSTEM_V1, AUTHDATA_FLAG_CRITICAL, NULL, NULL, NULL, { handle_request_authdata } },
+ { "tgt", AUTHDATA_SYSTEM_V1, AUTHDATA_FLAG_CRITICAL, NULL, NULL, NULL, { handle_tgt_authdata } },
};
static krb5_authdata_systems *authdata_systems;
static int n_authdata_systems;
static struct plugin_dir_handle authdata_plugins;
+/* Load both v0 and v1 authdata plugins */
krb5_error_code
load_authdata_plugins(krb5_context context)
{
- void **authdata_plugins_ftables = NULL;
- struct krb5plugin_authdata_ftable_v0 *ftable = NULL;
+ void **authdata_plugins_ftables_v0 = NULL;
+ void **authdata_plugins_ftables_v1 = NULL;
size_t module_count;
- int i, k;
+ size_t i, k;
init_proc server_init_proc = NULL;
+ krb5_error_code code;
/* Attempt to load all of the authdata plugins we can find. */
PLUGIN_DIR_INIT(&authdata_plugins);
@@ -156,23 +143,41 @@ load_authdata_plugins(krb5_context context)
}
/* Get the method tables provided by the loaded plugins. */
- authdata_plugins_ftables = NULL;
+ authdata_plugins_ftables_v0 = NULL;
+ authdata_plugins_ftables_v1 = NULL;
n_authdata_systems = 0;
+
if (krb5int_get_plugin_dir_data(&authdata_plugins,
+ "authdata_server_1",
+ &authdata_plugins_ftables_v1, &context->err) != 0 ||
+ krb5int_get_plugin_dir_data(&authdata_plugins,
"authdata_server_0",
- &authdata_plugins_ftables, &context->err) != 0) {
- return KRB5_PLUGIN_NO_HANDLE;
+ &authdata_plugins_ftables_v0, &context->err) != 0) {
+ code = KRB5_PLUGIN_NO_HANDLE;
+ goto cleanup;
}
/* Count the valid modules. */
module_count = sizeof(static_authdata_systems)
/ sizeof(static_authdata_systems[0]);
- if (authdata_plugins_ftables != NULL) {
- for (i = 0; authdata_plugins_ftables[i] != NULL; i++) {
- ftable = authdata_plugins_ftables[i];
- if ((ftable->authdata_proc != NULL)) {
+
+ if (authdata_plugins_ftables_v1 != NULL) {
+ struct krb5plugin_authdata_ftable_v1 *ftable;
+
+ for (i = 0; authdata_plugins_ftables_v1[i] != NULL; i++) {
+ ftable = authdata_plugins_ftables_v1[i];
+ if (ftable->authdata_proc != NULL)
+ module_count++;
+ }
+ }
+
+ if (authdata_plugins_ftables_v0 != NULL) {
+ struct krb5plugin_authdata_ftable_v0 *ftable;
+
+ for (i = 0; authdata_plugins_ftables_v0[i] != NULL; i++) {
+ ftable = authdata_plugins_ftables_v0[i];
+ if (ftable->authdata_proc != NULL)
module_count++;
- }
}
}
@@ -180,16 +185,14 @@ load_authdata_plugins(krb5_context context)
* leave room for a terminator entry. */
authdata_systems = calloc(module_count + 1, sizeof(krb5_authdata_systems));
if (authdata_systems == NULL) {
- krb5int_free_plugin_dir_data(authdata_plugins_ftables);
- return ENOMEM;
+ code = ENOMEM;
+ goto cleanup;
}
/* Add the locally-supplied mechanisms to the dynamic list first. */
for (i = 0, k = 0;
i < sizeof(static_authdata_systems) / sizeof(static_authdata_systems[0]);
i++) {
- if (static_authdata_systems[i].type == -1)
- break;
authdata_systems[k] = static_authdata_systems[i];
/* Try to initialize the authdata system. If it fails, we'll remove it
* from the list of systems we'll be using. */
@@ -202,13 +205,53 @@ load_authdata_plugins(krb5_context context)
k++;
}
- /* Now add the dynamically-loaded mechanisms to the list. */
- if (authdata_plugins_ftables != NULL) {
- for (i = 0; authdata_plugins_ftables[i] != NULL; i++) {
+ /* Add dynamically loaded V1 plugins */
+ if (authdata_plugins_ftables_v1 != NULL) {
+ struct krb5plugin_authdata_ftable_v1 *ftable;
+
+ for (i = 0; authdata_plugins_ftables_v1[i] != NULL; i++) {
+ krb5_error_code initerr;
+ void *pctx = NULL;
+
+ ftable = authdata_plugins_ftables_v1[i];
+ if ((ftable->authdata_proc == NULL)) {
+ continue;
+ }
+ server_init_proc = ftable->init_proc;
+ if ((server_init_proc != NULL) &&
+ ((initerr = (*server_init_proc)(context, &pctx)) != 0)) {
+ const char *emsg;
+ emsg = krb5_get_error_message(context, initerr);
+ if (emsg) {
+ krb5_klog_syslog(LOG_ERR,
+ "authdata %s failed to initialize: %s",
+ ftable->name, emsg);
+ krb5_free_error_message(context, emsg);
+ }
+ memset(&authdata_systems[k], 0, sizeof(authdata_systems[k]));
+
+ continue;
+ }
+
+ authdata_systems[k].name = ftable->name;
+ authdata_systems[k].type = AUTHDATA_SYSTEM_V1;
+ authdata_systems[k].init = server_init_proc;
+ authdata_systems[k].fini = ftable->fini_proc;
+ authdata_systems[k].handle_authdata.v1 = ftable->authdata_proc;
+ authdata_systems[k].plugin_context = pctx;
+ k++;
+ }
+ }
+
+ /* Add dynamically loaded V0 plugins */
+ if (authdata_plugins_ftables_v0 != NULL) {
+ struct krb5plugin_authdata_ftable_v0 *ftable;
+
+ for (i = 0; authdata_plugins_ftables_v0[i] != NULL; i++) {
krb5_error_code initerr;
void *pctx = NULL;
- ftable = authdata_plugins_ftables[i];
+ ftable = authdata_plugins_ftables_v0[i];
if ((ftable->authdata_proc == NULL)) {
continue;
}
@@ -229,19 +272,28 @@ load_authdata_plugins(krb5_context context)
}
authdata_systems[k].name = ftable->name;
+ authdata_systems[k].type = AUTHDATA_SYSTEM_V0;
authdata_systems[k].init = server_init_proc;
authdata_systems[k].fini = ftable->fini_proc;
- authdata_systems[k].handle_authdata = ftable->authdata_proc;
+ authdata_systems[k].handle_authdata.v0 = ftable->authdata_proc;
authdata_systems[k].plugin_context = pctx;
k++;
}
- krb5int_free_plugin_dir_data(authdata_plugins_ftables);
}
+
n_authdata_systems = k;
/* Add the end-of-list marker. */
authdata_systems[k].name = "[end]";
- authdata_systems[k].type = -1;
- return 0;
+ authdata_systems[k].type = AUTHDATA_SYSTEM_UNKNOWN;
+ code = 0;
+
+cleanup:
+ if (authdata_plugins_ftables_v1 != NULL)
+ krb5int_free_plugin_dir_data(authdata_plugins_ftables_v1);
+ if (authdata_plugins_ftables_v0 != NULL)
+ krb5int_free_plugin_dir_data(authdata_plugins_ftables_v0);
+
+ return code;
}
krb5_error_code
@@ -264,33 +316,296 @@ unload_authdata_plugins(krb5_context context)
return 0;
}
+/* Merge authdata. If copy == 0, in_authdata is invalid on return */
+static krb5_error_code
+merge_authdata (krb5_context context,
+ krb5_authdata **in_authdata,
+ krb5_authdata ***out_authdata,
+ krb5_boolean copy)
+{
+ size_t i, nadata = 0;
+ krb5_authdata **authdata = *out_authdata;
+
+ if (in_authdata == NULL || in_authdata[0] == NULL)
+ return 0;
+
+ if (authdata != NULL) {
+ for (nadata = 0; authdata[nadata] != NULL; nadata++)
+ ;
+ }
+
+ for (i = 0; in_authdata[i] != NULL; i++)
+ ;
+
+ if (authdata == NULL) {
+ authdata = (krb5_authdata **)calloc(i + 1, sizeof(krb5_authdata *));
+ } else {
+ authdata = (krb5_authdata **)realloc(authdata,
+ ((nadata + i + 1) * sizeof(krb5_authdata *)));
+ }
+ if (authdata == NULL)
+ return ENOMEM;
+
+ if (copy) {
+ krb5_error_code code;
+ krb5_authdata **tmp;
+
+ code = krb5_copy_authdata(context, in_authdata, &tmp);
+ if (code != 0)
+ return code;
+
+ in_authdata = tmp;
+ }
+
+ for (i = 0; in_authdata[i] != NULL; i++)
+ authdata[nadata + i] = in_authdata[i];
+
+ authdata[nadata + i] = NULL;
+
+ free(in_authdata);
+
+ *out_authdata = authdata;
+
+ return 0;
+}
+
+/* Handle copying TGS-REQ authorization data into reply */
+static krb5_error_code
+handle_request_authdata (krb5_context context,
+ unsigned int flags,
+ krb5_db_entry *client,
+ krb5_db_entry *server,
+ krb5_db_entry *krbtgt,
+ krb5_keyblock *client_key,
+ krb5_keyblock *server_key,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request,
+ krb5_const_principal for_user_princ,
+ krb5_enc_tkt_part *enc_tkt_request,
+ krb5_enc_tkt_part *enc_tkt_reply)
+{
+ krb5_error_code code;
+ krb5_data scratch;
+
+ if (request->msg_type != KRB5_TGS_REQ ||
+ request->authorization_data.ciphertext.data == NULL)
+ return 0;
+
+ assert(enc_tkt_request != NULL);
+
+ scratch.length = request->authorization_data.ciphertext.length;
+ scratch.data = malloc(scratch.length);
+ if (scratch.data == NULL)
+ return ENOMEM;
+
+ code = krb5_c_decrypt(context,
+ enc_tkt_request->session,
+ KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY,
+ 0, &request->authorization_data,
+ &scratch);
+ if (code != 0) {
+ free(scratch.data);
+ return code;
+ }
+
+ /* scratch now has the authorization data, so we decode it, and make
+ * it available to subsequent authdata plugins */
+ code = decode_krb5_authdata(&scratch, &request->unenc_authdata);
+ if (code != 0) {
+ free(scratch.data);
+ return code;
+ }
+
+ free(scratch.data);
+
+ code = merge_authdata(context, request->unenc_authdata,
+ &enc_tkt_reply->authorization_data, TRUE /* copy */);
+
+ return code;
+}
+
+/* Handle backend-managed authorization data */
+static krb5_error_code
+handle_tgt_authdata (krb5_context context,
+ unsigned int flags,
+ krb5_db_entry *client,
+ krb5_db_entry *server,
+ krb5_db_entry *krbtgt,
+ krb5_keyblock *client_key,
+ krb5_keyblock *server_key,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request,
+ krb5_const_principal for_user_princ,
+ krb5_enc_tkt_part *enc_tkt_request,
+ krb5_enc_tkt_part *enc_tkt_reply)
+{
+ krb5_error_code code;
+ krb5_authdata **db_authdata = NULL;
+ krb5_db_entry ad_entry;
+ int ad_nprincs = 0;
+ krb5_boolean tgs_req = (request->msg_type == KRB5_TGS_REQ);
+ krb5_const_principal actual_client;
+
+ /*
+ * Check whether KDC issued authorization data should be included.
+ * A server can explicitly disable the inclusion of authorization
+ * data by setting the KRB5_KDB_NO_AUTH_DATA_REQUIRED flag on its
+ * principal entry. Otherwise authorization data will be included
+ * if it was present in the TGT, the client is from another realm
+ * or protocol transition/constrained delegation was used, or, in
+ * the AS-REQ case, if the pre-auth data indicated the PAC should
+ * be present.
+ *
+ * We permit sign_authorization_data() to return a krb5_db_entry
+ * representing the principal associated with the authorization
+ * data, in case that principal is not local to our realm and we
+ * need to perform additional checks (such as disabling delegation
+ * for cross-realm protocol transition below).
+ */
+ if (tgs_req) {
+ assert(enc_tkt_request != NULL);
+
+ if (isflagset(server->attributes, KRB5_KDB_NO_AUTH_DATA_REQUIRED))
+ return 0;
+
+ if (enc_tkt_request->authorization_data == NULL &&
+ !isflagset(flags, KRB5_KDB_FLAG_CROSS_REALM | KRB5_KDB_FLAGS_S4U))
+ return 0;
+
+ assert(enc_tkt_reply->times.authtime == enc_tkt_request->times.authtime);
+ } else {
+ if (!isflagset(flags, KRB5_KDB_FLAG_INCLUDE_PAC))
+ return 0;
+ }
+
+ /*
+ * We have this special case for protocol transition, because for
+ * cross-realm protocol transition the ticket reply client will
+ * not be changed until the final hop.
+ */
+ if (isflagset(flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION))
+ actual_client = for_user_princ;
+ else
+ actual_client = enc_tkt_reply->client;
+
+ /*
+ * If the backend does not implement the sign authdata method, then
+ * just copy the TGT authorization data into the reply, except for
+ * the constrained delegation case (which requires special handling
+ * because it will promote untrusted auth data to KDC issued auth
+ * data; this requires backend-specific code)
+ *
+ * Presently this interface does not support using request auth data
+ * to influence (eg. possibly restrict) the reply auth data.
+ */
+ code = sign_db_authdata(context,
+ flags,
+ actual_client,
+ client,
+ server,
+ krbtgt,
+ client_key,
+ server_key, /* U2U or server key */
+ enc_tkt_reply->times.authtime,
+ tgs_req ? enc_tkt_request->authorization_data : NULL,
+ &db_authdata,
+ &ad_entry,
+ &ad_nprincs);
+ if (code == KRB5_KDB_DBTYPE_NOSUP) {
+ assert(ad_nprincs == 0);
+ assert(db_authdata == NULL);
+
+ if (isflagset(flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION))
+ return KRB5KDC_ERR_POLICY;
+
+ if (tgs_req)
+ return merge_authdata(context, enc_tkt_request->authorization_data,
+ &enc_tkt_reply->authorization_data, TRUE);
+ else
+ return 0;
+ }
+
+ if (ad_nprincs != 0) {
+ if (isflagset(flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION) &&
+ isflagset(ad_entry.attributes, KRB5_KDB_DISALLOW_FORWARDABLE))
+ clear(enc_tkt_reply->flags, TKT_FLG_FORWARDABLE);
+
+ krb5_db_free_principal(context, &ad_entry, ad_nprincs);
+
+ if (ad_nprincs != 1) {
+ if (db_authdata != NULL)
+ krb5_free_authdata(context, db_authdata);
+ return KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE;
+ }
+ }
+
+ if (db_authdata != NULL) {
+ code = merge_authdata(context, db_authdata,
+ &enc_tkt_reply->authorization_data,
+ FALSE);
+ if (code != 0)
+ krb5_free_authdata(context, db_authdata);
+ }
+
+ return code;
+}
+
krb5_error_code
-handle_authdata (krb5_context context, krb5_db_entry *client,
- krb5_data *req_pkt, krb5_kdc_req *request,
+handle_authdata (krb5_context context,
+ unsigned int flags,
+ krb5_db_entry *client,
+ krb5_db_entry *server,
+ krb5_db_entry *krbtgt,
+ krb5_keyblock *client_key,
+ krb5_keyblock *server_key,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request,
+ krb5_const_principal for_user_princ,
+ krb5_enc_tkt_part *enc_tkt_request,
krb5_enc_tkt_part *enc_tkt_reply)
{
- krb5_error_code retval = 0;
+ krb5_error_code code = 0;
int i;
- const char *emsg;
-
- krb5_klog_syslog (LOG_DEBUG, "handling authdata");
+ assert(enc_tkt_reply->authorization_data == NULL);
for (i = 0; i < n_authdata_systems; i++) {
const krb5_authdata_systems *asys = &authdata_systems[i];
- if (asys->handle_authdata && asys->type != -1) {
- retval = asys->handle_authdata(context, client, req_pkt,
- request, enc_tkt_reply);
- if (retval) {
- emsg = krb5_get_error_message (context, retval);
- krb5_klog_syslog (LOG_INFO,
- "authdata (%s) handling failure: %s",
- asys->name, emsg);
- krb5_free_error_message (context, emsg);
- } else {
- krb5_klog_syslog (LOG_DEBUG, ".. .. ok");
- }
+
+ switch (asys->type) {
+ case AUTHDATA_SYSTEM_V0:
+ /* V0 was only in AS-REQ code path */
+ if (request->msg_type != KRB5_AS_REQ)
+ continue;
+
+ code = (*asys->handle_authdata.v0)(context, client, req_pkt,
+ request, enc_tkt_reply);
+ break;
+ case AUTHDATA_SYSTEM_V1:
+ code = (*asys->handle_authdata.v1)(context, flags,
+ client, server, krbtgt,
+ client_key, server_key,
+ req_pkt, request, for_user_princ,
+ enc_tkt_request,
+ enc_tkt_reply);
+ break;
+ default:
+ code = 0;
+ break;
+ }
+ if (code != 0) {
+ const char *emsg;
+
+ emsg = krb5_get_error_message (context, code);
+ krb5_klog_syslog (LOG_INFO,
+ "authdata (%s) handling failure: %s",
+ asys->name, emsg);
+ krb5_free_error_message (context, emsg);
+
+ if (asys->flags & AUTHDATA_FLAG_CRITICAL)
+ break;
}
}
- return 0;
+ return code;
}
+