krb5_error_code k5_clean_hostname(krb5_context context, const char *host, char *cleanname, size_t lhsize) { char *p; krb5_error_code ret; size_t l; cleanname[0] = '\0'; if (host != NULL) { if (strlcpy(cleanname, host, lhsize) >= lhsize) return ENOMEM; } else { ret = krb5int_get_fq_local_hostname(cleanname, lhsize); if (ret) return ret; } /* Fold to lowercase. */ for (p = cleanname; *p; p++) { if (isupper((unsigned char)*p)) *p = tolower((unsigned char)*p); } /* Strip off trailing dot. */ l = strlen(cleanname); if (l > 0 && cleanname[l - 1] == '.') cleanname[l - 1] = '\0'; return 0; }
/* * Common code for krb5_get_host_realm and krb5_get_fallback_host_realm * to do basic sanity checks on supplied hostname. */ krb5_error_code KRB5_CALLCONV krb5int_clean_hostname(krb5_context context, const char *host, char *local_host, size_t lhsize) { char *cp; krb5_error_code retval; int l; local_host[0]=0; #ifdef DEBUG_REFERRALS printf("krb5int_clean_hostname called: host<%s>, local_host<%s>, size %d\n",host,local_host,lhsize); #endif if (host) { /* Filter out numeric addresses if the caller utterly failed to convert them to names. */ /* IPv4 - dotted quads only */ if (strspn(host, "01234567890.") == strlen(host)) { /* All numbers and dots... if it's three dots, it's an IP address, and we reject it. But "12345" could be a local hostname, couldn't it? We'll just assume that a name with three dots is not meant to be an all-numeric hostname three all-numeric domains down from the current domain. */ int ndots = 0; const char *p; for (p = host; *p; p++) if (*p == '.') ndots++; if (ndots == 3) return KRB5_ERR_NUMERIC_REALM; } if (strchr(host, ':')) /* IPv6 numeric address form? Bye bye. */ return KRB5_ERR_NUMERIC_REALM; /* Should probably error out if strlen(host) > MAXDNAME. */ strncpy(local_host, host, lhsize); local_host[lhsize - 1] = '\0'; } else { retval = krb5int_get_fq_local_hostname (local_host, lhsize); if (retval) return retval; } /* fold to lowercase */ for (cp = local_host; *cp; cp++) { if (isupper((unsigned char) (*cp))) *cp = tolower((unsigned char) *cp); } l = strlen(local_host); /* strip off trailing dot */ if (l && local_host[l-1] == '.') local_host[l-1] = 0; #ifdef DEBUG_REFERRALS printf("krb5int_clean_hostname ending: host<%s>, local_host<%s>, size %d\n",host,local_host,lhsize); #endif return 0; }
krb5_error_code KRB5_CALLCONV krb5_get_default_realm(krb5_context context, char **lrealm) { char *realm = 0; char *cp; char localhost[MAX_DNS_NAMELEN+1]; krb5_error_code retval; (void) memset(localhost, 0, sizeof(localhost)); if (!context || (context->magic != KV5M_CONTEXT)) return KV5M_CONTEXT; /* * Solaris Kerberos: (illumos) * Another way to provide the default realm. */ if (!context->default_realm) { if ((realm = getenv("KRB5_DEFAULT_REALM")) != NULL) { context->default_realm = strdup(realm); if (context->default_realm == NULL) return ENOMEM; } } if (!context->default_realm) { context->default_realm = 0; if (context->profile != 0) { retval = profile_get_string(context->profile, "libdefaults", "default_realm", 0, 0, &realm); if (!retval && realm) { context->default_realm = malloc(strlen(realm) + 1); if (!context->default_realm) { profile_release_string(realm); return ENOMEM; } strcpy(context->default_realm, realm); profile_release_string(realm); } } if (context->default_realm == 0) { #ifdef KRB5_DNS_LOOKUP if (_krb5_use_dns_realm(context)) { /* * Since this didn't appear in our config file, try looking * it up via DNS. Look for a TXT records of the form: * * _kerberos.<localhost> * _kerberos.<domainname> * _kerberos.<searchlist> * */ char * p; krb5int_get_fq_local_hostname (localhost, sizeof(localhost)); if ( localhost[0] ) { p = localhost; do { retval = krb5_try_realm_txt_rr("_kerberos", p, &context->default_realm); p = strchr(p,'.'); if (p) p++; } while (retval && p && p[0]); if (retval) retval = krb5_try_realm_txt_rr("_kerberos", "", &context->default_realm); } else { retval = krb5_try_realm_txt_rr("_kerberos", "", &context->default_realm); } if (retval) { return(KRB5_CONFIG_NODEFREALM); } } else #endif /* KRB5_DNS_LOOKUP */ if (getenv("MS_INTEROP") == NULL) { /* * Solaris Kerberos: * Try to find a realm based on one of the local IP addresses. * Don't do this for AD, which often does _not_ support any * DNS reverse lookup, making these queries take forever. */ (void) krb5int_foreach_localaddr(context, krb5int_address_get_realm, 0, 0); /* * Solaris Kerberos: * As a final fallback try to find a realm based on the resolver search * list */ if (context->default_realm == 0) { struct __res_state res; int i; (void) memset(&res, 0, sizeof (res)); if (res_ninit(&res) == 0) { for (i = 0; res.dnsrch[i]; i++) { krb5int_domain_get_realm(context, res.dnsrch[i], &context->default_realm); if (context->default_realm != 0) break; } res_ndestroy(&res); } } } } } if (context->default_realm == 0) return(KRB5_CONFIG_NODEFREALM); if (context->default_realm[0] == 0) { free (context->default_realm); context->default_realm = 0; return KRB5_CONFIG_NODEFREALM; } realm = context->default_realm; /*LINTED*/ if (!(*lrealm = cp = malloc((unsigned int) strlen(realm) + 1))) return ENOMEM; strcpy(cp, realm); return(0); }
krb5_error_code KRB5_CALLCONV krb5_get_default_realm(krb5_context context, char **lrealm) { char *realm = 0; krb5_error_code retval; if (!context || (context->magic != KV5M_CONTEXT)) return KV5M_CONTEXT; if (!context->default_realm) { /* * XXX should try to figure out a reasonable default based * on the host's DNS domain. */ context->default_realm = 0; if (context->profile != 0) { retval = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_DEFAULT_REALM, 0, 0, &realm); if (!retval && realm) { context->default_realm = strdup(realm); if (!context->default_realm) { profile_release_string(realm); return ENOMEM; } profile_release_string(realm); } } #ifndef KRB5_DNS_LOOKUP else return KRB5_CONFIG_CANTOPEN; #else /* KRB5_DNS_LOOKUP */ if (context->default_realm == 0) { int use_dns = _krb5_use_dns_realm(context); if ( use_dns ) { /* * Since this didn't appear in our config file, try looking * it up via DNS. Look for a TXT records of the form: * * _kerberos.<localhost> * _kerberos.<domainname> * _kerberos.<searchlist> * */ char localhost[MAX_DNS_NAMELEN+1]; char * p; krb5int_get_fq_local_hostname (localhost, sizeof(localhost)); if ( localhost[0] ) { p = localhost; do { retval = krb5_try_realm_txt_rr("_kerberos", p, &context->default_realm); p = strchr(p,'.'); if (p) p++; } while (retval && p && p[0]); if (retval) retval = krb5_try_realm_txt_rr("_kerberos", "", &context->default_realm); } else { retval = krb5_try_realm_txt_rr("_kerberos", "", &context->default_realm); } if (retval) { return(KRB5_CONFIG_NODEFREALM); } } } #endif /* KRB5_DNS_LOOKUP */ } if (context->default_realm == 0) return(KRB5_CONFIG_NODEFREALM); if (context->default_realm[0] == 0) { free (context->default_realm); context->default_realm = 0; return KRB5_CONFIG_NODEFREALM; } realm = context->default_realm; if (!(*lrealm = strdup(realm))) return ENOMEM; return(0); }