1 /*
2 * CDDL HEADER START
3 *
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
7 * with the License.
8 *
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.
13 *
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]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 */
27
28 /*
29 * This source was formally rpcgen generated, but has been
30 * checked in.
31 */
32
33 #include "ypxfrd.h"
34 #include <stdio.h>
35 #include <stdlib.h> /* getenv, exit */
36 #include <signal.h>
37 #include <rpc/pmap_clnt.h> /* for pmap_unset */
38 #include <string.h> /* strcmp */
39 #include <unistd.h> /* setsid */
40 #include <sys/types.h>
41 #include <memory.h>
42 #include <stropts.h>
43 #include <netconfig.h>
44 #include <sys/resource.h> /* rlimit */
45 #include <syslog.h>
46 #include <ndbm.h>
47 #include "shim.h"
48 #include "yptol.h"
49
50 #ifndef SIG_PF
51 #define SIG_PF void(*)(int)
52 #endif
53
54 #ifdef DEBUG
55 #define RPC_SVC_FG
56 #endif
57
58 #define _RPCSVC_CLOSEDOWN 120
59
60 /*
61 * Copyr 1989 Sun Micro
62 * #ident "@(#)ypxfrd.x 1.2 00/05/01 SMI"
63 * This is NOT source code!
64 * DO NOT EDIT THIS FILE!
65 */
66 static int _rpcpmstart; /* Started by a port monitor ? */
67
68 /* States a server can be in wrt request */
69
70 #define _IDLE 0
71 #define _SERVED 1
72
73 static int _rpcsvcstate = _IDLE; /* Set when a request is serviced */
74 static int _rpcsvccount = 0; /* Number of requests being serviced */
75
76 static void
_msgout(char * msg)77 _msgout(char *msg)
78 {
79 #ifdef RPC_SVC_FG
80 if (_rpcpmstart)
81 syslog(LOG_ERR, "%s", msg);
82 else
83 (void) fprintf(stderr, "%s\n", msg);
84 #else
85 syslog(LOG_ERR, "%s", msg);
86 #endif
87 }
88
89 static void
closedown(int sig)90 closedown(int sig)
91 {
92 if (_rpcsvcstate == _IDLE && _rpcsvccount == 0) {
93 int size;
94 int i, openfd = 0;
95
96 size = svc_max_pollfd;
97 for (i = 0; i < size && openfd < 2; i++)
98 if (svc_pollfd[i].fd >= 0)
99 openfd++;
100 if (openfd <= 1)
101 exit(0);
102 } else
103 _rpcsvcstate = _IDLE;
104
105 (void) signal(SIGALRM, (SIG_PF) closedown);
106 (void) alarm(_RPCSVC_CLOSEDOWN/2);
107 }
108
109 static void
ypxfrd_1(struct svc_req * rqstp,register SVCXPRT * transp)110 ypxfrd_1(struct svc_req *rqstp, register SVCXPRT *transp)
111 {
112 union {
113 hosereq getdbm_1_arg;
114 } argument;
115 char *result;
116 xdrproc_t _xdr_argument, _xdr_result;
117 char *(*local)(char *, struct svc_req *);
118
119 _rpcsvccount++;
120 switch (rqstp->rq_proc) {
121 case NULLPROC:
122 (void) svc_sendreply(transp,
123 (xdrproc_t)xdr_void, (char *)NULL);
124 _rpcsvccount--;
125 _rpcsvcstate = _SERVED;
126 return;
127
128 case getdbm:
129 _xdr_argument = (xdrproc_t)xdr_hosereq;
130 _xdr_result = (xdrproc_t)xdr_dbmfyl;
131 local = (char *(*)(char *, struct svc_req *)) getdbm_1_svc;
132 break;
133
134 default:
135 svcerr_noproc(transp);
136 _rpcsvccount--;
137 _rpcsvcstate = _SERVED;
138 return;
139 }
140 (void) memset((char *)&argument, 0, sizeof (argument));
141 if (!svc_getargs(transp, _xdr_argument, (caddr_t)&argument)) {
142 svcerr_decode(transp);
143 _rpcsvccount--;
144 _rpcsvcstate = _SERVED;
145 return;
146 }
147 result = (*local)((char *)&argument, rqstp);
148 if (_xdr_result && result != NULL &&
149 !svc_sendreply(transp, _xdr_result, result)) {
150 svcerr_systemerr(transp);
151 }
152 if (!svc_freeargs(transp, _xdr_argument, (caddr_t)&argument)) {
153 _msgout("unable to free arguments");
154 exit(1);
155 }
156 _rpcsvccount--;
157 _rpcsvcstate = _SERVED;
158 }
159
160 int
main()161 main()
162 {
163 pid_t pid;
164 int i;
165 int stat;
166
167 (void) sigset(SIGPIPE, SIG_IGN);
168
169 /*
170 * If stdin looks like a TLI endpoint, we assume
171 * that we were started by a port monitor. If
172 * t_getstate fails with TBADF, this is not a
173 * TLI endpoint.
174 */
175 if (t_getstate(0) != -1 || t_errno != TBADF) {
176 char *netid;
177 struct netconfig *nconf = NULL;
178 SVCXPRT *transp;
179 int pmclose;
180
181 _rpcpmstart = 1;
182 openlog("ypxfrd", LOG_NDELAY|LOG_PID, LOG_DAEMON);
183
184 if ((netid = getenv("NLSPROVIDER")) == NULL) {
185 /* started from inetd */
186 pmclose = 1;
187 } else {
188 if ((nconf = getnetconfigent(netid)) == NULL)
189 _msgout("cannot get transport info");
190
191 pmclose = (t_getstate(0) != T_DATAXFER);
192 }
193 if ((transp = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {
194 _msgout("cannot create server handle");
195 exit(1);
196 }
197 if (nconf)
198 freenetconfigent(nconf);
199 if (!svc_reg(transp, YPXFRD, V1, ypxfrd_1, 0)) {
200 _msgout("unable to register (YPXFRD, V1).");
201 exit(1);
202 }
203 if (pmclose) {
204 (void) signal(SIGALRM, (SIG_PF) closedown);
205 (void) alarm(_RPCSVC_CLOSEDOWN/2);
206 }
207
208 if (yptol_mode) {
209 stat = parseConfig(NULL, NTOL_MAP_FILE);
210 if (stat == 1) {
211 _msgout("NIS to LDAP mapping inactive.");
212 } else if (stat != 0) {
213 _msgout("Aborting after NIS to LDAP "
214 "mapping error.");
215 exit(1);
216 }
217 }
218
219 svc_run();
220 exit(1);
221 /* NOTREACHED */
222 } else {
223 #ifndef RPC_SVC_FG
224 #pragma weak closefrom
225 extern void closefrom();
226 int size;
227 struct rlimit rl;
228 pid = fork();
229 if (pid < 0) {
230 perror("cannot fork");
231 exit(1);
232 }
233 if (pid)
234 exit(0);
235 closelog();
236 if (closefrom != NULL)
237 closefrom(0);
238 else {
239 rl.rlim_max = 0;
240 getrlimit(RLIMIT_NOFILE, &rl);
241 if ((size = rl.rlim_max) == 0)
242 exit(1);
243 for (i = 0; i < size; i++)
244 (void) close(i);
245 }
246 i = open("/dev/null", 2);
247 (void) dup2(i, 1);
248 (void) dup2(i, 2);
249 openlog("ypxfrd", LOG_NDELAY|LOG_PID, LOG_DAEMON);
250 setsid();
251 #endif
252 }
253
254 if (yptol_mode) {
255 stat = parseConfig(NULL, NTOL_MAP_FILE);
256 if (stat == 1) {
257 _msgout("NIS to LDAP mapping inactive.");
258 } else if (stat != 0) {
259 _msgout("Aborting after NIS to LDAP mapping error.");
260 exit(1);
261 }
262 }
263
264 if (!svc_create(ypxfrd_1, YPXFRD, V1, "visible")) {
265 _msgout("unable to create (YPXFRD, V1) for visible.");
266 exit(1);
267 }
268
269 svc_run();
270 _msgout("svc_run returned");
271 exit(1);
272 /* NOTREACHED */
273 }
274