2 * Copyright (c) 1983, 1990 The Regents of the University of California.
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 "@(#) Copyright (c) 1983, 1990 The Regents of the University of California.\n\
37 All rights reserved.\n";
41 static char sccsid
[] = "@(#)rsh.c 5.24 (Berkeley) 7/1/91";
50 #include <sys/types.h>
51 #include <sys/ioctl.h>
60 #include <net/netlib.h>
61 #include <net/gen/netdb.h>
62 int main( int argc
, char *argv
[] );
64 char *copyargs( char **argv
);
65 void sendsig( int signo
);
66 void talk( int nflag
, long omask
, int pid
, int rem
);
68 #define _PATH_RLOGIN1 "/bin/rlogin"
69 #define _PATH_RLOGIN2 "/usr/bin/rlogin"
72 #include <sys/types.h>
73 #include <sys/signal.h>
74 #include <sys/socket.h>
75 #include <sys/ioctl.h>
78 #include <netinet/in.h>
86 #include "pathnames.h"
90 #include <kerberosIV/des.h>
91 #include <kerberosIV/krb.h>
94 Key_schedule schedule
;
95 int use_kerberos
= 1, doencrypt
;
96 char dst_realm_buf
[REALM_SZ
], *dest_realm
;
97 extern char *krb_realmofhost();
116 int argoff
, asrsh
, ch
, dflag
, nflag
, one
, pid
, rem
, uid
;
118 char *args
, *host
, *user
;
124 argoff
= asrsh
= dflag
= nflag
= 0;
128 /* if called as something other than "rsh", use it as the host name */
129 if (p
= rindex(argv
[0], '/'))
133 if (strcmp(p
, "rsh"))
138 /* handle "rsh host flags" */
139 if (!host
&& argc
> 2 && argv
[1][0] != '-') {
146 #define OPTIONS "8KLdek:l:nwx"
148 #define OPTIONS "8KLdek:l:nw"
151 #define OPTIONS "8KLdel:nw"
153 while ((ch
= getopt(argc
- argoff
, argv
+ argoff
, OPTIONS
)) != EOF
)
160 case 'L': /* -8Lew are ignored to allow rlogin aliases */
173 dest_realm
= dst_realm_buf
;
174 strncpy(dest_realm
, optarg
, REALM_SZ
);
184 des_set_key(cred
.session
, schedule
);
194 /* if haven't gotten a host yet, do so */
195 if (!host
&& !(host
= argv
[optind
++]))
198 /* if no further arguments, must have been called as rlogin. */
202 execv(_PATH_RLOGIN1
, argv
);
203 execv(_PATH_RLOGIN2
, argv
);
204 (void)fprintf(stderr
, "rsh: can't exec rlogin\n");
211 if (!(pw
= getpwuid(uid
= getuid()))) {
212 (void)fprintf(stderr
, "rsh: unknown user id.\n");
220 /* -x turns off -n */
226 args
= copyargs(argv
);
231 sp
= getservbyname((doencrypt
? "ekshell" : "kshell"), "tcp");
234 warning("can't get entry for %s/tcp service",
235 doencrypt
? "ekshell" : "kshell");
240 sp
= getservbyname("shell", "tcp");
242 (void)fprintf(stderr
, "rsh: shell/tcp: unknown service.\n");
251 if (dest_realm
== NULL
)
252 dest_realm
= krb_realmofhost(host
);
256 rem
= krcmd_mutual(&host
, sp
->s_port
, user
, args
,
257 &rfd2
, dest_realm
, &cred
, schedule
);
260 rem
= krcmd(&host
, sp
->s_port
, user
, args
, &rfd2
,
264 sp
= getservbyname("shell", "tcp");
266 (void)fprintf(stderr
,
267 "rsh: unknown service shell/tcp.\n");
270 if (errno
== ECONNREFUSED
)
271 warning("remote host doesn't support Kerberos");
273 warning("can't provide Kerberos auth data");
278 (void)fprintf(stderr
,
279 "rsh: the -x flag requires Kerberos authentication.\n");
282 rem
= rcmd(&host
, sp
->s_port
, pw
->pw_name
, user
, args
, &rfd2
);
285 rem
= rcmd(&host
, sp
->s_port
, pw
->pw_name
, user
, args
, &rfd2
);
292 (void)fprintf(stderr
, "rsh: can't establish stderr.\n");
297 if (setsockopt(rem
, SOL_SOCKET
, SO_DEBUG
, &one
,
299 (void)fprintf(stderr
, "rsh: setsockopt: %s.\n",
301 if (setsockopt(rfd2
, SOL_SOCKET
, SO_DEBUG
, &one
,
303 (void)fprintf(stderr
, "rsh: setsockopt: %s.\n",
310 omask
= sigblock(sigmask(SIGINT
)|sigmask(SIGQUIT
)|sigmask(SIGTERM
));
312 if (signal(SIGINT
, SIG_IGN
) != SIG_IGN
)
313 (void)signal(SIGINT
, sendsig
);
314 if (signal(SIGQUIT
, SIG_IGN
) != SIG_IGN
)
315 (void)signal(SIGQUIT
, sendsig
);
316 if (signal(SIGTERM
, SIG_IGN
) != SIG_IGN
)
317 (void)signal(SIGTERM
, sendsig
);
322 (void)fprintf(stderr
,
323 "rsh: fork: %s.\n", strerror(errno
));
337 (void)ioctl(rfd2
, FIONBIO
, &one
);
338 (void)ioctl(rem
, FIONBIO
, &one
);
342 talk(nflag
, omask
, pid
, rem
);
347 printf("killing %d with %d\n", pid
, SIGKILL
);
349 (void)kill(pid
, SIGKILL
);
355 talk(nflag
, omask
, pid
, rem
)
362 int readfrom
, ready
, rembits
;
368 if (!nflag
&& pid
== 0) {
372 if ((cc
= read(0, buf
, sizeof buf
)) <= 0)
379 if (select(16, 0, &rembits
, 0, 0) < 0) {
380 if (errno
!= EINTR
) {
381 (void)fprintf(stderr
,
382 "rsh: select: %s.\n", strerror(errno
));
387 if ((rembits
& (1 << rem
)) == 0)
393 wc
= des_write(rem
, bp
, cc
);
397 wc
= write(rem
, bp
, cc
);
400 if (errno
== EWOULDBLOCK
)
412 ioctl(rem
, NWIOTCPSHUTDOWN
, NULL
);
414 (void)shutdown(rem
, 1);
423 (void)fprintf(stderr
, "rsh: fork: %s.\n", strerror(errno
));
426 close (pid1
? rfd2
: rem
);
430 cc
= read(pid1
? rem
: rfd2
, buf
, sizeof buf
);
436 printf("killing %d with %d\n", pid1
, SIGKILL
);
443 (void)write(pid1
? 1 : 2, buf
, cc
);
446 (void)sigsetmask(omask
);
447 readfrom
= (1 << rfd2
) | (1 << rem
);
450 if (select(16, &ready
, 0, 0, 0) < 0) {
451 if (errno
!= EINTR
) {
452 (void)fprintf(stderr
,
453 "rsh: select: %s.\n", strerror(errno
));
458 if (ready
& (1 << rfd2
)) {
463 cc
= des_read(rfd2
, buf
, sizeof buf
);
467 cc
= read(rfd2
, buf
, sizeof buf
);
469 if (errno
!= EWOULDBLOCK
)
470 readfrom
&= ~(1 << rfd2
);
472 (void)write(2, buf
, cc
);
474 if (ready
& (1 << rem
)) {
479 cc
= des_read(rem
, buf
, sizeof buf
);
483 cc
= read(rem
, buf
, sizeof buf
);
485 if (errno
!= EWOULDBLOCK
)
486 readfrom
&= ~(1 << rem
);
488 (void)write(1, buf
, cc
);
501 (void)des_write(rfd2
, &signo
, 1);
505 (void)write(rfd2
, &signo
, 1);
516 (void)fprintf(stderr
, "rsh: warning, using standard rsh: ");
518 fmt
= va_arg(ap
, char *);
519 vfprintf(stderr
, fmt
, ap
);
521 (void)fprintf(stderr
, ".\n");
530 register char **ap
, *p
;
537 for (ap
= argv
; *ap
; ++ap
)
538 cc
+= strlen(*ap
) + 1;
539 if (!(args
= malloc((u_int
)cc
))) {
540 (void)fprintf(stderr
, "rsh: %s.\n", strerror(ENOMEM
));
543 for (p
= args
, ap
= argv
; *ap
; ++ap
) {
544 (void)strcpy(p
, *ap
);
545 for (p
= strcpy(p
, *ap
); *p
; ++p
);
555 (void)fprintf(stderr
,
556 "usage: rsh [-nd%s]%s[-l login] host [command]\n",
559 "x", " [-k realm] ");