4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2017 Gary Mills
24 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
32 * Portions of this source code were derived from Berkeley 4.3 BSD
33 * under license from the Regents of the University of California.
37 * This contains the mainline code for the YP server. Data
38 * structures which are process-global are also in this module.
41 /* this is so that ypserv will compile under 5.5 */
44 extern int gettimeofday(struct timeval
*);
47 #include <sys/types.h>
51 #include <netconfig.h>
53 #include <sys/select.h>
63 static char register_failed
[] = "ypserv: Unable to register service for ";
67 * client_setup_failure will be TRUE, if setup of the
68 * connection to rpc.nisd_resolv failed
70 bool client_setup_failure
= FALSE
;
73 bool init_dit
= FALSE
;
74 bool init_containers
= FALSE
;
75 bool init_maps
= FALSE
;
76 char **ldapCLA
= NULL
;
78 /* For DNS forwarding command line option (-d) */
79 bool dnsforward
= FALSE
;
81 CLIENT
*resolv_client
= NULL
;
82 char *resolv_tp
= "ticots";
85 /* For cluster support (-c) */
86 bool multiflag
= FALSE
;
89 static char logfile
[] = "/var/yp/ypserv.log";
90 void logprintf(char *format
, ...);
92 static void ypexit(void);
93 static void ypinit(int argc
, char **argv
);
94 static void ypdispatch(struct svc_req
*rqstp
, SVCXPRT
*transp
);
95 static void ypolddispatch(struct svc_req
*rqstp
, SVCXPRT
*transp
);
96 static void ypget_command_line_args(int argc
, char **argv
);
97 extern void setup_resolv(bool *fwding
, int *child
,
98 CLIENT
**client
, char *tp_type
, long prognum
);
99 static void cleanup_resolv(int);
102 * This is the main line code for the yp server.
105 main(int argc
, char **argv
)
107 if (geteuid() != 0) {
108 fprintf(stderr
, "must be root to run %s\n", argv
[0]);
115 /* If requested set up the N2L maps. May take a while */
117 if (FAILURE
== dump_maps_to_dit(init_containers
)) {
118 fprintf(stderr
, "Fatal error dumping maps to DIT."
119 " See syslog and LDAP server logs for details.\n");
124 if (FAILURE
== dump_dit_to_maps()) {
125 fprintf(stderr
, "Fatal error dumping DIT to maps."
126 " See syslog and LDAP server logs for details.\n");
131 * If we were asked to init the maps now exit. User will then use
132 * ypstart to restart ypserv and all the other NIS daemons.
134 if (init_dit
|| init_maps
) {
135 printf("Map setup complete. Please now restart NIS daemons "
143 * This is stupid, but the compiler likes to warn us about the
144 * absence of returns from main()
152 int olddispatch
; /* Register on protocol version 1 ? */
153 int class; /* Other services that must succeed */
155 int ok
; /* Registered successfully ? */
158 ypservice_t service
[] = {
159 { "udp", -1, 1, 4, 0, 0 },
160 { "tcp", -1, 1, 4, 0, 0 },
161 { "udp6", -1, 0, 6, 0, 0 },
162 { "tcp6", -1, 0, 6, 0, 0 }
165 #define MAXSERVICES (sizeof (service)/sizeof (service[0]))
167 int service_classes
[MAXSERVICES
];
170 * Does startup processing for the yp server.
173 ypinit(int argc
, char **argv
)
177 struct sigaction act
;
179 SVCXPRT
*utransp
, *ttransp
;
180 struct netconfig
*nconf
;
181 int connmaxrec
= RPC_MAXDATASIZE
;
182 int i
, j
, services
= 0;
186 * Init yptol flags. Will get redone by init_lock_system() but we need
187 * to know if we should parse yptol cmd line options.
191 ypget_command_line_args(argc
, argv
);
197 logprintf("ypserv: ypinit fork failure.\n");
206 if (!init_lock_system(FALSE
)) {
210 get_secure_nets(argv
[0]);
218 stat
= parseConfig(ldapCLA
, NTOL_MAP_FILE
);
220 logprintf("NIS to LDAP mapping inactive.\n");
221 } else if (stat
!= 0) {
222 logprintf("Aborting after NIS to LDAP mapping "
230 freopen("/dev/null", "r", stdin
);
231 if (access(logfile
, _IOWRT
)) {
232 freopen("/dev/null", "w", stdout
);
233 freopen("/dev/null", "w", stderr
);
235 freopen(logfile
, "a", stdout
);
236 freopen(logfile
, "a", stderr
);
239 (void) open("/dev/tty", O_RDWR
);
245 sigset(SIGHUP
, (void (*)())sysvconfig
);
247 sigset(SIGHUP
, SIG_IGN
);
251 * Setting disposition to SIG_IGN will not create zombies when child
252 * processes terminate.
254 sigset(SIGCHLD
, SIG_IGN
);
256 act
.sa_handler
= cleanup_resolv
;
257 sigemptyset(&act
.sa_mask
);
258 act
.sa_flags
= SA_RESETHAND
;
259 sigaction(SIGTERM
, &act
, NULL
);
260 sigaction(SIGQUIT
, &act
, NULL
);
261 sigaction(SIGABRT
, &act
, NULL
);
262 sigaction(SIGBUS
, &act
, NULL
);
263 sigaction(SIGSEGV
, &act
, NULL
);
266 * Set non-blocking mode and maximum record size for
267 * connection oriented RPC transports.
269 if (!rpc_control(RPC_SVC_CONNMAXREC_SET
, &connmaxrec
)) {
270 logprintf("unable to set maximum RPC record size");
273 svc_unreg(YPPROG
, YPVERS
);
274 svc_unreg(YPPROG
, YPVERS_ORIG
);
276 for (i
= 0; i
< sizeof (service
)/sizeof (ypservice_t
); i
++) {
278 service_classes
[i
] = -1;
280 if ((nconf
= getnetconfigent(service
[i
].netid
)) == NULL
) {
281 logprintf("getnetconfigent(\"%s\") failed\n",
286 if ((service
[i
].fd
= t_open(nconf
->nc_device
, O_RDWR
, NULL
)) <
288 logprintf("t_open failed for %s\n", service
[i
].netid
);
289 freenetconfigent(nconf
);
293 if (netdir_options(nconf
, ND_SET_RESERVEDPORT
, service
[i
].fd
,
295 logprintf("could not set reserved port for %s\n",
297 (void) close(service
[i
].fd
);
299 freenetconfigent(nconf
);
303 if ((service
[i
].xprt
= svc_tli_create(service
[i
].fd
, nconf
,
304 NULL
, 0, 0)) == NULL
) {
305 logprintf("svc_tli_create failed for %s\n",
307 (void) close(service
[i
].fd
);
309 freenetconfigent(nconf
);
313 if (!svc_reg(service
[i
].xprt
, YPPROG
, YPVERS
, ypdispatch
,
315 logprintf("%s %s\n", service
[i
].netid
, register_failed
);
316 svc_destroy(service
[i
].xprt
);
318 (void) close(service
[i
].fd
);
320 freenetconfigent(nconf
);
324 if (service
[i
].olddispatch
&& !svc_reg(service
[i
].xprt
, YPPROG
,
325 YPVERS_ORIG
, ypolddispatch
, nconf
)) {
326 logprintf("old %s %s\n",
327 service
[i
].netid
, register_failed
);
328 /* Can only unregister prognum/versnum */
329 svc_destroy(service
[i
].xprt
);
331 (void) close(service
[i
].fd
);
333 freenetconfigent(nconf
);
339 service_classes
[i
] = service
[i
].class;
341 freenetconfigent(nconf
);
346 * Check if we managed to register enough services to continue.
347 * It's OK if we managed to register all IPv4 services but no
348 * IPv6, or the other way around, but not if we (say) registered
349 * IPv4 UDP but not TCP.
352 for (j
= 0; j
< MAXSERVICES
; j
++) {
353 if (service_classes
[j
] >= 0) {
355 * Must have all services of this class
358 for (i
= 0; i
< MAXSERVICES
; i
++) {
359 if (service
[i
].ok
== 0 &&
361 service_classes
[j
]) {
363 "unable to register all services for class %d\n",
371 logprintf("unable to register any services\n");
375 /* Now we setup circuit_n or yp_all() and yp_update() will not work */
376 if (!svc_create(ypdispatch
, YPPROG
, YPVERS
, "circuit_n")) {
377 logprintf("circuit_n %s\n", register_failed
);
382 setup_resolv(&dnsforward
, &resolv_pid
,
383 &resolv_client
, resolv_tp
, 0);
384 if (resolv_client
== NULL
)
385 client_setup_failure
= TRUE
;
390 cleanup_resolv(int sig
)
393 kill(resolv_pid
, sig
);
399 * This picks up any command line args passed from the process invocation.
402 ypget_command_line_args(int argc
, char **argv
)
404 for (argv
++; --argc
; argv
++) {
406 if ((*argv
)[0] == '-') {
408 switch ((*argv
)[1]) {
409 #ifdef MINUS_C_OPTION
415 if (access("/etc/resolv.conf", F_OK
) == -1) {
417 "No /etc/resolv.conf file, -d option ignored\n");
423 init_containers
= TRUE
;
424 /* ... and also do -i stuff */
429 fprintf(stderr
, "-%c option is illegal "
430 "if not in NIS to LDAP mode. Exiting\n",
437 if ('r' != (*argv
)[2])
444 fprintf(stderr
, "-r option is illegal "
445 "if not in NIS to LDAP mode. "
458 /* If setting up don't run silent or demonize */
459 if (init_dit
|| init_maps
)
465 * This dispatches to server action routines based on the input procedure
466 * number. ypdispatch is called from the RPC function svc_run.
469 ypdispatch(struct svc_req
*rqstp
, SVCXPRT
*transp
)
475 /* prepare to answer questions about system v filesystem aliases */
480 sigaddset(&set
, SIGCHLD
);
481 sigprocmask(SIG_BLOCK
, &set
, &oset
);
483 switch (rqstp
->rq_proc
) {
487 if (!svc_sendreply(transp
, xdr_void
, 0))
488 logprintf("ypserv: Can't reply to rpc call.\n");
492 ypdomain(transp
, TRUE
);
495 case YPPROC_DOMAIN_NONACK
:
496 ypdomain(transp
, FALSE
);
500 ypmatch(transp
, rqstp
);
512 ypxfr(transp
, YPPROC_XFR
);
516 ypxfr(transp
, YPPROC_NEWXFR
);
522 if (!svc_sendreply(transp
, xdr_void
, 0))
523 logprintf("ypserv: Can't reply to rpc call.\n");
543 svcerr_noproc(transp
);
548 sigprocmask(SIG_SETMASK
, &oset
, (sigset_t
*)NULL
);
553 ypolddispatch(struct svc_req
*rqstp
, SVCXPRT
*transp
)
558 sigaddset(&set
, SIGCHLD
);
559 sigprocmask(SIG_BLOCK
, &set
, &oset
);
561 switch (rqstp
->rq_proc
) {
564 if (!svc_sendreply(transp
, xdr_void
, 0))
565 logprintf("ypserv: Can't replay to rpc call.\n");
568 case YPOLDPROC_DOMAIN
:
569 ypdomain(transp
, TRUE
);
572 case YPOLDPROC_DOMAIN_NONACK
:
573 ypdomain(transp
, FALSE
);
576 case YPOLDPROC_MATCH
:
577 ypoldmatch(transp
, rqstp
);
580 case YPOLDPROC_FIRST
:
604 svcerr_noproc(transp
);
608 sigprocmask(SIG_SETMASK
, &oset
, (sigset_t
*)NULL
);
612 * This flushes output to stderr, then aborts the server process to leave a
623 * This constructs a logging record.
626 logprintf(char *format
, ...)
631 va_start(ap
, format
);
636 fprintf(stderr
, "%19.19s: ", ctime(&t
.tv_sec
));
639 vfprintf(stderr
, format
, ap
);