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
main(argc,argv)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 */
Set_VMS_UAF_Info()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 */
readline(p,n)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