diff options
| author | Alexandra Ellwood <lxs@mit.edu> | 2008-10-24 19:46:41 +0000 |
|---|---|---|
| committer | Alexandra Ellwood <lxs@mit.edu> | 2008-10-24 19:46:41 +0000 |
| commit | 4d901a092a69a69be251131174166fc661d13633 (patch) | |
| tree | dc1227f213605bc27561acdf4005b74df65f7b0b /src/lib | |
| parent | 9d3a0fa806297b18967f2108c637e65c6904987c (diff) | |
| download | krb5-4d901a092a69a69be251131174166fc661d13633.tar.gz krb5-4d901a092a69a69be251131174166fc661d13633.tar.xz krb5-4d901a092a69a69be251131174166fc661d13633.zip | |
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
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/krb5/krb/bld_princ.c | 203 | ||||
| -rw-r--r-- | src/lib/krb5/libkrb5.exports | 1 |
2 files changed, 140 insertions, 64 deletions
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 <stdarg.h> #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 |
