1 /* 2 * 4.2BSD TCP/IP server for uucico - VMS version 3 * uucico's TCP channel causes this server to be run at the remote end. 4 * 5 * Lou Salkind 6 * New York University 7 */ 8 9 #include <stdio.h> 10 #include <signal.h> 11 #include <sys/param.h> 12 #include <sys/socket.h> 13 #include <sys/ioctl.h> 14 #include <netinet/in.h> 15 #include <netdb.h> 16 #include <sys/wait.h> 17 #include <pwd.h> 18 19 #include <eunice/eunice.h> 20 #include <vms/uafdef.h> 21 #include <vms/pcbdef.h> 22 #include <vms/phddef.h> 23 #include <vms/jibdef.h> 24 #include <vms/arbdef.h> 25 #include <vms/prvdef.h> 26 27 28 struct uaf uaf; /* VMS UAF record for local user */ 29 struct passwd *getpwnam(); 30 char *getenv(), *sprintf(); 31 32 main(argc, argv) 33 int argc; 34 char **argv; 35 { 36 struct servent *sp; 37 char user[64]; 38 char passwd[64]; 39 char *p; 40 char ebuf[30]; 41 struct passwd *pwd; 42 struct hostent *hp; 43 struct sockaddr_in from; 44 struct sockaddr_in *fromp; 45 unsigned int *q; 46 extern Set_VMS_UAF_Info(); 47 int s; 48 49 { 50 /* 51 * Make stdin/stdout/stderr read/write 52 */ 53 if (FD_FAB_Pointer[0]->status == AUTO_OPENR) 54 FD_FAB_Pointer[0]->status = AUTO_OPENRW; 55 close(1); close(2); 56 dup(0); dup(0); 57 } 58 59 (void) signal(SIGINT, SIG_DFL); 60 (void) signal(SIGQUIT, SIG_DFL); 61 (void) signal(SIGTERM, SIG_DFL); 62 63 /* 64 * Get stuff out of the environment 65 */ 66 fromp = &from; 67 q = (unsigned int *)fromp; 68 if ((p = getenv("SYS$ERROR")) == NULL) { 69 fprintf(stderr, "Can not translate SYS$ERROR\n"); 70 exit(1); 71 } 72 sscanf(p, "%x,%x,%x,%x", &q[0], &q[1], &q[2], &q[3]); 73 74 fromp->sin_port = ntohs((u_short)fromp->sin_port); 75 if (fromp->sin_family != AF_INET) { 76 fprintf(stderr, "uucpd: malformed from address\n"); 77 exit(1); 78 } 79 hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr), 80 fromp->sin_family); 81 if (hp == 0) { 82 fprintf(stderr, "Host name for your address unknown\n"); 83 exit(1); 84 } 85 alarm(60); 86 if (readline(user, sizeof user) < 0) { 87 fprintf(stderr, "user read\n"); 88 exit(0); 89 } 90 if (readline(passwd, sizeof passwd) < 0) { 91 fprintf(stderr, "passwd read\n"); 92 exit(0); 93 } 94 95 alarm(0); 96 setpwent(); 97 if (!(validate_vms_user(user, passwd, &uaf) & 1) || 98 (uaf.uaf$b_flags & UAF$M_DISACNT)) { 99 fprintf(stderr, "Login incorrect.\n"); 100 exit(1); 101 } 102 pwd = getpwnam(user); 103 if (pwd == NULL) { 104 fprintf(stderr, "Login incorrect.\n"); 105 exit(1); 106 } 107 endpwent(); 108 if (chdir(pwd->pw_dir) < 0) { 109 fprintf(stderr, "No remote directory.\n"); 110 exit(1); 111 } 112 sys$cmkrnl(Set_VMS_UAF_Info, 0); /* Set the VMS environment info */ 113 sprintf(ebuf, "-h%s", inet_ntoa(from.sin_addr)); 114 if (vfork() == 0) { 115 execl("/usr/lib/uucp/uucico", "uucico", ebuf, (char *)0); 116 perror("uucico server: execl"); 117 _exit(1); 118 } 119 wait(&s); 120 exit(0); 121 } 122 123 /* 124 * 125 * KERNEL Mode routine to stuff the PCB/JIB for this process with 126 * the correct quotas/information from the VMS UAF record. 127 * 128 */ 129 Set_VMS_UAF_Info() 130 { 131 extern struct PCB *ctl$gl_pcb; 132 extern struct PHD *ctl$gl_phd; 133 extern char ctl$t_username[], ctl$t_account[]; 134 extern unsigned int ctl$gq_procpriv[2]; 135 register struct PCB *pcb; 136 register struct JIB *jib; 137 register struct ARB *arb; 138 register struct PHD *phd; 139 register int i; 140 141 /* 142 * Get PCB and JIB pointers 143 */ 144 pcb = ctl$gl_pcb; 145 phd = ctl$gl_phd; 146 jib = pcb->pcb$l_jib; 147 arb = pcb->pcb$l_arb; 148 /* 149 * Set our execution priority 150 */ 151 sys$setpri(0,0,uaf.uaf$b_pri,0); 152 153 /* DEFAULT DIRECTORY/DISK ALREADY SET */ 154 155 /* 156 * Set username (space padded) 157 */ 158 for(i = 0; i < sizeof(uaf.uaf$t_username); i++) { 159 jib->jib$t_username[i] = uaf.uaf$t_username[i]; 160 ctl$t_username[i] = uaf.uaf$t_username[i]; 161 } 162 for(i = sizeof(uaf.uaf$t_username); i < sizeof(jib->jib$t_username); i++) { 163 jib->jib$t_username[i] = ' '; 164 } 165 /* 166 * Set account (blank padded) [to ctl region as well???] 167 */ 168 for(i = 0; i < sizeof(uaf.uaf$t_account); i++) { 169 jib->jib$t_account[i] = uaf.uaf$t_account[i]; 170 ctl$t_account[i] = uaf.uaf$t_account[i]; 171 } 172 for(i = sizeof(uaf.uaf$t_account); i < sizeof(jib->jib$t_account); i++) { 173 jib->jib$t_account[i] = ' '; 174 } 175 /* 176 * Set UIC 177 */ 178 arb->arb$w_grp = pcb->pcb$w_grp = uaf.uaf$w_grp; 179 arb->arb$w_mem = pcb->pcb$w_mem = uaf.uaf$w_mem; 180 181 /* SET PROCESS NAME TO USERNAME?? */ 182 183 /* 184 * Set quotas 185 */ 186 i = (uaf.uaf$w_biolm - pcb->pcb$w_biolm); 187 pcb->pcb$w_biolm += i; 188 pcb->pcb$w_biocnt += i; 189 190 i = (uaf.uaf$w_diolm - pcb->pcb$w_diolm); 191 pcb->pcb$w_diolm += i; 192 pcb->pcb$w_diocnt += i; 193 194 i = uaf.uaf$l_bytlm ? uaf.uaf$l_bytlm : uaf.uaf$w_bytlm; 195 i = i - jib->jib$l_bytlm; 196 jib->jib$l_bytlm += i; 197 jib->jib$l_bytcnt += i; 198 199 jib->jib$w_prclim = uaf.uaf$w_prccnt; 200 201 i = (uaf.uaf$w_fillm - jib->jib$w_fillm); 202 jib->jib$w_fillm += i; 203 jib->jib$w_filcnt += i; 204 205 i = *((int *)&uaf.uaf$w_pgflquota[0]); 206 i = (i - jib->jib$l_pgflquota); 207 jib->jib$l_pgflquota += i; 208 jib->jib$l_pgflcnt += i; 209 210 i = (uaf.uaf$w_tqcnt - jib->jib$w_tqlm); 211 jib->jib$w_tqlm += i; 212 jib->jib$w_tqcnt += i; 213 214 i = (uaf.uaf$w_enqlm - jib->jib$w_enqlim); 215 jib->jib$w_enqlim += i; 216 jib->jib$w_enqcnt += i; 217 218 i = (uaf.uaf$w_shrfillm - jib->jib$w_shrflim); 219 jib->jib$w_shrflim += i; 220 jib->jib$w_shrfcnt += i; 221 222 i = (uaf.uaf$l_pbytlm - jib->jib$l_pbytlim); 223 jib->jib$l_pbytlim += i; 224 jib->jib$l_pbytcnt += i; 225 226 /* 227 * Fill in privileges 228 */ 229 i = *((int *)&uaf.uaf$l_priv[0]); 230 i &= ~(1<<PRV$V_BYPASS); /* TOO DANGEROUS TO GIVE TO USER */ 231 pcb->pcb$q_priv[0] = i; 232 arb->arb$q_priv[0] = i; 233 jib->jib$q_priv[0] = i; 234 phd->phd$q_authpriv[0] = i; 235 ctl$gq_procpriv[0] = i; 236 i = *((int *)&uaf.uaf$l_priv[2]); 237 pcb->pcb$q_priv[1] = i; 238 arb->arb$q_priv[1] = i; 239 jib->jib$q_priv[1] = i; 240 phd->phd$q_authpriv[1] = i; 241 ctl$gq_procpriv[1] = i; 242 } 243 244 245 /* 246 * Read a line from standard input (NETWORK) 247 */ 248 readline(p, n) 249 register char *p; 250 register int n; 251 { 252 char c; 253 254 while (n-- > 0) { 255 if (read(0, &c, 1) <= 0) 256 return(-1); 257 c &= 0177; 258 if (c == '\n' || c == '\r') { 259 *p = '\0'; 260 return(0); 261 } 262 *p++ = c; 263 } 264 return(-1); 265 } 266 267