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.1 (Berkeley) 05/30/85"; 9 #endif not lint 10 11 #include <stdio.h> 12 #include <sys/types.h> 13 #include <sys/socket.h> 14 15 #include <netinet/in.h> 16 17 #include <netdb.h> 18 #include <errno.h> 19 20 extern errno; 21 char *index(), *sprintf(); 22 23 rcmd(ahost, rport, locuser, remuser, cmd, fd2p) 24 char **ahost; 25 int rport; 26 char *locuser, *remuser, *cmd; 27 int *fd2p; 28 { 29 int s, timo = 1; 30 struct sockaddr_in sin, sin2, from; 31 char c; 32 int lport = IPPORT_RESERVED - 1; 33 struct hostent *hp; 34 35 hp = gethostbyname(*ahost); 36 if (hp == 0) { 37 fprintf(stderr, "%s: unknown host\n", *ahost); 38 return (-1); 39 } 40 *ahost = hp->h_name; 41 retry: 42 s = rresvport(&lport); 43 if (s < 0) 44 return (-1); 45 sin.sin_family = hp->h_addrtype; 46 bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); 47 sin.sin_port = rport; 48 if (connect(s, (caddr_t)&sin, sizeof (sin), 0) < 0) { 49 (void) close(s); 50 if (errno == EADDRINUSE) { 51 lport--; 52 goto retry; 53 } 54 if (errno == ECONNREFUSED && timo <= 16) { 55 sleep(timo); 56 timo *= 2; 57 goto retry; 58 } 59 perror(hp->h_name); 60 return (-1); 61 } 62 lport--; 63 if (fd2p == 0) { 64 write(s, "", 1); 65 lport = 0; 66 } else { 67 char num[8]; 68 int s2 = rresvport(&lport), s3; 69 int len = sizeof (from); 70 71 if (s2 < 0) 72 goto bad; 73 listen(s2, 1); 74 (void) sprintf(num, "%d", lport); 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 } 80 s3 = accept(s2, &from, &len, 0); 81 (void) close(s2); 82 if (s3 < 0) { 83 perror("accept"); 84 lport = 0; 85 goto bad; 86 } 87 *fd2p = s3; 88 from.sin_port = ntohs((u_short)from.sin_port); 89 if (from.sin_family != AF_INET || 90 from.sin_port >= IPPORT_RESERVED) { 91 fprintf(stderr, 92 "socket: protocol failure in circuit setup.\n"); 93 goto bad2; 94 } 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); 101 goto bad2; 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 } 109 goto bad2; 110 } 111 return (s); 112 bad2: 113 if (lport) 114 (void) close(*fd2p); 115 bad: 116 (void) close(s); 117 return (-1); 118 } 119 120 rresvport(alport) 121 int *alport; 122 { 123 struct sockaddr_in sin; 124 int s; 125 126 sin.sin_family = AF_INET; 127 sin.sin_addr.s_addr = 0; 128 s = socket(AF_INET, SOCK_STREAM, 0, 0); 129 if (s < 0) 130 return (-1); 131 for (;;) { 132 sin.sin_port = htons((u_short)*alport); 133 if (bind(s, (caddr_t)&sin, sizeof (sin), 0) >= 0) 134 return (s); 135 if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) { 136 perror("socket"); 137 (void) close(s); 138 return (-1); 139 } 140 (*alport)--; 141 if (*alport == IPPORT_RESERVED/2) { 142 fprintf(stderr, "socket: All ports in use\n"); 143 (void) close(s); 144 return (-1); 145 } 146 } 147 } 148 149 ruserok(rhost, superuser, ruser, luser) 150 char *rhost; 151 int superuser; 152 char *ruser, *luser; 153 { 154 FILE *hostf; 155 char ahost[32]; 156 int first = 1; 157 158 hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r"); 159 again: 160 if (hostf) { 161 while (fgets(ahost, sizeof (ahost), hostf)) { 162 register char *p; 163 char *user; 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'; 178 if (!strcmp(rhost, ahost) && 179 !strcmp(ruser, *user ? user : luser)) { 180 (void) fclose(hostf); 181 return (0); 182 } 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); 192 } 193