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";
42 static char sccsid
[] = "@(#)rsh.c 5.24 (Berkeley) 7/1/91";
52 #include <sys/types.h>
53 #include <sys/ioctl.h>
62 #include <net/netlib.h>
64 int main( int argc
, char *argv
[] );
66 char *copyargs( char **argv
);
67 void sendsig( int signo
);
68 void talk( int nflag
, long omask
, int pid
, int rem
);
70 #define _PATH_RLOGIN1 "/bin/rlogin"
71 #define _PATH_RLOGIN2 "/usr/bin/rlogin"
74 #include <sys/types.h>
75 #include <sys/signal.h>
76 #include <sys/socket.h>
77 #include <sys/ioctl.h>
80 #include <netinet/in.h>
88 #include "pathnames.h"
92 #include <kerberosIV/des.h>
93 #include <kerberosIV/krb.h>
96 Key_schedule schedule
;
97 int use_kerberos
= 1, doencrypt
;
98 char dst_realm_buf
[REALM_SZ
], *dest_realm
;
99 extern char *krb_realmofhost();
118 int argoff
, asrsh
, ch
, dflag
, nflag
, one
, pid
, rem
, uid
;
120 char *args
, *host
, *user
;
121 #if !defined(__minix)
126 argoff
= asrsh
= dflag
= nflag
= 0;
130 /* if called as something other than "rsh", use it as the host name */
131 if ((p
= rindex(argv
[0], '/')))
135 if (strcmp(p
, "rsh"))
140 /* handle "rsh host flags" */
141 if (!host
&& argc
> 2 && argv
[1][0] != '-') {
148 #define OPTIONS "8KLdek:l:nwx"
150 #define OPTIONS "8KLdek:l:nw"
153 #define OPTIONS "8KLdel:nw"
155 while ((ch
= getopt(argc
- argoff
, argv
+ argoff
, OPTIONS
)) != EOF
)
162 case 'L': /* -8Lew are ignored to allow rlogin aliases */
175 dest_realm
= dst_realm_buf
;
176 strncpy(dest_realm
, optarg
, REALM_SZ
);
186 des_set_key(cred
.session
, schedule
);
196 /* if haven't gotten a host yet, do so */
197 if (!host
&& !(host
= argv
[optind
++]))
200 /* if no further arguments, must have been called as rlogin. */
204 execv(_PATH_RLOGIN1
, argv
);
205 execv(_PATH_RLOGIN2
, argv
);
206 (void)fprintf(stderr
, "rsh: can't exec rlogin\n");
213 if (!(pw
= getpwuid(uid
= getuid()))) {
214 (void)fprintf(stderr
, "rsh: unknown user id.\n");
222 /* -x turns off -n */
228 args
= copyargs(argv
);
233 sp
= getservbyname((doencrypt
? "ekshell" : "kshell"), "tcp");
236 warning("can't get entry for %s/tcp service",
237 doencrypt
? "ekshell" : "kshell");
242 sp
= getservbyname("shell", "tcp");
244 (void)fprintf(stderr
, "rsh: shell/tcp: unknown service.\n");
253 if (dest_realm
== NULL
)
254 dest_realm
= krb_realmofhost(host
);
258 rem
= krcmd_mutual(&host
, sp
->s_port
, user
, args
,
259 &rfd2
, dest_realm
, &cred
, schedule
);
262 rem
= krcmd(&host
, sp
->s_port
, user
, args
, &rfd2
,
266 sp
= getservbyname("shell", "tcp");
268 (void)fprintf(stderr
,
269 "rsh: unknown service shell/tcp.\n");
272 if (errno
== ECONNREFUSED
)
273 warning("remote host doesn't support Kerberos");
275 warning("can't provide Kerberos auth data");
280 (void)fprintf(stderr
,
281 "rsh: the -x flag requires Kerberos authentication.\n");
284 rem
= rcmd(&host
, sp
->s_port
, pw
->pw_name
, user
, args
, &rfd2
);
287 rem
= rcmd(&host
, sp
->s_port
, pw
->pw_name
, user
, args
, &rfd2
);
294 (void)fprintf(stderr
, "rsh: can't establish stderr.\n");
297 #if !defined(__minix)
299 if (setsockopt(rem
, SOL_SOCKET
, SO_DEBUG
, &one
,
301 (void)fprintf(stderr
, "rsh: setsockopt: %s.\n",
303 if (setsockopt(rfd2
, SOL_SOCKET
, SO_DEBUG
, &one
,
305 (void)fprintf(stderr
, "rsh: setsockopt: %s.\n",
311 #if !defined(__minix)
312 omask
= sigblock(sigmask(SIGINT
)|sigmask(SIGQUIT
)|sigmask(SIGTERM
));
314 if (signal(SIGINT
, SIG_IGN
) != SIG_IGN
)
315 (void)signal(SIGINT
, sendsig
);
316 if (signal(SIGQUIT
, SIG_IGN
) != SIG_IGN
)
317 (void)signal(SIGQUIT
, sendsig
);
318 if (signal(SIGTERM
, SIG_IGN
) != SIG_IGN
)
319 (void)signal(SIGTERM
, sendsig
);
324 (void)fprintf(stderr
,
325 "rsh: fork: %s.\n", strerror(errno
));
339 (void)ioctl(rfd2
, FIONBIO
, &one
);
340 (void)ioctl(rem
, FIONBIO
, &one
);
344 talk(nflag
, omask
, pid
, rem
);
349 printf("killing %d with %d\n", pid
, SIGKILL
);
351 (void)kill(pid
, SIGKILL
);
357 talk(nflag
, omask
, pid
, rem
)
364 #if !defined(__minix)
365 int readfrom
, ready
, rembits
;
372 if (!nflag
&& pid
== 0) {
376 if ((cc
= read(0, buf
, sizeof buf
)) <= 0)
381 #if !defined(__minix)
383 if (select(16, 0, &rembits
, 0, 0) < 0) {
384 if (errno
!= EINTR
) {
385 (void)fprintf(stderr
,
386 "rsh: select: %s.\n", strerror(errno
));
391 if ((rembits
& (1 << rem
)) == 0)
397 wc
= des_write(rem
, bp
, cc
);
401 wc
= write(rem
, bp
, cc
);
403 #if !defined(__minix)
404 if (errno
== EWOULDBLOCK
)
416 ioctl(rem
, NWIOTCPSHUTDOWN
, NULL
);
418 (void)shutdown(rem
, 1);
427 (void)fprintf(stderr
, "rsh: fork: %s.\n", strerror(errno
));
430 close (pid1
? rfd2
: rem
);
434 cc
= read(pid1
? rem
: rfd2
, buf
, sizeof buf
);
440 printf("killing %d with %d\n", pid1
, SIGKILL
);
447 (void)write(pid1
? 1 : 2, buf
, cc
);
450 (void)sigsetmask(omask
);
451 readfrom
= (1 << rfd2
) | (1 << rem
);
454 if (select(16, &ready
, 0, 0, 0) < 0) {
455 if (errno
!= EINTR
) {
456 (void)fprintf(stderr
,
457 "rsh: select: %s.\n", strerror(errno
));
462 if (ready
& (1 << rfd2
)) {
467 cc
= des_read(rfd2
, buf
, sizeof buf
);
471 cc
= read(rfd2
, buf
, sizeof buf
);
473 if (errno
!= EWOULDBLOCK
)
474 readfrom
&= ~(1 << rfd2
);
476 (void)write(2, buf
, cc
);
478 if (ready
& (1 << rem
)) {
483 cc
= des_read(rem
, buf
, sizeof buf
);
487 cc
= read(rem
, buf
, sizeof buf
);
489 if (errno
!= EWOULDBLOCK
)
490 readfrom
&= ~(1 << rem
);
492 (void)write(1, buf
, cc
);
505 (void)des_write(rfd2
, &signo
, 1);
509 (void)write(rfd2
, &signo
, 1);
520 (void)fprintf(stderr
, "rsh: warning, using standard rsh: ");
522 fmt
= va_arg(ap
, char *);
523 vfprintf(stderr
, fmt
, ap
);
525 (void)fprintf(stderr
, ".\n");
534 register char **ap
, *p
;
536 #if !defined(__minix)
541 for (ap
= argv
; *ap
; ++ap
)
542 cc
+= strlen(*ap
) + 1;
543 if (!(args
= malloc((u_int
)cc
))) {
544 (void)fprintf(stderr
, "rsh: %s.\n", strerror(ENOMEM
));
547 for (p
= args
, ap
= argv
; *ap
; ++ap
) {
548 (void)strcpy(p
, *ap
);
549 for (p
= strcpy(p
, *ap
); *p
; ++p
);
559 (void)fprintf(stderr
,
560 "usage: rsh [-nd%s]%s[-l login] host [command]\n",
563 "x", " [-k realm] ");