locate_kdc.c revision fe598cdcd847f8359013532d5c691bb6190378c0
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Use is subject to license terms.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#pragma ident "%Z%%M% %I% %E% SMI"
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * lib/krb5/os/locate_kdc.c
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Copyright 1990,2000,2001,2002 by the Massachusetts Institute of Technology.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * All Rights Reserved.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
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 *
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 *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * get socket addresses for KDC.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define NEED_SOCKETS
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include "fake-addrinfo.h"
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include "k5-int.h"
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include "os-proto.h"
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <stdio.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef KRB5_DNS_LOOKUP
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef WSHELPER
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <wshelper.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#else /* WSHELPER */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <netinet/in.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <arpa/inet.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <arpa/nameser.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <resolv.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <netdb.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif /* WSHELPER */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifndef T_SRV
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define T_SRV 33
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif /* T_SRV */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* for old Unixes and friends ... */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifndef MAXHOSTNAMELEN
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define MAXHOSTNAMELEN 64
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define MAX_DNS_NAMELEN (15*(MAXHOSTNAMELEN + 1)+1)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* Solaris Kerberos: default to dns lookup for the KDC but not the realm */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define DEFAULT_LOOKUP_KDC 1
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define DEFAULT_LOOKUP_REALM 0
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* Solaris Kerberos: want dbg messages to syslog */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define fprintf krbint_dbg_syslog
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <stdarg.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <com_err.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrbint_dbg_syslog(FILE *file, const char *fmt, ...)
8682d1ef2a0960ed5a9f05b9448eaa3e68ac931fRichard Lowe{
8682d1ef2a0960ed5a9f05b9448eaa3e68ac931fRichard Lowe va_list args;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu char err_str[2048];
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu va_start(args, fmt);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu vsnprintf(err_str, sizeof (err_str), fmt, args);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu syslog(LOG_DEBUG, err_str);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu va_end(args);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int
a31148363f598def767ac48c5d82e1572e44b935Gerry Liumaybe_use_dns (krb5_context context, const char *name, int defalt)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu krb5_error_code code;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu char * value = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int use_dns = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = profile_get_string(context->profile, "libdefaults",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu name, 0, 0, &value);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (value == 0 && code == 0)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = profile_get_string(context->profile, "libdefaults",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "dns_fallback", 0, 0, &value);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return defalt;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (value == 0)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return defalt;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu use_dns = _krb5_conf_boolean(value);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu profile_release_string(value);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return use_dns;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu_krb5_use_dns_kdc(krb5_context context)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return maybe_use_dns (context, "dns_lookup_kdc", DEFAULT_LOOKUP_KDC);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu_krb5_use_dns_realm(krb5_context context)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return maybe_use_dns (context, "dns_lookup_realm", DEFAULT_LOOKUP_REALM);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif /* KRB5_DNS_LOOKUP */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*ARGSUSED*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int get_port (const char *service, int stream, int defalt)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
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 struct addrinfo hints = { 0 };
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct addrinfo *ai;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int err;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu hints.ai_family = PF_INET;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu hints.ai_socktype = stream ? SOCK_STREAM : SOCK_DGRAM;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = getaddrinfo (NULL, service, &hints, &ai);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err == 0 && ai != 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (ai->ai_addr->sa_family == AF_INET) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int port = ((struct sockaddr_in *)ai->ai_addr)->sin_port;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu freeaddrinfo (ai);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return port;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu freeaddrinfo (ai);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Any error - don't complain, just use default. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return htons (defalt);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5int_grow_addrlist (struct addrlist *lp, int nmore)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int i;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int newspace = lp->space + nmore;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu size_t newsize = newspace * sizeof (struct addrlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct addrinfo **newaddrs;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* NULL check a concession to SunOS4 compatibility for now; not
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu required for pure ANSI support. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (lp->addrs)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu newaddrs = realloc (lp->addrs, newsize);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu else
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu newaddrs = malloc (newsize);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (newaddrs == NULL)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return errno;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (i = lp->space; i < newspace; i++)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu newaddrs[i] = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu lp->addrs = newaddrs;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu lp->space = newspace;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define grow_list krb5int_grow_addrlist
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* Free up everything pointed to by the addrlist structure, but don't
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu free the structure itself. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuvoid
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5int_free_addrlist (struct addrlist *lp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int i;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (i = 0; i < lp->naddrs; i++)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu freeaddrinfo (lp->addrs[i]);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu free (lp->addrs);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu lp->addrs = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu lp->naddrs = lp->space = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define free_list krb5int_free_addrlist
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int translate_ai_error (int err)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu switch (err) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case 0:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case EAI_BADFLAGS:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case EAI_FAMILY:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case EAI_SOCKTYPE:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case EAI_SERVICE:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* All of these indicate bad inputs to getaddrinfo. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return EINVAL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case EAI_AGAIN:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Translate to standard errno code. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return EAGAIN;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case EAI_MEMORY:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Translate to standard errno code. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return ENOMEM;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef EAI_ADDRFAMILY
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case EAI_ADDRFAMILY:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#if EAI_NODATA != EAI_NONAME
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case EAI_NODATA:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case EAI_NONAME:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Name not known or no address data, but no error. Do
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu nothing more. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef EAI_SYSTEM
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case EAI_SYSTEM:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* System error, obviously. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return errno;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu default:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* An error code we haven't handled? */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return EINVAL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int add_addrinfo_to_list (struct addrlist *lp, struct addrinfo *a)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int err;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu switch (a->ai_socktype) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case SOCK_DGRAM:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf(stderr, "\tdgram\n");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case SOCK_STREAM:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf(stderr, "\tstream\n");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case SOCK_RAW:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf(stderr, "\traw\n");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case 0:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu default:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf(stderr, "\tsocket type %d\n", a->ai_socktype);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (lp->naddrs == lp->space) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = grow_list (lp, 1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "grow_list failed %d\n", err);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return err;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu lp->addrs[lp->naddrs++] = a;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu a->ai_next = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "count is now %d\n", lp->naddrs);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define add_host_to_list krb5int_add_host_to_list
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5int_add_host_to_list (struct addrlist *lp, const char *hostname,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int port, int secport,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int socktype, int family)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct addrinfo *addrs, *a, *anext, hint;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int err;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu char portbuf[10], secportbuf[10];
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "adding hostname %s, ports %d,%d\n", hostname,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ntohs (port), ntohs (secport));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu memset(&hint, 0, sizeof(hint));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu hint.ai_family = family;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu hint.ai_socktype = socktype;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sprintf(portbuf, "%d", ntohs(port));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sprintf(secportbuf, "%d", ntohs(secport));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = getaddrinfo (hostname, portbuf, &hint, &addrs);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return translate_ai_error (err);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu anext = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (a = addrs; a != 0 && err == 0; a = anext) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu anext = a->ai_next;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = add_addrinfo_to_list (lp, a);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err || secport == 0)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu goto egress;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (socktype == 0)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu socktype = SOCK_DGRAM;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu else if (socktype != SOCK_DGRAM)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu goto egress;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu hint.ai_family = AF_INET;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = getaddrinfo (hostname, secportbuf, &hint, &addrs);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (err) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = translate_ai_error (err);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu goto egress;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (a = addrs; a != 0 && err == 0; a = anext) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu anext = a->ai_next;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu err = add_addrinfo_to_list (lp, a);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuegress:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (anext)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu freeaddrinfo (anext);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return err;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
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 Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic krb5_error_code
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu const char * name, struct addrlist *addrlist,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int get_masters, int socktype,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int udpport, int sec_udpport, int family)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu const char *realm_srv_names[4];
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu char **masterlist, **hostlist, *host, *port, *cp;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu krb5_error_code code;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int i, j, count, ismaster;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr,
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#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if ((host = malloc(realm->length + 1)) == NULL)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return ENOMEM;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu strncpy(host, realm->data, realm->length);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu host[realm->length] = '\0';
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu hostlist = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu masterlist = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu realm_srv_names[0] = "realms";
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu realm_srv_names[1] = host;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu realm_srv_names[2] = name;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu realm_srv_names[3] = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = profile_get_values(context->profile, realm_srv_names, &hostlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "config file lookup failed: %s\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu error_message(code));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code == PROF_NO_SECTION || code == PROF_NO_RELATION)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = KRB5_REALM_UNKNOWN;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu krb5_xfree(host);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return code;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu count = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu while (hostlist && hostlist[count])
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu count++;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "found %d entries under 'kdc'\n", count);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (count == 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu profile_free_list(hostlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu krb5_xfree(host);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu addrlist->naddrs = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (get_masters) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu realm_srv_names[0] = "realms";
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu realm_srv_names[1] = host;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu realm_srv_names[2] = "admin_server";
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu realm_srv_names[3] = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = profile_get_values(context->profile, realm_srv_names,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu &masterlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu krb5_xfree(host);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code == 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (i=0; masterlist[i]; i++) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu host = masterlist[i];
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Strip off excess whitespace
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu cp = strchr(host, ' ');
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (cp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *cp = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu cp = strchr(host, '\t');
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (cp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *cp = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu cp = strchr(host, ':');
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (cp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *cp = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu } else {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu krb5_xfree(host);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
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
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef HAVE_NETINET_IN_H
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (sec_udpport)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu count = count * 2;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (i=0; hostlist[i]; i++) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int p1, p2;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu host = hostlist[i];
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "entry %d is '%s'\n", i, host);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Strip off excess whitespace
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu cp = strchr(host, ' ');
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (cp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *cp = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu cp = strchr(host, '\t');
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (cp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *cp = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu port = strchr(host, ':');
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (port) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *port = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu port++;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ismaster = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (masterlist) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (j=0; masterlist[j]; j++) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (strcasecmp(hostlist[i], masterlist[j]) == 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ismaster = 1;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (get_masters && !ismaster)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu continue;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (port) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu unsigned long l;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef HAVE_STROUL
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu char *endptr;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu l = strtoul (port, &endptr, 10);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (endptr == NULL || *endptr != 0)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return EINVAL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#else
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu l = atoi (port);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* L is unsigned, don't need to check <0. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (l > 65535)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return EINVAL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu p1 = htons (l);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu p2 = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu } else {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu p1 = udpport;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu p2 = sec_udpport;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (socktype != 0)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = add_host_to_list (addrlist, hostlist[i], p1, p2,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu socktype, family);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu else {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = add_host_to_list (addrlist, hostlist[i], p1, p2,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu SOCK_DGRAM, family);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code == 0)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = add_host_to_list (addrlist, hostlist[i], p1, p2,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu SOCK_STREAM, family);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "error %d returned from add_host_to_list\n", code);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (hostlist)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu profile_free_list (hostlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (masterlist)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu profile_free_list (masterlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return code;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (hostlist)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu profile_free_list(hostlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (masterlist)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu profile_free_list(masterlist);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef KRB5_DNS_LOOKUP
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define make_srv_query_realm krb5int_make_srv_query_realm
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic krb5_error_code
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5_locate_srv_dns_1 (const krb5_data *realm,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu const char *service,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu const char *protocol,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct addrlist *addrlist,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int family)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct srv_dns_entry *head = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct srv_dns_entry *entry = NULL, *next;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu krb5_error_code code = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = make_srv_query_realm(realm, service, protocol, &head);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
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 */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (head == NULL)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Check for the "." case indicating no support. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (head->next == 0 && head->host[0] == 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu free(head->host);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu free(head);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return KRB5_ERR_NO_SERVICE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "walking answer list:\n");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (entry = head; entry != NULL; entry = next) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "\tport=%d host=%s\n", entry->port, entry->host);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu next = entry->next;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = add_host_to_list (addrlist, entry->host, htons (entry->port), 0,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (strcmp("_tcp", protocol)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ? SOCK_DGRAM
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu : SOCK_STREAM), family);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (entry == head) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu free(entry->host);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu free(entry);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu head = next;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu entry = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "[end]\n");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu krb5int_free_srv_dns_data(head);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return code;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif /* KRB5_DNS_LOOKUP */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Wrapper function for the two backends
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5_error_code
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5int_locate_server (krb5_context context, const krb5_data *realm,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct addrlist *addrlist,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int get_masters,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu const char *profname, const char *dnsname,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int socktype,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* network order port numbers! */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int dflport1, int dflport2,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int family)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu krb5_error_code code;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct addrlist al = ADDRLIST_INIT;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *addrlist = al;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Solaris Kerberos: skip local file search if profname == NULL */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (profname != NULL) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * We always try the local file first
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = krb5_locate_srv_conf_1(context, realm, profname, &al,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu get_masters, socktype, dflport1, dflport2, family);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef KRB5_DNS_LOOKUP
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code && dnsname != 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int use_dns = _krb5_use_dns_kdc(context);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (use_dns) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (socktype == SOCK_DGRAM || socktype == 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = krb5_locate_srv_dns_1(realm, dnsname, "_udp",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu &al, family);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf(stderr, "dns udp lookup returned error %d\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if ((socktype == SOCK_STREAM || socktype == 0) && code == 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = krb5_locate_srv_dns_1(realm, dnsname, "_tcp",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu &al, family);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf(stderr, "dns tcp lookup returned error %d\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif /* KRB5_DNS_LOOKUP */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code == 0)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "krb5int_locate_server found %d addresses\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu al.naddrs);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu else
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "krb5int_locate_server returning error code %d\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code != 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (al.space)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu free_list (&al);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return code;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (al.naddrs == 0) { /* No good servers */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (al.space)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu free_list (&al);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return KRB5_REALM_CANT_RESOLVE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *addrlist = al;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5_error_code
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5_locate_kdc(krb5_context context, const krb5_data *realm,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct addrlist *addrlist,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int get_masters, int socktype, int family)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int udpport, sec_udpport;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu udpport = get_port (KDC_PORTNAME, 0, KRB5_DEFAULT_PORT);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (socktype == SOCK_STREAM)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sec_udpport = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu else {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sec_udpport = get_port (KDC_SECONDARY_PORTNAME, 0,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (udpport == htons (KRB5_DEFAULT_PORT)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ? KRB5_DEFAULT_SEC_PORT
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu : KRB5_DEFAULT_PORT));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (sec_udpport == udpport)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sec_udpport = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return krb5int_locate_server(context, realm, addrlist, get_masters, "kdc",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (get_masters
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ? "_kerberos-master"
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu : "_kerberos"),
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu socktype, udpport, sec_udpport, family);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Solaris Kerberos: for backward compat. Avoid using this
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * function!
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5_error_code
a31148363f598def767ac48c5d82e1572e44b935Gerry Liukrb5_get_servername(krb5_context context,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu const krb5_data *realm,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu const char *name, const char *proto,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu char *srvhost,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu unsigned short *port)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu krb5_error_code code = KRB5_REALM_UNKNOWN;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef KRB5_DNS_LOOKUP
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int use_dns = _krb5_use_dns_kdc(context);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (use_dns) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct srv_dns_entry *head = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu code = make_srv_query_realm(realm, name, proto, &head);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (code)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (code);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (head == NULL)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return KRB5_REALM_CANT_RESOLVE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *port = head->port;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) strlcpy(srvhost, head->host, MAX_DNS_NAMELEN);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#ifdef DEBUG
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu fprintf (stderr, "krb5_get_servername svrhost %s, port %d\n",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu srvhost, *port);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu krb5int_free_srv_dns_data(head);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#endif /* KRB5_DNS_LOOKUP */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (code);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu