GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ypserv/ypserv/ypserv_proc.c Lines: 0 441 0.0 %
Date: 2017-11-07 Branches: 0 278 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: ypserv_proc.c,v 1.29 2015/01/16 06:40:23 deraadt Exp $ */
2
3
/*
4
 * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
17
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
 */
28
29
#include <rpc/rpc.h>
30
#include <rpcsvc/yp.h>
31
#include "ypv1.h"
32
#include <rpcsvc/ypclnt.h>
33
#include <sys/stat.h>
34
#include <sys/socket.h>
35
#include <netinet/in.h>
36
#include <arpa/inet.h>
37
#include "ypdb.h"
38
#include "acl.h"
39
#include <fcntl.h>
40
#include <dirent.h>
41
#include <stdio.h>
42
#include <string.h>
43
#include <unistd.h>
44
#include <stdlib.h>
45
#include "yplog.h"
46
#include "ypdef.h"
47
#include "ypserv.h"
48
49
#ifdef DEBUG
50
#define YPLOG yplog
51
#else /* DEBUG */
52
#define YPLOG if (!ok) yplog
53
#endif /* DEBUG */
54
55
static char *True = "true";
56
static char *False = "FALSE";
57
#define TORF(N) ((N) ? True : False)
58
59
/*ARGSUSED*/
60
void *
61
ypproc_null_2_svc(void *argp, struct svc_req *rqstp)
62
{
63
	static char *result;
64
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
65
	int ok = acl_check_host(&caller->sin_addr);
66
67
	YPLOG("null_2: caller=[%s].%d, auth_ok=%s",
68
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok));
69
70
	if (!ok) {
71
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
72
		return(NULL);
73
	}
74
75
	result = NULL;
76
	return ((void *)&result);
77
}
78
79
bool_t *
80
ypproc_domain_2_svc(domainname *argp, struct svc_req *rqstp)
81
{
82
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
83
	int ok = acl_check_host(&caller->sin_addr);
84
	static char domain_path[PATH_MAX];
85
	static bool_t result;
86
	struct stat finfo;
87
88
	if (strchr(*argp, '/'))
89
		goto bail;
90
	snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp);
91
	result = (bool_t) ((stat(domain_path, &finfo) == 0) &&
92
	    S_ISDIR(finfo.st_mode));
93
94
	YPLOG("domain_2: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s",
95
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
96
	    TORF(ok), *argp, TORF(result));
97
98
	if (!ok) {
99
bail:
100
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
101
		return(NULL);
102
	}
103
	return (&result);
104
}
105
106
bool_t *
107
ypproc_domain_nonack_2_svc(domainname *argp, struct svc_req *rqstp)
108
{
109
	static bool_t result; /* is domain served? */
110
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
111
	int ok = acl_check_host(&caller->sin_addr);
112
	static char domain_path[PATH_MAX];
113
	struct stat finfo;
114
115
	if (strchr(*argp, '/'))
116
		goto bail;
117
	snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp);
118
	result = (bool_t) ((stat(domain_path, &finfo) == 0) &&
119
	    S_ISDIR(finfo.st_mode));
120
121
	YPLOG("domain_nonack_2: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s",
122
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok),
123
	    *argp, TORF(result));
124
125
	if (!ok) {
126
bail:
127
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
128
		return(NULL);
129
	}
130
131
	if (!result)
132
		return(NULL); /* don't send nack */
133
	return (&result);
134
}
135
136
ypresp_val *
137
ypproc_match_2_svc(ypreq_key *argp, struct svc_req *rqstp)
138
{
139
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
140
	int ok = acl_check_host(&caller->sin_addr);
141
	int secure = ypdb_secure(argp->domain, argp->map);
142
	static ypresp_val res;
143
144
	if (strchr(argp->domain, '/') || strchr(argp->map, '/'))
145
		goto bail;
146
	YPLOG("match_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s",
147
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
148
	    TORF(ok), TORF(secure),
149
	    argp->domain, argp->map, argp->key.keydat_len, argp->key.keydat_val);
150
151
	if (!ok) {
152
bail:
153
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
154
		return(NULL);
155
	}
156
157
	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
158
		res.stat = YP_YPERR;
159
	} else {
160
		res = ypdb_get_record(argp->domain, argp->map, argp->key, TRUE);
161
	}
