krb5 commit: Move add_to_transited to a separate file
Tom Yu
tlyu at MIT.EDU
Mon Oct 15 20:27:43 EDT 2012
https://github.com/krb5/krb5/commit/b57463a2e6e6a1ad047fafc54793c98ccf1c507b
commit b57463a2e6e6a1ad047fafc54793c98ccf1c507b
Author: Tom Yu <tlyu at mit.edu>
Date: Wed Sep 12 17:19:24 2012 -0400
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.
src/kdc/Makefile.in | 10 +-
src/kdc/kdc_transit.c | 415 +++++++++++++++++++++++++++++++++++++++++++++++++
src/kdc/kdc_util.c | 380 --------------------------------------------
3 files changed, 420 insertions(+), 385 deletions(-)
diff --git a/src/kdc/Makefile.in b/src/kdc/Makefile.in
index 497c6f8..52e65d6 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 0000000..88b4616
--- /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 <stddef.h>
+
+#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 773d8cf..371072b 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)
More information about the cvs-krb5
mailing list