From dd8b146093d4bdf8a7d0c0eb8156b62d090448d7 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Wed, 30 Sep 2020 02:12:00 -0400 Subject: [PATCH] Avoid passing DB entry structures in KDC When validating AS or TGS requests, pass pointers to DB entry structures, not the structures themselves. (cherry picked from commit 7ccc08a889b40693b2ce7f108f2cdda51bc04bff) --- src/kdc/do_as_req.c | 4 ++-- src/kdc/do_tgs_req.c | 2 +- src/kdc/kdc_util.c | 34 +++++++++++++++++----------------- src/kdc/kdc_util.h | 6 +++--- src/kdc/tgs_policy.c | 35 ++++++++++++++++++----------------- 5 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c index 9ae7b0a5e..c2dfea9b8 100644 --- a/src/kdc/do_as_req.c +++ b/src/kdc/do_as_req.c @@ -663,8 +663,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt, au_state->stage = VALIDATE_POL; if ((errcode = validate_as_request(kdc_active_realm, - state->request, *state->client, - *state->server, state->kdc_time, + state->request, state->client, + state->server, state->kdc_time, &state->status, &state->e_data))) { errcode += ERROR_TABLE_BASE_krb5; goto errout; diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c index 74cd19e96..d345797c4 100644 --- a/src/kdc/do_tgs_req.c +++ b/src/kdc/do_tgs_req.c @@ -260,7 +260,7 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt, goto cleanup; if ((retval = validate_tgs_request(kdc_active_realm, - request, *server, header_ticket, + request, server, header_ticket, kdc_time, &status, &e_data))) { if (retval == KDC_ERR_POLICY || retval == KDC_ERR_BADOPTION) au_state->violation = PROT_CONSTRAINT; diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c index a4a05b9fa..b2042862a 100644 --- a/src/kdc/kdc_util.c +++ b/src/kdc/kdc_util.c @@ -612,8 +612,8 @@ check_anon(kdc_realm_t *kdc_active_realm, KDC_OPT_ENC_TKT_IN_SKEY | KDC_OPT_CNAME_IN_ADDL_TKT) int validate_as_request(kdc_realm_t *kdc_active_realm, - krb5_kdc_req *request, krb5_db_entry client, - krb5_db_entry server, krb5_timestamp kdc_time, + krb5_kdc_req *request, krb5_db_entry *client, + krb5_db_entry *server, krb5_timestamp kdc_time, const char **status, krb5_pa_data ***e_data) { krb5_error_code ret; @@ -627,7 +627,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm, } /* The client must not be expired */ - if (client.expiration && ts_after(kdc_time, client.expiration)) { + if (client->expiration && ts_after(kdc_time, client->expiration)) { *status = "CLIENT EXPIRED"; if (vague_errors) return(KRB_ERR_GENERIC); @@ -637,8 +637,8 @@ validate_as_request(kdc_realm_t *kdc_active_realm, /* The client's password must not be expired, unless the server is a KRB5_KDC_PWCHANGE_SERVICE. */ - if (client.pw_expiration && ts_after(kdc_time, client.pw_expiration) && - !isflagset(server.attributes, KRB5_KDB_PWCHANGE_SERVICE)) { + if (client->pw_expiration && ts_after(kdc_time, client->pw_expiration) && + !isflagset(server->attributes, KRB5_KDB_PWCHANGE_SERVICE)) { *status = "CLIENT KEY EXPIRED"; if (vague_errors) return(KRB_ERR_GENERIC); @@ -647,7 +647,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm, } /* The server must not be expired */ - if (server.expiration && ts_after(kdc_time, server.expiration)) { + if (server->expiration && ts_after(kdc_time, server->expiration)) { *status = "SERVICE EXPIRED"; return(KDC_ERR_SERVICE_EXP); } @@ -656,8 +656,8 @@ validate_as_request(kdc_realm_t *kdc_active_realm, * If the client requires password changing, then only allow the * pwchange service. */ - if (isflagset(client.attributes, KRB5_KDB_REQUIRES_PWCHANGE) && - !isflagset(server.attributes, KRB5_KDB_PWCHANGE_SERVICE)) { + if (isflagset(client->attributes, KRB5_KDB_REQUIRES_PWCHANGE) && + !isflagset(server->attributes, KRB5_KDB_PWCHANGE_SERVICE)) { *status = "REQUIRED PWCHANGE"; return(KDC_ERR_KEY_EXP); } @@ -665,37 +665,37 @@ validate_as_request(kdc_realm_t *kdc_active_realm, /* Client and server must allow postdating tickets */ if ((isflagset(request->kdc_options, KDC_OPT_ALLOW_POSTDATE) || isflagset(request->kdc_options, KDC_OPT_POSTDATED)) && - (isflagset(client.attributes, KRB5_KDB_DISALLOW_POSTDATED) || - isflagset(server.attributes, KRB5_KDB_DISALLOW_POSTDATED))) { + (isflagset(client->attributes, KRB5_KDB_DISALLOW_POSTDATED) || + isflagset(server->attributes, KRB5_KDB_DISALLOW_POSTDATED))) { *status = "POSTDATE NOT ALLOWED"; return(KDC_ERR_CANNOT_POSTDATE); } /* Check to see if client is locked out */ - if (isflagset(client.attributes, KRB5_KDB_DISALLOW_ALL_TIX)) { + if (isflagset(client->attributes, KRB5_KDB_DISALLOW_ALL_TIX)) { *status = "CLIENT LOCKED OUT"; return(KDC_ERR_CLIENT_REVOKED); } /* Check to see if server is locked out */ - if (isflagset(server.attributes, KRB5_KDB_DISALLOW_ALL_TIX)) { + if (isflagset(server->attributes, KRB5_KDB_DISALLOW_ALL_TIX)) { *status = "SERVICE LOCKED OUT"; return(KDC_ERR_S_PRINCIPAL_UNKNOWN); } /* Check to see if server is allowed to be a service */ - if (isflagset(server.attributes, KRB5_KDB_DISALLOW_SVR)) { + if (isflagset(server->attributes, KRB5_KDB_DISALLOW_SVR)) { *status = "SERVICE NOT ALLOWED"; return(KDC_ERR_MUST_USE_USER2USER); } - if (check_anon(kdc_active_realm, client.princ, request->server) != 0) { + if (check_anon(kdc_active_realm, client->princ, request->server) != 0) { *status = "ANONYMOUS NOT ALLOWED"; return(KDC_ERR_POLICY); } /* Perform KDB module policy checks. */ - ret = krb5_db_check_policy_as(kdc_context, request, &client, &server, + ret = krb5_db_check_policy_as(kdc_context, request, client, server, kdc_time, status, e_data); if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP) return errcode_to_protocol(ret); @@ -1568,8 +1568,8 @@ kdc_process_s4u2self_req(kdc_realm_t *kdc_active_realm, princ->pw_expiration = 0; clear(princ->attributes, KRB5_KDB_REQUIRES_PWCHANGE); - code = validate_as_request(kdc_active_realm, request, *princ, - no_server, kdc_time, status, &e_data); + code = validate_as_request(kdc_active_realm, request, princ, + &no_server, kdc_time, status, &e_data); if (code) { krb5_db_free_principal(kdc_context, princ); krb5_free_pa_data(kdc_context, e_data); diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h index 42b7ee208..04007a8f5 100644 --- a/src/kdc/kdc_util.h +++ b/src/kdc/kdc_util.h @@ -76,12 +76,12 @@ get_local_tgt(krb5_context context, const krb5_data *realm, krb5_db_entry **storage_out, krb5_keyblock *kb_out); int -validate_as_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry, - krb5_db_entry, krb5_timestamp, +validate_as_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry *, + krb5_db_entry *, krb5_timestamp, const char **, krb5_pa_data ***); int -validate_tgs_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry, +validate_tgs_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry *, krb5_ticket *, krb5_timestamp, const char **, krb5_pa_data ***); diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c index 554345ba5..3f4fa8499 100644 --- a/src/kdc/tgs_policy.c +++ b/src/kdc/tgs_policy.c @@ -48,7 +48,7 @@ struct tgsflagrule { }; /* Service principal TGS policy checking functions */ -typedef int (check_tgs_svc_pol_fn)(krb5_kdc_req *, krb5_db_entry, +typedef int (check_tgs_svc_pol_fn)(krb5_kdc_req *, krb5_db_entry *, krb5_ticket *, krb5_timestamp, const char **); @@ -110,7 +110,7 @@ static const struct tgsflagrule svcdenyrules[] = { * A service principal can forbid some TGS-REQ options. */ static int -check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry server, +check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry *server, krb5_ticket *tkt, krb5_timestamp kdc_time, const char **status) { @@ -122,7 +122,7 @@ check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry server, r = &svcdenyrules[i]; if (!(r->reqflags & req->kdc_options)) continue; - if (r->checkflag & server.attributes) { + if (r->checkflag & server->attributes) { *status = r->status; return r->err; } @@ -134,20 +134,20 @@ check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry server, * A service principal can deny all TGS-REQs for it. */ static int -check_tgs_svc_deny_all(krb5_kdc_req *req, krb5_db_entry server, +check_tgs_svc_deny_all(krb5_kdc_req *req, krb5_db_entry *server, krb5_ticket *tkt, krb5_timestamp kdc_time, const char **status) { - if (server.attributes & KRB5_KDB_DISALLOW_ALL_TIX) { + if (server->attributes & KRB5_KDB_DISALLOW_ALL_TIX) { *status = "SERVER LOCKED OUT"; return KDC_ERR_S_PRINCIPAL_UNKNOWN; } - if ((server.attributes & KRB5_KDB_DISALLOW_SVR) && + if ((server->attributes & KRB5_KDB_DISALLOW_SVR) && !(req->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY)) { *status = "SERVER NOT ALLOWED"; return KDC_ERR_MUST_USE_USER2USER; } - if (server.attributes & KRB5_KDB_DISALLOW_TGT_BASED) { + if (server->attributes & KRB5_KDB_DISALLOW_TGT_BASED) { if (krb5_is_tgs_principal(tkt->server)) { *status = "TGT BASED NOT ALLOWED"; return KDC_ERR_POLICY; @@ -160,17 +160,17 @@ check_tgs_svc_deny_all(krb5_kdc_req *req, krb5_db_entry server, * A service principal can require certain TGT flags. */ static int -check_tgs_svc_reqd_flags(krb5_kdc_req *req, krb5_db_entry server, +check_tgs_svc_reqd_flags(krb5_kdc_req *req, krb5_db_entry *server, krb5_ticket *tkt, krb5_timestamp kdc_time, const char **status) { - if (server.attributes & KRB5_KDB_REQUIRES_HW_AUTH) { + if (server->attributes & KRB5_KDB_REQUIRES_HW_AUTH) { if (!(tkt->enc_part2->flags & TKT_FLG_HW_AUTH)) { *status = "NO HW PREAUTH"; return KRB_ERR_GENERIC; } } - if (server.attributes & KRB5_KDB_REQUIRES_PRE_AUTH) { + if (server->attributes & KRB5_KDB_REQUIRES_PRE_AUTH) { if (!(tkt->enc_part2->flags & TKT_FLG_PRE_AUTH)) { *status = "NO PREAUTH"; return KRB_ERR_GENERIC; @@ -180,10 +180,10 @@ check_tgs_svc_reqd_flags(krb5_kdc_req *req, krb5_db_entry server, } static int -check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt, +check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry *server, krb5_ticket *tkt, krb5_timestamp kdc_time, const char **status) { - if (server.expiration && ts_after(kdc_time, server.expiration)) { + if (server->expiration && ts_after(kdc_time, server->expiration)) { *status = "SERVICE EXPIRED"; return KDC_ERR_SERVICE_EXP; } @@ -191,8 +191,9 @@ check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt, } static int -check_tgs_svc_policy(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt, - krb5_timestamp kdc_time, const char **status) +check_tgs_svc_policy(krb5_kdc_req *req, krb5_db_entry *server, + krb5_ticket *tkt, krb5_timestamp kdc_time, + const char **status) { int errcode; size_t i; @@ -317,7 +318,7 @@ check_tgs_tgt(kdc_realm_t *kdc_active_realm, krb5_kdc_req *req, int validate_tgs_request(kdc_realm_t *kdc_active_realm, - krb5_kdc_req *request, krb5_db_entry server, + krb5_kdc_req *request, krb5_db_entry *server, krb5_ticket *ticket, krb5_timestamp kdc_time, const char **status, krb5_pa_data ***e_data) { @@ -367,8 +368,8 @@ validate_tgs_request(kdc_realm_t *kdc_active_realm, } /* Perform KDB module policy checks. */ - ret = krb5_db_check_policy_tgs(kdc_context, request, &server, - ticket, status, e_data); + ret = krb5_db_check_policy_tgs(kdc_context, request, server, ticket, + status, e_data); if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP) return errcode_to_protocol(ret);