162
163
#ifdef DEBUG
164
	yplog("  match2_status: %s", yperr_string(ypprot_err(res.stat)));
165
#endif
166
	return (&res);
167
}
168
169
ypresp_key_val *
170
ypproc_first_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
171
{
172
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
173
	int ok = acl_check_host(&caller->sin_addr);
174
	int secure = ypdb_secure(argp->domain, argp->map);
175
	static ypresp_key_val res;
176
177
	if (strchr(argp->domain, '/') || strchr(argp->map, '/'))
178
		goto bail;
179
	YPLOG( "first_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
180
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
181
	    TORF(ok), TORF(secure), argp->domain, argp->map);
182
	if (!ok) {
183
bail:
184
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
185
		return(NULL);
186
	}
187
188
	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
189
		res.stat = YP_YPERR;
190
	} else {
191
		res = ypdb_get_first(argp->domain, argp->map,FALSE);
192
	}
193
194
#ifdef DEBUG
195
	yplog("  first2_status: %s", yperr_string(ypprot_err(res.stat)));
196
#endif
197
	return (&res);
198
}
199
200
ypresp_key_val *
201
ypproc_next_2_svc(ypreq_key *argp, struct svc_req *rqstp)
202
{
203
	static ypresp_key_val res;
204
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
205
	int ok = acl_check_host(&caller->sin_addr);
206
	int secure = ypdb_secure(argp->domain, argp->map);
207
208
	if (strchr(argp->domain, '/') || strchr(argp->map, '/'))
209
		goto bail;
210
	YPLOG("next_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s",
211
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
212
	    TORF(ok), TORF(secure),
213
	    argp->domain, argp->map, argp->key.keydat_len, argp->key.keydat_val);
214
215
	if (!ok) {
216
bail:
217
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
218
		return(NULL);
219
	}
220
221
	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
222
		res.stat = YP_YPERR;
223
	} else {
224
		res = ypdb_get_next(argp->domain, argp->map, argp->key,FALSE);
225
	}
226
227
#ifdef DEBUG
228
	yplog("  next2_status: %s", yperr_string(ypprot_err(res.stat)));
229
#endif
230
	return (&res);
231
}
232
233
ypresp_xfr *
234
ypproc_xfr_2_svc(ypreq_xfr *argp, struct svc_req *rqstp)
235
{
236
	static ypresp_xfr res;
237
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
238
	int ok = acl_check_host(&caller->sin_addr);
239
	pid_t	pid;
240
	char	tid[11], prog[11], port[11];
241
	char	ypxfr_proc[] = YPXFR_PROC, *ipadd;
242
243
	bzero(&res, sizeof(res));
244
245
	YPLOG("xfr_2: caller=[%s].%d, auth_ok=%s, domain=%s, tid=%d, prog=%d",
246
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok),
247
	    argp->map_parms.domain, argp->transid, argp->prog);
248
	YPLOG("       ipadd=%s, port=%d, map=%s", inet_ntoa(caller->sin_addr),
249
	    argp->port, argp->map_parms.map);
250
251
	if (strchr(argp->map_parms.domain, '/') ||
252
	    strchr(argp->map_parms.map, '/') ||
253
	    ntohs(caller->sin_port) >= IPPORT_RESERVED) {
254
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
255
		return(NULL);
256
	}
257
258
	snprintf(tid, sizeof(tid), "%d", argp->transid);
259
	snprintf(prog, sizeof(prog), "%d", argp->prog);
260
	snprintf(port, sizeof(port), "%d", argp->port);
261
	ipadd = inet_ntoa(caller->sin_addr);
262
263
	pid = vfork();
264
	if (pid == -1) {
265
		svcerr_systemerr(rqstp->rq_xprt);
266
		return(NULL);
267
	}
268
	if (pid == 0) {
269
		execl(ypxfr_proc, "ypxfr", "-d", argp->map_parms.domain,
270
		    "-C", tid, prog, ipadd, port, argp->map_parms.map, (char *)NULL);
271
		_exit(1);
272
	}
273
	/*
274
	 * XXX: fill in res
275
	 */
276
	return (&res);
