krb5/Avoid-passing-DB-entry-stru...

299 lines
13 KiB
Diff

From dd8b146093d4bdf8a7d0c0eb8156b62d090448d7 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
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);