1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 28*7c478bd9Sstevel@tonic-gate /* 29*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 30*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 31*7c478bd9Sstevel@tonic-gate * All Rights Reserved 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 34*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 35*7c478bd9Sstevel@tonic-gate * contributors. 36*7c478bd9Sstevel@tonic-gate */ 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate /* 41*7c478bd9Sstevel@tonic-gate * rpcbind.c 42*7c478bd9Sstevel@tonic-gate * Implements the program, version to address mapping for rpc. 43*7c478bd9Sstevel@tonic-gate * 44*7c478bd9Sstevel@tonic-gate */ 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate #include <dlfcn.h> 47*7c478bd9Sstevel@tonic-gate #include <stdio.h> 48*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 49*7c478bd9Sstevel@tonic-gate #include <unistd.h> 50*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 51*7c478bd9Sstevel@tonic-gate #include <string.h> 52*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 53*7c478bd9Sstevel@tonic-gate #include <netconfig.h> 54*7c478bd9Sstevel@tonic-gate #include <netdir.h> 55*7c478bd9Sstevel@tonic-gate #include <errno.h> 56*7c478bd9Sstevel@tonic-gate #include <sys/wait.h> 57*7c478bd9Sstevel@tonic-gate #include <signal.h> 58*7c478bd9Sstevel@tonic-gate #include <string.h> 59*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 60*7c478bd9Sstevel@tonic-gate #include <thread.h> 61*7c478bd9Sstevel@tonic-gate #include <synch.h> 62*7c478bd9Sstevel@tonic-gate #include <deflt.h> 63*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 64*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 65*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 66*7c478bd9Sstevel@tonic-gate #endif 67*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 68*7c478bd9Sstevel@tonic-gate #include <sys/termios.h> 69*7c478bd9Sstevel@tonic-gate #include "rpcbind.h" 70*7c478bd9Sstevel@tonic-gate #include <sys/syslog.h> 71*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 72*7c478bd9Sstevel@tonic-gate #include <syslog.h> 73*7c478bd9Sstevel@tonic-gate #include <string.h> 74*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 75*7c478bd9Sstevel@tonic-gate #include <sys/resource.h> 76*7c478bd9Sstevel@tonic-gate #include <rpcsvc/daemon_utils.h> 77*7c478bd9Sstevel@tonic-gate #include <priv_utils.h> 78*7c478bd9Sstevel@tonic-gate #include <libscf.h> 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 81*7c478bd9Sstevel@tonic-gate extern void pmap_service(struct svc_req *, SVCXPRT *xprt); 82*7c478bd9Sstevel@tonic-gate #endif 83*7c478bd9Sstevel@tonic-gate extern void rpcb_service_3(struct svc_req *, SVCXPRT *xprt); 84*7c478bd9Sstevel@tonic-gate extern void rpcb_service_4(struct svc_req *, SVCXPRT *xprt); 85*7c478bd9Sstevel@tonic-gate extern void read_warmstart(void); 86*7c478bd9Sstevel@tonic-gate extern void write_warmstart(void); 87*7c478bd9Sstevel@tonic-gate extern int Is_ipv6present(void); 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate #define MAX_FILEDESC_LIMIT 1023 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate static void terminate(int); 92*7c478bd9Sstevel@tonic-gate static void detachfromtty(void); 93*7c478bd9Sstevel@tonic-gate static void parseargs(int, char *[]); 94*7c478bd9Sstevel@tonic-gate static void rbllist_add(ulong_t, ulong_t, struct netconfig *, struct netbuf *); 95*7c478bd9Sstevel@tonic-gate static int init_transport(struct netconfig *); 96*7c478bd9Sstevel@tonic-gate static int check_netconfig(void); 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate static boolean_t check_hostserv(struct netconfig *, const char *, const char *); 99*7c478bd9Sstevel@tonic-gate static void rpcb_check_init(void); 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate /* Global variables */ 103*7c478bd9Sstevel@tonic-gate #ifdef ND_DEBUG 104*7c478bd9Sstevel@tonic-gate int debugging = 1; /* Tell me what's going on */ 105*7c478bd9Sstevel@tonic-gate #else 106*7c478bd9Sstevel@tonic-gate int debugging = 0; /* Tell me what's going on */ 107*7c478bd9Sstevel@tonic-gate #endif 108*7c478bd9Sstevel@tonic-gate static int ipv6flag = 0; 109*7c478bd9Sstevel@tonic-gate int doabort = 0; /* When debugging, do an abort on errors */ 110*7c478bd9Sstevel@tonic-gate static int listen_backlog = 64; 111*7c478bd9Sstevel@tonic-gate rpcblist_ptr list_rbl; /* A list of version 3/4 rpcbind services */ 112*7c478bd9Sstevel@tonic-gate char *loopback_dg; /* Datagram loopback transport, for set and unset */ 113*7c478bd9Sstevel@tonic-gate char *loopback_vc; /* COTS loopback transport, for set and unset */ 114*7c478bd9Sstevel@tonic-gate char *loopback_vc_ord; /* COTS_ORD loopback transport, for set and unset */ 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate boolean_t verboselog = B_FALSE; 117*7c478bd9Sstevel@tonic-gate boolean_t wrap_enabled = B_FALSE; 118*7c478bd9Sstevel@tonic-gate boolean_t allow_indirect = B_TRUE; 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate /* Local Variable */ 121*7c478bd9Sstevel@tonic-gate static int warmstart = 0; /* Grab a old copy of registrations */ 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 124*7c478bd9Sstevel@tonic-gate PMAPLIST *list_pml; /* A list of version 2 rpcbind services */ 125*7c478bd9Sstevel@tonic-gate char *udptrans; /* Name of UDP transport */ 126*7c478bd9Sstevel@tonic-gate char *tcptrans; /* Name of TCP transport */ 127*7c478bd9Sstevel@tonic-gate char *udp_uaddr; /* Universal UDP address */ 128*7c478bd9Sstevel@tonic-gate char *tcp_uaddr; /* Universal TCP address */ 129*7c478bd9Sstevel@tonic-gate #endif 130*7c478bd9Sstevel@tonic-gate static char servname[] = "rpcbind"; 131*7c478bd9Sstevel@tonic-gate static char superuser[] = "superuser"; 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate static const char daemon_dir[] = DAEMON_DIR; 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate int 136*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 137*7c478bd9Sstevel@tonic-gate { 138*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 139*7c478bd9Sstevel@tonic-gate void *nc_handle; /* Net config handle */ 140*7c478bd9Sstevel@tonic-gate struct rlimit rl; 141*7c478bd9Sstevel@tonic-gate int maxrecsz = RPC_MAXDATASIZE; 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate parseargs(argc, argv); 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate getrlimit(RLIMIT_NOFILE, &rl); 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate if (rl.rlim_cur < MAX_FILEDESC_LIMIT) { 148*7c478bd9Sstevel@tonic-gate if (rl.rlim_max <= MAX_FILEDESC_LIMIT) 149*7c478bd9Sstevel@tonic-gate rl.rlim_cur = rl.rlim_max; 150*7c478bd9Sstevel@tonic-gate else 151*7c478bd9Sstevel@tonic-gate rl.rlim_cur = MAX_FILEDESC_LIMIT; 152*7c478bd9Sstevel@tonic-gate setrlimit(RLIMIT_NOFILE, &rl); 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate openlog("rpcbind", LOG_CONS, LOG_DAEMON); 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate /* 157*7c478bd9Sstevel@tonic-gate * Create the daemon directory in /var/run 158*7c478bd9Sstevel@tonic-gate */ 159*7c478bd9Sstevel@tonic-gate if (mkdir(daemon_dir, DAEMON_DIR_MODE) == 0 || errno == EEXIST) { 160*7c478bd9Sstevel@tonic-gate chmod(daemon_dir, DAEMON_DIR_MODE); 161*7c478bd9Sstevel@tonic-gate chown(daemon_dir, DAEMON_UID, DAEMON_GID); 162*7c478bd9Sstevel@tonic-gate } else { 163*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "failed to create \"%s\": %m", daemon_dir); 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate /* 167*7c478bd9Sstevel@tonic-gate * These privileges are required for the t_bind check rpcbind uses 168*7c478bd9Sstevel@tonic-gate * to determine whether a service is still live or not. 169*7c478bd9Sstevel@tonic-gate */ 170*7c478bd9Sstevel@tonic-gate if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, DAEMON_UID, 171*7c478bd9Sstevel@tonic-gate DAEMON_GID, PRIV_NET_PRIVADDR, PRIV_SYS_NFS, (char *)NULL) == -1) { 172*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Insufficient privileges\n"); 173*7c478bd9Sstevel@tonic-gate exit(1); 174*7c478bd9Sstevel@tonic-gate } 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate /* 177*7c478bd9Sstevel@tonic-gate * Enable non-blocking mode and maximum record size checks for 178*7c478bd9Sstevel@tonic-gate * connection oriented transports. 179*7c478bd9Sstevel@tonic-gate */ 180*7c478bd9Sstevel@tonic-gate if (!rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrecsz)) { 181*7c478bd9Sstevel@tonic-gate syslog(LOG_INFO, "unable to set RPC max record size"); 182*7c478bd9Sstevel@tonic-gate } 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate nc_handle = setnetconfig(); /* open netconfig file */ 185*7c478bd9Sstevel@tonic-gate if (nc_handle == NULL) { 186*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "could not read /etc/netconfig"); 187*7c478bd9Sstevel@tonic-gate exit(1); 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate loopback_dg = ""; 190*7c478bd9Sstevel@tonic-gate loopback_vc = ""; 191*7c478bd9Sstevel@tonic-gate loopback_vc_ord = ""; 192*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 193*7c478bd9Sstevel@tonic-gate udptrans = ""; 194*7c478bd9Sstevel@tonic-gate tcptrans = ""; 195*7c478bd9Sstevel@tonic-gate #endif 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate { 198*7c478bd9Sstevel@tonic-gate /* 199*7c478bd9Sstevel@tonic-gate * rpcbind is the first application to encounter the 200*7c478bd9Sstevel@tonic-gate * various netconfig files. check_netconfig() verifies 201*7c478bd9Sstevel@tonic-gate * that they are set up correctly and complains loudly 202*7c478bd9Sstevel@tonic-gate * if not. 203*7c478bd9Sstevel@tonic-gate */ 204*7c478bd9Sstevel@tonic-gate int trouble; 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate trouble = check_netconfig(); 207*7c478bd9Sstevel@tonic-gate if (trouble) { 208*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 209*7c478bd9Sstevel@tonic-gate "%s: found %d errors with network configuration files. Exiting.", 210*7c478bd9Sstevel@tonic-gate argv[0], trouble); 211*7c478bd9Sstevel@tonic-gate fprintf(stderr, 212*7c478bd9Sstevel@tonic-gate "%s: found %d errors with network configuration files. Exiting.\n", 213*7c478bd9Sstevel@tonic-gate argv[0], trouble); 214*7c478bd9Sstevel@tonic-gate exit(1); 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate ipv6flag = Is_ipv6present(); 218*7c478bd9Sstevel@tonic-gate rpcb_check_init(); 219*7c478bd9Sstevel@tonic-gate while (nconf = getnetconfig(nc_handle)) { 220*7c478bd9Sstevel@tonic-gate if (nconf->nc_flag & NC_VISIBLE) 221*7c478bd9Sstevel@tonic-gate init_transport(nconf); 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate endnetconfig(nc_handle); 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate if ((loopback_dg[0] == NULL) && (loopback_vc[0] == NULL) && 226*7c478bd9Sstevel@tonic-gate (loopback_vc_ord[0] == NULL)) { 227*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "could not find loopback transports"); 228*7c478bd9Sstevel@tonic-gate exit(1); 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate /* catch the usual termination signals for graceful exit */ 232*7c478bd9Sstevel@tonic-gate (void) signal(SIGINT, terminate); 233*7c478bd9Sstevel@tonic-gate (void) signal(SIGTERM, terminate); 234*7c478bd9Sstevel@tonic-gate (void) signal(SIGQUIT, terminate); 235*7c478bd9Sstevel@tonic-gate /* ignore others that could get sent */ 236*7c478bd9Sstevel@tonic-gate (void) signal(SIGHUP, SIG_IGN); 237*7c478bd9Sstevel@tonic-gate (void) signal(SIGUSR1, SIG_IGN); 238*7c478bd9Sstevel@tonic-gate (void) signal(SIGUSR2, SIG_IGN); 239*7c478bd9Sstevel@tonic-gate if (warmstart) { 240*7c478bd9Sstevel@tonic-gate read_warmstart(); 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate if (debugging) { 243*7c478bd9Sstevel@tonic-gate printf("rpcbind debugging enabled."); 244*7c478bd9Sstevel@tonic-gate if (doabort) { 245*7c478bd9Sstevel@tonic-gate printf(" Will abort on errors!\n"); 246*7c478bd9Sstevel@tonic-gate } else { 247*7c478bd9Sstevel@tonic-gate printf("\n"); 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate } else { 250*7c478bd9Sstevel@tonic-gate detachfromtty(); 251*7c478bd9Sstevel@tonic-gate } 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate /* These are basic privileges we do not need */ 254*7c478bd9Sstevel@tonic-gate __fini_daemon_priv(PRIV_PROC_EXEC, PRIV_PROC_SESSION, 255*7c478bd9Sstevel@tonic-gate PRIV_FILE_LINK_ANY, PRIV_PROC_INFO, (char *)NULL); 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate my_svc_run(); 258*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "svc_run returned unexpectedly"); 259*7c478bd9Sstevel@tonic-gate rpcbind_abort(); 260*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 261*7c478bd9Sstevel@tonic-gate } 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate /* 264*7c478bd9Sstevel@tonic-gate * Increments a counter each time a problem is found with the network 265*7c478bd9Sstevel@tonic-gate * configuration information. 266*7c478bd9Sstevel@tonic-gate */ 267*7c478bd9Sstevel@tonic-gate static int 268*7c478bd9Sstevel@tonic-gate check_netconfig(void) 269*7c478bd9Sstevel@tonic-gate { 270*7c478bd9Sstevel@tonic-gate void *nc; 271*7c478bd9Sstevel@tonic-gate void *dlcookie; 272*7c478bd9Sstevel@tonic-gate int busted = 0; 273*7c478bd9Sstevel@tonic-gate int i; 274*7c478bd9Sstevel@tonic-gate int lo_clts_found = 0, lo_cots_found = 0, lo_cotsord_found = 0; 275*7c478bd9Sstevel@tonic-gate struct netconfig *nconf, *np; 276*7c478bd9Sstevel@tonic-gate struct stat sb; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate nc = setnetconfig(); 279*7c478bd9Sstevel@tonic-gate if (nc == NULL) { 280*7c478bd9Sstevel@tonic-gate if (debugging) 281*7c478bd9Sstevel@tonic-gate fprintf(stderr, 282*7c478bd9Sstevel@tonic-gate "setnetconfig() failed: %s\n", nc_sperror()); 283*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, "setnetconfig() failed: %s", nc_sperror()); 284*7c478bd9Sstevel@tonic-gate return (1); 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate while (np = getnetconfig(nc)) { 287*7c478bd9Sstevel@tonic-gate if ((np->nc_flag & NC_VISIBLE) == 0) 288*7c478bd9Sstevel@tonic-gate continue; 289*7c478bd9Sstevel@tonic-gate if (debugging) 290*7c478bd9Sstevel@tonic-gate fprintf(stderr, "checking netid \"%s\"\n", 291*7c478bd9Sstevel@tonic-gate np->nc_netid); 292*7c478bd9Sstevel@tonic-gate if (strcmp(np->nc_protofmly, NC_LOOPBACK) == 0) 293*7c478bd9Sstevel@tonic-gate switch (np->nc_semantics) { 294*7c478bd9Sstevel@tonic-gate case NC_TPI_CLTS: 295*7c478bd9Sstevel@tonic-gate lo_clts_found = 1; 296*7c478bd9Sstevel@tonic-gate break; 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate case NC_TPI_COTS: 299*7c478bd9Sstevel@tonic-gate lo_cots_found = 1; 300*7c478bd9Sstevel@tonic-gate break; 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate case NC_TPI_COTS_ORD: 303*7c478bd9Sstevel@tonic-gate lo_cotsord_found = 1; 304*7c478bd9Sstevel@tonic-gate break; 305*7c478bd9Sstevel@tonic-gate } 306*7c478bd9Sstevel@tonic-gate if (stat(np->nc_device, &sb) == -1 && errno == ENOENT) { 307*7c478bd9Sstevel@tonic-gate if (debugging) 308*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\tdevice %s does not exist\n", 309*7c478bd9Sstevel@tonic-gate np->nc_device); 310*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "netid %s: device %s does not exist", 311*7c478bd9Sstevel@tonic-gate np->nc_netid, np->nc_device); 312*7c478bd9Sstevel@tonic-gate busted++; 313*7c478bd9Sstevel@tonic-gate } else 314*7c478bd9Sstevel@tonic-gate if (debugging) 315*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\tdevice %s present\n", 316*7c478bd9Sstevel@tonic-gate np->nc_device); 317*7c478bd9Sstevel@tonic-gate for (i = 0; i < np->nc_nlookups; i++) { 318*7c478bd9Sstevel@tonic-gate char *libname = np->nc_lookups[i]; 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate if ((dlcookie = dlopen(libname, RTLD_LAZY)) == NULL) { 321*7c478bd9Sstevel@tonic-gate char *dlerrstr; 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate dlerrstr = dlerror(); 324*7c478bd9Sstevel@tonic-gate if (debugging) { 325*7c478bd9Sstevel@tonic-gate fprintf(stderr, 326*7c478bd9Sstevel@tonic-gate "\tnetid %s: dlopen of name-to-address library %s failed\ndlerror: %s", 327*7c478bd9Sstevel@tonic-gate np->nc_netid, libname, dlerrstr ? dlerrstr : ""); 328*7c478bd9Sstevel@tonic-gate } 329*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 330*7c478bd9Sstevel@tonic-gate "netid %s: dlopen of name-to-address library %s failed", 331*7c478bd9Sstevel@tonic-gate np->nc_netid, libname); 332*7c478bd9Sstevel@tonic-gate if (dlerrstr) 333*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "%s", dlerrstr); 334*7c478bd9Sstevel@tonic-gate busted++; 335*7c478bd9Sstevel@tonic-gate } else { 336*7c478bd9Sstevel@tonic-gate if (debugging) 337*7c478bd9Sstevel@tonic-gate fprintf(stderr, 338*7c478bd9Sstevel@tonic-gate "\tdlopen of name-to-address library %s succeeded\n", libname); 339*7c478bd9Sstevel@tonic-gate (void) dlclose(dlcookie); 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate nconf = getnetconfigent(np->nc_netid); 343*7c478bd9Sstevel@tonic-gate 344*7c478bd9Sstevel@tonic-gate if (!check_hostserv(nconf, HOST_SELF, "")) 345*7c478bd9Sstevel@tonic-gate busted++; 346*7c478bd9Sstevel@tonic-gate if (!check_hostserv(nconf, HOST_SELF_CONNECT, "")) 347*7c478bd9Sstevel@tonic-gate busted++; 348*7c478bd9Sstevel@tonic-gate if (!check_hostserv(nconf, HOST_SELF, "rpcbind")) 349*7c478bd9Sstevel@tonic-gate busted++; 350*7c478bd9Sstevel@tonic-gate if (!check_hostserv(nconf, HOST_SELF_CONNECT, "rpcbind")) 351*7c478bd9Sstevel@tonic-gate busted++; 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate freenetconfigent(nconf); 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate endnetconfig(nc); 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate if (lo_clts_found) { 358*7c478bd9Sstevel@tonic-gate if (debugging) 359*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Found CLTS loopback transport\n"); 360*7c478bd9Sstevel@tonic-gate } else { 361*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, "no CLTS loopback transport found\n"); 362*7c478bd9Sstevel@tonic-gate if (debugging) 363*7c478bd9Sstevel@tonic-gate fprintf(stderr, "no CLTS loopback transport found\n"); 364*7c478bd9Sstevel@tonic-gate } 365*7c478bd9Sstevel@tonic-gate if (lo_cots_found) { 366*7c478bd9Sstevel@tonic-gate if (debugging) 367*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Found COTS loopback transport\n"); 368*7c478bd9Sstevel@tonic-gate } else { 369*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, "no COTS loopback transport found\n"); 370*7c478bd9Sstevel@tonic-gate if (debugging) 371*7c478bd9Sstevel@tonic-gate fprintf(stderr, "no COTS loopback transport found\n"); 372*7c478bd9Sstevel@tonic-gate } 373*7c478bd9Sstevel@tonic-gate if (lo_cotsord_found) { 374*7c478bd9Sstevel@tonic-gate if (debugging) 375*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Found COTS ORD loopback transport\n"); 376*7c478bd9Sstevel@tonic-gate } else { 377*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, "no COTS ORD loopback transport found\n"); 378*7c478bd9Sstevel@tonic-gate if (debugging) 379*7c478bd9Sstevel@tonic-gate fprintf(stderr, 380*7c478bd9Sstevel@tonic-gate "no COTS ORD loopback transport found\n"); 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate return (busted); 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate /* 387*7c478bd9Sstevel@tonic-gate * Adds the entry into the rpcbind database. 388*7c478bd9Sstevel@tonic-gate * If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also 389*7c478bd9Sstevel@tonic-gate * Returns 0 if succeeds, else fails 390*7c478bd9Sstevel@tonic-gate */ 391*7c478bd9Sstevel@tonic-gate static int 392*7c478bd9Sstevel@tonic-gate init_transport(struct netconfig *nconf) 393*7c478bd9Sstevel@tonic-gate { 394*7c478bd9Sstevel@tonic-gate int fd; 395*7c478bd9Sstevel@tonic-gate struct t_bind *taddr, *baddr; 396*7c478bd9Sstevel@tonic-gate SVCXPRT *my_xprt; 397*7c478bd9Sstevel@tonic-gate struct nd_addrlist *nas; 398*7c478bd9Sstevel@tonic-gate struct nd_hostserv hs; 399*7c478bd9Sstevel@tonic-gate int status; /* bound checking ? */ 400*7c478bd9Sstevel@tonic-gate static int msgprt = 0; 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate static int setopt_reuseaddr(int); 403*7c478bd9Sstevel@tonic-gate static int setup_callit(int); 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate if ((nconf->nc_semantics != NC_TPI_CLTS) && 406*7c478bd9Sstevel@tonic-gate (nconf->nc_semantics != NC_TPI_COTS) && 407*7c478bd9Sstevel@tonic-gate (nconf->nc_semantics != NC_TPI_COTS_ORD)) 408*7c478bd9Sstevel@tonic-gate return (1); /* not my type */ 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate if ((strcmp(nconf->nc_protofmly, NC_INET6) == 0) && !ipv6flag) { 411*7c478bd9Sstevel@tonic-gate if (!msgprt) 412*7c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 413*7c478bd9Sstevel@tonic-gate "/etc/netconfig has IPv6 entries but IPv6 is not configured"); 414*7c478bd9Sstevel@tonic-gate msgprt++; 415*7c478bd9Sstevel@tonic-gate return (1); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate #ifdef ND_DEBUG 418*7c478bd9Sstevel@tonic-gate { 419*7c478bd9Sstevel@tonic-gate int i; 420*7c478bd9Sstevel@tonic-gate char **s; 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: %d lookup routines :\n", 423*7c478bd9Sstevel@tonic-gate nconf->nc_netid, nconf->nc_nlookups); 424*7c478bd9Sstevel@tonic-gate for (i = 0, s = nconf->nc_lookups; i < nconf->nc_nlookups; i++, s++) 425*7c478bd9Sstevel@tonic-gate fprintf(stderr, "[%d] - %s\n", i, *s); 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate #endif 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate if ((fd = t_open(nconf->nc_device, O_RDWR, NULL)) < 0) { 430*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "%s: cannot open connection: %s", 431*7c478bd9Sstevel@tonic-gate nconf->nc_netid, t_errlist[t_errno]); 432*7c478bd9Sstevel@tonic-gate return (1); 433*7c478bd9Sstevel@tonic-gate } 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate /* 436*7c478bd9Sstevel@tonic-gate * Negotiate for returning the ucred of the caller. This should 437*7c478bd9Sstevel@tonic-gate * done before enabling the endpoint for service via 438*7c478bd9Sstevel@tonic-gate * t_bind() so that requests to rpcbind contain the uid. 439*7c478bd9Sstevel@tonic-gate */ 440*7c478bd9Sstevel@tonic-gate svc_fd_negotiate_ucred(fd); 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate taddr = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR); 443*7c478bd9Sstevel@tonic-gate baddr = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR); 444*7c478bd9Sstevel@tonic-gate if ((baddr == NULL) || (taddr == NULL)) { 445*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "%s: cannot allocate netbuf: %s", 446*7c478bd9Sstevel@tonic-gate nconf->nc_netid, t_errlist[t_errno]); 447*7c478bd9Sstevel@tonic-gate exit(1); 448*7c478bd9Sstevel@tonic-gate } 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate /* Get rpcbind's address on this transport */ 451*7c478bd9Sstevel@tonic-gate hs.h_host = HOST_SELF; 452*7c478bd9Sstevel@tonic-gate hs.h_serv = servname; 453*7c478bd9Sstevel@tonic-gate if (netdir_getbyname(nconf, &hs, &nas)) 454*7c478bd9Sstevel@tonic-gate goto error; 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate /* Copy the address */ 457*7c478bd9Sstevel@tonic-gate taddr->addr.len = nas->n_addrs->len; 458*7c478bd9Sstevel@tonic-gate memcpy(taddr->addr.buf, nas->n_addrs->buf, (int)nas->n_addrs->len); 459*7c478bd9Sstevel@tonic-gate #ifdef ND_DEBUG 460*7c478bd9Sstevel@tonic-gate { 461*7c478bd9Sstevel@tonic-gate /* for debugging print out our universal address */ 462*7c478bd9Sstevel@tonic-gate char *uaddr; 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate uaddr = taddr2uaddr(nconf, nas->n_addrs); 465*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "rpcbind : my address is %s\n", uaddr); 466*7c478bd9Sstevel@tonic-gate (void) free(uaddr); 467*7c478bd9Sstevel@tonic-gate } 468*7c478bd9Sstevel@tonic-gate #endif 469*7c478bd9Sstevel@tonic-gate netdir_free((char *)nas, ND_ADDRLIST); 470*7c478bd9Sstevel@tonic-gate 471*7c478bd9Sstevel@tonic-gate if (nconf->nc_semantics == NC_TPI_CLTS) 472*7c478bd9Sstevel@tonic-gate taddr->qlen = 0; 473*7c478bd9Sstevel@tonic-gate else 474*7c478bd9Sstevel@tonic-gate taddr->qlen = listen_backlog; 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate if (strcmp(nconf->nc_proto, NC_TCP) == 0) { 477*7c478bd9Sstevel@tonic-gate /* 478*7c478bd9Sstevel@tonic-gate * Sm: If we are running then set SO_REUSEADDR option 479*7c478bd9Sstevel@tonic-gate * so that we can bind to our preferred address even if 480*7c478bd9Sstevel@tonic-gate * previous connections are in FIN_WAIT state 481*7c478bd9Sstevel@tonic-gate */ 482*7c478bd9Sstevel@tonic-gate #ifdef ND_DEBUG 483*7c478bd9Sstevel@tonic-gate fprintf(stdout, "Setting SO_REUSEADDR.\n"); 484*7c478bd9Sstevel@tonic-gate #endif 485*7c478bd9Sstevel@tonic-gate if (setopt_reuseaddr(fd) == -1) { 486*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "Couldn't set SO_REUSEADDR option"); 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate if (t_bind(fd, taddr, baddr) != 0) { 491*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "%s: cannot bind: %s", 492*7c478bd9Sstevel@tonic-gate nconf->nc_netid, t_errlist[t_errno]); 493*7c478bd9Sstevel@tonic-gate goto error; 494*7c478bd9Sstevel@tonic-gate } 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate if (memcmp(taddr->addr.buf, baddr->addr.buf, (int)baddr->addr.len)) { 498*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "%s: address in use", nconf->nc_netid); 499*7c478bd9Sstevel@tonic-gate goto error; 500*7c478bd9Sstevel@tonic-gate } 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, baddr, 0, 0); 503*7c478bd9Sstevel@tonic-gate if (my_xprt == (SVCXPRT *)NULL) { 504*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "%s: could not create service", 505*7c478bd9Sstevel@tonic-gate nconf->nc_netid); 506*7c478bd9Sstevel@tonic-gate goto error; 507*7c478bd9Sstevel@tonic-gate } 508*7c478bd9Sstevel@tonic-gate 509*7c478bd9Sstevel@tonic-gate /* set up multicast address for RPC CALL_IT, IPv6 */ 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate if ((strcmp(nconf->nc_protofmly, NC_INET6) == 0) && 512*7c478bd9Sstevel@tonic-gate (strcmp(nconf->nc_proto, NC_UDP) == 0)) { 513*7c478bd9Sstevel@tonic-gate if (setup_callit(fd) < 0) { 514*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "Unable to join IPv6 multicast group \ 515*7c478bd9Sstevel@tonic-gate for rpc broadcast %s", RPCB_MULTICAST_ADDR); 516*7c478bd9Sstevel@tonic-gate } 517*7c478bd9Sstevel@tonic-gate } 518*7c478bd9Sstevel@tonic-gate 519*7c478bd9Sstevel@tonic-gate if (strcmp(nconf->nc_proto, NC_TCP) == 0) { 520*7c478bd9Sstevel@tonic-gate svc_control(my_xprt, SVCSET_KEEPALIVE, (void *) TRUE); 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 524*7c478bd9Sstevel@tonic-gate /* 525*7c478bd9Sstevel@tonic-gate * Register both the versions for tcp/ip and udp/ip 526*7c478bd9Sstevel@tonic-gate */ 527*7c478bd9Sstevel@tonic-gate if ((strcmp(nconf->nc_protofmly, NC_INET) == 0) && 528*7c478bd9Sstevel@tonic-gate ((strcmp(nconf->nc_proto, NC_TCP) == 0) || 529*7c478bd9Sstevel@tonic-gate (strcmp(nconf->nc_proto, NC_UDP) == 0))) { 530*7c478bd9Sstevel@tonic-gate PMAPLIST *pml; 531*7c478bd9Sstevel@tonic-gate 532*7c478bd9Sstevel@tonic-gate if (!svc_register(my_xprt, PMAPPROG, PMAPVERS, 533*7c478bd9Sstevel@tonic-gate pmap_service, NULL)) { 534*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "could not register on %s", 535*7c478bd9Sstevel@tonic-gate nconf->nc_netid); 536*7c478bd9Sstevel@tonic-gate goto error; 537*7c478bd9Sstevel@tonic-gate } 538*7c478bd9Sstevel@tonic-gate pml = (PMAPLIST *)malloc((uint_t)sizeof (PMAPLIST)); 539*7c478bd9Sstevel@tonic-gate if (pml == (PMAPLIST *)NULL) { 540*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "no memory!"); 541*7c478bd9Sstevel@tonic-gate exit(1); 542*7c478bd9Sstevel@tonic-gate } 543*7c478bd9Sstevel@tonic-gate pml->pml_map.pm_prog = PMAPPROG; 544*7c478bd9Sstevel@tonic-gate pml->pml_map.pm_vers = PMAPVERS; 545*7c478bd9Sstevel@tonic-gate pml->pml_map.pm_port = PMAPPORT; 546*7c478bd9Sstevel@tonic-gate if (strcmp(nconf->nc_proto, NC_TCP) == 0) { 547*7c478bd9Sstevel@tonic-gate if (tcptrans[0]) { 548*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 549*7c478bd9Sstevel@tonic-gate "cannot have more than one TCP transport"); 550*7c478bd9Sstevel@tonic-gate goto error; 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate tcptrans = strdup(nconf->nc_netid); 553*7c478bd9Sstevel@tonic-gate pml->pml_map.pm_prot = IPPROTO_TCP; 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate /* Let's snarf the universal address */ 556*7c478bd9Sstevel@tonic-gate /* "h1.h2.h3.h4.p1.p2" */ 557*7c478bd9Sstevel@tonic-gate tcp_uaddr = taddr2uaddr(nconf, &baddr->addr); 558*7c478bd9Sstevel@tonic-gate } else { 559*7c478bd9Sstevel@tonic-gate if (udptrans[0]) { 560*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 561*7c478bd9Sstevel@tonic-gate "cannot have more than one UDP transport"); 562*7c478bd9Sstevel@tonic-gate goto error; 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate udptrans = strdup(nconf->nc_netid); 565*7c478bd9Sstevel@tonic-gate pml->pml_map.pm_prot = IPPROTO_UDP; 566*7c478bd9Sstevel@tonic-gate 567*7c478bd9Sstevel@tonic-gate /* Let's snarf the universal address */ 568*7c478bd9Sstevel@tonic-gate /* "h1.h2.h3.h4.p1.p2" */ 569*7c478bd9Sstevel@tonic-gate udp_uaddr = taddr2uaddr(nconf, &baddr->addr); 570*7c478bd9Sstevel@tonic-gate } 571*7c478bd9Sstevel@tonic-gate pml->pml_next = list_pml; 572*7c478bd9Sstevel@tonic-gate list_pml = pml; 573*7c478bd9Sstevel@tonic-gate 574*7c478bd9Sstevel@tonic-gate /* Add version 3 information */ 575*7c478bd9Sstevel@tonic-gate pml = (PMAPLIST *)malloc((uint_t)sizeof (PMAPLIST)); 576*7c478bd9Sstevel@tonic-gate if (pml == (PMAPLIST *)NULL) { 577*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "no memory!"); 578*7c478bd9Sstevel@tonic-gate exit(1); 579*7c478bd9Sstevel@tonic-gate } 580*7c478bd9Sstevel@tonic-gate pml->pml_map = list_pml->pml_map; 581*7c478bd9Sstevel@tonic-gate pml->pml_map.pm_vers = RPCBVERS; 582*7c478bd9Sstevel@tonic-gate pml->pml_next = list_pml; 583*7c478bd9Sstevel@tonic-gate list_pml = pml; 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate /* Add version 4 information */ 586*7c478bd9Sstevel@tonic-gate pml = (PMAPLIST *)malloc((uint_t)sizeof (PMAPLIST)); 587*7c478bd9Sstevel@tonic-gate if (pml == (PMAPLIST *)NULL) { 588*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "no memory!"); 589*7c478bd9Sstevel@tonic-gate exit(1); 590*7c478bd9Sstevel@tonic-gate } 591*7c478bd9Sstevel@tonic-gate pml->pml_map = list_pml->pml_map; 592*7c478bd9Sstevel@tonic-gate pml->pml_map.pm_vers = RPCBVERS4; 593*7c478bd9Sstevel@tonic-gate pml->pml_next = list_pml; 594*7c478bd9Sstevel@tonic-gate list_pml = pml; 595*7c478bd9Sstevel@tonic-gate 596*7c478bd9Sstevel@tonic-gate /* Also add version 2 stuff to rpcbind list */ 597*7c478bd9Sstevel@tonic-gate rbllist_add(PMAPPROG, PMAPVERS, nconf, &baddr->addr); 598*7c478bd9Sstevel@tonic-gate } 599*7c478bd9Sstevel@tonic-gate #endif 600*7c478bd9Sstevel@tonic-gate 601*7c478bd9Sstevel@tonic-gate /* version 3 registration */ 602*7c478bd9Sstevel@tonic-gate if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS, rpcb_service_3, NULL)) { 603*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "could not register %s version 3", 604*7c478bd9Sstevel@tonic-gate nconf->nc_netid); 605*7c478bd9Sstevel@tonic-gate goto error; 606*7c478bd9Sstevel@tonic-gate } 607*7c478bd9Sstevel@tonic-gate rbllist_add(RPCBPROG, RPCBVERS, nconf, &baddr->addr); 608*7c478bd9Sstevel@tonic-gate 609*7c478bd9Sstevel@tonic-gate /* version 4 registration */ 610*7c478bd9Sstevel@tonic-gate if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS4, rpcb_service_4, NULL)) { 611*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "could not register %s version 4", 612*7c478bd9Sstevel@tonic-gate nconf->nc_netid); 613*7c478bd9Sstevel@tonic-gate goto error; 614*7c478bd9Sstevel@tonic-gate } 615*7c478bd9Sstevel@tonic-gate rbllist_add(RPCBPROG, RPCBVERS4, nconf, &baddr->addr); 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) { 618*7c478bd9Sstevel@tonic-gate if (nconf->nc_semantics == NC_TPI_CLTS) 619*7c478bd9Sstevel@tonic-gate loopback_dg = strdup(nconf->nc_netid); 620*7c478bd9Sstevel@tonic-gate else if (nconf->nc_semantics == NC_TPI_COTS) 621*7c478bd9Sstevel@tonic-gate loopback_vc = strdup(nconf->nc_netid); 622*7c478bd9Sstevel@tonic-gate else if (nconf->nc_semantics == NC_TPI_COTS_ORD) 623*7c478bd9Sstevel@tonic-gate loopback_vc_ord = strdup(nconf->nc_netid); 624*7c478bd9Sstevel@tonic-gate } 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate /* decide if bound checking works for this transport */ 627*7c478bd9Sstevel@tonic-gate status = add_bndlist(nconf, taddr, baddr); 628*7c478bd9Sstevel@tonic-gate #ifdef BIND_DEBUG 629*7c478bd9Sstevel@tonic-gate if (status < 0) { 630*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Error in finding bind status for %s\n", 631*7c478bd9Sstevel@tonic-gate nconf->nc_netid); 632*7c478bd9Sstevel@tonic-gate } else if (status == 0) { 633*7c478bd9Sstevel@tonic-gate fprintf(stderr, "check binding for %s\n", 634*7c478bd9Sstevel@tonic-gate nconf->nc_netid); 635*7c478bd9Sstevel@tonic-gate } else if (status > 0) { 636*7c478bd9Sstevel@tonic-gate fprintf(stderr, "No check binding for %s\n", 637*7c478bd9Sstevel@tonic-gate nconf->nc_netid); 638*7c478bd9Sstevel@tonic-gate } 639*7c478bd9Sstevel@tonic-gate #endif 640*7c478bd9Sstevel@tonic-gate /* 641*7c478bd9Sstevel@tonic-gate * rmtcall only supported on CLTS transports for now. 642*7c478bd9Sstevel@tonic-gate * only needed when we are allowing indirect calls 643*7c478bd9Sstevel@tonic-gate */ 644*7c478bd9Sstevel@tonic-gate if (allow_indirect && nconf->nc_semantics == NC_TPI_CLTS) { 645*7c478bd9Sstevel@tonic-gate status = create_rmtcall_fd(nconf); 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate #ifdef BIND_DEBUG 648*7c478bd9Sstevel@tonic-gate if (status < 0) { 649*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Could not create rmtcall fd for %s\n", 650*7c478bd9Sstevel@tonic-gate nconf->nc_netid); 651*7c478bd9Sstevel@tonic-gate } else { 652*7c478bd9Sstevel@tonic-gate fprintf(stderr, "rmtcall fd for %s is %d\n", 653*7c478bd9Sstevel@tonic-gate nconf->nc_netid, status); 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate #endif 656*7c478bd9Sstevel@tonic-gate } 657*7c478bd9Sstevel@tonic-gate (void) t_free((char *)taddr, T_BIND); 658*7c478bd9Sstevel@tonic-gate (void) t_free((char *)baddr, T_BIND); 659*7c478bd9Sstevel@tonic-gate return (0); 660*7c478bd9Sstevel@tonic-gate error: 661*7c478bd9Sstevel@tonic-gate (void) t_free((char *)taddr, T_BIND); 662*7c478bd9Sstevel@tonic-gate (void) t_free((char *)baddr, T_BIND); 663*7c478bd9Sstevel@tonic-gate (void) t_close(fd); 664*7c478bd9Sstevel@tonic-gate return (1); 665*7c478bd9Sstevel@tonic-gate } 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate static void 668*7c478bd9Sstevel@tonic-gate rbllist_add(ulong_t prog, ulong_t vers, struct netconfig *nconf, 669*7c478bd9Sstevel@tonic-gate struct netbuf *addr) 670*7c478bd9Sstevel@tonic-gate { 671*7c478bd9Sstevel@tonic-gate rpcblist_ptr rbl; 672*7c478bd9Sstevel@tonic-gate 673*7c478bd9Sstevel@tonic-gate rbl = (rpcblist_ptr)malloc((uint_t)sizeof (rpcblist)); 674*7c478bd9Sstevel@tonic-gate if (rbl == (rpcblist_ptr)NULL) { 675*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "no memory!"); 676*7c478bd9Sstevel@tonic-gate exit(1); 677*7c478bd9Sstevel@tonic-gate } 678*7c478bd9Sstevel@tonic-gate 679*7c478bd9Sstevel@tonic-gate rbl->rpcb_map.r_prog = prog; 680*7c478bd9Sstevel@tonic-gate rbl->rpcb_map.r_vers = vers; 681*7c478bd9Sstevel@tonic-gate rbl->rpcb_map.r_netid = strdup(nconf->nc_netid); 682*7c478bd9Sstevel@tonic-gate rbl->rpcb_map.r_addr = taddr2uaddr(nconf, addr); 683*7c478bd9Sstevel@tonic-gate rbl->rpcb_map.r_owner = strdup(superuser); 684*7c478bd9Sstevel@tonic-gate rbl->rpcb_next = list_rbl; /* Attach to global list */ 685*7c478bd9Sstevel@tonic-gate list_rbl = rbl; 686*7c478bd9Sstevel@tonic-gate } 687*7c478bd9Sstevel@tonic-gate 688*7c478bd9Sstevel@tonic-gate /* 689*7c478bd9Sstevel@tonic-gate * Catch the signal and die 690*7c478bd9Sstevel@tonic-gate */ 691*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 692*7c478bd9Sstevel@tonic-gate static void 693*7c478bd9Sstevel@tonic-gate terminate(int sig) 694*7c478bd9Sstevel@tonic-gate { 695*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "rpcbind terminating on signal."); 696*7c478bd9Sstevel@tonic-gate write_warmstart(); /* Dump yourself */ 697*7c478bd9Sstevel@tonic-gate exit(2); 698*7c478bd9Sstevel@tonic-gate } 699*7c478bd9Sstevel@tonic-gate 700*7c478bd9Sstevel@tonic-gate void 701*7c478bd9Sstevel@tonic-gate rpcbind_abort(void) 702*7c478bd9Sstevel@tonic-gate { 703*7c478bd9Sstevel@tonic-gate write_warmstart(); /* Dump yourself */ 704*7c478bd9Sstevel@tonic-gate abort(); 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate /* 708*7c478bd9Sstevel@tonic-gate * detach from tty 709*7c478bd9Sstevel@tonic-gate */ 710*7c478bd9Sstevel@tonic-gate static void 711*7c478bd9Sstevel@tonic-gate detachfromtty(void) 712*7c478bd9Sstevel@tonic-gate { 713*7c478bd9Sstevel@tonic-gate close(0); 714*7c478bd9Sstevel@tonic-gate close(1); 715*7c478bd9Sstevel@tonic-gate close(2); 716*7c478bd9Sstevel@tonic-gate switch (forkall()) { 717*7c478bd9Sstevel@tonic-gate case (pid_t)-1: 718*7c478bd9Sstevel@tonic-gate perror("fork"); 719*7c478bd9Sstevel@tonic-gate break; 720*7c478bd9Sstevel@tonic-gate case 0: 721*7c478bd9Sstevel@tonic-gate break; 722*7c478bd9Sstevel@tonic-gate default: 723*7c478bd9Sstevel@tonic-gate exit(0); 724*7c478bd9Sstevel@tonic-gate } 725*7c478bd9Sstevel@tonic-gate setsid(); 726*7c478bd9Sstevel@tonic-gate (void) open("/dev/null", O_RDWR, 0); 727*7c478bd9Sstevel@tonic-gate dup(0); 728*7c478bd9Sstevel@tonic-gate dup(0); 729*7c478bd9Sstevel@tonic-gate } 730*7c478bd9Sstevel@tonic-gate 731*7c478bd9Sstevel@tonic-gate /* get command line options */ 732*7c478bd9Sstevel@tonic-gate static void 733*7c478bd9Sstevel@tonic-gate parseargs(int argc, char *argv[]) 734*7c478bd9Sstevel@tonic-gate { 735*7c478bd9Sstevel@tonic-gate int c; 736*7c478bd9Sstevel@tonic-gate int tmp; 737*7c478bd9Sstevel@tonic-gate 738*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "dwal:")) != EOF) { 739*7c478bd9Sstevel@tonic-gate switch (c) { 740*7c478bd9Sstevel@tonic-gate case 'd': 741*7c478bd9Sstevel@tonic-gate debugging = 1; 742*7c478bd9Sstevel@tonic-gate break; 743*7c478bd9Sstevel@tonic-gate case 'a': 744*7c478bd9Sstevel@tonic-gate doabort = 1; /* when debugging, do an abort on */ 745*7c478bd9Sstevel@tonic-gate break; /* errors; for rpcbind developers */ 746*7c478bd9Sstevel@tonic-gate /* only! */ 747*7c478bd9Sstevel@tonic-gate case 'w': 748*7c478bd9Sstevel@tonic-gate warmstart = 1; 749*7c478bd9Sstevel@tonic-gate break; 750*7c478bd9Sstevel@tonic-gate 751*7c478bd9Sstevel@tonic-gate case 'l': 752*7c478bd9Sstevel@tonic-gate if (sscanf(optarg, "%d", &tmp)) { 753*7c478bd9Sstevel@tonic-gate if (tmp > listen_backlog) { 754*7c478bd9Sstevel@tonic-gate listen_backlog = tmp; 755*7c478bd9Sstevel@tonic-gate } 756*7c478bd9Sstevel@tonic-gate } 757*7c478bd9Sstevel@tonic-gate break; 758*7c478bd9Sstevel@tonic-gate default: /* error */ 759*7c478bd9Sstevel@tonic-gate fprintf(stderr, 760*7c478bd9Sstevel@tonic-gate "usage: rpcbind [-d] [-w] [-l listen_backlog]\n"); 761*7c478bd9Sstevel@tonic-gate exit(1); 762*7c478bd9Sstevel@tonic-gate } 763*7c478bd9Sstevel@tonic-gate } 764*7c478bd9Sstevel@tonic-gate if (doabort && !debugging) { 765*7c478bd9Sstevel@tonic-gate fprintf(stderr, 766*7c478bd9Sstevel@tonic-gate "-a (abort) specified without -d (debugging) -- ignored.\n"); 767*7c478bd9Sstevel@tonic-gate doabort = 0; 768*7c478bd9Sstevel@tonic-gate } 769*7c478bd9Sstevel@tonic-gate } 770*7c478bd9Sstevel@tonic-gate 771*7c478bd9Sstevel@tonic-gate static int 772*7c478bd9Sstevel@tonic-gate setopt_reuseaddr(int fd) 773*7c478bd9Sstevel@tonic-gate { 774*7c478bd9Sstevel@tonic-gate struct t_optmgmt req, resp; 775*7c478bd9Sstevel@tonic-gate struct opthdr *opt; 776*7c478bd9Sstevel@tonic-gate char reqbuf[128]; 777*7c478bd9Sstevel@tonic-gate int *ip; 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate opt = (struct opthdr *)reqbuf; 780*7c478bd9Sstevel@tonic-gate opt->level = SOL_SOCKET; 781*7c478bd9Sstevel@tonic-gate opt->name = SO_REUSEADDR; 782*7c478bd9Sstevel@tonic-gate opt->len = sizeof (int); 783*7c478bd9Sstevel@tonic-gate 784*7c478bd9Sstevel@tonic-gate ip = (int *)&reqbuf[sizeof (struct opthdr)]; 785*7c478bd9Sstevel@tonic-gate *ip = 1; 786*7c478bd9Sstevel@tonic-gate 787*7c478bd9Sstevel@tonic-gate req.flags = T_NEGOTIATE; 788*7c478bd9Sstevel@tonic-gate req.opt.len = sizeof (struct opthdr) + opt->len; 789*7c478bd9Sstevel@tonic-gate req.opt.buf = (char *)opt; 790*7c478bd9Sstevel@tonic-gate 791*7c478bd9Sstevel@tonic-gate resp.flags = 0; 792*7c478bd9Sstevel@tonic-gate resp.opt.buf = reqbuf; 793*7c478bd9Sstevel@tonic-gate resp.opt.maxlen = sizeof (reqbuf); 794*7c478bd9Sstevel@tonic-gate 795*7c478bd9Sstevel@tonic-gate if (t_optmgmt(fd, &req, &resp) < 0 || resp.flags != T_SUCCESS) { 796*7c478bd9Sstevel@tonic-gate t_error("t_optmgmt"); 797*7c478bd9Sstevel@tonic-gate return (-1); 798*7c478bd9Sstevel@tonic-gate } 799*7c478bd9Sstevel@tonic-gate return (0); 800*7c478bd9Sstevel@tonic-gate } 801*7c478bd9Sstevel@tonic-gate 802*7c478bd9Sstevel@tonic-gate static int 803*7c478bd9Sstevel@tonic-gate setup_callit(int fd) 804*7c478bd9Sstevel@tonic-gate { 805*7c478bd9Sstevel@tonic-gate struct ipv6_mreq mreq; 806*7c478bd9Sstevel@tonic-gate struct t_optmgmt req, resp; 807*7c478bd9Sstevel@tonic-gate struct opthdr *opt; 808*7c478bd9Sstevel@tonic-gate char reqbuf[ sizeof (struct ipv6_mreq) + 24]; 809*7c478bd9Sstevel@tonic-gate struct ipv6_mreq *pmreq; 810*7c478bd9Sstevel@tonic-gate 811*7c478bd9Sstevel@tonic-gate opt = (struct opthdr *)reqbuf; 812*7c478bd9Sstevel@tonic-gate 813*7c478bd9Sstevel@tonic-gate opt->level = IPPROTO_IPV6; 814*7c478bd9Sstevel@tonic-gate opt->name = IPV6_ADD_MEMBERSHIP; 815*7c478bd9Sstevel@tonic-gate opt->len = sizeof (struct ipv6_mreq); 816*7c478bd9Sstevel@tonic-gate 817*7c478bd9Sstevel@tonic-gate /* multicast address */ 818*7c478bd9Sstevel@tonic-gate (void) inet_pton(AF_INET6, RPCB_MULTICAST_ADDR, 819*7c478bd9Sstevel@tonic-gate mreq.ipv6mr_multiaddr.s6_addr); 820*7c478bd9Sstevel@tonic-gate mreq.ipv6mr_interface = 0; 821*7c478bd9Sstevel@tonic-gate 822*7c478bd9Sstevel@tonic-gate /* insert it into opt */ 823*7c478bd9Sstevel@tonic-gate pmreq = (struct ipv6_mreq *)&reqbuf[sizeof (struct opthdr)]; 824*7c478bd9Sstevel@tonic-gate memcpy(pmreq, &mreq, sizeof (struct ipv6_mreq)); 825*7c478bd9Sstevel@tonic-gate 826*7c478bd9Sstevel@tonic-gate req.flags = T_NEGOTIATE; 827*7c478bd9Sstevel@tonic-gate req.opt.len = sizeof (struct opthdr) + opt->len; 828*7c478bd9Sstevel@tonic-gate req.opt.buf = (char *)opt; 829*7c478bd9Sstevel@tonic-gate 830*7c478bd9Sstevel@tonic-gate resp.flags = 0; 831*7c478bd9Sstevel@tonic-gate resp.opt.buf = reqbuf; 832*7c478bd9Sstevel@tonic-gate resp.opt.maxlen = sizeof (reqbuf); 833*7c478bd9Sstevel@tonic-gate 834*7c478bd9Sstevel@tonic-gate if (t_optmgmt(fd, &req, &resp) < 0 || resp.flags != T_SUCCESS) { 835*7c478bd9Sstevel@tonic-gate t_error("t_optmgmt"); 836*7c478bd9Sstevel@tonic-gate return (-1); 837*7c478bd9Sstevel@tonic-gate } 838*7c478bd9Sstevel@tonic-gate return (0); 839*7c478bd9Sstevel@tonic-gate } 840*7c478bd9Sstevel@tonic-gate 841*7c478bd9Sstevel@tonic-gate static boolean_t 842*7c478bd9Sstevel@tonic-gate check_hostserv(struct netconfig *nconf, const char *host, const char *serv) 843*7c478bd9Sstevel@tonic-gate { 844*7c478bd9Sstevel@tonic-gate struct nd_hostserv nh; 845*7c478bd9Sstevel@tonic-gate struct nd_addrlist *na; 846*7c478bd9Sstevel@tonic-gate const char *hostname = host; 847*7c478bd9Sstevel@tonic-gate const char *servname = serv; 848*7c478bd9Sstevel@tonic-gate int retval; 849*7c478bd9Sstevel@tonic-gate 850*7c478bd9Sstevel@tonic-gate if (strcmp(host, HOST_SELF) == 0) 851*7c478bd9Sstevel@tonic-gate hostname = "HOST_SELF"; 852*7c478bd9Sstevel@tonic-gate else if (strcmp(host, HOST_SELF_CONNECT) == 0) 853*7c478bd9Sstevel@tonic-gate hostname = "HOST_SELF_CONNECT"; 854*7c478bd9Sstevel@tonic-gate 855*7c478bd9Sstevel@tonic-gate if (serv[0] == '\0') 856*7c478bd9Sstevel@tonic-gate servname = "<any>"; 857*7c478bd9Sstevel@tonic-gate 858*7c478bd9Sstevel@tonic-gate nh.h_host = (char *)host; 859*7c478bd9Sstevel@tonic-gate nh.h_serv = (char *)serv; 860*7c478bd9Sstevel@tonic-gate 861*7c478bd9Sstevel@tonic-gate retval = netdir_getbyname(nconf, &nh, &na); 862*7c478bd9Sstevel@tonic-gate if (retval != ND_OK || na->n_cnt == 0) { 863*7c478bd9Sstevel@tonic-gate if (retval == ND_OK) 864*7c478bd9Sstevel@tonic-gate netdir_free(na, ND_ADDRLIST); 865*7c478bd9Sstevel@tonic-gate 866*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, "netid %s: cannot find an address for host " 867*7c478bd9Sstevel@tonic-gate "%s, service \"%s\"", nconf->nc_netid, hostname, servname); 868*7c478bd9Sstevel@tonic-gate if (debugging) { 869*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\tnetdir_getbyname for %s, " 870*7c478bd9Sstevel@tonic-gate "service \"%s\" failed\n", hostname, servname); 871*7c478bd9Sstevel@tonic-gate } 872*7c478bd9Sstevel@tonic-gate return (B_FALSE); 873*7c478bd9Sstevel@tonic-gate } 874*7c478bd9Sstevel@tonic-gate netdir_free(na, ND_ADDRLIST); 875*7c478bd9Sstevel@tonic-gate 876*7c478bd9Sstevel@tonic-gate if (debugging) { 877*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\tnetdir_getbyname for %s, service " 878*7c478bd9Sstevel@tonic-gate "service \"%s\" succeeded\n", hostname, servname); 879*7c478bd9Sstevel@tonic-gate } 880*7c478bd9Sstevel@tonic-gate return (B_TRUE); 881*7c478bd9Sstevel@tonic-gate } 882*7c478bd9Sstevel@tonic-gate 883*7c478bd9Sstevel@tonic-gate #define DEFRPCBIND "/etc/default/rpcbind" 884*7c478bd9Sstevel@tonic-gate 885*7c478bd9Sstevel@tonic-gate /* Maximum outstanding syslog requests */ 886*7c478bd9Sstevel@tonic-gate #define MAXLOG 100 887*7c478bd9Sstevel@tonic-gate /* Maximum length: the messages generated are fairly short; no hostnames. */ 888*7c478bd9Sstevel@tonic-gate #define MAXMSG 128 889*7c478bd9Sstevel@tonic-gate 890*7c478bd9Sstevel@tonic-gate typedef struct logmsg { 891*7c478bd9Sstevel@tonic-gate struct logmsg *log_next; 892*7c478bd9Sstevel@tonic-gate int log_pri; 893*7c478bd9Sstevel@tonic-gate char log_msg[MAXMSG]; 894*7c478bd9Sstevel@tonic-gate } logmsg; 895*7c478bd9Sstevel@tonic-gate 896*7c478bd9Sstevel@tonic-gate static logmsg *loghead = NULL; 897*7c478bd9Sstevel@tonic-gate static logmsg **logtailp = &loghead; 898*7c478bd9Sstevel@tonic-gate static mutex_t logmutex = DEFAULTMUTEX; 899*7c478bd9Sstevel@tonic-gate static cond_t logcond = DEFAULTCV; 900*7c478bd9Sstevel@tonic-gate static int logcount = 0; 901*7c478bd9Sstevel@tonic-gate 902*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 903*7c478bd9Sstevel@tonic-gate static void * 904*7c478bd9Sstevel@tonic-gate logthread(void *arg) 905*7c478bd9Sstevel@tonic-gate { 906*7c478bd9Sstevel@tonic-gate while (1) { 907*7c478bd9Sstevel@tonic-gate logmsg *msg; 908*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&logmutex); 909*7c478bd9Sstevel@tonic-gate while ((msg = loghead) == NULL) 910*7c478bd9Sstevel@tonic-gate (void) cond_wait(&logcond, &logmutex); 911*7c478bd9Sstevel@tonic-gate 912*7c478bd9Sstevel@tonic-gate loghead = msg->log_next; 913*7c478bd9Sstevel@tonic-gate logcount--; 914*7c478bd9Sstevel@tonic-gate if (loghead == NULL) { 915*7c478bd9Sstevel@tonic-gate logtailp = &loghead; 916*7c478bd9Sstevel@tonic-gate logcount = 0; 917*7c478bd9Sstevel@tonic-gate } 918*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&logmutex); 919*7c478bd9Sstevel@tonic-gate syslog(msg->log_pri, "%s", msg->log_msg); 920*7c478bd9Sstevel@tonic-gate free(msg); 921*7c478bd9Sstevel@tonic-gate } 922*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 923*7c478bd9Sstevel@tonic-gate } 924*7c478bd9Sstevel@tonic-gate 925*7c478bd9Sstevel@tonic-gate /* 926*7c478bd9Sstevel@tonic-gate * Initialize: read the configuration parameters from the default file. 927*7c478bd9Sstevel@tonic-gate */ 928*7c478bd9Sstevel@tonic-gate static void 929*7c478bd9Sstevel@tonic-gate rpcb_check_init(void) 930*7c478bd9Sstevel@tonic-gate { 931*7c478bd9Sstevel@tonic-gate thread_t tid; 932*7c478bd9Sstevel@tonic-gate scf_simple_prop_t *prop; 933*7c478bd9Sstevel@tonic-gate uint8_t *bool; 934*7c478bd9Sstevel@tonic-gate 935*7c478bd9Sstevel@tonic-gate if ((prop = scf_simple_prop_get(NULL, NULL, "config", 936*7c478bd9Sstevel@tonic-gate "enable_tcpwrappers")) != NULL) { 937*7c478bd9Sstevel@tonic-gate 938*7c478bd9Sstevel@tonic-gate if ((bool = scf_simple_prop_next_boolean(prop)) != NULL) { 939*7c478bd9Sstevel@tonic-gate wrap_enabled = (*bool == 0) ? B_FALSE : B_TRUE; 940*7c478bd9Sstevel@tonic-gate } else { 941*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, "enable_tcpwrappers no value %s", 942*7c478bd9Sstevel@tonic-gate scf_strerror(scf_error())); 943*7c478bd9Sstevel@tonic-gate } 944*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(prop); 945*7c478bd9Sstevel@tonic-gate } else { 946*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, "unable to get enable_tcpwrappers %s", 947*7c478bd9Sstevel@tonic-gate scf_strerror(scf_error())); 948*7c478bd9Sstevel@tonic-gate } 949*7c478bd9Sstevel@tonic-gate if ((prop = scf_simple_prop_get(NULL, NULL, "config", 950*7c478bd9Sstevel@tonic-gate "verbose_logging")) != NULL) { 951*7c478bd9Sstevel@tonic-gate 952*7c478bd9Sstevel@tonic-gate if ((bool = scf_simple_prop_next_boolean(prop)) != NULL) { 953*7c478bd9Sstevel@tonic-gate verboselog = (*bool == 0) ? B_FALSE : B_TRUE; 954*7c478bd9Sstevel@tonic-gate } else { 955*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, "verboselog no value %s", 956*7c478bd9Sstevel@tonic-gate scf_strerror(scf_error())); 957*7c478bd9Sstevel@tonic-gate } 958*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(prop); 959*7c478bd9Sstevel@tonic-gate } else { 960*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, "unable to get verbose_logging %s", 961*7c478bd9Sstevel@tonic-gate scf_strerror(scf_error())); 962*7c478bd9Sstevel@tonic-gate } 963*7c478bd9Sstevel@tonic-gate if ((prop = scf_simple_prop_get(NULL, NULL, "config", 964*7c478bd9Sstevel@tonic-gate "allow_indirect")) != NULL) { 965*7c478bd9Sstevel@tonic-gate 966*7c478bd9Sstevel@tonic-gate if ((bool = scf_simple_prop_next_boolean(prop)) != NULL) { 967*7c478bd9Sstevel@tonic-gate allow_indirect = (*bool == 0) ? B_FALSE : B_TRUE; 968*7c478bd9Sstevel@tonic-gate } else { 969*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, "allow_indirect no value %s", 970*7c478bd9Sstevel@tonic-gate scf_strerror(scf_error())); 971*7c478bd9Sstevel@tonic-gate } 972*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(prop); 973*7c478bd9Sstevel@tonic-gate } else { 974*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, "unable to get allow_indirect %s", 975*7c478bd9Sstevel@tonic-gate scf_strerror(scf_error())); 976*7c478bd9Sstevel@tonic-gate } 977*7c478bd9Sstevel@tonic-gate 978*7c478bd9Sstevel@tonic-gate if (wrap_enabled) 979*7c478bd9Sstevel@tonic-gate (void) thr_create(NULL, 0, logthread, NULL, THR_DETACHED, &tid); 980*7c478bd9Sstevel@tonic-gate } 981*7c478bd9Sstevel@tonic-gate 982*7c478bd9Sstevel@tonic-gate /* 983*7c478bd9Sstevel@tonic-gate * qsyslog() - queue a request for syslog(); if syslog blocks, the other 984*7c478bd9Sstevel@tonic-gate * thread blocks; we make sure we don't run out of memory by allowing 985*7c478bd9Sstevel@tonic-gate * only a limited number of outstandig syslog() requests. 986*7c478bd9Sstevel@tonic-gate */ 987*7c478bd9Sstevel@tonic-gate void 988*7c478bd9Sstevel@tonic-gate qsyslog(int pri, const char *fmt, ...) 989*7c478bd9Sstevel@tonic-gate { 990*7c478bd9Sstevel@tonic-gate logmsg *msg = malloc(sizeof (*msg)); 991*7c478bd9Sstevel@tonic-gate int oldcount; 992*7c478bd9Sstevel@tonic-gate va_list ap; 993*7c478bd9Sstevel@tonic-gate 994*7c478bd9Sstevel@tonic-gate if (msg == NULL) 995*7c478bd9Sstevel@tonic-gate return; 996*7c478bd9Sstevel@tonic-gate 997*7c478bd9Sstevel@tonic-gate msg->log_pri = pri; 998*7c478bd9Sstevel@tonic-gate 999*7c478bd9Sstevel@tonic-gate va_start(ap, fmt); 1000*7c478bd9Sstevel@tonic-gate (void) vsnprintf(msg->log_msg, sizeof (msg->log_msg), fmt, ap); 1001*7c478bd9Sstevel@tonic-gate va_end(ap); 1002*7c478bd9Sstevel@tonic-gate 1003*7c478bd9Sstevel@tonic-gate msg->log_next = NULL; 1004*7c478bd9Sstevel@tonic-gate 1005*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&logmutex); 1006*7c478bd9Sstevel@tonic-gate oldcount = logcount; 1007*7c478bd9Sstevel@tonic-gate if (logcount < MAXLOG) { 1008*7c478bd9Sstevel@tonic-gate logcount++; 1009*7c478bd9Sstevel@tonic-gate *logtailp = msg; 1010*7c478bd9Sstevel@tonic-gate logtailp = &msg->log_next; 1011*7c478bd9Sstevel@tonic-gate } else { 1012*7c478bd9Sstevel@tonic-gate free(msg); 1013*7c478bd9Sstevel@tonic-gate } 1014*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&logmutex); 1015*7c478bd9Sstevel@tonic-gate if (oldcount == 0) 1016*7c478bd9Sstevel@tonic-gate (void) cond_signal(&logcond); 1017*7c478bd9Sstevel@tonic-gate } 1018