277
}
278
279
/*ARGSUSED*/
280
void *
281
ypproc_clear_2_svc(void *argp, struct svc_req *rqstp)
282
{
283
	static char *res;
284
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
285
	int ok = acl_check_host(&caller->sin_addr);
286
287
	YPLOG( "clear_2: caller=[%s].%d, auth_ok=%s, opt=%s",
288
	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok),
289
#ifdef OPTDB
290
		True
291
#else
292
		False
293
#endif
294
	);
295
296
	if (ntohs(caller->sin_port) >= IPPORT_RESERVED)
297
		ok = FALSE;
298
299
	if (!ok) {
300
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
301
		return(NULL);
302
	}
303
304
	res = NULL;
305
306
#ifdef OPTDB
307
	ypdb_close_all();
308
#endif
309
	return ((void *)&res);
310
}
311
312
ypresp_all *
313
ypproc_all_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
314
{
315
	static ypresp_all res;
316
	pid_t pid;
317
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
318
	int ok = acl_check_host(&caller->sin_addr);
319
	int secure = ypdb_secure(argp->domain, argp->map);
320
321
	if (strchr(argp->domain, '/') || strchr(argp->map, '/'))
322
		goto bail;
323
	YPLOG( "all_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
324
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
325
	    TORF(ok), TORF(secure), argp->domain, argp->map);
326
327
	if (!ok) {
328
bail:
329
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
330
		return(NULL);
331
	}
332
	bzero(&res, sizeof(res));
333
334
	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
335
		res.ypresp_all_u.val.stat = YP_YPERR;
336
		return(&res);
337
	}
338
339
	pid = fork();
340
	if (pid) {
341
		if (pid == -1) {
342
			/* XXXCDC An error has occurred */
343
		}
344
		return(NULL); /* PARENT: continue */
345
	}
346
	/* CHILD: send result, then exit */
347
348
	if (!svc_sendreply(rqstp->rq_xprt, ypdb_xdr_get_all, (char *)argp)) {
349
		svcerr_systemerr(rqstp->rq_xprt);
350
	}
351
	exit(0);
352
}
353
354
ypresp_master *
355
ypproc_master_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
356
{
357
	static ypresp_master res;
358
	static peername nopeer = "";
359
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
360
	int ok = acl_check_host(&caller->sin_addr);
361
	int secure = ypdb_secure(argp->domain, argp->map);
362
363
	if (strchr(argp->domain, '/') || strchr(argp->map, '/'))
364
		goto bail;
365
	YPLOG( "master_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
366
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
367
	    TORF(ok), TORF(secure), argp->domain, argp->map);
368
369
	if (!ok) {
370
bail:
371
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
372
		return(NULL);
373
	}
374
375
	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
376
		res.stat = YP_YPERR;
377
	} else {
378
		res = ypdb_get_master(argp->domain, argp->map);
379
	}
380
381
#ifdef DEBUG
382
	yplog("  master2_status: %s", yperr_string(ypprot_err(res.stat)));
383
#endif
384
385
	/*
386
	 * This code was added because a yppoll <unknown-domain>
387
	 * from a sun crashed the server in xdr_string, trying
388
	 * to access the peer through a NULL-pointer. yppoll in
389
	 * this server start asking for order. If order is ok
390
	 * then it will ask for master. SunOS 4 asks for both
391
	 * always. I'm not sure this is the best place for the
392
	 * fix, but for now it will do. xdr_peername or
393
	 * xdr_string in ypserv_xdr.c may be a better place?
394
	 */
395
	if (res.peer == NULL)
396
		res.peer = nopeer;
397
	return (&res);
398
}
399
400
401
ypresp_order *
402
ypproc_order_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
403
{
404
	static ypresp_order res;
405
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
406
	int ok = acl_check_host(&caller->sin_addr);
407
	int secure = ypdb_secure(argp->domain, argp->map);
408
409
	if (strchr(argp->domain, '/'))
410
		goto bail;
411
	YPLOG( "order_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
412
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
413
	    TORF(ok), TORF(secure), argp->domain, argp->map);
414
415
	if (!ok) {
416
bail:
417
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
418
		return(NULL);
419
	}
420
421
	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
422
		res.stat = YP_YPERR;
423
	} else if (strchr(argp->map, '/')) {
424
		res.stat = YP_NOMAP;
425
	} else {
426
		res = ypdb_get_order(argp->domain, argp->map);
427
	}
