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 7 #ifndef lint 8 static char sccsid[] = "@(#)rcmd.c 5.4 (Berkeley) 09/09/85"; 9 #endif not lint 10 11 #include <stdio.h> 12 #include <ctype.h> 13 #include <sys/param.h> 14 #include <sys/socket.h> 15 16 #include <netinet/in.h> 17 18 #include <netdb.h> 19 #include <errno.h> 20 21 extern errno; 22 char *index(), *sprintf(); 23 24 rcmd(ahost, rport, locuser, remuser, cmd, fd2p) 25 char **ahost; 26 int rport; 27 char *locuser, *remuser, *cmd; 28 int *fd2p; 29 { 30 int s, timo = 1; 31 struct sockaddr_in sin, sin2, from; 32 char c; 33 int lport = IPPORT_RESERVED - 1; 34 struct hostent *hp; 35 36 hp = gethostbyname(*ahost); 37 if (hp == 0) { 38 fprintf(stderr, "%s: unknown host\n", *ahost); 39 return (-1); 40 } 41 *ahost = hp->h_name; 42 retry: 43 s = rresvport(&lport); 44 if (s < 0) 45 return (-1); 46 sin.sin_family = hp->h_addrtype; 47 bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); 48 sin.sin_port = rport; 49 if (connect(s, (caddr_t)&sin, sizeof (sin), 0) < 0) { 50 (void) close(s); 51 if (errno == EADDRINUSE) { 52 lport--; 53 goto retry; 54 } 55 if (errno == ECONNREFUSED && timo <= 16) { 56 sleep(timo); 57 timo *= 2; 58 goto retry; 59 } 60 perror(hp->h_name); 61 return (-1); 62 } 63 lport--; 64 if (fd2p == 0) { 65 write(s, "", 1); 66 lport = 0; 67 } else { 68 char num[8]; 69 int s2 = rresvport(&lport), s3; 70 int len = sizeof (from); 71 72 if (s2 < 0) 73 goto bad; 74 listen(s2, 1); 75 (void) sprintf(num, "%d", lport); 76 if (write(s, num, strlen(num)+1) != strlen(num)+1) { 77 perror("write: setting up stderr"); 78 (void) close(s2); 79 goto bad; 80 } 81 s3 = accept(s2, &from, &len, 0); 82 (void) close(s2); 83 if (s3 < 0) { 84 perror("accept"); 85 lport = 0; 86 goto bad; 87 } 88 *fd2p = s3; 89 from.sin_port = ntohs((u_short)from.sin_port); 90 if (from.sin_family != AF_INET || 91 from.sin_port >= IPPORT_RESERVED) { 92 fprintf(stderr, 93 "socket: protocol failure in circuit setup.\n"); 94 goto bad2; 95 } 96 } 97 (void) write(s, locuser, strlen(locuser)+1); 98 (void) write(s, remuser, strlen(remuser)+1); 99 (void) write(s, cmd, strlen(cmd)+1); 100 if (read(s, &c, 1) != 1) { 101 perror(*ahost); 102 goto bad2; 103 } 104 if (c != 0) { 105 while (read(s, &c, 1) == 1) { 106 (void) write(2, &c, 1); 107 if (c == '\n') 108 break; 109 } 110 goto bad2; 111 } 112 return (s); 113 bad2: 114 if (lport) 115 (void) close(*fd2p); 116 bad: 117 (void) close(s); 118 return (-1); 119 } 120 121 rresvport(alport) 122 int *alport; 123 { 124 struct sockaddr_in sin; 125 int s; 126 127 sin.sin_family = AF_INET; 128 sin.sin_addr.s_addr = INADDR_ANY; 129 s = socket(AF_INET, SOCK_STREAM, 0); 130 if (s < 0) 131 return (-1); 132 for (;;) { 133 sin.sin_port = htons((u_short)*alport); 134 if (bind(s, (caddr_t)&sin, sizeof (sin), 0) >= 0) 135 return (s); 136 if (errno == EADDRNOTAVAIL) 137 return (-1); 138 if (errno != EADDRINUSE) { 139 perror("socket"); 140 (void) close(s); 141 return (-1); 142 } 143 (*alport)--; 144 if (*alport == IPPORT_RESERVED/2) { 145 fprintf(stderr, "socket: All ports in use\n"); 146 (void) close(s); 147 return (-1); 148 } 149 } 150 } 151 152 ruserok(rhost, superuser, ruser, luser) 153 char *rhost; 154 int superuser; 155 char *ruser, *luser; 156 { 157 FILE *hostf; 158 char fhost[MAXHOSTNAMELEN]; 159 char ahost[MAXHOSTNAMELEN]; 160 int first = 1; 161 register char *sp, *p; 162 int baselen = -1; 163 164 sp = rhost; 165 p = fhost; 166 while (*sp) { 167 if (*sp == '.') { 168 if (baselen == -1) 169 baselen = sp - rhost; 170 *p++ = *sp++; 171 } else { 172 *p++ = isupper(*sp) ? tolower(*sp++) : *sp++; 173 } 174 } 175 *p = '\0'; 176 hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r"); 177 again: 178 if (hostf) { 179 while (fgets(ahost, sizeof (ahost), hostf)) { 180 char *user; 181 182 p = ahost; 183 while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') 184 *p++ = isupper(*p) ? tolower(*p) : *p; 185 if (*p == ' ' || *p == '\t') { 186 *p++ = '\0'; 187 while (*p == ' ' || *p == '\t') 188 p++; 189 user = p; 190 while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') 191 p++; 192 } else 193 user = p; 194 *p = '\0'; 195 if (_checkhost(fhost, ahost, baselen) && 196 !strcmp(ruser, *user ? user : luser)) { 197 (void) fclose(hostf); 198 return (0); 199 } 200 } 201 (void) fclose(hostf); 202 } 203 if (first == 1) { 204 first = 0; 205 hostf = fopen(".rhosts", "r"); 206 goto again; 207 } 208 return (-1); 209 } 210 211 _checkhost(rhost, lhost, len) 212 char *rhost, *lhost; 213 int len; 214 { 215 static char ldomain[MAXHOSTNAMELEN]; 216 static char *domainp = NULL; 217 register char *cp; 218 219 if (len == -1) 220 return(!strcmp(rhost, lhost)); 221 if (strncmp(rhost, lhost, len)) 222 return(0); 223 if (!strcmp(rhost, lhost)) 224 return(1); 225 if (*(lhost + len) != '\0') 226 return(0); 227 if (!domainp) { 228 if (gethostname(ldomain, sizeof(ldomain)) == -1) { 229 domainp = (char *)1; 230 return(0); 231 } 232 ldomain[MAXHOSTNAMELEN] = NULL; 233 if ((domainp = index(ldomain, '.') + 1) == (char *)1) 234 return(0); 235 cp = domainp; 236 while (*cp) 237 *cp++ = isupper(*cp) ? tolower(*cp) : *cp; 238 } 239 if (domainp == (char *)1) 240 return(0); 241 return(!strcmp(domainp, rhost + len +1)); 242 } 243