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