2 * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "krb5_locl.h"
35 #ifdef HAVE_RES_SEARCH
38 #ifdef HAVE_ARPA_NAMESER_H
39 #include <arpa/nameser.h>
44 RCSID("$Id: principal.c 20223 2007-02-15 04:17:04Z lha $");
46 #define princ_num_comp(P) ((P)->name.name_string.len)
47 #define princ_type(P) ((P)->name.name_type)
48 #define princ_comp(P) ((P)->name.name_string.val)
49 #define princ_ncomp(P, N) ((P)->name.name_string.val[(N)])
50 #define princ_realm(P) ((P)->realm)
52 void KRB5_LIB_FUNCTION
53 krb5_free_principal(krb5_context context,
62 void KRB5_LIB_FUNCTION
63 krb5_principal_set_type(krb5_context context,
64 krb5_principal principal,
67 princ_type(principal) = type;
71 krb5_principal_get_type(krb5_context context,
72 krb5_const_principal principal)
74 return princ_type(principal);
77 const char* KRB5_LIB_FUNCTION
78 krb5_principal_get_realm(krb5_context context,
79 krb5_const_principal principal)
81 return princ_realm(principal);
84 const char* KRB5_LIB_FUNCTION
85 krb5_principal_get_comp_string(krb5_context context,
86 krb5_const_principal principal,
87 unsigned int component)
89 if(component >= princ_num_comp(principal))
91 return princ_ncomp(principal, component);
94 krb5_error_code KRB5_LIB_FUNCTION
95 krb5_parse_name_flags(krb5_context context,
98 krb5_principal *principal)
101 heim_general_string *comp;
102 heim_general_string realm = NULL;
114 int enterprise = (flags & KRB5_PRINCIPAL_PARSE_ENTERPRISE);
118 #define RFLAGS (KRB5_PRINCIPAL_PARSE_NO_REALM|KRB5_PRINCIPAL_PARSE_MUST_REALM)
120 if ((flags & RFLAGS) == RFLAGS) {
121 krb5_set_error_string(context, "Can't require both realm and "
122 "no realm at the same time");
123 return KRB5_ERR_NO_SERVICE;
127 /* count number of component,
128 * enterprise names only have one component
132 for(p = name; *p; p++){
135 krb5_set_error_string (context,
136 "trailing \\ in principal name");
137 return KRB5_PARSE_MALFORMED;
146 comp = calloc(ncomp, sizeof(*comp));
148 krb5_set_error_string (context, "malloc: out of memory");
153 p = start = q = s = strdup(name);
156 krb5_set_error_string (context, "malloc: out of memory");
172 krb5_set_error_string (context,
173 "trailing \\ in principal name");
174 ret = KRB5_PARSE_MALFORMED;
177 }else if(enterprise && first_at) {
180 }else if((c == '/' && !enterprise) || c == '@'){
182 krb5_set_error_string (context,
183 "part after realm in principal name");
184 ret = KRB5_PARSE_MALFORMED;
187 comp[n] = malloc(q - start + 1);
188 if (comp[n] == NULL) {
189 krb5_set_error_string (context, "malloc: out of memory");
193 memcpy(comp[n], start, q - start);
194 comp[n][q - start] = 0;
202 if(got_realm && (c == ':' || c == '/' || c == '\0')) {
203 krb5_set_error_string (context,
204 "part after realm in principal name");
205 ret = KRB5_PARSE_MALFORMED;
211 if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) {
212 krb5_set_error_string (context, "realm found in 'short' principal "
213 "expected to be without one");
214 ret = KRB5_PARSE_MALFORMED;
217 realm = malloc(q - start + 1);
219 krb5_set_error_string (context, "malloc: out of memory");
223 memcpy(realm, start, q - start);
224 realm[q - start] = 0;
226 if (flags & KRB5_PRINCIPAL_PARSE_MUST_REALM) {
227 krb5_set_error_string (context, "realm NOT found in principal "
228 "expected to be with one");
229 ret = KRB5_PARSE_MALFORMED;
231 } else if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) {
234 ret = krb5_get_default_realm (context, &realm);
239 comp[n] = malloc(q - start + 1);
240 if (comp[n] == NULL) {
241 krb5_set_error_string (context, "malloc: out of memory");
245 memcpy(comp[n], start, q - start);
246 comp[n][q - start] = 0;
249 *principal = malloc(sizeof(**principal));
250 if (*principal == NULL) {
251 krb5_set_error_string (context, "malloc: out of memory");
256 (*principal)->name.name_type = KRB5_NT_ENTERPRISE_PRINCIPAL;
258 (*principal)->name.name_type = KRB5_NT_PRINCIPAL;
259 (*principal)->name.name_string.val = comp;
260 princ_num_comp(*principal) = n;
261 (*principal)->realm = realm;
274 krb5_error_code KRB5_LIB_FUNCTION
275 krb5_parse_name(krb5_context context,
277 krb5_principal *principal)
279 return krb5_parse_name_flags(context, name, 0, principal);
282 static const char quotable_chars[] = " \n\t\b\\/@";
283 static const char replace_chars[] = " ntb\\/@";
285 #define add_char(BASE, INDEX, LEN, C) do { if((INDEX) < (LEN)) (BASE)[(INDEX)++] = (C); }while(0);
288 quote_string(const char *s, char *out, size_t idx, size_t len)
291 for(p = s; *p && idx < len; p++){
292 if((q = strchr(quotable_chars, *p))){
293 add_char(out, idx, len, '\\');
294 add_char(out, idx, len, replace_chars[q - quotable_chars]);
296 add_char(out, idx, len, *p);
304 static krb5_error_code
305 unparse_name_fixed(krb5_context context,
306 krb5_const_principal principal,
313 int short_form = (flags & KRB5_PRINCIPAL_UNPARSE_SHORT) != 0;
314 int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) != 0;
316 if (!no_realm && princ_realm(principal) == NULL) {
317 krb5_set_error_string(context, "Realm missing from principal, "
322 for(i = 0; i < princ_num_comp(principal); i++){
324 add_char(name, idx, len, '/');
325 idx = quote_string(princ_ncomp(principal, i), name, idx, len);
327 krb5_set_error_string(context, "Out of space printing principal");
331 /* add realm if different from default realm */
332 if(short_form && !no_realm) {
335 ret = krb5_get_default_realm(context, &r);
338 if(strcmp(princ_realm(principal), r) != 0)
342 if(!short_form && !no_realm) {
343 add_char(name, idx, len, '@');
344 idx = quote_string(princ_realm(principal), name, idx, len);
346 krb5_set_error_string(context,
347 "Out of space printing realm of principal");
354 krb5_error_code KRB5_LIB_FUNCTION
355 krb5_unparse_name_fixed(krb5_context context,
356 krb5_const_principal principal,
360 return unparse_name_fixed(context, principal, name, len, 0);
363 krb5_error_code KRB5_LIB_FUNCTION
364 krb5_unparse_name_fixed_short(krb5_context context,
365 krb5_const_principal principal,
369 return unparse_name_fixed(context, principal, name, len,
370 KRB5_PRINCIPAL_UNPARSE_SHORT);
373 krb5_error_code KRB5_LIB_FUNCTION
374 krb5_unparse_name_fixed_flags(krb5_context context,
375 krb5_const_principal principal,
380 return unparse_name_fixed(context, principal, name, len, flags);
383 static krb5_error_code
384 unparse_name(krb5_context context,
385 krb5_const_principal principal,
389 size_t len = 0, plen;
393 if (princ_realm(principal)) {
394 plen = strlen(princ_realm(principal));
396 if(strcspn(princ_realm(principal), quotable_chars) == plen)
402 for(i = 0; i < princ_num_comp(principal); i++){
403 plen = strlen(princ_ncomp(principal, i));
404 if(strcspn(princ_ncomp(principal, i), quotable_chars) == plen)
413 krb5_set_error_string (context, "malloc: out of memory");
416 ret = unparse_name_fixed(context, principal, *name, len, flags);
424 krb5_error_code KRB5_LIB_FUNCTION
425 krb5_unparse_name(krb5_context context,
426 krb5_const_principal principal,
429 return unparse_name(context, principal, name, 0);
432 krb5_error_code KRB5_LIB_FUNCTION
433 krb5_unparse_name_flags(krb5_context context,
434 krb5_const_principal principal,
438 return unparse_name(context, principal, name, flags);
441 krb5_error_code KRB5_LIB_FUNCTION
442 krb5_unparse_name_short(krb5_context context,
443 krb5_const_principal principal,
446 return unparse_name(context, principal, name, KRB5_PRINCIPAL_UNPARSE_SHORT);
449 #if 0 /* not implemented */
451 krb5_error_code KRB5_LIB_FUNCTION
452 krb5_unparse_name_ext(krb5_context context,
453 krb5_const_principal principal,
457 krb5_abortx(context, "unimplemented krb5_unparse_name_ext called");
462 krb5_realm * KRB5_LIB_FUNCTION
463 krb5_princ_realm(krb5_context context,
464 krb5_principal principal)
466 return &princ_realm(principal);
470 void KRB5_LIB_FUNCTION
471 krb5_princ_set_realm(krb5_context context,
472 krb5_principal principal,
475 princ_realm(principal) = *realm;
479 krb5_error_code KRB5_LIB_FUNCTION
480 krb5_build_principal(krb5_context context,
481 krb5_principal *principal,
483 krb5_const_realm realm,
489 ret = krb5_build_principal_va(context, principal, rlen, realm, ap);
494 static krb5_error_code
495 append_component(krb5_context context, krb5_principal p,
499 heim_general_string *tmp;
500 size_t len = princ_num_comp(p);
502 tmp = realloc(princ_comp(p), (len + 1) * sizeof(*tmp));
504 krb5_set_error_string (context, "malloc: out of memory");
508 princ_ncomp(p, len) = malloc(comp_len + 1);
509 if (princ_ncomp(p, len) == NULL) {
510 krb5_set_error_string (context, "malloc: out of memory");
513 memcpy (princ_ncomp(p, len), comp, comp_len);
514 princ_ncomp(p, len)[comp_len] = '\0';
520 va_ext_princ(krb5_context context, krb5_principal p, va_list ap)
525 len = va_arg(ap, int);
528 s = va_arg(ap, const char*);
529 append_component(context, p, s, len);
534 va_princ(krb5_context context, krb5_principal p, va_list ap)
538 s = va_arg(ap, const char*);
541 append_component(context, p, s, strlen(s));
546 static krb5_error_code
547 build_principal(krb5_context context,
548 krb5_principal *principal,
550 krb5_const_realm realm,
551 void (*func)(krb5_context, krb5_principal, va_list),
556 p = calloc(1, sizeof(*p));
558 krb5_set_error_string (context, "malloc: out of memory");
561 princ_type(p) = KRB5_NT_PRINCIPAL;
563 princ_realm(p) = strdup(realm);
564 if(p->realm == NULL){
566 krb5_set_error_string (context, "malloc: out of memory");
570 (*func)(context, p, ap);
575 krb5_error_code KRB5_LIB_FUNCTION
576 krb5_make_principal(krb5_context context,
577 krb5_principal *principal,
578 krb5_const_realm realm,
585 ret = krb5_get_default_realm(context, &r);
591 ret = krb5_build_principal_va(context, principal, strlen(realm), realm, ap);
598 krb5_error_code KRB5_LIB_FUNCTION
599 krb5_build_principal_va(krb5_context context,
600 krb5_principal *principal,
602 krb5_const_realm realm,
605 return build_principal(context, principal, rlen, realm, va_princ, ap);
608 krb5_error_code KRB5_LIB_FUNCTION
609 krb5_build_principal_va_ext(krb5_context context,
610 krb5_principal *principal,
612 krb5_const_realm realm,
615 return build_principal(context, principal, rlen, realm, va_ext_princ, ap);
619 krb5_error_code KRB5_LIB_FUNCTION
620 krb5_build_principal_ext(krb5_context context,
621 krb5_principal *principal,
623 krb5_const_realm realm,
629 ret = krb5_build_principal_va_ext(context, principal, rlen, realm, ap);
635 krb5_error_code KRB5_LIB_FUNCTION
636 krb5_copy_principal(krb5_context context,
637 krb5_const_principal inprinc,
638 krb5_principal *outprinc)
640 krb5_principal p = malloc(sizeof(*p));
642 krb5_set_error_string (context, "malloc: out of memory");
645 if(copy_Principal(inprinc, p)) {
647 krb5_set_error_string (context, "malloc: out of memory");
655 * return TRUE iff princ1 == princ2 (without considering the realm)
658 krb5_boolean KRB5_LIB_FUNCTION
659 krb5_principal_compare_any_realm(krb5_context context,
660 krb5_const_principal princ1,
661 krb5_const_principal princ2)
664 if(princ_num_comp(princ1) != princ_num_comp(princ2))
666 for(i = 0; i < princ_num_comp(princ1); i++){
667 if(strcmp(princ_ncomp(princ1, i), princ_ncomp(princ2, i)) != 0)
674 * return TRUE iff princ1 == princ2
677 krb5_boolean KRB5_LIB_FUNCTION
678 krb5_principal_compare(krb5_context context,
679 krb5_const_principal princ1,
680 krb5_const_principal princ2)
682 if(!krb5_realm_compare(context, princ1, princ2))
684 return krb5_principal_compare_any_realm(context, princ1, princ2);
688 * return TRUE iff realm(princ1) == realm(princ2)
691 krb5_boolean KRB5_LIB_FUNCTION
692 krb5_realm_compare(krb5_context context,
693 krb5_const_principal princ1,
694 krb5_const_principal princ2)
696 return strcmp(princ_realm(princ1), princ_realm(princ2)) == 0;
700 * return TRUE iff princ matches pattern
703 krb5_boolean KRB5_LIB_FUNCTION
704 krb5_principal_match(krb5_context context,
705 krb5_const_principal princ,
706 krb5_const_principal pattern)
709 if(princ_num_comp(princ) != princ_num_comp(pattern))
711 if(fnmatch(princ_realm(pattern), princ_realm(princ), 0) != 0)
713 for(i = 0; i < princ_num_comp(princ); i++){
714 if(fnmatch(princ_ncomp(pattern, i), princ_ncomp(princ, i), 0) != 0)
721 static struct v4_name_convert {
724 } default_v4_name_convert[] = {
726 { "hprop", "hprop" },
735 * return the converted instance name of `name' in `realm'.
736 * look in the configuration file and then in the default set above.
737 * return NULL if no conversion is appropriate.
741 get_name_conversion(krb5_context context, const char *realm, const char *name)
743 struct v4_name_convert *q;
746 p = krb5_config_get_string(context, NULL, "realms", realm,
747 "v4_name_convert", "host", name, NULL);
749 p = krb5_config_get_string(context, NULL, "libdefaults",
750 "v4_name_convert", "host", name, NULL);
754 /* XXX should be possible to override default list */
755 p = krb5_config_get_string(context, NULL,
764 p = krb5_config_get_string(context, NULL,
772 for(q = default_v4_name_convert; q->from; q++)
773 if(strcmp(q->from, name) == 0)
779 * convert the v4 principal `name.instance@realm' to a v5 principal in `princ'.
780 * if `resolve', use DNS.
781 * if `func', use that function for validating the conversion
784 krb5_error_code KRB5_LIB_FUNCTION
785 krb5_425_conv_principal_ext2(krb5_context context,
787 const char *instance,
789 krb5_boolean (*func)(krb5_context,
790 void *, krb5_principal),
792 krb5_boolean resolve,
793 krb5_principal *princ)
798 char host[MAXHOSTNAMELEN];
799 char local_hostname[MAXHOSTNAMELEN];
801 /* do the following: if the name is found in the
802 `v4_name_convert:host' part, is is assumed to be a `host' type
803 principal, and the instance is looked up in the
804 `v4_instance_convert' part. if not found there the name is
805 (optionally) looked up as a hostname, and if that doesn't yield
806 anything, the `default_domain' is appended to the instance
811 if(instance[0] == 0){
815 p = get_name_conversion(context, realm, name);
819 p = krb5_config_get_string(context, NULL, "realms", realm,
820 "v4_instance_convert", instance, NULL);
823 ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
824 if(func == NULL || (*func)(context, funcctx, pr)){
828 krb5_free_principal(context, pr);
830 krb5_clear_error_string (context);
831 return HEIM_ERR_V4_PRINC_NO_CONV;
834 krb5_boolean passed = FALSE;
839 r = dns_lookup(instance, "aaaa");
841 if (r->head && r->head->type == T_AAAA) {
842 inst = strdup(r->head->domain);
847 r = dns_lookup(instance, "a");
849 if(r->head && r->head->type == T_A) {
850 inst = strdup(r->head->domain);
857 struct addrinfo hints, *ai;
859 memset (&hints, 0, sizeof(hints));
860 hints.ai_flags = AI_CANONNAME;
861 ret = getaddrinfo(instance, NULL, &hints, &ai);
863 const struct addrinfo *a;
864 for (a = ai; a != NULL; a = a->ai_next) {
865 if (a->ai_canonname != NULL) {
866 inst = strdup (a->ai_canonname);
876 krb5_set_error_string (context, "malloc: out of memory");
880 ret = krb5_make_principal(context, &pr, realm, name, inst,
884 if(func == NULL || (*func)(context, funcctx, pr)){
888 krb5_free_principal(context, pr);
893 snprintf(host, sizeof(host), "%s.%s", instance, realm);
895 ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
896 if((*func)(context, funcctx, pr)){
900 krb5_free_principal(context, pr);
904 * if the instance is the first component of the local hostname,
905 * the converted host should be the long hostname.
909 gethostname (local_hostname, sizeof(local_hostname)) == 0 &&
910 strncmp(instance, local_hostname, strlen(instance)) == 0 &&
911 local_hostname[strlen(instance)] == '.') {
912 strlcpy(host, local_hostname, sizeof(host));
918 domains = krb5_config_get_strings(context, NULL, "realms", realm,
920 for(d = domains; d && *d; d++){
921 snprintf(host, sizeof(host), "%s.%s", instance, *d);
922 ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
923 if(func == NULL || (*func)(context, funcctx, pr)){
925 krb5_config_free_strings(domains);
928 krb5_free_principal(context, pr);
930 krb5_config_free_strings(domains);
934 p = krb5_config_get_string(context, NULL, "realms", realm,
935 "default_domain", NULL);
937 /* this should be an error, just faking a name is not good */
938 krb5_clear_error_string (context);
939 return HEIM_ERR_V4_PRINC_NO_CONV;
944 snprintf(host, sizeof(host), "%s.%s", instance, p);
946 ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
947 if(func == NULL || (*func)(context, funcctx, pr)){
951 krb5_free_principal(context, pr);
952 krb5_clear_error_string (context);
953 return HEIM_ERR_V4_PRINC_NO_CONV;
955 p = krb5_config_get_string(context, NULL,
963 p = krb5_config_get_string(context, NULL,
972 ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
973 if(func == NULL || (*func)(context, funcctx, pr)){
977 krb5_free_principal(context, pr);
978 krb5_clear_error_string (context);
979 return HEIM_ERR_V4_PRINC_NO_CONV;
983 convert_func(krb5_context conxtext, void *funcctx, krb5_principal principal)
985 krb5_boolean (*func)(krb5_context, krb5_principal) = funcctx;
986 return (*func)(conxtext, principal);
989 krb5_error_code KRB5_LIB_FUNCTION
990 krb5_425_conv_principal_ext(krb5_context context,
992 const char *instance,
994 krb5_boolean (*func)(krb5_context, krb5_principal),
995 krb5_boolean resolve,
996 krb5_principal *principal)
998 return krb5_425_conv_principal_ext2(context,
1002 func ? convert_func : NULL,
1010 krb5_error_code KRB5_LIB_FUNCTION
1011 krb5_425_conv_principal(krb5_context context,
1013 const char *instance,
1015 krb5_principal *princ)
1017 krb5_boolean resolve = krb5_config_get_bool(context,
1020 "v4_instance_resolve",
1023 return krb5_425_conv_principal_ext(context, name, instance, realm,
1024 NULL, resolve, princ);
1029 check_list(const krb5_config_binding *l, const char *name, const char **out)
1032 if (l->type != krb5_config_string)
1034 if(strcmp(name, l->u.string) == 0) {
1044 name_convert(krb5_context context, const char *name, const char *realm,
1047 const krb5_config_binding *l;
1048 l = krb5_config_get_list (context,
1055 if(l && check_list(l, name, out))
1056 return KRB5_NT_SRV_HST;
1057 l = krb5_config_get_list (context,
1063 if(l && check_list(l, name, out))
1064 return KRB5_NT_SRV_HST;
1065 l = krb5_config_get_list (context,
1072 if(l && check_list(l, name, out))
1073 return KRB5_NT_UNKNOWN;
1074 l = krb5_config_get_list (context,
1080 if(l && check_list(l, name, out))
1081 return KRB5_NT_UNKNOWN;
1083 /* didn't find it in config file, try built-in list */
1085 struct v4_name_convert *q;
1086 for(q = default_v4_name_convert; q->from; q++) {
1087 if(strcmp(name, q->to) == 0) {
1089 return KRB5_NT_SRV_HST;
1097 * convert the v5 principal in `principal' into a v4 corresponding one
1098 * in `name, instance, realm'
1099 * this is limited interface since there's no length given for these
1100 * three parameters. They have to be 40 bytes each (ANAME_SZ).
1103 krb5_error_code KRB5_LIB_FUNCTION
1104 krb5_524_conv_principal(krb5_context context,
1105 const krb5_principal principal,
1110 const char *n, *i, *r;
1112 int type = princ_type(principal);
1113 const int aname_sz = 40;
1115 r = principal->realm;
1117 switch(principal->name.name_string.len){
1119 n = principal->name.name_string.val[0];
1123 n = principal->name.name_string.val[0];
1124 i = principal->name.name_string.val[1];
1127 krb5_set_error_string (context,
1128 "cannot convert a %d component principal",
1129 principal->name.name_string.len);
1130 return KRB5_PARSE_MALFORMED;
1135 int t = name_convert(context, n, r, &tmp);
1142 if(type == KRB5_NT_SRV_HST){
1145 strlcpy (tmpinst, i, sizeof(tmpinst));
1146 p = strchr(tmpinst, '.');
1152 if (strlcpy (name, n, aname_sz) >= aname_sz) {
1153 krb5_set_error_string (context,
1154 "too long name component to convert");
1155 return KRB5_PARSE_MALFORMED;
1157 if (strlcpy (instance, i, aname_sz) >= aname_sz) {
1158 krb5_set_error_string (context,
1159 "too long instance component to convert");
1160 return KRB5_PARSE_MALFORMED;
1162 if (strlcpy (realm, r, aname_sz) >= aname_sz) {
1163 krb5_set_error_string (context,
1164 "too long realm component to convert");
1165 return KRB5_PARSE_MALFORMED;
1171 * Create a principal in `ret_princ' for the service `sname' running
1172 * on host `hostname'. */
1174 krb5_error_code KRB5_LIB_FUNCTION
1175 krb5_sname_to_principal (krb5_context context,
1176 const char *hostname,
1179 krb5_principal *ret_princ)
1181 krb5_error_code ret;
1182 char localhost[MAXHOSTNAMELEN];
1183 char **realms, *host = NULL;
1185 if(type != KRB5_NT_SRV_HST && type != KRB5_NT_UNKNOWN) {
1186 krb5_set_error_string (context, "unsupported name type %d",
1188 return KRB5_SNAME_UNSUPP_NAMETYPE;
1190 if(hostname == NULL) {
1191 gethostname(localhost, sizeof(localhost));
1192 hostname = localhost;
1196 if(type == KRB5_NT_SRV_HST) {
1197 ret = krb5_expand_hostname_realms (context, hostname,
1204 ret = krb5_get_host_realm(context, hostname, &realms);
1209 ret = krb5_make_principal(context, ret_princ, realms[0], sname,
1213 krb5_free_host_realm(context, realms);