diff options
Diffstat (limited to 'src/lib/krb5/krb/unparse.c')
-rw-r--r-- | src/lib/krb5/krb/unparse.c | 133 |
1 files changed, 106 insertions, 27 deletions
diff --git a/src/lib/krb5/krb/unparse.c b/src/lib/krb5/krb/unparse.c index e24dccf..ec0976f 100644 --- a/src/lib/krb5/krb/unparse.c +++ b/src/lib/krb5/krb/unparse.c @@ -1,7 +1,7 @@ /* * lib/krb5/krb/unparse.c * - * Copyright 1990 by the Massachusetts Institute of Technology. + * Copyright 1990, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -58,33 +58,52 @@ #define COMPONENT_SEP '/' static int -component_length_quoted(const krb5_data *src) +component_length_quoted(const krb5_data *src, int flags) { const char *cp = src->data; int length = src->length; int j; int size = length; - for (j = 0; j < length; j++,cp++) - if (*cp == REALM_SEP || *cp == COMPONENT_SEP || - *cp == '\0' || *cp == '\\' || *cp == '\t' || - *cp == '\n' || *cp == '\b') - size++; + if ((flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) == 0) { + int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) && + !(flags & KRB5_PRINCIPAL_UNPARSE_SHORT); + + for (j = 0; j < length; j++,cp++) + if ((!no_realm && *cp == REALM_SEP) || + *cp == COMPONENT_SEP || + *cp == '\0' || *cp == '\\' || *cp == '\t' || + *cp == '\n' || *cp == '\b') + size++; + } + return size; } static int -copy_component_quoting(char *dest, const krb5_data *src) +copy_component_quoting(char *dest, const krb5_data *src, int flags) { int j; const char *cp = src->data; char *q = dest; int length = src->length; + if (flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) { + memcpy(dest, src->data, src->length); + return src->length; + } + for (j=0; j < length; j++,cp++) { + int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) && + !(flags & KRB5_PRINCIPAL_UNPARSE_SHORT); + switch (*cp) { - case COMPONENT_SEP: case REALM_SEP: + if (no_realm) { + *q++ = *cp; + break; + } + case COMPONENT_SEP: case '\\': *q++ = '\\'; *q++ = *cp; @@ -101,6 +120,13 @@ copy_component_quoting(char *dest, const krb5_data *src) *q++ = '\\'; *q++ = 'b'; break; +#if 0 + /* Heimdal escapes spaces in principal names upon unparsing */ + case ' ': + *q++ = '\\'; + *q++ = ' '; + break; +#endif case '\0': *q++ = '\\'; *q++ = '0'; @@ -112,27 +138,47 @@ copy_component_quoting(char *dest, const krb5_data *src) return q - dest; } -krb5_error_code KRB5_CALLCONV -krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, - char **name, unsigned int *size) +static krb5_error_code +k5_unparse_name(krb5_context context, krb5_const_principal principal, + int flags, char **name, unsigned int *size) { char *cp, *q; int i; int length; krb5_int32 nelem; unsigned int totalsize = 0; + char *default_realm = NULL; + krb5_error_code ret = 0; if (!principal || !name) return KRB5_PARSE_MALFORMED; - totalsize += component_length_quoted(krb5_princ_realm(context, - principal)); - totalsize++; /* This is for the separator */ + if (flags & KRB5_PRINCIPAL_UNPARSE_SHORT) { + /* omit realm if local realm */ + krb5_principal_data p; + + ret = krb5_get_default_realm(context, &default_realm); + if (ret != 0) + goto cleanup; + + krb5_princ_realm(context, &p)->length = strlen(default_realm); + krb5_princ_realm(context, &p)->data = default_realm; + + if (krb5_realm_compare(context, &p, principal)) + flags |= KRB5_PRINCIPAL_UNPARSE_NO_REALM; + } + + if ((flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) == 0) { + totalsize += component_length_quoted(krb5_princ_realm(context, + principal), + flags); + totalsize++; /* This is for the separator */ + } nelem = krb5_princ_size(context, principal); for (i = 0; i < (int) nelem; i++) { cp = krb5_princ_component(context, principal, i)->data; - totalsize += component_length_quoted(krb5_princ_component(context, principal, i)); + totalsize += component_length_quoted(krb5_princ_component(context, principal, i), flags); totalsize++; /* This is for the separator */ } if (nelem == 0) @@ -143,7 +189,7 @@ krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, * provided, use it, realloc'ing it if necessary. * * We need only n-1 seperators for n components, but we need - * an extra byte for the NULL at the end. + * an extra byte for the NUL at the end. */ if (size) { if (*name && (*size < totalsize)) { @@ -156,8 +202,10 @@ krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, *name = malloc(totalsize); } - if (!*name) - return ENOMEM; + if (!*name) { + ret = ENOMEM; + goto cleanup; + } q = *name; @@ -167,24 +215,55 @@ krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, q += copy_component_quoting(q, krb5_princ_component(context, principal, - i)); + i), + flags); *q++ = COMPONENT_SEP; } if (i > 0) q--; /* Back up last component separator */ - *q++ = REALM_SEP; - q += copy_component_quoting(q, krb5_princ_realm(context, principal)); + if ((flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) == 0) { + *q++ = REALM_SEP; + q += copy_component_quoting(q, krb5_princ_realm(context, principal), flags); + } *q++ = '\0'; - - return 0; + +cleanup: + if (default_realm != NULL) + krb5_free_default_realm(context, default_realm); + + return ret; } krb5_error_code KRB5_CALLCONV krb5_unparse_name(krb5_context context, krb5_const_principal principal, register char **name) { - if (name) /* name == NULL will return error from _ext */ - *name = NULL; - return(krb5_unparse_name_ext(context, principal, name, NULL)); + if (name != NULL) /* name == NULL will return error from _ext */ + *name = NULL; + + return k5_unparse_name(context, principal, 0, name, NULL); +} + +krb5_error_code KRB5_CALLCONV +krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, + char **name, unsigned int *size) +{ + return k5_unparse_name(context, principal, 0, name, size); +} + +krb5_error_code KRB5_CALLCONV +krb5_unparse_name_flags(krb5_context context, krb5_const_principal principal, + int flags, char **name) +{ + if (name != NULL) + *name = NULL; + return k5_unparse_name(context, principal, flags, name, NULL); +} + +krb5_error_code KRB5_CALLCONV +krb5_unparse_name_flags_ext(krb5_context context, krb5_const_principal principal, + int flags, char **name, unsigned int *size) +{ + return k5_unparse_name(context, principal, flags, name, size); } |