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