Commit | Line | Data |
---|---|---|
586c39b1 DF |
1 | /* |
2 | * Copyright (c) 1983 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
6 | ||
f0bb4ca8 | 7 | #ifndef lint |
586c39b1 DF |
8 | static char sccsid[] = "@(#)rcmd.c 5.1 (Berkeley) %G%"; |
9 | #endif not lint | |
f0bb4ca8 BJ |
10 | |
11 | #include <stdio.h> | |
12 | #include <sys/types.h> | |
13 | #include <sys/socket.h> | |
40d6b022 SL |
14 | |
15 | #include <netinet/in.h> | |
16 | ||
3f5b52bc | 17 | #include <netdb.h> |
40d6b022 | 18 | #include <errno.h> |
f0bb4ca8 BJ |
19 | |
20 | extern errno; | |
21 | char *index(), *sprintf(); | |
f0bb4ca8 BJ |
22 | |
23 | rcmd(ahost, rport, locuser, remuser, cmd, fd2p) | |
24 | char **ahost; | |
25 | int rport; | |
26 | char *locuser, *remuser, *cmd; | |
27 | int *fd2p; | |
28 | { | |
40d6b022 | 29 | int s, timo = 1; |
f0bb4ca8 BJ |
30 | struct sockaddr_in sin, sin2, from; |
31 | char c; | |
40d6b022 | 32 | int lport = IPPORT_RESERVED - 1; |
3f5b52bc | 33 | struct hostent *hp; |
f0bb4ca8 | 34 | |
3f5b52bc SL |
35 | hp = gethostbyname(*ahost); |
36 | if (hp == 0) { | |
f0bb4ca8 BJ |
37 | fprintf(stderr, "%s: unknown host\n", *ahost); |
38 | return (-1); | |
39 | } | |
3f5b52bc | 40 | *ahost = hp->h_name; |
f0bb4ca8 | 41 | retry: |
c1dfbf19 | 42 | s = rresvport(&lport); |
f0bb4ca8 BJ |
43 | if (s < 0) |
44 | return (-1); | |
3f5b52bc | 45 | sin.sin_family = hp->h_addrtype; |
40d6b022 | 46 | bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); |
b567f18d | 47 | sin.sin_port = rport; |
40d6b022 | 48 | if (connect(s, (caddr_t)&sin, sizeof (sin), 0) < 0) { |
ea19968f | 49 | (void) close(s); |
40d6b022 | 50 | if (errno == EADDRINUSE) { |
40d6b022 SL |
51 | lport--; |
52 | goto retry; | |
53 | } | |
f0bb4ca8 | 54 | if (errno == ECONNREFUSED && timo <= 16) { |
f0bb4ca8 BJ |
55 | sleep(timo); |
56 | timo *= 2; | |
57 | goto retry; | |
58 | } | |
40d6b022 | 59 | perror(hp->h_name); |
f0bb4ca8 BJ |
60 | return (-1); |
61 | } | |
40d6b022 | 62 | lport--; |
f0bb4ca8 BJ |
63 | if (fd2p == 0) { |
64 | write(s, "", 1); | |
c1dfbf19 | 65 | lport = 0; |
f0bb4ca8 BJ |
66 | } else { |
67 | char num[8]; | |
c1dfbf19 | 68 | int s2 = rresvport(&lport), s3; |
ea19968f | 69 | int len = sizeof (from); |
f0bb4ca8 | 70 | |
ea19968f RC |
71 | if (s2 < 0) |
72 | goto bad; | |
40d6b022 | 73 | listen(s2, 1); |
c1dfbf19 | 74 | (void) sprintf(num, "%d", lport); |
2c510808 SL |
75 | if (write(s, num, strlen(num)+1) != strlen(num)+1) { |
76 | perror("write: setting up stderr"); | |
77 | (void) close(s2); | |
78 | goto bad; | |
79 | } | |
ea19968f RC |
80 | s3 = accept(s2, &from, &len, 0); |
81 | (void) close(s2); | |
82 | if (s3 < 0) { | |
f0bb4ca8 | 83 | perror("accept"); |
c1dfbf19 | 84 | lport = 0; |
f0bb4ca8 BJ |
85 | goto bad; |
86 | } | |
40d6b022 SL |
87 | *fd2p = s3; |
88 | from.sin_port = ntohs((u_short)from.sin_port); | |
f0bb4ca8 BJ |
89 | if (from.sin_family != AF_INET || |
90 | from.sin_port >= IPPORT_RESERVED) { | |
91 | fprintf(stderr, | |
92 | "socket: protocol failure in circuit setup.\n"); | |
40d6b022 | 93 | goto bad2; |
f0bb4ca8 | 94 | } |
f0bb4ca8 BJ |
95 | } |
96 | (void) write(s, locuser, strlen(locuser)+1); | |
97 | (void) write(s, remuser, strlen(remuser)+1); | |
98 | (void) write(s, cmd, strlen(cmd)+1); | |
99 | if (read(s, &c, 1) != 1) { | |
100 | perror(*ahost); | |
40d6b022 | 101 | goto bad2; |
f0bb4ca8 BJ |
102 | } |
103 | if (c != 0) { | |
104 | while (read(s, &c, 1) == 1) { | |
105 | (void) write(2, &c, 1); | |
106 | if (c == '\n') | |
107 | break; | |
108 | } | |
40d6b022 | 109 | goto bad2; |
f0bb4ca8 BJ |
110 | } |
111 | return (s); | |
40d6b022 | 112 | bad2: |
c1dfbf19 | 113 | if (lport) |
f0bb4ca8 | 114 | (void) close(*fd2p); |
40d6b022 | 115 | bad: |
f0bb4ca8 BJ |
116 | (void) close(s); |
117 | return (-1); | |
118 | } | |
119 | ||
c1dfbf19 SL |
120 | rresvport(alport) |
121 | int *alport; | |
f0bb4ca8 BJ |
122 | { |
123 | struct sockaddr_in sin; | |
f0bb4ca8 BJ |
124 | int s; |
125 | ||
40d6b022 SL |
126 | sin.sin_family = AF_INET; |
127 | sin.sin_addr.s_addr = 0; | |
b567f18d | 128 | s = socket(AF_INET, SOCK_STREAM, 0, 0); |
40d6b022 SL |
129 | if (s < 0) |
130 | return (-1); | |
f0bb4ca8 | 131 | for (;;) { |
40d6b022 SL |
132 | sin.sin_port = htons((u_short)*alport); |
133 | if (bind(s, (caddr_t)&sin, sizeof (sin), 0) >= 0) | |
f0bb4ca8 BJ |
134 | return (s); |
135 | if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) { | |
136 | perror("socket"); | |
ea19968f | 137 | (void) close(s); |
f0bb4ca8 BJ |
138 | return (-1); |
139 | } | |
40d6b022 SL |
140 | (*alport)--; |
141 | if (*alport == IPPORT_RESERVED/2) { | |
f0bb4ca8 | 142 | fprintf(stderr, "socket: All ports in use\n"); |
ea19968f | 143 | (void) close(s); |
f0bb4ca8 BJ |
144 | return (-1); |
145 | } | |
146 | } | |
147 | } | |
148 | ||
ff3164c8 SL |
149 | ruserok(rhost, superuser, ruser, luser) |
150 | char *rhost; | |
151 | int superuser; | |
152 | char *ruser, *luser; | |
f0bb4ca8 BJ |
153 | { |
154 | FILE *hostf; | |
155 | char ahost[32]; | |
156 | int first = 1; | |
157 | ||
ff3164c8 | 158 | hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r"); |
f0bb4ca8 BJ |
159 | again: |
160 | if (hostf) { | |
161 | while (fgets(ahost, sizeof (ahost), hostf)) { | |
7620d83a | 162 | register char *p; |
f0bb4ca8 | 163 | char *user; |
7620d83a JB |
164 | |
165 | p = ahost; | |
166 | while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') | |
167 | p++; | |
168 | if (*p == ' ' || *p == '\t') { | |
169 | *p++ = '\0'; | |
170 | while (*p == ' ' || *p == '\t') | |
171 | p++; | |
172 | user = p; | |
173 | while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') | |
174 | p++; | |
175 | } else | |
176 | user = p; | |
177 | *p = '\0'; | |
f0bb4ca8 | 178 | if (!strcmp(rhost, ahost) && |
7620d83a | 179 | !strcmp(ruser, *user ? user : luser)) { |
ff3164c8 SL |
180 | (void) fclose(hostf); |
181 | return (0); | |
182 | } | |
f0bb4ca8 BJ |
183 | } |
184 | (void) fclose(hostf); | |
185 | } | |
186 | if (first == 1) { | |
187 | first = 0; | |
188 | hostf = fopen(".rhosts", "r"); | |
189 | goto again; | |
190 | } | |
191 | return (-1); | |
f0bb4ca8 | 192 | } |