1 /* $NetBSD: principal.c,v 1.1.1.2 2014/04/24 12:45:51 pettai Exp $ */
4 * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * @page krb5_principal_intro The principal handing functions.
39 * A Kerberos principal is a email address looking string that
40 * contains to parts separeted by a @. The later part is the kerbero
41 * realm the principal belongs to and the former is a list of 0 or
42 * more components. For example
45 host/hummel.it.su.se@SU.SE
49 * See the library functions here: @ref krb5_principal
52 #include "krb5_locl.h"
53 #ifdef HAVE_RES_SEARCH
56 #ifdef HAVE_ARPA_NAMESER_H
57 #include <arpa/nameser.h>
60 #include <krb5/resolve.h>
62 #define princ_num_comp(P) ((P)->name.name_string.len)
63 #define princ_type(P) ((P)->name.name_type)
64 #define princ_comp(P) ((P)->name.name_string.val)
65 #define princ_ncomp(P, N) ((P)->name.name_string.val[(N)])
66 #define princ_realm(P) ((P)->realm)
69 * Frees a Kerberos principal allocated by the library with
70 * krb5_parse_name(), krb5_make_principal() or any other related
71 * principal functions.
73 * @param context A Kerberos context.
74 * @param p a principal to free.
76 * @return An krb5 error code, see krb5_get_error_message().
78 * @ingroup krb5_principal
81 KRB5_LIB_FUNCTION
void KRB5_LIB_CALL
82 krb5_free_principal(krb5_context context
,
92 * Set the type of the principal
94 * @param context A Kerberos context.
95 * @param principal principal to set the type for
96 * @param type the new type
98 * @return An krb5 error code, see krb5_get_error_message().
100 * @ingroup krb5_principal
103 KRB5_LIB_FUNCTION
void KRB5_LIB_CALL
104 krb5_principal_set_type(krb5_context context
,
105 krb5_principal principal
,
108 princ_type(principal
) = type
;
112 * Get the type of the principal
114 * @param context A Kerberos context.
115 * @param principal principal to get the type for
117 * @return the type of principal
119 * @ingroup krb5_principal
122 KRB5_LIB_FUNCTION
int KRB5_LIB_CALL
123 krb5_principal_get_type(krb5_context context
,
124 krb5_const_principal principal
)
126 return princ_type(principal
);
130 * Get the realm of the principal
132 * @param context A Kerberos context.
133 * @param principal principal to get the realm for
135 * @return realm of the principal, don't free or use after krb5_principal is freed
137 * @ingroup krb5_principal
140 KRB5_LIB_FUNCTION
const char* KRB5_LIB_CALL
141 krb5_principal_get_realm(krb5_context context
,
142 krb5_const_principal principal
)
144 return princ_realm(principal
);
147 KRB5_LIB_FUNCTION
const char* KRB5_LIB_CALL
148 krb5_principal_get_comp_string(krb5_context context
,
149 krb5_const_principal principal
,
150 unsigned int component
)
152 if(component
>= princ_num_comp(principal
))
154 return princ_ncomp(principal
, component
);
158 * Get number of component is principal.
160 * @param context Kerberos 5 context
161 * @param principal principal to query
163 * @return number of components in string
165 * @ingroup krb5_principal
168 KRB5_LIB_FUNCTION
unsigned int KRB5_LIB_CALL
169 krb5_principal_get_num_comp(krb5_context context
,
170 krb5_const_principal principal
)
172 return princ_num_comp(principal
);
176 * Parse a name into a krb5_principal structure, flags controls the behavior.
178 * @param context Kerberos 5 context
179 * @param name name to parse into a Kerberos principal
180 * @param flags flags to control the behavior
181 * @param principal returned principal, free with krb5_free_principal().
183 * @return An krb5 error code, see krb5_get_error_message().
185 * @ingroup krb5_principal
188 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
189 krb5_parse_name_flags(krb5_context context
,
192 krb5_principal
*principal
)
195 heim_general_string
*comp
;
196 heim_general_string realm
= NULL
;
208 int enterprise
= (flags
& KRB5_PRINCIPAL_PARSE_ENTERPRISE
);
212 #define RFLAGS (KRB5_PRINCIPAL_PARSE_NO_REALM|KRB5_PRINCIPAL_PARSE_REQUIRE_REALM)
214 if ((flags
& RFLAGS
) == RFLAGS
) {
215 krb5_set_error_message(context
, KRB5_ERR_NO_SERVICE
,
216 N_("Can't require both realm and "
217 "no realm at the same time", ""));
218 return KRB5_ERR_NO_SERVICE
;
222 /* count number of component,
223 * enterprise names only have one component
227 for(p
= name
; *p
; p
++){
230 krb5_set_error_message(context
, KRB5_PARSE_MALFORMED
,
231 N_("trailing \\ in principal name", ""));
232 return KRB5_PARSE_MALFORMED
;
241 comp
= calloc(ncomp
, sizeof(*comp
));
243 krb5_set_error_message(context
, ENOMEM
,
244 N_("malloc: out of memory", ""));
249 p
= start
= q
= s
= strdup(name
);
252 krb5_set_error_message(context
, ENOMEM
,
253 N_("malloc: out of memory", ""));
269 ret
= KRB5_PARSE_MALFORMED
;
270 krb5_set_error_message(context
, ret
,
271 N_("trailing \\ in principal name", ""));
274 }else if(enterprise
&& first_at
) {
277 }else if((c
== '/' && !enterprise
) || c
== '@'){
279 ret
= KRB5_PARSE_MALFORMED
;
280 krb5_set_error_message(context
, ret
,
281 N_("part after realm in principal name", ""));
284 comp
[n
] = malloc(q
- start
+ 1);
285 if (comp
[n
] == NULL
) {
287 krb5_set_error_message(context
, ret
,
288 N_("malloc: out of memory", ""));
291 memcpy(comp
[n
], start
, q
- start
);
292 comp
[n
][q
- start
] = 0;
300 if(got_realm
&& (c
== '/' || c
== '\0')) {
301 ret
= KRB5_PARSE_MALFORMED
;
302 krb5_set_error_message(context
, ret
,
303 N_("part after realm in principal name", ""));
309 if (flags
& KRB5_PRINCIPAL_PARSE_NO_REALM
) {
310 ret
= KRB5_PARSE_MALFORMED
;
311 krb5_set_error_message(context
, ret
,
312 N_("realm found in 'short' principal "
313 "expected to be without one", ""));
316 realm
= malloc(q
- start
+ 1);
319 krb5_set_error_message(context
, ret
,
320 N_("malloc: out of memory", ""));
323 memcpy(realm
, start
, q
- start
);
324 realm
[q
- start
] = 0;
326 if (flags
& KRB5_PRINCIPAL_PARSE_REQUIRE_REALM
) {
327 ret
= KRB5_PARSE_MALFORMED
;
328 krb5_set_error_message(context
, ret
,
329 N_("realm NOT found in principal "
330 "expected to be with one", ""));
332 } else if (flags
& KRB5_PRINCIPAL_PARSE_NO_REALM
) {
335 ret
= krb5_get_default_realm (context
, &realm
);
340 comp
[n
] = malloc(q
- start
+ 1);
341 if (comp
[n
] == NULL
) {
343 krb5_set_error_message(context
, ret
,
344 N_("malloc: out of memory", ""));
347 memcpy(comp
[n
], start
, q
- start
);
348 comp
[n
][q
- start
] = 0;
351 *principal
= malloc(sizeof(**principal
));
352 if (*principal
== NULL
) {
354 krb5_set_error_message(context
, ret
,
355 N_("malloc: out of memory", ""));
359 (*principal
)->name
.name_type
= KRB5_NT_ENTERPRISE_PRINCIPAL
;
361 (*principal
)->name
.name_type
= KRB5_NT_PRINCIPAL
;
362 (*principal
)->name
.name_string
.val
= comp
;
363 princ_num_comp(*principal
) = n
;
364 (*principal
)->realm
= realm
;
378 * Parse a name into a krb5_principal structure
380 * @param context Kerberos 5 context
381 * @param name name to parse into a Kerberos principal
382 * @param principal returned principal, free with krb5_free_principal().
384 * @return An krb5 error code, see krb5_get_error_message().
386 * @ingroup krb5_principal
389 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
390 krb5_parse_name(krb5_context context
,
392 krb5_principal
*principal
)
394 return krb5_parse_name_flags(context
, name
, 0, principal
);
397 static const char quotable_chars
[] = " \n\t\b\\/@";
398 static const char replace_chars
[] = " ntb\\/@";
399 static const char nq_chars
[] = " \\/@";
401 #define add_char(BASE, INDEX, LEN, C) do { if((INDEX) < (LEN)) (BASE)[(INDEX)++] = (C); }while(0);
404 quote_string(const char *s
, char *out
, size_t idx
, size_t len
, int display
)
407 for(p
= s
; *p
&& idx
< len
; p
++){
408 q
= strchr(quotable_chars
, *p
);
410 add_char(out
, idx
, len
, replace_chars
[q
- quotable_chars
]);
412 add_char(out
, idx
, len
, '\\');
413 add_char(out
, idx
, len
, replace_chars
[q
- quotable_chars
]);
415 add_char(out
, idx
, len
, *p
);
423 static krb5_error_code
424 unparse_name_fixed(krb5_context context
,
425 krb5_const_principal principal
,
432 int short_form
= (flags
& KRB5_PRINCIPAL_UNPARSE_SHORT
) != 0;
433 int no_realm
= (flags
& KRB5_PRINCIPAL_UNPARSE_NO_REALM
) != 0;
434 int display
= (flags
& KRB5_PRINCIPAL_UNPARSE_DISPLAY
) != 0;
436 if (!no_realm
&& princ_realm(principal
) == NULL
) {
437 krb5_set_error_message(context
, ERANGE
,
438 N_("Realm missing from principal, "
439 "can't unparse", ""));
443 for(i
= 0; i
< princ_num_comp(principal
); i
++){
445 add_char(name
, idx
, len
, '/');
446 idx
= quote_string(princ_ncomp(principal
, i
), name
, idx
, len
, display
);
448 krb5_set_error_message(context
, ERANGE
,
449 N_("Out of space printing principal", ""));
453 /* add realm if different from default realm */
454 if(short_form
&& !no_realm
) {
457 ret
= krb5_get_default_realm(context
, &r
);
460 if(strcmp(princ_realm(principal
), r
) != 0)
464 if(!short_form
&& !no_realm
) {
465 add_char(name
, idx
, len
, '@');
466 idx
= quote_string(princ_realm(principal
), name
, idx
, len
, display
);
468 krb5_set_error_message(context
, ERANGE
,
469 N_("Out of space printing "
470 "realm of principal", ""));
478 * Unparse the principal name to a fixed buffer
480 * @param context A Kerberos context.
481 * @param principal principal to unparse
482 * @param name buffer to write name to
483 * @param len length of buffer
485 * @return An krb5 error code, see krb5_get_error_message().
487 * @ingroup krb5_principal
490 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
491 krb5_unparse_name_fixed(krb5_context context
,
492 krb5_const_principal principal
,
496 return unparse_name_fixed(context
, principal
, name
, len
, 0);
500 * Unparse the principal name to a fixed buffer. The realm is skipped
501 * if its a default realm.
503 * @param context A Kerberos context.
504 * @param principal principal to unparse
505 * @param name buffer to write name to
506 * @param len length of buffer
508 * @return An krb5 error code, see krb5_get_error_message().
510 * @ingroup krb5_principal
513 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
514 krb5_unparse_name_fixed_short(krb5_context context
,
515 krb5_const_principal principal
,
519 return unparse_name_fixed(context
, principal
, name
, len
,
520 KRB5_PRINCIPAL_UNPARSE_SHORT
);
524 * Unparse the principal name with unparse flags to a fixed buffer.
526 * @param context A Kerberos context.
527 * @param principal principal to unparse
528 * @param flags unparse flags
529 * @param name buffer to write name to
530 * @param len length of buffer
532 * @return An krb5 error code, see krb5_get_error_message().
534 * @ingroup krb5_principal
537 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
538 krb5_unparse_name_fixed_flags(krb5_context context
,
539 krb5_const_principal principal
,
544 return unparse_name_fixed(context
, principal
, name
, len
, flags
);
547 static krb5_error_code
548 unparse_name(krb5_context context
,
549 krb5_const_principal principal
,
553 size_t len
= 0, plen
;
557 if (princ_realm(principal
)) {
558 plen
= strlen(princ_realm(principal
));
560 if(strcspn(princ_realm(principal
), quotable_chars
) == plen
)
566 for(i
= 0; i
< princ_num_comp(principal
); i
++){
567 plen
= strlen(princ_ncomp(principal
, i
));
568 if(strcspn(princ_ncomp(principal
, i
), quotable_chars
) == plen
)
577 krb5_set_error_message(context
, ENOMEM
,
578 N_("malloc: out of memory", ""));
581 ret
= unparse_name_fixed(context
, principal
, *name
, len
, flags
);
590 * Unparse the Kerberos name into a string
592 * @param context Kerberos 5 context
593 * @param principal principal to query
594 * @param name resulting string, free with krb5_xfree()
596 * @return An krb5 error code, see krb5_get_error_message().
598 * @ingroup krb5_principal
601 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
602 krb5_unparse_name(krb5_context context
,
603 krb5_const_principal principal
,
606 return unparse_name(context
, principal
, name
, 0);
610 * Unparse the Kerberos name into a string
612 * @param context Kerberos 5 context
613 * @param principal principal to query
614 * @param flags flag to determine the behavior
615 * @param name resulting string, free with krb5_xfree()
617 * @return An krb5 error code, see krb5_get_error_message().
619 * @ingroup krb5_principal
622 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
623 krb5_unparse_name_flags(krb5_context context
,
624 krb5_const_principal principal
,
628 return unparse_name(context
, principal
, name
, flags
);
632 * Unparse the principal name to a allocated buffer. The realm is
633 * skipped if its a default realm.
635 * @param context A Kerberos context.
636 * @param principal principal to unparse
637 * @param name returned buffer, free with krb5_xfree()
639 * @return An krb5 error code, see krb5_get_error_message().
641 * @ingroup krb5_principal
644 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
645 krb5_unparse_name_short(krb5_context context
,
646 krb5_const_principal principal
,
649 return unparse_name(context
, principal
, name
, KRB5_PRINCIPAL_UNPARSE_SHORT
);
653 * Set a new realm for a principal, and as a side-effect free the
656 * @param context A Kerberos context.
657 * @param principal principal set the realm for
658 * @param realm the new realm to set
660 * @return An krb5 error code, see krb5_get_error_message().
662 * @ingroup krb5_principal
665 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
666 krb5_principal_set_realm(krb5_context context
,
667 krb5_principal principal
,
668 krb5_const_realm realm
)
670 if (princ_realm(principal
))
671 free(princ_realm(principal
));
673 princ_realm(principal
) = strdup(realm
);
674 if (princ_realm(principal
) == NULL
) {
675 krb5_set_error_message(context
, ENOMEM
,
676 N_("malloc: out of memory", ""));
682 #ifndef HEIMDAL_SMALLER
684 * Build a principal using vararg style building
686 * @param context A Kerberos context.
687 * @param principal returned principal
688 * @param rlen length of realm
689 * @param realm realm name
690 * @param ... a list of components ended with NULL.
692 * @return An krb5 error code, see krb5_get_error_message().
694 * @ingroup krb5_principal
697 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
698 krb5_build_principal(krb5_context context
,
699 krb5_principal
*principal
,
701 krb5_const_realm realm
,
707 ret
= krb5_build_principal_va(context
, principal
, rlen
, realm
, ap
);
714 * Build a principal using vararg style building
716 * @param context A Kerberos context.
717 * @param principal returned principal
718 * @param realm realm name
719 * @param ... a list of components ended with NULL.
721 * @return An krb5 error code, see krb5_get_error_message().
723 * @ingroup krb5_principal
726 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
727 krb5_make_principal(krb5_context context
,
728 krb5_principal
*principal
,
729 krb5_const_realm realm
,
736 ret
= krb5_get_default_realm(context
, &r
);
742 ret
= krb5_build_principal_va(context
, principal
, strlen(realm
), realm
, ap
);
749 static krb5_error_code
750 append_component(krb5_context context
, krb5_principal p
,
754 heim_general_string
*tmp
;
755 size_t len
= princ_num_comp(p
);
757 tmp
= realloc(princ_comp(p
), (len
+ 1) * sizeof(*tmp
));
759 krb5_set_error_message(context
, ENOMEM
,
760 N_("malloc: out of memory", ""));
764 princ_ncomp(p
, len
) = malloc(comp_len
+ 1);
765 if (princ_ncomp(p
, len
) == NULL
) {
766 krb5_set_error_message(context
, ENOMEM
,
767 N_("malloc: out of memory", ""));
770 memcpy (princ_ncomp(p
, len
), comp
, comp_len
);
771 princ_ncomp(p
, len
)[comp_len
] = '\0';
777 va_ext_princ(krb5_context context
, krb5_principal p
, va_list ap
)
782 len
= va_arg(ap
, int);
785 s
= va_arg(ap
, const char*);
786 append_component(context
, p
, s
, len
);
791 va_princ(krb5_context context
, krb5_principal p
, va_list ap
)
795 s
= va_arg(ap
, const char*);
798 append_component(context
, p
, s
, strlen(s
));
802 static krb5_error_code
803 build_principal(krb5_context context
,
804 krb5_principal
*principal
,
806 krb5_const_realm realm
,
807 void (*func
)(krb5_context
, krb5_principal
, va_list),
812 p
= calloc(1, sizeof(*p
));
814 krb5_set_error_message(context
, ENOMEM
,
815 N_("malloc: out of memory", ""));
818 princ_type(p
) = KRB5_NT_PRINCIPAL
;
820 princ_realm(p
) = strdup(realm
);
821 if(p
->realm
== NULL
){
823 krb5_set_error_message(context
, ENOMEM
,
824 N_("malloc: out of memory", ""));
828 (*func
)(context
, p
, ap
);
833 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
834 krb5_build_principal_va(krb5_context context
,
835 krb5_principal
*principal
,
837 krb5_const_realm realm
,
840 return build_principal(context
, principal
, rlen
, realm
, va_princ
, ap
);
843 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
844 krb5_build_principal_va_ext(krb5_context context
,
845 krb5_principal
*principal
,
847 krb5_const_realm realm
,
850 return build_principal(context
, principal
, rlen
, realm
, va_ext_princ
, ap
);
854 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
855 krb5_build_principal_ext(krb5_context context
,
856 krb5_principal
*principal
,
858 krb5_const_realm realm
,
864 ret
= krb5_build_principal_va_ext(context
, principal
, rlen
, realm
, ap
);
872 * @param context A Kerberos context.
873 * @param inprinc principal to copy
874 * @param outprinc copied principal, free with krb5_free_principal()
876 * @return An krb5 error code, see krb5_get_error_message().
878 * @ingroup krb5_principal
882 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
883 krb5_copy_principal(krb5_context context
,
884 krb5_const_principal inprinc
,
885 krb5_principal
*outprinc
)
887 krb5_principal p
= malloc(sizeof(*p
));
889 krb5_set_error_message(context
, ENOMEM
,
890 N_("malloc: out of memory", ""));
893 if(copy_Principal(inprinc
, p
)) {
895 krb5_set_error_message(context
, ENOMEM
,
896 N_("malloc: out of memory", ""));
904 * Return TRUE iff princ1 == princ2 (without considering the realm)
906 * @param context Kerberos 5 context
907 * @param princ1 first principal to compare
908 * @param princ2 second principal to compare
910 * @return non zero if equal, 0 if not
912 * @ingroup krb5_principal
913 * @see krb5_principal_compare()
914 * @see krb5_realm_compare()
917 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
918 krb5_principal_compare_any_realm(krb5_context context
,
919 krb5_const_principal princ1
,
920 krb5_const_principal princ2
)
923 if(princ_num_comp(princ1
) != princ_num_comp(princ2
))
925 for(i
= 0; i
< princ_num_comp(princ1
); i
++){
926 if(strcmp(princ_ncomp(princ1
, i
), princ_ncomp(princ2
, i
)) != 0)
932 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
933 _krb5_principal_compare_PrincipalName(krb5_context context
,
934 krb5_const_principal princ1
,
935 PrincipalName
*princ2
)
938 if (princ_num_comp(princ1
) != princ2
->name_string
.len
)
940 for(i
= 0; i
< princ_num_comp(princ1
); i
++){
941 if(strcmp(princ_ncomp(princ1
, i
), princ2
->name_string
.val
[i
]) != 0)
949 * Compares the two principals, including realm of the principals and returns
950 * TRUE if they are the same and FALSE if not.
952 * @param context Kerberos 5 context
953 * @param princ1 first principal to compare
954 * @param princ2 second principal to compare
956 * @ingroup krb5_principal
957 * @see krb5_principal_compare_any_realm()
958 * @see krb5_realm_compare()
962 * return TRUE iff princ1 == princ2
965 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
966 krb5_principal_compare(krb5_context context
,
967 krb5_const_principal princ1
,
968 krb5_const_principal princ2
)
970 if(!krb5_realm_compare(context
, princ1
, princ2
))
972 return krb5_principal_compare_any_realm(context
, princ1
, princ2
);
976 * return TRUE iff realm(princ1) == realm(princ2)
978 * @param context Kerberos 5 context
979 * @param princ1 first principal to compare
980 * @param princ2 second principal to compare
982 * @ingroup krb5_principal
983 * @see krb5_principal_compare_any_realm()
984 * @see krb5_principal_compare()
987 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
988 krb5_realm_compare(krb5_context context
,
989 krb5_const_principal princ1
,
990 krb5_const_principal princ2
)
992 return strcmp(princ_realm(princ1
), princ_realm(princ2
)) == 0;
996 * return TRUE iff princ matches pattern
998 * @ingroup krb5_principal
1001 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
1002 krb5_principal_match(krb5_context context
,
1003 krb5_const_principal princ
,
1004 krb5_const_principal pattern
)
1007 if(princ_num_comp(princ
) != princ_num_comp(pattern
))
1009 if(fnmatch(princ_realm(pattern
), princ_realm(princ
), 0) != 0)
1011 for(i
= 0; i
< princ_num_comp(princ
); i
++){
1012 if(fnmatch(princ_ncomp(pattern
, i
), princ_ncomp(princ
, i
), 0) != 0)
1019 * Create a principal for the service running on hostname. If
1020 * KRB5_NT_SRV_HST is used, the hostname is canonization using DNS (or
1021 * some other service), this is potentially insecure.
1023 * @param context A Kerberos context.
1024 * @param hostname hostname to use
1025 * @param sname Service name to use
1026 * @param type name type of pricipal, use KRB5_NT_SRV_HST or KRB5_NT_UNKNOWN.
1027 * @param ret_princ return principal, free with krb5_free_principal().
1029 * @return An krb5 error code, see krb5_get_error_message().
1031 * @ingroup krb5_principal
1034 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1035 krb5_sname_to_principal (krb5_context context
,
1036 const char *hostname
,
1039 krb5_principal
*ret_princ
)
1041 krb5_error_code ret
;
1042 char localhost
[MAXHOSTNAMELEN
];
1043 char **realms
, *host
= NULL
;
1045 if(type
!= KRB5_NT_SRV_HST
&& type
!= KRB5_NT_UNKNOWN
) {
1046 krb5_set_error_message(context
, KRB5_SNAME_UNSUPP_NAMETYPE
,
1047 N_("unsupported name type %d", ""),
1049 return KRB5_SNAME_UNSUPP_NAMETYPE
;
1051 if(hostname
== NULL
) {
1052 ret
= gethostname(localhost
, sizeof(localhost
) - 1);
1055 krb5_set_error_message(context
, ret
,
1056 N_("Failed to get local hostname", ""));
1059 localhost
[sizeof(localhost
) - 1] = '\0';
1060 hostname
= localhost
;
1064 if(type
== KRB5_NT_SRV_HST
) {
1065 ret
= krb5_expand_hostname_realms (context
, hostname
,
1072 ret
= krb5_get_host_realm(context
, hostname
, &realms
);
1077 ret
= krb5_make_principal(context
, ret_princ
, realms
[0], sname
,
1081 krb5_free_host_realm(context
, realms
);
1085 static const struct {
1089 { "UNKNOWN", KRB5_NT_UNKNOWN
},
1090 { "PRINCIPAL", KRB5_NT_PRINCIPAL
},
1091 { "SRV_INST", KRB5_NT_SRV_INST
},
1092 { "SRV_HST", KRB5_NT_SRV_HST
},
1093 { "SRV_XHST", KRB5_NT_SRV_XHST
},
1094 { "UID", KRB5_NT_UID
},
1095 { "X500_PRINCIPAL", KRB5_NT_X500_PRINCIPAL
},
1096 { "SMTP_NAME", KRB5_NT_SMTP_NAME
},
1097 { "ENTERPRISE_PRINCIPAL", KRB5_NT_ENTERPRISE_PRINCIPAL
},
1098 { "ENT_PRINCIPAL_AND_ID", KRB5_NT_ENT_PRINCIPAL_AND_ID
},
1099 { "MS_PRINCIPAL", KRB5_NT_MS_PRINCIPAL
},
1100 { "MS_PRINCIPAL_AND_ID", KRB5_NT_MS_PRINCIPAL_AND_ID
},
1105 * Parse nametype string and return a nametype integer
1107 * @ingroup krb5_principal
1110 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1111 krb5_parse_nametype(krb5_context context
, const char *str
, int32_t *nametype
)
1115 for(i
= 0; nametypes
[i
].type
; i
++) {
1116 if (strcasecmp(nametypes
[i
].type
, str
) == 0) {
1117 *nametype
= nametypes
[i
].value
;
1121 krb5_set_error_message(context
, KRB5_PARSE_MALFORMED
,
1122 N_("Failed to find name type %s", ""), str
);
1123 return KRB5_PARSE_MALFORMED
;
1127 * Check if the cname part of the principal is a krbtgt principal
1129 * @ingroup krb5_principal
1132 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
1133 krb5_principal_is_krbtgt(krb5_context context
, krb5_const_principal p
)
1135 return p
->name
.name_string
.len
== 2 &&
1136 strcmp(p
->name
.name_string
.val
[0], KRB5_TGS_NAME
) == 0;