428
429
#ifdef DEBUG
430
	yplog("  order2_status: %s", yperr_string(ypprot_err(res.stat)));
431
#endif
432
	return (&res);
433
}
434
435
436
ypresp_maplist *
437
ypproc_maplist_2_svc(domainname *argp, struct svc_req *rqstp)
438
{
439
	static ypresp_maplist res;
440
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
441
	int ok = acl_check_host(&caller->sin_addr);
442
	static char domain_path[PATH_MAX];
443
	struct stat finfo;
444
	DIR   *dirp = NULL;
445
	struct dirent *dp;
446
	char  *suffix;
447
	ypstat status;
448
	struct ypmaplist *m;
449
	char  *map_name;
450
451
	if (strchr(*argp, '/'))
452
		goto bail;
453
	YPLOG("maplist_2: caller=[%s].%d, auth_ok=%s, domain=%s",
454
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok),
455
	    *argp);
456
457
	if (!ok) {
458
bail:
459
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
460
		return(NULL);
461
	}
462
463
	bzero(&res, sizeof(res));
464
	snprintf(domain_path, sizeof domain_path, "%s/%s", YP_DB_PATH, *argp);
465
466
	status = YP_TRUE;
467
	res.maps = NULL;
468
469
	if (!((stat(domain_path, &finfo) == 0) && S_ISDIR(finfo.st_mode)))
470
		status = YP_NODOM;
471
472
	if (status >= 0) {
473
		if ((dirp = opendir(domain_path)) == NULL)
474
			status = YP_NODOM;
475
	}
476
477
	if (status >= 0) {
478
		for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
479
			if ((!strcmp(dp->d_name, ".")) ||
480
			    ((!strcmp(dp->d_name, ".."))) ||
481
			    (dp->d_namlen < 4))
482
				continue;
483
			suffix = (char *) &dp->d_name[dp->d_namlen-3];
484
			if (strcmp(suffix, ".db") == 0) {
485
				if ((m = malloc(sizeof(struct ypmaplist))) == NULL) {
486
					status = YP_YPERR;
487
					break;
488
				}
489
490
				if ((map_name = malloc(dp->d_namlen - 2)) == NULL) {
491
					free(m);
492
					status = YP_YPERR;
493
					break;
494
				}
495
496
				m->next = res.maps;
497
				m->map = map_name;
498
				res.maps = m;
499
				strncpy(map_name, dp->d_name, dp->d_namlen - 3);
500
				m->map[dp->d_namlen - 3] = '\0';
501
			}
502
		}
503
	}
504
	if (dirp != NULL)
505
		closedir(dirp);
506
507
	res.stat = status;
508
#ifdef DEBUG
509
	yplog("  maplist_status: %s", yperr_string(ypprot_err(res.stat)));
510
#endif
511
	return (&res);
512
}
513
514
/*ARGSUSED*/
515
void *
516
ypoldproc_null_1_svc(void *argp, struct svc_req *rqstp)
517
{
518
	static char *result;
519
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
520
	int ok = acl_check_host(&caller->sin_addr);
521
522
	YPLOG("null_1: caller=[%s].%d, auth_ok=%s",
523
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok));
524
525
	if (!ok) {
526
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
527
		return(NULL);
528
	}
529
530
	result = NULL;
531
532
	return ((void *)&result);
533
}
534
535
bool_t *
536
ypoldproc_domain_1_svc(domainname *argp, struct svc_req *rqstp)
537
{
538
	static bool_t result; /* is domain_served? */
539
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
540
	int ok = acl_check_host(&caller->sin_addr);
541
	static char domain_path[PATH_MAX];
542
	struct stat finfo;
543
544
	if (strchr(*argp, '/'))
545
		goto bail;
546
	snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp);
547
	result = (bool_t) ((stat(domain_path, &finfo) == 0) &&
548
				    S_ISDIR(finfo.st_mode));
549
550
	YPLOG("domain_1: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s",
551
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
552
	    TORF(ok), *argp, TORF(result));
553
554
	if (!ok) {
555
bail:
556
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
557
		return(NULL);
558
	}
559
560
	return (&result);
