|
Packit |
fd8b60 |
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
Packit |
fd8b60 |
/* kdc/tgs_policy.c */
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Copyright (C) 2012 by the Massachusetts Institute of Technology.
|
|
Packit |
fd8b60 |
* All rights reserved.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
fd8b60 |
* modification, are permitted provided that the following conditions
|
|
Packit |
fd8b60 |
* are met:
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* * Redistributions of source code must retain the above copyright
|
|
Packit |
fd8b60 |
* notice, this list of conditions and the following disclaimer.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* * Redistributions in binary form must reproduce the above copyright
|
|
Packit |
fd8b60 |
* notice, this list of conditions and the following disclaimer in
|
|
Packit |
fd8b60 |
* the documentation and/or other materials provided with the
|
|
Packit |
fd8b60 |
* distribution.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
fd8b60 |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
fd8b60 |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
Packit |
fd8b60 |
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
Packit |
fd8b60 |
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
Packit |
fd8b60 |
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
Packit |
fd8b60 |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
Packit |
fd8b60 |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
Packit |
fd8b60 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
Packit |
fd8b60 |
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
Packit |
fd8b60 |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
Packit |
fd8b60 |
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#include "k5-int.h"
|
|
Packit |
fd8b60 |
#include "kdc_util.h"
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Routines that validate a TGS request; checks a lot of things. :-)
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* Returns a Kerberos protocol error number, which is _not_ the same
|
|
Packit |
fd8b60 |
* as a com_err error number!
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
struct tgsflagrule {
|
|
Packit |
fd8b60 |
krb5_flags reqflags; /* Flag(s) in TGS-REQ */
|
|
Packit |
fd8b60 |
krb5_flags checkflag; /* Flags to check against */
|
|
Packit |
fd8b60 |
char *status; /* Status string */
|
|
Packit |
fd8b60 |
int err; /* Protocol error code */
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Service principal TGS policy checking functions */
|
|
Packit |
fd8b60 |
typedef int (check_tgs_svc_pol_fn)(krb5_kdc_req *, krb5_db_entry,
|
|
Packit |
fd8b60 |
krb5_ticket *, krb5_timestamp,
|
|
Packit |
fd8b60 |
const char **);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static check_tgs_svc_pol_fn check_tgs_svc_deny_opts;
|
|
Packit |
fd8b60 |
static check_tgs_svc_pol_fn check_tgs_svc_deny_all;
|
|
Packit |
fd8b60 |
static check_tgs_svc_pol_fn check_tgs_svc_reqd_flags;
|
|
Packit |
fd8b60 |
static check_tgs_svc_pol_fn check_tgs_svc_time;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static check_tgs_svc_pol_fn * const svc_pol_fns[] = {
|
|
Packit |
fd8b60 |
check_tgs_svc_deny_opts, check_tgs_svc_deny_all, check_tgs_svc_reqd_flags,
|
|
Packit |
fd8b60 |
check_tgs_svc_time
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static const struct tgsflagrule tgsflagrules[] = {
|
|
Packit |
fd8b60 |
{ KDC_OPT_FORWARDED, TKT_FLG_FORWARDABLE,
|
|
Packit |
fd8b60 |
"TGT NOT FORWARDABLE", KDC_ERR_BADOPTION },
|
|
Packit |
fd8b60 |
{ KDC_OPT_PROXY, TKT_FLG_PROXIABLE,
|
|
Packit |
fd8b60 |
"TGT NOT PROXIABLE", KDC_ERR_BADOPTION },
|
|
Packit |
fd8b60 |
{ (KDC_OPT_ALLOW_POSTDATE | KDC_OPT_POSTDATED), TKT_FLG_MAY_POSTDATE,
|
|
Packit |
fd8b60 |
"TGT NOT POSTDATABLE", KDC_ERR_BADOPTION },
|
|
Packit |
fd8b60 |
{ KDC_OPT_VALIDATE, TKT_FLG_INVALID,
|
|
Packit |
fd8b60 |
"VALIDATE VALID TICKET", KDC_ERR_BADOPTION },
|
|
Packit |
fd8b60 |
{ KDC_OPT_RENEW, TKT_FLG_RENEWABLE,
|
|
Packit |
fd8b60 |
"TICKET NOT RENEWABLE", KDC_ERR_BADOPTION }
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Some TGS-REQ options require that the ticket have corresponding flags set.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static int
|
|
Packit |
fd8b60 |
check_tgs_opts(krb5_kdc_req *req, krb5_ticket *tkt, const char **status)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
size_t i;
|
|
Packit |
fd8b60 |
size_t nrules = sizeof(tgsflagrules) / sizeof(tgsflagrules[0]);
|
|
Packit |
fd8b60 |
const struct tgsflagrule *r;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for (i = 0; i < nrules; i++) {
|
|
Packit |
fd8b60 |
r = &tgsflagrules[i];
|
|
Packit |
fd8b60 |
if (r->reqflags & req->kdc_options) {
|
|
Packit |
fd8b60 |
if (!(r->checkflag & tkt->enc_part2->flags)) {
|
|
Packit |
fd8b60 |
*status = r->status;
|
|
Packit |
fd8b60 |
return r->err;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static const struct tgsflagrule svcdenyrules[] = {
|
|
Packit |
fd8b60 |
{ KDC_OPT_RENEWABLE, KRB5_KDB_DISALLOW_RENEWABLE,
|
|
Packit |
fd8b60 |
"NON-RENEWABLE TICKET", KDC_ERR_POLICY },
|
|
Packit |
fd8b60 |
{ KDC_OPT_ALLOW_POSTDATE, KRB5_KDB_DISALLOW_POSTDATED,
|
|
Packit |
fd8b60 |
"NON-POSTDATABLE TICKET", KDC_ERR_CANNOT_POSTDATE },
|
|
Packit |
fd8b60 |
{ KDC_OPT_ENC_TKT_IN_SKEY, KRB5_KDB_DISALLOW_DUP_SKEY,
|
|
Packit |
fd8b60 |
"DUP_SKEY DISALLOWED", KDC_ERR_POLICY }
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* A service principal can forbid some TGS-REQ options.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static int
|
|
Packit |
fd8b60 |
check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry server,
|
|
Packit |
fd8b60 |
krb5_ticket *tkt, krb5_timestamp kdc_time,
|
|
Packit |
fd8b60 |
const char **status)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
size_t i;
|
|
Packit |
fd8b60 |
size_t nrules = sizeof(svcdenyrules) / sizeof(svcdenyrules[0]);
|
|
Packit |
fd8b60 |
const struct tgsflagrule *r;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for (i = 0; i < nrules; i++) {
|
|
Packit |
fd8b60 |
r = &svcdenyrules[i];
|
|
Packit |
fd8b60 |
if (!(r->reqflags & req->kdc_options))
|
|
Packit |
fd8b60 |
continue;
|
|
Packit |
fd8b60 |
if (r->checkflag & server.attributes) {
|
|
Packit |
fd8b60 |
*status = r->status;
|
|
Packit |
fd8b60 |
return r->err;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* A service principal can deny all TGS-REQs for it.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static int
|
|
Packit |
fd8b60 |
check_tgs_svc_deny_all(krb5_kdc_req *req, krb5_db_entry server,
|
|
Packit |
fd8b60 |
krb5_ticket *tkt, krb5_timestamp kdc_time,
|
|
Packit |
fd8b60 |
const char **status)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (server.attributes & KRB5_KDB_DISALLOW_ALL_TIX) {
|
|
Packit |
fd8b60 |
*status = "SERVER LOCKED OUT";
|
|
Packit |
fd8b60 |
return KDC_ERR_S_PRINCIPAL_UNKNOWN;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if ((server.attributes & KRB5_KDB_DISALLOW_SVR) &&
|
|
Packit |
fd8b60 |
!(req->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY)) {
|
|
Packit |
fd8b60 |
*status = "SERVER NOT ALLOWED";
|
|
Packit |
fd8b60 |
return KDC_ERR_MUST_USE_USER2USER;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (server.attributes & KRB5_KDB_DISALLOW_TGT_BASED) {
|
|
Packit |
fd8b60 |
if (krb5_is_tgs_principal(tkt->server)) {
|
|
Packit |
fd8b60 |
*status = "TGT BASED NOT ALLOWED";
|
|
Packit |
fd8b60 |
return KDC_ERR_POLICY;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* A service principal can require certain TGT flags.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static int
|
|
Packit |
fd8b60 |
check_tgs_svc_reqd_flags(krb5_kdc_req *req, krb5_db_entry server,
|
|
Packit |
fd8b60 |
krb5_ticket *tkt,
|
|
Packit |
fd8b60 |
krb5_timestamp kdc_time, const char **status)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (server.attributes & KRB5_KDB_REQUIRES_HW_AUTH) {
|
|
Packit |
fd8b60 |
if (!(tkt->enc_part2->flags & TKT_FLG_HW_AUTH)) {
|
|
Packit |
fd8b60 |
*status = "NO HW PREAUTH";
|
|
Packit |
fd8b60 |
return KRB_ERR_GENERIC;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (server.attributes & KRB5_KDB_REQUIRES_PRE_AUTH) {
|
|
Packit |
fd8b60 |
if (!(tkt->enc_part2->flags & TKT_FLG_PRE_AUTH)) {
|
|
Packit |
fd8b60 |
*status = "NO PREAUTH";
|
|
Packit |
fd8b60 |
return KRB_ERR_GENERIC;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static int
|
|
Packit |
fd8b60 |
check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt,
|
|
Packit |
fd8b60 |
krb5_timestamp kdc_time, const char **status)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (server.expiration && ts_after(kdc_time, server.expiration)) {
|
|
Packit |
fd8b60 |
*status = "SERVICE EXPIRED";
|
|
Packit |
fd8b60 |
return KDC_ERR_SERVICE_EXP;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static int
|
|
Packit |
fd8b60 |
check_tgs_svc_policy(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt,
|
|
Packit |
fd8b60 |
krb5_timestamp kdc_time, const char **status)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
int errcode;
|
|
Packit |
fd8b60 |
size_t i;
|
|
Packit |
fd8b60 |
size_t nfns = sizeof(svc_pol_fns) / sizeof(svc_pol_fns[0]);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for (i = 0; i < nfns; i++) {
|
|
Packit |
fd8b60 |
errcode = svc_pol_fns[i](req, server, tkt, kdc_time, status);
|
|
Packit |
fd8b60 |
if (errcode != 0)
|
|
Packit |
fd8b60 |
return errcode;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Check header ticket timestamps against the current time.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static int
|
|
Packit |
fd8b60 |
check_tgs_times(krb5_kdc_req *req, krb5_ticket_times *times,
|
|
Packit |
fd8b60 |
krb5_timestamp kdc_time, const char **status)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_timestamp starttime;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* For validating a postdated ticket, check the start time vs. the
|
|
Packit |
fd8b60 |
KDC time. */
|
|
Packit |
fd8b60 |
if (req->kdc_options & KDC_OPT_VALIDATE) {
|
|
Packit |
fd8b60 |
starttime = times->starttime ? times->starttime : times->authtime;
|
|
Packit |
fd8b60 |
if (ts_after(starttime, kdc_time)) {
|
|
Packit |
fd8b60 |
*status = "NOT_YET_VALID";
|
|
Packit |
fd8b60 |
return KRB_AP_ERR_TKT_NYV;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Check the renew_till time. The endtime was already
|
|
Packit |
fd8b60 |
* been checked in the initial authentication check.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
if ((req->kdc_options & KDC_OPT_RENEW) &&
|
|
Packit |
fd8b60 |
ts_after(kdc_time, times->renew_till)) {
|
|
Packit |
fd8b60 |
*status = "TKT_EXPIRED";
|
|
Packit |
fd8b60 |
return KRB_AP_ERR_TKT_EXPIRED;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static int
|
|
Packit |
fd8b60 |
check_tgs_s4u2proxy(kdc_realm_t *kdc_active_realm,
|
|
Packit |
fd8b60 |
krb5_kdc_req *req, const char **status)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (req->kdc_options & KDC_OPT_CNAME_IN_ADDL_TKT) {
|
|
Packit |
fd8b60 |
/* Check that second ticket is in request. */
|
|
Packit |
fd8b60 |
if (!req->second_ticket || !req->second_ticket[0]) {
|
|
Packit |
fd8b60 |
*status = "NO_2ND_TKT";
|
|
Packit |
fd8b60 |
return KDC_ERR_BADOPTION;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static int
|
|
Packit |
fd8b60 |
check_tgs_u2u(kdc_realm_t *kdc_active_realm,
|
|
Packit |
fd8b60 |
krb5_kdc_req *req, const char **status)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (req->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY) {
|
|
Packit |
fd8b60 |
/* Check that second ticket is in request. */
|
|
Packit |
fd8b60 |
if (!req->second_ticket || !req->second_ticket[0]) {
|
|
Packit |
fd8b60 |
*status = "NO_2ND_TKT";
|
|
Packit |
fd8b60 |
return KDC_ERR_BADOPTION;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/* Check that second ticket is a TGT. */
|
|
Packit |
fd8b60 |
if (!krb5_principal_compare(kdc_context,
|
|
Packit |
fd8b60 |
req->second_ticket[0]->server,
|
|
Packit |
fd8b60 |
tgs_server)) {
|
|
Packit |
fd8b60 |
*status = "2ND_TKT_NOT_TGS";
|
|
Packit |
fd8b60 |
return KDC_ERR_POLICY;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Some TGS-REQ options allow for a non-TGS principal in the ticket. Do some
|
|
Packit |
fd8b60 |
* checks that are peculiar to these cases. (e.g., ticket service principal
|
|
Packit |
fd8b60 |
* matches requested service principal)
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static int
|
|
Packit |
fd8b60 |
check_tgs_nontgt(kdc_realm_t *kdc_active_realm,
|
|
Packit |
fd8b60 |
krb5_kdc_req *req, krb5_ticket *tkt, const char **status)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (!krb5_principal_compare(kdc_context, tkt->server, req->server)) {
|
|
Packit |
fd8b60 |
*status = "SERVER DIDN'T MATCH TICKET FOR RENEW/FORWARD/ETC";
|
|
Packit |
fd8b60 |
return KDC_ERR_SERVER_NOMATCH;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/* Cannot proxy ticket granting tickets. */
|
|
Packit |
fd8b60 |
if ((req->kdc_options & KDC_OPT_PROXY) &&
|
|
Packit |
fd8b60 |
krb5_is_tgs_principal(req->server)) {
|
|
Packit |
fd8b60 |
*status = "CAN'T PROXY TGT";
|
|
Packit |
fd8b60 |
return KDC_ERR_BADOPTION;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Do some checks for a normal TGS-REQ (where the ticket service must be a TGS
|
|
Packit |
fd8b60 |
* principal).
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static int
|
|
Packit |
fd8b60 |
check_tgs_tgt(kdc_realm_t *kdc_active_realm, krb5_kdc_req *req,
|
|
Packit |
fd8b60 |
krb5_ticket *tkt, const char **status)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
/* Make sure it's a TGS principal. */
|
|
Packit |
fd8b60 |
if (!krb5_is_tgs_principal(tkt->server)) {
|
|
Packit |
fd8b60 |
*status = "BAD TGS SERVER NAME";
|
|
Packit |
fd8b60 |
return KRB_AP_ERR_NOT_US;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/* TGS principal second component must match service realm. */
|
|
Packit |
fd8b60 |
if (!data_eq(*krb5_princ_component(kdc_context, tkt->server, 1),
|
|
Packit |
fd8b60 |
*krb5_princ_realm(kdc_context, req->server))) {
|
|
Packit |
fd8b60 |
*status = "BAD TGS SERVER INSTANCE";
|
|
Packit |
fd8b60 |
return KRB_AP_ERR_NOT_US;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
int
|
|
Packit |
fd8b60 |
validate_tgs_request(kdc_realm_t *kdc_active_realm,
|
|
Packit |
fd8b60 |
krb5_kdc_req *request, krb5_db_entry server,
|
|
Packit |
fd8b60 |
krb5_ticket *ticket, krb5_timestamp kdc_time,
|
|
Packit |
fd8b60 |
const char **status, krb5_pa_data ***e_data)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
int errcode;
|
|
Packit |
fd8b60 |
krb5_error_code ret;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Depends only on request and ticket. */
|
|
Packit |
fd8b60 |
errcode = check_tgs_opts(request, ticket, status);
|
|
Packit |
fd8b60 |
if (errcode != 0)
|
|
Packit |
fd8b60 |
return errcode;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Depends only on request, ticket times, and current time. */
|
|
Packit |
fd8b60 |
errcode = check_tgs_times(request, &ticket->enc_part2->times, kdc_time,
|
|
Packit |
fd8b60 |
status);
|
|
Packit |
fd8b60 |
if (errcode != 0)
|
|
Packit |
fd8b60 |
return errcode;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
errcode = check_tgs_svc_policy(request, server, ticket, kdc_time, status);
|
|
Packit |
fd8b60 |
if (errcode != 0)
|
|
Packit |
fd8b60 |
return errcode;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (request->kdc_options & NON_TGT_OPTION)
|
|
Packit |
fd8b60 |
errcode = check_tgs_nontgt(kdc_active_realm, request, ticket, status);
|
|
Packit |
fd8b60 |
else
|
|
Packit |
fd8b60 |
errcode = check_tgs_tgt(kdc_active_realm, request, ticket, status);
|
|
Packit |
fd8b60 |
if (errcode != 0)
|
|
Packit |
fd8b60 |
return errcode;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Check the hot list */
|
|
Packit |
fd8b60 |
if (check_hot_list(ticket)) {
|
|
Packit |
fd8b60 |
*status = "HOT_LIST";
|
|
Packit |
fd8b60 |
return(KRB_AP_ERR_REPEAT);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
errcode = check_tgs_u2u(kdc_active_realm, request, status);
|
|
Packit |
fd8b60 |
if (errcode != 0)
|
|
Packit |
fd8b60 |
return errcode;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
errcode = check_tgs_s4u2proxy(kdc_active_realm, request, status);
|
|
Packit |
fd8b60 |
if (errcode != 0)
|
|
Packit |
fd8b60 |
return errcode;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (check_anon(kdc_active_realm, ticket->enc_part2->client,
|
|
Packit |
fd8b60 |
request->server) != 0) {
|
|
Packit |
fd8b60 |
*status = "ANONYMOUS NOT ALLOWED";
|
|
Packit |
fd8b60 |
return(KDC_ERR_POLICY);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Perform KDB module policy checks. */
|
|
Packit |
fd8b60 |
ret = krb5_db_check_policy_tgs(kdc_context, request, &server,
|
|
Packit |
fd8b60 |
ticket, status, e_data);
|
|
Packit |
fd8b60 |
if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP)
|
|
Packit |
fd8b60 |
return errcode_to_protocol(ret);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|