]>
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 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /* $OpenBSD: rcmdsh.c,v 1.4 1997/07/23 16:59:37 millert Exp $ */
28 * This is an rcmd() replacement originally by
29 * Chris Siebenmann <cks@utcc.utoronto.ca>.
32 #if defined(LIBC_SCCS) && !defined(lint)
33 static char *rcsid
= "$OpenBSD: rcmdsh.c,v 1.4 1997/07/23 16:59:37 millert Exp $";
34 #endif /* LIBC_SCCS and not lint */
36 #include <sys/types.h>
37 #include <sys/socket.h>
48 * This is a replacement rcmd() function that uses the rsh(1)
49 * program in place of a direct rcmd(3) function call so as to
50 * avoid having to be root. Note that rport is ignored.
54 rcmdsh(ahost
, rport
, locuser
, remuser
, cmd
, rshprog
)
57 const char *locuser
, *remuser
, *cmd
;
65 /* What rsh/shell to use. */
69 /* locuser must exist on this host. */
70 if ((pw
= getpwnam(locuser
)) == NULL
) {
71 (void) fprintf(stderr
, "rcmdsh: unknown user: %s\n", locuser
);
75 /* Validate remote hostname. */
76 if (strcmp(*ahost
, "localhost") != 0) {
77 if ((hp
= gethostbyname(*ahost
)) == NULL
) {
84 /* Get a socketpair we'll use for stdin and stdout. */
85 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
) < 0) {
86 perror("rcmdsh: socketpair");
92 perror("rcmdsh: fork failed");
94 } else if (cpid
== 0) {
96 * Child. We use sp[1] to be stdin/stdout, and close sp[0].
99 if (dup2(sp
[1], 0) < 0 || dup2(0, 1) < 0) {
100 perror("rcmdsh: dup2 failed");
103 /* Fork again to lose parent. */
106 perror("rcmdsh: fork to lose parent failed");
112 /* In grandchild here. Become local user for rshprog. */
113 if (setuid(pw
->pw_uid
)) {
114 (void) fprintf(stderr
, "rcmdsh: setuid(%u): %s\n",
115 pw
->pw_uid
, strerror(errno
));
120 * If remote host is "localhost" and local and remote user
121 * are the same, avoid running remote shell for efficiency.
123 if (!strcmp(*ahost
, "localhost") && !strcmp(locuser
, remuser
)) {
124 if (pw
->pw_shell
[0] == '\0')
125 rshprog
= _PATH_BSHELL
;
127 rshprog
= pw
->pw_shell
;
128 p
= strrchr(rshprog
, '/');
129 execlp(rshprog
, p
? p
+1 : rshprog
, "-c", cmd
,
132 p
= strrchr(rshprog
, '/');
133 execlp(rshprog
, p
? p
+1 : rshprog
, *ahost
, "-l",
134 remuser
, cmd
, (char *) NULL
);
136 (void) fprintf(stderr
, "rcmdsh: execlp %s failed: %s\n",
137 rshprog
, strerror(errno
));
140 /* Parent. close sp[1], return sp[0]. */