#include "adm_proto.h"
static void find_alternate_tgs (krb5_kdc_req *, krb5_db_entry *,
- krb5_boolean *, int *);
+ krb5_boolean *, int *);
static krb5_error_code prepare_error_tgs (krb5_kdc_req *, krb5_ticket *,
- int, krb5_principal,
- krb5_data **, const char *);
+ int, krb5_principal,
+ krb5_data **, const char *);
-static krb5_boolean
+static krb5_int32
is_substr ( char *, krb5_data *);
/*ARGSUSED*/
krb5_error_code
process_tgs_req(krb5_data *pkt, const krb5_fulladdr *from,
- krb5_data **response)
+krb5_data **response)
{
krb5_keyblock * subkey = 0;
krb5_kdc_req *request = 0;
char *cname = 0, *sname = 0, *altcname = 0;
krb5_last_req_entry *nolrarray[2], nolrentry;
krb5_enctype useenctype;
- int errcode, errcode2;
+ int errcode, errcode2;
register int i;
size_t len;
int firstpass = 1;
- const char *status = 0;
+ const char *status = 0;
krb5_enc_tkt_part *header_enc_tkt = NULL; /* ticket granting or evidence ticket */
krb5_db_entry client, krbtgt;
int c_nprincs = 0, k_nprincs = 0;
- krb5_pa_for_user *for_user = NULL; /* protocol transition request */
- krb5_authdata **kdc_issued_auth_data = NULL; /* auth data issued by KDC */
- unsigned int c_flags = 0, s_flags = 0; /* client/server KDB flags */
+ krb5_pa_for_user *for_user = NULL; /* protocol transition request */
+ krb5_authdata **kdc_issued_auth_data = NULL; /* auth data issued by KDC */
+ unsigned int c_flags = 0, s_flags = 0; /* client/server KDB flags */
char *s4u_name = NULL;
krb5_boolean is_referral, db_ref_done = FALSE;
const char *emsg = NULL;
krb5_data *comp1 = NULL, *comp2 = NULL;
krb5_data *tgs_1 =NULL, *server_1 = NULL;
krb5_principal krbtgt_princ;
+ krb5_int32 host_based_srv_listed, no_host_referral_listed;
session_key.contents = NULL;
retval = decode_krb5_tgs_req(pkt, &request);
if (retval)
- return retval;
+ return retval;
/*
* setup_server_realm() sets up the global realm-specific data pointer.
*/
if ((retval = setup_server_realm(request->server))) {
- krb5_free_kdc_req(kdc_context, request);
- return retval;
+ krb5_free_kdc_req(kdc_context, request);
+ return retval;
}
errcode = kdc_process_tgs_req(request, from, pkt, &header_ticket,
- &krbtgt, &k_nprincs, &subkey);
+ &krbtgt, &k_nprincs, &subkey);
if (header_ticket && header_ticket->enc_part2 &&
- (errcode2 = krb5_unparse_name(kdc_context,
- header_ticket->enc_part2->client,
- &cname))) {
- status = "UNPARSING CLIENT";
- errcode = errcode2;
- goto cleanup;
+ (errcode2 = krb5_unparse_name(kdc_context,
+ header_ticket->enc_part2->client,
+ &cname))) {
+ status = "UNPARSING CLIENT";
+ errcode = errcode2;
+ goto cleanup;
}
limit_string(cname);
if (errcode) {
- status = "PROCESS_TGS";
- goto cleanup;
+ status = "PROCESS_TGS";
+ goto cleanup;
}
if (!header_ticket) {
- errcode = KRB5_NO_TKT_SUPPLIED; /* XXX? */
- status="UNEXPECTED NULL in header_ticket";
- goto cleanup;
+ errcode = KRB5_NO_TKT_SUPPLIED; /* XXX? */
+ status="UNEXPECTED NULL in header_ticket";
+ goto cleanup;
}
/*
header? */
if (isflagset(request->kdc_options, KDC_OPT_CANONICALIZE)) {
- setflag(c_flags, KRB5_KDB_FLAG_CANONICALIZE);
- setflag(s_flags, KRB5_KDB_FLAG_CANONICALIZE);
+ setflag(c_flags, KRB5_KDB_FLAG_CANONICALIZE);
+ setflag(s_flags, KRB5_KDB_FLAG_CANONICALIZE);
}
db_ref_done = FALSE;
ref_tgt_again:
nprincs = 1;
if ((errcode = krb5_unparse_name(kdc_context, request->server, &sname))) {
- status = "UNPARSING SERVER";
- goto cleanup;
+ status = "UNPARSING SERVER";
+ goto cleanup;
}
limit_string(sname);
errcode = krb5_db_get_principal_ext(kdc_context,
- request->server,
- s_flags,
- &server,
- &nprincs,
- &more);
+ request->server,
+ s_flags,
+ &server,
+ &nprincs,
+ &more);
if (errcode) {
- status = "LOOKING_UP_SERVER";
- nprincs = 0;
- goto cleanup;
+ status = "LOOKING_UP_SERVER";
+ nprincs = 0;
+ goto cleanup;
}
tgt_again:
if (more) {
- status = "NON_UNIQUE_PRINCIPAL";
- errcode = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE;
- goto cleanup;
+ status = "NON_UNIQUE_PRINCIPAL";
+ errcode = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE;
+ goto cleanup;
} else if (nprincs != 1) {
- /*
- * might be a request for a TGT for some other realm; we
- * should do our best to find such a TGS in this db
- */
+ /*
+ * might be a request for a TGT for some other realm; we
+ * should do our best to find such a TGS in this db
+ */
if (firstpass ) {
if ( krb5_is_tgs_principal(request->server) == TRUE) { /* Principal is a name of krb ticket service */
} else if ( db_ref_done == FALSE) {
/* By now we know that server principal name is unknown <== nprincs!=1 from get_principal
- * If CANONICALIZE flag is set in the request (1)
- * If req is not U2U authn. req (2)
- * the requested server princ. has exactly two components (3)
+ * If CANONICALIZE flag is set in the request
+ * If req is not U2U authn. req
+ * the requested server princ. has exactly two components
* either
- * the name type is NT-SRV-HST (4.a)
+ * the name type is NT-SRV-HST
* or name type is NT-UNKNOWN and
- * the 1st component is listed in conf file under host_based_services (4.b)
- * the 1st component is not in a list in conf under "no_host_referral" (5)
- * the 2d component looks like fully-qualified domain name (FQDN) (6)
+ * the 1st component is listed in conf file under host_based_services
+ * the 1st component is not in a list in conf under "no_host_referral"
+ * the 2d component looks like fully-qualified domain name (FQDN)
* If all of these conditions are satisfied - try mapping the FQDN and
* re-process the request as if client had asked for cross-realm TGT.
*/
- if (isflagset(request->kdc_options, KDC_OPT_CANONICALIZE) == TRUE && /* (1) */
- !isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY) && /* (2) */
- krb5_princ_size(kdc_context, request->server) == 2) { /* (3) */
+ if (isflagset(request->kdc_options, KDC_OPT_CANONICALIZE) == TRUE &&
+ !isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY) &&
+ krb5_princ_size(kdc_context, request->server) == 2) {
comp1 = krb5_princ_component(kdc_context, request->server, 0);
comp2 = krb5_princ_component(kdc_context, request->server, 1);
- if ((krb5_princ_type(kdc_context, request->server) == KRB5_NT_SRV_HST || /* (4.a) */
- (krb5_princ_type(kdc_context, request->server) == KRB5_NT_UNKNOWN && /* (4.b) */
- (is_substr(kdc_active_realm->realm_host_based_services, comp1)==TRUE ||
- strchr(kdc_active_realm->realm_host_based_services, '*')))) &&
- (kdc_active_realm->realm_no_host_referral == NULL ||
- (!strchr(kdc_active_realm->realm_host_based_services, '*') &&
- is_substr(kdc_active_realm->realm_no_host_referral,comp1)==FALSE))) { /* (5) */
-
- for ( len=0; len < comp2->length; len++) {
- if ( comp2->data[len] == '.' ) break;
+ host_based_srv_listed = FALSE;
+ no_host_referral_listed = TRUE;
+ if (kdc_active_realm->realm_host_based_services != NULL) {
+ host_based_srv_listed =
+ is_substr(kdc_active_realm->realm_host_based_services, comp1);
+ if (host_based_srv_listed == ENOMEM) {
+ retval = ENOMEM;
+ goto cleanup;
}
- if ( len == comp2->length) /* (6) */
+ }
+ if (kdc_active_realm->realm_no_host_referral != NULL) {
+ no_host_referral_listed =
+ is_substr(kdc_active_realm->realm_no_host_referral,comp1);
+ if (no_host_referral_listed == ENOMEM) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ }
+
+ if ((krb5_princ_type(kdc_context, request->server) == KRB5_NT_SRV_HST ||
+ (krb5_princ_type(kdc_context, request->server) == KRB5_NT_UNKNOWN &&
+ kdc_active_realm->realm_host_based_services != NULL &&
+ (host_based_srv_listed == TRUE ||
+ strchr(kdc_active_realm->realm_host_based_services, '*')))) &&
+ (kdc_active_realm->realm_no_host_referral == NULL ||
+ (!strchr(kdc_active_realm->realm_host_based_services, '*') &&
+ no_host_referral_listed == FALSE))) {
+
+ for (len=0; len < comp2->length; len++) {
+ if (comp2->data[len] == '.') break;
+ }
+ if (len == comp2->length)
goto cleanup;
- /* try mapping FQDN or the containing domains */
temp_buf = calloc(1, comp2->length+1);
- if ( !temp_buf){
+ if (!temp_buf){
retval = ENOMEM;
goto cleanup;
}
(*request->server).realm.data,
"krbtgt", realms[0], (char *)0);
- for (cpp = realms; *cpp; cpp++) free(*cpp);
+ for (cpp = realms; *cpp; cpp++) free(*cpp);
krb5_free_principal(kdc_context, request->server);
retval = krb5_copy_principal(kdc_context, krbtgt_princ, &(request->server));
- if ( retval == 0 ) {
+ if (retval == 0) {
db_ref_done = TRUE;
+ if (sname != NULL) free(sname);
goto ref_tgt_again;
}
}
}
}
-
- krb5_db_free_principal(kdc_context, &server, nprincs);
- status = "UNKNOWN_SERVER";
- errcode = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
- goto cleanup;
+ krb5_db_free_principal(kdc_context, &server, nprincs);
+ status = "UNKNOWN_SERVER";
+ errcode = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
+ goto cleanup;
}
if ((errcode = krb5_timeofday(kdc_context, &kdc_time))) {
- status = "TIME_OF_DAY";
- goto cleanup;
+ status = "TIME_OF_DAY";
+ goto cleanup;
}
if ((retval = validate_tgs_request(request, server, header_ticket,
- kdc_time, &status))) {
- if (!status)
- status = "UNKNOWN_REASON";
- errcode = retval + ERROR_TABLE_BASE_krb5;
- goto cleanup;
+ kdc_time, &status))) {
+ if (!status)
+ status = "UNKNOWN_REASON";
+ errcode = retval + ERROR_TABLE_BASE_krb5;
+ goto cleanup;
}
if (!is_local_principal(header_enc_tkt->client))
- setflag(c_flags, KRB5_KDB_FLAG_CROSS_REALM);
+ setflag(c_flags, KRB5_KDB_FLAG_CROSS_REALM);
is_referral = krb5_is_tgs_principal(server.princ) &&
- !krb5_principal_compare(kdc_context, tgs_server, server.princ);
+ !krb5_principal_compare(kdc_context, tgs_server, server.princ);
/* Check for protocol transition */
errcode = kdc_process_s4u2self_req(kdc_context, request, header_enc_tkt->client,
- &server, header_enc_tkt->session, kdc_time,
- &for_user, &client, &c_nprincs, &status);
+ &server, header_enc_tkt->session, kdc_time,
+ &for_user, &client, &c_nprincs, &status);
if (errcode)
- goto cleanup;
+ goto cleanup;
if (for_user != NULL)
- setflag(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION);
+ setflag(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION);
/*
* We pick the session keytype here....
*/
useenctype = 0;
if (isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY |
- KDC_OPT_CNAME_IN_ADDL_TKT)) {
- krb5_keyblock * st_sealing_key;
- krb5_kvno st_srv_kvno;
- krb5_enctype etype;
- krb5_db_entry st_client;
- int st_nprincs = 0;
-
- /*
- * Get the key for the second ticket, and decrypt it.
- */
- if ((errcode = kdc_get_server_key(request->second_ticket[st_idx],
- c_flags,
- TRUE, /* match_enctype */
- &st_client,
- &st_nprincs,
- &st_sealing_key,
- &st_srv_kvno))) {
- status = "2ND_TKT_SERVER";
- goto cleanup;
- }
- errcode = krb5_decrypt_tkt_part(kdc_context, st_sealing_key,
- request->second_ticket[st_idx]);
- krb5_free_keyblock(kdc_context, st_sealing_key);
- if (errcode) {
- status = "2ND_TKT_DECRYPT";
- krb5_db_free_principal(kdc_context, &st_client, st_nprincs);
- goto cleanup;
- }
-
- etype = request->second_ticket[st_idx]->enc_part2->session->enctype;
- if (!krb5_c_valid_enctype(etype)) {
- status = "BAD_ETYPE_IN_2ND_TKT";
- errcode = KRB5KDC_ERR_ETYPE_NOSUPP;
- krb5_db_free_principal(kdc_context, &st_client, st_nprincs);
- goto cleanup;
- }
-
- for (i = 0; i < request->nktypes; i++) {
- if (request->ktype[i] == etype) {
- useenctype = etype;
- break;
- }
- }
-
- if (isflagset(request->kdc_options, KDC_OPT_CNAME_IN_ADDL_TKT)) {
- /* Do constrained delegation protocol and authorization checks */
- errcode = kdc_process_s4u2proxy_req(kdc_context,
- request,
- request->second_ticket[st_idx]->enc_part2,
- &st_client,
- header_ticket->enc_part2->client,
- request->server,
- &status);
- if (errcode)
- goto cleanup;
-
- setflag(c_flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION);
-
- assert(krb5_is_tgs_principal(header_ticket->server));
-
- /* From now on, use evidence ticket as header ticket */
- header_enc_tkt = request->second_ticket[st_idx]->enc_part2;
-
- assert(c_nprincs == 0); /* assured by kdc_process_s4u2self_req() */
-
- client = st_client;
- c_nprincs = st_nprincs;
- } else {
- /* "client" is not used for user2user */
- krb5_db_free_principal(kdc_context, &st_client, st_nprincs);
- }
+ KDC_OPT_CNAME_IN_ADDL_TKT)) {
+ krb5_keyblock * st_sealing_key;
+ krb5_kvno st_srv_kvno;
+ krb5_enctype etype;
+ krb5_db_entry st_client;
+ int st_nprincs = 0;
+
+ /*
+ * Get the key for the second ticket, and decrypt it.
+ */
+ if ((errcode = kdc_get_server_key(request->second_ticket[st_idx],
+ c_flags,
+ TRUE, /* match_enctype */
+ &st_client,
+ &st_nprincs,
+ &st_sealing_key,
+ &st_srv_kvno))) {
+ status = "2ND_TKT_SERVER";
+ goto cleanup;
+ }
+ errcode = krb5_decrypt_tkt_part(kdc_context, st_sealing_key,
+ request->second_ticket[st_idx]);
+ krb5_free_keyblock(kdc_context, st_sealing_key);
+ if (errcode) {
+ status = "2ND_TKT_DECRYPT";
+ krb5_db_free_principal(kdc_context, &st_client, st_nprincs);
+ goto cleanup;
+ }
+
+ etype = request->second_ticket[st_idx]->enc_part2->session->enctype;
+ if (!krb5_c_valid_enctype(etype)) {
+ status = "BAD_ETYPE_IN_2ND_TKT";
+ errcode = KRB5KDC_ERR_ETYPE_NOSUPP;
+ krb5_db_free_principal(kdc_context, &st_client, st_nprincs);
+ goto cleanup;
+ }
+
+ for (i = 0; i < request->nktypes; i++) {
+ if (request->ktype[i] == etype) {
+ useenctype = etype;
+ break;
+ }
+ }
+
+ if (isflagset(request->kdc_options, KDC_OPT_CNAME_IN_ADDL_TKT)) {
+ /* Do constrained delegation protocol and authorization checks */
+ errcode = kdc_process_s4u2proxy_req(kdc_context,
+ request,
+ request->second_ticket[st_idx]->enc_part2,
+ &st_client,
+ header_ticket->enc_part2->client,
+ request->server,
+ &status);
+ if (errcode)
+ goto cleanup;
+
+ setflag(c_flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION);
+
+ assert(krb5_is_tgs_principal(header_ticket->server));
+
+ /* From now on, use evidence ticket as header ticket */
+ header_enc_tkt = request->second_ticket[st_idx]->enc_part2;
+
+ assert(c_nprincs == 0); /* assured by kdc_process_s4u2self_req() */
+
+ client = st_client;
+ c_nprincs = st_nprincs;
+ } else {
+ /* "client" is not used for user2user */
+ krb5_db_free_principal(kdc_context, &st_client, st_nprincs);
+ }
}
/*
* Select the keytype for the ticket session key.
*/
if ((useenctype == 0) &&
- (useenctype = select_session_keytype(kdc_context, &server,
- request->nktypes,
- request->ktype)) == 0) {
- /* unsupported ktype */
- status = "BAD_ENCRYPTION_TYPE";
- errcode = KRB5KDC_ERR_ETYPE_NOSUPP;
- goto cleanup;
+ (useenctype = select_session_keytype(kdc_context, &server,
+ request->nktypes,
+ request->ktype)) == 0) {
+ /* unsupported ktype */
+ status = "BAD_ENCRYPTION_TYPE";
+ errcode = KRB5KDC_ERR_ETYPE_NOSUPP;
+ goto cleanup;
}
errcode = krb5_c_make_random_key(kdc_context, useenctype, &session_key);
if (errcode) {
- /* random key failed */
- status = "RANDOM_KEY_FAILED";
- goto cleanup;
+ /* random key failed */
+ status = "RANDOM_KEY_FAILED";
+ goto cleanup;
}
authtime = header_enc_tkt->times.authtime;
if (is_referral)
- ticket_reply.server = server.princ;
+ ticket_reply.server = server.princ;
else
- ticket_reply.server = request->server; /* XXX careful for realm... */
+ ticket_reply.server = request->server; /* XXX careful for realm... */
enc_tkt_reply.flags = 0;
enc_tkt_reply.times.starttime = 0;
if (isflagset(server.attributes, KRB5_KDB_OK_AS_DELEGATE) &&
- !is_referral) {
- /* Ensure that we are not returning a referral */
- setflag(enc_tkt_reply.flags, TKT_FLG_OK_AS_DELEGATE);
+ !is_referral) {
+ /* Ensure that we are not returning a referral */
+ setflag(enc_tkt_reply.flags, TKT_FLG_OK_AS_DELEGATE);
}
/*
* authtime's value.
*/
if (!(header_enc_tkt->times.starttime))
- header_enc_tkt->times.starttime = header_enc_tkt->times.authtime;
+ header_enc_tkt->times.starttime = header_enc_tkt->times.authtime;
/* don't use new addresses unless forwarded, see below */
enc_tkt_reply.caddrs = header_enc_tkt->caddrs;
/* noaddrarray[0] = 0; */
- reply_encpart.caddrs = 0; /* optional...don't put it in */
+ reply_encpart.caddrs = 0;/* optional...don't put it in */
reply_encpart.enc_padata = NULL;
/* It should be noted that local policy may affect the */
/* realms may refuse to issue renewable tickets */
if (isflagset(request->kdc_options, KDC_OPT_FORWARDABLE))
- setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
+ setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION)) {
- if (!krb5_is_tgs_principal(server.princ) &&
- is_local_principal(server.princ)) {
- if (isflagset(server.attributes, KRB5_KDB_OK_TO_AUTH_AS_DELEGATE))
- setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
- else
- clear(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
- }
- if (isflagset(client.attributes, KRB5_KDB_DISALLOW_FORWARDABLE))
- clear(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
+ if (!krb5_is_tgs_principal(server.princ) &&
+ is_local_principal(server.princ)) {
+ if (isflagset(server.attributes, KRB5_KDB_OK_TO_AUTH_AS_DELEGATE))
+ setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
+ else
+ clear(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
+ }
+ if (isflagset(client.attributes, KRB5_KDB_DISALLOW_FORWARDABLE))
+ clear(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
}
if (isflagset(request->kdc_options, KDC_OPT_FORWARDED)) {
- setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDED);
+ setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDED);
- /* include new addresses in ticket & reply */
+ /* include new addresses in ticket & reply */
- enc_tkt_reply.caddrs = request->addresses;
- reply_encpart.caddrs = request->addresses;
- }
+ enc_tkt_reply.caddrs = request->addresses;
+ reply_encpart.caddrs = request->addresses;
+ }
if (isflagset(header_enc_tkt->flags, TKT_FLG_FORWARDED))
- setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDED);
+ setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDED);
if (isflagset(request->kdc_options, KDC_OPT_PROXIABLE))
- setflag(enc_tkt_reply.flags, TKT_FLG_PROXIABLE);
+ setflag(enc_tkt_reply.flags, TKT_FLG_PROXIABLE);
if (isflagset(request->kdc_options, KDC_OPT_PROXY)) {
- setflag(enc_tkt_reply.flags, TKT_FLG_PROXY);
+ setflag(enc_tkt_reply.flags, TKT_FLG_PROXY);
- /* include new addresses in ticket & reply */
+ /* include new addresses in ticket & reply */
- enc_tkt_reply.caddrs = request->addresses;
- reply_encpart.caddrs = request->addresses;
+ enc_tkt_reply.caddrs = request->addresses;
+ reply_encpart.caddrs = request->addresses;
}
if (isflagset(request->kdc_options, KDC_OPT_ALLOW_POSTDATE))
- setflag(enc_tkt_reply.flags, TKT_FLG_MAY_POSTDATE);
+ setflag(enc_tkt_reply.flags, TKT_FLG_MAY_POSTDATE);
if (isflagset(request->kdc_options, KDC_OPT_POSTDATED)) {
- setflag(enc_tkt_reply.flags, TKT_FLG_POSTDATED);
- setflag(enc_tkt_reply.flags, TKT_FLG_INVALID);
- enc_tkt_reply.times.starttime = request->from;
+ setflag(enc_tkt_reply.flags, TKT_FLG_POSTDATED);
+ setflag(enc_tkt_reply.flags, TKT_FLG_INVALID);
+ enc_tkt_reply.times.starttime = request->from;
} else
- enc_tkt_reply.times.starttime = kdc_time;
+ enc_tkt_reply.times.starttime = kdc_time;
if (isflagset(request->kdc_options, KDC_OPT_VALIDATE)) {
- assert(isflagset(c_flags, KRB5_KDB_FLAGS_S4U) == 0);
- /* BEWARE of allocation hanging off of ticket & enc_part2, it belongs
- to the caller */
- ticket_reply = *(header_ticket);
- enc_tkt_reply = *(header_ticket->enc_part2);
- clear(enc_tkt_reply.flags, TKT_FLG_INVALID);
+ assert(isflagset(c_flags, KRB5_KDB_FLAGS_S4U) == 0);
+ /* BEWARE of allocation hanging off of ticket & enc_part2, it belongs
+ to the caller */
+ ticket_reply = *(header_ticket);
+ enc_tkt_reply = *(header_ticket->enc_part2);
+ clear(enc_tkt_reply.flags, TKT_FLG_INVALID);
}
if (isflagset(request->kdc_options, KDC_OPT_RENEW)) {
- krb5_deltat old_life;
+ krb5_deltat old_life;
- assert(isflagset(c_flags, KRB5_KDB_FLAGS_S4U) == 0);
- /* BEWARE of allocation hanging off of ticket & enc_part2, it belongs
- to the caller */
- ticket_reply = *(header_ticket);
- enc_tkt_reply = *(header_ticket->enc_part2);
+ assert(isflagset(c_flags, KRB5_KDB_FLAGS_S4U) == 0);
+ /* BEWARE of allocation hanging off of ticket & enc_part2, it belongs
+ to the caller */
+ ticket_reply = *(header_ticket);
+ enc_tkt_reply = *(header_ticket->enc_part2);
- old_life = enc_tkt_reply.times.endtime - enc_tkt_reply.times.starttime;
+ old_life = enc_tkt_reply.times.endtime - enc_tkt_reply.times.starttime;
- enc_tkt_reply.times.starttime = kdc_time;
- enc_tkt_reply.times.endtime =
- min(header_ticket->enc_part2->times.renew_till,
- kdc_time + old_life);
+ enc_tkt_reply.times.starttime = kdc_time;
+ enc_tkt_reply.times.endtime =
+ min(header_ticket->enc_part2->times.renew_till,
+ kdc_time + old_life);
} else {
- /* not a renew request */
- enc_tkt_reply.times.starttime = kdc_time;
- until = (request->till == 0) ? kdc_infinity : request->till;
- enc_tkt_reply.times.endtime =
- min(until, min(enc_tkt_reply.times.starttime + server.max_life,
- min(enc_tkt_reply.times.starttime + max_life_for_realm,
- header_enc_tkt->times.endtime)));
- if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE_OK) &&
- (enc_tkt_reply.times.endtime < request->till) &&
- isflagset(header_enc_tkt->flags, TKT_FLG_RENEWABLE)) {
- setflag(request->kdc_options, KDC_OPT_RENEWABLE);
- request->rtime =
- min(request->till, header_enc_tkt->times.renew_till);
- }
+ /* not a renew request */
+ enc_tkt_reply.times.starttime = kdc_time;
+ until = (request->till == 0) ? kdc_infinity : request->till;
+ enc_tkt_reply.times.endtime =
+ min(until, min(enc_tkt_reply.times.starttime + server.max_life,
+ min(enc_tkt_reply.times.starttime + max_life_for_realm,
+ header_enc_tkt->times.endtime)));
+ if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE_OK) &&
+ (enc_tkt_reply.times.endtime < request->till) &&
+ isflagset(header_enc_tkt->flags, TKT_FLG_RENEWABLE)) {
+ setflag(request->kdc_options, KDC_OPT_RENEWABLE);
+ request->rtime =
+ min(request->till, header_enc_tkt->times.renew_till);
+ }
}
rtime = (request->rtime == 0) ? kdc_infinity : request->rtime;
if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE)) {
- /* already checked above in policy check to reject request for a
- renewable ticket using a non-renewable ticket */
- setflag(enc_tkt_reply.flags, TKT_FLG_RENEWABLE);
- enc_tkt_reply.times.renew_till =
- min(rtime,
- min(header_enc_tkt->times.renew_till,
- enc_tkt_reply.times.starttime +
- min(server.max_renewable_life,
- max_renewable_life_for_realm)));
+ /* already checked above in policy check to reject request for a
+ renewable ticket using a non-renewable ticket */
+ setflag(enc_tkt_reply.flags, TKT_FLG_RENEWABLE);
+ enc_tkt_reply.times.renew_till =
+ min(rtime,
+ min(header_enc_tkt->times.renew_till,
+ enc_tkt_reply.times.starttime +
+ min(server.max_renewable_life,
+ max_renewable_life_for_realm)));
} else {
- enc_tkt_reply.times.renew_till = 0;
+ enc_tkt_reply.times.renew_till = 0;
}
/*
* Propagate the preauthentication flags through to the returned ticket.
*/
if (isflagset(header_enc_tkt->flags, TKT_FLG_PRE_AUTH))
- setflag(enc_tkt_reply.flags, TKT_FLG_PRE_AUTH);
+ setflag(enc_tkt_reply.flags, TKT_FLG_PRE_AUTH);
if (isflagset(header_enc_tkt->flags, TKT_FLG_HW_AUTH))
- setflag(enc_tkt_reply.flags, TKT_FLG_HW_AUTH);
+ setflag(enc_tkt_reply.flags, TKT_FLG_HW_AUTH);
/* starttime is optional, and treated as authtime if not present.
so we can nuke it if it matches */
if (enc_tkt_reply.times.starttime == enc_tkt_reply.times.authtime)
- enc_tkt_reply.times.starttime = 0;
+ enc_tkt_reply.times.starttime = 0;
if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION)) {
- errcode = krb5_unparse_name(kdc_context, for_user->user, &s4u_name);
+ errcode = krb5_unparse_name(kdc_context, for_user->user, &s4u_name);
} else if (isflagset(c_flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION)) {
- errcode = krb5_unparse_name(kdc_context, header_enc_tkt->client, &s4u_name);
+ errcode = krb5_unparse_name(kdc_context, header_enc_tkt->client, &s4u_name);
} else {
- errcode = 0;
+ errcode = 0;
}
if (errcode) {
- status = "UNPARSING S4U CLIENT";
- goto cleanup;
+ status = "UNPARSING S4U CLIENT";
+ goto cleanup;
}
if (isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY)) {
- krb5_enc_tkt_part *t2enc = request->second_ticket[st_idx]->enc_part2;
- encrypting_key = *(t2enc->session);
+ krb5_enc_tkt_part *t2enc = request->second_ticket[st_idx]->enc_part2;
+ encrypting_key = *(t2enc->session);
} else {
- /*
- * Find the server key
- */
- if ((errcode = krb5_dbe_find_enctype(kdc_context, &server,
- -1, /* ignore keytype */
- -1, /* Ignore salttype */
- 0, /* Get highest kvno */
- &server_key))) {
- status = "FINDING_SERVER_KEY";
- goto cleanup;
- }
- /* convert server.key into a real key (it may be encrypted
- * in the database) */
- if ((errcode = krb5_dbekd_decrypt_key_data(kdc_context,
- &master_keyblock,
- server_key, &encrypting_key,
- NULL))) {
- status = "DECRYPT_SERVER_KEY";
- goto cleanup;
- }
+ /*
+ * Find the server key
+ */
+ if ((errcode = krb5_dbe_find_enctype(kdc_context, &server,
+ -1, /* ignore keytype */
+ -1, /* Ignore salttype */
+ 0,/* Get highest kvno */
+ &server_key))) {
+ status = "FINDING_SERVER_KEY";
+ goto cleanup;
+ }
+ /* convert server.key into a real key (it may be encrypted
+ * in the database) */
+ if ((errcode = krb5_dbekd_decrypt_key_data(kdc_context,
+ &master_keyblock,
+ server_key, &encrypting_key,
+ NULL))) {
+ status = "DECRYPT_SERVER_KEY";
+ goto cleanup;
+ }
}
if (isflagset(c_flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION)) {
- /*
- * Don't allow authorization data to be disabled if constrained
- * delegation is requested. We don't want to deny the server
- * the ability to validate that delegation was used.
- */
- clear(server.attributes, KRB5_KDB_NO_AUTH_DATA_REQUIRED);
+ /*
+ * Don't allow authorization data to be disabled if constrained
+ * delegation is requested. We don't want to deny the server
+ * the ability to validate that delegation was used.
+ */
+ clear(server.attributes, KRB5_KDB_NO_AUTH_DATA_REQUIRED);
}
if (isflagset(server.attributes, KRB5_KDB_NO_AUTH_DATA_REQUIRED) == 0) {
- /*
- * If we are not doing protocol transition/constrained delegation
- * and there was no authorization data included, try to lookup
- * the client principal as it may be mapped to a local account.
- *
- * Always validate authorization data for constrained delegation
- * because we must validate the KDC signatures.
- */
- if (!isflagset(c_flags, KRB5_KDB_FLAGS_S4U) &&
- header_enc_tkt->authorization_data == NULL) {
-
- /* Generate authorization data so we can include it in ticket */
- setflag(c_flags, KRB5_KDB_FLAG_INCLUDE_PAC);
- /* Map principals from foreign (possibly non-AD) realms */
- setflag(c_flags, KRB5_KDB_FLAG_MAP_PRINCIPALS);
-
- assert(c_nprincs == 0); /* should not have been looked up already */
-
- c_nprincs = 1;
- errcode = krb5_db_get_principal_ext(kdc_context,
- header_enc_tkt->client,
- c_flags,
- &client,
- &c_nprincs,
- &more);
- /*
- * We can ignore errors because the principal may be a
- * valid cross-realm principal for which we have no local
- * mapping. But we do want to check that at most one entry
- * was returned.
- */
- if (errcode == 0 && (more || c_nprincs > 1)) {
- errcode = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE;
- goto cleanup;
- } else if (errcode) {
- c_nprincs = 0;
- }
- }
+ /*
+ * If we are not doing protocol transition/constrained delegation
+ * and there was no authorization data included, try to lookup
+ * the client principal as it may be mapped to a local account.
+ *
+ * Always validate authorization data for constrained delegation
+ * because we must validate the KDC signatures.
+ */
+ if (!isflagset(c_flags, KRB5_KDB_FLAGS_S4U) &&
+ header_enc_tkt->authorization_data == NULL) {
+
+ /* Generate authorization data so we can include it in ticket */
+ setflag(c_flags, KRB5_KDB_FLAG_INCLUDE_PAC);
+ /* Map principals from foreign (possibly non-AD) realms */
+ setflag(c_flags, KRB5_KDB_FLAG_MAP_PRINCIPALS);
+
+ assert(c_nprincs == 0); /* should not have been looked up already */
+
+ c_nprincs = 1;
+ errcode = krb5_db_get_principal_ext(kdc_context,
+ header_enc_tkt->client,
+ c_flags,
+ &client,
+ &c_nprincs,
+ &more);
+ /*
+ * We can ignore errors because the principal may be a
+ * valid cross-realm principal for which we have no local
+ * mapping. But we do want to check that at most one entry
+ * was returned.
+ */
+ if (errcode == 0 && (more || c_nprincs > 1)) {
+ errcode = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE;
+ goto cleanup;
+ } else if (errcode) {
+ c_nprincs = 0;
+ }
+ }
}
enc_tkt_reply.authorization_data = NULL;
if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION) &&
- is_local_principal(header_enc_tkt->client))
- enc_tkt_reply.client = for_user->user;
+ is_local_principal(header_enc_tkt->client))
+ enc_tkt_reply.client = for_user->user;
else
- enc_tkt_reply.client = header_enc_tkt->client;
+ enc_tkt_reply.client = header_enc_tkt->client;
errcode = handle_authdata(kdc_context,
- c_flags,
- (c_nprincs != 0) ? &client : NULL,
- &server,
- (k_nprincs != 0) ? &krbtgt : NULL,
- subkey != NULL ? subkey :
- header_ticket->enc_part2->session,
- &encrypting_key, /* U2U or server key */
- pkt,
- request,
- for_user ? for_user->user : NULL,
- header_enc_tkt,
- &enc_tkt_reply);
+ c_flags,
+ (c_nprincs != 0) ? &client : NULL,
+ &server,
+ (k_nprincs != 0) ? &krbtgt : NULL,
+ subkey != NULL ? subkey :
+ header_ticket->enc_part2->session,
+ &encrypting_key, /* U2U or server key */
+ pkt,
+ request,
+ for_user ? for_user->user : NULL,
+ header_enc_tkt,
+ &enc_tkt_reply);
if (errcode) {
- krb5_klog_syslog(LOG_INFO, "TGS_REQ : handle_authdata (%d)", errcode);
- status = "HANDLE_AUTHDATA";
- goto cleanup;
+ krb5_klog_syslog(LOG_INFO, "TGS_REQ : handle_authdata (%d)", errcode);
+ status = "HANDLE_AUTHDATA";
+ goto cleanup;
}
if (is_referral && isflagset(s_flags, KRB5_KDB_FLAG_CANONICALIZE)) {
- errcode = return_svr_referral_data(kdc_context,
- &server, &reply_encpart);
- if (errcode) {
- status = "KDC_RETURN_ENC_PADATA";
- goto cleanup;
- }
+ errcode = return_svr_referral_data(kdc_context,
+ &server, &reply_encpart);
+ if (errcode) {
+ status = "KDC_RETURN_ENC_PADATA";
+ goto cleanup;
+ }
}
enc_tkt_reply.session = &session_key;
/* realm compare is like strcmp, but knows how to deal with these args */
if (realm_compare(header_ticket->server, tgs_server) ||
- realm_compare(header_ticket->server, enc_tkt_reply.client)) {
- /* tgt issued by local realm or issued by realm of client */
- enc_tkt_reply.transited = header_enc_tkt->transited;
+ realm_compare(header_ticket->server, enc_tkt_reply.client)) {
+ /* tgt issued by local realm or issued by realm of client */
+ enc_tkt_reply.transited = header_enc_tkt->transited;
} else {
- /* tgt issued by some other realm and not the realm of the client */
- /* assemble new transited field into allocated storage */
- if (header_enc_tkt->transited.tr_type !=
- KRB5_DOMAIN_X500_COMPRESS) {
- status = "BAD_TRTYPE";
- errcode = KRB5KDC_ERR_TRTYPE_NOSUPP;
- goto cleanup;
- }
- enc_tkt_transited.tr_type = KRB5_DOMAIN_X500_COMPRESS;
- enc_tkt_transited.magic = 0;
- enc_tkt_transited.tr_contents.magic = 0;
- enc_tkt_transited.tr_contents.data = 0;
- enc_tkt_transited.tr_contents.length = 0;
- enc_tkt_reply.transited = enc_tkt_transited;
- if ((errcode =
- add_to_transited(&header_enc_tkt->transited.tr_contents,
- &enc_tkt_reply.transited.tr_contents,
- header_ticket->server,
- enc_tkt_reply.client,
- request->server))) {
- status = "ADD_TR_FAIL";
- goto cleanup;
- }
- newtransited = 1;
+ /* tgt issued by some other realm and not the realm of the client */
+ /* assemble new transited field into allocated storage */
+ if (header_enc_tkt->transited.tr_type !=
+ KRB5_DOMAIN_X500_COMPRESS) {
+ status = "BAD_TRTYPE";
+ errcode = KRB5KDC_ERR_TRTYPE_NOSUPP;
+ goto cleanup;
+ }
+ enc_tkt_transited.tr_type = KRB5_DOMAIN_X500_COMPRESS;
+ enc_tkt_transited.magic = 0;
+ enc_tkt_transited.tr_contents.magic = 0;
+ enc_tkt_transited.tr_contents.data = 0;
+ enc_tkt_transited.tr_contents.length = 0;
+ enc_tkt_reply.transited = enc_tkt_transited;
+ if ((errcode =
+ add_to_transited(&header_enc_tkt->transited.tr_contents,
+ &enc_tkt_reply.transited.tr_contents,
+ header_ticket->server,
+ enc_tkt_reply.client,
+ request->server))) {
+ status = "ADD_TR_FAIL";
+ goto cleanup;
+ }
+ newtransited = 1;
}
if (isflagset(c_flags, KRB5_KDB_FLAG_CROSS_REALM)) {
- errcode = validate_transit_path(kdc_context, header_enc_tkt->client,
- &server,
- (k_nprincs != 0) ? &krbtgt : NULL);
- if (errcode) {
- status = "NON_TRANSITIVE";
- goto cleanup;
- }
+ errcode = validate_transit_path(kdc_context, header_enc_tkt->client,
+ &server,
+ (k_nprincs != 0) ? &krbtgt : NULL);
+ if (errcode) {
+ status = "NON_TRANSITIVE";
+ goto cleanup;
+ }
}
if (!isflagset (request->kdc_options, KDC_OPT_DISABLE_TRANSITED_CHECK)) {
- unsigned int tlen;
- char *tdots;
-
- errcode = kdc_check_transited_list (kdc_context,
- &enc_tkt_reply.transited.tr_contents,
- krb5_princ_realm (kdc_context, header_enc_tkt->client),
- krb5_princ_realm (kdc_context, request->server));
- tlen = enc_tkt_reply.transited.tr_contents.length;
- tdots = tlen > 125 ? "..." : "";
- tlen = tlen > 125 ? 125 : tlen;
-
- if (errcode == 0) {
- setflag (enc_tkt_reply.flags, TKT_FLG_TRANSIT_POLICY_CHECKED);
- } else if (errcode == KRB5KRB_AP_ERR_ILL_CR_TKT)
- krb5_klog_syslog (LOG_INFO,
- "bad realm transit path from '%s' to '%s' "
- "via '%.*s%s'",
- cname ? cname : "<unknown client>",
- sname ? sname : "<unknown server>",
- tlen,
- enc_tkt_reply.transited.tr_contents.data,
- tdots);
- else {
- emsg = krb5_get_error_message(kdc_context, errcode);
- krb5_klog_syslog (LOG_ERR,
- "unexpected error checking transit from "
- "'%s' to '%s' via '%.*s%s': %s",
- cname ? cname : "<unknown client>",
- sname ? sname : "<unknown server>",
- tlen,
- enc_tkt_reply.transited.tr_contents.data,
- tdots, emsg);
- krb5_free_error_message(kdc_context, emsg);
- emsg = NULL;
- }
+ unsigned int tlen;
+ char *tdots;
+
+ errcode = kdc_check_transited_list (kdc_context,
+ &enc_tkt_reply.transited.tr_contents,
+ krb5_princ_realm (kdc_context, header_enc_tkt->client),
+ krb5_princ_realm (kdc_context, request->server));
+ tlen = enc_tkt_reply.transited.tr_contents.length;
+ tdots = tlen > 125 ? "..." : "";
+ tlen = tlen > 125 ? 125 : tlen;
+
+ if (errcode == 0) {
+ setflag (enc_tkt_reply.flags, TKT_FLG_TRANSIT_POLICY_CHECKED);
+ } else if (errcode == KRB5KRB_AP_ERR_ILL_CR_TKT)
+ krb5_klog_syslog (LOG_INFO,
+ "bad realm transit path from '%s' to '%s' "
+ "via '%.*s%s'",
+ cname ? cname : "<unknown client>",
+ sname ? sname : "<unknown server>",
+ tlen,
+ enc_tkt_reply.transited.tr_contents.data,
+ tdots);
+ else {
+ emsg = krb5_get_error_message(kdc_context, errcode);
+ krb5_klog_syslog (LOG_ERR,
+ "unexpected error checking transit from "
+ "'%s' to '%s' via '%.*s%s': %s",
+ cname ? cname : "<unknown client>",
+ sname ? sname : "<unknown server>",
+ tlen,
+ enc_tkt_reply.transited.tr_contents.data,
+ tdots, emsg);
+ krb5_free_error_message(kdc_context, emsg);
+ emsg = NULL;
+ }
} else
- krb5_klog_syslog (LOG_INFO, "not checking transit path");
+ krb5_klog_syslog (LOG_INFO, "not checking transit path");
if (reject_bad_transit
- && !isflagset (enc_tkt_reply.flags, TKT_FLG_TRANSIT_POLICY_CHECKED)) {
- errcode = KRB5KDC_ERR_POLICY;
- status = "BAD_TRANSIT";
- goto cleanup;
+ && !isflagset (enc_tkt_reply.flags, TKT_FLG_TRANSIT_POLICY_CHECKED)) {
+ errcode = KRB5KDC_ERR_POLICY;
+ status = "BAD_TRANSIT";
+ goto cleanup;
}
ticket_reply.enc_part2 = &enc_tkt_reply;
* the second ticket.
*/
if (isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY)) {
- /*
- * Make sure the client for the second ticket matches
- * requested server.
- */
- krb5_enc_tkt_part *t2enc = request->second_ticket[st_idx]->enc_part2;
- krb5_principal client2 = t2enc->client;
- if (!krb5_principal_compare(kdc_context, request->server, client2)) {
- if ((errcode = krb5_unparse_name(kdc_context, client2, &altcname)))
- altcname = 0;
- if (altcname != NULL)
- limit_string(altcname);
-
- errcode = KRB5KDC_ERR_SERVER_NOMATCH;
- status = "2ND_TKT_MISMATCH";
- goto cleanup;
- }
-
- ticket_reply.enc_part.kvno = 0;
- ticket_reply.enc_part.enctype = t2enc->session->enctype;
- st_idx++;
+ /*
+ * Make sure the client for the second ticket matches
+ * requested server.
+ */
+ krb5_enc_tkt_part *t2enc = request->second_ticket[st_idx]->enc_part2;
+ krb5_principal client2 = t2enc->client;
+ if (!krb5_principal_compare(kdc_context, request->server, client2)) {
+ if ((errcode = krb5_unparse_name(kdc_context, client2, &altcname)))
+ altcname = 0;
+ if (altcname != NULL)
+ limit_string(altcname);
+
+ errcode = KRB5KDC_ERR_SERVER_NOMATCH;
+ status = "2ND_TKT_MISMATCH";
+ goto cleanup;
+ }
+
+ ticket_reply.enc_part.kvno = 0;
+ ticket_reply.enc_part.enctype = t2enc->session->enctype;
+ st_idx++;
} else {
- ticket_reply.enc_part.kvno = server_key->key_data_kvno;
+ ticket_reply.enc_part.kvno = server_key->key_data_kvno;
}
errcode = krb5_encrypt_tkt_part(kdc_context, &encrypting_key,
- &ticket_reply);
+ &ticket_reply);
if (!isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY))
- krb5_free_keyblock_contents(kdc_context, &encrypting_key);
+ krb5_free_keyblock_contents(kdc_context, &encrypting_key);
if (errcode) {
- status = "TKT_ENCRYPT";
- goto cleanup;
+ status = "TKT_ENCRYPT";
+ goto cleanup;
}
/* Start assembling the response */
reply.msg_type = KRB5_TGS_REP;
- reply.padata = 0; /* always */
+ reply.padata = 0;/* always */
reply.client = enc_tkt_reply.client;
- reply.enc_part.kvno = 0; /* We are using the session key */
+ reply.enc_part.kvno = 0;/* We are using the session key */
reply.ticket = &ticket_reply;
reply_encpart.session = &session_key;
/* starttime is optional, and treated as authtime if not present.
so we can nuke it if it matches */
if (enc_tkt_reply.times.starttime == enc_tkt_reply.times.authtime)
- enc_tkt_reply.times.starttime = 0;
+ enc_tkt_reply.times.starttime = 0;
nolrentry.lr_type = KRB5_LRQ_NONE;
nolrentry.value = 0;
nolrarray[0] = &nolrentry;
nolrarray[1] = 0;
- reply_encpart.last_req = nolrarray; /* not available for TGS reqs */
- reply_encpart.key_exp = 0; /* ditto */
+ reply_encpart.last_req = nolrarray; /* not available for TGS reqs */
+ reply_encpart.key_exp = 0;/* ditto */
reply_encpart.flags = enc_tkt_reply.flags;
reply_encpart.server = ticket_reply.server;
in the AP_REQ */
reply.enc_part.enctype = subkey ? subkey->enctype :
- header_ticket->enc_part2->session->enctype;
+ header_ticket->enc_part2->session->enctype;
errcode = krb5_encode_kdc_rep(kdc_context, KRB5_TGS_REP, &reply_encpart,
- subkey ? 1 : 0,
- subkey ? subkey :
- header_ticket->enc_part2->session,
- &reply, response);
+ subkey ? 1 : 0,
+ subkey ? subkey :
+ header_ticket->enc_part2->session,
+ &reply, response);
if (errcode) {
- status = "ENCODE_KDC_REP";
+ status = "ENCODE_KDC_REP";
} else {
- status = "ISSUE";
+ status = "ISSUE";
}
memset(ticket_reply.enc_part.ciphertext.data, 0,
- ticket_reply.enc_part.ciphertext.length);
+ ticket_reply.enc_part.ciphertext.length);
free(ticket_reply.enc_part.ciphertext.data);
/* these parts are left on as a courtesy from krb5_encode_kdc_rep so we
can use them in raw form if needed. But, we don't... */
memset(reply.enc_part.ciphertext.data, 0,
- reply.enc_part.ciphertext.length);
+ reply.enc_part.ciphertext.length);
free(reply.enc_part.ciphertext.data);
cleanup:
assert(status != NULL);
if (errcode)
- emsg = krb5_get_error_message (kdc_context, errcode);
+ emsg = krb5_get_error_message (kdc_context, errcode);
log_tgs_req(from, request, &reply, cname, sname, altcname, authtime,
- c_flags, s4u_name, status, errcode, emsg);
+ c_flags, s4u_name, status, errcode, emsg);
if (errcode) {
- krb5_free_error_message (kdc_context, emsg);
- emsg = NULL;
+ krb5_free_error_message (kdc_context, emsg);
+ emsg = NULL;
}
if (errcode) {
int got_err = 0;
- if (status == 0) {
- status = krb5_get_error_message (kdc_context, errcode);
- got_err = 1;
- }
- errcode -= ERROR_TABLE_BASE_krb5;
- if (errcode < 0 || errcode > 128)
- errcode = KRB_ERR_GENERIC;
-
- retval = prepare_error_tgs(request, header_ticket, errcode,
- nprincs ? server.princ : NULL,
- response, status);
- if (got_err) {
- krb5_free_error_message (kdc_context, status);
- status = 0;
- }
+ if (status == 0) {
+ status = krb5_get_error_message (kdc_context, errcode);
+ got_err = 1;
+ }
+ errcode -= ERROR_TABLE_BASE_krb5;
+ if (errcode < 0 || errcode > 128)
+ errcode = KRB_ERR_GENERIC;
+
+ retval = prepare_error_tgs(request, header_ticket, errcode,
+ nprincs ? server.princ : NULL,
+ response, status);
+ if (got_err) {
+ krb5_free_error_message (kdc_context, status);
+ status = 0;
+ }
}
if (header_ticket != NULL)
- krb5_free_ticket(kdc_context, header_ticket);
+ krb5_free_ticket(kdc_context, header_ticket);
if (request != NULL)
- krb5_free_kdc_req(kdc_context, request);
+ krb5_free_kdc_req(kdc_context, request);
if (cname != NULL)
- free(cname);
+ free(cname);
if (sname != NULL)
- free(sname);
+ free(sname);
if (nprincs != 0)
- krb5_db_free_principal(kdc_context, &server, 1);
+ krb5_db_free_principal(kdc_context, &server, 1);
if (session_key.contents != NULL)
- krb5_free_keyblock_contents(kdc_context, &session_key);
+ krb5_free_keyblock_contents(kdc_context, &session_key);
if (newtransited)
- free(enc_tkt_reply.transited.tr_contents.data);
+ free(enc_tkt_reply.transited.tr_contents.data);
if (k_nprincs)
- krb5_db_free_principal(kdc_context, &krbtgt, k_nprincs);
+ krb5_db_free_principal(kdc_context, &krbtgt, k_nprincs);
if (c_nprincs)
- krb5_db_free_principal(kdc_context, &client, c_nprincs);
+ krb5_db_free_principal(kdc_context, &client, c_nprincs);
if (for_user != NULL)
- krb5_free_pa_for_user(kdc_context, for_user);
+ krb5_free_pa_for_user(kdc_context, for_user);
if (kdc_issued_auth_data != NULL)
- krb5_free_authdata(kdc_context, kdc_issued_auth_data);
+ krb5_free_authdata(kdc_context, kdc_issued_auth_data);
if (s4u_name != NULL)
- free(s4u_name);
+ free(s4u_name);
if (subkey != NULL)
- krb5_free_keyblock(kdc_context, subkey);
+ krb5_free_keyblock(kdc_context, subkey);
return retval;
}
static krb5_error_code
prepare_error_tgs (krb5_kdc_req *request, krb5_ticket *ticket, int error,
krb5_principal canon_server,
- krb5_data **response, const char *status)
+ krb5_data **response, const char *status)
{
krb5_error errpkt;
krb5_error_code retval;
errpkt.cusec = 0;
if ((retval = krb5_us_timeofday(kdc_context, &errpkt.stime,
- &errpkt.susec)))
- return(retval);
+ &errpkt.susec)))
+ return(retval);
errpkt.error = error;
errpkt.server = request->server;
if (ticket && ticket->enc_part2)
- errpkt.client = ticket->enc_part2->client;
+ errpkt.client = ticket->enc_part2->client;
else
- errpkt.client = NULL;
+ errpkt.client = NULL;
errpkt.text.length = strlen(status) + 1;
if (!(errpkt.text.data = strdup(status)))
- return ENOMEM;
+ return ENOMEM;
if (!(scratch = (krb5_data *)malloc(sizeof(*scratch)))) {
- free(errpkt.text.data);
- return ENOMEM;
+ free(errpkt.text.data);
+ return ENOMEM;
}
errpkt.e_data.length = 0;
errpkt.e_data.data = NULL;
retval = krb5_mk_error(kdc_context, &errpkt, scratch);
free(errpkt.text.data);
if (retval)
- free(scratch);
+ free(scratch);
else
- *response = scratch;
+ *response = scratch;
return retval;
}
*/
static void
find_alternate_tgs(krb5_kdc_req *request, krb5_db_entry *server,
- krb5_boolean *more, int *nprincs)
+ krb5_boolean *more, int *nprincs)
{
krb5_error_code retval;
krb5_principal *plist, *pl2;
* the principal.
*/
if ((retval = krb5_walk_realm_tree(kdc_context,
- krb5_princ_realm(kdc_context, request->server),
- krb5_princ_component(kdc_context, request->server, 1),
- &plist, KRB5_REALM_BRANCH_CHAR)))
- return;
+ krb5_princ_realm(kdc_context, request->server),
+ krb5_princ_component(kdc_context, request->server, 1),
+ &plist, KRB5_REALM_BRANCH_CHAR)))
+ return;
/* move to the end */
for (pl2 = plist; *pl2; pl2++);
/* the first entry in this array is for krbtgt/local@local, so we
ignore it */
while (--pl2 > plist) {
- *nprincs = 1;
- tmp = *krb5_princ_realm(kdc_context, *pl2);
- krb5_princ_set_realm(kdc_context, *pl2,
- krb5_princ_realm(kdc_context, tgs_server));
- retval = get_principal(kdc_context, *pl2, server, nprincs, more);
- krb5_princ_set_realm(kdc_context, *pl2, &tmp);
- if (retval) {
- *nprincs = 0;
- *more = FALSE;
- krb5_free_realm_tree(kdc_context, plist);
- return;
- }
- if (*more) {
- krb5_db_free_principal(kdc_context, server, *nprincs);
- continue;
- } else if (*nprincs == 1) {
- /* Found it! */
- krb5_principal tmpprinc;
-
- tmp = *krb5_princ_realm(kdc_context, *pl2);
- krb5_princ_set_realm(kdc_context, *pl2,
- krb5_princ_realm(kdc_context, tgs_server));
- if ((retval = krb5_copy_principal(kdc_context, *pl2, &tmpprinc))) {
- krb5_db_free_principal(kdc_context, server, *nprincs);
- krb5_princ_set_realm(kdc_context, *pl2, &tmp);
- continue;
- }
- krb5_princ_set_realm(kdc_context, *pl2, &tmp);
-
- krb5_free_principal(kdc_context, request->server);
- request->server = tmpprinc;
- log_tgs_alt_tgt(request->server);
- krb5_free_realm_tree(kdc_context, plist);
- return;
- }
- krb5_db_free_principal(kdc_context, server, *nprincs);
- continue;
+ *nprincs = 1;
+ tmp = *krb5_princ_realm(kdc_context, *pl2);
+ krb5_princ_set_realm(kdc_context, *pl2,
+ krb5_princ_realm(kdc_context, tgs_server));
+ retval = get_principal(kdc_context, *pl2, server, nprincs, more);
+ krb5_princ_set_realm(kdc_context, *pl2, &tmp);
+ if (retval) {
+ *nprincs = 0;
+ *more = FALSE;
+ krb5_free_realm_tree(kdc_context, plist);
+ return;
+ }
+ if (*more) {
+ krb5_db_free_principal(kdc_context, server, *nprincs);
+ continue;
+ } else if (*nprincs == 1) {
+ /* Found it! */
+ krb5_principal tmpprinc;
+
+ tmp = *krb5_princ_realm(kdc_context, *pl2);
+ krb5_princ_set_realm(kdc_context, *pl2,
+ krb5_princ_realm(kdc_context, tgs_server));
+ if ((retval = krb5_copy_principal(kdc_context, *pl2, &tmpprinc))) {
+ krb5_db_free_principal(kdc_context, server, *nprincs);
+ krb5_princ_set_realm(kdc_context, *pl2, &tmp);
+ continue;
+ }
+ krb5_princ_set_realm(kdc_context, *pl2, &tmp);
+
+ krb5_free_principal(kdc_context, request->server);
+ request->server = tmpprinc;
+ log_tgs_alt_tgt(request->server);
+ krb5_free_realm_tree(kdc_context, plist);
+ return;
+ }
+ krb5_db_free_principal(kdc_context, server, *nprincs);
+ continue;
}
*nprincs = 0;
/* is_substr - verfies if d1 contains d2->data with head/trail-ing whitespaces
*/
-static krb5_boolean
+static krb5_int32
is_substr ( char *d1, krb5_data *d2)
{
krb5_boolean ret = FALSE;
if ( d1 && d2 && d2->data && (d2->length+2 <= strlen(d1))){
if ((new_d2 = calloc(1,d2->length+1))) {
strncpy(new_d2,d2->data,d2->length);
- asprintf( &d2_formated, "%c%s%c", ' ', new_d2, ' ');
- if ( d2_formated != 0 && strstr( d1, d2_formated) != NULL)
+ if (asprintf( &d2_formated, "%c%s%c", ' ', new_d2, ' ') < 0)
+ ret = ENOMEM;
+ else if (d2_formated != 0 && strstr(d1, d2_formated) != NULL)
ret = TRUE;
free(new_d2);
free(d2_formated);
return ret;
}
-
-