Skip to content

Commit

Permalink
Avoid passing DB entry structures in KDC
Browse files Browse the repository at this point in the history
When validating AS or TGS requests, pass pointers to DB entry
structures, not the structures themselves.
  • Loading branch information
greghudson committed Sep 30, 2020
1 parent 2812109 commit 7ccc08a
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 40 deletions.
4 changes: 2 additions & 2 deletions src/kdc/do_as_req.c
Original file line number Diff line number Diff line change
Expand Up @@ -644,8 +644,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;
Expand Down
2 changes: 1 addition & 1 deletion src/kdc/do_tgs_req.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,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;
Expand Down
34 changes: 17 additions & 17 deletions src/kdc/kdc_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,8 +623,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;
Expand All @@ -638,7 +638,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);
Expand All @@ -648,8 +648,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);
Expand All @@ -658,7 +658,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);
}
Expand All @@ -667,46 +667,46 @@ 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);
}

/* 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);
Expand Down Expand Up @@ -1580,8 +1580,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);
Expand Down
6 changes: 3 additions & 3 deletions src/kdc/kdc_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,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 ***);

Expand Down
35 changes: 18 additions & 17 deletions src/kdc/tgs_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 **);

Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
}
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -180,19 +180,20 @@ 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;
}
return 0;
}

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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit 7ccc08a

Please sign in to comment.