aboutsummaryrefslogtreecommitdiff
path: root/src/lib/krb5/krb/unparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/krb5/krb/unparse.c')
-rw-r--r--src/lib/krb5/krb/unparse.c153
1 files changed, 108 insertions, 45 deletions
diff --git a/src/lib/krb5/krb/unparse.c b/src/lib/krb5/krb/unparse.c
index 36fd9c2..d16a2c5 100644
--- a/src/lib/krb5/krb/unparse.c
+++ b/src/lib/krb5/krb/unparse.c
@@ -8,6 +8,10 @@
* <krb5/copyright.h>.
*
* krb5_unparse_name() routine
+ *
+ * Rewritten by Theodore Ts'o to propoerly unparse principal names
+ * which have the component or realm separator as part of one of their
+ * components.
*/
#if !defined(lint) && !defined(SABER)
@@ -15,68 +19,127 @@ static char rcsid_unparse_c[] =
"$Id$";
#endif /* !lint & !SABER */
+#include <stdio.h>
#include <krb5/copyright.h>
-
#include <krb5/krb5.h>
#include <krb5/ext-proto.h>
/*
- converts the multi-part
- principal format used in the protocols to a single-string representation
- of the name.
-
- the name returned is in allocated storage and should be freed by the caller
- when finished.
-
- Conventions: / is used to separate components; @ is used to separate
- the realm from the rest of the name. If any component besides the realm has
- a / or @ in it, an error is returned.
-
- returns system errors XXX
+ * converts the multi-part principal format used in the protocols to a
+ * single-string representation of the name.
+ *
+ * The name returned is in allocated storage and should be freed by
+ * the caller when finished.
+ *
+ * Conventions: / is used to separate components; @ is used to
+ * separate the realm from the rest of the name. If '/', '@', or '\0'
+ * appear in any the component, they will be representing using
+ * backslash encoding. ("\/", "\@", or '\0', respectively)
+ *
+ * returns system errors XXX
*/
#define REALM_SEP '@'
#define COMPONENT_SEP '/'
-#define REALM_SEP_STRING "@"
-#define COMPONENT_SEP_STRING "/"
krb5_error_code
-krb5_unparse_name(principal, name)
+krb5_unparse_name_ext(principal, name, size)
const krb5_principal principal;
register char **name;
+int *size;
{
- register char *cp;
- register int i;
- int totalsize = 0;
-
- if (!principal[0] || !principal[1])
- return KRB5_PARSE_MALFORMED;
- /* check for invalid elements of components; don't need to check
- realm, which is first component */
- for (i = 1; principal[i]; i++) {
- for (cp = principal[i]->data;
- cp < principal[i]->data + principal[i]->length; cp++)
- if (*cp == REALM_SEP || *cp == COMPONENT_SEP)
- return KRB5_PARSE_ILLCHAR;
- totalsize += principal[i]->length + 1; /* + 1 for separator */
- }
- totalsize += principal[0]->length; /* no +1 since we need only n-1 seps
- for n components */
-
- *name = malloc(totalsize+1); /* room for null */
- if (!*name)
- return ENOMEM;
+ register char *cp, *q;
+ register int i,j;
+ register int totalsize = 0;
+ int length;
- (void) bzero(*name, totalsize+1);
+ if (!principal[0] || !principal[1])
+ return KRB5_PARSE_MALFORMED;
+ for (i = 0; principal[i]; i++) {
+ cp = principal[i]->data;
+ length = principal[i]->length;
+ for (j=0; j < length; j++,cp++)
+ if (*cp == REALM_SEP || *cp == COMPONENT_SEP ||
+ *cp == '\0' || *cp == '\\' || *cp == '\t')
+ totalsize += 2;
+ else
+ totalsize++;
+ totalsize++; /* This is for the separator */
+ }
- for (i = 1; principal[i]; i++) {
- strncat(*name, principal[i]->data, principal[i]->length);
- if (principal[i+1]) /* don't append sep to last elt */
- strcat(*name, COMPONENT_SEP_STRING);
- }
+ /*
+ * we need only n-1 seps for n components, but we need an
+ * extra byte for the NULL at the end
+ */
+ if (*name) {
+ if (*size < (totalsize)) {
+ *size = totalsize;
+ *name = realloc(*name, totalsize);
+ }
+ } else {
+ *name = malloc(totalsize); /* room for null */
+ *size = totalsize;
+ }
+
+ if (!*name)
+ return ENOMEM;
- strcat(*name, REALM_SEP_STRING);
- strncat(*name, principal[0]->data, principal[0]->length);
+ q = *name;
+
+ for (i = 1; principal[i]; i++) {
+ cp = principal[i]->data;
+ length = principal[i]->length;
+ for (j=0; j < length; j++,cp++) {
+ switch (*cp) {
+ case COMPONENT_SEP:
+ case REALM_SEP:
+ case '\t':
+ case '\\':
+ *q++ = '\\';
+ *q++ = *cp;
+ break;
+ case '\0':
+ *q++ = '\\';
+ *q++ = '0';
+ break;
+ default:
+ *q++ = *cp;
+ }
+ }
+ *q++ = COMPONENT_SEP;
+ }
+ q--; /* Back up last component separator */
+ *q++ = REALM_SEP;
+
+ cp = principal[0]->data;
+ length = principal[0]->length;
+ for (j=0; j < length; j++,cp++) {
+ switch (*cp) {
+ case COMPONENT_SEP:
+ case REALM_SEP:
+ *q++ = '\\';
+ *q++ = *cp;
+ break;
+ case '\0':
+ *q++ = '\\';
+ *q++ = '0';
+ break;
+ default:
+ *q++ = *cp;
+ }
+ }
+ *q++ = '\0';
+
return 0;
}
+
+krb5_error_code
+krb5_unparse_name(principal, name)
+const krb5_principal principal;
+register char **name;
+{
+ return(krb5_unparse_name_ext(principal, name, NULL));
+}
+
+