2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 RCSID("$Id: kcmd.c,v 1.20.4.1 2000/10/10 12:55:55 assar Exp $");
38 #define START_PORT 5120 /* arbitrary */
43 struct sockaddr_in sin;
46 sin.sin_family = AF_INET;
47 sin.sin_addr.s_addr = INADDR_ANY;
48 s = socket(AF_INET, SOCK_STREAM, 0);
52 sin.sin_port = htons((u_short)*alport);
53 if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
55 if (errno != EADDRINUSE) {
61 if (*alport == IPPORT_RESERVED/2) {
63 if (*alport == IPPORT_RESERVED) {
66 errno = EAGAIN; /* close */
84 Key_schedule schedule,
86 struct sockaddr_in *laddr,
87 struct sockaddr_in *faddr,
92 struct sockaddr_in sin, from;
95 int lport = IPPORT_RESERVED - 1;
97 int lport = START_PORT;
106 hp = gethostbyname(*ahost);
108 /* fprintf(stderr, "%s: unknown host\n", *ahost); */
112 host_save = strdup(hp->h_name);
113 if (host_save == NULL)
116 h_addr_list = hp->h_addr_list;
118 /* If realm is null, look up from table */
119 if (realm == NULL || realm[0] == '\0')
120 realm = krb_realmofhost(host_save);
126 warnx("kcmd(socket): All ports in use\n");
128 warn("kcmd: socket");
131 sin.sin_family = hp->h_addrtype;
132 memcpy (&sin.sin_addr, h_addr_list[0], sizeof(sin.sin_addr));
133 sin.sin_port = rport;
134 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
137 if (errno == EADDRINUSE) {
142 * don't wait very long for Kerberos rcmd.
144 if (errno == ECONNREFUSED && timo <= 4) {
145 /* sleep(timo); don't wait at all here */
149 if (h_addr_list[1] != NULL) {
150 warn ("kcmd: connect (%s)",
151 inet_ntoa(sin.sin_addr));
153 memcpy(&sin.sin_addr,
155 sizeof(sin.sin_addr));
156 fprintf(stderr, "Trying %s...\n",
157 inet_ntoa(sin.sin_addr));
160 if (errno != ECONNREFUSED)
161 warn ("connect(%s)", hp->h_name);
170 int s2 = getport(&lport), s3;
171 int len = sizeof(from);
178 snprintf(num, sizeof(num), "%d", lport);
179 if (write(s, num, strlen(num) + 1) != strlen(num) + 1) {
180 warn("kcmd(write): setting up stderr");
188 if (s >= FD_SETSIZE || s2 >= FD_SETSIZE) {
189 warnx("file descriptor too large");
198 status = select(FD_SETSIZE, &fds, NULL, NULL, NULL);
199 if(FD_ISSET(s, &fds)){
200 warnx("kcmd: connection unexpectedly closed.");
206 s3 = accept(s2, (struct sockaddr *)&from, &len);
209 warn ("kcmd: accept");
216 from.sin_port = ntohs((u_short)from.sin_port);
217 if (from.sin_family != AF_INET ||
218 from.sin_port >= IPPORT_RESERVED) {
219 warnx("kcmd(socket): "
220 "protocol failure in circuit setup.");
226 * Kerberos-authenticated service. Don't have to send locuser,
227 * since its already in the ticket, and we'll extract it on
230 /* write(s, locuser, strlen(locuser)+1); */
232 /* set up the needed stuff for mutual auth, but only if necessary */
233 if (authopts & KOPT_DO_MUTUAL) {
237 sin_len = sizeof(struct sockaddr_in);
238 if (getsockname(s, (struct sockaddr *)laddr, &sin_len) < 0) {
239 warn("kcmd(getsockname)");
244 if ((status = krb_sendauth(authopts, s, ticket, service, *ahost,
245 realm, (unsigned long) getpid(), msg_data,
249 "KCMDV0.1")) != KSUCCESS)
252 write(s, remuser, strlen(remuser)+1);
253 write(s, cmd, strlen(cmd)+1);
255 if ((rc = read(s, &c, 1)) != 1) {
257 warn("read(%s)", *ahost);
259 warnx("kcmd: bad connection with remote host");
264 while (read(s, &c, 1) == 1) {