561
}
562
563
bool_t *
564
ypoldproc_domain_nonack_1_svc(domainname *argp, struct svc_req *rqstp)
565
{
566
	static bool_t result; /* is domain served? */
567
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
568
	int ok = acl_check_host(&caller->sin_addr);
569
	static char domain_path[PATH_MAX];
570
	struct stat finfo;
571
572
	if (strchr(*argp, '/'))
573
		goto bail;
574
	snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp);
575
	result = (bool_t) ((stat(domain_path, &finfo) == 0) &&
576
				    S_ISDIR(finfo.st_mode));
577
578
	YPLOG(
579
	  "domain_nonack_1: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s",
580
	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok),
581
	  *argp, TORF(result));
582
583
	if (!ok) {
584
bail:
585
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
586
		return(NULL);
587
	}
588
589
	if (!result) {
590
		return(NULL); /* don't send nack */
591
	}
592
593
	return (&result);
594
}
595
596
ypresponse *
597
ypoldproc_match_1_svc(yprequest *argp, struct svc_req *rqstp)
598
{
599
	static ypresponse res;
600
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
601
	int ok = acl_check_host(&caller->sin_addr);
602
	int secure;
603
604
	if (strchr(argp->ypmatch_req_domain, '/') ||
605
	    strchr(argp->ypmatch_req_map, '/'))
606
		goto bail;
607
	res.yp_resptype = YPMATCH_RESPTYPE;
608
	res.ypmatch_resp_valptr = "";
609
	res.ypmatch_resp_valsize = 0;
610
611
	if (argp->yp_reqtype != YPMATCH_REQTYPE) {
612
		res.ypmatch_resp_status = YP_BADARGS;
613
		return(&res);
614
	}
615
616
	secure = ypdb_secure(argp->ypmatch_req_domain, argp->ypmatch_req_map);
617
618
	YPLOG(
619
	  "match_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s",
620
	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
621
	  TORF(ok), TORF(secure),
622
	  argp->ypmatch_req_domain,  argp->ypmatch_req_map,
623
	  argp->ypmatch_req_keysize, argp->ypmatch_req_keyptr);
624
625
	if (!ok) {
626
bail:
627
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
628
		return(NULL);
629
	}
630
631
	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
632
		res.ypmatch_resp_status = YP_YPERR;
633
	} else {
634
		res.ypmatch_resp_val = ypdb_get_record(
635
		    argp->ypmatch_req_domain, argp->ypmatch_req_map,
636
		    argp->ypmatch_req_keydat, TRUE);
637
	}
638
639
#ifdef DEBUG
640
	yplog("  match1_status: %s",
641
	    yperr_string(ypprot_err(res.ypmatch_resp_status)));
642
#endif
643
644
	return (&res);
645
}
646
647
ypresponse *
648
ypoldproc_first_1_svc(yprequest *argp, struct svc_req *rqstp)
649
{
650
	static ypresponse res;
651
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
652
	int ok = acl_check_host(&caller->sin_addr);
653
	int secure;
654
655
	if (strchr(argp->ypfirst_req_domain, '/') ||
656
	    strchr(argp->ypfirst_req_map, '/'))
657
		goto bail;
658
	res.yp_resptype = YPFIRST_RESPTYPE;
659
	res.ypfirst_resp_valptr = res.ypfirst_resp_keyptr = "";
660
	res.ypfirst_resp_valsize = res.ypfirst_resp_keysize = 0;
661
662
	if (argp->yp_reqtype != YPREQ_NOKEY) {
663
		res.ypfirst_resp_status = YP_BADARGS;
664
		return(&res);
665
	}
666
667
	secure = ypdb_secure(argp->ypfirst_req_domain, argp->ypfirst_req_map);
668
669
	YPLOG( "first_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
670
	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
671
	  TORF(ok), TORF(secure),
672
	  argp->ypfirst_req_domain, argp->ypfirst_req_map);
673
674
	if (!ok) {
675
bail:
676
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
677
		return(NULL);
678
	}
679
680
	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
681
		res.ypfirst_resp_status = YP_YPERR;
682
	} else {
683
		res.ypfirst_resp_val = ypdb_get_first(
684
		    argp->ypfirst_req_domain, argp->ypfirst_req_map, FALSE);
685
	}
686
687
#ifdef DEBUG
688
	yplog("  first1_status: %s",
689
	    yperr_string(ypprot_err(res.ypfirst_resp_status)));
