]>
git.saurik.com Git - apple/libinfo.git/blob - util.subproj/rcmdsh.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
24 /* $OpenBSD: rcmdsh.c,v 1.4 1997/07/23 16:59:37 millert Exp $ */
27 * This is an rcmd() replacement originally by
28 * Chris Siebenmann <cks@utcc.utoronto.ca>.
31 #if defined(LIBC_SCCS) && !defined(lint)
32 static char *rcsid
= "$OpenBSD: rcmdsh.c,v 1.4 1997/07/23 16:59:37 millert Exp $";
33 #endif /* LIBC_SCCS and not lint */
35 #include <sys/types.h>
36 #include <sys/socket.h>
47 * This is a replacement rcmd() function that uses the rsh(1)
48 * program in place of a direct rcmd(3) function call so as to
49 * avoid having to be root. Note that rport is ignored.
53 rcmdsh(ahost
, rport
, locuser
, remuser
, cmd
, rshprog
)
56 const char *locuser
, *remuser
, *cmd
;
64 /* What rsh/shell to use. */
68 /* locuser must exist on this host. */
69 if ((pw
= getpwnam(locuser
)) == NULL
) {
70 (void) fprintf(stderr
, "rcmdsh: unknown user: %s\n", locuser
);
74 /* Validate remote hostname. */
75 if (strcmp(*ahost
, "localhost") != 0) {
76 if ((hp
= gethostbyname(*ahost
)) == NULL
) {
83 /* Get a socketpair we'll use for stdin and stdout. */
84 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
) < 0) {
85 perror("rcmdsh: socketpair");
91 perror("rcmdsh: fork failed");
93 } else if (cpid
== 0) {
95 * Child. We use sp[1] to be stdin/stdout, and close sp[0].
98 if (dup2(sp
[1], 0) < 0 || dup2(0, 1) < 0) {
99 perror("rcmdsh: dup2 failed");
102 /* Fork again to lose parent. */
105 perror("rcmdsh: fork to lose parent failed");
111 /* In grandchild here. Become local user for rshprog. */
112 if (setuid(pw
->pw_uid
)) {
113 (void) fprintf(stderr
, "rcmdsh: setuid(%u): %s\n",
114 pw
->pw_uid
, strerror(errno
));
119 * If remote host is "localhost" and local and remote user
120 * are the same, avoid running remote shell for efficiency.
122 if (!strcmp(*ahost
, "localhost") && !strcmp(locuser
, remuser
)) {
123 if (pw
->pw_shell
[0] == '\0')
124 rshprog
= _PATH_BSHELL
;
126 rshprog
= pw
->pw_shell
;
127 p
= strrchr(rshprog
, '/');
128 execlp(rshprog
, p
? p
+1 : rshprog
, "-c", cmd
,
131 p
= strrchr(rshprog
, '/');
132 execlp(rshprog
, p
? p
+1 : rshprog
, *ahost
, "-l",
133 remuser
, cmd
, (char *) NULL
);
135 (void) fprintf(stderr
, "rcmdsh: execlp %s failed: %s\n",
136 rshprog
, strerror(errno
));
139 /* Parent. close sp[1], return sp[0]. */