From 4d901a092a69a69be251131174166fc661d13633 Mon Sep 17 00:00:00 2001 From: Alexandra Ellwood Date: Fri, 24 Oct 2008 19:46:41 +0000 Subject: [PATCH] krb5_build_principal_va does not allocate krb5_principal krb5_build_principal_va does not allocate the outer krb5_principal, making it useless for generating krb5_principals which can be freed with krb5_free_principal. Added krb5_build_principal_alloc_va which allocates the krb5_principal. Added krb5int_build_principal_alloc_va which is used by KIM to avoid code duplication. KIM's kim_identity_create_from_components takes the first component as an argument because principals with no components cannot be represented with the KIM UI. Modified KIM to use this new API. ticket: new git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20918 dc483132-0cff-0310-8789-dd5450dbe970 --- src/include/k5-int.h | 9 ++ src/include/krb5/krb5.hin | 8 +- src/kim/lib/kim_identity.c | 62 ++--------- src/lib/krb5/krb/bld_princ.c | 203 ++++++++++++++++++++++++----------- src/lib/krb5/libkrb5.exports | 1 + 5 files changed, 166 insertions(+), 117 deletions(-) diff --git a/src/include/k5-int.h b/src/include/k5-int.h index f05adecf3..cbc810e77 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -2518,6 +2518,15 @@ void KRB5_CALLCONV krb5_realm_iterator_free void KRB5_CALLCONV krb5_free_realm_string (krb5_context context, char *str); +/* Internal principal function used by KIM to avoid code duplication */ +krb5_error_code KRB5_CALLCONV +krb5int_build_principal_alloc_va(krb5_context context, + krb5_principal *princ, + unsigned int rlen, + const char *realm, + const char *first, + va_list ap); + /* Some data comparison and conversion functions. */ #if 0 static inline int data_cmp(krb5_data d1, krb5_data d2) diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin index 82e52ab52..62fd90df4 100644 --- a/src/include/krb5/krb5.hin +++ b/src/include/krb5/krb5.hin @@ -1599,9 +1599,15 @@ krb5_error_code KRB5_CALLCONV_C krb5_build_principal __attribute__ ((sentinel)) #endif ; -krb5_error_code KRB5_CALLCONV krb5_build_principal_va +#if KRB5_DEPRECATED +KRB5_ATTR_DEPRECATED krb5_error_code KRB5_CALLCONV krb5_build_principal_va (krb5_context, krb5_principal, unsigned int, const char *, va_list); +#endif + +/* Version of krb5_build_principal_va which allocates krb5_principal_data */ +krb5_error_code KRB5_CALLCONV krb5_build_principal_alloc_va + (krb5_context, krb5_principal *, unsigned int, const char *, va_list); krb5_error_code KRB5_CALLCONV krb5_425_conv_principal (krb5_context, diff --git a/src/kim/lib/kim_identity.c b/src/kim/lib/kim_identity.c index 834b8d614..6592d09c8 100644 --- a/src/kim/lib/kim_identity.c +++ b/src/kim/lib/kim_identity.c @@ -24,8 +24,8 @@ * or implied warranty. */ +#include "k5-int.h" #include -#include #include "kim_private.h" /* ------------------------------------------------------------------------ */ @@ -110,7 +110,6 @@ kim_error kim_identity_create_from_components (kim_identity *out_identity, { kim_error err = KIM_NO_ERROR; kim_identity identity = NULL; - krb5_principal_data principal_data; /* allocated by KIM so can't be returned */ if (!err && !out_identity ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && !in_realm ) { err = check_error (KIM_NULL_PARAMETER_ERR); } @@ -126,64 +125,23 @@ kim_error kim_identity_create_from_components (kim_identity *out_identity, if (!err) { va_list args; - kim_count component_count = 1; - + va_start (args, in_1st_component); - while (va_arg (args, kim_string)) { component_count++; } + err = krb5_error (identity->context, + krb5int_build_principal_alloc_va (identity->context, + &identity->principal, + strlen(in_realm), + in_realm, + in_1st_component, + args)); va_end (args); - - principal_data.length = component_count; - principal_data.data = (krb5_data *) malloc (component_count * sizeof (krb5_data)); - if (!principal_data.data) { err = KIM_OUT_OF_MEMORY_ERR; } } - - if (!err) { - va_list args; - krb5_int32 i; - - krb5_princ_set_realm_length (context, &principal_data, strlen (in_realm)); - krb5_princ_set_realm_data (context, &principal_data, (char *) in_realm); - - va_start (args, in_1st_component); - for (i = 0; !err && (i < principal_data.length); i++) { - kim_string component = NULL; - if (i == 0) { - err = kim_string_copy (&component, in_1st_component); - } else { - err = kim_string_copy (&component, va_arg (args, kim_string)); - } - - if (!err) { - principal_data.data[i].data = (char *) component; - principal_data.data[i].length = strlen (component); - } - } - va_end (args); - } - - if (!err) { - /* make a copy that has actually been allocated by the krb5 - * library so krb5_free_principal can be called on it */ - err = krb5_error (identity->context, - krb5_copy_principal (identity->context, - &principal_data, - &identity->principal)); - } - + if (!err) { *out_identity = identity; identity = NULL; } - if (principal_data.data) { - krb5_int32 i; - - for (i = 0; i < principal_data.length; i++) { - kim_string component = principal_data.data[i].data; - kim_string_free (&component); - } - free (principal_data.data); - } kim_identity_free (&identity); return check_error (err); diff --git a/src/lib/krb5/krb/bld_princ.c b/src/lib/krb5/krb/bld_princ.c index 03bf1267e..1b9a89447 100644 --- a/src/lib/krb5/krb/bld_princ.c +++ b/src/lib/krb5/krb/bld_princ.c @@ -30,84 +30,159 @@ #include #include "k5-int.h" -krb5_error_code -KRB5_CALLCONV -krb5_build_principal_va(krb5_context context, krb5_principal princ, unsigned int rlen, const char *realm, va_list ap) +/* Takes first component as argument for KIM API, + * which does not allow realms with zero components */ +static krb5_error_code +krb5int_build_principal_va(krb5_context context, + krb5_principal princ, + unsigned int rlen, + const char *realm, + const char *first, + va_list ap) { - register int i, count = 0; - register char *next; - char *tmpdata; - krb5_data *data; - - /* guess at an initial sufficent count of 2 pieces */ - count = 2; - - /* get space for array and realm, and insert realm */ - data = (krb5_data *) malloc(sizeof(krb5_data) * count); - if (data == 0) - return ENOMEM; - krb5_princ_set_realm_length(context, princ, rlen); - tmpdata = malloc(rlen); - if (!tmpdata) { - free (data); - return ENOMEM; + krb5_error_code retval = 0; + char *r = NULL; + krb5_data *data = NULL; + krb5_int32 count = 0; + krb5_int32 size = 2; /* initial guess at needed space */ + char *component = NULL; + + data = malloc(size * sizeof(krb5_data)); + if (!data) { retval = ENOMEM; } + + if (!retval) { + r = strdup(realm); + if (!r) { retval = ENOMEM; } + } + + if (!retval && first) { + data[0].length = strlen(first); + data[0].data = strdup(first); + if (!data[0].data) { retval = ENOMEM; } + count++; + + /* ap is only valid if first is non-NULL */ + while (!retval && (component = va_arg(ap, char *))) { + if (count == size) { + krb5_data *new_data = NULL; + + size *= 2; + new_data = realloc ((char *) data, sizeof(krb5_data) * size); + if (new_data) { + data = new_data; + } else { + retval = ENOMEM; + } + } + + if (!retval) { + data[count].length = strlen(component); + data[count].data = strdup(component); + if (!data[count].data) { retval = ENOMEM; } + count++; + } + } + } + + if (!retval) { + princ->type = KRB5_NT_UNKNOWN; + princ->magic = KV5M_PRINCIPAL; + krb5_princ_set_realm_data(context, princ, r); + krb5_princ_set_realm_length(context, princ, strlen(r)); + princ->data = data; + princ->length = count; + r = NULL; /* take ownership */ + data = NULL; /* take ownership */ + } + + if (data) { + while (--count >= 0) { + krb5_xfree(data[count].data); + } + krb5_xfree(data); } - krb5_princ_set_realm_data(context, princ, tmpdata); - memcpy(tmpdata, realm, rlen); + krb5_xfree(r); + + return retval; +} - /* process rest of components */ +krb5_error_code KRB5_CALLCONV +krb5_build_principal_va(krb5_context context, + krb5_principal princ, + unsigned int rlen, + const char *realm, + va_list ap) +{ + char *first = va_arg(ap, char *); + + return krb5int_build_principal_va(context, princ, rlen, realm, first, ap); +} - for (i = 0, next = va_arg(ap, char *); - next; - next = va_arg(ap, char *), i++) { - if (i == count) { - /* not big enough. realloc the array */ - krb5_data *p_tmp; - p_tmp = (krb5_data *) realloc((char *)data, - sizeof(krb5_data)*(count*2)); - if (!p_tmp) { - free_out: - while (--i >= 0) - krb5_xfree(data[i].data); - krb5_xfree(data); - krb5_xfree(tmpdata); - return (ENOMEM); - } - count *= 2; - data = p_tmp; - } +/* Takes first component as argument for KIM API, + * which does not allow realms with zero components */ +krb5_error_code KRB5_CALLCONV +krb5int_build_principal_alloc_va(krb5_context context, + krb5_principal *princ, + unsigned int rlen, + const char *realm, + const char *first, + va_list ap) +{ + krb5_error_code retval = 0; + + krb5_principal p = malloc(sizeof(krb5_principal_data)); + if (!p) { retval = ENOMEM; } + + if (!retval) { + retval = krb5int_build_principal_va(context, p, rlen, realm, first, ap); + } + + if (!retval) { + *princ = p; + } else { + krb5_xfree(p); + } + + return retval; +} - data[i].length = strlen(next); - data[i].data = strdup(next); - if (!data[i].data) - goto free_out; +krb5_error_code KRB5_CALLCONV +krb5_build_principal_alloc_va(krb5_context context, + krb5_principal *princ, + unsigned int rlen, + const char *realm, + va_list ap) +{ + krb5_error_code retval = 0; + + krb5_principal p = malloc(sizeof(krb5_principal_data)); + if (!p) { retval = ENOMEM; } + + if (!retval) { + retval = krb5_build_principal_va(context, p, rlen, realm, ap); + } + + if (!retval) { + *princ = p; + } else { + krb5_xfree(p); } - princ->data = data; - princ->length = i; - princ->type = KRB5_NT_UNKNOWN; - princ->magic = KV5M_PRINCIPAL; - return 0; + + return retval; } krb5_error_code KRB5_CALLCONV_C -krb5_build_principal(krb5_context context, krb5_principal * princ, +krb5_build_principal(krb5_context context, + krb5_principal * princ, unsigned int rlen, const char * realm, ...) { + krb5_error_code retval = 0; va_list ap; - krb5_error_code retval; - krb5_principal pr_ret = (krb5_principal)malloc(sizeof(krb5_principal_data)); - - if (!pr_ret) - return ENOMEM; - + va_start(ap, realm); - retval = krb5_build_principal_va(context, pr_ret, rlen, realm, ap); + retval = krb5_build_principal_alloc_va(context, princ, rlen, realm, ap); va_end(ap); - if (retval == 0) - *princ = pr_ret; - else - krb5_xfree(pr_ret); - + return retval; } diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports index 2d503b851..9b12be985 100644 --- a/src/lib/krb5/libkrb5.exports +++ b/src/lib/krb5/libkrb5.exports @@ -120,6 +120,7 @@ krb5_auth_to_rep krb5_build_principal krb5_build_principal_ext krb5_build_principal_va +krb5_build_principal_alloc_va krb5_cc_close krb5_cc_copy_creds krb5_cc_default -- 2.26.2