locate_kdc.c revision fe598cdcd847f8359013532d5c691bb6190378c0
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Use is subject to license terms.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#pragma ident "%Z%%M% %I% %E% SMI"
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Copyright 1990,2000,2001,2002 by the Massachusetts Institute of Technology.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * All Rights Reserved.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Export of this software from the United States of America may
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * require a specific license from the United States Government.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * It is the responsibility of any person or organization contemplating
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * export to obtain such a license before exporting.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * distribute this software and its documentation for any purpose and
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * without fee is hereby granted, provided that the above copyright
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * notice appear in all copies and that both that copyright notice and
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * this permission notice appear in supporting documentation, and that
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * the name of M.I.T. not be used in advertising or publicity pertaining
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * to distribution of the software without specific, written prior
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * permission. Furthermore if you modify this software you must label
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * your software as modified software and not distribute it in such a
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * fashion that it might be confused with the original M.I.T. software.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * M.I.T. makes no representations about the suitability of
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * this software for any purpose. It is provided "as is" without express
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * or implied warranty.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * get socket addresses for KDC.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#else /* WSHELPER */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif /* WSHELPER */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif /* T_SRV */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* for old Unixes and friends ... */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define MAX_DNS_NAMELEN (15*(MAXHOSTNAMELEN + 1)+1)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* Solaris Kerberos: default to dns lookup for the KDC but not the realm */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* Solaris Kerberos: want dbg messages to syslog */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrbint_dbg_syslog(FILE *file, const char *fmt, ...)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liumaybe_use_dns (krb5_context context, const char *name, int defalt)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = profile_get_string(context->profile, "libdefaults",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = profile_get_string(context->profile, "libdefaults",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return maybe_use_dns (context, "dns_lookup_kdc", DEFAULT_LOOKUP_KDC);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return maybe_use_dns (context, "dns_lookup_realm", DEFAULT_LOOKUP_REALM);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif /* KRB5_DNS_LOOKUP */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int get_port (const char *service, int stream, int defalt)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#if 0 /* Only used for "kerberos" and "kerberos-sec", and we want the
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu right port numbers even on the OSes that botch the entries in
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /etc/services. So don't bother with the lookup, except maybe
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu to produce a warning. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu hints.ai_socktype = stream ? SOCK_STREAM : SOCK_DGRAM;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int port = ((struct sockaddr_in *)ai->ai_addr)->sin_port;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Any error - don't complain, just use default. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5int_grow_addrlist (struct addrlist *lp, int nmore)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu size_t newsize = newspace * sizeof (struct addrlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* NULL check a concession to SunOS4 compatibility for now; not
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu required for pure ANSI support. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* Free up everything pointed to by the addrlist structure, but don't
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu free the structure itself. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* All of these indicate bad inputs to getaddrinfo. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Translate to standard errno code. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Translate to standard errno code. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Name not known or no address data, but no error. Do
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu nothing more. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* System error, obviously. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* An error code we haven't handled? */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int add_addrinfo_to_list (struct addrlist *lp, struct addrinfo *a)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu switch (a->ai_socktype) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf(stderr, "\tsocket type %d\n", a->ai_socktype);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "count is now %d\n", lp->naddrs);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5int_add_host_to_list (struct addrlist *lp, const char *hostname,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "adding hostname %s, ports %d,%d\n", hostname,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = getaddrinfo (hostname, portbuf, &hint, &addrs);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = getaddrinfo (hostname, secportbuf, &hint, &addrs);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * returns count of number of addresses found
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * if master is non-NULL, it is filled in with the index of
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * the master kdc
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "looking in krb5.conf for realm %s entry %s; ports %d,%d\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu realm->data, name, ntohs (udpport), ntohs (sec_udpport));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = profile_get_values(context->profile, realm_srv_names, &hostlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "config file lookup failed: %s\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code == PROF_NO_SECTION || code == PROF_NO_RELATION)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "found %d entries under 'kdc'\n", count);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = profile_get_values(context->profile, realm_srv_names,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (i=0; masterlist[i]; i++) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Strip off excess whitespace
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* at this point, if master is non-NULL, then either the master kdc
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu is required, and there is one, or the master kdc is not required,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu and there may or may not be one. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (i=0; hostlist[i]; i++) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Strip off excess whitespace
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (j=0; masterlist[j]; j++) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (strcasecmp(hostlist[i], masterlist[j]) == 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu unsigned long l;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* L is unsigned, don't need to check <0. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (l > 65535)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = add_host_to_list (addrlist, hostlist[i], p1, p2,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = add_host_to_list (addrlist, hostlist[i], p1, p2,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = add_host_to_list (addrlist, hostlist[i], p1, p2,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "error %d returned from add_host_to_list\n", code);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define make_srv_query_realm krb5int_make_srv_query_realm
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu const char *service,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = make_srv_query_realm(realm, service, protocol, &head);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Okay! Now we've got a linked list of entries sorted by
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * priority. Start looking up A records and returning
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * addresses.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Check for the "." case indicating no support. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "\tport=%d host=%s\n", entry->port, entry->host);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = add_host_to_list (addrlist, entry->host, htons (entry->port), 0,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif /* KRB5_DNS_LOOKUP */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Wrapper function for the two backends
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5int_locate_server (krb5_context context, const krb5_data *realm,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* network order port numbers! */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Solaris Kerberos: skip local file search if profname == NULL */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * We always try the local file first
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = krb5_locate_srv_conf_1(context, realm, profname, &al,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu get_masters, socktype, dflport1, dflport2, family);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = krb5_locate_srv_dns_1(realm, dnsname, "_udp",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf(stderr, "dns udp lookup returned error %d\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if ((socktype == SOCK_STREAM || socktype == 0) && code == 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = krb5_locate_srv_dns_1(realm, dnsname, "_tcp",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf(stderr, "dns tcp lookup returned error %d\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif /* KRB5_DNS_LOOKUP */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "krb5int_locate_server found %d addresses\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "krb5int_locate_server returning error code %d\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5_locate_kdc(krb5_context context, const krb5_data *realm,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu udpport = get_port (KDC_PORTNAME, 0, KRB5_DEFAULT_PORT);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sec_udpport = get_port (KDC_SECONDARY_PORTNAME, 0,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return krb5int_locate_server(context, realm, addrlist, get_masters, "kdc",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ? "_kerberos-master"
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu : "_kerberos"),
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Solaris Kerberos: for backward compat. Avoid using this
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu unsigned short *port)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = make_srv_query_realm(realm, name, proto, &head);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) strlcpy(srvhost, head->host, MAX_DNS_NAMELEN);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "krb5_get_servername svrhost %s, port %d\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif /* KRB5_DNS_LOOKUP */