📄 principal.c
字号:
ret = krb5_make_principal(context, &pr, realm, name, instance, NULL); if(func == NULL || (*func)(context, funcctx, pr)){ *princ = pr; return 0; } krb5_free_principal(context, pr); *princ = NULL; krb5_clear_error_string (context); return HEIM_ERR_V4_PRINC_NO_CONV; } if(resolve){ krb5_boolean passed = FALSE; char *inst = NULL;#ifdef USE_RESOLVER struct dns_reply *r; r = dns_lookup(instance, "aaaa"); if (r) { if (r->head && r->head->type == T_AAAA) { inst = strdup(r->head->domain); passed = TRUE; } dns_free_data(r); } else { r = dns_lookup(instance, "a"); if (r) { if(r->head && r->head->type == T_A) { inst = strdup(r->head->domain); passed = TRUE; } dns_free_data(r); } }#else struct addrinfo hints, *ai; memset (&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; ret = getaddrinfo(instance, NULL, &hints, &ai); if (ret == 0) { const struct addrinfo *a; for (a = ai; a != NULL; a = a->ai_next) { if (a->ai_canonname != NULL) { inst = strdup (a->ai_canonname); passed = TRUE; break; } } freeaddrinfo (ai); }#endif if (passed) { if (inst == NULL) { krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } strlwr(inst); ret = krb5_make_principal(context, &pr, realm, name, inst, NULL); free (inst); if(ret == 0) { if(func == NULL || (*func)(context, funcctx, pr)){ *princ = pr; return 0; } krb5_free_principal(context, pr); } } } if(func != NULL) { snprintf(host, sizeof(host), "%s.%s", instance, realm); strlwr(host); ret = krb5_make_principal(context, &pr, realm, name, host, NULL); if((*func)(context, funcctx, pr)){ *princ = pr; return 0; } krb5_free_principal(context, pr); } /* * if the instance is the first component of the local hostname, * the converted host should be the long hostname. */ if (func == NULL && gethostname (local_hostname, sizeof(local_hostname)) == 0 && strncmp(instance, local_hostname, strlen(instance)) == 0 && local_hostname[strlen(instance)] == '.') { strlcpy(host, local_hostname, sizeof(host)); goto local_host; } { char **domains, **d; domains = krb5_config_get_strings(context, NULL, "realms", realm, "v4_domains", NULL); for(d = domains; d && *d; d++){ snprintf(host, sizeof(host), "%s.%s", instance, *d); ret = krb5_make_principal(context, &pr, realm, name, host, NULL); if(func == NULL || (*func)(context, funcctx, pr)){ *princ = pr; krb5_config_free_strings(domains); return 0; } krb5_free_principal(context, pr); } krb5_config_free_strings(domains); } p = krb5_config_get_string(context, NULL, "realms", realm, "default_domain", NULL); if(p == NULL){ /* this should be an error, just faking a name is not good */ krb5_clear_error_string (context); return HEIM_ERR_V4_PRINC_NO_CONV; } if (*p == '.') ++p; snprintf(host, sizeof(host), "%s.%s", instance, p);local_host: ret = krb5_make_principal(context, &pr, realm, name, host, NULL); if(func == NULL || (*func)(context, funcctx, pr)){ *princ = pr; return 0; } krb5_free_principal(context, pr); krb5_clear_error_string (context); return HEIM_ERR_V4_PRINC_NO_CONV;no_host: p = krb5_config_get_string(context, NULL, "realms", realm, "v4_name_convert", "plain", name, NULL); if(p == NULL) p = krb5_config_get_string(context, NULL, "libdefaults", "v4_name_convert", "plain", name, NULL); if(p) name = p; ret = krb5_make_principal(context, &pr, realm, name, instance, NULL); if(func == NULL || (*func)(context, funcctx, pr)){ *princ = pr; return 0; } krb5_free_principal(context, pr); krb5_clear_error_string (context); return HEIM_ERR_V4_PRINC_NO_CONV;}static krb5_booleanconvert_func(krb5_context conxtext, void *funcctx, krb5_principal principal){ krb5_boolean (*func)(krb5_context, krb5_principal) = funcctx; return (*func)(conxtext, principal);}krb5_error_code KRB5_LIB_FUNCTIONkrb5_425_conv_principal_ext(krb5_context context, const char *name, const char *instance, const char *realm, krb5_boolean (*func)(krb5_context, krb5_principal), krb5_boolean resolve, krb5_principal *principal){ return krb5_425_conv_principal_ext2(context, name, instance, realm, func ? convert_func : NULL, func, resolve, principal);}krb5_error_code KRB5_LIB_FUNCTIONkrb5_425_conv_principal(krb5_context context, const char *name, const char *instance, const char *realm, krb5_principal *princ){ krb5_boolean resolve = krb5_config_get_bool(context, NULL, "libdefaults", "v4_instance_resolve", NULL); return krb5_425_conv_principal_ext(context, name, instance, realm, NULL, resolve, princ);}static intcheck_list(const krb5_config_binding *l, const char *name, const char **out){ while(l){ if (l->type != krb5_config_string) continue; if(strcmp(name, l->u.string) == 0) { *out = l->name; return 1; } l = l->next; } return 0;}static intname_convert(krb5_context context, const char *name, const char *realm, const char **out){ const krb5_config_binding *l; l = krb5_config_get_list (context, NULL, "realms", realm, "v4_name_convert", "host", NULL); if(l && check_list(l, name, out)) return KRB5_NT_SRV_HST; l = krb5_config_get_list (context, NULL, "libdefaults", "v4_name_convert", "host", NULL); if(l && check_list(l, name, out)) return KRB5_NT_SRV_HST; l = krb5_config_get_list (context, NULL, "realms", realm, "v4_name_convert", "plain", NULL); if(l && check_list(l, name, out)) return KRB5_NT_UNKNOWN; l = krb5_config_get_list (context, NULL, "libdefaults", "v4_name_convert", "host", NULL); if(l && check_list(l, name, out)) return KRB5_NT_UNKNOWN; /* didn't find it in config file, try built-in list */ { struct v4_name_convert *q; for(q = default_v4_name_convert; q->from; q++) { if(strcmp(name, q->to) == 0) { *out = q->from; return KRB5_NT_SRV_HST; } } } return -1;}/* * convert the v5 principal in `principal' into a v4 corresponding one * in `name, instance, realm' * this is limited interface since there's no length given for these * three parameters. They have to be 40 bytes each (ANAME_SZ). */krb5_error_code KRB5_LIB_FUNCTIONkrb5_524_conv_principal(krb5_context context, const krb5_principal principal, char *name, char *instance, char *realm){ const char *n, *i, *r; char tmpinst[40]; int type = princ_type(principal); const int aname_sz = 40; r = principal->realm; switch(principal->name.name_string.len){ case 1: n = principal->name.name_string.val[0]; i = ""; break; case 2: n = principal->name.name_string.val[0]; i = principal->name.name_string.val[1]; break; default: krb5_set_error_string (context, "cannot convert a %d component principal", principal->name.name_string.len); return KRB5_PARSE_MALFORMED; } { const char *tmp; int t = name_convert(context, n, r, &tmp); if(t >= 0) { type = t; n = tmp; } } if(type == KRB5_NT_SRV_HST){ char *p; strlcpy (tmpinst, i, sizeof(tmpinst)); p = strchr(tmpinst, '.'); if(p) *p = 0; i = tmpinst; } if (strlcpy (name, n, aname_sz) >= aname_sz) { krb5_set_error_string (context, "too long name component to convert"); return KRB5_PARSE_MALFORMED; } if (strlcpy (instance, i, aname_sz) >= aname_sz) { krb5_set_error_string (context, "too long instance component to convert"); return KRB5_PARSE_MALFORMED; } if (strlcpy (realm, r, aname_sz) >= aname_sz) { krb5_set_error_string (context, "too long realm component to convert"); return KRB5_PARSE_MALFORMED; } return 0;}/* * Create a principal in `ret_princ' for the service `sname' running * on host `hostname'. */ krb5_error_code KRB5_LIB_FUNCTIONkrb5_sname_to_principal (krb5_context context, const char *hostname, const char *sname, int32_t type, krb5_principal *ret_princ){ krb5_error_code ret; char localhost[MAXHOSTNAMELEN]; char **realms, *host = NULL; if(type != KRB5_NT_SRV_HST && type != KRB5_NT_UNKNOWN) { krb5_set_error_string (context, "unsupported name type %d", type); return KRB5_SNAME_UNSUPP_NAMETYPE; } if(hostname == NULL) { gethostname(localhost, sizeof(localhost)); hostname = localhost; } if(sname == NULL) sname = "host"; if(type == KRB5_NT_SRV_HST) { ret = krb5_expand_hostname_realms (context, hostname, &host, &realms); if (ret) return ret; strlwr(host); hostname = host; } else { ret = krb5_get_host_realm(context, hostname, &realms); if(ret) return ret; } ret = krb5_make_principal(context, ret_princ, realms[0], sname, hostname, NULL); if(host) free(host); krb5_free_host_realm(context, realms); return ret;}static const struct { const char *type; int32_t value;} nametypes[] = { { "UNKNOWN", KRB5_NT_UNKNOWN }, { "PRINCIPAL", KRB5_NT_PRINCIPAL }, { "SRV_INST", KRB5_NT_SRV_INST }, { "SRV_HST", KRB5_NT_SRV_HST }, { "SRV_XHST", KRB5_NT_SRV_XHST }, { "UID", KRB5_NT_UID }, { "X500_PRINCIPAL", KRB5_NT_X500_PRINCIPAL }, { "SMTP_NAME", KRB5_NT_SMTP_NAME }, { "ENTERPRISE_PRINCIPAL", KRB5_NT_ENTERPRISE_PRINCIPAL }, { "ENT_PRINCIPAL_AND_ID", KRB5_NT_ENT_PRINCIPAL_AND_ID }, { "MS_PRINCIPAL", KRB5_NT_MS_PRINCIPAL }, { "MS_PRINCIPAL_AND_ID", KRB5_NT_MS_PRINCIPAL_AND_ID }, { NULL }};krb5_error_codekrb5_parse_nametype(krb5_context context, const char *str, int32_t *nametype){ size_t i; for(i = 0; nametypes[i].type; i++) { if (strcasecmp(nametypes[i].type, str) == 0) { *nametype = nametypes[i].value; return 0; } } krb5_set_error_string(context, "Failed to find name type %s", str); return KRB5_PARSE_MALFORMED;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -