kdc: simplify client_access windc plugin API

Make client_access plugin API take a single argument, astgs_request_t. Note: in
order to avoid making r->outpadata public (it's an internal buffer), but allow
Samba to modify the reply pa data, some pointer magic is required.
This commit is contained in:
Luke Howard
2021-12-23 20:51:37 +11:00
committed by Nico Williams
parent 36fe09f433
commit 64dad876a4
6 changed files with 24 additions and 82 deletions

View File

@@ -70,8 +70,9 @@ struct kdc_patypes;
struct astgs_request_desc {
ASTGS_REQUEST_DESC_COMMON_ELEMENTS;
/* Only AS */
METHOD_DATA outpadata;
/* Only AS */
const struct kdc_patypes *pa_used;
struct as_request_pa_state *pa_state;

View File

@@ -1169,15 +1169,8 @@ _kdc_encode_reply(krb5_context context,
if (ret)
return ret;
if (rep->padata) {
free_METHOD_DATA(rep->padata);
} else {
rep->padata = calloc(1, sizeof(*(rep->padata)));
if (rep->padata == NULL) {
krb5_data_free(&data);
return ENOMEM;
}
}
free_METHOD_DATA(&r->outpadata);
rep->padata = &r->outpadata;
ret = krb5_padata_add(context, rep->padata,
KRB5_PADATA_FX_FAST,
@@ -2102,6 +2095,8 @@ _kdc_as_rep(astgs_request_t r)
memset(rep, 0, sizeof(*rep));
rep->padata = &r->outpadata; /* so we don't need to make this public */
/*
* Look for FAST armor and unwrap
*/
@@ -2381,7 +2376,7 @@ _kdc_as_rep(astgs_request_t r)
* with in a preauth mech.
*/
ret = _kdc_check_access(r, &r->outpadata);
ret = _kdc_check_access(r);
if(ret)
goto out;
@@ -2685,17 +2680,8 @@ _kdc_as_rep(astgs_request_t r)
if (ret)
goto out;
if (r->outpadata.len) {
ALLOC(rep->padata);
if (rep->padata == NULL) {
ret = ENOMEM;
goto out;
}
ret = copy_METHOD_DATA(&r->outpadata, rep->padata);
if (ret)
goto out;
}
if (r->outpadata.len == 0)
rep->padata = NULL;
/* Add the PAC */
if (!r->et.flags.anonymous) {
@@ -2775,6 +2761,7 @@ _kdc_as_rep(astgs_request_t r)
}
out:
r->rep.padata = NULL; /* may point to outpadata */
free_AS_REP(&r->rep);
/*

View File

@@ -600,8 +600,7 @@ tgs_make_reply(astgs_request_t r,
krb5_principal client_principal,
const char *tgt_realm,
uint16_t rodc_id,
krb5_boolean add_ticket_sig,
const METHOD_DATA *enc_pa_data)
krb5_boolean add_ticket_sig)
{
KDC_REQ_BODY *b = &r->req.req_body;
const char **e_text = &r->e_text;
@@ -786,16 +785,7 @@ tgs_make_reply(astgs_request_t r,
_kdc_log_timestamp(r, "TGS-REQ", et->authtime, et->starttime,
et->endtime, et->renew_till);
if (enc_pa_data->len) {
rep->padata = calloc(1, sizeof(*rep->padata));
if (rep->padata == NULL) {
ret = ENOMEM;
goto out;
}
ret = copy_METHOD_DATA(enc_pa_data, rep->padata);
if (ret)
goto out;
}
rep->padata = r->outpadata.len ? &r->outpadata : NULL;
if (krb5_enctype_valid(r->context, serverkey->keytype) != 0
&& _kdc_is_weak_exception(server->entry.principal, serverkey->keytype))
@@ -1476,8 +1466,6 @@ tgs_build_reply(astgs_request_t priv,
hdb_entry_ex *krbtgt_out = NULL;
METHOD_DATA enc_pa_data;
PrincipalName *s;
Realm r;
EncTicketPart adtkt;
@@ -1491,7 +1479,6 @@ tgs_build_reply(astgs_request_t priv,
memset(&sessionkey, 0, sizeof(sessionkey));
memset(&adtkt, 0, sizeof(adtkt));
memset(&enc_pa_data, 0, sizeof(enc_pa_data));
s = b->sname;
r = b->realm;
@@ -2402,7 +2389,7 @@ server_lookup:
}
pa.padata_type = KRB5_PADATA_SERVER_REFERRAL;
ret = add_METHOD_DATA(&enc_pa_data, &pa);
ret = add_METHOD_DATA(&priv->outpadata, &pa);
krb5_data_free(&pa.padata_value);
if (ret) {
kdc_log(context, config, 4,
@@ -2457,8 +2444,7 @@ server_lookup:
cp,
tgt_realm,
rodc_id,
add_ticket_sig,
&enc_pa_data);
add_ticket_sig);
out:
free(user2user_name);
@@ -2488,7 +2474,6 @@ out:
krb5_free_principal(context, sp);
krb5_free_principal(context, krbtgt_out_principal);
free(ref_realm);
free_METHOD_DATA(&enc_pa_data);
free_EncTicketPart(&adtkt);
@@ -2608,6 +2593,7 @@ out:
free(csec);
free(cusec);
r->rep.padata = NULL; /* may point to outpadata */
free_TGS_REP(&r->rep);
free_TransitedEncoding(&r->et.transited);
free(r->et.starttime);
@@ -2646,6 +2632,9 @@ out:
_kdc_free_fast_state(&r->fast);
krb5_pac_free(r->context, r->pac);
if (r->outpadata.len)
free_METHOD_DATA(&r->outpadata);
if (auth_data) {
free_AuthorizationData(auth_data);
free(auth_data);

View File

@@ -184,48 +184,24 @@ _kdc_pac_verify(krb5_context context,
0, &uc, verify);
}
struct check_uc {
krb5_kdc_configuration *config;
hdb_entry_ex *client_ex;
const char *client_name;
hdb_entry_ex *server_ex;
const char *server_name;
KDC_REQ *req;
METHOD_DATA *method_data;
};
static krb5_error_code KRB5_LIB_CALL
check(krb5_context context, const void *plug, void *plugctx, void *userctx)
{
krb5plugin_windc_ftable *ft = (krb5plugin_windc_ftable *)plug;
struct check_uc *uc = (struct check_uc *)userctx;
if (ft->client_access == NULL)
return KRB5_PLUGIN_NO_HANDLE;
return ft->client_access((void *)plug, context, uc->config,
uc->client_ex, uc->client_name,
uc->server_ex, uc->server_name,
uc->req, uc->method_data);
return ft->client_access((void *)plug, userctx);
}
krb5_error_code
_kdc_check_access(astgs_request_t r, METHOD_DATA *method_data)
_kdc_check_access(astgs_request_t r)
{
krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE;
struct check_uc uc;
if (have_plugin) {
uc.config = r->config;
uc.client_ex = r->client;
uc.client_name = r->cname;
uc.server_ex = r->server;
uc.server_name = r->sname;
uc.req = &r->req;
uc.method_data = method_data;
ret = _krb5_plugin_run_f(r->context, &windc_plugin_data,
0, &uc, check);
0, r, check);
}
if (ret == KRB5_PLUGIN_NO_HANDLE)

View File

@@ -71,12 +71,7 @@ typedef krb5_error_code
krb5_pac *);
typedef krb5_error_code
(KRB5_CALLCONV *krb5plugin_windc_client_access)(
void *, krb5_context,
krb5_kdc_configuration *config,
hdb_entry_ex *, const char *,
hdb_entry_ex *, const char *,
KDC_REQ *, METHOD_DATA *);
(KRB5_CALLCONV *krb5plugin_windc_client_access)(void *, astgs_request_t);
typedef krb5_error_code
(KRB5_CALLCONV *krb5plugin_windc_finalize_reply)(void *, astgs_request_t r);

View File

@@ -95,15 +95,9 @@ pac_verify(void *ctx, krb5_context context,
}
static krb5_error_code KRB5_CALLCONV
client_access(void *ctx,
krb5_context context,
krb5_kdc_configuration *config,
hdb_entry_ex *client, const char *client_name,
hdb_entry_ex *server, const char *server_name,
KDC_REQ *req,
METHOD_DATA *data)
client_access(void *ctx, astgs_request_t r)
{
krb5_warnx(context, "client_access");
krb5_warnx(r->context, "client_access");
return 0;
}