xref: /original-bsd/usr.bin/uucp/vms/uucpd.c (revision a95f03a8)
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