690
#endif
691
692
	return (&res);
693
}
694
695
ypresponse *
696
ypoldproc_next_1_svc(yprequest *argp, struct svc_req *rqstp)
697
{
698
	static ypresponse res;
699
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
700
	int ok = acl_check_host(&caller->sin_addr);
701
	int secure;
702
703
	if (strchr(argp->ypnext_req_domain, '/') ||
704
	    strchr(argp->ypnext_req_map, '/'))
705
		goto bail;
706
	res.yp_resptype = YPNEXT_RESPTYPE;
707
	res.ypnext_resp_valptr = res.ypnext_resp_keyptr = "";
708
	res.ypnext_resp_valsize = res.ypnext_resp_keysize = 0;
709
710
	if (argp->yp_reqtype != YPNEXT_REQTYPE) {
711
		res.ypnext_resp_status = YP_BADARGS;
712
		return(&res);
713
	}
714
715
	secure = ypdb_secure(argp->ypnext_req_domain, argp->ypnext_req_map);
716
717
	YPLOG(
718
	  "next_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s",
719
	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
720
	  TORF(ok), TORF(secure),
721
	  argp->ypnext_req_domain,  argp->ypnext_req_map,
722
	  argp->ypnext_req_keysize, argp->ypnext_req_keyptr);
723
724
	if (!ok) {
725
bail:
726
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
727
		return(NULL);
728
	}
729
730
	if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
731
		res.ypnext_resp_status = YP_YPERR;
732
	} else {
733
		res.ypnext_resp_val = ypdb_get_next(
734
		    argp->ypnext_req_domain, argp->ypnext_req_map,
735
		    argp->ypnext_req_keydat, FALSE);
736
	}
737
738
#ifdef DEBUG
739
	yplog("  next1_status: %s",
740
	    yperr_string(ypprot_err(res.ypnext_resp_status)));
741
#endif
742
743
	return (&res);
744
}
745
746
ypresponse *
747
ypoldproc_poll_1_svc(yprequest *argp, struct svc_req *rqstp)
748
{
749
	static ypresponse res;
750
	ypresp_order order;
751
	ypresp_master master;
752
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
753
	int ok = acl_check_host(&caller->sin_addr);
754
	int secure;
755
756
	if (strchr(argp->yppoll_req_domain, '/') ||
757
	    strchr(argp->yppoll_req_map, '/'))
758
		goto bail;
759
	res.yp_resptype = YPPOLL_RESPTYPE;
760
	res.yppoll_resp_domain = argp->yppoll_req_domain;
761
	res.yppoll_resp_map = argp->yppoll_req_map;
762
	res.yppoll_resp_ordernum = 0;
763
	res.yppoll_resp_owner = "";
764
765
	if (argp->yp_reqtype != YPPOLL_REQTYPE) {
766
		return(&res);
767
	}
768
769
	secure = ypdb_secure(argp->yppoll_req_domain, argp->yppoll_req_map);
770
771
	YPLOG( "poll_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
772
	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
773
	  TORF(ok), TORF(secure),
774
	  argp->yppoll_req_domain, argp->yppoll_req_map);
775
776
	if (!ok) {
777
bail:
778
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
779
		return(NULL);
780
	}
781
782
	if (!(secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED))) {
783
		order = ypdb_get_order(argp->yppoll_req_domain,
784
		    argp->yppoll_req_map);
785
		master = ypdb_get_master(argp->yppoll_req_domain,
786
		    argp->yppoll_req_map);
787
		res.yppoll_resp_ordernum = order.ordernum;
788
		res.yppoll_resp_owner = master.peer;
789
	}
790
791
#ifdef DEBUG
792
	yplog("  poll1_status: %s", "none");
793
#endif
794
	return (&res);
