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