17c478bd9Sstevel@tonic-gate /*
2ba7b222eSGlenn Barry  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate  * lib/krb5/krb/parse.c
87c478bd9Sstevel@tonic-gate  *
9ba7b222eSGlenn Barry  * Copyright 1990,1991,2008 by the Massachusetts Institute of Technology.
107c478bd9Sstevel@tonic-gate  * All Rights Reserved.
117c478bd9Sstevel@tonic-gate  *
127c478bd9Sstevel@tonic-gate  * Export of this software from the United States of America may
137c478bd9Sstevel@tonic-gate  *   require a specific license from the United States Government.
147c478bd9Sstevel@tonic-gate  *   It is the responsibility of any person or organization contemplating
157c478bd9Sstevel@tonic-gate  *   export to obtain such a license before exporting.
16*55fea89dSDan Cross  *
177c478bd9Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
187c478bd9Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
197c478bd9Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
207c478bd9Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
217c478bd9Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
227c478bd9Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
237c478bd9Sstevel@tonic-gate  * to distribution of the software without specific, written prior
247c478bd9Sstevel@tonic-gate  * permission.  Furthermore if you modify this software you must label
257c478bd9Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
267c478bd9Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
277c478bd9Sstevel@tonic-gate  * M.I.T. makes no representations about the suitability of
287c478bd9Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
297c478bd9Sstevel@tonic-gate  * or implied warranty.
30*55fea89dSDan Cross  *
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  * krb5_parse_name() routine.
337c478bd9Sstevel@tonic-gate  *
347c478bd9Sstevel@tonic-gate  * Rewritten by Theodore Ts'o to properly handle arbitrary quoted
357c478bd9Sstevel@tonic-gate  * characters in the principal name.
367c478bd9Sstevel@tonic-gate  */
377c478bd9Sstevel@tonic-gate 
38159d09a2SMark Phalan 
397c478bd9Sstevel@tonic-gate #include "k5-int.h"
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * converts a single-string representation of the name to the
437c478bd9Sstevel@tonic-gate  * multi-part principal format used in the protocols.
447c478bd9Sstevel@tonic-gate  *
45*55fea89dSDan Cross  * principal will point to allocated storage which should be freed by
467c478bd9Sstevel@tonic-gate  * the caller (using krb5_free_principal) after use.
47*55fea89dSDan Cross  *
487c478bd9Sstevel@tonic-gate  * Conventions:  / is used to separate components.  If @ is present in the
497c478bd9Sstevel@tonic-gate  * string, then the rest of the string after it represents the realm name.
507c478bd9Sstevel@tonic-gate  * Otherwise the local realm name is used.
51*55fea89dSDan Cross  *
527c478bd9Sstevel@tonic-gate  * error return:
537c478bd9Sstevel@tonic-gate  *	KRB5_PARSE_MALFORMED	badly formatted string
547c478bd9Sstevel@tonic-gate  *
557c478bd9Sstevel@tonic-gate  * also returns system errors:
56159d09a2SMark Phalan  *	ENOMEM	malloc failed/out of memory
577c478bd9Sstevel@tonic-gate  *
587c478bd9Sstevel@tonic-gate  * get_default_realm() is called; it may return other errors.
597c478bd9Sstevel@tonic-gate  */
607c478bd9Sstevel@tonic-gate 
61159d09a2SMark Phalan #define REALM_SEP	'@'
627c478bd9Sstevel@tonic-gate #define	COMPONENT_SEP	'/'
63159d09a2SMark Phalan #define QUOTECHAR	'\\'
647c478bd9Sstevel@tonic-gate 
65159d09a2SMark Phalan #define FCOMPNUM	10
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate /*
687c478bd9Sstevel@tonic-gate  * May the fleas of a thousand camels infest the ISO, they who think
697c478bd9Sstevel@tonic-gate  * that arbitrarily large multi-component names are a Good Thing.....
707c478bd9Sstevel@tonic-gate  */
71ba7b222eSGlenn Barry static krb5_error_code
72ba7b222eSGlenn Barry /*LINTED*/
k5_parse_name(krb5_context context,const char * name,int flags,krb5_principal * nprincipal)73ba7b222eSGlenn Barry k5_parse_name(krb5_context context, const char *name,
74ba7b222eSGlenn Barry 	      int flags, krb5_principal *nprincipal)
757c478bd9Sstevel@tonic-gate {
76159d09a2SMark Phalan 	register const char	*cp;
77159d09a2SMark Phalan 	register char	*q;
78ba7b222eSGlenn Barry 	register int	i,c,size;
797c478bd9Sstevel@tonic-gate 	int		components = 0;
807c478bd9Sstevel@tonic-gate 	const char	*parsed_realm = NULL;
817c478bd9Sstevel@tonic-gate 	int		fcompsize[FCOMPNUM];
82505d05c7Sgtb 	unsigned int	realmsize = 0;
837c478bd9Sstevel@tonic-gate #ifndef _KERNEL
84505d05c7Sgtb 	char		*default_realm = NULL;
85505d05c7Sgtb 	int		default_realm_size = 0;
867c478bd9Sstevel@tonic-gate 	krb5_error_code retval;
877c478bd9Sstevel@tonic-gate #endif
88505d05c7Sgtb 	char		*tmpdata;
89505d05c7Sgtb 	krb5_principal	principal;
90ba7b222eSGlenn Barry 	unsigned int	enterprise = (flags & KRB5_PRINCIPAL_PARSE_ENTERPRISE);
91ba7b222eSGlenn Barry 	int		first_at;
92ba7b222eSGlenn Barry 
93ba7b222eSGlenn Barry 	*nprincipal = NULL;
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 	/*
967c478bd9Sstevel@tonic-gate 	 * Pass 1.  Find out how many components there are to the name,
97ba7b222eSGlenn Barry 	 * and get string sizes for the first FCOMPNUM components. For
98ba7b222eSGlenn Barry 	 * enterprise principal names (UPNs), there is only a single
99ba7b222eSGlenn Barry 	 * component.
1007c478bd9Sstevel@tonic-gate 	 */
1017c478bd9Sstevel@tonic-gate 	size = 0;
1027c478bd9Sstevel@tonic-gate 	/*LINTED*/
103ba7b222eSGlenn Barry 	for (i=0,cp = name, first_at = 1; (c = *cp); cp++) {
1047c478bd9Sstevel@tonic-gate 		if (c == QUOTECHAR) {
1057c478bd9Sstevel@tonic-gate 			cp++;
1067c478bd9Sstevel@tonic-gate 			/*LINTED*/
1077c478bd9Sstevel@tonic-gate 			if (!(c = *cp))
1087c478bd9Sstevel@tonic-gate 				/*
109ba7b222eSGlenn Barry 			 	 * QUOTECHAR can't be at the last
110ba7b222eSGlenn Barry 			 	 * character of the name!
111ba7b222eSGlenn Barry 			 	 */
112159d09a2SMark Phalan 				return(KRB5_PARSE_MALFORMED);
1137c478bd9Sstevel@tonic-gate 			size++;
1147c478bd9Sstevel@tonic-gate 			continue;
115ba7b222eSGlenn Barry 		} else if (c == COMPONENT_SEP && !enterprise) {
1167c478bd9Sstevel@tonic-gate 			if (parsed_realm)
1177c478bd9Sstevel@tonic-gate 				/*
1187c478bd9Sstevel@tonic-gate 				 * Shouldn't see a component separator
1197c478bd9Sstevel@tonic-gate 				 * after we've parsed out the realm name!
1207c478bd9Sstevel@tonic-gate 				 */
121159d09a2SMark Phalan 				return(KRB5_PARSE_MALFORMED);
1227c478bd9Sstevel@tonic-gate 			if (i < FCOMPNUM) {
1237c478bd9Sstevel@tonic-gate 				fcompsize[i] = size;
1247c478bd9Sstevel@tonic-gate 			}
1257c478bd9Sstevel@tonic-gate 			size = 0;
1267c478bd9Sstevel@tonic-gate 			i++;
127ba7b222eSGlenn Barry 		} else if (c == REALM_SEP && (!enterprise || !first_at)) {
128fe598cdcSmp 			if (parsed_realm)
1297c478bd9Sstevel@tonic-gate 				/*
130fe598cdcSmp 				 * Multiple realm separaters
131fe598cdcSmp 				 * not allowed; zero-length realms are.
1327c478bd9Sstevel@tonic-gate 				 */
133159d09a2SMark Phalan 				return(KRB5_PARSE_MALFORMED);
134ba7b222eSGlenn Barry 			parsed_realm = cp + 1;
1357c478bd9Sstevel@tonic-gate 			if (i < FCOMPNUM) {
1367c478bd9Sstevel@tonic-gate 				fcompsize[i] = size;
1377c478bd9Sstevel@tonic-gate 			}
1387c478bd9Sstevel@tonic-gate 			size = 0;
139ba7b222eSGlenn Barry 		} else {
140ba7b222eSGlenn Barry 			if (c == REALM_SEP && enterprise && first_at)
141ba7b222eSGlenn Barry 				first_at = 0;
142ba7b222eSGlenn Barry 
1437c478bd9Sstevel@tonic-gate 			size++;
144ba7b222eSGlenn Barry 		}
1457c478bd9Sstevel@tonic-gate 	}
146ba7b222eSGlenn Barry 	if (parsed_realm != NULL)
1477c478bd9Sstevel@tonic-gate 		realmsize = size;
148*55fea89dSDan Cross 	else if (i < FCOMPNUM)
1497c478bd9Sstevel@tonic-gate 		fcompsize[i] = size;
1507c478bd9Sstevel@tonic-gate 	components = i + 1;
1517c478bd9Sstevel@tonic-gate 	/*
1527c478bd9Sstevel@tonic-gate 	 * Now, we allocate the principal structure and all of its
1537c478bd9Sstevel@tonic-gate 	 * component pieces
1547c478bd9Sstevel@tonic-gate 	 */
155159d09a2SMark Phalan 	principal = (krb5_principal)MALLOC(sizeof(krb5_principal_data));
156ba7b222eSGlenn Barry 	if (principal == NULL) {
157ba7b222eSGlenn Barry 	    return(ENOMEM);
1587c478bd9Sstevel@tonic-gate 	}
159159d09a2SMark Phalan 	principal->data = (krb5_data *)MALLOC(sizeof(krb5_data) * components);
160ba7b222eSGlenn Barry 	if (principal->data == NULL) {
161ba7b222eSGlenn Barry 	    krb5_xfree_wrap(principal, sizeof(krb5_principal_data));
162159d09a2SMark Phalan 	    return ENOMEM;
1637c478bd9Sstevel@tonic-gate 	}
1647c478bd9Sstevel@tonic-gate 	principal->length = components;
165ba7b222eSGlenn Barry 
1667c478bd9Sstevel@tonic-gate 	/*
167ba7b222eSGlenn Barry 	 * If a realm was not found, then use the default realm, unless
168ba7b222eSGlenn Barry 	 * KRB5_PRINCIPAL_PARSE_NO_REALM was specified in which case the
169ba7b222eSGlenn Barry 	 * realm will be empty.
1707c478bd9Sstevel@tonic-gate 	 */
1717c478bd9Sstevel@tonic-gate #ifndef _KERNEL
1727c478bd9Sstevel@tonic-gate 	if (!parsed_realm) {
173ba7b222eSGlenn Barry 	    if (flags & KRB5_PRINCIPAL_PARSE_REQUIRE_REALM) {
174ba7b222eSGlenn Barry 		krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
175ba7b222eSGlenn Barry 				       "Principal %s is missing required realm", name);
176ba7b222eSGlenn Barry 		krb5_xfree_wrap(principal->data, principal->length);
177ba7b222eSGlenn Barry 		krb5_xfree_wrap(principal, sizeof(krb5_principal_data));
178ba7b222eSGlenn Barry 		return KRB5_PARSE_MALFORMED;
179ba7b222eSGlenn Barry 	    }
180ba7b222eSGlenn Barry 	    if (!default_realm && (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) == 0) {
1817c478bd9Sstevel@tonic-gate 		retval = krb5_get_default_realm(context, &default_realm);
1827c478bd9Sstevel@tonic-gate 		if (retval) {
183ba7b222eSGlenn Barry 		    krb5_xfree_wrap(principal->data, principal->length);
184ba7b222eSGlenn Barry 		    krb5_xfree_wrap(principal, sizeof(krb5_principal_data));
185159d09a2SMark Phalan 		    return(retval);
1867c478bd9Sstevel@tonic-gate 		}
1877c478bd9Sstevel@tonic-gate 		default_realm_size = strlen(default_realm);
1887c478bd9Sstevel@tonic-gate 	    }
1897c478bd9Sstevel@tonic-gate 	    realmsize = default_realm_size;
190ba7b222eSGlenn Barry 	} else if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) {
191ba7b222eSGlenn Barry 	    krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
192ba7b222eSGlenn Barry 				  "Principal %s has realm present", name);
193ba7b222eSGlenn Barry 	    krb5_xfree_wrap(principal->data, principal->length);
194ba7b222eSGlenn Barry 	    krb5_xfree_wrap(principal, sizeof(krb5_principal_data));
195ba7b222eSGlenn Barry 	    return KRB5_PARSE_MALFORMED;
1967c478bd9Sstevel@tonic-gate 	}
1977c478bd9Sstevel@tonic-gate #endif
198ba7b222eSGlenn Barry 
1997c478bd9Sstevel@tonic-gate 	/*
2007c478bd9Sstevel@tonic-gate 	 * Pass 2.  Happens only if there were more than FCOMPNUM
2017c478bd9Sstevel@tonic-gate 	 * component; if this happens, someone should be shot
2027c478bd9Sstevel@tonic-gate 	 * immediately.  Nevertheless, we will attempt to handle said
2037c478bd9Sstevel@tonic-gate 	 * case..... <martyred sigh>
2047c478bd9Sstevel@tonic-gate 	 */
2057c478bd9Sstevel@tonic-gate 	if (components >= FCOMPNUM) {
2067c478bd9Sstevel@tonic-gate 		size = 0;
2077c478bd9Sstevel@tonic-gate 		parsed_realm = NULL;
2087c478bd9Sstevel@tonic-gate 		/*LINTED*/
209159d09a2SMark Phalan 		for (i=0,cp = name; (c = *cp); cp++) {
2107c478bd9Sstevel@tonic-gate 			if (c == QUOTECHAR) {
2117c478bd9Sstevel@tonic-gate 				cp++;
2127c478bd9Sstevel@tonic-gate 				size++;
2137c478bd9Sstevel@tonic-gate 			} else if (c == COMPONENT_SEP) {
214505d05c7Sgtb 				if (krb5_princ_size(context, principal) > i)
215505d05c7Sgtb 					krb5_princ_component(context, principal, i)->length = size;
2167c478bd9Sstevel@tonic-gate 				size = 0;
2177c478bd9Sstevel@tonic-gate 				i++;
2187c478bd9Sstevel@tonic-gate 			} else if (c == REALM_SEP) {
219505d05c7Sgtb 				if (krb5_princ_size(context, principal) > i)
220505d05c7Sgtb 					krb5_princ_component(context, principal, i)->length = size;
2217c478bd9Sstevel@tonic-gate 				size = 0;
2227c478bd9Sstevel@tonic-gate 				parsed_realm = cp+1;
2237c478bd9Sstevel@tonic-gate 			} else
2247c478bd9Sstevel@tonic-gate 				size++;
2257c478bd9Sstevel@tonic-gate 		}
2267c478bd9Sstevel@tonic-gate 		if (parsed_realm)
2277c478bd9Sstevel@tonic-gate 			krb5_princ_realm(context, principal)->length = size;
2287c478bd9Sstevel@tonic-gate 		else
229505d05c7Sgtb 			if (krb5_princ_size(context, principal) > i)
230159d09a2SMark Phalan 				krb5_princ_component(context, principal, i)->length = size;
2317c478bd9Sstevel@tonic-gate 		if (i + 1 != components) {
232505d05c7Sgtb #ifndef _KERNEL
233159d09a2SMark Phalan #if !defined(_WIN32)
234ba7b222eSGlenn Barry  		    fprintf(stderr,
235159d09a2SMark Phalan 			    "Programming error in krb5_parse_name!");
236159d09a2SMark Phalan #endif
237ba7b222eSGlenn Barry  		    ASSERT(i + 1 == components);
238ba7b222eSGlenn Barry  		    abort();
2397c478bd9Sstevel@tonic-gate #else
240ba7b222eSGlenn Barry  		    ASSERT(i + 1 == components);
241505d05c7Sgtb #endif /* !_KERNEL */
242ba7b222eSGlenn Barry 
2437c478bd9Sstevel@tonic-gate 		}
2447c478bd9Sstevel@tonic-gate 	} else {
2457c478bd9Sstevel@tonic-gate 		/*
2467c478bd9Sstevel@tonic-gate 		 * If there were fewer than FCOMPSIZE components (the
2477c478bd9Sstevel@tonic-gate 		 * usual case), then just copy the sizes to the
2487c478bd9Sstevel@tonic-gate 		 * principal structure
2497c478bd9Sstevel@tonic-gate 		 */
250159d09a2SMark Phalan 		for (i=0; i < components; i++)
251159d09a2SMark Phalan 			krb5_princ_component(context, principal, i)->length = fcompsize[i];
2527c478bd9Sstevel@tonic-gate 	}
253*55fea89dSDan Cross 	/*
2547c478bd9Sstevel@tonic-gate 	 * Now, we need to allocate the space for the strings themselves.....
2557c478bd9Sstevel@tonic-gate 	 */
256ba7b222eSGlenn Barry 	tmpdata = MALLOC(realmsize + 1);
2577c478bd9Sstevel@tonic-gate 	if (tmpdata == 0) {
258ba7b222eSGlenn Barry 		krb5_xfree_wrap(principal->data, principal->length);
259ba7b222eSGlenn Barry 		krb5_xfree_wrap(principal, sizeof(krb5_principal_data));
260505d05c7Sgtb #ifndef _KERNEL
261ba7b222eSGlenn Barry 		krb5_xfree_wrap(default_realm, strlen(default_realm));
262505d05c7Sgtb #endif
263ba7b222eSGlenn Barry 		return ENOMEM;
2647c478bd9Sstevel@tonic-gate 	}
2657c478bd9Sstevel@tonic-gate 	krb5_princ_set_realm_length(context, principal, realmsize);
2667c478bd9Sstevel@tonic-gate 	krb5_princ_set_realm_data(context, principal, tmpdata);
267159d09a2SMark Phalan 	for (i=0; i < components; i++) {
268159d09a2SMark Phalan 		char *tmpdata2 =
269159d09a2SMark Phalan 		  MALLOC(krb5_princ_component(context, principal, i)->length + 1);
270ba7b222eSGlenn Barry 		if (tmpdata2 == NULL) {
2717c478bd9Sstevel@tonic-gate 			for (i--; i >= 0; i--)
272ba7b222eSGlenn Barry  				krb5_xfree_wrap(krb5_princ_component(context,
2737c478bd9Sstevel@tonic-gate 				    principal, i)->data,
274ba7b222eSGlenn Barry                                     krb5_princ_component(context,
275ba7b222eSGlenn Barry                                     principal, i)->length + 1);
276ba7b222eSGlenn Barry 
277ba7b222eSGlenn Barry  			krb5_xfree_wrap(krb5_princ_realm(context,
278ba7b222eSGlenn Barry  			    principal)->data, krb5_princ_realm(context,
279ba7b222eSGlenn Barry  			    principal)->length + 1);
280ba7b222eSGlenn Barry 
2817c478bd9Sstevel@tonic-gate 			krb5_xfree_wrap(principal->data, principal->length);
2827c478bd9Sstevel@tonic-gate 			krb5_xfree_wrap(principal, sizeof(krb5_principal_data));
283505d05c7Sgtb #ifndef _KERNEL
284ba7b222eSGlenn Barry 			krb5_xfree_wrap(default_realm, strlen(default_realm));
285505d05c7Sgtb #endif
286ba7b222eSGlenn Barry 			return(ENOMEM);
2877c478bd9Sstevel@tonic-gate 		}
288505d05c7Sgtb 		krb5_princ_component(context, principal, i)->data = tmpdata2;
2897c478bd9Sstevel@tonic-gate 		krb5_princ_component(context, principal, i)->magic = KV5M_DATA;
2907c478bd9Sstevel@tonic-gate 	}
291*55fea89dSDan Cross 
2927c478bd9Sstevel@tonic-gate 	/*
2937c478bd9Sstevel@tonic-gate 	 * Pass 3.  Now we go through the string a *third* time, this
2947c478bd9Sstevel@tonic-gate 	 * time filling in the krb5_principal structure which we just
2957c478bd9Sstevel@tonic-gate 	 * allocated.
2967c478bd9Sstevel@tonic-gate 	 */
2977c478bd9Sstevel@tonic-gate 	q = krb5_princ_component(context, principal, 0)->data;
2987c478bd9Sstevel@tonic-gate 	/*LINTED*/
299ba7b222eSGlenn Barry 	for (i=0,cp = name, first_at = 1; (c = *cp); cp++) {
3007c478bd9Sstevel@tonic-gate 		if (c == QUOTECHAR) {
3017c478bd9Sstevel@tonic-gate 			cp++;
3027c478bd9Sstevel@tonic-gate 			switch (c = *cp) {
3037c478bd9Sstevel@tonic-gate 			case 'n':
3047c478bd9Sstevel@tonic-gate 				*q++ = '\n';
3057c478bd9Sstevel@tonic-gate 				break;
3067c478bd9Sstevel@tonic-gate 			case 't':
3077c478bd9Sstevel@tonic-gate 				*q++ = '\t';
3087c478bd9Sstevel@tonic-gate 				break;
3097c478bd9Sstevel@tonic-gate 			case 'b':
3107c478bd9Sstevel@tonic-gate 				*q++ = '\b';
3117c478bd9Sstevel@tonic-gate 				break;
3127c478bd9Sstevel@tonic-gate 			case '0':
3137c478bd9Sstevel@tonic-gate 				*q++ = '\0';
3147c478bd9Sstevel@tonic-gate 				break;
3157c478bd9Sstevel@tonic-gate 			default:
316ba7b222eSGlenn Barry 				*q++ = c;
317ba7b222eSGlenn Barry 				break;
3187c478bd9Sstevel@tonic-gate 			}
319ba7b222eSGlenn Barry 		} else if (c == COMPONENT_SEP && !enterprise) {
320ba7b222eSGlenn Barry 			i++;
321ba7b222eSGlenn Barry 			*q++ = '\0';
322ba7b222eSGlenn Barry 			q = krb5_princ_component(context, principal, i)->data;
323ba7b222eSGlenn Barry 		} else if (c == REALM_SEP && (!enterprise || !first_at)) {
3247c478bd9Sstevel@tonic-gate 			i++;
3257c478bd9Sstevel@tonic-gate 			*q++ = '\0';
326ba7b222eSGlenn Barry 			q = krb5_princ_realm(context, principal)->data;
327ba7b222eSGlenn Barry 		} else {
328ba7b222eSGlenn Barry 			if (c == REALM_SEP && enterprise && first_at)
329ba7b222eSGlenn Barry 				first_at = 0;
330ba7b222eSGlenn Barry 
331ba7b222eSGlenn Barry 			*q++ = c;
332ba7b222eSGlenn Barry 		}
3337c478bd9Sstevel@tonic-gate 	}
3347c478bd9Sstevel@tonic-gate 	*q++ = '\0';
335ba7b222eSGlenn Barry 	/*LINTED*/
336ba7b222eSGlenn Barry 	if (!parsed_realm) {
337505d05c7Sgtb #ifndef _KERNEL
338ba7b222eSGlenn Barry 
339ba7b222eSGlenn Barry 		if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM)
340ba7b222eSGlenn Barry 			(krb5_princ_realm(context, principal)->data)[0] = '\0';
341ba7b222eSGlenn Barry 		else
342ba7b222eSGlenn Barry 			strlcpy(krb5_princ_realm(context, principal)->data, default_realm, realmsize+1);
3437c478bd9Sstevel@tonic-gate #endif
344ba7b222eSGlenn Barry 	}
3457c478bd9Sstevel@tonic-gate 	/*
3467c478bd9Sstevel@tonic-gate 	 * Alright, we're done.  Now stuff a pointer to this monstrosity
3477c478bd9Sstevel@tonic-gate 	 * into the return variable, and let's get out of here.
3487c478bd9Sstevel@tonic-gate 	 */
349ba7b222eSGlenn Barry 	if (enterprise)
350ba7b222eSGlenn Barry 		krb5_princ_type(context, principal) = KRB5_NT_ENTERPRISE_PRINCIPAL;
351ba7b222eSGlenn Barry 	else
352ba7b222eSGlenn Barry 		krb5_princ_type(context, principal) = KRB5_NT_PRINCIPAL;
3537c478bd9Sstevel@tonic-gate 	principal->magic = KV5M_PRINCIPAL;
3547c478bd9Sstevel@tonic-gate 	principal->realm.magic = KV5M_DATA;
3557c478bd9Sstevel@tonic-gate 	*nprincipal = principal;
356ba7b222eSGlenn Barry 
357505d05c7Sgtb #ifndef _KERNEL
358ba7b222eSGlenn Barry 	if (default_realm != NULL)
359ba7b222eSGlenn Barry  	    krb5_xfree_wrap(default_realm, strlen(default_realm));
360505d05c7Sgtb #endif
361ba7b222eSGlenn Barry 
3627c478bd9Sstevel@tonic-gate 	return(0);
3637c478bd9Sstevel@tonic-gate }
364ba7b222eSGlenn Barry 
365ba7b222eSGlenn Barry krb5_error_code KRB5_CALLCONV
krb5_parse_name(krb5_context context,const char * name,krb5_principal * nprincipal)366ba7b222eSGlenn Barry krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincipal)
367ba7b222eSGlenn Barry {
368ba7b222eSGlenn Barry 	 return k5_parse_name(context, name, 0, nprincipal);
369ba7b222eSGlenn Barry }
370ba7b222eSGlenn Barry 
371ba7b222eSGlenn Barry krb5_error_code KRB5_CALLCONV
krb5_parse_name_flags(krb5_context context,const char * name,int flags,krb5_principal * nprincipal)372ba7b222eSGlenn Barry krb5_parse_name_flags(krb5_context context, const char *name,
373ba7b222eSGlenn Barry 		      int flags, krb5_principal *nprincipal)
374ba7b222eSGlenn Barry {
375ba7b222eSGlenn Barry 	 return k5_parse_name(context, name, flags, nprincipal);
376ba7b222eSGlenn Barry }
377