1 /* $NetBSD: rexec.c,v 1.15 2002/11/11 23:43:03 thorpej Exp $ */
4 * Copyright (c) 1980, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
33 #if defined(LIBC_SCCS) && !defined(lint)
35 static char sccsid
[] = "@(#)rexec.c 8.1 (Berkeley) 6/4/93";
37 __RCSID("$NetBSD: rexec.c,v 1.15 2002/11/11 23:43:03 thorpej Exp $");
39 #endif /* LIBC_SCCS and not lint */
41 #include <sys/types.h>
42 #include <sys/socket.h>
44 #include <netinet/in.h>
56 int ruserpass
__P((const char *, char **, char **));
57 int rexec
__P((char **, int, char *, char *, char *, int *));
60 rexec(ahost
, rport
, name
, pass
, cmd
, fd2p
)
63 char *name
, *pass
, *cmd
;
66 struct sockaddr_in rsin
, from
;
71 unsigned int timo
= 1;
75 _DIAGASSERT(ahost
!= NULL
);
76 _DIAGASSERT(name
!= NULL
);
77 _DIAGASSERT(pass
!= NULL
);
78 _DIAGASSERT(cmd
!= NULL
);
79 /* fd2p may be NULL */
81 hp
= gethostbyname(*ahost
);
83 warnx("Error resolving %s (%s)", *ahost
, hstrerror(h_errno
));
87 (void)ruserpass(hp
->h_name
, &name
, &pass
);
89 if ((s
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1) {
90 warn("Cannot create socket");
93 rsin
.sin_family
= hp
->h_addrtype
;
94 rsin
.sin_len
= sizeof(rsin
);
95 rsin
.sin_port
= rport
;
96 /* Avoid data corruption from bogus DNS results */
97 if (hp
->h_length
> (int) sizeof(rsin
.sin_addr
))
98 len
= sizeof(rsin
.sin_addr
);
101 memcpy(&rsin
.sin_addr
, hp
->h_addr
, len
);
102 if (connect(s
, (struct sockaddr
*)(void *)&rsin
, sizeof(rsin
)) == -1) {
103 if (errno
== ECONNREFUSED
&& timo
<= 16) {
109 warn("Cannot connect to %s", hp
->h_name
);
114 (void)write(s
, "", 1);
118 struct sockaddr_in sin2
;
121 s2
= socket(AF_INET
, SOCK_STREAM
, 0);
123 warn("Error creating socket");
128 sin2len
= sizeof(sin2
);
129 if (getsockname(s2
, (struct sockaddr
*)(void *)&sin2
,
130 &sin2len
) == -1 || sin2len
!= sizeof(sin2
)) {
131 warn("Failed to get socket name");
135 port
= ntohs((u_short
)sin2
.sin_port
);
136 (void)snprintf(num
, sizeof(num
), "%u", port
);
137 (void)write(s
, num
, strlen(num
)+1);
139 fromlen
= sizeof(from
);
140 s3
= accept(s2
, (struct sockaddr
*)(void *)&from
, &fromlen
);
143 warn("Error accepting connection");
149 (void)write(s
, name
, strlen(name
) + 1);
150 /* should public key encypt the password here */
151 (void)write(s
, pass
, strlen(pass
) + 1);
152 (void)write(s
, cmd
, strlen(cmd
) + 1);
153 if (read(s
, &c
, 1) != 1) {
154 warn("Error reading from %s", *ahost
);
158 while (read(s
, &c
, 1) == 1) {
159 (void) write(2, &c
, 1);