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 { struct astgs_request_desc {
ASTGS_REQUEST_DESC_COMMON_ELEMENTS; ASTGS_REQUEST_DESC_COMMON_ELEMENTS;
/* Only AS */
METHOD_DATA outpadata; METHOD_DATA outpadata;
/* Only AS */
const struct kdc_patypes *pa_used; const struct kdc_patypes *pa_used;
struct as_request_pa_state *pa_state; struct as_request_pa_state *pa_state;

View File

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

View File

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

View File

@@ -184,48 +184,24 @@ _kdc_pac_verify(krb5_context context,
0, &uc, verify); 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 static krb5_error_code KRB5_LIB_CALL
check(krb5_context context, const void *plug, void *plugctx, void *userctx) check(krb5_context context, const void *plug, void *plugctx, void *userctx)
{ {
krb5plugin_windc_ftable *ft = (krb5plugin_windc_ftable *)plug; krb5plugin_windc_ftable *ft = (krb5plugin_windc_ftable *)plug;
struct check_uc *uc = (struct check_uc *)userctx;
if (ft->client_access == NULL) if (ft->client_access == NULL)
return KRB5_PLUGIN_NO_HANDLE; return KRB5_PLUGIN_NO_HANDLE;
return ft->client_access((void *)plug, context, uc->config, return ft->client_access((void *)plug, userctx);
uc->client_ex, uc->client_name,
uc->server_ex, uc->server_name,
uc->req, uc->method_data);
} }
krb5_error_code 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; krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE;
struct check_uc uc;
if (have_plugin) { 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, ret = _krb5_plugin_run_f(r->context, &windc_plugin_data,
0, &uc, check); 0, r, check);
} }
if (ret == KRB5_PLUGIN_NO_HANDLE) if (ret == KRB5_PLUGIN_NO_HANDLE)

View File

@@ -71,12 +71,7 @@ typedef krb5_error_code
krb5_pac *); krb5_pac *);
typedef krb5_error_code typedef krb5_error_code
(KRB5_CALLCONV *krb5plugin_windc_client_access)( (KRB5_CALLCONV *krb5plugin_windc_client_access)(void *, astgs_request_t);
void *, krb5_context,
krb5_kdc_configuration *config,
hdb_entry_ex *, const char *,
hdb_entry_ex *, const char *,
KDC_REQ *, METHOD_DATA *);
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);

View File

@@ -95,15 +95,9 @@ pac_verify(void *ctx, krb5_context context,
} }
static krb5_error_code KRB5_CALLCONV static krb5_error_code KRB5_CALLCONV
client_access(void *ctx, client_access(void *ctx, astgs_request_t r)
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)
{ {
krb5_warnx(context, "client_access"); krb5_warnx(r->context, "client_access");
return 0; return 0;
} }