From: Tom Yu Date: Wed, 12 Sep 2012 21:19:24 +0000 (-0400) Subject: Move add_to_transited to a separate file X-Git-Tag: krb5-1.11-alpha1~56 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b57463a2e6e6a1ad047fafc54793c98ccf1c507b;p=thirdparty%2Fkrb5.git Move add_to_transited to a separate file add_to_transited() is fairly large, and also fairly independent of the other contents of kdc_util.c. Move it into kdc_transit.c. Also simplifies the building of rtest by removing dependencies that kdc_util.c previously needed to satisfy undefined symbols. --- diff --git a/src/kdc/Makefile.in b/src/kdc/Makefile.in index 497c6f8d89..52e65d6776 100644 --- a/src/kdc/Makefile.in +++ b/src/kdc/Makefile.in @@ -26,7 +26,8 @@ SRCS= \ $(srcdir)/policy.c \ $(srcdir)/extern.c \ $(srcdir)/replay.c \ - $(srcdir)/kdc_authdata.c + $(srcdir)/kdc_authdata.c \ + $(srcdir)/kdc_transit.c OBJS= \ kdc5_err.o \ @@ -42,12 +43,11 @@ OBJS= \ policy.o \ extern.o \ replay.o \ - kdc_authdata.o + kdc_authdata.o \ + kdc_transit.o RT_OBJS= rtest.o \ - kdc_util.o \ - policy.o \ - extern.o + kdc_transit.o depend:: kdc5_err.c kdc5_err.h diff --git a/src/kdc/kdc_transit.c b/src/kdc/kdc_transit.c new file mode 100644 index 0000000000..88b4616b27 --- /dev/null +++ b/src/kdc/kdc_transit.c @@ -0,0 +1,415 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* kdc/kdc_transit.c */ +/* + * Copyright (C) 2012 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "k5-int.h" +#include "kdc_util.h" + +#define MAX_REALM_LN 500 + +/* + * subrealm - determine if r2 is a subrealm of r1 + * + * SUBREALM takes two realms, r1 and r2, and + * determines if r2 is a subrealm of r1. + * r2 is a subrealm of r1 if (r1 is a prefix + * of r2 AND r1 and r2 begin with a /) or if + * (r1 is a suffix of r2 and neither r1 nor r2 + * begin with a /). + * + * RETURNS: If r2 is a subrealm, and r1 is a prefix, the number + * of characters in the suffix of r2 is returned as a + * negative number. + * + * If r2 is a subrealm, and r1 is a suffix, the number + * of characters in the prefix of r2 is returned as a + * positive number. + * + * If r2 is not a subrealm, SUBREALM returns 0. + */ +static int +subrealm(char *r1, char *r2) +{ + size_t l1,l2; + l1 = strlen(r1); + l2 = strlen(r2); + if(l2 <= l1) return(0); + if((*r1 == '/') && (*r2 == '/') && (strncmp(r1,r2,l1) == 0)) return(l1-l2); + if((*r1 != '/') && (*r2 != '/') && (strncmp(r1,r2+l2-l1,l1) == 0)) + return(l2-l1); + return(0); +} + +/* + * add_to_transited Adds the name of the realm which issued the + * ticket granting ticket on which the new ticket to + * be issued is based (note that this is the same as + * the realm of the server listed in the ticket + * granting ticket. + * + * ASSUMPTIONS: This procedure assumes that the transited field from + * the existing ticket granting ticket already appears + * in compressed form. It will add the new realm while + * maintaining that form. As long as each successive + * realm is added using this (or a similar) routine, the + * transited field will be in compressed form. The + * basis step is an empty transited field which is, by + * its nature, in its most compressed form. + * + * ARGUMENTS: krb5_data *tgt_trans Transited field from TGT + * krb5_data *new_trans The transited field for the new ticket + * krb5_principal tgs Name of ticket granting server + * This includes the realm of the KDC + * that issued the ticket granting + * ticket. This is the realm that is + * to be added to the transited field. + * krb5_principal client Name of the client + * krb5_principal server The name of the requested server. + * This may be the an intermediate + * ticket granting server. + * + * The last two argument are needed since they are + * implicitly part of the transited field of the new ticket + * even though they are not explicitly listed. + * + * RETURNS: krb5_error_code - Success, or out of memory + * + * MODIFIES: new_trans: ->length will contain the length of the new + * transited field. + * + * If ->data was not null when this procedure + * is called, the memory referenced by ->data + * will be deallocated. + * + * Memory will be allocated for the new transited field + * ->data will be updated to point to the newly + * allocated memory. + * + * BUGS: The space allocated for the new transited field is the + * maximum that might be needed given the old transited field, + * and the realm to be added. This length is calculated + * assuming that no compression of the new realm is possible. + * This has no adverse consequences other than the allocation + * of more space than required. + * + * This procedure will not yet use the null subfield notation, + * and it will get confused if it sees it. + * + * This procedure does not check for quoted commas in realm + * names. + */ + +static char * +data2string (krb5_data *d) +{ + char *s; + s = malloc(d->length + 1); + if (s) { + memcpy(s, d->data, d->length); + s[d->length] = 0; + } + return s; +} + +krb5_error_code +add_to_transited(krb5_data *tgt_trans, krb5_data *new_trans, + krb5_principal tgs, krb5_principal client, + krb5_principal server) +{ + krb5_error_code retval; + char *realm; + char *trans; + char *otrans, *otrans_ptr; + size_t bufsize; + + /* The following are for stepping through the transited field */ + + char prev[MAX_REALM_LN]; + char next[MAX_REALM_LN]; + char current[MAX_REALM_LN]; + char exp[MAX_REALM_LN]; /* Expanded current realm name */ + + int i; + int clst, nlst; /* count of last character in current and next */ + int pl, pl1; /* prefix length */ + int added; /* TRUE = new realm has been added */ + + realm = data2string(krb5_princ_realm(kdc_context, tgs)); + if (realm == NULL) + return(ENOMEM); + + otrans = data2string(tgt_trans); + if (otrans == NULL) { + free(realm); + return(ENOMEM); + } + /* Keep track of start so we can free */ + otrans_ptr = otrans; + + /* +1 for null, + +1 for extra comma which may be added between + +1 for potential space when leading slash in realm */ + bufsize = strlen(realm) + strlen(otrans) + 3; + if (bufsize > MAX_REALM_LN) + bufsize = MAX_REALM_LN; + if (!(trans = (char *) malloc(bufsize))) { + retval = ENOMEM; + goto fail; + } + + if (new_trans->data) free(new_trans->data); + new_trans->data = trans; + new_trans->length = 0; + + trans[0] = '\0'; + + /* For the purpose of appending, the realm preceding the first */ + /* realm in the transited field is considered the null realm */ + + prev[0] = '\0'; + + /* read field into current */ + for (i = 0; *otrans != '\0';) { + if (*otrans == '\\') { + if (*(++otrans) == '\0') + break; + else + continue; + } + if (*otrans == ',') { + otrans++; + break; + } + current[i++] = *otrans++; + if (i >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + } + current[i] = '\0'; + + added = (krb5_princ_realm(kdc_context, client)->length == strlen(realm) && + !strncmp(krb5_princ_realm(kdc_context, client)->data, realm, strlen(realm))) || + (krb5_princ_realm(kdc_context, server)->length == strlen(realm) && + !strncmp(krb5_princ_realm(kdc_context, server)->data, realm, strlen(realm))); + + while (current[0]) { + + /* figure out expanded form of current name */ + + clst = strlen(current) - 1; + if (current[0] == ' ') { + strncpy(exp, current+1, sizeof(exp) - 1); + exp[sizeof(exp) - 1] = '\0'; + } + else if ((current[0] == '/') && (prev[0] == '/')) { + strncpy(exp, prev, sizeof(exp) - 1); + exp[sizeof(exp) - 1] = '\0'; + if (strlen(exp) + strlen(current) + 1 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + strncat(exp, current, sizeof(exp) - 1 - strlen(exp)); + } + else if (current[clst] == '.') { + strncpy(exp, current, sizeof(exp) - 1); + exp[sizeof(exp) - 1] = '\0'; + if (strlen(exp) + strlen(prev) + 1 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + strncat(exp, prev, sizeof(exp) - 1 - strlen(exp)); + } + else { + strncpy(exp, current, sizeof(exp) - 1); + exp[sizeof(exp) - 1] = '\0'; + } + + /* read field into next */ + for (i = 0; *otrans != '\0';) { + if (*otrans == '\\') { + if (*(++otrans) == '\0') + break; + else + continue; + } + if (*otrans == ',') { + otrans++; + break; + } + next[i++] = *otrans++; + if (i >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + } + next[i] = '\0'; + nlst = i - 1; + + if (!strcmp(exp, realm)) added = TRUE; + + /* If we still have to insert the new realm */ + + if (!added) { + + /* Is the next field compressed? If not, and if the new */ + /* realm is a subrealm of the current realm, compress */ + /* the new realm, and insert immediately following the */ + /* current one. Note that we can not do this if the next*/ + /* field is already compressed since it would mess up */ + /* what has already been done. In most cases, this is */ + /* not a problem because the realm to be added will be a */ + /* subrealm of the next field too, and we will catch */ + /* it in a future iteration. */ + + /* Note that the second test here is an unsigned comparison, + so the first half (or a cast) is also required. */ + assert(nlst < 0 || nlst < (int)sizeof(next)); + if ((nlst < 0 || next[nlst] != '.') && + (next[0] != '/') && + (pl = subrealm(exp, realm))) { + added = TRUE; + current[sizeof(current) - 1] = '\0'; + if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + strncat(current, ",", sizeof(current) - 1 - strlen(current)); + if (pl > 0) { + strncat(current, realm, (unsigned) pl); + } + else { + strncat(current, realm+strlen(realm)+pl, (unsigned) (-pl)); + } + } + + /* Whether or not the next field is compressed, if the */ + /* realm to be added is a superrealm of the current realm,*/ + /* then the current realm can be compressed. First the */ + /* realm to be added must be compressed relative to the */ + /* previous realm (if possible), and then the current */ + /* realm compressed relative to the new realm. Note that */ + /* if the realm to be added is also a superrealm of the */ + /* previous realm, it would have been added earlier, and */ + /* we would not reach this step this time around. */ + + else if ((pl = subrealm(realm, exp))) { + added = TRUE; + current[0] = '\0'; + if ((pl1 = subrealm(prev,realm))) { + if (strlen(current) + (pl1>0?pl1:-pl1) + 1 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + if (pl1 > 0) { + strncat(current, realm, (unsigned) pl1); + } + else { + strncat(current, realm+strlen(realm)+pl1, (unsigned) (-pl1)); + } + } + else { /* If not a subrealm */ + if ((realm[0] == '/') && prev[0]) { + if (strlen(current) + 2 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + strncat(current, " ", sizeof(current) - 1 - strlen(current)); + current[sizeof(current) - 1] = '\0'; + } + if (strlen(current) + strlen(realm) + 1 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + strncat(current, realm, sizeof(current) - 1 - strlen(current)); + current[sizeof(current) - 1] = '\0'; + } + if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + strncat(current,",", sizeof(current) - 1 - strlen(current)); + current[sizeof(current) - 1] = '\0'; + if (pl > 0) { + strncat(current, exp, (unsigned) pl); + } + else { + strncat(current, exp+strlen(exp)+pl, (unsigned)(-pl)); + } + } + } + + if (new_trans->length != 0) { + if (strlcat(trans, ",", bufsize) >= bufsize) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + } + if (strlcat(trans, current, bufsize) >= bufsize) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + new_trans->length = strlen(trans); + + strncpy(prev, exp, sizeof(prev) - 1); + prev[sizeof(prev) - 1] = '\0'; + strncpy(current, next, sizeof(current) - 1); + current[sizeof(current) - 1] = '\0'; + } + + if (!added) { + if (new_trans->length != 0) { + if (strlcat(trans, ",", bufsize) >= bufsize) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + } + if((realm[0] == '/') && trans[0]) { + if (strlcat(trans, " ", bufsize) >= bufsize) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + } + if (strlcat(trans, realm, bufsize) >= bufsize) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + new_trans->length = strlen(trans); + } + + retval = 0; +fail: + free(realm); + free(otrans_ptr); + return (retval); +} diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c index 773d8cf172..371072b5b2 100644 --- a/src/kdc/kdc_util.c +++ b/src/kdc/kdc_util.c @@ -550,386 +550,6 @@ check_hot_list(krb5_ticket *ticket) } -#define MAX_REALM_LN 500 - - -/* - * subrealm - determine if r2 is a subrealm of r1 - * - * SUBREALM takes two realms, r1 and r2, and - * determines if r2 is a subrealm of r1. - * r2 is a subrealm of r1 if (r1 is a prefix - * of r2 AND r1 and r2 begin with a /) or if - * (r1 is a suffix of r2 and neither r1 nor r2 - * begin with a /). - * - * RETURNS: If r2 is a subrealm, and r1 is a prefix, the number - * of characters in the suffix of r2 is returned as a - * negative number. - * - * If r2 is a subrealm, and r1 is a suffix, the number - * of characters in the prefix of r2 is returned as a - * positive number. - * - * If r2 is not a subrealm, SUBREALM returns 0. - */ -static int -subrealm(char *r1, char *r2) -{ - size_t l1,l2; - l1 = strlen(r1); - l2 = strlen(r2); - if(l2 <= l1) return(0); - if((*r1 == '/') && (*r2 == '/') && (strncmp(r1,r2,l1) == 0)) return(l1-l2); - if((*r1 != '/') && (*r2 != '/') && (strncmp(r1,r2+l2-l1,l1) == 0)) - return(l2-l1); - return(0); -} - -/* - * add_to_transited Adds the name of the realm which issued the - * ticket granting ticket on which the new ticket to - * be issued is based (note that this is the same as - * the realm of the server listed in the ticket - * granting ticket. - * - * ASSUMPTIONS: This procedure assumes that the transited field from - * the existing ticket granting ticket already appears - * in compressed form. It will add the new realm while - * maintaining that form. As long as each successive - * realm is added using this (or a similar) routine, the - * transited field will be in compressed form. The - * basis step is an empty transited field which is, by - * its nature, in its most compressed form. - * - * ARGUMENTS: krb5_data *tgt_trans Transited field from TGT - * krb5_data *new_trans The transited field for the new ticket - * krb5_principal tgs Name of ticket granting server - * This includes the realm of the KDC - * that issued the ticket granting - * ticket. This is the realm that is - * to be added to the transited field. - * krb5_principal client Name of the client - * krb5_principal server The name of the requested server. - * This may be the an intermediate - * ticket granting server. - * - * The last two argument are needed since they are - * implicitly part of the transited field of the new ticket - * even though they are not explicitly listed. - * - * RETURNS: krb5_error_code - Success, or out of memory - * - * MODIFIES: new_trans: ->length will contain the length of the new - * transited field. - * - * If ->data was not null when this procedure - * is called, the memory referenced by ->data - * will be deallocated. - * - * Memory will be allocated for the new transited field - * ->data will be updated to point to the newly - * allocated memory. - * - * BUGS: The space allocated for the new transited field is the - * maximum that might be needed given the old transited field, - * and the realm to be added. This length is calculated - * assuming that no compression of the new realm is possible. - * This has no adverse consequences other than the allocation - * of more space than required. - * - * This procedure will not yet use the null subfield notation, - * and it will get confused if it sees it. - * - * This procedure does not check for quoted commas in realm - * names. - */ - -static char * -data2string (krb5_data *d) -{ - char *s; - s = malloc(d->length + 1); - if (s) { - memcpy(s, d->data, d->length); - s[d->length] = 0; - } - return s; -} - -krb5_error_code -add_to_transited(krb5_data *tgt_trans, krb5_data *new_trans, - krb5_principal tgs, krb5_principal client, - krb5_principal server) -{ - krb5_error_code retval; - char *realm; - char *trans; - char *otrans, *otrans_ptr; - size_t bufsize; - - /* The following are for stepping through the transited field */ - - char prev[MAX_REALM_LN]; - char next[MAX_REALM_LN]; - char current[MAX_REALM_LN]; - char exp[MAX_REALM_LN]; /* Expanded current realm name */ - - int i; - int clst, nlst; /* count of last character in current and next */ - int pl, pl1; /* prefix length */ - int added; /* TRUE = new realm has been added */ - - realm = data2string(krb5_princ_realm(kdc_context, tgs)); - if (realm == NULL) - return(ENOMEM); - - otrans = data2string(tgt_trans); - if (otrans == NULL) { - free(realm); - return(ENOMEM); - } - /* Keep track of start so we can free */ - otrans_ptr = otrans; - - /* +1 for null, - +1 for extra comma which may be added between - +1 for potential space when leading slash in realm */ - bufsize = strlen(realm) + strlen(otrans) + 3; - if (bufsize > MAX_REALM_LN) - bufsize = MAX_REALM_LN; - if (!(trans = (char *) malloc(bufsize))) { - retval = ENOMEM; - goto fail; - } - - if (new_trans->data) free(new_trans->data); - new_trans->data = trans; - new_trans->length = 0; - - trans[0] = '\0'; - - /* For the purpose of appending, the realm preceding the first */ - /* realm in the transited field is considered the null realm */ - - prev[0] = '\0'; - - /* read field into current */ - for (i = 0; *otrans != '\0';) { - if (*otrans == '\\') { - if (*(++otrans) == '\0') - break; - else - continue; - } - if (*otrans == ',') { - otrans++; - break; - } - current[i++] = *otrans++; - if (i >= MAX_REALM_LN) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - } - current[i] = '\0'; - - added = (krb5_princ_realm(kdc_context, client)->length == strlen(realm) && - !strncmp(krb5_princ_realm(kdc_context, client)->data, realm, strlen(realm))) || - (krb5_princ_realm(kdc_context, server)->length == strlen(realm) && - !strncmp(krb5_princ_realm(kdc_context, server)->data, realm, strlen(realm))); - - while (current[0]) { - - /* figure out expanded form of current name */ - - clst = strlen(current) - 1; - if (current[0] == ' ') { - strncpy(exp, current+1, sizeof(exp) - 1); - exp[sizeof(exp) - 1] = '\0'; - } - else if ((current[0] == '/') && (prev[0] == '/')) { - strncpy(exp, prev, sizeof(exp) - 1); - exp[sizeof(exp) - 1] = '\0'; - if (strlen(exp) + strlen(current) + 1 >= MAX_REALM_LN) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - strncat(exp, current, sizeof(exp) - 1 - strlen(exp)); - } - else if (current[clst] == '.') { - strncpy(exp, current, sizeof(exp) - 1); - exp[sizeof(exp) - 1] = '\0'; - if (strlen(exp) + strlen(prev) + 1 >= MAX_REALM_LN) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - strncat(exp, prev, sizeof(exp) - 1 - strlen(exp)); - } - else { - strncpy(exp, current, sizeof(exp) - 1); - exp[sizeof(exp) - 1] = '\0'; - } - - /* read field into next */ - for (i = 0; *otrans != '\0';) { - if (*otrans == '\\') { - if (*(++otrans) == '\0') - break; - else - continue; - } - if (*otrans == ',') { - otrans++; - break; - } - next[i++] = *otrans++; - if (i >= MAX_REALM_LN) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - } - next[i] = '\0'; - nlst = i - 1; - - if (!strcmp(exp, realm)) added = TRUE; - - /* If we still have to insert the new realm */ - - if (!added) { - - /* Is the next field compressed? If not, and if the new */ - /* realm is a subrealm of the current realm, compress */ - /* the new realm, and insert immediately following the */ - /* current one. Note that we can not do this if the next*/ - /* field is already compressed since it would mess up */ - /* what has already been done. In most cases, this is */ - /* not a problem because the realm to be added will be a */ - /* subrealm of the next field too, and we will catch */ - /* it in a future iteration. */ - - /* Note that the second test here is an unsigned comparison, - so the first half (or a cast) is also required. */ - assert(nlst < 0 || nlst < (int)sizeof(next)); - if ((nlst < 0 || next[nlst] != '.') && - (next[0] != '/') && - (pl = subrealm(exp, realm))) { - added = TRUE; - current[sizeof(current) - 1] = '\0'; - if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - strncat(current, ",", sizeof(current) - 1 - strlen(current)); - if (pl > 0) { - strncat(current, realm, (unsigned) pl); - } - else { - strncat(current, realm+strlen(realm)+pl, (unsigned) (-pl)); - } - } - - /* Whether or not the next field is compressed, if the */ - /* realm to be added is a superrealm of the current realm,*/ - /* then the current realm can be compressed. First the */ - /* realm to be added must be compressed relative to the */ - /* previous realm (if possible), and then the current */ - /* realm compressed relative to the new realm. Note that */ - /* if the realm to be added is also a superrealm of the */ - /* previous realm, it would have been added earlier, and */ - /* we would not reach this step this time around. */ - - else if ((pl = subrealm(realm, exp))) { - added = TRUE; - current[0] = '\0'; - if ((pl1 = subrealm(prev,realm))) { - if (strlen(current) + (pl1>0?pl1:-pl1) + 1 >= MAX_REALM_LN) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - if (pl1 > 0) { - strncat(current, realm, (unsigned) pl1); - } - else { - strncat(current, realm+strlen(realm)+pl1, (unsigned) (-pl1)); - } - } - else { /* If not a subrealm */ - if ((realm[0] == '/') && prev[0]) { - if (strlen(current) + 2 >= MAX_REALM_LN) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - strncat(current, " ", sizeof(current) - 1 - strlen(current)); - current[sizeof(current) - 1] = '\0'; - } - if (strlen(current) + strlen(realm) + 1 >= MAX_REALM_LN) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - strncat(current, realm, sizeof(current) - 1 - strlen(current)); - current[sizeof(current) - 1] = '\0'; - } - if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - strncat(current,",", sizeof(current) - 1 - strlen(current)); - current[sizeof(current) - 1] = '\0'; - if (pl > 0) { - strncat(current, exp, (unsigned) pl); - } - else { - strncat(current, exp+strlen(exp)+pl, (unsigned)(-pl)); - } - } - } - - if (new_trans->length != 0) { - if (strlcat(trans, ",", bufsize) >= bufsize) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - } - if (strlcat(trans, current, bufsize) >= bufsize) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - new_trans->length = strlen(trans); - - strncpy(prev, exp, sizeof(prev) - 1); - prev[sizeof(prev) - 1] = '\0'; - strncpy(current, next, sizeof(current) - 1); - current[sizeof(current) - 1] = '\0'; - } - - if (!added) { - if (new_trans->length != 0) { - if (strlcat(trans, ",", bufsize) >= bufsize) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - } - if((realm[0] == '/') && trans[0]) { - if (strlcat(trans, " ", bufsize) >= bufsize) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - } - if (strlcat(trans, realm, bufsize) >= bufsize) { - retval = KRB5KRB_AP_ERR_ILL_CR_TKT; - goto fail; - } - new_trans->length = strlen(trans); - } - - retval = 0; -fail: - free(realm); - free(otrans_ptr); - return (retval); -} - /* Convert an API error code to a protocol error code. */ static int errcode_to_protocol(krb5_error_code code)