+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+
+/*
+ * lib/krb5/krb/auth_con.c
+ *
+ * Copyright 2010 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
#include "k5-int.h"
+#include "int-proto.h"
#include "auth_con.h"
static krb5_boolean chk_heimdal_seqnum(krb5_ui_4, krb5_ui_4);
-static krb5_error_code
-actx_copy_addr(krb5_context context, const krb5_address *inad, krb5_address **outad)
-{
- krb5_address *tmpad;
-
- if (!(tmpad = (krb5_address *)malloc(sizeof(*tmpad))))
- return ENOMEM;
- *tmpad = *inad;
- if (!(tmpad->contents = (krb5_octet *)malloc(inad->length))) {
- free(tmpad);
- return ENOMEM;
- }
- memcpy(tmpad->contents, inad->contents, inad->length);
- *outad = tmpad;
- return 0;
-}
-
krb5_error_code KRB5_CALLCONV
krb5_auth_con_init(krb5_context context, krb5_auth_context *auth_context)
{
*auth_context =
- (krb5_auth_context)calloc(1, sizeof(struct _krb5_auth_context));
+ (krb5_auth_context)calloc(1, sizeof(struct _krb5_auth_context));
if (!*auth_context)
- return ENOMEM;
+ return ENOMEM;
/* Default flags, do time not seq */
- (*auth_context)->auth_context_flags =
- KRB5_AUTH_CONTEXT_DO_TIME | KRB5_AUTH_CONN_INITIALIZED;
+ (*auth_context)->auth_context_flags =
+ KRB5_AUTH_CONTEXT_DO_TIME | KRB5_AUTH_CONN_INITIALIZED;
(*auth_context)->req_cksumtype = context->default_ap_req_sumtype;
(*auth_context)->safe_cksumtype = context->default_safe_sumtype;
krb5_error_code KRB5_CALLCONV
krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context)
{
- if (auth_context->local_addr)
- krb5_free_address(context, auth_context->local_addr);
- if (auth_context->remote_addr)
- krb5_free_address(context, auth_context->remote_addr);
- if (auth_context->local_port)
- krb5_free_address(context, auth_context->local_port);
- if (auth_context->remote_port)
- krb5_free_address(context, auth_context->remote_port);
- if (auth_context->authentp)
- krb5_free_authenticator(context, auth_context->authentp);
- if (auth_context->keyblock)
- krb5_free_keyblock(context, auth_context->keyblock);
- if (auth_context->send_subkey)
- krb5_free_keyblock(context, auth_context->send_subkey);
- if (auth_context->recv_subkey)
- krb5_free_keyblock(context, auth_context->recv_subkey);
+ if (auth_context == NULL)
+ return 0;
+ if (auth_context->local_addr)
+ krb5_free_address(context, auth_context->local_addr);
+ if (auth_context->remote_addr)
+ krb5_free_address(context, auth_context->remote_addr);
+ if (auth_context->local_port)
+ krb5_free_address(context, auth_context->local_port);
+ if (auth_context->remote_port)
+ krb5_free_address(context, auth_context->remote_port);
+ if (auth_context->authentp)
+ krb5_free_authenticator(context, auth_context->authentp);
+ if (auth_context->key)
+ krb5_k_free_key(context, auth_context->key);
+ if (auth_context->send_subkey)
+ krb5_k_free_key(context, auth_context->send_subkey);
+ if (auth_context->recv_subkey)
+ krb5_k_free_key(context, auth_context->recv_subkey);
if (auth_context->rcache)
- krb5_rc_close(context, auth_context->rcache);
+ krb5_rc_close(context, auth_context->rcache);
if (auth_context->permitted_etypes)
- free(auth_context->permitted_etypes);
+ free(auth_context->permitted_etypes);
+ if (auth_context->ad_context)
+ krb5_authdata_context_free(context, auth_context->ad_context);
free(auth_context);
return 0;
}
krb5_error_code
krb5_auth_con_setaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address *local_addr, krb5_address *remote_addr)
{
- krb5_error_code retval;
+ krb5_error_code retval;
/* Free old addresses */
if (auth_context->local_addr)
- (void) krb5_free_address(context, auth_context->local_addr);
+ (void) krb5_free_address(context, auth_context->local_addr);
if (auth_context->remote_addr)
- (void) krb5_free_address(context, auth_context->remote_addr);
+ (void) krb5_free_address(context, auth_context->remote_addr);
retval = 0;
if (local_addr)
- retval = actx_copy_addr(context,
- local_addr,
- &auth_context->local_addr);
+ retval = krb5_copy_addr(context,
+ local_addr,
+ &auth_context->local_addr);
else
- auth_context->local_addr = NULL;
+ auth_context->local_addr = NULL;
if (!retval && remote_addr)
- retval = actx_copy_addr(context,
- remote_addr,
- &auth_context->remote_addr);
+ retval = krb5_copy_addr(context,
+ remote_addr,
+ &auth_context->remote_addr);
else
- auth_context->remote_addr = NULL;
+ auth_context->remote_addr = NULL;
return retval;
}
krb5_error_code KRB5_CALLCONV
krb5_auth_con_getaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address **local_addr, krb5_address **remote_addr)
{
- krb5_error_code retval;
+ krb5_error_code retval;
retval = 0;
if (local_addr && auth_context->local_addr) {
- retval = actx_copy_addr(context,
- auth_context->local_addr,
- local_addr);
+ retval = krb5_copy_addr(context,
+ auth_context->local_addr,
+ local_addr);
}
if (!retval && (remote_addr) && auth_context->remote_addr) {
- retval = actx_copy_addr(context,
- auth_context->remote_addr,
- remote_addr);
+ retval = krb5_copy_addr(context,
+ auth_context->remote_addr,
+ remote_addr);
}
return retval;
}
krb5_error_code KRB5_CALLCONV
krb5_auth_con_setports(krb5_context context, krb5_auth_context auth_context, krb5_address *local_port, krb5_address *remote_port)
{
- krb5_error_code retval;
+ krb5_error_code retval;
/* Free old addresses */
if (auth_context->local_port)
- (void) krb5_free_address(context, auth_context->local_port);
+ (void) krb5_free_address(context, auth_context->local_port);
if (auth_context->remote_port)
- (void) krb5_free_address(context, auth_context->remote_port);
+ (void) krb5_free_address(context, auth_context->remote_port);
retval = 0;
if (local_port)
- retval = actx_copy_addr(context,
- local_port,
- &auth_context->local_port);
+ retval = krb5_copy_addr(context,
+ local_port,
+ &auth_context->local_port);
else
- auth_context->local_port = NULL;
+ auth_context->local_port = NULL;
if (!retval && remote_port)
- retval = actx_copy_addr(context,
- remote_port,
- &auth_context->remote_port);
+ retval = krb5_copy_addr(context,
+ remote_port,
+ &auth_context->remote_port);
else
- auth_context->remote_port = NULL;
+ auth_context->remote_port = NULL;
return retval;
}
krb5_error_code KRB5_CALLCONV
krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock)
{
- if (auth_context->keyblock)
- krb5_free_keyblock(context, auth_context->keyblock);
- return(krb5_copy_keyblock(context, keyblock, &(auth_context->keyblock)));
+ if (auth_context->key)
+ krb5_k_free_key(context, auth_context->key);
+ return(krb5_k_create_key(context, keyblock, &(auth_context->key)));
}
krb5_error_code KRB5_CALLCONV
krb5_auth_con_getkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
{
- if (auth_context->keyblock)
- return krb5_copy_keyblock(context, auth_context->keyblock, keyblock);
+ if (auth_context->key)
+ return krb5_k_key_keyblock(context, auth_context->key, keyblock);
*keyblock = NULL;
return 0;
}
+krb5_error_code KRB5_CALLCONV
+krb5_auth_con_getkey_k(krb5_context context, krb5_auth_context auth_context,
+ krb5_key *key)
+{
+ krb5_k_reference_key(context, auth_context->key);
+ *key = auth_context->key;
+ return 0;
+}
+
krb5_error_code KRB5_CALLCONV
krb5_auth_con_getlocalsubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
{
krb5_auth_con_setsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock)
{
if (ac->send_subkey != NULL)
- krb5_free_keyblock(ctx, ac->send_subkey);
+ krb5_k_free_key(ctx, ac->send_subkey);
ac->send_subkey = NULL;
if (keyblock !=NULL)
- return krb5_copy_keyblock(ctx, keyblock, &ac->send_subkey);
+ return krb5_k_create_key(ctx, keyblock, &ac->send_subkey);
else
- return 0;
+ return 0;
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_auth_con_setsendsubkey_k(krb5_context ctx, krb5_auth_context ac,
+ krb5_key key)
+{
+ krb5_k_free_key(ctx, ac->send_subkey);
+ ac->send_subkey = key;
+ krb5_k_reference_key(ctx, key);
+ return 0;
}
krb5_error_code KRB5_CALLCONV
krb5_auth_con_setrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock)
{
if (ac->recv_subkey != NULL)
- krb5_free_keyblock(ctx, ac->recv_subkey);
+ krb5_k_free_key(ctx, ac->recv_subkey);
ac->recv_subkey = NULL;
if (keyblock != NULL)
- return krb5_copy_keyblock(ctx, keyblock, &ac->recv_subkey);
+ return krb5_k_create_key(ctx, keyblock, &ac->recv_subkey);
else
- return 0;
+ return 0;
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_auth_con_setrecvsubkey_k(krb5_context ctx, krb5_auth_context ac,
+ krb5_key key)
+{
+ krb5_k_free_key(ctx, ac->recv_subkey);
+ ac->recv_subkey = key;
+ krb5_k_reference_key(ctx, key);
+ return 0;
}
krb5_error_code KRB5_CALLCONV
krb5_auth_con_getsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)
{
if (ac->send_subkey != NULL)
- return krb5_copy_keyblock(ctx, ac->send_subkey, keyblock);
+ return krb5_k_key_keyblock(ctx, ac->send_subkey, keyblock);
*keyblock = NULL;
return 0;
}
+krb5_error_code KRB5_CALLCONV
+krb5_auth_con_getsendsubkey_k(krb5_context ctx, krb5_auth_context ac,
+ krb5_key *key)
+{
+ krb5_k_reference_key(ctx, ac->send_subkey);
+ *key = ac->send_subkey;
+ return 0;
+}
+
krb5_error_code KRB5_CALLCONV
krb5_auth_con_getrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)
{
if (ac->recv_subkey != NULL)
- return krb5_copy_keyblock(ctx, ac->recv_subkey, keyblock);
+ return krb5_k_key_keyblock(ctx, ac->recv_subkey, keyblock);
*keyblock = NULL;
return 0;
}
+krb5_error_code KRB5_CALLCONV
+krb5_auth_con_getrecvsubkey_k(krb5_context ctx, krb5_auth_context ac,
+ krb5_key *key)
+{
+ krb5_k_reference_key(ctx, ac->recv_subkey);
+ *key = ac->recv_subkey;
+ return 0;
+}
+
krb5_error_code KRB5_CALLCONV
krb5_auth_con_set_req_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_cksumtype cksumtype)
{
*seqnumber = auth_context->local_seq_number;
return 0;
}
-#ifndef LEAN_CLIENT
-krb5_error_code KRB5_CALLCONV
-krb5_auth_con_getauthenticator(krb5_context context, krb5_auth_context auth_context, krb5_authenticator **authenticator)
-{
- return (krb5_copy_authenticator(context, auth_context->authentp,
- authenticator));
-}
-#endif
krb5_error_code KRB5_CALLCONV
krb5_auth_con_getremoteseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber)
krb5_auth_con_initivector(krb5_context context, krb5_auth_context auth_context)
{
krb5_error_code ret;
-
- if (auth_context->keyblock) {
- size_t blocksize;
-
- if ((ret = krb5_c_block_size(context, auth_context->keyblock->enctype,
- &blocksize)))
- return(ret);
- if ((auth_context->i_vector = (krb5_pointer)calloc(1,blocksize))) {
- return 0;
- }
- return ENOMEM;
+ krb5_enctype enctype;
+
+ if (auth_context->key) {
+ size_t blocksize;
+
+ enctype = krb5_k_key_enctype(context, auth_context->key);
+ if ((ret = krb5_c_block_size(context, enctype, &blocksize)))
+ return(ret);
+ if ((auth_context->i_vector = (krb5_pointer)calloc(1,blocksize))) {
+ return 0;
+ }
+ return ENOMEM;
}
return EINVAL; /* XXX need an error for no keyblock */
}
auth_context->rcache = rcache;
return 0;
}
-
+
krb5_error_code
krb5_auth_con_getrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache *rcache)
{
*rcache = auth_context->rcache;
return 0;
}
-
+
krb5_error_code
-krb5_auth_con_setpermetypes(krb5_context context, krb5_auth_context auth_context, const krb5_enctype *permetypes)
+krb5_auth_con_setpermetypes(krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_enctype *permetypes)
{
- krb5_enctype * newpe;
- int i;
-
- for (i=0; permetypes[i]; i++)
- ;
- i++; /* include the zero */
-
- if ((newpe = (krb5_enctype *) malloc(i*sizeof(krb5_enctype)))
- == NULL)
- return(ENOMEM);
+ krb5_enctype *newpe;
+ krb5_error_code ret;
- if (auth_context->permitted_etypes)
- free(auth_context->permitted_etypes);
+ ret = krb5int_copy_etypes(permetypes, &newpe);
+ if (ret != 0)
+ return ret;
+ free(auth_context->permitted_etypes);
auth_context->permitted_etypes = newpe;
-
- memcpy(newpe, permetypes, i*sizeof(krb5_enctype));
-
return 0;
}
krb5_error_code
-krb5_auth_con_getpermetypes(krb5_context context, krb5_auth_context auth_context, krb5_enctype **permetypes)
+krb5_auth_con_getpermetypes(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_enctype **permetypes)
{
- krb5_enctype * newpe;
- int i;
-
- if (! auth_context->permitted_etypes) {
- *permetypes = NULL;
- return(0);
- }
-
- for (i=0; auth_context->permitted_etypes[i]; i++)
- ;
- i++; /* include the zero */
-
- if ((newpe = (krb5_enctype *) malloc(i*sizeof(krb5_enctype)))
- == NULL)
- return(ENOMEM);
-
- *permetypes = newpe;
-
- memcpy(newpe, auth_context->permitted_etypes, i*sizeof(krb5_enctype));
-
- return(0);
+ *permetypes = NULL;
+ if (auth_context->permitted_etypes == NULL)
+ return 0;
+ return krb5int_copy_etypes(auth_context->permitted_etypes, permetypes);
}
krb5_error_code KRB5_CALLCONV
krb5_auth_con_set_checksum_func( krb5_context context,
- krb5_auth_context auth_context,
- krb5_mk_req_checksum_func func,
- void *data)
+ krb5_auth_context auth_context,
+ krb5_mk_req_checksum_func func,
+ void *data)
{
- auth_context->checksum_func = func;
- auth_context->checksum_func_data = data;
- return 0;
+ auth_context->checksum_func = func;
+ auth_context->checksum_func_data = data;
+ return 0;
}
krb5_error_code KRB5_CALLCONV
krb5_auth_con_get_checksum_func( krb5_context context,
- krb5_auth_context auth_context,
- krb5_mk_req_checksum_func *func,
- void **data)
+ krb5_auth_context auth_context,
+ krb5_mk_req_checksum_func *func,
+ void **data)
{
- *func = auth_context->checksum_func;
- *data = auth_context->checksum_func_data;
- return 0;
+ *func = auth_context->checksum_func;
+ *data = auth_context->checksum_func_data;
+ return 0;
}
/*
* compatibility with our older implementations. This also means that
* encodings emitted by Heimdal are ambiguous.
*
- * Heimdal counter value received uint32 value
+ * Heimdal counter value received uint32 value
*
- * 0x00000080 0xFFFFFF80
- * 0x000000FF 0xFFFFFFFF
- * 0x00008000 0xFFFF8000
- * 0x0000FFFF 0xFFFFFFFF
- * 0x00800000 0xFF800000
- * 0x00FFFFFF 0xFFFFFFFF
- * 0xFF800000 0xFF800000
- * 0xFFFFFFFF 0xFFFFFFFF
+ * 0x00000080 0xFFFFFF80
+ * 0x000000FF 0xFFFFFFFF
+ * 0x00008000 0xFFFF8000
+ * 0x0000FFFF 0xFFFFFFFF
+ * 0x00800000 0xFF800000
+ * 0x00FFFFFF 0xFFFFFFFF
+ * 0xFF800000 0xFF800000
+ * 0xFFFFFFFF 0xFFFFFFFF
*
* We use two auth_context flags, SANE_SEQ and HEIMDAL_SEQ, which are
* only set after we can unambiguously determine the sanity of the
* If sender is known to be sane, accept _only_ exact matches.
*/
if (ac->auth_context_flags & KRB5_AUTH_CONN_SANE_SEQ)
- return in_seq == exp_seq;
+ return in_seq == exp_seq;
/*
* If sender is not known to be sane, first check the ambiguous
* range of received values, 0xFF800000..0xFFFFFFFF.
*/
if ((in_seq & 0xFF800000) == 0xFF800000) {
- /*
- * If expected sequence number is in the range
- * 0xFF800000..0xFFFFFFFF, then we can't make any
- * determinations about the sanity of the sending
- * implementation.
- */
- if ((exp_seq & 0xFF800000) == 0xFF800000 && in_seq == exp_seq)
- return 1;
- /*
- * If sender is not known for certain to be a broken Heimdal
- * implementation, check for exact match.
- */
- if (!(ac->auth_context_flags & KRB5_AUTH_CONN_HEIMDAL_SEQ)
- && in_seq == exp_seq)
- return 1;
- /*
- * Now apply hairy algorithm for matching sequence numbers
- * sent by broken Heimdal implementations. If it matches, we
- * know for certain it's a broken Heimdal sender.
- */
- if (chk_heimdal_seqnum(exp_seq, in_seq)) {
- ac->auth_context_flags |= KRB5_AUTH_CONN_HEIMDAL_SEQ;
- return 1;
- }
- return 0;
+ /*
+ * If expected sequence number is in the range
+ * 0xFF800000..0xFFFFFFFF, then we can't make any
+ * determinations about the sanity of the sending
+ * implementation.
+ */
+ if ((exp_seq & 0xFF800000) == 0xFF800000 && in_seq == exp_seq)
+ return 1;
+ /*
+ * If sender is not known for certain to be a broken Heimdal
+ * implementation, check for exact match.
+ */
+ if (!(ac->auth_context_flags & KRB5_AUTH_CONN_HEIMDAL_SEQ)
+ && in_seq == exp_seq)
+ return 1;
+ /*
+ * Now apply hairy algorithm for matching sequence numbers
+ * sent by broken Heimdal implementations. If it matches, we
+ * know for certain it's a broken Heimdal sender.
+ */
+ if (chk_heimdal_seqnum(exp_seq, in_seq)) {
+ ac->auth_context_flags |= KRB5_AUTH_CONN_HEIMDAL_SEQ;
+ return 1;
+ }
+ return 0;
}
/*
* it matches the received value, sender is known to be sane.
*/
if (in_seq == exp_seq) {
- if (( exp_seq & 0xFFFFFF80) == 0x00000080
- || (exp_seq & 0xFFFF8000) == 0x00008000
- || (exp_seq & 0xFF800000) == 0x00800000)
- ac->auth_context_flags |= KRB5_AUTH_CONN_SANE_SEQ;
- return 1;
+ if (( exp_seq & 0xFFFFFF80) == 0x00000080
+ || (exp_seq & 0xFFFF8000) == 0x00008000
+ || (exp_seq & 0xFF800000) == 0x00800000)
+ ac->auth_context_flags |= KRB5_AUTH_CONN_SANE_SEQ;
+ return 1;
}
/*
* and mark the sender as being a broken Heimdal implementation.
*/
if (exp_seq == 0
- && !(ac->auth_context_flags & KRB5_AUTH_CONN_HEIMDAL_SEQ)) {
- switch (in_seq) {
- case 0x100:
- case 0x10000:
- case 0x1000000:
- ac->auth_context_flags |= KRB5_AUTH_CONN_HEIMDAL_SEQ;
- exp_seq = in_seq;
- return 1;
- default:
- return 0;
- }
+ && !(ac->auth_context_flags & KRB5_AUTH_CONN_HEIMDAL_SEQ)) {
+ switch (in_seq) {
+ case 0x100:
+ case 0x10000:
+ case 0x1000000:
+ ac->auth_context_flags |= KRB5_AUTH_CONN_HEIMDAL_SEQ;
+ exp_seq = in_seq;
+ return 1;
+ default:
+ return 0;
+ }
}
return 0;
}
chk_heimdal_seqnum(krb5_ui_4 exp_seq, krb5_ui_4 in_seq)
{
if (( exp_seq & 0xFF800000) == 0x00800000
- && (in_seq & 0xFF800000) == 0xFF800000
- && (in_seq & 0x00FFFFFF) == exp_seq)
- return 1;
+ && (in_seq & 0xFF800000) == 0xFF800000
+ && (in_seq & 0x00FFFFFF) == exp_seq)
+ return 1;
else if (( exp_seq & 0xFFFF8000) == 0x00008000
- && (in_seq & 0xFFFF8000) == 0xFFFF8000
- && (in_seq & 0x0000FFFF) == exp_seq)
- return 1;
+ && (in_seq & 0xFFFF8000) == 0xFFFF8000
+ && (in_seq & 0x0000FFFF) == exp_seq)
+ return 1;
else if (( exp_seq & 0xFFFFFF80) == 0x00000080
- && (in_seq & 0xFFFFFF80) == 0xFFFFFF80
- && (in_seq & 0x000000FF) == exp_seq)
- return 1;
+ && (in_seq & 0xFFFFFF80) == 0xFFFFFF80
+ && (in_seq & 0x000000FF) == exp_seq)
+ return 1;
else
- return 0;
+ return 0;
}
krb5_error_code
krb5_auth_con_get_subkey_enctype(krb5_context context,
- krb5_auth_context auth_context,
- krb5_enctype *etype)
+ krb5_auth_context auth_context,
+ krb5_enctype *etype)
{
*etype = auth_context->negotiated_etype;
return 0;
}
+krb5_error_code
+krb5_auth_con_get_authdata_context(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_authdata_context *ad_context)
+{
+ *ad_context = auth_context->ad_context;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_con_set_authdata_context(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_authdata_context ad_context)
+{
+ auth_context->ad_context = ad_context;
+ return 0;
+}