diff options
Diffstat (limited to 'lib/krb5/transited.c')
| -rw-r--r-- | lib/krb5/transited.c | 219 |
1 files changed, 103 insertions, 116 deletions
diff --git a/lib/krb5/transited.c b/lib/krb5/transited.c index 9b67ecc04f26..5e21987bca91 100644 --- a/lib/krb5/transited.c +++ b/lib/krb5/transited.c @@ -1,40 +1,38 @@ /* - * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * 2. 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. + * 2. 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. * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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 "krb5_locl.h" -RCSID("$Id: transited.c 21745 2007-07-31 16:11:25Z lha $"); - /* this is an attempt at one of the most horrible `compression' schemes that has ever been invented; it's so amazingly brain-dead that words can not describe it, and all this just to save a few @@ -57,16 +55,15 @@ free_realms(struct tr_realm *r) r = r->next; free(p->realm); free(p); - } + } } static int make_path(krb5_context context, struct tr_realm *r, const char *from, const char *to) { - const char *p; - struct tr_realm *path = r->next; struct tr_realm *tmp; + const char *p; if(strlen(from) < strlen(to)){ const char *str; @@ -74,71 +71,65 @@ make_path(krb5_context context, struct tr_realm *r, from = to; to = str; } - + if(strcmp(from + strlen(from) - strlen(to), to) == 0){ p = from; while(1){ p = strchr(p, '.'); if(p == NULL) { - krb5_clear_error_string (context); + krb5_clear_error_message (context); return KRB5KDC_ERR_POLICY; } p++; if(strcmp(p, to) == 0) break; tmp = calloc(1, sizeof(*tmp)); - if(tmp == NULL){ - krb5_set_error_string (context, "malloc: out of memory"); - return ENOMEM; - } - tmp->next = path; - path = tmp; - path->realm = strdup(p); - if(path->realm == NULL){ - r->next = path; /* XXX */ - krb5_set_error_string (context, "malloc: out of memory"); - return ENOMEM;; + if(tmp == NULL) + return krb5_enomem(context); + tmp->next = r->next; + r->next = tmp; + tmp->realm = strdup(p); + if(tmp->realm == NULL){ + r->next = tmp->next; + free(tmp); + return krb5_enomem(context); } } }else if(strncmp(from, to, strlen(to)) == 0){ p = from + strlen(from); while(1){ while(p >= from && *p != '/') p--; - if(p == from) { - r->next = path; /* XXX */ + if(p == from) return KRB5KDC_ERR_POLICY; - } + if(strncmp(to, from, p - from) == 0) break; tmp = calloc(1, sizeof(*tmp)); - if(tmp == NULL){ - krb5_set_error_string (context, "malloc: out of memory"); - return ENOMEM; - } - tmp->next = path; - path = tmp; - path->realm = malloc(p - from + 1); - if(path->realm == NULL){ - r->next = path; /* XXX */ - krb5_set_error_string (context, "malloc: out of memory"); - return ENOMEM; + if(tmp == NULL) + return krb5_enomem(context); + tmp->next = r->next; + r->next = tmp; + tmp->realm = malloc(p - from + 1); + if(tmp->realm == NULL){ + r->next = tmp->next; + free(tmp); + return krb5_enomem(context); } - memcpy(path->realm, from, p - from); - path->realm[p - from] = '\0'; + memcpy(tmp->realm, from, p - from); + tmp->realm[p - from] = '\0'; p--; } } else { - krb5_clear_error_string (context); + krb5_clear_error_message (context); return KRB5KDC_ERR_POLICY; } - r->next = path; - + return 0; } static int make_paths(krb5_context context, - struct tr_realm *realms, const char *client_realm, + struct tr_realm *realms, const char *client_realm, const char *server_realm) { struct tr_realm *r; @@ -186,8 +177,7 @@ expand_realms(krb5_context context, tmp = realloc(r->realm, len); if(tmp == NULL){ free_realms(realms); - krb5_set_error_string (context, "malloc: out of memory"); - return ENOMEM; + return krb5_enomem(context); } r->realm = tmp; strlcat(r->realm, prev_realm, len); @@ -200,8 +190,7 @@ expand_realms(krb5_context context, tmp = malloc(len); if(tmp == NULL){ free_realms(realms); - krb5_set_error_string (context, "malloc: out of memory"); - return ENOMEM; + return krb5_enomem(context); } strlcpy(tmp, prev_realm, len); strlcat(tmp, r->realm, len); @@ -285,17 +274,14 @@ decode_realms(krb5_context context, } if(tr[i] == ','){ tmp = malloc(tr + i - start + 1); - if(tmp == NULL){ - krb5_set_error_string (context, "malloc: out of memory"); - return ENOMEM; - } + if(tmp == NULL) + return krb5_enomem(context); memcpy(tmp, start, tr + i - start); tmp[tr + i - start] = '\0'; r = make_realm(tmp); if(r == NULL){ free_realms(*realms); - krb5_set_error_string (context, "malloc: out of memory"); - return ENOMEM; + return krb5_enomem(context); } *realms = append_realm(*realms, r); start = tr + i + 1; @@ -304,32 +290,30 @@ decode_realms(krb5_context context, tmp = malloc(tr + i - start + 1); if(tmp == NULL){ free(*realms); - krb5_set_error_string (context, "malloc: out of memory"); - return ENOMEM; + return krb5_enomem(context); } memcpy(tmp, start, tr + i - start); tmp[tr + i - start] = '\0'; r = make_realm(tmp); if(r == NULL){ free_realms(*realms); - krb5_set_error_string (context, "malloc: out of memory"); - return ENOMEM; + return krb5_enomem(context); } *realms = append_realm(*realms, r); - + return 0; } -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_domain_x500_decode(krb5_context context, - krb5_data tr, char ***realms, int *num_realms, + krb5_data tr, char ***realms, unsigned int *num_realms, const char *client_realm, const char *server_realm) { struct tr_realm *r = NULL; struct tr_realm *p, **q; int ret; - + if(tr.length == 0) { *realms = NULL; *num_realms = 0; @@ -340,39 +324,37 @@ krb5_domain_x500_decode(krb5_context context, ret = decode_realms(context, tr.data, tr.length, &r); if(ret) return ret; - + /* apply prefix rule */ ret = expand_realms(context, r, client_realm); if(ret) return ret; - + ret = make_paths(context, r, client_realm, server_realm); if(ret) return ret; - + /* remove empty components and count realms */ - q = &r; *num_realms = 0; - for(p = r; p; ){ - if(p->realm[0] == '\0'){ + for(q = &r; *q; ){ + if((*q)->realm[0] == '\0'){ + p = *q; + *q = (*q)->next; free(p->realm); - *q = p->next; free(p); - p = *q; }else{ - q = &p->next; - p = p->next; + q = &(*q)->next; (*num_realms)++; } } - if (*num_realms < 0 || *num_realms + 1 > UINT_MAX/sizeof(**realms)) + if (*num_realms + 1 > UINT_MAX/sizeof(**realms)) return ERANGE; { char **R; R = malloc((*num_realms + 1) * sizeof(*R)); if (R == NULL) - return ENOMEM; + return krb5_enomem(context); *realms = R; while(r){ *R++ = r->realm; @@ -384,12 +366,13 @@ krb5_domain_x500_decode(krb5_context context, return 0; } -krb5_error_code KRB5_LIB_FUNCTION -krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding) +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_domain_x500_encode(char **realms, unsigned int num_realms, + krb5_data *encoding) { char *s = NULL; int len = 0; - int i; + unsigned int i; krb5_data_zero(encoding); if (num_realms == 0) return 0; @@ -404,7 +387,7 @@ krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding) return ENOMEM; *s = '\0'; for(i = 0; i < num_realms; i++){ - if(i && i < num_realms - 1) + if(i) strlcat(s, ",", len + 1); if(realms[i][0] == '/') strlcat(s, " ", len + 1); @@ -415,25 +398,25 @@ krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding) return 0; } -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_check_transited(krb5_context context, krb5_const_realm client_realm, krb5_const_realm server_realm, krb5_realm *realms, - int num_realms, + unsigned int num_realms, int *bad_realm) { char **tr_realms; char **p; - int i; + size_t i; if(num_realms == 0) return 0; - - tr_realms = krb5_config_get_strings(context, NULL, - "capaths", - client_realm, - server_realm, + + tr_realms = krb5_config_get_strings(context, NULL, + "capaths", + client_realm, + server_realm, NULL); for(i = 0; i < num_realms; i++) { for(p = tr_realms; p && *p; p++) { @@ -442,8 +425,10 @@ krb5_check_transited(krb5_context context, } if(p == NULL || *p == NULL) { krb5_config_free_strings(tr_realms); - krb5_set_error_string (context, "no transit through realm %s", - realms[i]); + krb5_set_error_message (context, KRB5KRB_AP_ERR_ILL_CR_TKT, + N_("no transit allowed " + "through realm %s", ""), + realms[i]); if(bad_realm) *bad_realm = i; return KRB5KRB_AP_ERR_ILL_CR_TKT; @@ -453,17 +438,17 @@ krb5_check_transited(krb5_context context, return 0; } -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_check_transited_realms(krb5_context context, - const char *const *realms, - int num_realms, + const char *const *realms, + unsigned int num_realms, int *bad_realm) { - int i; + size_t i; int ret = 0; - char **bad_realms = krb5_config_get_strings(context, NULL, - "libdefaults", - "transited_realms_reject", + char **bad_realms = krb5_config_get_strings(context, NULL, + "libdefaults", + "transited_realms_reject", NULL); if(bad_realms == NULL) return 0; @@ -472,9 +457,11 @@ krb5_check_transited_realms(krb5_context context, char **p; for(p = bad_realms; *p; p++) if(strcmp(*p, realms[i]) == 0) { - krb5_set_error_string (context, "no transit through realm %s", - *p); ret = KRB5KRB_AP_ERR_ILL_CR_TKT; + krb5_set_error_message (context, ret, + N_("no transit allowed " + "through realm %s", ""), + *p); if(bad_realm) *bad_realm = i; break; |
