1 /* 2 * Copyright 2005 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 if (nelem == 0 ) 102 totalsize++; 103 104 /* 105 * Allocate space for the ascii string; if space has been 106 * provided, use it, realloc'ing it if necessary. 107 * 108 * We need only n-1 seperators for n components, but we need 109 * an extra byte for the NULL at the end. 110 */ 111 /*The realloc case seems to be bogus 112 * We never pass non-null name 113 */ 114 115 /* if (*name) { 116 if (*size < (totalsize)) { 117 *size = totalsize; 118 *name = realloc(*name, totalsize); 119 } 120 } else { 121 */ 122 123 *name = MALLOC(totalsize); 124 if (size) 125 *size = totalsize; 126 127 if (!*name) 128 return ENOMEM; 129 130 q = *name; 131 132 for (i = 0; i < (int) nelem; i++) { 133 cp = krb5_princ_component(context, principal, i)->data; 134 length = krb5_princ_component(context, principal, i)->length; 135 for (j=0; j < length; j++,cp++) { 136 switch (*cp) { 137 case COMPONENT_SEP: 138 case REALM_SEP: 139 case '\\': 140 *q++ = '\\'; 141 *q++ = *cp; 142 break; 143 case '\t': 144 *q++ = '\\'; 145 *q++ = 't'; 146 break; 147 case '\n': 148 *q++ = '\\'; 149 *q++ = 'n'; 150 break; 151 case '\b': 152 *q++ = '\\'; 153 *q++ = 'b'; 154 break; 155 case '\0': 156 *q++ = '\\'; 157 *q++ = '0'; 158 break; 159 default: 160 *q++ = *cp; 161 } 162 } 163 *q++ = COMPONENT_SEP; 164 } 165 166 if (i > 0) 167 q--; /* Back up last component separator */ 168 *q++ = REALM_SEP; 169 170 cp = krb5_princ_realm(context, principal)->data; 171 length = krb5_princ_realm(context, principal)->length; 172 for (j=0; j < length; j++,cp++) { 173 switch (*cp) { 174 case COMPONENT_SEP: 175 case REALM_SEP: 176 case '\\': 177 *q++ = '\\'; 178 *q++ = *cp; 179 break; 180 case '\t': 181 *q++ = '\\'; 182 *q++ = 't'; 183 break; 184 case '\n': 185 *q++ = '\\'; 186 *q++ = 'n'; 187 break; 188 case '\b': 189 *q++ = '\\'; 190 *q++ = 'b'; 191 break; 192 case '\0': 193 *q++ = '\\'; 194 *q++ = '0'; 195 break; 196 default: 197 *q++ = *cp; 198 } 199 } 200 *q++ = '\0'; 201 202 return 0; 203 } 204 205 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 206 krb5_unparse_name(context, principal, name) 207 krb5_context context; 208 krb5_const_principal principal; 209 register char **name; 210 { 211 *name = NULL; 212 return(krb5_unparse_name_ext(context, principal, name, NULL)); 213 } 214 215