xref: /freebsd-src/crypto/heimdal/lib/krb5/principal.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
1b528cefcSMark Murray /*
2*ae771770SStanislav Sedov  * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
3b528cefcSMark Murray  * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray  * All rights reserved.
5b528cefcSMark Murray  *
6b528cefcSMark Murray  * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray  * modification, are permitted provided that the following conditions
8b528cefcSMark Murray  * are met:
9b528cefcSMark Murray  *
10b528cefcSMark Murray  * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray  *
13b528cefcSMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray  *    documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray  *
17b528cefcSMark Murray  * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray  *    may be used to endorse or promote products derived from this software
19b528cefcSMark Murray  *    without specific prior written permission.
20b528cefcSMark Murray  *
21b528cefcSMark Murray  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray  * SUCH DAMAGE.
32b528cefcSMark Murray  */
33b528cefcSMark Murray 
34*ae771770SStanislav Sedov /**
35*ae771770SStanislav Sedov  * @page krb5_principal_intro The principal handing functions.
36*ae771770SStanislav Sedov  *
37*ae771770SStanislav Sedov  * A Kerberos principal is a email address looking string that
38*ae771770SStanislav Sedov  * contains to parts separeted by a @.  The later part is the kerbero
39*ae771770SStanislav Sedov  * realm the principal belongs to and the former is a list of 0 or
40*ae771770SStanislav Sedov  * more components. For example
41*ae771770SStanislav Sedov  * @verbatim
42*ae771770SStanislav Sedov lha@SU.SE
43*ae771770SStanislav Sedov host/hummel.it.su.se@SU.SE
44*ae771770SStanislav Sedov host/admin@H5L.ORG
45*ae771770SStanislav Sedov @endverbatim
46*ae771770SStanislav Sedov  *
47*ae771770SStanislav Sedov  * See the library functions here: @ref krb5_principal
48*ae771770SStanislav Sedov  */
49*ae771770SStanislav Sedov 
50b528cefcSMark Murray #include "krb5_locl.h"
51b528cefcSMark Murray #ifdef HAVE_RES_SEARCH
52b528cefcSMark Murray #define USE_RESOLVER
53b528cefcSMark Murray #endif
54b528cefcSMark Murray #ifdef HAVE_ARPA_NAMESER_H
55b528cefcSMark Murray #include <arpa/nameser.h>
56b528cefcSMark Murray #endif
575e9cd1aeSAssar Westerlund #include <fnmatch.h>
58b528cefcSMark Murray #include "resolve.h"
59b528cefcSMark Murray 
60b528cefcSMark Murray #define princ_num_comp(P) ((P)->name.name_string.len)
61b528cefcSMark Murray #define princ_type(P) ((P)->name.name_type)
62b528cefcSMark Murray #define princ_comp(P) ((P)->name.name_string.val)
63b528cefcSMark Murray #define princ_ncomp(P, N) ((P)->name.name_string.val[(N)])
64b528cefcSMark Murray #define princ_realm(P) ((P)->realm)
65b528cefcSMark Murray 
66*ae771770SStanislav Sedov /**
67*ae771770SStanislav Sedov  * Frees a Kerberos principal allocated by the library with
68*ae771770SStanislav Sedov  * krb5_parse_name(), krb5_make_principal() or any other related
69*ae771770SStanislav Sedov  * principal functions.
70*ae771770SStanislav Sedov  *
71*ae771770SStanislav Sedov  * @param context A Kerberos context.
72*ae771770SStanislav Sedov  * @param p a principal to free.
73*ae771770SStanislav Sedov  *
74*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
75*ae771770SStanislav Sedov  *
76*ae771770SStanislav Sedov  * @ingroup krb5_principal
77*ae771770SStanislav Sedov  */
78*ae771770SStanislav Sedov 
79*ae771770SStanislav Sedov KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_free_principal(krb5_context context,krb5_principal p)80b528cefcSMark Murray krb5_free_principal(krb5_context context,
81b528cefcSMark Murray 		    krb5_principal p)
82b528cefcSMark Murray {
83b528cefcSMark Murray     if(p){
84b528cefcSMark Murray 	free_Principal(p);
85b528cefcSMark Murray 	free(p);
86b528cefcSMark Murray     }
87b528cefcSMark Murray }
88b528cefcSMark Murray 
89*ae771770SStanislav Sedov /**
90*ae771770SStanislav Sedov  * Set the type of the principal
91*ae771770SStanislav Sedov  *
92*ae771770SStanislav Sedov  * @param context A Kerberos context.
93*ae771770SStanislav Sedov  * @param principal principal to set the type for
94*ae771770SStanislav Sedov  * @param type the new type
95*ae771770SStanislav Sedov  *
96*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
97*ae771770SStanislav Sedov  *
98*ae771770SStanislav Sedov  * @ingroup krb5_principal
99*ae771770SStanislav Sedov  */
100*ae771770SStanislav Sedov 
101*ae771770SStanislav Sedov KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_principal_set_type(krb5_context context,krb5_principal principal,int type)102c19800e8SDoug Rabson krb5_principal_set_type(krb5_context context,
103c19800e8SDoug Rabson 			krb5_principal principal,
104c19800e8SDoug Rabson 			int type)
105c19800e8SDoug Rabson {
106c19800e8SDoug Rabson     princ_type(principal) = type;
107c19800e8SDoug Rabson }
108c19800e8SDoug Rabson 
109*ae771770SStanislav Sedov /**
110*ae771770SStanislav Sedov  * Get the type of the principal
111*ae771770SStanislav Sedov  *
112*ae771770SStanislav Sedov  * @param context A Kerberos context.
113*ae771770SStanislav Sedov  * @param principal principal to get the type for
114*ae771770SStanislav Sedov  *
115*ae771770SStanislav Sedov  * @return the type of principal
116*ae771770SStanislav Sedov  *
117*ae771770SStanislav Sedov  * @ingroup krb5_principal
118*ae771770SStanislav Sedov  */
119*ae771770SStanislav Sedov 
120*ae771770SStanislav Sedov KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_principal_get_type(krb5_context context,krb5_const_principal principal)1214137ff4cSJacques Vidrine krb5_principal_get_type(krb5_context context,
122c19800e8SDoug Rabson 			krb5_const_principal principal)
1234137ff4cSJacques Vidrine {
1244137ff4cSJacques Vidrine     return princ_type(principal);
1254137ff4cSJacques Vidrine }
1264137ff4cSJacques Vidrine 
127*ae771770SStanislav Sedov /**
128*ae771770SStanislav Sedov  * Get the realm of the principal
129*ae771770SStanislav Sedov  *
130*ae771770SStanislav Sedov  * @param context A Kerberos context.
131*ae771770SStanislav Sedov  * @param principal principal to get the realm for
132*ae771770SStanislav Sedov  *
133*ae771770SStanislav Sedov  * @return realm of the principal, don't free or use after krb5_principal is freed
134*ae771770SStanislav Sedov  *
135*ae771770SStanislav Sedov  * @ingroup krb5_principal
136*ae771770SStanislav Sedov  */
137*ae771770SStanislav Sedov 
138*ae771770SStanislav Sedov KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL
krb5_principal_get_realm(krb5_context context,krb5_const_principal principal)1394137ff4cSJacques Vidrine krb5_principal_get_realm(krb5_context context,
140c19800e8SDoug Rabson 			 krb5_const_principal principal)
1414137ff4cSJacques Vidrine {
1424137ff4cSJacques Vidrine     return princ_realm(principal);
1434137ff4cSJacques Vidrine }
1444137ff4cSJacques Vidrine 
145*ae771770SStanislav Sedov KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL
krb5_principal_get_comp_string(krb5_context context,krb5_const_principal principal,unsigned int component)1464137ff4cSJacques Vidrine krb5_principal_get_comp_string(krb5_context context,
147c19800e8SDoug Rabson 			       krb5_const_principal principal,
1484137ff4cSJacques Vidrine 			       unsigned int component)
1494137ff4cSJacques Vidrine {
1504137ff4cSJacques Vidrine     if(component >= princ_num_comp(principal))
1514137ff4cSJacques Vidrine        return NULL;
1524137ff4cSJacques Vidrine     return princ_ncomp(principal, component);
1534137ff4cSJacques Vidrine }
1544137ff4cSJacques Vidrine 
155*ae771770SStanislav Sedov /**
156*ae771770SStanislav Sedov  * Get number of component is principal.
157*ae771770SStanislav Sedov  *
158*ae771770SStanislav Sedov  * @param context Kerberos 5 context
159*ae771770SStanislav Sedov  * @param principal principal to query
160*ae771770SStanislav Sedov  *
161*ae771770SStanislav Sedov  * @return number of components in string
162*ae771770SStanislav Sedov  *
163*ae771770SStanislav Sedov  * @ingroup krb5_principal
164*ae771770SStanislav Sedov  */
165*ae771770SStanislav Sedov 
166*ae771770SStanislav Sedov KRB5_LIB_FUNCTION unsigned int KRB5_LIB_CALL
krb5_principal_get_num_comp(krb5_context context,krb5_const_principal principal)167*ae771770SStanislav Sedov krb5_principal_get_num_comp(krb5_context context,
168*ae771770SStanislav Sedov 			    krb5_const_principal principal)
169*ae771770SStanislav Sedov {
170*ae771770SStanislav Sedov     return princ_num_comp(principal);
171*ae771770SStanislav Sedov }
172*ae771770SStanislav Sedov 
173*ae771770SStanislav Sedov /**
174*ae771770SStanislav Sedov  * Parse a name into a krb5_principal structure, flags controls the behavior.
175*ae771770SStanislav Sedov  *
176*ae771770SStanislav Sedov  * @param context Kerberos 5 context
177*ae771770SStanislav Sedov  * @param name name to parse into a Kerberos principal
178*ae771770SStanislav Sedov  * @param flags flags to control the behavior
179*ae771770SStanislav Sedov  * @param principal returned principal, free with krb5_free_principal().
180*ae771770SStanislav Sedov  *
181*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
182*ae771770SStanislav Sedov  *
183*ae771770SStanislav Sedov  * @ingroup krb5_principal
184*ae771770SStanislav Sedov  */
185*ae771770SStanislav Sedov 
186*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_parse_name_flags(krb5_context context,const char * name,int flags,krb5_principal * principal)187c19800e8SDoug Rabson krb5_parse_name_flags(krb5_context context,
188b528cefcSMark Murray 		      const char *name,
189c19800e8SDoug Rabson 		      int flags,
190b528cefcSMark Murray 		      krb5_principal *principal)
191b528cefcSMark Murray {
192b528cefcSMark Murray     krb5_error_code ret;
193c19800e8SDoug Rabson     heim_general_string *comp;
194c19800e8SDoug Rabson     heim_general_string realm = NULL;
195b528cefcSMark Murray     int ncomp;
196b528cefcSMark Murray 
1978373020dSJacques Vidrine     const char *p;
198b528cefcSMark Murray     char *q;
199b528cefcSMark Murray     char *s;
200b528cefcSMark Murray     char *start;
201b528cefcSMark Murray 
202b528cefcSMark Murray     int n;
203b528cefcSMark Murray     char c;
204b528cefcSMark Murray     int got_realm = 0;
205c19800e8SDoug Rabson     int first_at = 1;
206c19800e8SDoug Rabson     int enterprise = (flags & KRB5_PRINCIPAL_PARSE_ENTERPRISE);
207b528cefcSMark Murray 
208c19800e8SDoug Rabson     *principal = NULL;
209c19800e8SDoug Rabson 
210*ae771770SStanislav Sedov #define RFLAGS (KRB5_PRINCIPAL_PARSE_NO_REALM|KRB5_PRINCIPAL_PARSE_REQUIRE_REALM)
211c19800e8SDoug Rabson 
212c19800e8SDoug Rabson     if ((flags & RFLAGS) == RFLAGS) {
213*ae771770SStanislav Sedov 	krb5_set_error_message(context, KRB5_ERR_NO_SERVICE,
214*ae771770SStanislav Sedov 			       N_("Can't require both realm and "
215*ae771770SStanislav Sedov 				  "no realm at the same time", ""));
216c19800e8SDoug Rabson 	return KRB5_ERR_NO_SERVICE;
217c19800e8SDoug Rabson     }
218c19800e8SDoug Rabson #undef RFLAGS
219c19800e8SDoug Rabson 
220c19800e8SDoug Rabson     /* count number of component,
221c19800e8SDoug Rabson      * enterprise names only have one component
222c19800e8SDoug Rabson      */
223b528cefcSMark Murray     ncomp = 1;
224c19800e8SDoug Rabson     if (!enterprise) {
2258373020dSJacques Vidrine 	for(p = name; *p; p++){
226b528cefcSMark Murray 	    if(*p=='\\'){
227adb0ddaeSAssar Westerlund 		if(!p[1]) {
228*ae771770SStanislav Sedov 		    krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
229*ae771770SStanislav Sedov 					   N_("trailing \\ in principal name", ""));
230b528cefcSMark Murray 		    return KRB5_PARSE_MALFORMED;
231adb0ddaeSAssar Westerlund 		}
232b528cefcSMark Murray 		p++;
233b528cefcSMark Murray 	    } else if(*p == '/')
234b528cefcSMark Murray 		ncomp++;
235c19800e8SDoug Rabson 	    else if(*p == '@')
236c19800e8SDoug Rabson 		break;
237c19800e8SDoug Rabson 	}
238b528cefcSMark Murray     }
239b528cefcSMark Murray     comp = calloc(ncomp, sizeof(*comp));
240adb0ddaeSAssar Westerlund     if (comp == NULL) {
241*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM,
242*ae771770SStanislav Sedov 			       N_("malloc: out of memory", ""));
243b528cefcSMark Murray 	return ENOMEM;
244adb0ddaeSAssar Westerlund     }
245b528cefcSMark Murray 
246b528cefcSMark Murray     n = 0;
2478373020dSJacques Vidrine     p = start = q = s = strdup(name);
248b528cefcSMark Murray     if (start == NULL) {
249b528cefcSMark Murray 	free (comp);
250*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM,
251*ae771770SStanislav Sedov 			       N_("malloc: out of memory", ""));
252b528cefcSMark Murray 	return ENOMEM;
253b528cefcSMark Murray     }
254b528cefcSMark Murray     while(*p){
255b528cefcSMark Murray 	c = *p++;
256b528cefcSMark Murray 	if(c == '\\'){
257b528cefcSMark Murray 	    c = *p++;
258b528cefcSMark Murray 	    if(c == 'n')
259b528cefcSMark Murray 		c = '\n';
260b528cefcSMark Murray 	    else if(c == 't')
261b528cefcSMark Murray 		c = '\t';
262b528cefcSMark Murray 	    else if(c == 'b')
263b528cefcSMark Murray 		c = '\b';
264b528cefcSMark Murray 	    else if(c == '0')
265b528cefcSMark Murray 		c = '\0';
2665bda878eSJacques Vidrine 	    else if(c == '\0') {
2675bda878eSJacques Vidrine 		ret = KRB5_PARSE_MALFORMED;
268*ae771770SStanislav Sedov 		krb5_set_error_message(context, ret,
269*ae771770SStanislav Sedov 				       N_("trailing \\ in principal name", ""));
2705bda878eSJacques Vidrine 		goto exit;
2715bda878eSJacques Vidrine 	    }
272c19800e8SDoug Rabson 	}else if(enterprise && first_at) {
273c19800e8SDoug Rabson 	    if (c == '@')
274c19800e8SDoug Rabson 		first_at = 0;
275c19800e8SDoug Rabson 	}else if((c == '/' && !enterprise) || c == '@'){
276b528cefcSMark Murray 	    if(got_realm){
277b528cefcSMark Murray 		ret = KRB5_PARSE_MALFORMED;
278*ae771770SStanislav Sedov 		krb5_set_error_message(context, ret,
279*ae771770SStanislav Sedov 				       N_("part after realm in principal name", ""));
280b528cefcSMark Murray 		goto exit;
281b528cefcSMark Murray 	    }else{
282b528cefcSMark Murray 		comp[n] = malloc(q - start + 1);
283b528cefcSMark Murray 		if (comp[n] == NULL) {
284b528cefcSMark Murray 		    ret = ENOMEM;
285*ae771770SStanislav Sedov 		    krb5_set_error_message(context, ret,
286*ae771770SStanislav Sedov 					   N_("malloc: out of memory", ""));
287b528cefcSMark Murray 		    goto exit;
288b528cefcSMark Murray 		}
28913e3f4d6SMark Murray 		memcpy(comp[n], start, q - start);
290b528cefcSMark Murray 		comp[n][q - start] = 0;
291b528cefcSMark Murray 		n++;
292b528cefcSMark Murray 	    }
293b528cefcSMark Murray 	    if(c == '@')
294b528cefcSMark Murray 		got_realm = 1;
295b528cefcSMark Murray 	    start = q;
296b528cefcSMark Murray 	    continue;
297b528cefcSMark Murray 	}
298*ae771770SStanislav Sedov 	if(got_realm && (c == '/' || c == '\0')) {
299b528cefcSMark Murray 	    ret = KRB5_PARSE_MALFORMED;
300*ae771770SStanislav Sedov 	    krb5_set_error_message(context, ret,
301*ae771770SStanislav Sedov 				   N_("part after realm in principal name", ""));
302b528cefcSMark Murray 	    goto exit;
303b528cefcSMark Murray 	}
304b528cefcSMark Murray 	*q++ = c;
305b528cefcSMark Murray     }
306b528cefcSMark Murray     if(got_realm){
307c19800e8SDoug Rabson 	if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) {
308c19800e8SDoug Rabson 	    ret = KRB5_PARSE_MALFORMED;
309*ae771770SStanislav Sedov 	    krb5_set_error_message(context, ret,
310*ae771770SStanislav Sedov 				   N_("realm found in 'short' principal "
311*ae771770SStanislav Sedov 				      "expected to be without one", ""));
312c19800e8SDoug Rabson 	    goto exit;
313c19800e8SDoug Rabson 	}
314b528cefcSMark Murray 	realm = malloc(q - start + 1);
315b528cefcSMark Murray 	if (realm == NULL) {
316b528cefcSMark Murray 	    ret = ENOMEM;
317*ae771770SStanislav Sedov 	    krb5_set_error_message(context, ret,
318*ae771770SStanislav Sedov 				   N_("malloc: out of memory", ""));
319b528cefcSMark Murray 	    goto exit;
320b528cefcSMark Murray 	}
32113e3f4d6SMark Murray 	memcpy(realm, start, q - start);
322b528cefcSMark Murray 	realm[q - start] = 0;
323b528cefcSMark Murray     }else{
324*ae771770SStanislav Sedov 	if (flags & KRB5_PRINCIPAL_PARSE_REQUIRE_REALM) {
325c19800e8SDoug Rabson 	    ret = KRB5_PARSE_MALFORMED;
326*ae771770SStanislav Sedov 	    krb5_set_error_message(context, ret,
327*ae771770SStanislav Sedov 				   N_("realm NOT found in principal "
328*ae771770SStanislav Sedov 				      "expected to be with one", ""));
329c19800e8SDoug Rabson 	    goto exit;
330c19800e8SDoug Rabson 	} else if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) {
331c19800e8SDoug Rabson 	    realm = NULL;
332c19800e8SDoug Rabson 	} else {
333b528cefcSMark Murray 	    ret = krb5_get_default_realm (context, &realm);
334b528cefcSMark Murray 	    if (ret)
335b528cefcSMark Murray 		goto exit;
336c19800e8SDoug Rabson 	}
337b528cefcSMark Murray 
338b528cefcSMark Murray 	comp[n] = malloc(q - start + 1);
339b528cefcSMark Murray 	if (comp[n] == NULL) {
340b528cefcSMark Murray 	    ret = ENOMEM;
341*ae771770SStanislav Sedov 	    krb5_set_error_message(context, ret,
342*ae771770SStanislav Sedov 				   N_("malloc: out of memory", ""));
343b528cefcSMark Murray 	    goto exit;
344b528cefcSMark Murray 	}
34513e3f4d6SMark Murray 	memcpy(comp[n], start, q - start);
346b528cefcSMark Murray 	comp[n][q - start] = 0;
347b528cefcSMark Murray 	n++;
348b528cefcSMark Murray     }
349b528cefcSMark Murray     *principal = malloc(sizeof(**principal));
350b528cefcSMark Murray     if (*principal == NULL) {
351b528cefcSMark Murray 	ret = ENOMEM;
352*ae771770SStanislav Sedov 	krb5_set_error_message(context, ret,
353*ae771770SStanislav Sedov 			       N_("malloc: out of memory", ""));
354b528cefcSMark Murray 	goto exit;
355b528cefcSMark Murray     }
356c19800e8SDoug Rabson     if (enterprise)
357c19800e8SDoug Rabson 	(*principal)->name.name_type = KRB5_NT_ENTERPRISE_PRINCIPAL;
358c19800e8SDoug Rabson     else
359b528cefcSMark Murray 	(*principal)->name.name_type = KRB5_NT_PRINCIPAL;
360b528cefcSMark Murray     (*principal)->name.name_string.val = comp;
361b528cefcSMark Murray     princ_num_comp(*principal) = n;
362b528cefcSMark Murray     (*principal)->realm = realm;
363b528cefcSMark Murray     free(s);
364b528cefcSMark Murray     return 0;
365b528cefcSMark Murray exit:
366b528cefcSMark Murray     while(n>0){
367b528cefcSMark Murray 	free(comp[--n]);
368b528cefcSMark Murray     }
369b528cefcSMark Murray     free(comp);
370c19800e8SDoug Rabson     free(realm);
371b528cefcSMark Murray     free(s);
372b528cefcSMark Murray     return ret;
373b528cefcSMark Murray }
374b528cefcSMark Murray 
375*ae771770SStanislav Sedov /**
376*ae771770SStanislav Sedov  * Parse a name into a krb5_principal structure
377*ae771770SStanislav Sedov  *
378*ae771770SStanislav Sedov  * @param context Kerberos 5 context
379*ae771770SStanislav Sedov  * @param name name to parse into a Kerberos principal
380*ae771770SStanislav Sedov  * @param principal returned principal, free with krb5_free_principal().
381*ae771770SStanislav Sedov  *
382*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
383*ae771770SStanislav Sedov  *
384*ae771770SStanislav Sedov  * @ingroup krb5_principal
385*ae771770SStanislav Sedov  */
386*ae771770SStanislav Sedov 
387*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_parse_name(krb5_context context,const char * name,krb5_principal * principal)388c19800e8SDoug Rabson krb5_parse_name(krb5_context context,
389c19800e8SDoug Rabson 		const char *name,
390c19800e8SDoug Rabson 		krb5_principal *principal)
391c19800e8SDoug Rabson {
392c19800e8SDoug Rabson     return krb5_parse_name_flags(context, name, 0, principal);
393c19800e8SDoug Rabson }
394c19800e8SDoug Rabson 
395b528cefcSMark Murray static const char quotable_chars[] = " \n\t\b\\/@";
396b528cefcSMark Murray static const char replace_chars[] = " ntb\\/@";
397c19800e8SDoug Rabson static const char nq_chars[] = "    \\/@";
398b528cefcSMark Murray 
399b528cefcSMark Murray #define add_char(BASE, INDEX, LEN, C) do { if((INDEX) < (LEN)) (BASE)[(INDEX)++] = (C); }while(0);
400b528cefcSMark Murray 
401b528cefcSMark Murray static size_t
quote_string(const char * s,char * out,size_t idx,size_t len,int display)402c19800e8SDoug Rabson quote_string(const char *s, char *out, size_t idx, size_t len, int display)
403b528cefcSMark Murray {
404b528cefcSMark Murray     const char *p, *q;
405c19800e8SDoug Rabson     for(p = s; *p && idx < len; p++){
406c19800e8SDoug Rabson 	q = strchr(quotable_chars, *p);
407c19800e8SDoug Rabson 	if (q && display) {
408c19800e8SDoug Rabson 	    add_char(out, idx, len, replace_chars[q - quotable_chars]);
409c19800e8SDoug Rabson 	} else if (q) {
410c19800e8SDoug Rabson 	    add_char(out, idx, len, '\\');
411c19800e8SDoug Rabson 	    add_char(out, idx, len, replace_chars[q - quotable_chars]);
412b528cefcSMark Murray 	}else
413c19800e8SDoug Rabson 	    add_char(out, idx, len, *p);
414b528cefcSMark Murray     }
415c19800e8SDoug Rabson     if(idx < len)
416c19800e8SDoug Rabson 	out[idx] = '\0';
417c19800e8SDoug Rabson     return idx;
418b528cefcSMark Murray }
419b528cefcSMark Murray 
420b528cefcSMark Murray 
421b528cefcSMark Murray static krb5_error_code
unparse_name_fixed(krb5_context context,krb5_const_principal principal,char * name,size_t len,int flags)422b528cefcSMark Murray unparse_name_fixed(krb5_context context,
423b528cefcSMark Murray 		   krb5_const_principal principal,
424b528cefcSMark Murray 		   char *name,
425b528cefcSMark Murray 		   size_t len,
426c19800e8SDoug Rabson 		   int flags)
427b528cefcSMark Murray {
428c19800e8SDoug Rabson     size_t idx = 0;
429*ae771770SStanislav Sedov     size_t i;
430c19800e8SDoug Rabson     int short_form = (flags & KRB5_PRINCIPAL_UNPARSE_SHORT) != 0;
431c19800e8SDoug Rabson     int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) != 0;
432c19800e8SDoug Rabson     int display = (flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) != 0;
433c19800e8SDoug Rabson 
434c19800e8SDoug Rabson     if (!no_realm && princ_realm(principal) == NULL) {
435*ae771770SStanislav Sedov 	krb5_set_error_message(context, ERANGE,
436*ae771770SStanislav Sedov 			       N_("Realm missing from principal, "
437*ae771770SStanislav Sedov 				  "can't unparse", ""));
438b528cefcSMark Murray 	return ERANGE;
439b528cefcSMark Murray     }
440c19800e8SDoug Rabson 
441c19800e8SDoug Rabson     for(i = 0; i < princ_num_comp(principal); i++){
442c19800e8SDoug Rabson 	if(i)
443c19800e8SDoug Rabson 	    add_char(name, idx, len, '/');
444c19800e8SDoug Rabson 	idx = quote_string(princ_ncomp(principal, i), name, idx, len, display);
445c19800e8SDoug Rabson 	if(idx == len) {
446*ae771770SStanislav Sedov 	    krb5_set_error_message(context, ERANGE,
447*ae771770SStanislav Sedov 				   N_("Out of space printing principal", ""));
448c19800e8SDoug Rabson 	    return ERANGE;
449c19800e8SDoug Rabson 	}
450c19800e8SDoug Rabson     }
451b528cefcSMark Murray     /* add realm if different from default realm */
452c19800e8SDoug Rabson     if(short_form && !no_realm) {
453b528cefcSMark Murray 	krb5_realm r;
454b528cefcSMark Murray 	krb5_error_code ret;
455b528cefcSMark Murray 	ret = krb5_get_default_realm(context, &r);
456b528cefcSMark Murray 	if(ret)
457b528cefcSMark Murray 	    return ret;
458b528cefcSMark Murray 	if(strcmp(princ_realm(principal), r) != 0)
459b528cefcSMark Murray 	    short_form = 0;
460b528cefcSMark Murray 	free(r);
461b528cefcSMark Murray     }
462c19800e8SDoug Rabson     if(!short_form && !no_realm) {
463c19800e8SDoug Rabson 	add_char(name, idx, len, '@');
464c19800e8SDoug Rabson 	idx = quote_string(princ_realm(principal), name, idx, len, display);
465c19800e8SDoug Rabson 	if(idx == len) {
466*ae771770SStanislav Sedov 	    krb5_set_error_message(context, ERANGE,
467*ae771770SStanislav Sedov 				   N_("Out of space printing "
468*ae771770SStanislav Sedov 				      "realm of principal", ""));
469b528cefcSMark Murray 	    return ERANGE;
470b528cefcSMark Murray 	}
471c19800e8SDoug Rabson     }
472b528cefcSMark Murray     return 0;
473b528cefcSMark Murray }
474b528cefcSMark Murray 
475*ae771770SStanislav Sedov /**
476*ae771770SStanislav Sedov  * Unparse the principal name to a fixed buffer
477*ae771770SStanislav Sedov  *
478*ae771770SStanislav Sedov  * @param context A Kerberos context.
479*ae771770SStanislav Sedov  * @param principal principal to unparse
480*ae771770SStanislav Sedov  * @param name buffer to write name to
481*ae771770SStanislav Sedov  * @param len length of buffer
482*ae771770SStanislav Sedov  *
483*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
484*ae771770SStanislav Sedov  *
485*ae771770SStanislav Sedov  * @ingroup krb5_principal
486*ae771770SStanislav Sedov  */
487*ae771770SStanislav Sedov 
488*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_unparse_name_fixed(krb5_context context,krb5_const_principal principal,char * name,size_t len)489b528cefcSMark Murray krb5_unparse_name_fixed(krb5_context context,
490b528cefcSMark Murray 			krb5_const_principal principal,
491b528cefcSMark Murray 			char *name,
492b528cefcSMark Murray 			size_t len)
493b528cefcSMark Murray {
494c19800e8SDoug Rabson     return unparse_name_fixed(context, principal, name, len, 0);
495b528cefcSMark Murray }
496b528cefcSMark Murray 
497*ae771770SStanislav Sedov /**
498*ae771770SStanislav Sedov  * Unparse the principal name to a fixed buffer. The realm is skipped
499*ae771770SStanislav Sedov  * if its a default realm.
500*ae771770SStanislav Sedov  *
501*ae771770SStanislav Sedov  * @param context A Kerberos context.
502*ae771770SStanislav Sedov  * @param principal principal to unparse
503*ae771770SStanislav Sedov  * @param name buffer to write name to
504*ae771770SStanislav Sedov  * @param len length of buffer
505*ae771770SStanislav Sedov  *
506*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
507*ae771770SStanislav Sedov  *
508*ae771770SStanislav Sedov  * @ingroup krb5_principal
509*ae771770SStanislav Sedov  */
510*ae771770SStanislav Sedov 
511*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_unparse_name_fixed_short(krb5_context context,krb5_const_principal principal,char * name,size_t len)512b528cefcSMark Murray krb5_unparse_name_fixed_short(krb5_context context,
513b528cefcSMark Murray 			      krb5_const_principal principal,
514b528cefcSMark Murray 			      char *name,
515b528cefcSMark Murray 			      size_t len)
516b528cefcSMark Murray {
517c19800e8SDoug Rabson     return unparse_name_fixed(context, principal, name, len,
518c19800e8SDoug Rabson 			      KRB5_PRINCIPAL_UNPARSE_SHORT);
519c19800e8SDoug Rabson }
520c19800e8SDoug Rabson 
521*ae771770SStanislav Sedov /**
522*ae771770SStanislav Sedov  * Unparse the principal name with unparse flags to a fixed buffer.
523*ae771770SStanislav Sedov  *
524*ae771770SStanislav Sedov  * @param context A Kerberos context.
525*ae771770SStanislav Sedov  * @param principal principal to unparse
526*ae771770SStanislav Sedov  * @param flags unparse flags
527*ae771770SStanislav Sedov  * @param name buffer to write name to
528*ae771770SStanislav Sedov  * @param len length of buffer
529*ae771770SStanislav Sedov  *
530*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
531*ae771770SStanislav Sedov  *
532*ae771770SStanislav Sedov  * @ingroup krb5_principal
533*ae771770SStanislav Sedov  */
534*ae771770SStanislav Sedov 
535*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_unparse_name_fixed_flags(krb5_context context,krb5_const_principal principal,int flags,char * name,size_t len)536c19800e8SDoug Rabson krb5_unparse_name_fixed_flags(krb5_context context,
537c19800e8SDoug Rabson 			      krb5_const_principal principal,
538c19800e8SDoug Rabson 			      int flags,
539c19800e8SDoug Rabson 			      char *name,
540c19800e8SDoug Rabson 			      size_t len)
541c19800e8SDoug Rabson {
542c19800e8SDoug Rabson     return unparse_name_fixed(context, principal, name, len, flags);
543b528cefcSMark Murray }
544b528cefcSMark Murray 
545b528cefcSMark Murray static krb5_error_code
unparse_name(krb5_context context,krb5_const_principal principal,char ** name,int flags)546b528cefcSMark Murray unparse_name(krb5_context context,
547b528cefcSMark Murray 	     krb5_const_principal principal,
548b528cefcSMark Murray 	     char **name,
549c19800e8SDoug Rabson 	     int flags)
550b528cefcSMark Murray {
551b528cefcSMark Murray     size_t len = 0, plen;
552*ae771770SStanislav Sedov     size_t i;
553b528cefcSMark Murray     krb5_error_code ret;
554b528cefcSMark Murray     /* count length */
555c19800e8SDoug Rabson     if (princ_realm(principal)) {
556b528cefcSMark Murray 	plen = strlen(princ_realm(principal));
557c19800e8SDoug Rabson 
558b528cefcSMark Murray 	if(strcspn(princ_realm(principal), quotable_chars) == plen)
559b528cefcSMark Murray 	    len += plen;
560b528cefcSMark Murray 	else
561b528cefcSMark Murray 	    len += 2*plen;
562c19800e8SDoug Rabson 	len++; /* '@' */
563c19800e8SDoug Rabson     }
564b528cefcSMark Murray     for(i = 0; i < princ_num_comp(principal); i++){
565b528cefcSMark Murray 	plen = strlen(princ_ncomp(principal, i));
566b528cefcSMark Murray 	if(strcspn(princ_ncomp(principal, i), quotable_chars) == plen)
567b528cefcSMark Murray 	    len += plen;
568b528cefcSMark Murray 	else
569b528cefcSMark Murray 	    len += 2*plen;
570b528cefcSMark Murray 	len++;
571b528cefcSMark Murray     }
572c19800e8SDoug Rabson     len++; /* '\0' */
573b528cefcSMark Murray     *name = malloc(len);
5741c43270aSJacques Vidrine     if(*name == NULL) {
575*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM,
576*ae771770SStanislav Sedov 			       N_("malloc: out of memory", ""));
577b528cefcSMark Murray 	return ENOMEM;
578adb0ddaeSAssar Westerlund     }
579c19800e8SDoug Rabson     ret = unparse_name_fixed(context, principal, *name, len, flags);
5801c43270aSJacques Vidrine     if(ret) {
581b528cefcSMark Murray 	free(*name);
5821c43270aSJacques Vidrine 	*name = NULL;
5831c43270aSJacques Vidrine     }
584b528cefcSMark Murray     return ret;
585b528cefcSMark Murray }
586b528cefcSMark Murray 
587*ae771770SStanislav Sedov /**
588*ae771770SStanislav Sedov  * Unparse the Kerberos name into a string
589*ae771770SStanislav Sedov  *
590*ae771770SStanislav Sedov  * @param context Kerberos 5 context
591*ae771770SStanislav Sedov  * @param principal principal to query
592*ae771770SStanislav Sedov  * @param name resulting string, free with krb5_xfree()
593*ae771770SStanislav Sedov  *
594*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
595*ae771770SStanislav Sedov  *
596*ae771770SStanislav Sedov  * @ingroup krb5_principal
597*ae771770SStanislav Sedov  */
598*ae771770SStanislav Sedov 
599*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_unparse_name(krb5_context context,krb5_const_principal principal,char ** name)600b528cefcSMark Murray krb5_unparse_name(krb5_context context,
601b528cefcSMark Murray 		  krb5_const_principal principal,
602b528cefcSMark Murray 		  char **name)
603b528cefcSMark Murray {
604c19800e8SDoug Rabson     return unparse_name(context, principal, name, 0);
605b528cefcSMark Murray }
606b528cefcSMark Murray 
607*ae771770SStanislav Sedov /**
608*ae771770SStanislav Sedov  * Unparse the Kerberos name into a string
609*ae771770SStanislav Sedov  *
610*ae771770SStanislav Sedov  * @param context Kerberos 5 context
611*ae771770SStanislav Sedov  * @param principal principal to query
612*ae771770SStanislav Sedov  * @param flags flag to determine the behavior
613*ae771770SStanislav Sedov  * @param name resulting string, free with krb5_xfree()
614*ae771770SStanislav Sedov  *
615*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
616*ae771770SStanislav Sedov  *
617*ae771770SStanislav Sedov  * @ingroup krb5_principal
618*ae771770SStanislav Sedov  */
619*ae771770SStanislav Sedov 
620*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_unparse_name_flags(krb5_context context,krb5_const_principal principal,int flags,char ** name)621c19800e8SDoug Rabson krb5_unparse_name_flags(krb5_context context,
622c19800e8SDoug Rabson 			krb5_const_principal principal,
623c19800e8SDoug Rabson 			int flags,
624c19800e8SDoug Rabson 			char **name)
625c19800e8SDoug Rabson {
626c19800e8SDoug Rabson     return unparse_name(context, principal, name, flags);
627c19800e8SDoug Rabson }
628c19800e8SDoug Rabson 
629*ae771770SStanislav Sedov /**
630*ae771770SStanislav Sedov  * Unparse the principal name to a allocated buffer. The realm is
631*ae771770SStanislav Sedov  * skipped if its a default realm.
632*ae771770SStanislav Sedov  *
633*ae771770SStanislav Sedov  * @param context A Kerberos context.
634*ae771770SStanislav Sedov  * @param principal principal to unparse
635*ae771770SStanislav Sedov  * @param name returned buffer, free with krb5_xfree()
636*ae771770SStanislav Sedov  *
637*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
638*ae771770SStanislav Sedov  *
639*ae771770SStanislav Sedov  * @ingroup krb5_principal
640*ae771770SStanislav Sedov  */
641*ae771770SStanislav Sedov 
642*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_unparse_name_short(krb5_context context,krb5_const_principal principal,char ** name)643b528cefcSMark Murray krb5_unparse_name_short(krb5_context context,
644b528cefcSMark Murray 			krb5_const_principal principal,
645b528cefcSMark Murray 			char **name)
646b528cefcSMark Murray {
647c19800e8SDoug Rabson     return unparse_name(context, principal, name, KRB5_PRINCIPAL_UNPARSE_SHORT);
648b528cefcSMark Murray }
649b528cefcSMark Murray 
650*ae771770SStanislav Sedov /**
651*ae771770SStanislav Sedov  * Set a new realm for a principal, and as a side-effect free the
652*ae771770SStanislav Sedov  * previous realm.
653*ae771770SStanislav Sedov  *
654*ae771770SStanislav Sedov  * @param context A Kerberos context.
655*ae771770SStanislav Sedov  * @param principal principal set the realm for
656*ae771770SStanislav Sedov  * @param realm the new realm to set
657*ae771770SStanislav Sedov  *
658*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
659*ae771770SStanislav Sedov  *
660*ae771770SStanislav Sedov  * @ingroup krb5_principal
661*ae771770SStanislav Sedov  */
662b528cefcSMark Murray 
663*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_principal_set_realm(krb5_context context,krb5_principal principal,krb5_const_realm realm)664*ae771770SStanislav Sedov krb5_principal_set_realm(krb5_context context,
665b528cefcSMark Murray 			 krb5_principal principal,
666*ae771770SStanislav Sedov 			 krb5_const_realm realm)
667b528cefcSMark Murray {
668*ae771770SStanislav Sedov     if (princ_realm(principal))
669*ae771770SStanislav Sedov 	free(princ_realm(principal));
670*ae771770SStanislav Sedov 
671*ae771770SStanislav Sedov     princ_realm(principal) = strdup(realm);
672*ae771770SStanislav Sedov     if (princ_realm(principal) == NULL) {
673*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM,
674*ae771770SStanislav Sedov 			       N_("malloc: out of memory", ""));
675*ae771770SStanislav Sedov 	return ENOMEM;
676*ae771770SStanislav Sedov     }
677*ae771770SStanislav Sedov     return 0;
678b528cefcSMark Murray }
679b528cefcSMark Murray 
680*ae771770SStanislav Sedov #ifndef HEIMDAL_SMALLER
681*ae771770SStanislav Sedov /**
682*ae771770SStanislav Sedov  * Build a principal using vararg style building
683*ae771770SStanislav Sedov  *
684*ae771770SStanislav Sedov  * @param context A Kerberos context.
685*ae771770SStanislav Sedov  * @param principal returned principal
686*ae771770SStanislav Sedov  * @param rlen length of realm
687*ae771770SStanislav Sedov  * @param realm realm name
688*ae771770SStanislav Sedov  * @param ... a list of components ended with NULL.
689*ae771770SStanislav Sedov  *
690*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
691*ae771770SStanislav Sedov  *
692*ae771770SStanislav Sedov  * @ingroup krb5_principal
693*ae771770SStanislav Sedov  */
694b528cefcSMark Murray 
695*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_build_principal(krb5_context context,krb5_principal * principal,int rlen,krb5_const_realm realm,...)696b528cefcSMark Murray krb5_build_principal(krb5_context context,
697b528cefcSMark Murray 		     krb5_principal *principal,
698b528cefcSMark Murray 		     int rlen,
699b528cefcSMark Murray 		     krb5_const_realm realm,
700b528cefcSMark Murray 		     ...)
701b528cefcSMark Murray {
702b528cefcSMark Murray     krb5_error_code ret;
703b528cefcSMark Murray     va_list ap;
704b528cefcSMark Murray     va_start(ap, realm);
705b528cefcSMark Murray     ret = krb5_build_principal_va(context, principal, rlen, realm, ap);
706b528cefcSMark Murray     va_end(ap);
707b528cefcSMark Murray     return ret;
708b528cefcSMark Murray }
709*ae771770SStanislav Sedov #endif
710*ae771770SStanislav Sedov 
711*ae771770SStanislav Sedov /**
712*ae771770SStanislav Sedov  * Build a principal using vararg style building
713*ae771770SStanislav Sedov  *
714*ae771770SStanislav Sedov  * @param context A Kerberos context.
715*ae771770SStanislav Sedov  * @param principal returned principal
716*ae771770SStanislav Sedov  * @param realm realm name
717*ae771770SStanislav Sedov  * @param ... a list of components ended with NULL.
718*ae771770SStanislav Sedov  *
719*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
720*ae771770SStanislav Sedov  *
721*ae771770SStanislav Sedov  * @ingroup krb5_principal
722*ae771770SStanislav Sedov  */
723*ae771770SStanislav Sedov 
724*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_make_principal(krb5_context context,krb5_principal * principal,krb5_const_realm realm,...)725*ae771770SStanislav Sedov krb5_make_principal(krb5_context context,
726*ae771770SStanislav Sedov 		    krb5_principal *principal,
727*ae771770SStanislav Sedov 		    krb5_const_realm realm,
728*ae771770SStanislav Sedov 		    ...)
729*ae771770SStanislav Sedov {
730*ae771770SStanislav Sedov     krb5_error_code ret;
731*ae771770SStanislav Sedov     krb5_realm r = NULL;
732*ae771770SStanislav Sedov     va_list ap;
733*ae771770SStanislav Sedov     if(realm == NULL) {
734*ae771770SStanislav Sedov 	ret = krb5_get_default_realm(context, &r);
735*ae771770SStanislav Sedov 	if(ret)
736*ae771770SStanislav Sedov 	    return ret;
737*ae771770SStanislav Sedov 	realm = r;
738*ae771770SStanislav Sedov     }
739*ae771770SStanislav Sedov     va_start(ap, realm);
740*ae771770SStanislav Sedov     ret = krb5_build_principal_va(context, principal, strlen(realm), realm, ap);
741*ae771770SStanislav Sedov     va_end(ap);
742*ae771770SStanislav Sedov     if(r)
743*ae771770SStanislav Sedov 	free(r);
744*ae771770SStanislav Sedov     return ret;
745*ae771770SStanislav Sedov }
746b528cefcSMark Murray 
747b528cefcSMark Murray static krb5_error_code
append_component(krb5_context context,krb5_principal p,const char * comp,size_t comp_len)748b528cefcSMark Murray append_component(krb5_context context, krb5_principal p,
74913e3f4d6SMark Murray 		 const char *comp,
750b528cefcSMark Murray 		 size_t comp_len)
751b528cefcSMark Murray {
752c19800e8SDoug Rabson     heim_general_string *tmp;
753b528cefcSMark Murray     size_t len = princ_num_comp(p);
75413e3f4d6SMark Murray 
755b528cefcSMark Murray     tmp = realloc(princ_comp(p), (len + 1) * sizeof(*tmp));
756adb0ddaeSAssar Westerlund     if(tmp == NULL) {
757*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM,
758*ae771770SStanislav Sedov 			       N_("malloc: out of memory", ""));
759b528cefcSMark Murray 	return ENOMEM;
760adb0ddaeSAssar Westerlund     }
761b528cefcSMark Murray     princ_comp(p) = tmp;
762b528cefcSMark Murray     princ_ncomp(p, len) = malloc(comp_len + 1);
763adb0ddaeSAssar Westerlund     if (princ_ncomp(p, len) == NULL) {
764*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM,
765*ae771770SStanislav Sedov 			       N_("malloc: out of memory", ""));
76613e3f4d6SMark Murray 	return ENOMEM;
767adb0ddaeSAssar Westerlund     }
768b528cefcSMark Murray     memcpy (princ_ncomp(p, len), comp, comp_len);
769b528cefcSMark Murray     princ_ncomp(p, len)[comp_len] = '\0';
770b528cefcSMark Murray     princ_num_comp(p)++;
771b528cefcSMark Murray     return 0;
772b528cefcSMark Murray }
773b528cefcSMark Murray 
774b528cefcSMark Murray static void
va_ext_princ(krb5_context context,krb5_principal p,va_list ap)775b528cefcSMark Murray va_ext_princ(krb5_context context, krb5_principal p, va_list ap)
776b528cefcSMark Murray {
777b528cefcSMark Murray     while(1){
77813e3f4d6SMark Murray 	const char *s;
779b528cefcSMark Murray 	int len;
780b528cefcSMark Murray 	len = va_arg(ap, int);
781b528cefcSMark Murray 	if(len == 0)
782b528cefcSMark Murray 	    break;
78313e3f4d6SMark Murray 	s = va_arg(ap, const char*);
784b528cefcSMark Murray 	append_component(context, p, s, len);
785b528cefcSMark Murray     }
786b528cefcSMark Murray }
787b528cefcSMark Murray 
788b528cefcSMark Murray static void
va_princ(krb5_context context,krb5_principal p,va_list ap)789b528cefcSMark Murray va_princ(krb5_context context, krb5_principal p, va_list ap)
790b528cefcSMark Murray {
791b528cefcSMark Murray     while(1){
79213e3f4d6SMark Murray 	const char *s;
79313e3f4d6SMark Murray 	s = va_arg(ap, const char*);
794b528cefcSMark Murray 	if(s == NULL)
795b528cefcSMark Murray 	    break;
796b528cefcSMark Murray 	append_component(context, p, s, strlen(s));
797b528cefcSMark Murray     }
798b528cefcSMark Murray }
799b528cefcSMark Murray 
800b528cefcSMark Murray static krb5_error_code
build_principal(krb5_context context,krb5_principal * principal,int rlen,krb5_const_realm realm,void (* func)(krb5_context,krb5_principal,va_list),va_list ap)801b528cefcSMark Murray build_principal(krb5_context context,
802b528cefcSMark Murray 		krb5_principal *principal,
803b528cefcSMark Murray 		int rlen,
804b528cefcSMark Murray 		krb5_const_realm realm,
805b528cefcSMark Murray 		void (*func)(krb5_context, krb5_principal, va_list),
806b528cefcSMark Murray 		va_list ap)
807b528cefcSMark Murray {
808b528cefcSMark Murray     krb5_principal p;
809b528cefcSMark Murray 
810b528cefcSMark Murray     p = calloc(1, sizeof(*p));
811adb0ddaeSAssar Westerlund     if (p == NULL) {
812*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM,
813*ae771770SStanislav Sedov 			       N_("malloc: out of memory", ""));
814b528cefcSMark Murray 	return ENOMEM;
815adb0ddaeSAssar Westerlund     }
816b528cefcSMark Murray     princ_type(p) = KRB5_NT_PRINCIPAL;
817b528cefcSMark Murray 
818b528cefcSMark Murray     princ_realm(p) = strdup(realm);
819b528cefcSMark Murray     if(p->realm == NULL){
820b528cefcSMark Murray 	free(p);
821*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM,
822*ae771770SStanislav Sedov 			       N_("malloc: out of memory", ""));
823b528cefcSMark Murray 	return ENOMEM;
824b528cefcSMark Murray     }
825b528cefcSMark Murray 
826b528cefcSMark Murray     (*func)(context, p, ap);
827b528cefcSMark Murray     *principal = p;
828b528cefcSMark Murray     return 0;
829b528cefcSMark Murray }
830b528cefcSMark Murray 
831*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_build_principal_va(krb5_context context,krb5_principal * principal,int rlen,krb5_const_realm realm,va_list ap)832b528cefcSMark Murray krb5_build_principal_va(krb5_context context,
833b528cefcSMark Murray 			krb5_principal *principal,
834b528cefcSMark Murray 			int rlen,
835b528cefcSMark Murray 			krb5_const_realm realm,
836b528cefcSMark Murray 			va_list ap)
837b528cefcSMark Murray {
838b528cefcSMark Murray     return build_principal(context, principal, rlen, realm, va_princ, ap);
839b528cefcSMark Murray }
840b528cefcSMark Murray 
841*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_build_principal_va_ext(krb5_context context,krb5_principal * principal,int rlen,krb5_const_realm realm,va_list ap)842b528cefcSMark Murray krb5_build_principal_va_ext(krb5_context context,
843b528cefcSMark Murray 			    krb5_principal *principal,
844b528cefcSMark Murray 			    int rlen,
845b528cefcSMark Murray 			    krb5_const_realm realm,
846b528cefcSMark Murray 			    va_list ap)
847b528cefcSMark Murray {
848b528cefcSMark Murray     return build_principal(context, principal, rlen, realm, va_ext_princ, ap);
849b528cefcSMark Murray }
850b528cefcSMark Murray 
851b528cefcSMark Murray 
852*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_build_principal_ext(krb5_context context,krb5_principal * principal,int rlen,krb5_const_realm realm,...)853b528cefcSMark Murray krb5_build_principal_ext(krb5_context context,
854b528cefcSMark Murray 			 krb5_principal *principal,
855b528cefcSMark Murray 			 int rlen,
856b528cefcSMark Murray 			 krb5_const_realm realm,
857b528cefcSMark Murray 			 ...)
858b528cefcSMark Murray {
859b528cefcSMark Murray     krb5_error_code ret;
860b528cefcSMark Murray     va_list ap;
861b528cefcSMark Murray     va_start(ap, realm);
862b528cefcSMark Murray     ret = krb5_build_principal_va_ext(context, principal, rlen, realm, ap);
863b528cefcSMark Murray     va_end(ap);
864b528cefcSMark Murray     return ret;
865b528cefcSMark Murray }
866b528cefcSMark Murray 
867*ae771770SStanislav Sedov /**
868*ae771770SStanislav Sedov  * Copy a principal
869*ae771770SStanislav Sedov  *
870*ae771770SStanislav Sedov  * @param context A Kerberos context.
871*ae771770SStanislav Sedov  * @param inprinc principal to copy
872*ae771770SStanislav Sedov  * @param outprinc copied principal, free with krb5_free_principal()
873*ae771770SStanislav Sedov  *
874*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
875*ae771770SStanislav Sedov  *
876*ae771770SStanislav Sedov  * @ingroup krb5_principal
877*ae771770SStanislav Sedov  */
878b528cefcSMark Murray 
879*ae771770SStanislav Sedov 
880*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_copy_principal(krb5_context context,krb5_const_principal inprinc,krb5_principal * outprinc)881b528cefcSMark Murray krb5_copy_principal(krb5_context context,
882b528cefcSMark Murray 		    krb5_const_principal inprinc,
883b528cefcSMark Murray 		    krb5_principal *outprinc)
884b528cefcSMark Murray {
885b528cefcSMark Murray     krb5_principal p = malloc(sizeof(*p));
886adb0ddaeSAssar Westerlund     if (p == NULL) {
887*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM,
888*ae771770SStanislav Sedov 			       N_("malloc: out of memory", ""));
889b528cefcSMark Murray 	return ENOMEM;
890adb0ddaeSAssar Westerlund     }
891adb0ddaeSAssar Westerlund     if(copy_Principal(inprinc, p)) {
892adb0ddaeSAssar Westerlund 	free(p);
893*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM,
894*ae771770SStanislav Sedov 			       N_("malloc: out of memory", ""));
895b528cefcSMark Murray 	return ENOMEM;
896adb0ddaeSAssar Westerlund     }
897b528cefcSMark Murray     *outprinc = p;
898b528cefcSMark Murray     return 0;
899b528cefcSMark Murray }
900b528cefcSMark Murray 
901*ae771770SStanislav Sedov /**
902*ae771770SStanislav Sedov  * Return TRUE iff princ1 == princ2 (without considering the realm)
903*ae771770SStanislav Sedov  *
904*ae771770SStanislav Sedov  * @param context Kerberos 5 context
905*ae771770SStanislav Sedov  * @param princ1 first principal to compare
906*ae771770SStanislav Sedov  * @param princ2 second principal to compare
907*ae771770SStanislav Sedov  *
908*ae771770SStanislav Sedov  * @return non zero if equal, 0 if not
909*ae771770SStanislav Sedov  *
910*ae771770SStanislav Sedov  * @ingroup krb5_principal
911*ae771770SStanislav Sedov  * @see krb5_principal_compare()
912*ae771770SStanislav Sedov  * @see krb5_realm_compare()
9135e9cd1aeSAssar Westerlund  */
914b528cefcSMark Murray 
915*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
krb5_principal_compare_any_realm(krb5_context context,krb5_const_principal princ1,krb5_const_principal princ2)916b528cefcSMark Murray krb5_principal_compare_any_realm(krb5_context context,
917b528cefcSMark Murray 				 krb5_const_principal princ1,
918b528cefcSMark Murray 				 krb5_const_principal princ2)
919b528cefcSMark Murray {
920*ae771770SStanislav Sedov     size_t i;
921b528cefcSMark Murray     if(princ_num_comp(princ1) != princ_num_comp(princ2))
922b528cefcSMark Murray 	return FALSE;
923b528cefcSMark Murray     for(i = 0; i < princ_num_comp(princ1); i++){
924b528cefcSMark Murray 	if(strcmp(princ_ncomp(princ1, i), princ_ncomp(princ2, i)) != 0)
925b528cefcSMark Murray 	    return FALSE;
926b528cefcSMark Murray     }
927b528cefcSMark Murray     return TRUE;
928b528cefcSMark Murray }
929b528cefcSMark Murray 
930*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
_krb5_principal_compare_PrincipalName(krb5_context context,krb5_const_principal princ1,PrincipalName * princ2)931*ae771770SStanislav Sedov _krb5_principal_compare_PrincipalName(krb5_context context,
932*ae771770SStanislav Sedov 				      krb5_const_principal princ1,
933*ae771770SStanislav Sedov 				      PrincipalName *princ2)
934*ae771770SStanislav Sedov {
935*ae771770SStanislav Sedov     size_t i;
936*ae771770SStanislav Sedov     if (princ_num_comp(princ1) != princ2->name_string.len)
937*ae771770SStanislav Sedov 	return FALSE;
938*ae771770SStanislav Sedov     for(i = 0; i < princ_num_comp(princ1); i++){
939*ae771770SStanislav Sedov 	if(strcmp(princ_ncomp(princ1, i), princ2->name_string.val[i]) != 0)
940*ae771770SStanislav Sedov 	    return FALSE;
941*ae771770SStanislav Sedov     }
942*ae771770SStanislav Sedov     return TRUE;
943*ae771770SStanislav Sedov }
944*ae771770SStanislav Sedov 
945*ae771770SStanislav Sedov 
946*ae771770SStanislav Sedov /**
947*ae771770SStanislav Sedov  * Compares the two principals, including realm of the principals and returns
948*ae771770SStanislav Sedov  * TRUE if they are the same and FALSE if not.
949*ae771770SStanislav Sedov  *
950*ae771770SStanislav Sedov  * @param context Kerberos 5 context
951*ae771770SStanislav Sedov  * @param princ1 first principal to compare
952*ae771770SStanislav Sedov  * @param princ2 second principal to compare
953*ae771770SStanislav Sedov  *
954*ae771770SStanislav Sedov  * @ingroup krb5_principal
955*ae771770SStanislav Sedov  * @see krb5_principal_compare_any_realm()
956*ae771770SStanislav Sedov  * @see krb5_realm_compare()
957*ae771770SStanislav Sedov  */
958*ae771770SStanislav Sedov 
9595e9cd1aeSAssar Westerlund /*
9605e9cd1aeSAssar Westerlund  * return TRUE iff princ1 == princ2
9615e9cd1aeSAssar Westerlund  */
9625e9cd1aeSAssar Westerlund 
963*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
krb5_principal_compare(krb5_context context,krb5_const_principal princ1,krb5_const_principal princ2)964b528cefcSMark Murray krb5_principal_compare(krb5_context context,
965b528cefcSMark Murray 		       krb5_const_principal princ1,
966b528cefcSMark Murray 		       krb5_const_principal princ2)
967b528cefcSMark Murray {
968b528cefcSMark Murray     if(!krb5_realm_compare(context, princ1, princ2))
969b528cefcSMark Murray 	return FALSE;
970b528cefcSMark Murray     return krb5_principal_compare_any_realm(context, princ1, princ2);
971b528cefcSMark Murray }
972b528cefcSMark Murray 
973*ae771770SStanislav Sedov /**
9745e9cd1aeSAssar Westerlund  * return TRUE iff realm(princ1) == realm(princ2)
975*ae771770SStanislav Sedov  *
976*ae771770SStanislav Sedov  * @param context Kerberos 5 context
977*ae771770SStanislav Sedov  * @param princ1 first principal to compare
978*ae771770SStanislav Sedov  * @param princ2 second principal to compare
979*ae771770SStanislav Sedov  *
980*ae771770SStanislav Sedov  * @ingroup krb5_principal
981*ae771770SStanislav Sedov  * @see krb5_principal_compare_any_realm()
982*ae771770SStanislav Sedov  * @see krb5_principal_compare()
9835e9cd1aeSAssar Westerlund  */
984b528cefcSMark Murray 
985*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
krb5_realm_compare(krb5_context context,krb5_const_principal princ1,krb5_const_principal princ2)986b528cefcSMark Murray krb5_realm_compare(krb5_context context,
987b528cefcSMark Murray 		   krb5_const_principal princ1,
988b528cefcSMark Murray 		   krb5_const_principal princ2)
989b528cefcSMark Murray {
990b528cefcSMark Murray     return strcmp(princ_realm(princ1), princ_realm(princ2)) == 0;
991b528cefcSMark Murray }
992b528cefcSMark Murray 
993*ae771770SStanislav Sedov /**
9945e9cd1aeSAssar Westerlund  * return TRUE iff princ matches pattern
995*ae771770SStanislav Sedov  *
996*ae771770SStanislav Sedov  * @ingroup krb5_principal
9975e9cd1aeSAssar Westerlund  */
9985e9cd1aeSAssar Westerlund 
999*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
krb5_principal_match(krb5_context context,krb5_const_principal princ,krb5_const_principal pattern)10005e9cd1aeSAssar Westerlund krb5_principal_match(krb5_context context,
10015e9cd1aeSAssar Westerlund 		     krb5_const_principal princ,
10025e9cd1aeSAssar Westerlund 		     krb5_const_principal pattern)
10035e9cd1aeSAssar Westerlund {
1004*ae771770SStanislav Sedov     size_t i;
10055e9cd1aeSAssar Westerlund     if(princ_num_comp(princ) != princ_num_comp(pattern))
10065e9cd1aeSAssar Westerlund 	return FALSE;
10075e9cd1aeSAssar Westerlund     if(fnmatch(princ_realm(pattern), princ_realm(princ), 0) != 0)
10085e9cd1aeSAssar Westerlund 	return FALSE;
10095e9cd1aeSAssar Westerlund     for(i = 0; i < princ_num_comp(princ); i++){
10105e9cd1aeSAssar Westerlund 	if(fnmatch(princ_ncomp(pattern, i), princ_ncomp(princ, i), 0) != 0)
10115e9cd1aeSAssar Westerlund 	    return FALSE;
10125e9cd1aeSAssar Westerlund     }
10135e9cd1aeSAssar Westerlund     return TRUE;
10145e9cd1aeSAssar Westerlund }
10155e9cd1aeSAssar Westerlund 
1016*ae771770SStanislav Sedov /**
1017*ae771770SStanislav Sedov  * Create a principal for the service running on hostname. If
1018*ae771770SStanislav Sedov  * KRB5_NT_SRV_HST is used, the hostname is canonization using DNS (or
1019*ae771770SStanislav Sedov  * some other service), this is potentially insecure.
1020*ae771770SStanislav Sedov  *
1021*ae771770SStanislav Sedov  * @param context A Kerberos context.
1022*ae771770SStanislav Sedov  * @param hostname hostname to use
1023*ae771770SStanislav Sedov  * @param sname Service name to use
1024*ae771770SStanislav Sedov  * @param type name type of pricipal, use KRB5_NT_SRV_HST or KRB5_NT_UNKNOWN.
1025*ae771770SStanislav Sedov  * @param ret_princ return principal, free with krb5_free_principal().
1026*ae771770SStanislav Sedov  *
1027*ae771770SStanislav Sedov  * @return An krb5 error code, see krb5_get_error_message().
1028*ae771770SStanislav Sedov  *
1029*ae771770SStanislav Sedov  * @ingroup krb5_principal
10305e9cd1aeSAssar Westerlund  */
10315e9cd1aeSAssar Westerlund 
1032*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_sname_to_principal(krb5_context context,const char * hostname,const char * sname,int32_t type,krb5_principal * ret_princ)1033b528cefcSMark Murray krb5_sname_to_principal (krb5_context context,
1034b528cefcSMark Murray 			 const char *hostname,
1035b528cefcSMark Murray 			 const char *sname,
1036b528cefcSMark Murray 			 int32_t type,
1037b528cefcSMark Murray 			 krb5_principal *ret_princ)
1038b528cefcSMark Murray {
1039b528cefcSMark Murray     krb5_error_code ret;
10405e9cd1aeSAssar Westerlund     char localhost[MAXHOSTNAMELEN];
1041b528cefcSMark Murray     char **realms, *host = NULL;
1042b528cefcSMark Murray 
1043adb0ddaeSAssar Westerlund     if(type != KRB5_NT_SRV_HST && type != KRB5_NT_UNKNOWN) {
1044*ae771770SStanislav Sedov 	krb5_set_error_message(context, KRB5_SNAME_UNSUPP_NAMETYPE,
1045*ae771770SStanislav Sedov 			       N_("unsupported name type %d", ""),
1046*ae771770SStanislav Sedov 			       (int)type);
1047b528cefcSMark Murray 	return KRB5_SNAME_UNSUPP_NAMETYPE;
1048adb0ddaeSAssar Westerlund     }
1049b528cefcSMark Murray     if(hostname == NULL) {
1050*ae771770SStanislav Sedov 	ret = gethostname(localhost, sizeof(localhost) - 1);
1051*ae771770SStanislav Sedov 	if (ret != 0) {
1052*ae771770SStanislav Sedov 	    ret = errno;
1053*ae771770SStanislav Sedov 	    krb5_set_error_message(context, ret,
1054*ae771770SStanislav Sedov 				   N_("Failed to get local hostname", ""));
1055*ae771770SStanislav Sedov 	    return ret;
1056*ae771770SStanislav Sedov 	}
1057*ae771770SStanislav Sedov 	localhost[sizeof(localhost) - 1] = '\0';
1058b528cefcSMark Murray 	hostname = localhost;
1059b528cefcSMark Murray     }
1060b528cefcSMark Murray     if(sname == NULL)
1061b528cefcSMark Murray 	sname = "host";
1062b528cefcSMark Murray     if(type == KRB5_NT_SRV_HST) {
106313e3f4d6SMark Murray 	ret = krb5_expand_hostname_realms (context, hostname,
106413e3f4d6SMark Murray 					   &host, &realms);
1065b528cefcSMark Murray 	if (ret)
1066b528cefcSMark Murray 	    return ret;
1067b528cefcSMark Murray 	strlwr(host);
1068b528cefcSMark Murray 	hostname = host;
106913e3f4d6SMark Murray     } else {
1070b528cefcSMark Murray 	ret = krb5_get_host_realm(context, hostname, &realms);
1071b528cefcSMark Murray 	if(ret)
1072b528cefcSMark Murray 	    return ret;
107313e3f4d6SMark Murray     }
1074b528cefcSMark Murray 
1075b528cefcSMark Murray     ret = krb5_make_principal(context, ret_princ, realms[0], sname,
1076b528cefcSMark Murray 			      hostname, NULL);
1077b528cefcSMark Murray     if(host)
1078b528cefcSMark Murray 	free(host);
1079b528cefcSMark Murray     krb5_free_host_realm(context, realms);
1080b528cefcSMark Murray     return ret;
1081b528cefcSMark Murray }
1082c19800e8SDoug Rabson 
1083c19800e8SDoug Rabson static const struct {
1084c19800e8SDoug Rabson     const char *type;
1085c19800e8SDoug Rabson     int32_t value;
1086c19800e8SDoug Rabson } nametypes[] = {
1087c19800e8SDoug Rabson     { "UNKNOWN", KRB5_NT_UNKNOWN },
1088c19800e8SDoug Rabson     { "PRINCIPAL", KRB5_NT_PRINCIPAL },
1089c19800e8SDoug Rabson     { "SRV_INST", KRB5_NT_SRV_INST },
1090c19800e8SDoug Rabson     { "SRV_HST", KRB5_NT_SRV_HST },
1091c19800e8SDoug Rabson     { "SRV_XHST", KRB5_NT_SRV_XHST },
1092c19800e8SDoug Rabson     { "UID", KRB5_NT_UID },
1093c19800e8SDoug Rabson     { "X500_PRINCIPAL", KRB5_NT_X500_PRINCIPAL },
1094c19800e8SDoug Rabson     { "SMTP_NAME", KRB5_NT_SMTP_NAME },
1095c19800e8SDoug Rabson     { "ENTERPRISE_PRINCIPAL", KRB5_NT_ENTERPRISE_PRINCIPAL },
1096c19800e8SDoug Rabson     { "ENT_PRINCIPAL_AND_ID", KRB5_NT_ENT_PRINCIPAL_AND_ID },
1097c19800e8SDoug Rabson     { "MS_PRINCIPAL", KRB5_NT_MS_PRINCIPAL },
1098c19800e8SDoug Rabson     { "MS_PRINCIPAL_AND_ID", KRB5_NT_MS_PRINCIPAL_AND_ID },
1099*ae771770SStanislav Sedov     { NULL, 0 }
1100c19800e8SDoug Rabson };
1101c19800e8SDoug Rabson 
1102*ae771770SStanislav Sedov /**
1103*ae771770SStanislav Sedov  * Parse nametype string and return a nametype integer
1104*ae771770SStanislav Sedov  *
1105*ae771770SStanislav Sedov  * @ingroup krb5_principal
1106*ae771770SStanislav Sedov  */
1107*ae771770SStanislav Sedov 
1108*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_parse_nametype(krb5_context context,const char * str,int32_t * nametype)1109c19800e8SDoug Rabson krb5_parse_nametype(krb5_context context, const char *str, int32_t *nametype)
1110c19800e8SDoug Rabson {
1111c19800e8SDoug Rabson     size_t i;
1112c19800e8SDoug Rabson 
1113c19800e8SDoug Rabson     for(i = 0; nametypes[i].type; i++) {
1114c19800e8SDoug Rabson 	if (strcasecmp(nametypes[i].type, str) == 0) {
1115c19800e8SDoug Rabson 	    *nametype = nametypes[i].value;
1116c19800e8SDoug Rabson 	    return 0;
1117c19800e8SDoug Rabson 	}
1118c19800e8SDoug Rabson     }
1119*ae771770SStanislav Sedov     krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
1120*ae771770SStanislav Sedov 			   N_("Failed to find name type %s", ""), str);
1121c19800e8SDoug Rabson     return KRB5_PARSE_MALFORMED;
1122c19800e8SDoug Rabson }
1123*ae771770SStanislav Sedov 
1124*ae771770SStanislav Sedov /**
1125*ae771770SStanislav Sedov  * Check if the cname part of the principal is a krbtgt principal
1126*ae771770SStanislav Sedov  *
1127*ae771770SStanislav Sedov  * @ingroup krb5_principal
1128*ae771770SStanislav Sedov  */
1129*ae771770SStanislav Sedov 
1130*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
krb5_principal_is_krbtgt(krb5_context context,krb5_const_principal p)1131*ae771770SStanislav Sedov krb5_principal_is_krbtgt(krb5_context context, krb5_const_principal p)
1132*ae771770SStanislav Sedov {
1133*ae771770SStanislav Sedov     return p->name.name_string.len == 2 &&
1134*ae771770SStanislav Sedov 	strcmp(p->name.name_string.val[0], KRB5_TGS_NAME) == 0;
1135*ae771770SStanislav Sedov 
1136*ae771770SStanislav Sedov }
1137