795
}
796
797
void *
798
ypoldproc_push_1_svc(yprequest *argp, struct svc_req *rqstp)
799
{
800
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
801
	int ok = acl_check_host(&caller->sin_addr);
802
	int secure;
803
	pid_t	pid;
804
	char	yppush_proc[] = YPPUSH_PROC;
805
806
	if (strchr(argp->yppush_req_domain, '/') ||
807
	    strchr(argp->yppush_req_map, '/'))
808
		goto bail;
809
	if (argp->yp_reqtype != YPPUSH_REQTYPE) {
810
		return(NULL);
811
	}
812
813
	secure = ypdb_secure(argp->yppush_req_domain, argp->yppush_req_map);
814
815
	YPLOG( "push_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
816
	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
817
	  TORF(ok), TORF(secure),
818
	  argp->yppush_req_domain, argp->yppush_req_map);
819
820
	if (ntohs(caller->sin_port) >= IPPORT_RESERVED)
821
		ok = FALSE;
822
823
	if (!ok) {
824
bail:
825
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
826
		return(NULL);
827
	}
828
829
	pid = vfork();
830
	if (pid == -1) {
831
		svcerr_systemerr(rqstp->rq_xprt);
832
		return(NULL);
833
	}
834
	if (pid == 0) {
835
		execl(yppush_proc, "yppush", "-d", argp->yppush_req_domain,
836
		    argp->yppush_req_map, (char *)NULL);
837
		_exit(1);
838
	}
839
	return (NULL);
840
}
841
842
void *
843
ypoldproc_pull_1_svc(yprequest *argp, struct svc_req *rqstp)
844
{
845
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
846
	int ok = acl_check_host(&caller->sin_addr);
847
	int secure;
848
	pid_t	pid;
849
	char	ypxfr_proc[] = YPXFR_PROC;
850
851
	if (strchr(argp->yppull_req_domain, '/') ||
852
	    strchr(argp->yppull_req_map, '/'))
853
		goto bail;
854
	if (argp->yp_reqtype != YPPULL_REQTYPE) {
855
		return(NULL);
856
	}
857
858
	secure = ypdb_secure(argp->yppull_req_domain, argp->yppull_req_map);
859
860
	YPLOG( "pull_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s",
861
	  inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
862
	  TORF(ok), TORF(secure),
863
	  argp->yppull_req_domain, argp->yppull_req_map);
864
865
	if (ntohs(caller->sin_port) >= IPPORT_RESERVED)
866
		ok = FALSE;
867
868
	if (!ok) {
869
bail:
870
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
871
		return(NULL);
872
	}
873
874
	pid = vfork();
875
	if (pid == -1) {
876
		svcerr_systemerr(rqstp->rq_xprt);
877
		return(NULL);
878
	}
879
	if (pid == 0) {
880
		execl(ypxfr_proc, "ypxfr", "-d", argp->yppull_req_domain,
881
		    argp->yppull_req_map, (char *)NULL);
882
		_exit(1);
883
	}
884
	return (NULL);
885
}
886
887
void *
888
ypoldproc_get_1_svc(yprequest *argp, struct svc_req *rqstp)
889
{
890
	struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt);
891
	int ok = acl_check_host(&caller->sin_addr);
892
	int secure;
893
	pid_t	pid;
894
	char	ypxfr_proc[] = YPXFR_PROC;
895
896
	if (strchr(argp->ypget_req_domain, '/') ||
897
	    strchr(argp->ypget_req_map, '/'))
898
		goto bail;
899
	if (argp->yp_reqtype != YPGET_REQTYPE)
900
		return(NULL);
901
902
	secure = ypdb_secure(argp->ypget_req_domain, argp->ypget_req_map);
903
904
	YPLOG( "get_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, owner=%s",
905
	    inet_ntoa(caller->sin_addr), ntohs(caller->sin_port),
906
	    TORF(ok), TORF(secure),
907
	    argp->ypget_req_domain, argp->ypget_req_map,
908
	    argp->ypget_req_owner);
909
910
	if (ntohs(caller->sin_port) >= IPPORT_RESERVED)
911
		ok = FALSE;
912
913
	if (!ok) {
914
bail:
915
		svcerr_auth(rqstp->rq_xprt, AUTH_FAILED);
916
		return(NULL);
917
	}
918
919
	pid = vfork();
920
	if (pid == -1) {
921
		svcerr_systemerr(rqstp->rq_xprt);
922
		return(NULL);
923
	}
924
	if (pid == 0) {
925
		execl(ypxfr_proc, "ypxfr", "-d", argp->ypget_req_domain, "-h",
926
		    argp->ypget_req_owner, argp->yppush_req_map, (char *)NULL);
927
		_exit(1);
928
	}
929
	return (NULL);
930
}