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 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 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 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 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