1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <unixio.h> 5 6 #include <errno.h> 7 #include <sys/socket.h> 8 #include <netinet/in.h> 9 #include <netdb.h> 10 11 int rcmd(char **remote_hostname, int remote_port, 12 char *local_user, char *remote_user, 13 char *command, int zero) 14 { 15 struct hostent *remote_hp; 16 struct hostent *local_hp; 17 struct sockaddr_in remote_isa; 18 struct sockaddr_in local_isa; 19 char local_hostname[80]; 20 char ch; 21 int s; 22 int local_port; 23 int rs; 24 25 remote_hp = gethostbyname(*remote_hostname); 26 if(!remote_hp) 27 { 28 perror("couldn't get remote host address"); 29 exit(-1); 30 } 31 32 /* Copy remote IP address into socket address structure */ 33 remote_isa.sin_family = AF_INET; 34 remote_isa.sin_port = htons(remote_port); 35 memcpy(&remote_isa.sin_addr, remote_hp->h_addr, sizeof(remote_isa.sin_addr)); 36 37 gethostname(local_hostname, 80); 38 local_hp = gethostbyname(local_hostname); 39 if(!local_hp) 40 { 41 perror("couldn't get local host address"); 42 exit(-1); 43 } 44 45 /* Copy local IP address into socket address structure */ 46 local_isa.sin_family = AF_INET; 47 memcpy(&local_isa.sin_addr, local_hp->h_addr, sizeof(local_isa.sin_addr)); 48 49 /* Create the local socket */ 50 s = socket(AF_INET, SOCK_STREAM, 0); 51 if(s < 0) 52 { 53 perror("socket failed\n"); 54 exit(-1); 55 } 56 57 /* Bind local socket with a port from IPPORT_RESERVED/2 to IPPORT_RESERVED - 1 58 this requires the OPER privilege under VMS -- to allow communication with 59 a stock rshd under UNIX */ 60 61 for(local_port = IPPORT_RESERVED - 1; local_port >= IPPORT_RESERVED/2; local_port--) 62 { 63 local_isa.sin_port = htons(local_port); 64 rs = bind(s, (struct sockaddr *)&local_isa, sizeof(local_isa)); 65 if(rs == 0) 66 break; 67 } 68 69 /* Bind local socket to an unprivileged port. A normal rshd will drop the 70 connection; you must be running a patched rshd invoked through inetd for 71 this connection method to work */ 72 73 if (rs != 0) 74 for(local_port = IPPORT_USERRESERVED - 1; 75 local_port > IPPORT_RESERVED; 76 local_port--) 77 { 78 local_isa.sin_port = htons(local_port); 79 rs = bind(s, (struct sockaddr *)&local_isa, sizeof(local_isa)); 80 if(rs == 0) 81 break; 82 } 83 84 rs = connect(s, (struct sockaddr *) &remote_isa, sizeof(remote_isa)); 85 if(rs == -1) 86 { 87 fprintf(stderr, "connect: errno = %d\n", errno); 88 close(s); 89 exit(-2); 90 } 91 92 /* Now supply authentication information */ 93 94 /* Auxiliary port number for error messages, we don't use it */ 95 write(s, "0\0", 2); 96 97 /* Who are we */ 98 write(s, local_user, strlen(local_user) + 1); 99 100 /* Who do we want to be */ 101 write(s, remote_user, strlen(remote_user) + 1); 102 103 /* What do we want to run */ 104 write(s, command, strlen(command) + 1); 105 106 /* NUL is sent back to us if information is acceptable */ 107 read(s, &ch, 1); 108 if(ch != '\0') 109 { 110 errno = EPERM; 111 return -1; 112 } 113 114 return s; 115 } 116