kdc: add referral_policy callback to windc plugin
Add a referral policy hook to the TGS as a more elegant way of resolving referral detection for Samba). The hook can either rewrite the server_princ in the request, or it can return an error to disable built-in referral processing.
This commit is contained in:
@@ -1518,6 +1518,7 @@ tgs_build_reply(astgs_request_t priv,
|
|||||||
|
|
||||||
server_lookup:
|
server_lookup:
|
||||||
priv->server = NULL;
|
priv->server = NULL;
|
||||||
|
priv->server_princ = sp;
|
||||||
if (server)
|
if (server)
|
||||||
_kdc_free_ent(context, server);
|
_kdc_free_ent(context, server);
|
||||||
server = NULL;
|
server = NULL;
|
||||||
@@ -1560,7 +1561,25 @@ server_lookup:
|
|||||||
Realm req_rlm;
|
Realm req_rlm;
|
||||||
krb5_realm *realms;
|
krb5_realm *realms;
|
||||||
|
|
||||||
if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
|
priv->ret = ret; /* advise policy plugin of failure reason */
|
||||||
|
ret2 = _kdc_referral_policy(priv);
|
||||||
|
if (ret2 == 0) {
|
||||||
|
heim_assert(priv->server_princ != sp,
|
||||||
|
"Referral policy plugin must update server principal");
|
||||||
|
|
||||||
|
krb5_free_principal(context, sp);
|
||||||
|
sp = priv->server_princ;
|
||||||
|
|
||||||
|
krb5_xfree(priv->sname);
|
||||||
|
priv->sname = NULL;
|
||||||
|
ret = krb5_unparse_name(context, sp, &priv->sname);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
spn = priv->sname;
|
||||||
|
goto server_lookup;
|
||||||
|
} else if (ret2 != KRB5_PLUGIN_NO_HANDLE) {
|
||||||
|
ret = ret2;
|
||||||
|
} else if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
|
||||||
if (capath == NULL) {
|
if (capath == NULL) {
|
||||||
/* With referalls, hierarchical capaths are always enabled */
|
/* With referalls, hierarchical capaths are always enabled */
|
||||||
ret2 = _krb5_find_capath(context, tgt->crealm, our_realm,
|
ret2 = _krb5_find_capath(context, tgt->crealm, our_realm,
|
||||||
|
21
kdc/windc.c
21
kdc/windc.c
@@ -234,6 +234,27 @@ _kdc_finalize_reply(astgs_request_t r)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static krb5_error_code KRB5_LIB_CALL
|
||||||
|
referral_policy(krb5_context context, const void *plug, void *plugctx, void *userctx)
|
||||||
|
{
|
||||||
|
krb5plugin_windc_ftable *ft = (krb5plugin_windc_ftable *)plug;
|
||||||
|
|
||||||
|
if (ft->referral_policy == NULL)
|
||||||
|
return KRB5_PLUGIN_NO_HANDLE;
|
||||||
|
return ft->referral_policy((void *)plug, userctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_error_code
|
||||||
|
_kdc_referral_policy(astgs_request_t r)
|
||||||
|
{
|
||||||
|
krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE;
|
||||||
|
|
||||||
|
if (have_plugin)
|
||||||
|
ret = _krb5_plugin_run_f(r->context, &windc_plugin_data, 0, r, referral_policy);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
uintptr_t KRB5_CALLCONV
|
uintptr_t KRB5_CALLCONV
|
||||||
kdc_get_instance(const char *libname)
|
kdc_get_instance(const char *libname)
|
||||||
{
|
{
|
||||||
|
@@ -84,6 +84,20 @@ typedef krb5_error_code
|
|||||||
typedef krb5_error_code
|
typedef krb5_error_code
|
||||||
(KRB5_CALLCONV *krb5plugin_windc_finalize_reply)(void *, astgs_request_t r);
|
(KRB5_CALLCONV *krb5plugin_windc_finalize_reply)(void *, astgs_request_t r);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A referral policy plugin can either rewrite the server principal
|
||||||
|
* by resetting priv->server_princ, or it can disable referral
|
||||||
|
* processing entirely by returning an error.
|
||||||
|
*
|
||||||
|
* The error code from the previous server lookup is available as r->ret.
|
||||||
|
*
|
||||||
|
* If the function returns KRB5_PLUGIN_NO_HANDLE, the TGS will continue
|
||||||
|
* with its default referral handling.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef krb5_error_code
|
||||||
|
(KRB5_CALLCONV *krb5plugin_windc_referral_policy)(void *, astgs_request_t r);
|
||||||
|
|
||||||
#define KRB5_WINDC_PLUGIN_MINOR 8
|
#define KRB5_WINDC_PLUGIN_MINOR 8
|
||||||
#define KRB5_WINDC_PLUGING_MINOR KRB5_WINDC_PLUGIN_MINOR
|
#define KRB5_WINDC_PLUGING_MINOR KRB5_WINDC_PLUGIN_MINOR
|
||||||
|
|
||||||
@@ -94,6 +108,7 @@ typedef struct krb5plugin_windc_ftable {
|
|||||||
krb5plugin_windc_pac_generate pac_generate;
|
krb5plugin_windc_pac_generate pac_generate;
|
||||||
krb5plugin_windc_pac_verify pac_verify;
|
krb5plugin_windc_pac_verify pac_verify;
|
||||||
krb5plugin_windc_client_access client_access;
|
krb5plugin_windc_client_access client_access;
|
||||||
|
krb5plugin_windc_referral_policy referral_policy;
|
||||||
krb5plugin_windc_finalize_reply finalize_reply;
|
krb5plugin_windc_finalize_reply finalize_reply;
|
||||||
} krb5plugin_windc_ftable;
|
} krb5plugin_windc_ftable;
|
||||||
|
|
||||||
|
@@ -123,6 +123,7 @@ static krb5plugin_windc_ftable windc = {
|
|||||||
pac_generate,
|
pac_generate,
|
||||||
pac_verify,
|
pac_verify,
|
||||||
client_access,
|
client_access,
|
||||||
|
NULL, /* referral_policy */
|
||||||
finalize_reply
|
finalize_reply
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user