1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/*
* $Source$
* $Author$
*
* Copyright 1990 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* For copying and distribution information, please see the file
* <krb5/copyright.h>.
*
* get socket addresses for KDC.
*/
#if !defined(lint) && !defined(SABER)
static char rcsid_locate_kdc_c[] =
"$Id$";
#endif /* !lint & !SABER */
#include <krb5/krb5.h>
#include <krb5/osconf.h>
#include <krb5/ext-proto.h>
#include <stdio.h>
#include <krb5/los-proto.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifdef KRB5_USE_INET
#include <netinet/in.h>
#endif
#include <netdb.h>
#include "os-proto.h"
#ifdef KRB5_USE_INET
extern char *krb5_kdc_udp_portname;
#endif
/*
* returns count of number of addresses found
*/
krb5_error_code
krb5_locate_kdc(realm, addr_pp, naddrs)
const krb5_data *realm;
struct sockaddr **addr_pp;
int *naddrs;
{
char **hostlist;
int code;
int i, j, out, count;
struct sockaddr *addr_p;
struct sockaddr_in *sin_p;
struct hostent *hp;
struct servent *sp;
#ifdef KRB5_USE_INET
u_short udpport = 0; /* 0 is an invalid UDP port #. */
#endif
hostlist = 0;
if (code = krb5_get_krbhst (realm, &hostlist))
return(code);
#ifdef KRB5_USE_INET
if (sp = getservbyname(krb5_kdc_udp_portname, "udp"))
udpport = sp->s_port;
#endif
for (i=0; hostlist[i]; i++)
;
count = i;
if (count == 0) {
*naddrs = 0;
return 0;
}
addr_p = (struct sockaddr *)malloc (sizeof (struct sockaddr) * count);
for (i=0, out=0; hostlist[i]; i++) {
hp = gethostbyname(hostlist[i]);
if (hp != 0) {
switch (hp->h_addrtype) {
#ifdef KRB5_USE_INET
case AF_INET:
if (udpport) /* must have gotten a port # */
for (j=0; hp->h_addr_list[j]; j++) {
sin_p = (struct sockaddr_in *) &addr_p[out++];
memset ((char *)sin_p, 0, sizeof(struct sockaddr));
sin_p->sin_family = hp->h_addrtype;
sin_p->sin_port = udpport;
memcpy((char *)&sin_p->sin_addr,
(char *)hp->h_addr_list[j],
sizeof(struct in_addr));
if (out >= count) {
count *= 2;
addr_p = (struct sockaddr *)
realloc ((char *)addr_p,
sizeof(struct sockaddr) * count);
}
}
break;
#endif
default:
break;
}
}
free(hostlist[i]);
hostlist[i] = 0;
}
free ((char *)hostlist);
/*
* XXX need to distinguish between
* "can't resolve KDC name" and
* "can't find any KDC names"
*/
*addr_pp = addr_p;
*naddrs = out;
return 0;
}
|