2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 /* $OpenBSD: ypserv.c,v 1.12 1997/11/04 07:40:52 deraadt Exp $ */
26 * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
27 * All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by Mats O Jansson
40 * 4. The name of the author may not be used to endorse or promote products
41 * derived from this software without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
44 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
47 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 static char rcsid
[] = "$OpenBSD: ypserv.c,v 1.12 1997/11/04 07:40:52 deraadt Exp $";
63 #include <stdlib.h>/* getenv, exit */
64 #include <rpc/pmap_clnt.h> /* for pmap_unset */
65 #include <string.h> /* strcmp */
70 #include <sys/ttycom.h>/* TIOCNOTTY */
72 #include <sysent.h> /* getdtablesize, open */
73 #endif /* __cplusplus */
75 #include <sys/socket.h>
76 #include <netinet/in.h>
82 #include <sys/ioctl.h> /* for ioctl */
83 #include <sys/fcntl.h> /* for open */
86 #define SIG_PF void(*)(int)
93 #define _RPCSVC_CLOSEDOWN 120
94 static int _rpcpmstart
; /* Started by a port monitor ? */
95 static int _rpcfdtype
; /* Whether Stream or Datagram ? */
96 static int _rpcsvcdirty
; /* Still serving ? */
99 char *progname
= "ypserv";
100 char *aclfile
= NULL
;
105 /* in the RPC library */
106 SVCXPRT
*svcfd_create(int, u_int
, u_int
);
109 void _msgout(char* msg
)
113 syslog(LOG_ERR
, msg
);
115 (void) fprintf(stderr
, "%s\n", msg
);
117 syslog(LOG_ERR
, msg
);
124 if (_rpcsvcdirty
== 0) {
125 extern fd_set svc_fdset
;
129 if (_rpcfdtype
== SOCK_DGRAM
)
132 size
= getdtablesize();
134 for (i
= 0, openfd
= 0; i
< size
&& openfd
< 2; i
++)
135 if (FD_ISSET(i
, &svc_fdset
))
137 if (openfd
<= (_rpcpmstart
?0:1))
140 (void) alarm(_RPCSVC_CLOSEDOWN
);
144 ypprog_1(struct svc_req
*rqstp
, register SVCXPRT
*transp
)
147 domainname ypproc_domain_1_arg
;
148 domainname ypproc_domain_nonack_1_arg
;
149 yprequest ypproc_match_1_arg
;
150 yprequest ypproc_first_1_arg
;
151 yprequest ypproc_next_1_arg
;
152 yprequest ypproc_poll_1_arg
;
153 yprequest ypproc_push_1_arg
;
154 yprequest ypproc_pull_1_arg
;
155 yprequest ypproc_get_1_arg
;
158 xdrproc_t xdr_argument
, xdr_result
;
159 char *(*local
)(char *, struct svc_req
*);
162 switch (rqstp
->rq_proc
) {
164 xdr_argument
= (xdrproc_t
) xdr_void
;
165 xdr_result
= (xdrproc_t
) xdr_void
;
166 local
= (char *(*)(char *, struct svc_req
*)) ypproc_null_1_svc
;
169 case YPOLDPROC_DOMAIN
:
170 xdr_argument
= (xdrproc_t
) xdr_domainname
;
171 xdr_result
= (xdrproc_t
) xdr_bool
;
172 local
= (char *(*)(char *, struct svc_req
*)) ypproc_domain_1_svc
;
175 case YPOLDPROC_DOMAIN_NONACK
:
176 xdr_argument
= (xdrproc_t
) xdr_domainname
;
177 xdr_result
= (xdrproc_t
) xdr_bool
;
178 local
= (char *(*)(char *, struct svc_req
*)) ypproc_domain_nonack_1_svc
;
181 case YPOLDPROC_MATCH
:
182 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
183 xdr_result
= (xdrproc_t
) xdr_ypresponse
;
184 local
= (char *(*)(char *, struct svc_req
*)) ypproc_match_1_svc
;
187 case YPOLDPROC_FIRST
:
188 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
189 xdr_result
= (xdrproc_t
) xdr_ypresponse
;
190 local
= (char *(*)(char *, struct svc_req
*)) ypproc_first_1_svc
;
194 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
195 xdr_result
= (xdrproc_t
) xdr_ypresponse
;
196 local
= (char *(*)(char *, struct svc_req
*)) ypproc_next_1_svc
;
200 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
201 xdr_result
= (xdrproc_t
) xdr_ypresponse
;
202 local
= (char *(*)(char *, struct svc_req
*)) ypproc_poll_1_svc
;
206 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
207 xdr_result
= (xdrproc_t
) xdr_void
;
208 local
= (char *(*)(char *, struct svc_req
*)) ypproc_push_1_svc
;
212 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
213 xdr_result
= (xdrproc_t
) xdr_void
;
214 local
= (char *(*)(char *, struct svc_req
*)) ypproc_pull_1_svc
;
218 xdr_argument
= (xdrproc_t
) xdr_yprequest
;
219 xdr_result
= (xdrproc_t
) xdr_void
;
220 local
= (char *(*)(char *, struct svc_req
*)) ypproc_get_1_svc
;
224 svcerr_noproc(transp
);
228 (void) memset((char *)&argument
, 0, sizeof (argument
));
229 if (!svc_getargs(transp
, xdr_argument
, (caddr_t
) &argument
)) {
230 svcerr_decode(transp
);
234 result
= (*local
)((char *)&argument
, rqstp
);
235 if (result
!= NULL
&& !svc_sendreply(transp
, xdr_result
, result
)) {
236 svcerr_systemerr(transp
);
238 if (!svc_freeargs(transp
, xdr_argument
, (caddr_t
) &argument
)) {
239 _msgout("unable to free arguments");
247 ypprog_2(struct svc_req
*rqstp
, register SVCXPRT
*transp
)
250 domainname ypproc_domain_2_arg
;
251 domainname ypproc_domain_nonack_2_arg
;
252 ypreq_key ypproc_match_2_arg
;
253 ypreq_nokey ypproc_first_2_arg
;
254 ypreq_key ypproc_next_2_arg
;
255 ypreq_xfr ypproc_xfr_2_arg
;
256 ypreq_nokey ypproc_all_2_arg
;
257 ypreq_nokey ypproc_master_2_arg
;
258 ypreq_nokey ypproc_order_2_arg
;
259 domainname ypproc_maplist_2_arg
;
262 xdrproc_t xdr_argument
, xdr_result
;
263 char *(*local
)(char *, struct svc_req
*);
266 switch (rqstp
->rq_proc
) {
268 xdr_argument
= (xdrproc_t
) xdr_void
;
269 xdr_result
= (xdrproc_t
) xdr_void
;
270 local
= (char *(*)(char *, struct svc_req
*)) ypproc_null_2_svc
;
274 xdr_argument
= (xdrproc_t
) xdr_domainname
;
275 xdr_result
= (xdrproc_t
) xdr_bool
;
276 local
= (char *(*)(char *, struct svc_req
*)) ypproc_domain_2_svc
;
279 case YPPROC_DOMAIN_NONACK
:
280 xdr_argument
= (xdrproc_t
) xdr_domainname
;
281 xdr_result
= (xdrproc_t
) xdr_bool
;
282 local
= (char *(*)(char *, struct svc_req
*)) ypproc_domain_nonack_2_svc
;
286 xdr_argument
= (xdrproc_t
) xdr_ypreq_key
;
287 xdr_result
= (xdrproc_t
) xdr_ypresp_val
;
288 local
= (char *(*)(char *, struct svc_req
*)) ypproc_match_2_svc
;
292 xdr_argument
= (xdrproc_t
) xdr_ypreq_nokey
;
293 xdr_result
= (xdrproc_t
) xdr_ypresp_key_val
;
294 local
= (char *(*)(char *, struct svc_req
*)) ypproc_first_2_svc
;
298 xdr_argument
= (xdrproc_t
) xdr_ypreq_key
;
299 xdr_result
= (xdrproc_t
) xdr_ypresp_key_val
;
300 local
= (char *(*)(char *, struct svc_req
*)) ypproc_next_2_svc
;
304 xdr_argument
= (xdrproc_t
) xdr_ypreq_xfr
;
305 xdr_result
= (xdrproc_t
) xdr_ypresp_xfr
;
306 local
= (char *(*)(char *, struct svc_req
*)) ypproc_xfr_2_svc
;
310 xdr_argument
= (xdrproc_t
) xdr_void
;
311 xdr_result
= (xdrproc_t
) xdr_void
;
312 local
= (char *(*)(char *, struct svc_req
*)) ypproc_clear_2_svc
;
316 xdr_argument
= (xdrproc_t
) xdr_ypreq_nokey
;
317 xdr_result
= (xdrproc_t
) xdr_ypresp_all
;
318 local
= (char *(*)(char *, struct svc_req
*)) ypproc_all_2_svc
;
322 xdr_argument
= (xdrproc_t
) xdr_ypreq_nokey
;
323 xdr_result
= (xdrproc_t
) xdr_ypresp_master
;
324 local
= (char *(*)(char *, struct svc_req
*)) ypproc_master_2_svc
;
328 xdr_argument
= (xdrproc_t
) xdr_ypreq_nokey
;
329 xdr_result
= (xdrproc_t
) xdr_ypresp_order
;
330 local
= (char *(*)(char *, struct svc_req
*)) ypproc_order_2_svc
;
334 xdr_argument
= (xdrproc_t
) xdr_domainname
;
335 xdr_result
= (xdrproc_t
) xdr_ypresp_maplist
;
336 local
= (char *(*)(char *, struct svc_req
*)) ypproc_maplist_2_svc
;
340 svcerr_noproc(transp
);
344 (void) memset((char *)&argument
, 0, sizeof (argument
));
345 if (!svc_getargs(transp
, xdr_argument
, (caddr_t
) &argument
)) {
346 svcerr_decode(transp
);
350 result
= (*local
)((char *)&argument
, rqstp
);
351 if (result
!= NULL
&& !svc_sendreply(transp
, xdr_result
, result
)) {
352 svcerr_systemerr(transp
);
354 if (!svc_freeargs(transp
, xdr_argument
, (caddr_t
) &argument
)) {
355 _msgout("unable to free arguments");
367 register SVCXPRT
*transp
= NULL
;
370 struct sockaddr_in saddr
;
371 int asize
= sizeof (saddr
);
378 while ((ch
= getopt(argc
, argv
, "1a:dx")) != -1)
398 (void)fprintf(stderr
,"usage: %s [-a aclfile] [-d] [-x]\n",progname
);
402 if (geteuid() != 0) {
403 (void)fprintf(stderr
,"%s: must be root to run.\n",progname
);
407 if (aclfile
!= NULL
) {
408 (void)yp_acl_init(aclfile
);
410 (void)yp_acl_securenet(YP_SECURENET_FILE
);
416 if (getsockname(0, (struct sockaddr
*)&saddr
, &asize
) == 0) {
417 int ssize
= sizeof (int);
419 if (saddr
.sin_family
!= AF_INET
)
421 if (getsockopt(0, SOL_SOCKET
, SO_TYPE
,
422 (char *)&_rpcfdtype
, &ssize
) == -1)
427 openlog("ypserv", LOG_PID
, LOG_DAEMON
);
435 perror("cannot fork");
440 size
= getdtablesize();
441 for (i
= 0; i
< size
; i
++)
443 i
= open("/dev/console", 2);
446 i
= open("/dev/tty", 2);
448 (void) ioctl(i
, TIOCNOTTY
, (char *)NULL
);
451 openlog("ypserv", LOG_PID
, LOG_DAEMON
);
454 (void) pmap_unset(YPPROG
, YPVERS
);
455 (void) pmap_unset(YPPROG
, YPOLDVERS
);
458 ypopenlog(); /* open log file */
459 ypdb_init(); /* init db stuff */
463 (void)signal(SIGCHLD
, sig_child
);
464 (void)signal(SIGHUP
, sig_hup
);
465 { FILE *pidfile
= fopen(YPSERV_PID_PATH
, "w");
466 if (pidfile
!= NULL
) {
467 fprintf(pidfile
, "%d\n", getpid());
472 if ((_rpcfdtype
== 0) || (_rpcfdtype
== SOCK_DGRAM
)) {
473 transp
= svcudp_create(sock
);
474 if (transp
== NULL
) {
475 _msgout("cannot create udp service.");
478 if (transp
->xp_port
>= IPPORT_RESERVED
) {
479 _msgout("cannot allocate udp privileged port.");
485 if (!svc_register(transp
, YPPROG
, YPOLDVERS
, ypprog_1
, proto
)) {
486 _msgout("unable to register (YPPROG, YPOLDVERS, udp).");
490 if (!svc_register(transp
, YPPROG
, YPVERS
, ypprog_2
, proto
)) {
491 _msgout("unable to register (YPPROG, YPVERS, udp).");
496 if ((_rpcfdtype
== 0) || (_rpcfdtype
== SOCK_STREAM
)) {
498 transp
= svcfd_create(sock
, 0, 0);
500 transp
= svctcp_create(sock
, 0, 0);
501 if (transp
== NULL
) {
502 _msgout("cannot create tcp service.");
505 if (transp
->xp_port
>= IPPORT_RESERVED
) {
506 _msgout("cannot allocate tcp privileged port.");
512 if (!svc_register(transp
, YPPROG
, YPOLDVERS
, ypprog_1
, proto
)) {
513 _msgout("unable to register (YPPROG, YPOLDVERS, tcp).");
517 if (!svc_register(transp
, YPPROG
, YPVERS
, ypprog_2
, proto
)) {
518 _msgout("unable to register (YPPROG, YPVERS, tcp).");
523 if (transp
== (SVCXPRT
*)NULL
) {
524 _msgout("could not create a handle");
528 (void) signal(SIGALRM
, (SIG_PF
) closedown
);
529 (void) alarm(_RPCSVC_CLOSEDOWN
);
532 _msgout("svc_run returned");
540 int save_errno
= errno
;
542 while (wait3((int *)NULL
, WNOHANG
, (struct rusage
*)NULL
) > 0)
551 if (aclfile
!= NULL
) {
552 yplog("sig_hup: reread %s",aclfile
);
553 (void)yp_acl_init(aclfile
);
555 yplog("sig_hup: reread %s",YP_SECURENET_FILE
);
556 (void)yp_acl_securenet(YP_SECURENET_FILE
);