1 /* 2 * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 /* 8 * lib/krb5/krb/unparse.c 9 * 10 * Copyright 1990 by the Massachusetts Institute of Technology. 11 * All Rights Reserved. 12 * 13 * Export of this software from the United States of America may 14 * require a specific license from the United States Government. 15 * It is the responsibility of any person or organization contemplating 16 * export to obtain such a license before exporting. 17 * 18 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 19 * distribute this software and its documentation for any purpose and 20 * without fee is hereby granted, provided that the above copyright 21 * notice appear in all copies and that both that copyright notice and 22 * this permission notice appear in supporting documentation, and that 23 * the name of M.I.T. not be used in advertising or publicity pertaining 24 * to distribution of the software without specific, written prior 25 * permission. M.I.T. makes no representations about the suitability of 26 * this software for any purpose. It is provided "as is" without express 27 * or implied warranty. 28 * 29 * 30 * krb5_unparse_name() routine 31 * 32 * Rewritten by Theodore Ts'o to propoerly unparse principal names 33 * which have the component or realm separator as part of one of their 34 * components. 35 */ 36 37 38 #include <k5-int.h> 39 #ifndef _KERNEL 40 #include <stdio.h> 41 #endif 42 43 /* 44 * converts the multi-part principal format used in the protocols to a 45 * single-string representation of the name. 46 * 47 * The name returned is in allocated storage and should be freed by 48 * the caller when finished. 49 * 50 * Conventions: / is used to separate components; @ is used to 51 * separate the realm from the rest of the name. If '/', '@', or '\0' 52 * appear in any the component, they will be representing using 53 * backslash encoding. ("\/", "\@", or '\0', respectively) 54 * 55 * returns error 56 * KRB_PARSE_MALFORMED principal is invalid (does not contain 57 * at least 2 components) 58 * also returns system errors 59 * ENOMEM unable to allocate memory for string 60 */ 61 62 #define REALM_SEP '@' 63 #define COMPONENT_SEP '/' 64 65 /*ARGSUSED*/ 66 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 67 krb5_unparse_name_ext(context, principal, name, size) 68 krb5_context context; 69 krb5_const_principal principal; 70 register char FAR * FAR *name; 71 int FAR *size; 72 { 73 register char *cp, *q; 74 register int i,j; 75 int length; 76 krb5_int32 nelem; 77 register int totalsize = 0; 78 79 cp = krb5_princ_realm(context, principal)->data; 80 length = krb5_princ_realm(context, principal)->length; 81 totalsize += length; 82 for (j = 0; j < length; j++,cp++) 83 if (*cp == REALM_SEP || *cp == COMPONENT_SEP || 84 *cp == '\0' || *cp == '\\' || *cp == '\t' || 85 *cp == '\n' || *cp == '\b') 86 totalsize++; 87 totalsize++; /* This is for the separator */ 88 89 nelem = krb5_princ_size(context, principal); 90 for (i = 0; i < (int) nelem; i++) { 91 cp = krb5_princ_component(context, principal, i)->data; 92 length = krb5_princ_component(context, principal, i)->length; 93 totalsize += length; 94 for (j=0; j < length; j++,cp++) 95 if (*cp == REALM_SEP || *cp == COMPONENT_SEP || 96 *cp == '\0' || *cp == '\\' || *cp == '\t' || 97 *cp == '\n' || *cp == '\b') 98 totalsize++; 99 totalsize++; /* This is for the separator */ 100 } 101 102 /* 103 * Allocate space for the ascii string; if space has been 104 * provided, use it, realloc'ing it if necessary. 105 * 106 * We need only n-1 seperators for n components, but we need 107 * an extra byte for the NULL at the end. 108 */ 109 /*The realloc case seems to be bogus 110 * We never pass non-null name 111 */ 112 113 /* if (*name) { 114 if (*size < (totalsize)) { 115 *size = totalsize; 116 *name = realloc(*name, totalsize); 117 } 118 } else { 119 */ 120 121 *name = MALLOC(totalsize); 122 if (size) 123 *size = totalsize; 124 125 if (!*name) 126 return ENOMEM; 127 128 q = *name; 129 130 for (i = 0; i < (int) nelem; i++) { 131 cp = krb5_princ_component(context, principal, i)->data; 132 length = krb5_princ_component(context, principal, i)->length; 133 for (j=0; j < length; j++,cp++) { 134 switch (*cp) { 135 case COMPONENT_SEP: 136 case REALM_SEP: 137 case '\\': 138 *q++ = '\\'; 139 *q++ = *cp; 140 break; 141 case '\t': 142 *q++ = '\\'; 143 *q++ = 't'; 144 break; 145 case '\n': 146 *q++ = '\\'; 147 *q++ = 'n'; 148 break; 149 case '\b': 150 *q++ = '\\'; 151 *q++ = 'b'; 152 break; 153 case '\0': 154 *q++ = '\\'; 155 *q++ = '0'; 156 break; 157 default: 158 *q++ = *cp; 159 } 160 } 161 *q++ = COMPONENT_SEP; 162 } 163 164 if (i > 0) 165 q--; /* Back up last component separator */ 166 *q++ = REALM_SEP; 167 168 cp = krb5_princ_realm(context, principal)->data; 169 length = krb5_princ_realm(context, principal)->length; 170 for (j=0; j < length; j++,cp++) { 171 switch (*cp) { 172 case COMPONENT_SEP: 173 case REALM_SEP: 174 case '\\': 175 *q++ = '\\'; 176 *q++ = *cp; 177 break; 178 case '\t': 179 *q++ = '\\'; 180 *q++ = 't'; 181 break; 182 case '\n': 183 *q++ = '\\'; 184 *q++ = 'n'; 185 break; 186 case '\b': 187 *q++ = '\\'; 188 *q++ = 'b'; 189 break; 190 case '\0': 191 *q++ = '\\'; 192 *q++ = '0'; 193 break; 194 default: 195 *q++ = *cp; 196 } 197 } 198 *q++ = '\0'; 199 200 return 0; 201 } 202 203 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 204 krb5_unparse_name(context, principal, name) 205 krb5_context context; 206 krb5_const_principal principal; 207 register char **name; 208 { 209 *name = NULL; 210 return(krb5_unparse_name_ext(context, principal, name, NULL)); 211 } 212 213