10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate /*
23*702Sth160488 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate *
260Sstevel@tonic-gate */
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate * This source was formally rpcgen generated, but has been
310Sstevel@tonic-gate * checked in.
320Sstevel@tonic-gate */
330Sstevel@tonic-gate
340Sstevel@tonic-gate #include "ypxfrd.h"
350Sstevel@tonic-gate #include <stdio.h>
360Sstevel@tonic-gate #include <stdlib.h> /* getenv, exit */
370Sstevel@tonic-gate #include <signal.h>
380Sstevel@tonic-gate #include <rpc/pmap_clnt.h> /* for pmap_unset */
390Sstevel@tonic-gate #include <string.h> /* strcmp */
400Sstevel@tonic-gate #include <unistd.h> /* setsid */
410Sstevel@tonic-gate #include <sys/types.h>
420Sstevel@tonic-gate #include <memory.h>
430Sstevel@tonic-gate #include <stropts.h>
440Sstevel@tonic-gate #include <netconfig.h>
450Sstevel@tonic-gate #include <sys/resource.h> /* rlimit */
460Sstevel@tonic-gate #include <syslog.h>
470Sstevel@tonic-gate #include <ndbm.h>
480Sstevel@tonic-gate #include "shim.h"
490Sstevel@tonic-gate #include "yptol.h"
500Sstevel@tonic-gate
510Sstevel@tonic-gate #ifndef SIG_PF
520Sstevel@tonic-gate #define SIG_PF void(*)(int)
530Sstevel@tonic-gate #endif
540Sstevel@tonic-gate
550Sstevel@tonic-gate #ifdef DEBUG
560Sstevel@tonic-gate #define RPC_SVC_FG
570Sstevel@tonic-gate #endif
580Sstevel@tonic-gate
590Sstevel@tonic-gate #define _RPCSVC_CLOSEDOWN 120
600Sstevel@tonic-gate
610Sstevel@tonic-gate /*
620Sstevel@tonic-gate * Copyr 1989 Sun Micro
630Sstevel@tonic-gate * #ident "@(#)ypxfrd.x 1.2 00/05/01 SMI"
640Sstevel@tonic-gate * This is NOT source code!
650Sstevel@tonic-gate * DO NOT EDIT THIS FILE!
660Sstevel@tonic-gate */
670Sstevel@tonic-gate static int _rpcpmstart; /* Started by a port monitor ? */
680Sstevel@tonic-gate
690Sstevel@tonic-gate /* States a server can be in wrt request */
700Sstevel@tonic-gate
710Sstevel@tonic-gate #define _IDLE 0
720Sstevel@tonic-gate #define _SERVED 1
730Sstevel@tonic-gate
740Sstevel@tonic-gate static int _rpcsvcstate = _IDLE; /* Set when a request is serviced */
750Sstevel@tonic-gate static int _rpcsvccount = 0; /* Number of requests being serviced */
760Sstevel@tonic-gate
770Sstevel@tonic-gate static void
_msgout(char * msg)780Sstevel@tonic-gate _msgout(char *msg)
790Sstevel@tonic-gate {
800Sstevel@tonic-gate #ifdef RPC_SVC_FG
810Sstevel@tonic-gate if (_rpcpmstart)
820Sstevel@tonic-gate syslog(LOG_ERR, "%s", msg);
830Sstevel@tonic-gate else
840Sstevel@tonic-gate (void) fprintf(stderr, "%s\n", msg);
850Sstevel@tonic-gate #else
860Sstevel@tonic-gate syslog(LOG_ERR, "%s", msg);
870Sstevel@tonic-gate #endif
880Sstevel@tonic-gate }
890Sstevel@tonic-gate
900Sstevel@tonic-gate static void
closedown(int sig)910Sstevel@tonic-gate closedown(int sig)
920Sstevel@tonic-gate {
930Sstevel@tonic-gate if (_rpcsvcstate == _IDLE && _rpcsvccount == 0) {
940Sstevel@tonic-gate int size;
950Sstevel@tonic-gate int i, openfd = 0;
960Sstevel@tonic-gate
970Sstevel@tonic-gate size = svc_max_pollfd;
980Sstevel@tonic-gate for (i = 0; i < size && openfd < 2; i++)
990Sstevel@tonic-gate if (svc_pollfd[i].fd >= 0)
1000Sstevel@tonic-gate openfd++;
1010Sstevel@tonic-gate if (openfd <= 1)
1020Sstevel@tonic-gate exit(0);
1030Sstevel@tonic-gate } else
1040Sstevel@tonic-gate _rpcsvcstate = _IDLE;
1050Sstevel@tonic-gate
1060Sstevel@tonic-gate (void) signal(SIGALRM, (SIG_PF) closedown);
1070Sstevel@tonic-gate (void) alarm(_RPCSVC_CLOSEDOWN/2);
1080Sstevel@tonic-gate }
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate static void
ypxfrd_1(struct svc_req * rqstp,register SVCXPRT * transp)1110Sstevel@tonic-gate ypxfrd_1(struct svc_req *rqstp, register SVCXPRT *transp)
1120Sstevel@tonic-gate {
1130Sstevel@tonic-gate union {
1140Sstevel@tonic-gate hosereq getdbm_1_arg;
1150Sstevel@tonic-gate } argument;
1160Sstevel@tonic-gate char *result;
1170Sstevel@tonic-gate xdrproc_t _xdr_argument, _xdr_result;
1180Sstevel@tonic-gate char *(*local)(char *, struct svc_req *);
1190Sstevel@tonic-gate
1200Sstevel@tonic-gate _rpcsvccount++;
1210Sstevel@tonic-gate switch (rqstp->rq_proc) {
1220Sstevel@tonic-gate case NULLPROC:
1230Sstevel@tonic-gate (void) svc_sendreply(transp,
1240Sstevel@tonic-gate (xdrproc_t)xdr_void, (char *)NULL);
1250Sstevel@tonic-gate _rpcsvccount--;
1260Sstevel@tonic-gate _rpcsvcstate = _SERVED;
1270Sstevel@tonic-gate return;
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate case getdbm:
1300Sstevel@tonic-gate _xdr_argument = (xdrproc_t)xdr_hosereq;
1310Sstevel@tonic-gate _xdr_result = (xdrproc_t)xdr_dbmfyl;
1320Sstevel@tonic-gate local = (char *(*)(char *, struct svc_req *)) getdbm_1_svc;
1330Sstevel@tonic-gate break;
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate default:
1360Sstevel@tonic-gate svcerr_noproc(transp);
1370Sstevel@tonic-gate _rpcsvccount--;
1380Sstevel@tonic-gate _rpcsvcstate = _SERVED;
1390Sstevel@tonic-gate return;
1400Sstevel@tonic-gate }
1410Sstevel@tonic-gate (void) memset((char *)&argument, 0, sizeof (argument));
1420Sstevel@tonic-gate if (!svc_getargs(transp, _xdr_argument, (caddr_t)&argument)) {
1430Sstevel@tonic-gate svcerr_decode(transp);
1440Sstevel@tonic-gate _rpcsvccount--;
1450Sstevel@tonic-gate _rpcsvcstate = _SERVED;
1460Sstevel@tonic-gate return;
1470Sstevel@tonic-gate }
1480Sstevel@tonic-gate result = (*local)((char *)&argument, rqstp);
1490Sstevel@tonic-gate if (_xdr_result && result != NULL &&
1500Sstevel@tonic-gate !svc_sendreply(transp, _xdr_result, result)) {
1510Sstevel@tonic-gate svcerr_systemerr(transp);
1520Sstevel@tonic-gate }
1530Sstevel@tonic-gate if (!svc_freeargs(transp, _xdr_argument, (caddr_t)&argument)) {
1540Sstevel@tonic-gate _msgout("unable to free arguments");
1550Sstevel@tonic-gate exit(1);
1560Sstevel@tonic-gate }
1570Sstevel@tonic-gate _rpcsvccount--;
1580Sstevel@tonic-gate _rpcsvcstate = _SERVED;
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate
161*702Sth160488 int
main()1620Sstevel@tonic-gate main()
1630Sstevel@tonic-gate {
1640Sstevel@tonic-gate pid_t pid;
1650Sstevel@tonic-gate int i;
1660Sstevel@tonic-gate int stat;
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate (void) sigset(SIGPIPE, SIG_IGN);
1690Sstevel@tonic-gate
1700Sstevel@tonic-gate /*
1710Sstevel@tonic-gate * If stdin looks like a TLI endpoint, we assume
1720Sstevel@tonic-gate * that we were started by a port monitor. If
1730Sstevel@tonic-gate * t_getstate fails with TBADF, this is not a
1740Sstevel@tonic-gate * TLI endpoint.
1750Sstevel@tonic-gate */
1760Sstevel@tonic-gate if (t_getstate(0) != -1 || t_errno != TBADF) {
1770Sstevel@tonic-gate char *netid;
1780Sstevel@tonic-gate struct netconfig *nconf = NULL;
1790Sstevel@tonic-gate SVCXPRT *transp;
1800Sstevel@tonic-gate int pmclose;
1810Sstevel@tonic-gate
1820Sstevel@tonic-gate _rpcpmstart = 1;
1830Sstevel@tonic-gate openlog("ypxfrd", LOG_NDELAY|LOG_PID, LOG_DAEMON);
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate if ((netid = getenv("NLSPROVIDER")) == NULL) {
1860Sstevel@tonic-gate /* started from inetd */
1870Sstevel@tonic-gate pmclose = 1;
1880Sstevel@tonic-gate } else {
1890Sstevel@tonic-gate if ((nconf = getnetconfigent(netid)) == NULL)
1900Sstevel@tonic-gate _msgout("cannot get transport info");
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate pmclose = (t_getstate(0) != T_DATAXFER);
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate if ((transp = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {
1950Sstevel@tonic-gate _msgout("cannot create server handle");
1960Sstevel@tonic-gate exit(1);
1970Sstevel@tonic-gate }
1980Sstevel@tonic-gate if (nconf)
1990Sstevel@tonic-gate freenetconfigent(nconf);
2000Sstevel@tonic-gate if (!svc_reg(transp, YPXFRD, V1, ypxfrd_1, 0)) {
2010Sstevel@tonic-gate _msgout("unable to register (YPXFRD, V1).");
2020Sstevel@tonic-gate exit(1);
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate if (pmclose) {
2050Sstevel@tonic-gate (void) signal(SIGALRM, (SIG_PF) closedown);
2060Sstevel@tonic-gate (void) alarm(_RPCSVC_CLOSEDOWN/2);
2070Sstevel@tonic-gate }
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate if (yptol_mode) {
2100Sstevel@tonic-gate stat = parseConfig(NULL, NTOL_MAP_FILE);
2110Sstevel@tonic-gate if (stat == 1) {
2120Sstevel@tonic-gate _msgout("NIS to LDAP mapping inactive.");
2130Sstevel@tonic-gate } else if (stat != 0) {
2140Sstevel@tonic-gate _msgout("Aborting after NIS to LDAP "
2150Sstevel@tonic-gate "mapping error.");
2160Sstevel@tonic-gate exit(1);
2170Sstevel@tonic-gate }
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate svc_run();
2210Sstevel@tonic-gate exit(1);
2220Sstevel@tonic-gate /* NOTREACHED */
2230Sstevel@tonic-gate } else {
2240Sstevel@tonic-gate #ifndef RPC_SVC_FG
2250Sstevel@tonic-gate #pragma weak closefrom
2260Sstevel@tonic-gate extern void closefrom();
2270Sstevel@tonic-gate int size;
2280Sstevel@tonic-gate struct rlimit rl;
2290Sstevel@tonic-gate pid = fork();
2300Sstevel@tonic-gate if (pid < 0) {
2310Sstevel@tonic-gate perror("cannot fork");
2320Sstevel@tonic-gate exit(1);
2330Sstevel@tonic-gate }
2340Sstevel@tonic-gate if (pid)
2350Sstevel@tonic-gate exit(0);
2360Sstevel@tonic-gate closelog();
2370Sstevel@tonic-gate if (closefrom != NULL)
2380Sstevel@tonic-gate closefrom(0);
2390Sstevel@tonic-gate else {
2400Sstevel@tonic-gate rl.rlim_max = 0;
2410Sstevel@tonic-gate getrlimit(RLIMIT_NOFILE, &rl);
2420Sstevel@tonic-gate if ((size = rl.rlim_max) == 0)
2430Sstevel@tonic-gate exit(1);
2440Sstevel@tonic-gate for (i = 0; i < size; i++)
2450Sstevel@tonic-gate (void) close(i);
2460Sstevel@tonic-gate }
2470Sstevel@tonic-gate i = open("/dev/null", 2);
2480Sstevel@tonic-gate (void) dup2(i, 1);
2490Sstevel@tonic-gate (void) dup2(i, 2);
2500Sstevel@tonic-gate openlog("ypxfrd", LOG_NDELAY|LOG_PID, LOG_DAEMON);
2510Sstevel@tonic-gate setsid();
2520Sstevel@tonic-gate #endif
2530Sstevel@tonic-gate }
2540Sstevel@tonic-gate
2550Sstevel@tonic-gate if (yptol_mode) {
2560Sstevel@tonic-gate stat = parseConfig(NULL, NTOL_MAP_FILE);
2570Sstevel@tonic-gate if (stat == 1) {
2580Sstevel@tonic-gate _msgout("NIS to LDAP mapping inactive.");
2590Sstevel@tonic-gate } else if (stat != 0) {
2600Sstevel@tonic-gate _msgout("Aborting after NIS to LDAP mapping error.");
2610Sstevel@tonic-gate exit(1);
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate }
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate if (!svc_create(ypxfrd_1, YPXFRD, V1, "visible")) {
2660Sstevel@tonic-gate _msgout("unable to create (YPXFRD, V1) for visible.");
2670Sstevel@tonic-gate exit(1);
2680Sstevel@tonic-gate }
2690Sstevel@tonic-gate
2700Sstevel@tonic-gate svc_run();
2710Sstevel@tonic-gate _msgout("svc_run returned");
2720Sstevel@tonic-gate exit(1);
2730Sstevel@tonic-gate /* NOTREACHED */
2740Sstevel@tonic-gate }
275