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 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate /* 31*7c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 4.3 BSD 32*7c478bd9Sstevel@tonic-gate * under license from the Regents of the University of California. 33*7c478bd9Sstevel@tonic-gate */ 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate /* 38*7c478bd9Sstevel@tonic-gate * 39*7c478bd9Sstevel@tonic-gate * This contains YP server code which supplies the set of functions 40*7c478bd9Sstevel@tonic-gate * requested using rpc. The top level functions in this module 41*7c478bd9Sstevel@tonic-gate * are those which have symbols of the form YPPROC_xxxx defined in 42*7c478bd9Sstevel@tonic-gate * yp_prot.h, and symbols of the form YPOLDPROC_xxxx defined in ypsym.h. 43*7c478bd9Sstevel@tonic-gate * The latter exist to provide compatibility to the old version of the yp 44*7c478bd9Sstevel@tonic-gate * protocol/server, and may emulate the behavior of the previous software 45*7c478bd9Sstevel@tonic-gate * by invoking some other program. 46*7c478bd9Sstevel@tonic-gate * 47*7c478bd9Sstevel@tonic-gate * This module also contains functions which are used by (and only by) the 48*7c478bd9Sstevel@tonic-gate * top-level functions here. 49*7c478bd9Sstevel@tonic-gate */ 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 52*7c478bd9Sstevel@tonic-gate #include <sys/socket.h> 53*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 54*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 55*7c478bd9Sstevel@tonic-gate #include <dirent.h> 56*7c478bd9Sstevel@tonic-gate #include <limits.h> 57*7c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 58*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 59*7c478bd9Sstevel@tonic-gate #include <string.h> 60*7c478bd9Sstevel@tonic-gate #include <malloc.h> 61*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 62*7c478bd9Sstevel@tonic-gate #include <unistd.h> 63*7c478bd9Sstevel@tonic-gate #include <stdio.h> 64*7c478bd9Sstevel@tonic-gate #include "ypsym.h" 65*7c478bd9Sstevel@tonic-gate #include "ypdefs.h" 66*7c478bd9Sstevel@tonic-gate #include <ctype.h> 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate /* Use shim version of DBM calls */ 69*7c478bd9Sstevel@tonic-gate #include "shim.h" 70*7c478bd9Sstevel@tonic-gate #include "shim_hooks.h" 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate USE_YP_PREFIX 73*7c478bd9Sstevel@tonic-gate USE_YP_SECURE 74*7c478bd9Sstevel@tonic-gate USE_YP_INTERDOMAIN 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate #ifndef YPXFR_PROC 77*7c478bd9Sstevel@tonic-gate #define YPXFR_PROC "/usr/lib/netsvc/yp/ypxfr" 78*7c478bd9Sstevel@tonic-gate #endif 79*7c478bd9Sstevel@tonic-gate static char ypxfr_proc[] = YPXFR_PROC; 80*7c478bd9Sstevel@tonic-gate #ifndef YPPUSH_PROC 81*7c478bd9Sstevel@tonic-gate #define YPPUSH_PROC "/usr/lib/netsvc/yp/yppush" 82*7c478bd9Sstevel@tonic-gate #endif 83*7c478bd9Sstevel@tonic-gate static char yppush_proc[] = YPPUSH_PROC; 84*7c478bd9Sstevel@tonic-gate struct yppriv_sym { 85*7c478bd9Sstevel@tonic-gate char *sym; 86*7c478bd9Sstevel@tonic-gate unsigned len; 87*7c478bd9Sstevel@tonic-gate }; 88*7c478bd9Sstevel@tonic-gate static char err_fork[] = "ypserv: %s fork failure.\n"; 89*7c478bd9Sstevel@tonic-gate #define FORK_ERR logprintf(err_fork, fun) 90*7c478bd9Sstevel@tonic-gate static char err_execl[] = "ypserv: %s execl failure.\n"; 91*7c478bd9Sstevel@tonic-gate #define EXEC_ERR logprintf(err_execl, fun) 92*7c478bd9Sstevel@tonic-gate static char err_respond[] = "ypserv: %s can't respond to rpc request.\n"; 93*7c478bd9Sstevel@tonic-gate #define RESPOND_ERR logprintf(err_respond, fun) 94*7c478bd9Sstevel@tonic-gate static char err_free[] = "ypserv: %s can't free args.\n"; 95*7c478bd9Sstevel@tonic-gate #define FREE_ERR logprintf(err_free, fun) 96*7c478bd9Sstevel@tonic-gate static char err_map[] = "ypserv: %s no such map or access denied.\n"; 97*7c478bd9Sstevel@tonic-gate #define MAP_ERR logprintf(err_map, fun) 98*7c478bd9Sstevel@tonic-gate static char err_vers[] = "ypserv: %s version not supported.\n"; 99*7c478bd9Sstevel@tonic-gate #define VERS_ERR logprintf(err_vers, fun) 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate static void ypfilter(DBM *fdb, datum *inkey, datum *outkey, datum *val, 102*7c478bd9Sstevel@tonic-gate uint_t *status, bool_t update); 103*7c478bd9Sstevel@tonic-gate static bool isypsym(datum *key); 104*7c478bd9Sstevel@tonic-gate static bool xdrypserv_ypall(XDR *xdrs, struct ypreq_nokey *req); 105*7c478bd9Sstevel@tonic-gate static int multihomed(struct ypreq_key req, struct ypresp_val *resp, 106*7c478bd9Sstevel@tonic-gate SVCXPRT *xprt, DBM *fdb); 107*7c478bd9Sstevel@tonic-gate static int omultihomed(struct yprequest req, struct ypresponse *resp, 108*7c478bd9Sstevel@tonic-gate SVCXPRT *xprt, DBM *fdb); 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate /* For DNS forwarding */ 112*7c478bd9Sstevel@tonic-gate extern bool dnsforward; 113*7c478bd9Sstevel@tonic-gate extern bool client_setup_failure; 114*7c478bd9Sstevel@tonic-gate extern int resolv_pid; 115*7c478bd9Sstevel@tonic-gate extern CLIENT *resolv_client; 116*7c478bd9Sstevel@tonic-gate extern char *resolv_tp; 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate /* 119*7c478bd9Sstevel@tonic-gate * This determines whether or not a passed domain is served by this 120*7c478bd9Sstevel@tonic-gate * server, and returns a boolean. Used by both old and new protocol 121*7c478bd9Sstevel@tonic-gate * versions. 122*7c478bd9Sstevel@tonic-gate */ 123*7c478bd9Sstevel@tonic-gate void 124*7c478bd9Sstevel@tonic-gate ypdomain(SVCXPRT *transp, bool always_respond) 125*7c478bd9Sstevel@tonic-gate { 126*7c478bd9Sstevel@tonic-gate char domain_name[YPMAXDOMAIN + 1]; 127*7c478bd9Sstevel@tonic-gate char *pdomain_name = domain_name; 128*7c478bd9Sstevel@tonic-gate bool isserved; 129*7c478bd9Sstevel@tonic-gate char *fun = "ypdomain"; 130*7c478bd9Sstevel@tonic-gate struct netbuf *nbuf; 131*7c478bd9Sstevel@tonic-gate sa_family_t af; 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate memset(domain_name, 0, sizeof (domain_name)); 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, (xdrproc_t)xdr_ypdomain_wrap_string, 136*7c478bd9Sstevel@tonic-gate (caddr_t)&pdomain_name)) { 137*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 138*7c478bd9Sstevel@tonic-gate return; 139*7c478bd9Sstevel@tonic-gate } 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate /* 142*7c478bd9Sstevel@tonic-gate * If the file /var/yp/securenets is present on the server, and if 143*7c478bd9Sstevel@tonic-gate * the hostname is present in the file, then let the client bind to 144*7c478bd9Sstevel@tonic-gate * the server. 145*7c478bd9Sstevel@tonic-gate */ 146*7c478bd9Sstevel@tonic-gate nbuf = svc_getrpccaller(transp); 147*7c478bd9Sstevel@tonic-gate af = ((struct sockaddr_storage *)nbuf->buf)->ss_family; 148*7c478bd9Sstevel@tonic-gate if (af != AF_INET && af != AF_INET6) { 149*7c478bd9Sstevel@tonic-gate logprintf("Protocol incorrect\n"); 150*7c478bd9Sstevel@tonic-gate return; 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate if (!(check_secure_net_ti(nbuf, fun))) { 154*7c478bd9Sstevel@tonic-gate MAP_ERR; 155*7c478bd9Sstevel@tonic-gate return; 156*7c478bd9Sstevel@tonic-gate } 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate isserved = ypcheck_domain(domain_name); 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate if (isserved || always_respond) { 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, xdr_bool, (char *)&isserved)) { 163*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate if (!isserved) 166*7c478bd9Sstevel@tonic-gate logprintf("Domain %s not supported\n", 167*7c478bd9Sstevel@tonic-gate domain_name); 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate } else { 170*7c478bd9Sstevel@tonic-gate /* 171*7c478bd9Sstevel@tonic-gate * This case is the one in which the domain is not 172*7c478bd9Sstevel@tonic-gate * supported, and in which we are not to respond in the 173*7c478bd9Sstevel@tonic-gate * unsupported case. We are going to make an error happen 174*7c478bd9Sstevel@tonic-gate * to allow the portmapper to end his wait without the 175*7c478bd9Sstevel@tonic-gate * normal timeout period. The assumption here is that 176*7c478bd9Sstevel@tonic-gate * the only process in the world which is using the function 177*7c478bd9Sstevel@tonic-gate * in its no-answer-if-nack form is the portmapper, which is 178*7c478bd9Sstevel@tonic-gate * doing the krock for pseudo-broadcast. If some poor fool 179*7c478bd9Sstevel@tonic-gate * calls this function as a single-cast message, the nack 180*7c478bd9Sstevel@tonic-gate * case will look like an incomprehensible error. Sigh... 181*7c478bd9Sstevel@tonic-gate * (The traditional Unix disclaimer) 182*7c478bd9Sstevel@tonic-gate */ 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 185*7c478bd9Sstevel@tonic-gate logprintf("Domain %s not supported (broadcast)\n", 186*7c478bd9Sstevel@tonic-gate domain_name); 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate /* 191*7c478bd9Sstevel@tonic-gate * This implements the yp "match" function. 192*7c478bd9Sstevel@tonic-gate */ 193*7c478bd9Sstevel@tonic-gate void 194*7c478bd9Sstevel@tonic-gate ypmatch(SVCXPRT *transp, struct svc_req *rqstp) 195*7c478bd9Sstevel@tonic-gate { 196*7c478bd9Sstevel@tonic-gate struct ypreq_key req; 197*7c478bd9Sstevel@tonic-gate struct ypresp_val resp; 198*7c478bd9Sstevel@tonic-gate char *fun = "ypmatch"; 199*7c478bd9Sstevel@tonic-gate DBM *fdb; 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate memset(&req, 0, sizeof (req)); 202*7c478bd9Sstevel@tonic-gate memset(&resp, 0, sizeof (resp)); 203*7c478bd9Sstevel@tonic-gate resp.status = (unsigned)YP_NOKEY; 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, (xdrproc_t)xdr_ypreq_key, (char *)&req)) { 206*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 207*7c478bd9Sstevel@tonic-gate return; 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate /* 211*7c478bd9Sstevel@tonic-gate * sanity check the map name and to a DBM lookup 212*7c478bd9Sstevel@tonic-gate * also perform an access check... 213*7c478bd9Sstevel@tonic-gate */ 214*7c478bd9Sstevel@tonic-gate if ((fdb = ypset_current_map(req.map, req.domain, 215*7c478bd9Sstevel@tonic-gate &resp.status)) != NULL && 216*7c478bd9Sstevel@tonic-gate yp_map_access(transp, &resp.status, fdb)) { 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate /* Check with the DBM database */ 219*7c478bd9Sstevel@tonic-gate resp.valdat = dbm_fetch(fdb, req.keydat); 220*7c478bd9Sstevel@tonic-gate if (resp.valdat.dptr != NULL) { 221*7c478bd9Sstevel@tonic-gate resp.status = YP_TRUE; 222*7c478bd9Sstevel@tonic-gate if (!silent) 223*7c478bd9Sstevel@tonic-gate printf("%s: dbm: %40.40s\n", 224*7c478bd9Sstevel@tonic-gate fun, resp.valdat.dptr); 225*7c478bd9Sstevel@tonic-gate goto send_reply; 226*7c478bd9Sstevel@tonic-gate } 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate /* 229*7c478bd9Sstevel@tonic-gate * If we're being asked to match YP_SECURE or YP_INTERDOMAIN 230*7c478bd9Sstevel@tonic-gate * and we haven't found it in the dbm file, then we don't 231*7c478bd9Sstevel@tonic-gate * really want to waste any more time. Specifically, we don't 232*7c478bd9Sstevel@tonic-gate * want to ask DNS 233*7c478bd9Sstevel@tonic-gate */ 234*7c478bd9Sstevel@tonic-gate if (req.keydat.dsize == 0 || 235*7c478bd9Sstevel@tonic-gate req.keydat.dptr == NULL || 236*7c478bd9Sstevel@tonic-gate req.keydat.dptr[0] == '\0' || 237*7c478bd9Sstevel@tonic-gate strncmp(req.keydat.dptr, yp_secure, req.keydat.dsize) == 0 || 238*7c478bd9Sstevel@tonic-gate strncmp(req.keydat.dptr, yp_interdomain, req.keydat.dsize) == 0) { 239*7c478bd9Sstevel@tonic-gate goto send_reply; 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate /* Let's try the YP_MULTI_ hack... */ 243*7c478bd9Sstevel@tonic-gate #ifdef MINUS_C_OPTION 244*7c478bd9Sstevel@tonic-gate if (multiflag == TRUE && multihomed(req, &resp, transp, fdb)) 245*7c478bd9Sstevel@tonic-gate goto send_reply; 246*7c478bd9Sstevel@tonic-gate #else 247*7c478bd9Sstevel@tonic-gate if (multihomed(req, &resp, transp, fdb)) 248*7c478bd9Sstevel@tonic-gate goto send_reply; 249*7c478bd9Sstevel@tonic-gate #endif 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate /* 252*7c478bd9Sstevel@tonic-gate * Let's try DNS, but if client_setup_failure is set, 253*7c478bd9Sstevel@tonic-gate * we have tried DNS in the past and failed, there is 254*7c478bd9Sstevel@tonic-gate * no reason in forcing an infinite loop by turning 255*7c478bd9Sstevel@tonic-gate * off DNS in setup_resolv() only to turn it back on 256*7c478bd9Sstevel@tonic-gate * again here. 257*7c478bd9Sstevel@tonic-gate */ 258*7c478bd9Sstevel@tonic-gate if (!dnsforward && !client_setup_failure) { 259*7c478bd9Sstevel@tonic-gate datum idkey, idval; 260*7c478bd9Sstevel@tonic-gate idkey.dptr = yp_interdomain; 261*7c478bd9Sstevel@tonic-gate idkey.dsize = yp_interdomain_sz; 262*7c478bd9Sstevel@tonic-gate idval = dbm_fetch(fdb, idkey); 263*7c478bd9Sstevel@tonic-gate if (idval.dptr) 264*7c478bd9Sstevel@tonic-gate dnsforward = TRUE; 265*7c478bd9Sstevel@tonic-gate } 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate if (dnsforward) { 268*7c478bd9Sstevel@tonic-gate if (!resolv_pid || !resolv_client) { 269*7c478bd9Sstevel@tonic-gate setup_resolv(&dnsforward, &resolv_pid, 270*7c478bd9Sstevel@tonic-gate &resolv_client, resolv_tp, 0); 271*7c478bd9Sstevel@tonic-gate if (resolv_client == NULL) 272*7c478bd9Sstevel@tonic-gate client_setup_failure = TRUE; 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate if (resolv_req(&dnsforward, &resolv_client, 276*7c478bd9Sstevel@tonic-gate &resolv_pid, resolv_tp, 277*7c478bd9Sstevel@tonic-gate rqstp->rq_xprt, &req, 278*7c478bd9Sstevel@tonic-gate req.map) == TRUE) 279*7c478bd9Sstevel@tonic-gate goto free_args; 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate } 282*7c478bd9Sstevel@tonic-gate send_reply: 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, (xdrproc_t)xdr_ypresp_val, 285*7c478bd9Sstevel@tonic-gate (caddr_t)&resp)) { 286*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate free_args: 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, (xdrproc_t)xdr_ypreq_key, 292*7c478bd9Sstevel@tonic-gate (char *)&req)) { 293*7c478bd9Sstevel@tonic-gate FREE_ERR; 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate /* 299*7c478bd9Sstevel@tonic-gate * This implements the yp "get first" function. 300*7c478bd9Sstevel@tonic-gate */ 301*7c478bd9Sstevel@tonic-gate void 302*7c478bd9Sstevel@tonic-gate ypfirst(SVCXPRT *transp) 303*7c478bd9Sstevel@tonic-gate { 304*7c478bd9Sstevel@tonic-gate struct ypreq_nokey req; 305*7c478bd9Sstevel@tonic-gate struct ypresp_key_val resp; 306*7c478bd9Sstevel@tonic-gate char *fun = "ypfirst"; 307*7c478bd9Sstevel@tonic-gate DBM *fdb; 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate memset(&req, 0, sizeof (req)); 310*7c478bd9Sstevel@tonic-gate memset(&resp, 0, sizeof (resp)); 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 313*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_nokey, 314*7c478bd9Sstevel@tonic-gate (char *)&req)) { 315*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 316*7c478bd9Sstevel@tonic-gate return; 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate if ((fdb = ypset_current_map(req.map, req.domain, 320*7c478bd9Sstevel@tonic-gate &resp.status)) != NULL && 321*7c478bd9Sstevel@tonic-gate yp_map_access(transp, &resp.status, fdb)) { 322*7c478bd9Sstevel@tonic-gate ypfilter(fdb, NULL, 323*7c478bd9Sstevel@tonic-gate &resp.keydat, &resp.valdat, &resp.status, FALSE); 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, 327*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypresp_key_val, 328*7c478bd9Sstevel@tonic-gate (char *)&resp)) { 329*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, (xdrproc_t)xdr_ypreq_nokey, 333*7c478bd9Sstevel@tonic-gate (char *)&req)) { 334*7c478bd9Sstevel@tonic-gate FREE_ERR; 335*7c478bd9Sstevel@tonic-gate } 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate /* 339*7c478bd9Sstevel@tonic-gate * This implements the yp "get next" function. 340*7c478bd9Sstevel@tonic-gate */ 341*7c478bd9Sstevel@tonic-gate void 342*7c478bd9Sstevel@tonic-gate ypnext(SVCXPRT *transp) 343*7c478bd9Sstevel@tonic-gate { 344*7c478bd9Sstevel@tonic-gate struct ypreq_key req; 345*7c478bd9Sstevel@tonic-gate struct ypresp_key_val resp; 346*7c478bd9Sstevel@tonic-gate char *fun = "ypnext"; 347*7c478bd9Sstevel@tonic-gate DBM *fdb; 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate memset(&req, 0, sizeof (req)); 350*7c478bd9Sstevel@tonic-gate memset(&resp, 0, sizeof (resp)); 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, (xdrproc_t)xdr_ypreq_key, (char *)&req)) { 353*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 354*7c478bd9Sstevel@tonic-gate return; 355*7c478bd9Sstevel@tonic-gate } 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate if ((fdb = ypset_current_map(req.map, req.domain, 358*7c478bd9Sstevel@tonic-gate &resp.status)) != NULL && 359*7c478bd9Sstevel@tonic-gate yp_map_access(transp, &resp.status, fdb)) { 360*7c478bd9Sstevel@tonic-gate ypfilter(fdb, &req.keydat, 361*7c478bd9Sstevel@tonic-gate &resp.keydat, &resp.valdat, &resp.status, FALSE); 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, 365*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypresp_key_val, 366*7c478bd9Sstevel@tonic-gate (char *)&resp)) { 367*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 371*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_key, 372*7c478bd9Sstevel@tonic-gate (char *)&req)) { 373*7c478bd9Sstevel@tonic-gate FREE_ERR; 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate /* 378*7c478bd9Sstevel@tonic-gate * This implements the "transfer map" function. It takes the domain 379*7c478bd9Sstevel@tonic-gate * and map names and the callback information provided by the 380*7c478bd9Sstevel@tonic-gate * requester (yppush on some node), and execs a ypxfr process to do 381*7c478bd9Sstevel@tonic-gate * the actual transfer. 382*7c478bd9Sstevel@tonic-gate */ 383*7c478bd9Sstevel@tonic-gate void 384*7c478bd9Sstevel@tonic-gate ypxfr(SVCXPRT *transp, int prog) 385*7c478bd9Sstevel@tonic-gate { 386*7c478bd9Sstevel@tonic-gate struct ypreq_newxfr newreq; 387*7c478bd9Sstevel@tonic-gate struct ypreq_xfr oldreq; 388*7c478bd9Sstevel@tonic-gate struct ypresp_val resp; /* not returned to the caller */ 389*7c478bd9Sstevel@tonic-gate char transid[32]; 390*7c478bd9Sstevel@tonic-gate char proto[32]; 391*7c478bd9Sstevel@tonic-gate char name[256]; 392*7c478bd9Sstevel@tonic-gate char *pdomain, *pmap; 393*7c478bd9Sstevel@tonic-gate pid_t pid = -1; 394*7c478bd9Sstevel@tonic-gate char *fun = "ypxfr"; 395*7c478bd9Sstevel@tonic-gate DBM *fdb; 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate if (prog == YPPROC_NEWXFR) { 398*7c478bd9Sstevel@tonic-gate memset(&newreq, 0, sizeof (newreq)); 399*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, (xdrproc_t)xdr_ypreq_newxfr, 400*7c478bd9Sstevel@tonic-gate (char *)&newreq)) { 401*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 402*7c478bd9Sstevel@tonic-gate return; 403*7c478bd9Sstevel@tonic-gate } 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate #ifdef OPCOM_DEBUG 406*7c478bd9Sstevel@tonic-gate fprintf(stderr, "newreq:\n" 407*7c478bd9Sstevel@tonic-gate "\tmap_parms:\n" 408*7c478bd9Sstevel@tonic-gate "\t\tdomain: %s\n" 409*7c478bd9Sstevel@tonic-gate "\t\tmap: %s\n" 410*7c478bd9Sstevel@tonic-gate "\t\tordernum: %u\n" 411*7c478bd9Sstevel@tonic-gate "\t\towner: %s\n" 412*7c478bd9Sstevel@tonic-gate "\ttransid: %u\n" 413*7c478bd9Sstevel@tonic-gate "\tproto: %u\n" 414*7c478bd9Sstevel@tonic-gate "\tname: %s\n\n", 415*7c478bd9Sstevel@tonic-gate newreq.map_parms.domain, 416*7c478bd9Sstevel@tonic-gate newreq.map_parms.map, 417*7c478bd9Sstevel@tonic-gate newreq.map_parms.ordernum, 418*7c478bd9Sstevel@tonic-gate newreq.map_parms.owner, 419*7c478bd9Sstevel@tonic-gate newreq.transid, 420*7c478bd9Sstevel@tonic-gate newreq.proto, 421*7c478bd9Sstevel@tonic-gate newreq.name); 422*7c478bd9Sstevel@tonic-gate #endif 423*7c478bd9Sstevel@tonic-gate sprintf(transid, "%u", newreq.transid); 424*7c478bd9Sstevel@tonic-gate sprintf(proto, "%u", newreq.proto); 425*7c478bd9Sstevel@tonic-gate sprintf(name, "%s", newreq.ypxfr_owner); 426*7c478bd9Sstevel@tonic-gate pdomain = newreq.ypxfr_domain; 427*7c478bd9Sstevel@tonic-gate pmap = newreq.ypxfr_map; 428*7c478bd9Sstevel@tonic-gate } else if (prog == YPPROC_XFR) { 429*7c478bd9Sstevel@tonic-gate memset(&oldreq, 0, sizeof (oldreq)); 430*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 431*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_xfr, 432*7c478bd9Sstevel@tonic-gate (char *)&oldreq)) { 433*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 434*7c478bd9Sstevel@tonic-gate return; 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate #ifdef OPCOM_DEBUG 438*7c478bd9Sstevel@tonic-gate fprintf(stderr, "oldreq:\n" 439*7c478bd9Sstevel@tonic-gate "\tmap_parms:\n" 440*7c478bd9Sstevel@tonic-gate "\t\tdomain: %s\n" 441*7c478bd9Sstevel@tonic-gate "\t\tmap: %s\n" 442*7c478bd9Sstevel@tonic-gate "\t\tordernum: %u\n" 443*7c478bd9Sstevel@tonic-gate "\t\towner: %s\n" 444*7c478bd9Sstevel@tonic-gate "\ttransid: %u\n" 445*7c478bd9Sstevel@tonic-gate "\tproto: %u\n" 446*7c478bd9Sstevel@tonic-gate "\tport: %u\n\n", 447*7c478bd9Sstevel@tonic-gate oldreq.map_parms.domain, 448*7c478bd9Sstevel@tonic-gate oldreq.map_parms.map, 449*7c478bd9Sstevel@tonic-gate oldreq.map_parms.ordernum, 450*7c478bd9Sstevel@tonic-gate oldreq.map_parms.owner, 451*7c478bd9Sstevel@tonic-gate oldreq.transid, 452*7c478bd9Sstevel@tonic-gate oldreq.proto, 453*7c478bd9Sstevel@tonic-gate oldreq.port); 454*7c478bd9Sstevel@tonic-gate #endif 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate sprintf(transid, "%u", oldreq.transid); 457*7c478bd9Sstevel@tonic-gate sprintf(proto, "%u", oldreq.proto); 458*7c478bd9Sstevel@tonic-gate sprintf(name, "%s", oldreq.ypxfr_owner); 459*7c478bd9Sstevel@tonic-gate pdomain = oldreq.ypxfr_domain; 460*7c478bd9Sstevel@tonic-gate pmap = oldreq.ypxfr_map; 461*7c478bd9Sstevel@tonic-gate } else { 462*7c478bd9Sstevel@tonic-gate VERS_ERR; 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate /* Check that the map exists and is accessible */ 466*7c478bd9Sstevel@tonic-gate if ((fdb = ypset_current_map(pmap, pdomain, &resp.status)) != NULL && 467*7c478bd9Sstevel@tonic-gate yp_map_access(transp, &resp.status, fdb)) { 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate pid = vfork(); 470*7c478bd9Sstevel@tonic-gate if (pid == -1) { 471*7c478bd9Sstevel@tonic-gate FORK_ERR; 472*7c478bd9Sstevel@tonic-gate } else if (pid == 0) { 473*7c478bd9Sstevel@tonic-gate if (prog == YPPROC_NEWXFR || prog == YPPROC_XFR) { 474*7c478bd9Sstevel@tonic-gate #ifdef OPCOM_DEBUG 475*7c478bd9Sstevel@tonic-gate fprintf(stderr, 476*7c478bd9Sstevel@tonic-gate "EXECL: %s, -d, %s, -C, %s, %s, %s, %s\n", 477*7c478bd9Sstevel@tonic-gate ypxfr_proc, pdomain, 478*7c478bd9Sstevel@tonic-gate transid, proto, name, pmap); 479*7c478bd9Sstevel@tonic-gate #endif 480*7c478bd9Sstevel@tonic-gate if (execl(ypxfr_proc, "ypxfr", "-d", 481*7c478bd9Sstevel@tonic-gate pdomain, "-C", transid, proto, 482*7c478bd9Sstevel@tonic-gate name, pmap, NULL)) 483*7c478bd9Sstevel@tonic-gate EXEC_ERR; 484*7c478bd9Sstevel@tonic-gate } else { 485*7c478bd9Sstevel@tonic-gate VERS_ERR; 486*7c478bd9Sstevel@tonic-gate } 487*7c478bd9Sstevel@tonic-gate _exit(1); 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate } else { 491*7c478bd9Sstevel@tonic-gate MAP_ERR; 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, xdr_void, 0)) { 494*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 495*7c478bd9Sstevel@tonic-gate } 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate if (prog == YPPROC_NEWXFR) { 498*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 499*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_newxfr, 500*7c478bd9Sstevel@tonic-gate (char *)&newreq)) { 501*7c478bd9Sstevel@tonic-gate FREE_ERR; 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate } 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate /* 507*7c478bd9Sstevel@tonic-gate * This implements the "get all" function. 508*7c478bd9Sstevel@tonic-gate */ 509*7c478bd9Sstevel@tonic-gate void 510*7c478bd9Sstevel@tonic-gate ypall(SVCXPRT *transp) 511*7c478bd9Sstevel@tonic-gate { 512*7c478bd9Sstevel@tonic-gate struct ypreq_nokey req; 513*7c478bd9Sstevel@tonic-gate struct ypresp_val resp; /* not returned to the caller */ 514*7c478bd9Sstevel@tonic-gate pid_t pid; 515*7c478bd9Sstevel@tonic-gate char *fun = "ypall"; 516*7c478bd9Sstevel@tonic-gate DBM *fdb; 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate req.domain = req.map = NULL; 519*7c478bd9Sstevel@tonic-gate 520*7c478bd9Sstevel@tonic-gate memset((char *)&req, 0, sizeof (req)); 521*7c478bd9Sstevel@tonic-gate 522*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 523*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_nokey, 524*7c478bd9Sstevel@tonic-gate (char *)&req)) { 525*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 526*7c478bd9Sstevel@tonic-gate return; 527*7c478bd9Sstevel@tonic-gate } 528*7c478bd9Sstevel@tonic-gate 529*7c478bd9Sstevel@tonic-gate pid = fork1(); 530*7c478bd9Sstevel@tonic-gate 531*7c478bd9Sstevel@tonic-gate if (pid) { 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate if (pid == -1) { 534*7c478bd9Sstevel@tonic-gate FORK_ERR; 535*7c478bd9Sstevel@tonic-gate } 536*7c478bd9Sstevel@tonic-gate 537*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 538*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_nokey, 539*7c478bd9Sstevel@tonic-gate (char *)&req)) { 540*7c478bd9Sstevel@tonic-gate FREE_ERR; 541*7c478bd9Sstevel@tonic-gate } 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate return; 544*7c478bd9Sstevel@tonic-gate } 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate /* 547*7c478bd9Sstevel@tonic-gate * access control hack: If denied then invalidate the map name. 548*7c478bd9Sstevel@tonic-gate */ 549*7c478bd9Sstevel@tonic-gate ypclr_current_map(); 550*7c478bd9Sstevel@tonic-gate if ((fdb = ypset_current_map(req.map, 551*7c478bd9Sstevel@tonic-gate req.domain, &resp.status)) != NULL && 552*7c478bd9Sstevel@tonic-gate !yp_map_access(transp, &resp.status, fdb)) { 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate req.map[0] = '-'; 555*7c478bd9Sstevel@tonic-gate } 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate /* 558*7c478bd9Sstevel@tonic-gate * This is the child process. The work gets done by xdrypserv_ypall/ 559*7c478bd9Sstevel@tonic-gate * we must clear the "current map" first so that we do not 560*7c478bd9Sstevel@tonic-gate * share a seek pointer with the parent server. 561*7c478bd9Sstevel@tonic-gate */ 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, 564*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdrypserv_ypall, 565*7c478bd9Sstevel@tonic-gate (char *)&req)) { 566*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 567*7c478bd9Sstevel@tonic-gate } 568*7c478bd9Sstevel@tonic-gate 569*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 570*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_nokey, 571*7c478bd9Sstevel@tonic-gate (char *)&req)) { 572*7c478bd9Sstevel@tonic-gate FREE_ERR; 573*7c478bd9Sstevel@tonic-gate } 574*7c478bd9Sstevel@tonic-gate 575*7c478bd9Sstevel@tonic-gate /* 576*7c478bd9Sstevel@tonic-gate * In yptol mode we may start a cache update thread within a child 577*7c478bd9Sstevel@tonic-gate * process. It is thus important that child processes do not exit, 578*7c478bd9Sstevel@tonic-gate * killing any such threads, before the thread has completed. 579*7c478bd9Sstevel@tonic-gate */ 580*7c478bd9Sstevel@tonic-gate if (yptol_mode) { 581*7c478bd9Sstevel@tonic-gate thr_join(0, NULL, NULL); 582*7c478bd9Sstevel@tonic-gate } 583*7c478bd9Sstevel@tonic-gate 584*7c478bd9Sstevel@tonic-gate exit(0); 585*7c478bd9Sstevel@tonic-gate } 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate /* 588*7c478bd9Sstevel@tonic-gate * This implements the "get master name" function. 589*7c478bd9Sstevel@tonic-gate */ 590*7c478bd9Sstevel@tonic-gate void 591*7c478bd9Sstevel@tonic-gate ypmaster(SVCXPRT *transp) 592*7c478bd9Sstevel@tonic-gate { 593*7c478bd9Sstevel@tonic-gate struct ypreq_nokey req; 594*7c478bd9Sstevel@tonic-gate struct ypresp_master resp; 595*7c478bd9Sstevel@tonic-gate char *nullstring = ""; 596*7c478bd9Sstevel@tonic-gate char *fun = "ypmaster"; 597*7c478bd9Sstevel@tonic-gate DBM *fdb; 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate memset((char *)&req, 0, sizeof (req)); 600*7c478bd9Sstevel@tonic-gate resp.master = nullstring; 601*7c478bd9Sstevel@tonic-gate resp.status = YP_TRUE; 602*7c478bd9Sstevel@tonic-gate 603*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 604*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_nokey, 605*7c478bd9Sstevel@tonic-gate (char *)&req)) { 606*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 607*7c478bd9Sstevel@tonic-gate return; 608*7c478bd9Sstevel@tonic-gate } 609*7c478bd9Sstevel@tonic-gate 610*7c478bd9Sstevel@tonic-gate if ((fdb = ypset_current_map(req.map, 611*7c478bd9Sstevel@tonic-gate req.domain, &resp.status)) != NULL && 612*7c478bd9Sstevel@tonic-gate yp_map_access(transp, &resp.status, fdb)) { 613*7c478bd9Sstevel@tonic-gate 614*7c478bd9Sstevel@tonic-gate if (!ypget_map_master(&resp.master, fdb)) { 615*7c478bd9Sstevel@tonic-gate resp.status = (unsigned)YP_BADDB; 616*7c478bd9Sstevel@tonic-gate } 617*7c478bd9Sstevel@tonic-gate } 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, 620*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypresp_master, 621*7c478bd9Sstevel@tonic-gate (char *)&resp)) { 622*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 623*7c478bd9Sstevel@tonic-gate } 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 626*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_nokey, 627*7c478bd9Sstevel@tonic-gate (char *)&req)) { 628*7c478bd9Sstevel@tonic-gate FREE_ERR; 629*7c478bd9Sstevel@tonic-gate } 630*7c478bd9Sstevel@tonic-gate } 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate /* 633*7c478bd9Sstevel@tonic-gate * This implements the "get order number" function. 634*7c478bd9Sstevel@tonic-gate */ 635*7c478bd9Sstevel@tonic-gate void 636*7c478bd9Sstevel@tonic-gate yporder(SVCXPRT *transp) 637*7c478bd9Sstevel@tonic-gate { 638*7c478bd9Sstevel@tonic-gate struct ypreq_nokey req; 639*7c478bd9Sstevel@tonic-gate struct ypresp_order resp; 640*7c478bd9Sstevel@tonic-gate char *fun = "yporder"; 641*7c478bd9Sstevel@tonic-gate DBM *fdb; 642*7c478bd9Sstevel@tonic-gate 643*7c478bd9Sstevel@tonic-gate req.domain = req.map = NULL; 644*7c478bd9Sstevel@tonic-gate resp.status = YP_TRUE; 645*7c478bd9Sstevel@tonic-gate resp.ordernum = 0; 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate memset((char *)&req, 0, sizeof (req)); 648*7c478bd9Sstevel@tonic-gate 649*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 650*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_nokey, 651*7c478bd9Sstevel@tonic-gate (char *)&req)) { 652*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 653*7c478bd9Sstevel@tonic-gate return; 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate resp.ordernum = 0; 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate if ((fdb = ypset_current_map(req.map, 659*7c478bd9Sstevel@tonic-gate req.domain, 660*7c478bd9Sstevel@tonic-gate &resp.status)) != NULL && 661*7c478bd9Sstevel@tonic-gate yp_map_access(transp, &resp.status, fdb)) { 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate if (!ypget_map_order(req.map, req.domain, &resp.ordernum)) { 664*7c478bd9Sstevel@tonic-gate resp.status = (unsigned)YP_BADDB; 665*7c478bd9Sstevel@tonic-gate } 666*7c478bd9Sstevel@tonic-gate } 667*7c478bd9Sstevel@tonic-gate 668*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, 669*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypresp_order, 670*7c478bd9Sstevel@tonic-gate (char *)&resp)) { 671*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 672*7c478bd9Sstevel@tonic-gate } 673*7c478bd9Sstevel@tonic-gate 674*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 675*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_nokey, 676*7c478bd9Sstevel@tonic-gate (char *)&req)) { 677*7c478bd9Sstevel@tonic-gate FREE_ERR; 678*7c478bd9Sstevel@tonic-gate } 679*7c478bd9Sstevel@tonic-gate } 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gate void 682*7c478bd9Sstevel@tonic-gate ypmaplist(SVCXPRT *transp) 683*7c478bd9Sstevel@tonic-gate { 684*7c478bd9Sstevel@tonic-gate char domain_name[YPMAXDOMAIN + 1]; 685*7c478bd9Sstevel@tonic-gate char *pdomain = domain_name; 686*7c478bd9Sstevel@tonic-gate char *fun = "ypmaplist"; 687*7c478bd9Sstevel@tonic-gate struct ypresp_maplist maplist; 688*7c478bd9Sstevel@tonic-gate struct ypmaplist *tmp; 689*7c478bd9Sstevel@tonic-gate 690*7c478bd9Sstevel@tonic-gate maplist.list = (struct ypmaplist *)NULL; 691*7c478bd9Sstevel@tonic-gate 692*7c478bd9Sstevel@tonic-gate memset(domain_name, 0, sizeof (domain_name)); 693*7c478bd9Sstevel@tonic-gate 694*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 695*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypdomain_wrap_string, 696*7c478bd9Sstevel@tonic-gate (caddr_t)&pdomain)) { 697*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 698*7c478bd9Sstevel@tonic-gate return; 699*7c478bd9Sstevel@tonic-gate } 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate maplist.status = yplist_maps(domain_name, &maplist.list); 702*7c478bd9Sstevel@tonic-gate 703*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, 704*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypresp_maplist, 705*7c478bd9Sstevel@tonic-gate (char *)&maplist)) { 706*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 707*7c478bd9Sstevel@tonic-gate } 708*7c478bd9Sstevel@tonic-gate 709*7c478bd9Sstevel@tonic-gate while (maplist.list) { 710*7c478bd9Sstevel@tonic-gate tmp = maplist.list->ypml_next; 711*7c478bd9Sstevel@tonic-gate free((char *)maplist.list); 712*7c478bd9Sstevel@tonic-gate maplist.list = tmp; 713*7c478bd9Sstevel@tonic-gate } 714*7c478bd9Sstevel@tonic-gate } 715*7c478bd9Sstevel@tonic-gate 716*7c478bd9Sstevel@tonic-gate /* 717*7c478bd9Sstevel@tonic-gate * Ancillary functions used by the top-level functions within this 718*7c478bd9Sstevel@tonic-gate * module 719*7c478bd9Sstevel@tonic-gate */ 720*7c478bd9Sstevel@tonic-gate 721*7c478bd9Sstevel@tonic-gate /* 722*7c478bd9Sstevel@tonic-gate * This returns TRUE if a given key is a yp-private symbol, otherwise 723*7c478bd9Sstevel@tonic-gate * FALSE 724*7c478bd9Sstevel@tonic-gate */ 725*7c478bd9Sstevel@tonic-gate static bool 726*7c478bd9Sstevel@tonic-gate isypsym(datum *key) 727*7c478bd9Sstevel@tonic-gate { 728*7c478bd9Sstevel@tonic-gate if ((key->dptr == NULL) || 729*7c478bd9Sstevel@tonic-gate (key->dsize < yp_prefix_sz) || 730*7c478bd9Sstevel@tonic-gate memcmp(yp_prefix, key->dptr, yp_prefix_sz) || 731*7c478bd9Sstevel@tonic-gate (!memcmp(key->dptr, "YP_MULTI_", 9))) { 732*7c478bd9Sstevel@tonic-gate return (FALSE); 733*7c478bd9Sstevel@tonic-gate } 734*7c478bd9Sstevel@tonic-gate return (TRUE); 735*7c478bd9Sstevel@tonic-gate } 736*7c478bd9Sstevel@tonic-gate 737*7c478bd9Sstevel@tonic-gate /* 738*7c478bd9Sstevel@tonic-gate * This provides private-symbol filtration for the enumeration functions. 739*7c478bd9Sstevel@tonic-gate */ 740*7c478bd9Sstevel@tonic-gate static void 741*7c478bd9Sstevel@tonic-gate ypfilter(DBM *fdb, datum *inkey, datum *outkey, datum *val, uint_t *status, 742*7c478bd9Sstevel@tonic-gate bool_t update) 743*7c478bd9Sstevel@tonic-gate { 744*7c478bd9Sstevel@tonic-gate datum k; 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate if (inkey) { 747*7c478bd9Sstevel@tonic-gate 748*7c478bd9Sstevel@tonic-gate if (isypsym(inkey)) { 749*7c478bd9Sstevel@tonic-gate *status = (unsigned)YP_BADARGS; 750*7c478bd9Sstevel@tonic-gate return; 751*7c478bd9Sstevel@tonic-gate } 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate k = dbm_do_nextkey(fdb, *inkey); 754*7c478bd9Sstevel@tonic-gate } else { 755*7c478bd9Sstevel@tonic-gate k = dbm_firstkey(fdb); 756*7c478bd9Sstevel@tonic-gate } 757*7c478bd9Sstevel@tonic-gate 758*7c478bd9Sstevel@tonic-gate while (k.dptr && isypsym(&k)) { 759*7c478bd9Sstevel@tonic-gate k = dbm_nextkey(fdb); 760*7c478bd9Sstevel@tonic-gate } 761*7c478bd9Sstevel@tonic-gate 762*7c478bd9Sstevel@tonic-gate if (k.dptr == NULL) { 763*7c478bd9Sstevel@tonic-gate *status = YP_NOMORE; 764*7c478bd9Sstevel@tonic-gate return; 765*7c478bd9Sstevel@tonic-gate } 766*7c478bd9Sstevel@tonic-gate 767*7c478bd9Sstevel@tonic-gate *outkey = k; 768*7c478bd9Sstevel@tonic-gate 769*7c478bd9Sstevel@tonic-gate /* 770*7c478bd9Sstevel@tonic-gate * In N2L mode we must call a version of dbm_fetch() that either does 771*7c478bd9Sstevel@tonic-gate * or does not check for entry updates. In non N2L mode both of these 772*7c478bd9Sstevel@tonic-gate * will end up doing a normal dbm_fetch(). 773*7c478bd9Sstevel@tonic-gate */ 774*7c478bd9Sstevel@tonic-gate if (update) 775*7c478bd9Sstevel@tonic-gate *val = shim_dbm_fetch(fdb, k); 776*7c478bd9Sstevel@tonic-gate else 777*7c478bd9Sstevel@tonic-gate *val = shim_dbm_fetch_noupdate(fdb, k); 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate if (val->dptr != NULL) { 780*7c478bd9Sstevel@tonic-gate *status = YP_TRUE; 781*7c478bd9Sstevel@tonic-gate } else { 782*7c478bd9Sstevel@tonic-gate *status = (unsigned)YP_BADDB; 783*7c478bd9Sstevel@tonic-gate } 784*7c478bd9Sstevel@tonic-gate } 785*7c478bd9Sstevel@tonic-gate 786*7c478bd9Sstevel@tonic-gate /* 787*7c478bd9Sstevel@tonic-gate * Serializes a stream of struct ypresp_key_val's. This is used 788*7c478bd9Sstevel@tonic-gate * only by the ypserv side of the transaction. 789*7c478bd9Sstevel@tonic-gate */ 790*7c478bd9Sstevel@tonic-gate static bool 791*7c478bd9Sstevel@tonic-gate xdrypserv_ypall(XDR *xdrs, struct ypreq_nokey *req) 792*7c478bd9Sstevel@tonic-gate { 793*7c478bd9Sstevel@tonic-gate bool_t more = TRUE; 794*7c478bd9Sstevel@tonic-gate struct ypresp_key_val resp; 795*7c478bd9Sstevel@tonic-gate DBM *fdb; 796*7c478bd9Sstevel@tonic-gate 797*7c478bd9Sstevel@tonic-gate resp.keydat.dptr = resp.valdat.dptr = (char *)NULL; 798*7c478bd9Sstevel@tonic-gate resp.keydat.dsize = resp.valdat.dsize = 0; 799*7c478bd9Sstevel@tonic-gate 800*7c478bd9Sstevel@tonic-gate if ((fdb = ypset_current_map(req->map, req->domain, 801*7c478bd9Sstevel@tonic-gate &resp.status)) != NULL) { 802*7c478bd9Sstevel@tonic-gate ypfilter(fdb, (datum *) NULL, &resp.keydat, &resp.valdat, 803*7c478bd9Sstevel@tonic-gate &resp.status, FALSE); 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate while (resp.status == YP_TRUE) { 806*7c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &more)) { 807*7c478bd9Sstevel@tonic-gate return (FALSE); 808*7c478bd9Sstevel@tonic-gate } 809*7c478bd9Sstevel@tonic-gate 810*7c478bd9Sstevel@tonic-gate if (!xdr_ypresp_key_val(xdrs, &resp)) { 811*7c478bd9Sstevel@tonic-gate return (FALSE); 812*7c478bd9Sstevel@tonic-gate } 813*7c478bd9Sstevel@tonic-gate 814*7c478bd9Sstevel@tonic-gate ypfilter(fdb, &resp.keydat, &resp.keydat, &resp.valdat, 815*7c478bd9Sstevel@tonic-gate &resp.status, FALSE); 816*7c478bd9Sstevel@tonic-gate } 817*7c478bd9Sstevel@tonic-gate } 818*7c478bd9Sstevel@tonic-gate 819*7c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &more)) { 820*7c478bd9Sstevel@tonic-gate return (FALSE); 821*7c478bd9Sstevel@tonic-gate } 822*7c478bd9Sstevel@tonic-gate 823*7c478bd9Sstevel@tonic-gate if (!xdr_ypresp_key_val(xdrs, &resp)) { 824*7c478bd9Sstevel@tonic-gate return (FALSE); 825*7c478bd9Sstevel@tonic-gate } 826*7c478bd9Sstevel@tonic-gate 827*7c478bd9Sstevel@tonic-gate more = FALSE; 828*7c478bd9Sstevel@tonic-gate 829*7c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &more)) { 830*7c478bd9Sstevel@tonic-gate return (FALSE); 831*7c478bd9Sstevel@tonic-gate } 832*7c478bd9Sstevel@tonic-gate 833*7c478bd9Sstevel@tonic-gate return (TRUE); 834*7c478bd9Sstevel@tonic-gate } 835*7c478bd9Sstevel@tonic-gate 836*7c478bd9Sstevel@tonic-gate /* 837*7c478bd9Sstevel@tonic-gate * Additions for sparc cluster support 838*7c478bd9Sstevel@tonic-gate */ 839*7c478bd9Sstevel@tonic-gate 840*7c478bd9Sstevel@tonic-gate /* 841*7c478bd9Sstevel@tonic-gate * Check for special multihomed host cookie in the key. If there, 842*7c478bd9Sstevel@tonic-gate * collect the addresses from the comma separated list and return 843*7c478bd9Sstevel@tonic-gate * the one that's nearest the client. 844*7c478bd9Sstevel@tonic-gate */ 845*7c478bd9Sstevel@tonic-gate static int 846*7c478bd9Sstevel@tonic-gate multihomed(struct ypreq_key req, struct ypresp_val *resp, 847*7c478bd9Sstevel@tonic-gate SVCXPRT *xprt, DBM *fdb) 848*7c478bd9Sstevel@tonic-gate { 849*7c478bd9Sstevel@tonic-gate char *cp, *bp; 850*7c478bd9Sstevel@tonic-gate ulong_t bestaddr, call_addr; 851*7c478bd9Sstevel@tonic-gate struct netbuf *nbuf; 852*7c478bd9Sstevel@tonic-gate char name[PATH_MAX]; 853*7c478bd9Sstevel@tonic-gate static char localbuf[_PBLKSIZ]; /* buffer for multihomed IPv6 addr */ 854*7c478bd9Sstevel@tonic-gate 855*7c478bd9Sstevel@tonic-gate if (strcmp(req.map, "hosts.byname") && 856*7c478bd9Sstevel@tonic-gate strcmp(req.map, "ipnodes.byname")) 857*7c478bd9Sstevel@tonic-gate /* default status is YP_NOKEY */ 858*7c478bd9Sstevel@tonic-gate return (0); 859*7c478bd9Sstevel@tonic-gate 860*7c478bd9Sstevel@tonic-gate if (strncmp(req.keydat.dptr, "YP_MULTI_", 9)) { 861*7c478bd9Sstevel@tonic-gate datum tmpname; 862*7c478bd9Sstevel@tonic-gate 863*7c478bd9Sstevel@tonic-gate strncpy(name, "YP_MULTI_", 9); 864*7c478bd9Sstevel@tonic-gate strncpy(name + 9, req.keydat.dptr, req.keydat.dsize); 865*7c478bd9Sstevel@tonic-gate tmpname.dsize = req.keydat.dsize + 9; 866*7c478bd9Sstevel@tonic-gate tmpname.dptr = name; 867*7c478bd9Sstevel@tonic-gate resp->valdat = dbm_fetch(fdb, tmpname); 868*7c478bd9Sstevel@tonic-gate } else { 869*7c478bd9Sstevel@tonic-gate /* 870*7c478bd9Sstevel@tonic-gate * Return whole line (for debugging) if YP_MULTI_hostnam 871*7c478bd9Sstevel@tonic-gate * is specified. 872*7c478bd9Sstevel@tonic-gate */ 873*7c478bd9Sstevel@tonic-gate resp->valdat = dbm_fetch(fdb, req.keydat); 874*7c478bd9Sstevel@tonic-gate if (resp->valdat.dptr != NULL) 875*7c478bd9Sstevel@tonic-gate return (1); 876*7c478bd9Sstevel@tonic-gate } 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate if (resp->valdat.dptr == NULL) 879*7c478bd9Sstevel@tonic-gate return (0); 880*7c478bd9Sstevel@tonic-gate 881*7c478bd9Sstevel@tonic-gate strncpy(name, req.keydat.dptr, req.keydat.dsize); 882*7c478bd9Sstevel@tonic-gate name[req.keydat.dsize] = NULL; 883*7c478bd9Sstevel@tonic-gate 884*7c478bd9Sstevel@tonic-gate if (strcmp(req.map, "ipnodes.byname") == 0) { 885*7c478bd9Sstevel@tonic-gate /* 886*7c478bd9Sstevel@tonic-gate * This section handles multihomed IPv6 addresses. 887*7c478bd9Sstevel@tonic-gate * It returns all the IPv6 addresses one per line and only 888*7c478bd9Sstevel@tonic-gate * the requested hostname is returned. NO aliases will be 889*7c478bd9Sstevel@tonic-gate * returned. This is done exactly the same way DNS forwarding 890*7c478bd9Sstevel@tonic-gate * daemon handles multihomed hosts. 891*7c478bd9Sstevel@tonic-gate * New IPv6 enabled clients should be able to handle this 892*7c478bd9Sstevel@tonic-gate * information returned. The sorting is also the client's 893*7c478bd9Sstevel@tonic-gate * responsibility. 894*7c478bd9Sstevel@tonic-gate */ 895*7c478bd9Sstevel@tonic-gate 896*7c478bd9Sstevel@tonic-gate char *buf, *endbuf; 897*7c478bd9Sstevel@tonic-gate 898*7c478bd9Sstevel@tonic-gate if ((buf = strdup(resp->valdat.dptr)) == NULL) /* no memory */ 899*7c478bd9Sstevel@tonic-gate return (0); 900*7c478bd9Sstevel@tonic-gate if ((bp = strtok(buf, " \t")) == NULL) { /* no address field */ 901*7c478bd9Sstevel@tonic-gate free(buf); 902*7c478bd9Sstevel@tonic-gate return (0); 903*7c478bd9Sstevel@tonic-gate } 904*7c478bd9Sstevel@tonic-gate if ((cp = strtok(NULL, "")) == NULL) { /* no host field */ 905*7c478bd9Sstevel@tonic-gate free(buf); 906*7c478bd9Sstevel@tonic-gate return (0); 907*7c478bd9Sstevel@tonic-gate } 908*7c478bd9Sstevel@tonic-gate if ((cp = strtok(bp, ",")) != NULL) { /* multihomed host */ 909*7c478bd9Sstevel@tonic-gate int bsize; 910*7c478bd9Sstevel@tonic-gate 911*7c478bd9Sstevel@tonic-gate localbuf[0] = '\0'; 912*7c478bd9Sstevel@tonic-gate bsize = sizeof (localbuf); 913*7c478bd9Sstevel@tonic-gate endbuf = localbuf; 914*7c478bd9Sstevel@tonic-gate 915*7c478bd9Sstevel@tonic-gate while (cp) { 916*7c478bd9Sstevel@tonic-gate if ((strlen(cp) + strlen(name)) >= bsize) { 917*7c478bd9Sstevel@tonic-gate /* out of range */ 918*7c478bd9Sstevel@tonic-gate break; 919*7c478bd9Sstevel@tonic-gate } 920*7c478bd9Sstevel@tonic-gate sprintf(endbuf, "%s %s\n", cp, name); 921*7c478bd9Sstevel@tonic-gate cp = strtok(NULL, ","); 922*7c478bd9Sstevel@tonic-gate endbuf = &endbuf[strlen(endbuf)]; 923*7c478bd9Sstevel@tonic-gate bsize = &localbuf[sizeof (localbuf)] - endbuf; 924*7c478bd9Sstevel@tonic-gate } 925*7c478bd9Sstevel@tonic-gate resp->valdat.dptr = localbuf; 926*7c478bd9Sstevel@tonic-gate resp->valdat.dsize = strlen(localbuf); 927*7c478bd9Sstevel@tonic-gate } 928*7c478bd9Sstevel@tonic-gate 929*7c478bd9Sstevel@tonic-gate free(buf); 930*7c478bd9Sstevel@tonic-gate /* remove trailing newline */ 931*7c478bd9Sstevel@tonic-gate if (resp->valdat.dsize && 932*7c478bd9Sstevel@tonic-gate resp->valdat.dptr[resp->valdat.dsize-1] == '\n') { 933*7c478bd9Sstevel@tonic-gate resp->valdat.dptr[resp->valdat.dsize-1] = '\0'; 934*7c478bd9Sstevel@tonic-gate resp->valdat.dsize -= 1; 935*7c478bd9Sstevel@tonic-gate } 936*7c478bd9Sstevel@tonic-gate 937*7c478bd9Sstevel@tonic-gate resp->status = YP_TRUE; 938*7c478bd9Sstevel@tonic-gate return (1); 939*7c478bd9Sstevel@tonic-gate } 940*7c478bd9Sstevel@tonic-gate nbuf = svc_getrpccaller(xprt); 941*7c478bd9Sstevel@tonic-gate /* 942*7c478bd9Sstevel@tonic-gate * OK, now I have a netbuf structure which I'm supposed to 943*7c478bd9Sstevel@tonic-gate * treat as opaque... I hate transport independance! 944*7c478bd9Sstevel@tonic-gate * So, we're just gonna doit wrong... By wrong I mean that 945*7c478bd9Sstevel@tonic-gate * we assume that the buf part of the netbuf structure is going 946*7c478bd9Sstevel@tonic-gate * to be a sockaddr_in. We'll then check the assumed family 947*7c478bd9Sstevel@tonic-gate * member and hope that we find AF_INET in there... if not 948*7c478bd9Sstevel@tonic-gate * then we can't continue. 949*7c478bd9Sstevel@tonic-gate */ 950*7c478bd9Sstevel@tonic-gate if (((struct sockaddr_in *)(nbuf->buf))->sin_family != AF_INET) 951*7c478bd9Sstevel@tonic-gate return (0); 952*7c478bd9Sstevel@tonic-gate 953*7c478bd9Sstevel@tonic-gate call_addr = ((struct sockaddr_in *)(nbuf->buf))->sin_addr.s_addr; 954*7c478bd9Sstevel@tonic-gate 955*7c478bd9Sstevel@tonic-gate cp = resp->valdat.dptr; 956*7c478bd9Sstevel@tonic-gate if ((bp = strtok(cp, " \t")) == NULL) /* no address field */ 957*7c478bd9Sstevel@tonic-gate return (0); 958*7c478bd9Sstevel@tonic-gate if ((cp = strtok(NULL, "")) == NULL) /* no host field */ 959*7c478bd9Sstevel@tonic-gate return (0); 960*7c478bd9Sstevel@tonic-gate bp = strtok(bp, ","); 961*7c478bd9Sstevel@tonic-gate 962*7c478bd9Sstevel@tonic-gate bestaddr = inet_addr(bp); 963*7c478bd9Sstevel@tonic-gate while (cp = strtok(NULL, ",")) { 964*7c478bd9Sstevel@tonic-gate ulong_t taddr; 965*7c478bd9Sstevel@tonic-gate 966*7c478bd9Sstevel@tonic-gate taddr = inet_addr(cp); 967*7c478bd9Sstevel@tonic-gate if (ntohl(call_addr ^ taddr) < ntohl(call_addr ^ bestaddr)) 968*7c478bd9Sstevel@tonic-gate bestaddr = taddr; 969*7c478bd9Sstevel@tonic-gate } 970*7c478bd9Sstevel@tonic-gate cp = resp->valdat.dptr; 971*7c478bd9Sstevel@tonic-gate sprintf(cp, "%s %s", inet_ntoa(*(struct in_addr *)&bestaddr), name); 972*7c478bd9Sstevel@tonic-gate resp->valdat.dsize = strlen(cp); 973*7c478bd9Sstevel@tonic-gate 974*7c478bd9Sstevel@tonic-gate resp->status = YP_TRUE; 975*7c478bd9Sstevel@tonic-gate 976*7c478bd9Sstevel@tonic-gate return (1); 977*7c478bd9Sstevel@tonic-gate } 978*7c478bd9Sstevel@tonic-gate 979*7c478bd9Sstevel@tonic-gate /* V1 dispatch routines */ 980*7c478bd9Sstevel@tonic-gate void 981*7c478bd9Sstevel@tonic-gate ypoldmatch(SVCXPRT *transp, struct svc_req *rqstp) 982*7c478bd9Sstevel@tonic-gate { 983*7c478bd9Sstevel@tonic-gate bool dbmop_ok = TRUE; 984*7c478bd9Sstevel@tonic-gate struct yprequest req; 985*7c478bd9Sstevel@tonic-gate struct ypreq_key nrq; 986*7c478bd9Sstevel@tonic-gate struct ypresponse resp; 987*7c478bd9Sstevel@tonic-gate char *fun = "ypoldmatch"; 988*7c478bd9Sstevel@tonic-gate DBM *fdb; 989*7c478bd9Sstevel@tonic-gate 990*7c478bd9Sstevel@tonic-gate memset((void *) &req, 0, sizeof (req)); 991*7c478bd9Sstevel@tonic-gate memset((void *) &resp, 0, sizeof (resp)); 992*7c478bd9Sstevel@tonic-gate 993*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 994*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 995*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 996*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 997*7c478bd9Sstevel@tonic-gate return; 998*7c478bd9Sstevel@tonic-gate } 999*7c478bd9Sstevel@tonic-gate 1000*7c478bd9Sstevel@tonic-gate if (req.yp_reqtype != YPMATCH_REQTYPE) { 1001*7c478bd9Sstevel@tonic-gate resp.ypmatch_resp_status = (unsigned)YP_BADARGS; 1002*7c478bd9Sstevel@tonic-gate dbmop_ok = FALSE; 1003*7c478bd9Sstevel@tonic-gate } 1004*7c478bd9Sstevel@tonic-gate 1005*7c478bd9Sstevel@tonic-gate if (dbmop_ok && 1006*7c478bd9Sstevel@tonic-gate (((fdb = ypset_current_map(req.ypmatch_req_map, 1007*7c478bd9Sstevel@tonic-gate req.ypmatch_req_domain, 1008*7c478bd9Sstevel@tonic-gate &resp.ypmatch_resp_status)) 1009*7c478bd9Sstevel@tonic-gate != NULL) && 1010*7c478bd9Sstevel@tonic-gate yp_map_access(transp, 1011*7c478bd9Sstevel@tonic-gate &resp.ypmatch_resp_status, 1012*7c478bd9Sstevel@tonic-gate fdb))) { 1013*7c478bd9Sstevel@tonic-gate 1014*7c478bd9Sstevel@tonic-gate /* Check with the DBM database */ 1015*7c478bd9Sstevel@tonic-gate resp.ypmatch_resp_valdat = dbm_fetch(fdb, 1016*7c478bd9Sstevel@tonic-gate req.ypmatch_req_keydat); 1017*7c478bd9Sstevel@tonic-gate 1018*7c478bd9Sstevel@tonic-gate if (resp.ypmatch_resp_valptr != NULL) { 1019*7c478bd9Sstevel@tonic-gate resp.ypmatch_resp_status = YP_TRUE; 1020*7c478bd9Sstevel@tonic-gate if (!silent) 1021*7c478bd9Sstevel@tonic-gate printf("%s: dbm: %s\n", 1022*7c478bd9Sstevel@tonic-gate fun, resp.ypmatch_resp_valptr); 1023*7c478bd9Sstevel@tonic-gate goto send_oldreply; 1024*7c478bd9Sstevel@tonic-gate } 1025*7c478bd9Sstevel@tonic-gate 1026*7c478bd9Sstevel@tonic-gate /* 1027*7c478bd9Sstevel@tonic-gate * If we're being asked to match YP_SECURE or YP_INTERDOMAIN 1028*7c478bd9Sstevel@tonic-gate * and we haven't found it in the dbm file, then we don't 1029*7c478bd9Sstevel@tonic-gate * really want to waste any more time. Specifically, we don't 1030*7c478bd9Sstevel@tonic-gate * want to ask DNS 1031*7c478bd9Sstevel@tonic-gate */ 1032*7c478bd9Sstevel@tonic-gate if (req.ypmatch_req_keysize == 0 || 1033*7c478bd9Sstevel@tonic-gate req.ypmatch_req_keyptr == NULL || 1034*7c478bd9Sstevel@tonic-gate req.ypmatch_req_keyptr[0] == '\0' || 1035*7c478bd9Sstevel@tonic-gate strncmp(req.ypmatch_req_keyptr, "YP_SECURE", 9) == 0 || 1036*7c478bd9Sstevel@tonic-gate strncmp(req.ypmatch_req_keyptr, "YP_INTERDOMAIN", 14) == 0) 1037*7c478bd9Sstevel@tonic-gate 1038*7c478bd9Sstevel@tonic-gate goto send_oldreply; 1039*7c478bd9Sstevel@tonic-gate 1040*7c478bd9Sstevel@tonic-gate /* Let's try the YP_MULTI_ hack... */ 1041*7c478bd9Sstevel@tonic-gate #ifdef MINUS_C_OPTION 1042*7c478bd9Sstevel@tonic-gate if (multiflag == TRUE && omultihomed(req, &resp, transp, fdb)) 1043*7c478bd9Sstevel@tonic-gate goto send_oldreply; 1044*7c478bd9Sstevel@tonic-gate #else 1045*7c478bd9Sstevel@tonic-gate if (omultihomed(req, &resp, transp, fdb)) 1046*7c478bd9Sstevel@tonic-gate goto send_oldreply; 1047*7c478bd9Sstevel@tonic-gate #endif 1048*7c478bd9Sstevel@tonic-gate 1049*7c478bd9Sstevel@tonic-gate /* Let's try DNS */ 1050*7c478bd9Sstevel@tonic-gate if (!dnsforward) { 1051*7c478bd9Sstevel@tonic-gate USE_YP_INTERDOMAIN 1052*7c478bd9Sstevel@tonic-gate datum idkey, idval; 1053*7c478bd9Sstevel@tonic-gate idkey.dptr = yp_interdomain; 1054*7c478bd9Sstevel@tonic-gate idkey.dsize = yp_interdomain_sz; 1055*7c478bd9Sstevel@tonic-gate idval = dbm_fetch(fdb, idkey); 1056*7c478bd9Sstevel@tonic-gate if (idval.dptr) 1057*7c478bd9Sstevel@tonic-gate dnsforward = TRUE; 1058*7c478bd9Sstevel@tonic-gate } 1059*7c478bd9Sstevel@tonic-gate 1060*7c478bd9Sstevel@tonic-gate if (dnsforward) { 1061*7c478bd9Sstevel@tonic-gate if (!resolv_pid) 1062*7c478bd9Sstevel@tonic-gate setup_resolv(&dnsforward, &resolv_pid, &resolv_client, 1063*7c478bd9Sstevel@tonic-gate resolv_tp, 0); 1064*7c478bd9Sstevel@tonic-gate 1065*7c478bd9Sstevel@tonic-gate if (req.yp_reqtype == YPREQ_KEY) { 1066*7c478bd9Sstevel@tonic-gate nrq = req.yp_reqbody.yp_req_keytype; 1067*7c478bd9Sstevel@tonic-gate 1068*7c478bd9Sstevel@tonic-gate resolv_req(&dnsforward, &resolv_client, &resolv_pid, 1069*7c478bd9Sstevel@tonic-gate resolv_tp, rqstp->rq_xprt, 1070*7c478bd9Sstevel@tonic-gate &nrq, nrq.map); 1071*7c478bd9Sstevel@tonic-gate } 1072*7c478bd9Sstevel@tonic-gate return; 1073*7c478bd9Sstevel@tonic-gate } 1074*7c478bd9Sstevel@tonic-gate } 1075*7c478bd9Sstevel@tonic-gate 1076*7c478bd9Sstevel@tonic-gate send_oldreply: 1077*7c478bd9Sstevel@tonic-gate 1078*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, 1079*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_ypresponse, 1080*7c478bd9Sstevel@tonic-gate (caddr_t)&resp)) { 1081*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 1082*7c478bd9Sstevel@tonic-gate } 1083*7c478bd9Sstevel@tonic-gate 1084*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 1085*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1086*7c478bd9Sstevel@tonic-gate (char *)&req)) { 1087*7c478bd9Sstevel@tonic-gate FREE_ERR; 1088*7c478bd9Sstevel@tonic-gate } 1089*7c478bd9Sstevel@tonic-gate } 1090*7c478bd9Sstevel@tonic-gate 1091*7c478bd9Sstevel@tonic-gate void 1092*7c478bd9Sstevel@tonic-gate ypoldfirst(SVCXPRT *transp) 1093*7c478bd9Sstevel@tonic-gate { 1094*7c478bd9Sstevel@tonic-gate bool dbmop_ok = TRUE; 1095*7c478bd9Sstevel@tonic-gate struct yprequest req; 1096*7c478bd9Sstevel@tonic-gate struct ypresponse resp; 1097*7c478bd9Sstevel@tonic-gate char *fun = "ypoldfirst"; 1098*7c478bd9Sstevel@tonic-gate DBM *fdb; 1099*7c478bd9Sstevel@tonic-gate 1100*7c478bd9Sstevel@tonic-gate memset((void *) &req, 0, sizeof (req)); 1101*7c478bd9Sstevel@tonic-gate memset((void *) &resp, 0, sizeof (resp)); 1102*7c478bd9Sstevel@tonic-gate 1103*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 1104*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1105*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 1106*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 1107*7c478bd9Sstevel@tonic-gate return; 1108*7c478bd9Sstevel@tonic-gate } 1109*7c478bd9Sstevel@tonic-gate 1110*7c478bd9Sstevel@tonic-gate if (req.yp_reqtype != YPFIRST_REQTYPE) { 1111*7c478bd9Sstevel@tonic-gate resp.ypfirst_resp_status = (unsigned)YP_BADARGS; 1112*7c478bd9Sstevel@tonic-gate dbmop_ok = FALSE; 1113*7c478bd9Sstevel@tonic-gate } 1114*7c478bd9Sstevel@tonic-gate 1115*7c478bd9Sstevel@tonic-gate if (dbmop_ok && 1116*7c478bd9Sstevel@tonic-gate ((fdb = ypset_current_map(req.ypfirst_req_map, 1117*7c478bd9Sstevel@tonic-gate req.ypfirst_req_domain, 1118*7c478bd9Sstevel@tonic-gate &resp.ypfirst_resp_status)) 1119*7c478bd9Sstevel@tonic-gate != NULL) && 1120*7c478bd9Sstevel@tonic-gate yp_map_access(transp, 1121*7c478bd9Sstevel@tonic-gate &resp.ypfirst_resp_status, 1122*7c478bd9Sstevel@tonic-gate fdb)) { 1123*7c478bd9Sstevel@tonic-gate 1124*7c478bd9Sstevel@tonic-gate resp.ypfirst_resp_keydat = dbm_firstkey(fdb); 1125*7c478bd9Sstevel@tonic-gate 1126*7c478bd9Sstevel@tonic-gate if (resp.ypfirst_resp_keyptr != NULL) { 1127*7c478bd9Sstevel@tonic-gate resp.ypfirst_resp_valdat = 1128*7c478bd9Sstevel@tonic-gate dbm_fetch(fdb, resp.ypfirst_resp_keydat); 1129*7c478bd9Sstevel@tonic-gate 1130*7c478bd9Sstevel@tonic-gate if (resp.ypfirst_resp_valptr != NULL) { 1131*7c478bd9Sstevel@tonic-gate resp.ypfirst_resp_status = YP_TRUE; 1132*7c478bd9Sstevel@tonic-gate } else { 1133*7c478bd9Sstevel@tonic-gate resp.ypfirst_resp_status = (unsigned)YP_BADDB; 1134*7c478bd9Sstevel@tonic-gate } 1135*7c478bd9Sstevel@tonic-gate } else { 1136*7c478bd9Sstevel@tonic-gate resp.ypfirst_resp_status = (unsigned)YP_NOKEY; 1137*7c478bd9Sstevel@tonic-gate } 1138*7c478bd9Sstevel@tonic-gate } 1139*7c478bd9Sstevel@tonic-gate 1140*7c478bd9Sstevel@tonic-gate resp.yp_resptype = YPFIRST_RESPTYPE; 1141*7c478bd9Sstevel@tonic-gate 1142*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, 1143*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_ypresponse, 1144*7c478bd9Sstevel@tonic-gate (caddr_t)&resp)) { 1145*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 1146*7c478bd9Sstevel@tonic-gate } 1147*7c478bd9Sstevel@tonic-gate 1148*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 1149*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1150*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 1151*7c478bd9Sstevel@tonic-gate FREE_ERR; 1152*7c478bd9Sstevel@tonic-gate } 1153*7c478bd9Sstevel@tonic-gate } 1154*7c478bd9Sstevel@tonic-gate 1155*7c478bd9Sstevel@tonic-gate void 1156*7c478bd9Sstevel@tonic-gate ypoldnext(SVCXPRT *transp) 1157*7c478bd9Sstevel@tonic-gate { 1158*7c478bd9Sstevel@tonic-gate bool dbmop_ok = TRUE; 1159*7c478bd9Sstevel@tonic-gate struct yprequest req; 1160*7c478bd9Sstevel@tonic-gate struct ypresponse resp; 1161*7c478bd9Sstevel@tonic-gate char *fun = "ypoldnext"; 1162*7c478bd9Sstevel@tonic-gate DBM *fdb; 1163*7c478bd9Sstevel@tonic-gate 1164*7c478bd9Sstevel@tonic-gate memset((void *) &req, 0, sizeof (req)); 1165*7c478bd9Sstevel@tonic-gate memset((void *) &resp, 0, sizeof (resp)); 1166*7c478bd9Sstevel@tonic-gate 1167*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 1168*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1169*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 1170*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 1171*7c478bd9Sstevel@tonic-gate return; 1172*7c478bd9Sstevel@tonic-gate } 1173*7c478bd9Sstevel@tonic-gate 1174*7c478bd9Sstevel@tonic-gate if (req.yp_reqtype != YPNEXT_REQTYPE) { 1175*7c478bd9Sstevel@tonic-gate resp.ypnext_resp_status = (unsigned)YP_BADARGS; 1176*7c478bd9Sstevel@tonic-gate dbmop_ok = FALSE; 1177*7c478bd9Sstevel@tonic-gate } 1178*7c478bd9Sstevel@tonic-gate 1179*7c478bd9Sstevel@tonic-gate if (dbmop_ok && 1180*7c478bd9Sstevel@tonic-gate ((fdb = ypset_current_map(req.ypnext_req_map, 1181*7c478bd9Sstevel@tonic-gate req.ypnext_req_domain, 1182*7c478bd9Sstevel@tonic-gate &resp.ypnext_resp_status)) != NULL && 1183*7c478bd9Sstevel@tonic-gate yp_map_access(transp, &resp.ypnext_resp_status, fdb))) { 1184*7c478bd9Sstevel@tonic-gate 1185*7c478bd9Sstevel@tonic-gate resp.ypnext_resp_keydat = dbm_nextkey(fdb); 1186*7c478bd9Sstevel@tonic-gate 1187*7c478bd9Sstevel@tonic-gate if (resp.ypnext_resp_keyptr != NULL) { 1188*7c478bd9Sstevel@tonic-gate resp.ypnext_resp_valdat = 1189*7c478bd9Sstevel@tonic-gate dbm_fetch(fdb, resp.ypnext_resp_keydat); 1190*7c478bd9Sstevel@tonic-gate 1191*7c478bd9Sstevel@tonic-gate if (resp.ypnext_resp_valptr != NULL) { 1192*7c478bd9Sstevel@tonic-gate resp.ypnext_resp_status = YP_TRUE; 1193*7c478bd9Sstevel@tonic-gate } else { 1194*7c478bd9Sstevel@tonic-gate resp.ypnext_resp_status = (unsigned)YP_BADDB; 1195*7c478bd9Sstevel@tonic-gate } 1196*7c478bd9Sstevel@tonic-gate } else { 1197*7c478bd9Sstevel@tonic-gate resp.ypnext_resp_status = (unsigned)YP_NOMORE; 1198*7c478bd9Sstevel@tonic-gate } 1199*7c478bd9Sstevel@tonic-gate } 1200*7c478bd9Sstevel@tonic-gate 1201*7c478bd9Sstevel@tonic-gate resp.yp_resptype = YPNEXT_RESPTYPE; 1202*7c478bd9Sstevel@tonic-gate 1203*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, 1204*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_ypresponse, 1205*7c478bd9Sstevel@tonic-gate (caddr_t)&resp)) { 1206*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 1207*7c478bd9Sstevel@tonic-gate } 1208*7c478bd9Sstevel@tonic-gate 1209*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 1210*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1211*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 1212*7c478bd9Sstevel@tonic-gate FREE_ERR; 1213*7c478bd9Sstevel@tonic-gate } 1214*7c478bd9Sstevel@tonic-gate } 1215*7c478bd9Sstevel@tonic-gate 1216*7c478bd9Sstevel@tonic-gate /* 1217*7c478bd9Sstevel@tonic-gate * This retrieves the order number and master peer name from the map. 1218*7c478bd9Sstevel@tonic-gate * The conditions for the various message fields are: domain is filled 1219*7c478bd9Sstevel@tonic-gate * in iff the domain exists. map is filled in iff the map exists. 1220*7c478bd9Sstevel@tonic-gate * order number is filled in iff it's in the map. owner is filled in 1221*7c478bd9Sstevel@tonic-gate * iff the master peer is in the map. 1222*7c478bd9Sstevel@tonic-gate */ 1223*7c478bd9Sstevel@tonic-gate void 1224*7c478bd9Sstevel@tonic-gate ypoldpoll(SVCXPRT *transp) 1225*7c478bd9Sstevel@tonic-gate { 1226*7c478bd9Sstevel@tonic-gate struct yprequest req; 1227*7c478bd9Sstevel@tonic-gate struct ypresponse resp; 1228*7c478bd9Sstevel@tonic-gate char *map = ""; 1229*7c478bd9Sstevel@tonic-gate char *domain = ""; 1230*7c478bd9Sstevel@tonic-gate char *owner = ""; 1231*7c478bd9Sstevel@tonic-gate uint_t error; 1232*7c478bd9Sstevel@tonic-gate char *fun = "ypoldpoll"; 1233*7c478bd9Sstevel@tonic-gate DBM *fdb; 1234*7c478bd9Sstevel@tonic-gate 1235*7c478bd9Sstevel@tonic-gate memset((void *) &req, 0, sizeof (req)); 1236*7c478bd9Sstevel@tonic-gate memset((void *) &resp, 0, sizeof (resp)); 1237*7c478bd9Sstevel@tonic-gate 1238*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 1239*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1240*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 1241*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 1242*7c478bd9Sstevel@tonic-gate return; 1243*7c478bd9Sstevel@tonic-gate } 1244*7c478bd9Sstevel@tonic-gate 1245*7c478bd9Sstevel@tonic-gate if (req.yp_reqtype == YPPOLL_REQTYPE) { 1246*7c478bd9Sstevel@tonic-gate if (strcmp(req.yppoll_req_domain, "yp_private") == 0 || 1247*7c478bd9Sstevel@tonic-gate strcmp(req.yppoll_req_map, "ypdomains") == 0 || 1248*7c478bd9Sstevel@tonic-gate strcmp(req.yppoll_req_map, "ypmaps") == 0) { 1249*7c478bd9Sstevel@tonic-gate 1250*7c478bd9Sstevel@tonic-gate /* 1251*7c478bd9Sstevel@tonic-gate * Backward comatibility for 2.0 NIS servers 1252*7c478bd9Sstevel@tonic-gate */ 1253*7c478bd9Sstevel@tonic-gate domain = req.yppoll_req_domain; 1254*7c478bd9Sstevel@tonic-gate map = req.yppoll_req_map; 1255*7c478bd9Sstevel@tonic-gate } else if ((fdb = ypset_current_map(req.yppoll_req_map, 1256*7c478bd9Sstevel@tonic-gate req.yppoll_req_domain, 1257*7c478bd9Sstevel@tonic-gate &error)) != NULL) { 1258*7c478bd9Sstevel@tonic-gate domain = req.yppoll_req_domain; 1259*7c478bd9Sstevel@tonic-gate map = req.yppoll_req_map; 1260*7c478bd9Sstevel@tonic-gate ypget_map_order(map, domain, 1261*7c478bd9Sstevel@tonic-gate &resp.yppoll_resp_ordernum); 1262*7c478bd9Sstevel@tonic-gate ypget_map_master(&owner, fdb); 1263*7c478bd9Sstevel@tonic-gate } else { 1264*7c478bd9Sstevel@tonic-gate switch ((int)error) { 1265*7c478bd9Sstevel@tonic-gate case YP_BADDB: 1266*7c478bd9Sstevel@tonic-gate map = req.yppoll_req_map; 1267*7c478bd9Sstevel@tonic-gate /* Fall through to set the domain too. */ 1268*7c478bd9Sstevel@tonic-gate 1269*7c478bd9Sstevel@tonic-gate case YP_NOMAP: 1270*7c478bd9Sstevel@tonic-gate domain = req.yppoll_req_domain; 1271*7c478bd9Sstevel@tonic-gate break; 1272*7c478bd9Sstevel@tonic-gate } 1273*7c478bd9Sstevel@tonic-gate } 1274*7c478bd9Sstevel@tonic-gate } 1275*7c478bd9Sstevel@tonic-gate 1276*7c478bd9Sstevel@tonic-gate resp.yp_resptype = YPPOLL_RESPTYPE; 1277*7c478bd9Sstevel@tonic-gate resp.yppoll_resp_domain = domain; 1278*7c478bd9Sstevel@tonic-gate resp.yppoll_resp_map = map; 1279*7c478bd9Sstevel@tonic-gate resp.yppoll_resp_owner = owner; 1280*7c478bd9Sstevel@tonic-gate 1281*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, 1282*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_ypresponse, 1283*7c478bd9Sstevel@tonic-gate (caddr_t)&resp)) { 1284*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 1285*7c478bd9Sstevel@tonic-gate } 1286*7c478bd9Sstevel@tonic-gate 1287*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 1288*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1289*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 1290*7c478bd9Sstevel@tonic-gate FREE_ERR; 1291*7c478bd9Sstevel@tonic-gate } 1292*7c478bd9Sstevel@tonic-gate } 1293*7c478bd9Sstevel@tonic-gate 1294*7c478bd9Sstevel@tonic-gate void 1295*7c478bd9Sstevel@tonic-gate ypoldpush(SVCXPRT *transp) 1296*7c478bd9Sstevel@tonic-gate { 1297*7c478bd9Sstevel@tonic-gate struct yprequest req; 1298*7c478bd9Sstevel@tonic-gate struct ypresp_val resp; 1299*7c478bd9Sstevel@tonic-gate pid_t pid = -1; 1300*7c478bd9Sstevel@tonic-gate char *fun = "ypoldpush"; 1301*7c478bd9Sstevel@tonic-gate DBM *fdb; 1302*7c478bd9Sstevel@tonic-gate 1303*7c478bd9Sstevel@tonic-gate memset((void *) &req, 0, sizeof (req)); 1304*7c478bd9Sstevel@tonic-gate 1305*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 1306*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1307*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 1308*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 1309*7c478bd9Sstevel@tonic-gate return; 1310*7c478bd9Sstevel@tonic-gate } 1311*7c478bd9Sstevel@tonic-gate 1312*7c478bd9Sstevel@tonic-gate if (((fdb = ypset_current_map(req.yppush_req_map, 1313*7c478bd9Sstevel@tonic-gate req.yppush_req_domain, 1314*7c478bd9Sstevel@tonic-gate &resp.status)) != NULL) && 1315*7c478bd9Sstevel@tonic-gate (yp_map_access(transp, &resp.status, fdb))) { 1316*7c478bd9Sstevel@tonic-gate 1317*7c478bd9Sstevel@tonic-gate pid = vfork(); 1318*7c478bd9Sstevel@tonic-gate } 1319*7c478bd9Sstevel@tonic-gate 1320*7c478bd9Sstevel@tonic-gate if (pid == -1) { 1321*7c478bd9Sstevel@tonic-gate FORK_ERR; 1322*7c478bd9Sstevel@tonic-gate } else if (pid == 0) { 1323*7c478bd9Sstevel@tonic-gate ypclr_current_map(); 1324*7c478bd9Sstevel@tonic-gate 1325*7c478bd9Sstevel@tonic-gate if (execl(yppush_proc, "yppush", "-d", req.yppush_req_domain, 1326*7c478bd9Sstevel@tonic-gate req.yppush_req_map, NULL)) { 1327*7c478bd9Sstevel@tonic-gate EXEC_ERR; 1328*7c478bd9Sstevel@tonic-gate } 1329*7c478bd9Sstevel@tonic-gate _exit(1); 1330*7c478bd9Sstevel@tonic-gate } 1331*7c478bd9Sstevel@tonic-gate 1332*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, 1333*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_void, 1334*7c478bd9Sstevel@tonic-gate (caddr_t)NULL)) { 1335*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 1336*7c478bd9Sstevel@tonic-gate } 1337*7c478bd9Sstevel@tonic-gate 1338*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 1339*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1340*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 1341*7c478bd9Sstevel@tonic-gate FREE_ERR; 1342*7c478bd9Sstevel@tonic-gate } 1343*7c478bd9Sstevel@tonic-gate } 1344*7c478bd9Sstevel@tonic-gate 1345*7c478bd9Sstevel@tonic-gate void 1346*7c478bd9Sstevel@tonic-gate ypoldpull(SVCXPRT *transp) 1347*7c478bd9Sstevel@tonic-gate { 1348*7c478bd9Sstevel@tonic-gate struct yprequest req; 1349*7c478bd9Sstevel@tonic-gate struct ypresp_val resp; 1350*7c478bd9Sstevel@tonic-gate pid_t pid = -1; 1351*7c478bd9Sstevel@tonic-gate char *fun = "ypoldpull"; 1352*7c478bd9Sstevel@tonic-gate DBM *fdb; 1353*7c478bd9Sstevel@tonic-gate 1354*7c478bd9Sstevel@tonic-gate memset((void *) &req, 0, sizeof (req)); 1355*7c478bd9Sstevel@tonic-gate 1356*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 1357*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1358*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 1359*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 1360*7c478bd9Sstevel@tonic-gate return; 1361*7c478bd9Sstevel@tonic-gate } 1362*7c478bd9Sstevel@tonic-gate 1363*7c478bd9Sstevel@tonic-gate if (req.yp_reqtype == YPPULL_REQTYPE) { 1364*7c478bd9Sstevel@tonic-gate 1365*7c478bd9Sstevel@tonic-gate if (((fdb = ypset_current_map(req.yppull_req_map, 1366*7c478bd9Sstevel@tonic-gate req.yppull_req_domain, 1367*7c478bd9Sstevel@tonic-gate &resp.status)) == NULL) || 1368*7c478bd9Sstevel@tonic-gate (yp_map_access(transp, &resp.status, fdb))) { 1369*7c478bd9Sstevel@tonic-gate pid = vfork(); 1370*7c478bd9Sstevel@tonic-gate } 1371*7c478bd9Sstevel@tonic-gate 1372*7c478bd9Sstevel@tonic-gate if (pid == -1) { 1373*7c478bd9Sstevel@tonic-gate FORK_ERR; 1374*7c478bd9Sstevel@tonic-gate } else if (pid == 0) { 1375*7c478bd9Sstevel@tonic-gate ypclr_current_map(); 1376*7c478bd9Sstevel@tonic-gate 1377*7c478bd9Sstevel@tonic-gate if (execl(ypxfr_proc, "ypxfr", "-d", 1378*7c478bd9Sstevel@tonic-gate req.yppull_req_domain, 1379*7c478bd9Sstevel@tonic-gate req.yppull_req_map, NULL)) { 1380*7c478bd9Sstevel@tonic-gate EXEC_ERR; 1381*7c478bd9Sstevel@tonic-gate } 1382*7c478bd9Sstevel@tonic-gate _exit(1); 1383*7c478bd9Sstevel@tonic-gate } 1384*7c478bd9Sstevel@tonic-gate } 1385*7c478bd9Sstevel@tonic-gate 1386*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 1387*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1388*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 1389*7c478bd9Sstevel@tonic-gate FREE_ERR; 1390*7c478bd9Sstevel@tonic-gate } 1391*7c478bd9Sstevel@tonic-gate } 1392*7c478bd9Sstevel@tonic-gate 1393*7c478bd9Sstevel@tonic-gate void 1394*7c478bd9Sstevel@tonic-gate ypoldget(SVCXPRT *transp) 1395*7c478bd9Sstevel@tonic-gate { 1396*7c478bd9Sstevel@tonic-gate struct yprequest req; 1397*7c478bd9Sstevel@tonic-gate struct ypresp_val resp; 1398*7c478bd9Sstevel@tonic-gate pid_t pid = -1; 1399*7c478bd9Sstevel@tonic-gate char *fun = "ypoldget"; 1400*7c478bd9Sstevel@tonic-gate DBM *fdb; 1401*7c478bd9Sstevel@tonic-gate 1402*7c478bd9Sstevel@tonic-gate memset((void *) &req, 0, sizeof (req)); 1403*7c478bd9Sstevel@tonic-gate 1404*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, 1405*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1406*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 1407*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 1408*7c478bd9Sstevel@tonic-gate return; 1409*7c478bd9Sstevel@tonic-gate } 1410*7c478bd9Sstevel@tonic-gate 1411*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, xdr_void, 0)) { 1412*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 1413*7c478bd9Sstevel@tonic-gate } 1414*7c478bd9Sstevel@tonic-gate 1415*7c478bd9Sstevel@tonic-gate if (req.yp_reqtype == YPGET_REQTYPE) { 1416*7c478bd9Sstevel@tonic-gate 1417*7c478bd9Sstevel@tonic-gate if (((fdb = ypset_current_map(req.ypget_req_map, 1418*7c478bd9Sstevel@tonic-gate req.ypget_req_domain, 1419*7c478bd9Sstevel@tonic-gate &resp.status)) == NULL) || 1420*7c478bd9Sstevel@tonic-gate (yp_map_access(transp, &resp.status, fdb))) { 1421*7c478bd9Sstevel@tonic-gate 1422*7c478bd9Sstevel@tonic-gate pid = vfork(); 1423*7c478bd9Sstevel@tonic-gate } 1424*7c478bd9Sstevel@tonic-gate 1425*7c478bd9Sstevel@tonic-gate if (pid == -1) { 1426*7c478bd9Sstevel@tonic-gate FORK_ERR; 1427*7c478bd9Sstevel@tonic-gate } else if (pid == 0) { 1428*7c478bd9Sstevel@tonic-gate 1429*7c478bd9Sstevel@tonic-gate ypclr_current_map(); 1430*7c478bd9Sstevel@tonic-gate 1431*7c478bd9Sstevel@tonic-gate if (execl(ypxfr_proc, "ypxfr", "-d", 1432*7c478bd9Sstevel@tonic-gate req.ypget_req_domain, "-h", 1433*7c478bd9Sstevel@tonic-gate req.ypget_req_owner, 1434*7c478bd9Sstevel@tonic-gate req.ypget_req_map, NULL)) { 1435*7c478bd9Sstevel@tonic-gate 1436*7c478bd9Sstevel@tonic-gate EXEC_ERR; 1437*7c478bd9Sstevel@tonic-gate } 1438*7c478bd9Sstevel@tonic-gate _exit(1); 1439*7c478bd9Sstevel@tonic-gate } 1440*7c478bd9Sstevel@tonic-gate } 1441*7c478bd9Sstevel@tonic-gate 1442*7c478bd9Sstevel@tonic-gate if (!svc_freeargs(transp, 1443*7c478bd9Sstevel@tonic-gate (xdrproc_t)_xdr_yprequest, 1444*7c478bd9Sstevel@tonic-gate (caddr_t)&req)) { 1445*7c478bd9Sstevel@tonic-gate RESPOND_ERR; 1446*7c478bd9Sstevel@tonic-gate } 1447*7c478bd9Sstevel@tonic-gate } 1448*7c478bd9Sstevel@tonic-gate 1449*7c478bd9Sstevel@tonic-gate static int 1450*7c478bd9Sstevel@tonic-gate omultihomed(struct yprequest req, 1451*7c478bd9Sstevel@tonic-gate struct ypresponse *resp, SVCXPRT *xprt, DBM *fdb) 1452*7c478bd9Sstevel@tonic-gate { 1453*7c478bd9Sstevel@tonic-gate char *cp, *bp; 1454*7c478bd9Sstevel@tonic-gate char name[PATH_MAX]; 1455*7c478bd9Sstevel@tonic-gate struct netbuf *nbuf; 1456*7c478bd9Sstevel@tonic-gate ulong_t bestaddr, call_addr; 1457*7c478bd9Sstevel@tonic-gate 1458*7c478bd9Sstevel@tonic-gate if (strcmp(req.ypmatch_req_map, "hosts.byname")) 1459*7c478bd9Sstevel@tonic-gate return (0); 1460*7c478bd9Sstevel@tonic-gate 1461*7c478bd9Sstevel@tonic-gate if (strncmp(req.ypmatch_req_keyptr, "YP_MULTI_", 9)) { 1462*7c478bd9Sstevel@tonic-gate datum tmpname; 1463*7c478bd9Sstevel@tonic-gate 1464*7c478bd9Sstevel@tonic-gate strncpy(name, "YP_MULTI_", 9); 1465*7c478bd9Sstevel@tonic-gate strncpy(name + 9, req.ypmatch_req_keyptr, 1466*7c478bd9Sstevel@tonic-gate req.ypmatch_req_keysize); 1467*7c478bd9Sstevel@tonic-gate tmpname.dsize = req.ypmatch_req_keysize + 9; 1468*7c478bd9Sstevel@tonic-gate tmpname.dptr = name; 1469*7c478bd9Sstevel@tonic-gate resp->ypmatch_resp_valdat = dbm_fetch(fdb, tmpname); 1470*7c478bd9Sstevel@tonic-gate } else { 1471*7c478bd9Sstevel@tonic-gate resp->ypmatch_resp_valdat = 1472*7c478bd9Sstevel@tonic-gate dbm_fetch(fdb, req.ypmatch_req_keydat); 1473*7c478bd9Sstevel@tonic-gate if (resp->ypmatch_resp_valptr != NULL) 1474*7c478bd9Sstevel@tonic-gate return (1); 1475*7c478bd9Sstevel@tonic-gate } 1476*7c478bd9Sstevel@tonic-gate 1477*7c478bd9Sstevel@tonic-gate if (resp->ypmatch_resp_valptr == NULL) 1478*7c478bd9Sstevel@tonic-gate return (0); 1479*7c478bd9Sstevel@tonic-gate 1480*7c478bd9Sstevel@tonic-gate strncpy(name, req.ypmatch_req_keyptr, req.ypmatch_req_keysize); 1481*7c478bd9Sstevel@tonic-gate name[req.ypmatch_req_keysize] = NULL; 1482*7c478bd9Sstevel@tonic-gate 1483*7c478bd9Sstevel@tonic-gate nbuf = svc_getrpccaller(xprt); 1484*7c478bd9Sstevel@tonic-gate 1485*7c478bd9Sstevel@tonic-gate /* 1486*7c478bd9Sstevel@tonic-gate * OK, now I have a netbuf structure which I'm supposed to treat 1487*7c478bd9Sstevel@tonic-gate * as opaque... I hate transport independance! So, we're just 1488*7c478bd9Sstevel@tonic-gate * gonna doit wrong... By wrong I mean that we assume that the 1489*7c478bd9Sstevel@tonic-gate * buf part of the netbuf structure is going to be a sockaddr_in. 1490*7c478bd9Sstevel@tonic-gate * We'll then check the assumed family member and hope that we 1491*7c478bd9Sstevel@tonic-gate * find AF_INET in there... if not then we can't continue. 1492*7c478bd9Sstevel@tonic-gate */ 1493*7c478bd9Sstevel@tonic-gate if (((struct sockaddr_in *)(nbuf->buf))->sin_family != AF_INET) 1494*7c478bd9Sstevel@tonic-gate return (0); 1495*7c478bd9Sstevel@tonic-gate 1496*7c478bd9Sstevel@tonic-gate call_addr = ((struct sockaddr_in *)(nbuf->buf))->sin_addr.s_addr; 1497*7c478bd9Sstevel@tonic-gate 1498*7c478bd9Sstevel@tonic-gate cp = resp->ypmatch_resp_valptr; 1499*7c478bd9Sstevel@tonic-gate if ((bp = strtok(cp, "\t")) == NULL) /* No address field */ 1500*7c478bd9Sstevel@tonic-gate return (0); 1501*7c478bd9Sstevel@tonic-gate if ((cp = strtok(NULL, "")) == NULL) /* No host field */ 1502*7c478bd9Sstevel@tonic-gate return (0); 1503*7c478bd9Sstevel@tonic-gate bp = strtok(bp, ","); 1504*7c478bd9Sstevel@tonic-gate 1505*7c478bd9Sstevel@tonic-gate bestaddr = inet_addr(bp); 1506*7c478bd9Sstevel@tonic-gate while (cp = strtok(NULL, ",")) { 1507*7c478bd9Sstevel@tonic-gate ulong_t taddr; 1508*7c478bd9Sstevel@tonic-gate 1509*7c478bd9Sstevel@tonic-gate taddr = inet_addr(cp); 1510*7c478bd9Sstevel@tonic-gate if (ntohl(call_addr ^ taddr) < ntohl(call_addr ^ bestaddr)) 1511*7c478bd9Sstevel@tonic-gate bestaddr = taddr; 1512*7c478bd9Sstevel@tonic-gate } 1513*7c478bd9Sstevel@tonic-gate 1514*7c478bd9Sstevel@tonic-gate cp = resp->ypmatch_resp_valptr; 1515*7c478bd9Sstevel@tonic-gate sprintf(cp, "%s %s", inet_ntoa(*(struct in_addr *)&bestaddr), name); 1516*7c478bd9Sstevel@tonic-gate resp->ypmatch_resp_valsize = strlen(cp); 1517*7c478bd9Sstevel@tonic-gate 1518*7c478bd9Sstevel@tonic-gate resp->ypmatch_resp_status = YP_TRUE; 1519*7c478bd9Sstevel@tonic-gate 1520*7c478bd9Sstevel@tonic-gate return (1); 1521*7c478bd9Sstevel@tonic-gate } 1522