2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
24 /* $OpenBSD: ypserv.c,v 1.12 1997/11/04 07:40:52 deraadt Exp $ */
27 * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
28 * All rights reserved.
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by Mats O Jansson
41 * 4. The name of the author may not be used to endorse or promote products
42 * derived from this software without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
45 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
48 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 static char rcsid
[] = "$OpenBSD: ypserv.c,v 1.12 1997/11/04 07:40:52 deraadt Exp $";
64 #include <stdlib.h>/* getenv, exit */
65 #include <rpc/pmap_clnt.h> /* for pmap_unset */
66 #include <string.h> /* strcmp */
71 #include <sys/ttycom.h>/* TIOCNOTTY */
73 #include <sysent.h> /* getdtablesize, open */
74 #endif /* __cplusplus */
76 #include <sys/socket.h>
77 #include <netinet/in.h>
83 #include <sys/ioctl.h> /* for ioctl */
84 #include <sys/fcntl.h> /* for open */
87 #define SIG_PF void(*)(int)
94 #define _RPCSVC_CLOSEDOWN 120
95 static int _rpcpmstart
; /* Started by a port monitor ? */
96 static int _rpcfdtype
; /* Whether Stream or Datagram ? */
97 static int _rpcsvcdirty
; /* Still serving ? */
100 char *progname
= "ypserv";
101 char *aclfile
= NULL
;
106 /* in the RPC library */
107 SVCXPRT
*svcfd_create(int, u_int
, u_int
);
110 void _msgout(char* msg
)
114 syslog(LOG_ERR
, msg
);
116 (void) fprintf(stderr
, "%s\n", msg
);
118 syslog(LOG_ERR
, msg
);
125 if (_rpcsvcdirty
== 0) {
126 extern fd_set svc_fdset
;
130 if (_rpcfdtype
== SOCK_DGRAM
)
133 size
= getdtablesize();
135 for (i
= 0, openfd
= 0; i
< size
&& openfd
< 2; i
++)
136 if (FD_ISSET(i
, &svc_fdset
))
138 if (openfd
<= (_rpcpmstart
?0:1))
141 (void) alarm(_RPCSVC_CLOSEDOWN
);
145 ypprog_1(struct svc_req
*rqstp
, register SVCXPRT
*transp
)
148 domainname ypproc_domain_1_arg
;
149 domainname ypproc_domain_nonack_1_arg
;
150 yprequest ypproc_match_1_arg
;
151 yprequest ypproc_first_1_arg
;
152 yprequest ypproc_next_1_arg
;
153 yprequest ypproc_poll_1_arg
;
154 yprequest ypproc_push_1_arg
;
155 yprequest ypproc_pull_1_arg
;
156 yprequest ypproc_get_1_arg
;
159 xdrproc_t xdr_argument
, xdr_result
;
160 char *(*local
)(char *, struct svc_req
*);
163 switch (rqstp
->rq_proc
) {
165 xdr_argument
= (xdrproc_t
) xdr_void
;
166 xdr_result
= (xdrproc_t
) xdr_void
;
167 local
= (char *(*)(char *, struct svc_req
*)) ypproc_null_1_svc
;
170 case YPOLDPROC_DOMAIN
:
171 xdr_argument
= (xdrproc_t
) xdr_domainname
;
172 xdr_result
= (xdrproc_t
) xdr_bool
;
173 local
= (char *(*)(char *, struct svc_req
*)) ypproc_domain_1_svc
;
176 case YPOLDPROC_DOMAIN_NONACK
:
177 xdr_argument
= (xdrproc_t
) xdr_domainname
;
178 xdr_result
= (xdrproc_t
) xdr_bool
;
179 local
= (char *(*)(char *, struct svc_req
*)) ypproc_domain_nonack_1_svc
;
182 case YPOLDPROC_MATCH
:
183 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
184 xdr_result
= (xdrproc_t
) xdr_ypresponse
;
185 local
= (char *(*)(char *, struct svc_req
*)) ypproc_match_1_svc
;
188 case YPOLDPROC_FIRST
:
189 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
190 xdr_result
= (xdrproc_t
) xdr_ypresponse
;
191 local
= (char *(*)(char *, struct svc_req
*)) ypproc_first_1_svc
;
195 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
196 xdr_result
= (xdrproc_t
) xdr_ypresponse
;
197 local
= (char *(*)(char *, struct svc_req
*)) ypproc_next_1_svc
;
201 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
202 xdr_result
= (xdrproc_t
) xdr_ypresponse
;
203 local
= (char *(*)(char *, struct svc_req
*)) ypproc_poll_1_svc
;
207 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
208 xdr_result
= (xdrproc_t
) xdr_void
;
209 local
= (char *(*)(char *, struct svc_req
*)) ypproc_push_1_svc
;
213 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
214 xdr_result
= (xdrproc_t
) xdr_void
;
215 local
= (char *(*)(char *, struct svc_req
*)) ypproc_pull_1_svc
;
219 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
220 xdr_result
= (xdrproc_t
) xdr_void
;
221 local
= (char *(*)(char *, struct svc_req
*)) ypproc_get_1_svc
;
225 svcerr_noproc(transp
);
229 (void) memset((char *)&argument
, 0, sizeof (argument
));
230 if (!svc_getargs(transp
, xdr_argument
, (caddr_t
) &argument
)) {
231 svcerr_decode(transp
);
235 result
= (*local
)((char *)&argument
, rqstp
);
236 if (result
!= NULL
&& !svc_sendreply(transp
, xdr_result
, result
)) {
237 svcerr_systemerr(transp
);
239 if (!svc_freeargs(transp
, xdr_argument
, (caddr_t
) &argument
)) {
240 _msgout("unable to free arguments");
248 ypprog_2(struct svc_req
*rqstp
, register SVCXPRT
*transp
)
251 domainname ypproc_domain_2_arg
;
252 domainname ypproc_domain_nonack_2_arg
;
253 ypreq_key ypproc_match_2_arg
;
254 ypreq_nokey ypproc_first_2_arg
;
255 ypreq_key ypproc_next_2_arg
;
256 ypreq_xfr ypproc_xfr_2_arg
;
257 ypreq_nokey ypproc_all_2_arg
;
258 ypreq_nokey ypproc_master_2_arg
;
259 ypreq_nokey ypproc_order_2_arg
;
260 domainname ypproc_maplist_2_arg
;
263 xdrproc_t xdr_argument
, xdr_result
;
264 char *(*local
)(char *, struct svc_req
*);
267 switch (rqstp
->rq_proc
) {
269 xdr_argument
= (xdrproc_t
) xdr_void
;
270 xdr_result
= (xdrproc_t
) xdr_void
;
271 local
= (char *(*)(char *, struct svc_req
*)) ypproc_null_2_svc
;
275 xdr_argument
= (xdrproc_t
) xdr_domainname
;
276 xdr_result
= (xdrproc_t
) xdr_bool
;
277 local
= (char *(*)(char *, struct svc_req
*)) ypproc_domain_2_svc
;
280 case YPPROC_DOMAIN_NONACK
:
281 xdr_argument
= (xdrproc_t
) xdr_domainname
;
282 xdr_result
= (xdrproc_t
) xdr_bool
;
283 local
= (char *(*)(char *, struct svc_req
*)) ypproc_domain_nonack_2_svc
;
287 xdr_argument
= (xdrproc_t
) xdr_ypreq_key
;
288 xdr_result
= (xdrproc_t
) xdr_ypresp_val
;
289 local
= (char *(*)(char *, struct svc_req
*)) ypproc_match_2_svc
;
293 xdr_argument
= (xdrproc_t
) xdr_ypreq_nokey
;
294 xdr_result
= (xdrproc_t
) xdr_ypresp_key_val
;
295 local
= (char *(*)(char *, struct svc_req
*)) ypproc_first_2_svc
;
299 xdr_argument
= (xdrproc_t
) xdr_ypreq_key
;
300 xdr_result
= (xdrproc_t
) xdr_ypresp_key_val
;
301 local
= (char *(*)(char *, struct svc_req
*)) ypproc_next_2_svc
;
305 xdr_argument
= (xdrproc_t
) xdr_ypreq_xfr
;
306 xdr_result
= (xdrproc_t
) xdr_ypresp_xfr
;
307 local
= (char *(*)(char *, struct svc_req
*)) ypproc_xfr_2_svc
;
311 xdr_argument
= (xdrproc_t
) xdr_void
;
312 xdr_result
= (xdrproc_t
) xdr_void
;
313 local
= (char *(*)(char *, struct svc_req
*)) ypproc_clear_2_svc
;
317 xdr_argument
= (xdrproc_t
) xdr_ypreq_nokey
;
318 xdr_result
= (xdrproc_t
) xdr_ypresp_all
;
319 local
= (char *(*)(char *, struct svc_req
*)) ypproc_all_2_svc
;
323 xdr_argument
= (xdrproc_t
) xdr_ypreq_nokey
;
324 xdr_result
= (xdrproc_t
) xdr_ypresp_master
;
325 local
= (char *(*)(char *, struct svc_req
*)) ypproc_master_2_svc
;
329 xdr_argument
= (xdrproc_t
) xdr_ypreq_nokey
;
330 xdr_result
= (xdrproc_t
) xdr_ypresp_order
;
331 local
= (char *(*)(char *, struct svc_req
*)) ypproc_order_2_svc
;
335 xdr_argument
= (xdrproc_t
) xdr_domainname
;
336 xdr_result
= (xdrproc_t
) xdr_ypresp_maplist
;
337 local
= (char *(*)(char *, struct svc_req
*)) ypproc_maplist_2_svc
;
341 svcerr_noproc(transp
);
345 (void) memset((char *)&argument
, 0, sizeof (argument
));
346 if (!svc_getargs(transp
, xdr_argument
, (caddr_t
) &argument
)) {
347 svcerr_decode(transp
);
351 result
= (*local
)((char *)&argument
, rqstp
);
352 if (result
!= NULL
&& !svc_sendreply(transp
, xdr_result
, result
)) {
353 svcerr_systemerr(transp
);
355 if (!svc_freeargs(transp
, xdr_argument
, (caddr_t
) &argument
)) {
356 _msgout("unable to free arguments");
368 register SVCXPRT
*transp
= NULL
;
371 struct sockaddr_in saddr
;
372 int asize
= sizeof (saddr
);
379 while ((ch
= getopt(argc
, argv
, "1a:dx")) != -1)
399 (void)fprintf(stderr
,"usage: %s [-a aclfile] [-d] [-x]\n",progname
);
403 if (geteuid() != 0) {
404 (void)fprintf(stderr
,"%s: must be root to run.\n",progname
);
408 if (aclfile
!= NULL
) {
409 (void)yp_acl_init(aclfile
);
411 (void)yp_acl_securenet(YP_SECURENET_FILE
);
417 if (getsockname(0, (struct sockaddr
*)&saddr
, &asize
) == 0) {
418 int ssize
= sizeof (int);
420 if (saddr
.sin_family
!= AF_INET
)
422 if (getsockopt(0, SOL_SOCKET
, SO_TYPE
,
423 (char *)&_rpcfdtype
, &ssize
) == -1)
428 openlog("ypserv", LOG_PID
, LOG_DAEMON
);
436 perror("cannot fork");
441 size
= getdtablesize();
442 for (i
= 0; i
< size
; i
++)
444 i
= open("/dev/console", 2);
447 i
= open("/dev/tty", 2);
449 (void) ioctl(i
, TIOCNOTTY
, (char *)NULL
);
452 openlog("ypserv", LOG_PID
, LOG_DAEMON
);
455 (void) pmap_unset(YPPROG
, YPVERS
);
456 (void) pmap_unset(YPPROG
, YPOLDVERS
);
459 ypopenlog(); /* open log file */
460 ypdb_init(); /* init db stuff */
464 (void)signal(SIGCHLD
, sig_child
);
465 (void)signal(SIGHUP
, sig_hup
);
466 { FILE *pidfile
= fopen(YPSERV_PID_PATH
, "w");
467 if (pidfile
!= NULL
) {
468 fprintf(pidfile
, "%d\n", getpid());
473 if ((_rpcfdtype
== 0) || (_rpcfdtype
== SOCK_DGRAM
)) {
474 transp
= svcudp_create(sock
);
475 if (transp
== NULL
) {
476 _msgout("cannot create udp service.");
479 if (transp
->xp_port
>= IPPORT_RESERVED
) {
480 _msgout("cannot allocate udp privileged port.");
486 if (!svc_register(transp
, YPPROG
, YPOLDVERS
, ypprog_1
, proto
)) {
487 _msgout("unable to register (YPPROG, YPOLDVERS, udp).");
491 if (!svc_register(transp
, YPPROG
, YPVERS
, ypprog_2
, proto
)) {
492 _msgout("unable to register (YPPROG, YPVERS, udp).");
497 if ((_rpcfdtype
== 0) || (_rpcfdtype
== SOCK_STREAM
)) {
499 transp
= svcfd_create(sock
, 0, 0);
501 transp
= svctcp_create(sock
, 0, 0);
502 if (transp
== NULL
) {
503 _msgout("cannot create tcp service.");
506 if (transp
->xp_port
>= IPPORT_RESERVED
) {
507 _msgout("cannot allocate tcp privileged port.");
513 if (!svc_register(transp
, YPPROG
, YPOLDVERS
, ypprog_1
, proto
)) {
514 _msgout("unable to register (YPPROG, YPOLDVERS, tcp).");
518 if (!svc_register(transp
, YPPROG
, YPVERS
, ypprog_2
, proto
)) {
519 _msgout("unable to register (YPPROG, YPVERS, tcp).");
524 if (transp
== (SVCXPRT
*)NULL
) {
525 _msgout("could not create a handle");
529 (void) signal(SIGALRM
, (SIG_PF
) closedown
);
530 (void) alarm(_RPCSVC_CLOSEDOWN
);
533 _msgout("svc_run returned");
541 int save_errno
= errno
;
543 while (wait3((int *)NULL
, WNOHANG
, (struct rusage
*)NULL
) > 0)
552 if (aclfile
!= NULL
) {
553 yplog("sig_hup: reread %s",aclfile
);
554 (void)yp_acl_init(aclfile
);
556 yplog("sig_hup: reread %s",YP_SECURENET_FILE
);
557 (void)yp_acl_securenet(YP_SECURENET_FILE
);