2 * lib/krb5/os/locate_kdc.c
4 * Copyright 1990 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. M.I.T. makes no representations about the suitability of
20 * this software for any purpose. It is provided "as is" without express
21 * or implied warranty.
24 * get socket addresses for KDC.
32 * returns count of number of addresses found
36 krb5_locate_kdc(context, realm, addr_pp, naddrs)
38 const krb5_data *realm;
39 struct sockaddr **addr_pp;
42 const char *realm_kdc_names[4];
43 char **hostlist, *host, *port, *cp;
46 struct sockaddr *addr_p;
47 struct sockaddr_in *sin_p;
51 u_short udpport = htons(KRB5_DEFAULT_PORT);
52 u_short sec_udpport = htons(KRB5_DEFAULT_SEC_PORT);
55 if ((host = malloc(realm->length + 1)) == NULL)
58 strncpy(host, realm->data, realm->length);
59 host[realm->length] = '\0';
62 realm_kdc_names[0] = "realms";
63 realm_kdc_names[1] = host;
64 realm_kdc_names[2] = "kdc";
65 realm_kdc_names[3] = 0;
67 code = profile_get_values(context->profile, realm_kdc_names, &hostlist);
70 if (code == PROF_NO_SECTION)
71 return KRB5_REALM_UNKNOWN;
72 if (code == PROF_NO_RELATION)
73 return KRB5_CONFIG_BADFORMAT;
78 if ((sp = getservbyname(KDC_PORTNAME, "udp")))
80 if ((sp = getservbyname(KDC_SECONDARY_PORTNAME, "udp")))
81 sec_udpport = sp->s_port;
83 if (sec_udpport == udpport)
87 while (hostlist && hostlist[count])
100 addr_p = (struct sockaddr *)malloc (sizeof (struct sockaddr) * count);
102 for (i=0, out=0; hostlist[i]; i++) {
105 * Strip off excess whitespace
107 cp = strchr(host, ' ');
110 cp = strchr(host, '\t');
113 port = strchr(host, ':');
118 hp = gethostbyname(hostlist[i]);
120 switch (hp->h_addrtype) {
123 for (j=0; hp->h_addr_list[j]; j++) {
124 sin_p = (struct sockaddr_in *) &addr_p[out++];
125 memset ((char *)sin_p, 0, sizeof(struct sockaddr));
126 sin_p->sin_family = hp->h_addrtype;
127 sin_p->sin_port = port ? htons(atoi(port)) : udpport;
128 memcpy((char *)&sin_p->sin_addr,
129 (char *)hp->h_addr_list[j],
130 sizeof(struct in_addr));
131 if (out+1 >= count) {
133 addr_p = (struct sockaddr *)
134 realloc ((char *)addr_p,
135 sizeof(struct sockaddr) * count);
137 if (sec_udpport && !port) {
138 addr_p[out] = addr_p[out-1];
139 sin_p = (struct sockaddr_in *) &addr_p[out++];
140 sin_p->sin_port = sec_udpport;
152 free ((char *)hostlist);
154 if (out == 0) { /* Couldn't resolve any KDC names */
156 return KRB5_REALM_CANT_RESOLVE;