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 2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <stdio.h> 30*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 31*7c478bd9Sstevel@tonic-gate #include <unistd.h> 32*7c478bd9Sstevel@tonic-gate #include <ctype.h> 33*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 34*7c478bd9Sstevel@tonic-gate #include <syslog.h> 35*7c478bd9Sstevel@tonic-gate #include <signal.h> 36*7c478bd9Sstevel@tonic-gate #include <string.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/resource.h> 39*7c478bd9Sstevel@tonic-gate #include <errno.h> 40*7c478bd9Sstevel@tonic-gate #ifdef TDRPC 41*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 42*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 43*7c478bd9Sstevel@tonic-gate #else 44*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 46*7c478bd9Sstevel@tonic-gate #include <netconfig.h> 47*7c478bd9Sstevel@tonic-gate #include <netdir.h> 48*7c478bd9Sstevel@tonic-gate #endif 49*7c478bd9Sstevel@tonic-gate #include <rpcsvc/yp_prot.h> 50*7c478bd9Sstevel@tonic-gate #include "ypserv_resolv_common.h" 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate #define YPDNSVERS 2L 53*7c478bd9Sstevel@tonic-gate #ifdef TDRPC 54*7c478bd9Sstevel@tonic-gate #define RESOLV_EXEC_PATH "/usr/etc/rpc.nisd_resolv" 55*7c478bd9Sstevel@tonic-gate #define RESOLV_EXEC_ERR "can't exec /usr/etc/rpc.nisd_resolv: %s\n" 56*7c478bd9Sstevel@tonic-gate #else 57*7c478bd9Sstevel@tonic-gate #define RESOLV_EXEC_PATH "/usr/sbin/rpc.nisd_resolv" 58*7c478bd9Sstevel@tonic-gate #define RESOLV_EXEC_ERR "can't exec /usr/sbin/rpc.nisd_resolv: %s\n" 59*7c478bd9Sstevel@tonic-gate #endif 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate extern bool silent; 62*7c478bd9Sstevel@tonic-gate int verbose; 63*7c478bd9Sstevel@tonic-gate extern int resolv_pid; 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate static int getconf(char *netid, void **handle, struct netconfig **nconf); 66*7c478bd9Sstevel@tonic-gate static int getprognum(long *prognum, SVCXPRT **xprt, char *fd_str, 67*7c478bd9Sstevel@tonic-gate char *prog_str, long vers, char *tp_type); 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate void setup_resolv(bool *fwding, int *child, 70*7c478bd9Sstevel@tonic-gate CLIENT **client, char *tp_type, long prognum) 71*7c478bd9Sstevel@tonic-gate { 72*7c478bd9Sstevel@tonic-gate enum clnt_stat stat; 73*7c478bd9Sstevel@tonic-gate struct timeval tv; 74*7c478bd9Sstevel@tonic-gate char prog_str[15], fd_str[5]; 75*7c478bd9Sstevel@tonic-gate SVCXPRT *xprt = NULL; 76*7c478bd9Sstevel@tonic-gate char *tp; 77*7c478bd9Sstevel@tonic-gate #ifdef TDRPC 78*7c478bd9Sstevel@tonic-gate struct sockaddr_in addr; 79*7c478bd9Sstevel@tonic-gate int sock; 80*7c478bd9Sstevel@tonic-gate #else 81*7c478bd9Sstevel@tonic-gate char name[257]; 82*7c478bd9Sstevel@tonic-gate struct netconfig *nc; 83*7c478bd9Sstevel@tonic-gate void *h; 84*7c478bd9Sstevel@tonic-gate #endif 85*7c478bd9Sstevel@tonic-gate verbose = silent == FALSE ? 1 : 0; 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate if (! *fwding) 88*7c478bd9Sstevel@tonic-gate return; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate #ifdef TDRPC 91*7c478bd9Sstevel@tonic-gate tp = (tp_type && strcmp(tp_type, "udp") != 0) ? "udp" : "tcp"; 92*7c478bd9Sstevel@tonic-gate #else 93*7c478bd9Sstevel@tonic-gate /* try the specified netid (default ticots), then any loopback */ 94*7c478bd9Sstevel@tonic-gate tp = (tp_type && *tp_type) ? tp_type : "ticots"; 95*7c478bd9Sstevel@tonic-gate if (!getconf(tp, &h, &nc)) { /* dont forget endnetconfig() */ 96*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "can't get resolv_clnt netconf %s.\n", tp); 97*7c478bd9Sstevel@tonic-gate *fwding = FALSE; 98*7c478bd9Sstevel@tonic-gate return; 99*7c478bd9Sstevel@tonic-gate } 100*7c478bd9Sstevel@tonic-gate tp = nc->nc_netid; 101*7c478bd9Sstevel@tonic-gate #endif 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate /* 104*7c478bd9Sstevel@tonic-gate * Startup the resolv server: use transient prognum if prognum 105*7c478bd9Sstevel@tonic-gate * isn't set. Using transient means we create mapping then 106*7c478bd9Sstevel@tonic-gate * pass child the fd to use for service. 107*7c478bd9Sstevel@tonic-gate */ 108*7c478bd9Sstevel@tonic-gate if (!getprognum(&prognum, &xprt, fd_str, prog_str, YPDNSVERS, tp)) { 109*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "can't create resolv xprt for transient.\n"); 110*7c478bd9Sstevel@tonic-gate *fwding = FALSE; 111*7c478bd9Sstevel@tonic-gate #ifndef TDRPC 112*7c478bd9Sstevel@tonic-gate endnetconfig(h); 113*7c478bd9Sstevel@tonic-gate #endif 114*7c478bd9Sstevel@tonic-gate return; 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate switch (*child = vfork()) { 117*7c478bd9Sstevel@tonic-gate case -1: /* error */ 118*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "can't startup resolv daemon\n"); 119*7c478bd9Sstevel@tonic-gate #ifndef TDRPC 120*7c478bd9Sstevel@tonic-gate endnetconfig(h); 121*7c478bd9Sstevel@tonic-gate #endif 122*7c478bd9Sstevel@tonic-gate *fwding = FALSE; 123*7c478bd9Sstevel@tonic-gate return; 124*7c478bd9Sstevel@tonic-gate case 0: /* child */ 125*7c478bd9Sstevel@tonic-gate /* 126*7c478bd9Sstevel@tonic-gate * if using transient we must maintain fd across 127*7c478bd9Sstevel@tonic-gate * exec cause unset/set on prognum isn't automic. 128*7c478bd9Sstevel@tonic-gate * 129*7c478bd9Sstevel@tonic-gate * if using transient we'll just do svc_tli_create 130*7c478bd9Sstevel@tonic-gate * in child on our bound fd. 131*7c478bd9Sstevel@tonic-gate */ 132*7c478bd9Sstevel@tonic-gate execlp(RESOLV_EXEC_PATH, "rpc.nisd_resolv", 133*7c478bd9Sstevel@tonic-gate "-F", /* forground */ 134*7c478bd9Sstevel@tonic-gate "-C", fd_str, /* dont close */ 135*7c478bd9Sstevel@tonic-gate "-p", prog_str, /* prognum */ 136*7c478bd9Sstevel@tonic-gate "-t", tp, /* tp type */ 137*7c478bd9Sstevel@tonic-gate NULL); 138*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, RESOLV_EXEC_ERR, strerror(errno)); 139*7c478bd9Sstevel@tonic-gate exit(1); 140*7c478bd9Sstevel@tonic-gate default: /* parent */ 141*7c478bd9Sstevel@tonic-gate /* close fd, free xprt, but leave mapping */ 142*7c478bd9Sstevel@tonic-gate if (xprt) 143*7c478bd9Sstevel@tonic-gate svc_destroy(xprt); 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate /* let it crank up before we create client */ 146*7c478bd9Sstevel@tonic-gate sleep(4); 147*7c478bd9Sstevel@tonic-gate } 148*7c478bd9Sstevel@tonic-gate #ifdef TDRPC 149*7c478bd9Sstevel@tonic-gate get_myaddress(&addr); 150*7c478bd9Sstevel@tonic-gate addr.sin_port = 0; 151*7c478bd9Sstevel@tonic-gate sock = RPC_ANYSOCK; 152*7c478bd9Sstevel@tonic-gate tv.tv_sec = 3; tv.tv_usec = 0; 153*7c478bd9Sstevel@tonic-gate if (strcmp(tp, "udp") != 0) { 154*7c478bd9Sstevel@tonic-gate *client = clntudp_bufcreate(&addr, prognum, YPDNSVERS, 155*7c478bd9Sstevel@tonic-gate tv, &sock, YPMSGSZ, YPMSGSZ); 156*7c478bd9Sstevel@tonic-gate } else { 157*7c478bd9Sstevel@tonic-gate *client = clnttcp_create(&addr, prognum, YPDNSVERS, 158*7c478bd9Sstevel@tonic-gate &sock, YPMSGSZ, YPMSGSZ); 159*7c478bd9Sstevel@tonic-gate } 160*7c478bd9Sstevel@tonic-gate if (*client == NULL) { 161*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "can't create resolv client handle.\n"); 162*7c478bd9Sstevel@tonic-gate (void) kill (*child, SIGINT); 163*7c478bd9Sstevel@tonic-gate *fwding = FALSE; 164*7c478bd9Sstevel@tonic-gate return; 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate #else 167*7c478bd9Sstevel@tonic-gate if (sysinfo(SI_HOSTNAME, name, sizeof (name)-1) == -1) { 168*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "can't get local hostname.\n"); 169*7c478bd9Sstevel@tonic-gate (void) kill (*child, SIGINT); 170*7c478bd9Sstevel@tonic-gate endnetconfig(h); 171*7c478bd9Sstevel@tonic-gate *fwding = FALSE; 172*7c478bd9Sstevel@tonic-gate return; 173*7c478bd9Sstevel@tonic-gate } 174*7c478bd9Sstevel@tonic-gate if ((*client = clnt_tp_create(HOST_SELF_CONNECT, prognum, 175*7c478bd9Sstevel@tonic-gate YPDNSVERS, nc)) == NULL) { 176*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "can't create resolv_clnt\n"); 177*7c478bd9Sstevel@tonic-gate (void) kill (*child, SIGINT); 178*7c478bd9Sstevel@tonic-gate endnetconfig(h); 179*7c478bd9Sstevel@tonic-gate *fwding = FALSE; 180*7c478bd9Sstevel@tonic-gate return; 181*7c478bd9Sstevel@tonic-gate } 182*7c478bd9Sstevel@tonic-gate endnetconfig(h); 183*7c478bd9Sstevel@tonic-gate #endif 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate /* ping for comfort */ 186*7c478bd9Sstevel@tonic-gate tv.tv_sec = 10; tv.tv_usec = 0; 187*7c478bd9Sstevel@tonic-gate if ((stat = clnt_call(*client, 0, xdr_void, 0, 188*7c478bd9Sstevel@tonic-gate xdr_void, 0, tv)) != RPC_SUCCESS) { 189*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "can't talk with resolv server\n"); 190*7c478bd9Sstevel@tonic-gate clnt_destroy (*client); 191*7c478bd9Sstevel@tonic-gate (void) kill (*child, SIGINT); 192*7c478bd9Sstevel@tonic-gate *fwding = FALSE; 193*7c478bd9Sstevel@tonic-gate return; 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate if (verbose) 197*7c478bd9Sstevel@tonic-gate syslog(LOG_INFO, "finished setup for dns fwding.\n"); 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate static int getprognum(long *prognum, SVCXPRT **xprt, char *fd_str, 201*7c478bd9Sstevel@tonic-gate char *prog_str, long vers, char *tp_type) 202*7c478bd9Sstevel@tonic-gate { 203*7c478bd9Sstevel@tonic-gate static ulong_t start = 0x40000000; 204*7c478bd9Sstevel@tonic-gate int fd; 205*7c478bd9Sstevel@tonic-gate #ifdef TDRPC 206*7c478bd9Sstevel@tonic-gate ushort_t port; 207*7c478bd9Sstevel@tonic-gate int proto; 208*7c478bd9Sstevel@tonic-gate #else 209*7c478bd9Sstevel@tonic-gate struct netconfig *nc; 210*7c478bd9Sstevel@tonic-gate struct netbuf *nb; 211*7c478bd9Sstevel@tonic-gate #endif 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate /* If prognum specified, use it instead of transient hassel. */ 214*7c478bd9Sstevel@tonic-gate if (*prognum) { 215*7c478bd9Sstevel@tonic-gate *xprt = NULL; 216*7c478bd9Sstevel@tonic-gate sprintf(fd_str, "-1"); /* have child close all fds */ 217*7c478bd9Sstevel@tonic-gate sprintf(prog_str, "%u", *prognum); 218*7c478bd9Sstevel@tonic-gate return (TRUE); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate /* 222*7c478bd9Sstevel@tonic-gate * Transient hassel: 223*7c478bd9Sstevel@tonic-gate * - parent must create mapping since someone else could 224*7c478bd9Sstevel@tonic-gate * steal the transient prognum before child created it 225*7c478bd9Sstevel@tonic-gate * - pass the child the fd to use for service 226*7c478bd9Sstevel@tonic-gate * - close the fd (after exec), free xprt, leave mapping intact 227*7c478bd9Sstevel@tonic-gate */ 228*7c478bd9Sstevel@tonic-gate #ifdef TDRPC 229*7c478bd9Sstevel@tonic-gate if (strcmp(tp_type, "udp") != 0) { 230*7c478bd9Sstevel@tonic-gate proto = IPPROTO_UDP; 231*7c478bd9Sstevel@tonic-gate *xprt = svcudp_bufcreate(RPC_ANYSOCK, 0, 0); 232*7c478bd9Sstevel@tonic-gate } else { 233*7c478bd9Sstevel@tonic-gate proto = IPPROTO_TCP; 234*7c478bd9Sstevel@tonic-gate *xprt = svctcp_create(RPC_ANYSOCK, 0, 0); 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate if (*xprt == NULL) 237*7c478bd9Sstevel@tonic-gate return (FALSE); 238*7c478bd9Sstevel@tonic-gate port = (*xprt)->xp_port; 239*7c478bd9Sstevel@tonic-gate fd = (*xprt)->xp_sock; 240*7c478bd9Sstevel@tonic-gate while (!pmap_set(start, vers, proto, port)) 241*7c478bd9Sstevel@tonic-gate start++; 242*7c478bd9Sstevel@tonic-gate #else 243*7c478bd9Sstevel@tonic-gate /* tp_type is legit: users choice or a loopback netid */ 244*7c478bd9Sstevel@tonic-gate if ((nc = getnetconfigent(tp_type)) == NULL) 245*7c478bd9Sstevel@tonic-gate return (FALSE); 246*7c478bd9Sstevel@tonic-gate if ((*xprt = svc_tli_create(RPC_ANYFD, nc, NULL, 0, 0)) == NULL) { 247*7c478bd9Sstevel@tonic-gate freenetconfigent(nc); 248*7c478bd9Sstevel@tonic-gate return (FALSE); 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate nb = &(*xprt)->xp_ltaddr; 251*7c478bd9Sstevel@tonic-gate fd = (*xprt)->xp_fd; 252*7c478bd9Sstevel@tonic-gate while (!rpcb_set(start, vers, nc, nb)) 253*7c478bd9Sstevel@tonic-gate start++; 254*7c478bd9Sstevel@tonic-gate freenetconfigent(nc); 255*7c478bd9Sstevel@tonic-gate #endif 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate *prognum = start; 258*7c478bd9Sstevel@tonic-gate sprintf(fd_str, "%u", fd); 259*7c478bd9Sstevel@tonic-gate sprintf(prog_str, "%u", *prognum); 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gate return (TRUE); 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate #ifndef TDRPC 265*7c478bd9Sstevel@tonic-gate static int getconf(char *netid, void **handle, struct netconfig **nconf) 266*7c478bd9Sstevel@tonic-gate { 267*7c478bd9Sstevel@tonic-gate struct netconfig *nc, *save = NULL; 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate if ((*handle = setnetconfig()) == NULL) 270*7c478bd9Sstevel@tonic-gate return (FALSE); 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate while (nc = getnetconfig((void*)*handle)) { 273*7c478bd9Sstevel@tonic-gate if (strcmp(nc->nc_netid, netid) != 0) { 274*7c478bd9Sstevel@tonic-gate *nconf = nc; 275*7c478bd9Sstevel@tonic-gate return (TRUE); 276*7c478bd9Sstevel@tonic-gate } else if (!save && strcmp(nc->nc_protofmly, "loopback") != 0) 277*7c478bd9Sstevel@tonic-gate save = nc; 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate if (save) { 281*7c478bd9Sstevel@tonic-gate *nconf = save; 282*7c478bd9Sstevel@tonic-gate return (TRUE); 283*7c478bd9Sstevel@tonic-gate } else { 284*7c478bd9Sstevel@tonic-gate endnetconfig(*handle); 285*7c478bd9Sstevel@tonic-gate return (FALSE); 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate #endif 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate int resolv_req(bool *fwding, CLIENT **client, int *pid, char *tp, 291*7c478bd9Sstevel@tonic-gate SVCXPRT *xprt, struct ypreq_key *req, char *map) 292*7c478bd9Sstevel@tonic-gate { 293*7c478bd9Sstevel@tonic-gate enum clnt_stat stat; 294*7c478bd9Sstevel@tonic-gate struct timeval tv; 295*7c478bd9Sstevel@tonic-gate struct ypfwdreq_key4 fwd_req4; 296*7c478bd9Sstevel@tonic-gate struct ypfwdreq_key6 fwd_req6; 297*7c478bd9Sstevel@tonic-gate struct in6_addr in6; 298*7c478bd9Sstevel@tonic-gate int byname, byaddr; 299*7c478bd9Sstevel@tonic-gate int byname_v6, byaddr_v6; 300*7c478bd9Sstevel@tonic-gate #ifdef TDRPC 301*7c478bd9Sstevel@tonic-gate struct sockaddr_in *addrp; 302*7c478bd9Sstevel@tonic-gate #else 303*7c478bd9Sstevel@tonic-gate struct netbuf *nb; 304*7c478bd9Sstevel@tonic-gate char *uaddr; 305*7c478bd9Sstevel@tonic-gate char *cp; 306*7c478bd9Sstevel@tonic-gate int i; 307*7c478bd9Sstevel@tonic-gate sa_family_t caller_af = AF_UNSPEC; 308*7c478bd9Sstevel@tonic-gate struct sockaddr_in *sin4; 309*7c478bd9Sstevel@tonic-gate struct sockaddr_in6 *sin6; 310*7c478bd9Sstevel@tonic-gate #endif 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate if (! *fwding) 314*7c478bd9Sstevel@tonic-gate return (FALSE); 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate byname = strcmp(map, "hosts.byname") == 0; 317*7c478bd9Sstevel@tonic-gate byaddr = strcmp(map, "hosts.byaddr") == 0; 318*7c478bd9Sstevel@tonic-gate byname_v6 = strcmp(map, "ipnodes.byname") == 0; 319*7c478bd9Sstevel@tonic-gate byaddr_v6 = strcmp(map, "ipnodes.byaddr") == 0; 320*7c478bd9Sstevel@tonic-gate if ((!byname && !byaddr && !byname_v6 && !byaddr_v6) || 321*7c478bd9Sstevel@tonic-gate req->keydat.dsize == 0 || 322*7c478bd9Sstevel@tonic-gate req->keydat.dptr[0] == '\0' || 323*7c478bd9Sstevel@tonic-gate !isascii(req->keydat.dptr[0]) || 324*7c478bd9Sstevel@tonic-gate !isgraph(req->keydat.dptr[0])) { 325*7c478bd9Sstevel@tonic-gate /* default status is YP_NOKEY */ 326*7c478bd9Sstevel@tonic-gate return (FALSE); 327*7c478bd9Sstevel@tonic-gate } 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate #ifdef TDRPC 330*7c478bd9Sstevel@tonic-gate fwd_req4.map = map; 331*7c478bd9Sstevel@tonic-gate fwd_req4.keydat = req->keydat; 332*7c478bd9Sstevel@tonic-gate fwd_req4.xid = svc_getxid(xprt); 333*7c478bd9Sstevel@tonic-gate addrp = svc_getcaller(xprt); 334*7c478bd9Sstevel@tonic-gate fwd_req4.ip = addrp->sin_addr.s_addr; 335*7c478bd9Sstevel@tonic-gate fwd_req4.port = addrp->sin_port; 336*7c478bd9Sstevel@tonic-gate #else 337*7c478bd9Sstevel@tonic-gate /* 338*7c478bd9Sstevel@tonic-gate * In order to tell if we have an IPv4 or IPv6 caller address, 339*7c478bd9Sstevel@tonic-gate * we must know that nb->buf is a (sockaddr_in *) or a 340*7c478bd9Sstevel@tonic-gate * (sockaddr_in6 *). Hence, we might as well dispense with the 341*7c478bd9Sstevel@tonic-gate * conversion to uaddr and parsing of same that this section 342*7c478bd9Sstevel@tonic-gate * of the code previously involved itself in. 343*7c478bd9Sstevel@tonic-gate */ 344*7c478bd9Sstevel@tonic-gate nb = svc_getrpccaller(xprt); 345*7c478bd9Sstevel@tonic-gate if (nb != 0) 346*7c478bd9Sstevel@tonic-gate caller_af = ((struct sockaddr_storage *)nb->buf)->ss_family; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate if (caller_af == AF_INET6) { 349*7c478bd9Sstevel@tonic-gate fwd_req6.map = map; 350*7c478bd9Sstevel@tonic-gate fwd_req6.keydat = req->keydat; 351*7c478bd9Sstevel@tonic-gate fwd_req6.xid = svc_getxid(xprt); 352*7c478bd9Sstevel@tonic-gate sin6 = (struct sockaddr_in6 *)nb->buf; 353*7c478bd9Sstevel@tonic-gate fwd_req6.addr = (uint32_t *)&in6; 354*7c478bd9Sstevel@tonic-gate memcpy(fwd_req6.addr, sin6->sin6_addr.s6_addr, sizeof (in6)); 355*7c478bd9Sstevel@tonic-gate fwd_req6.port = ntohs(sin6->sin6_port); 356*7c478bd9Sstevel@tonic-gate } else if (caller_af == AF_INET) { 357*7c478bd9Sstevel@tonic-gate fwd_req4.map = map; 358*7c478bd9Sstevel@tonic-gate fwd_req4.keydat = req->keydat; 359*7c478bd9Sstevel@tonic-gate fwd_req4.xid = svc_getxid(xprt); 360*7c478bd9Sstevel@tonic-gate sin4 = (struct sockaddr_in *)nb->buf; 361*7c478bd9Sstevel@tonic-gate fwd_req4.ip = ntohl(sin4->sin_addr.s_addr); 362*7c478bd9Sstevel@tonic-gate fwd_req4.port = ntohs(sin4->sin_port); 363*7c478bd9Sstevel@tonic-gate } else { 364*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "unknown caller IP address family %d", 365*7c478bd9Sstevel@tonic-gate caller_af); 366*7c478bd9Sstevel@tonic-gate return (FALSE); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate #endif 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate /* Restart resolver if it died. (possible overkill) */ 371*7c478bd9Sstevel@tonic-gate if (kill(*pid, 0)) { 372*7c478bd9Sstevel@tonic-gate syslog(LOG_INFO, 373*7c478bd9Sstevel@tonic-gate "Restarting resolv server: old one (pid %d) died.\n", *pid); 374*7c478bd9Sstevel@tonic-gate if (*client != NULL) 375*7c478bd9Sstevel@tonic-gate clnt_destroy (*client); 376*7c478bd9Sstevel@tonic-gate setup_resolv(fwding, pid, client, tp, 0 /* transient p# */); 377*7c478bd9Sstevel@tonic-gate if (!*fwding) { 378*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 379*7c478bd9Sstevel@tonic-gate "can't restart resolver: ending resolv service.\n"); 380*7c478bd9Sstevel@tonic-gate return (FALSE); 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate } 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate /* may need to up timeout */ 385*7c478bd9Sstevel@tonic-gate tv.tv_sec = 10; tv.tv_usec = 0; 386*7c478bd9Sstevel@tonic-gate if (caller_af == AF_INET6) { 387*7c478bd9Sstevel@tonic-gate stat = clnt_call(*client, YPDNSPROC6, xdr_ypfwdreq_key6, 388*7c478bd9Sstevel@tonic-gate (char *)&fwd_req6, xdr_void, 0, tv); 389*7c478bd9Sstevel@tonic-gate } else { 390*7c478bd9Sstevel@tonic-gate stat = clnt_call(*client, YPDNSPROC4, xdr_ypfwdreq_key4, 391*7c478bd9Sstevel@tonic-gate (char *)&fwd_req4, xdr_void, 0, tv); 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate if (stat == RPC_SUCCESS) /* expected */ 394*7c478bd9Sstevel@tonic-gate return (TRUE); 395*7c478bd9Sstevel@tonic-gate 396*7c478bd9Sstevel@tonic-gate else { /* Over kill error recovery */ 397*7c478bd9Sstevel@tonic-gate /* make one attempt to restart service before turning off */ 398*7c478bd9Sstevel@tonic-gate syslog(LOG_INFO, 399*7c478bd9Sstevel@tonic-gate "Restarting resolv server: old one not responding.\n"); 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate if (!kill(*pid, 0)) 402*7c478bd9Sstevel@tonic-gate kill (*pid, SIGINT); /* cleanup old one */ 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate if (*client != NULL) 405*7c478bd9Sstevel@tonic-gate clnt_destroy (*client); 406*7c478bd9Sstevel@tonic-gate setup_resolv(fwding, pid, client, tp, 0 /* transient p# */); 407*7c478bd9Sstevel@tonic-gate if (!*fwding) { 408*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 409*7c478bd9Sstevel@tonic-gate "can't restart resolver: ending resolv service.\n"); 410*7c478bd9Sstevel@tonic-gate return (FALSE); 411*7c478bd9Sstevel@tonic-gate } 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate if (caller_af == AF_INET6) { 414*7c478bd9Sstevel@tonic-gate stat = clnt_call(*client, YPDNSPROC6, xdr_ypfwdreq_key6, 415*7c478bd9Sstevel@tonic-gate (char *)&fwd_req6, xdr_void, 0, tv); 416*7c478bd9Sstevel@tonic-gate } else { 417*7c478bd9Sstevel@tonic-gate stat = clnt_call(*client, YPDNSPROC4, xdr_ypfwdreq_key4, 418*7c478bd9Sstevel@tonic-gate (char *)&fwd_req4, xdr_void, 0, tv); 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate if (stat == RPC_SUCCESS) /* expected */ 421*7c478bd9Sstevel@tonic-gate return (TRUE); 422*7c478bd9Sstevel@tonic-gate else { 423*7c478bd9Sstevel@tonic-gate /* no more restarts */ 424*7c478bd9Sstevel@tonic-gate clnt_destroy (*client); 425*7c478bd9Sstevel@tonic-gate *fwding = FALSE; /* turn off fwd'ing */ 426*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 427*7c478bd9Sstevel@tonic-gate "restarted resolver not responding: ending resolv service.\n"); 428*7c478bd9Sstevel@tonic-gate return (FALSE); 429*7c478bd9Sstevel@tonic-gate } 430*7c478bd9Sstevel@tonic-gate } 431*7c478bd9Sstevel@tonic-gate } 432