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 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 23*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 24*7c478bd9Sstevel@tonic-gate */ 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 31*7c478bd9Sstevel@tonic-gate * under license from the Regents of the University of 32*7c478bd9Sstevel@tonic-gate * 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 #include "mt.h" 38*7c478bd9Sstevel@tonic-gate #include "../rpc/rpc_mt.h" 39*7c478bd9Sstevel@tonic-gate #include <stdio.h> 40*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 41*7c478bd9Sstevel@tonic-gate #include <string.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 43*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 44*7c478bd9Sstevel@tonic-gate #include <rpc/trace.h> 45*7c478bd9Sstevel@tonic-gate #include <errno.h> 46*7c478bd9Sstevel@tonic-gate #include <unistd.h> 47*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 48*7c478bd9Sstevel@tonic-gate #include <netconfig.h> 49*7c478bd9Sstevel@tonic-gate #include <netdir.h> 50*7c478bd9Sstevel@tonic-gate #include <syslog.h> 51*7c478bd9Sstevel@tonic-gate #include "yp_b.h" 52*7c478bd9Sstevel@tonic-gate #include <rpcsvc/yp_prot.h> 53*7c478bd9Sstevel@tonic-gate #include <rpcsvc/ypclnt.h> 54*7c478bd9Sstevel@tonic-gate #include <sys/tiuser.h> 55*7c478bd9Sstevel@tonic-gate #include "nsl_stdio_prv.h" 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate #if defined(sparc) 58*7c478bd9Sstevel@tonic-gate #define _FSTAT _fstat 59*7c478bd9Sstevel@tonic-gate extern int _fstat(int, struct stat *); 60*7c478bd9Sstevel@tonic-gate #else /* !sparc */ 61*7c478bd9Sstevel@tonic-gate #define _FSTAT fstat 62*7c478bd9Sstevel@tonic-gate #endif /* sparc */ 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate #define BFSIZE (YPMAXDOMAIN + 32) /* size of binding file */ 66*7c478bd9Sstevel@tonic-gate int __ypipbufsize = 8192; /* size used for clnt_tli_create */ 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate /* This should match the one in ypbind.c */ 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate extern int getdomainname(char *, int); 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate static CLIENT *getclnt(rpcprog_t, rpcvers_t, struct netconfig *, int *); 73*7c478bd9Sstevel@tonic-gate static struct dom_binding *load_dom_binding(struct ypbind_resp *, char *, 74*7c478bd9Sstevel@tonic-gate int *); 75*7c478bd9Sstevel@tonic-gate static ypbind_resp *get_cached_domain(char *); 76*7c478bd9Sstevel@tonic-gate static int get_cached_transport(struct netconfig *, int, char *, int); 77*7c478bd9Sstevel@tonic-gate static int ypbind_running(int, int); 78*7c478bd9Sstevel@tonic-gate static void set_rdev(struct dom_binding *); 79*7c478bd9Sstevel@tonic-gate static int check_rdev(struct dom_binding *); 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate static char nullstring[] = ""; 82*7c478bd9Sstevel@tonic-gate /* 83*7c478bd9Sstevel@tonic-gate * Time parameters when talking to the ypbind and pmap processes 84*7c478bd9Sstevel@tonic-gate */ 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate #define YPSLEEPTIME 5 /* Time to sleep between tries */ 87*7c478bd9Sstevel@tonic-gate unsigned int _ypsleeptime = YPSLEEPTIME; 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate /* 90*7c478bd9Sstevel@tonic-gate * Time parameters when talking to the ypserv process 91*7c478bd9Sstevel@tonic-gate */ 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 94*7c478bd9Sstevel@tonic-gate #define YPTIMEOUT 120 /* Total seconds for timeout */ 95*7c478bd9Sstevel@tonic-gate #define YPINTER_TRY 60 /* Seconds between tries */ 96*7c478bd9Sstevel@tonic-gate #else 97*7c478bd9Sstevel@tonic-gate #define YPTIMEOUT 20 /* Total seconds for timeout */ 98*7c478bd9Sstevel@tonic-gate #define YPINTER_TRY 5 /* Seconds between tries */ 99*7c478bd9Sstevel@tonic-gate #endif 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate #define MAX_TRIES_FOR_NEW_YP 1 /* Number of times we'll try to */ 102*7c478bd9Sstevel@tonic-gate /* get a new YP server before */ 103*7c478bd9Sstevel@tonic-gate /* we'll settle for an old one. */ 104*7c478bd9Sstevel@tonic-gate struct timeval _ypserv_timeout = { 105*7c478bd9Sstevel@tonic-gate YPTIMEOUT, /* Seconds */ 106*7c478bd9Sstevel@tonic-gate 0 /* Microseconds */ 107*7c478bd9Sstevel@tonic-gate }; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate static mutex_t default_domain_lock = DEFAULTMUTEX; 110*7c478bd9Sstevel@tonic-gate static char *default_domain; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate /* 113*7c478bd9Sstevel@tonic-gate * The bound_domains_lock serializes all action in yp_unbind(), __yp_dobind(), 114*7c478bd9Sstevel@tonic-gate * newborn(), check_binding() and laod_dom_binding(), not just the direct 115*7c478bd9Sstevel@tonic-gate * manipulation of the bound_domains list. 116*7c478bd9Sstevel@tonic-gate * It also protects all of the fields within a domain binding except 117*7c478bd9Sstevel@tonic-gate * the server_name field (which is protected by the server_name_lock). 118*7c478bd9Sstevel@tonic-gate * A better implementation might try to serialize each domain separately, 119*7c478bd9Sstevel@tonic-gate * but normally we're only dealing with one domain (the default) anyway. 120*7c478bd9Sstevel@tonic-gate * To avoid one thread freeing a domain binding while another is using 121*7c478bd9Sstevel@tonic-gate * the binding, we maintain a reference count for each binding. The 122*7c478bd9Sstevel@tonic-gate * reference count is incremented in __yp_dobind. The thread calls 123*7c478bd9Sstevel@tonic-gate * __yp_rel_binding() when it has finished using the binding (which 124*7c478bd9Sstevel@tonic-gate * decrements the reference count). If the reference count is non-zero 125*7c478bd9Sstevel@tonic-gate * when a thread tries to free a binding, the need_free flag is set and 126*7c478bd9Sstevel@tonic-gate * the free is delayed. The __yp_rel_binding() routine checks the flag 127*7c478bd9Sstevel@tonic-gate * and calls the free routine if the flag is set and the reference 128*7c478bd9Sstevel@tonic-gate * count is zero. 129*7c478bd9Sstevel@tonic-gate */ 130*7c478bd9Sstevel@tonic-gate static mutex_t bound_domains_lock = DEFAULTMUTEX; 131*7c478bd9Sstevel@tonic-gate static struct dom_binding *bound_domains; /* List of bound domains */ 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate /* 135*7c478bd9Sstevel@tonic-gate * Must be called with bound_domains_lock held or with a dom_binding 136*7c478bd9Sstevel@tonic-gate * that cannot be referenced by another thread. 137*7c478bd9Sstevel@tonic-gate */ 138*7c478bd9Sstevel@tonic-gate void 139*7c478bd9Sstevel@tonic-gate free_dom_binding(p) 140*7c478bd9Sstevel@tonic-gate struct dom_binding *p; 141*7c478bd9Sstevel@tonic-gate { 142*7c478bd9Sstevel@tonic-gate if (p->ref_count != 0) { 143*7c478bd9Sstevel@tonic-gate p->need_free = 1; 144*7c478bd9Sstevel@tonic-gate return; 145*7c478bd9Sstevel@tonic-gate } 146*7c478bd9Sstevel@tonic-gate (void) check_rdev(p); 147*7c478bd9Sstevel@tonic-gate clnt_destroy(p->dom_client); 148*7c478bd9Sstevel@tonic-gate free(p->dom_domain); 149*7c478bd9Sstevel@tonic-gate free((char *)p); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate /* 153*7c478bd9Sstevel@tonic-gate * Attempts to find a dom_binding in the list at bound_domains having the 154*7c478bd9Sstevel@tonic-gate * domain name field equal to the passed domain name, and removes it if found. 155*7c478bd9Sstevel@tonic-gate * The domain-server binding will not exist after the call to this function. 156*7c478bd9Sstevel@tonic-gate * All resources associated with the binding will be freed. 157*7c478bd9Sstevel@tonic-gate * 158*7c478bd9Sstevel@tonic-gate * yp_unbind is MT-safe because it serializes on bound_domains_lock. 159*7c478bd9Sstevel@tonic-gate */ 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate static void 162*7c478bd9Sstevel@tonic-gate __yp_unbind_nolock(domain) 163*7c478bd9Sstevel@tonic-gate char *domain; 164*7c478bd9Sstevel@tonic-gate { 165*7c478bd9Sstevel@tonic-gate struct dom_binding *p; 166*7c478bd9Sstevel@tonic-gate struct dom_binding **prev; 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate if ((domain == NULL) || (strlen(domain) == 0)) { 169*7c478bd9Sstevel@tonic-gate return; 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate /* 173*7c478bd9Sstevel@tonic-gate * If we used a cache file to bind, then we will mark the 174*7c478bd9Sstevel@tonic-gate * cache bad. This will cause a subsequent call to __yp_dobind 175*7c478bd9Sstevel@tonic-gate * to ignore the cache and talk to ypbind. Otherwise, we 176*7c478bd9Sstevel@tonic-gate * have already gotten a binding by talking to ypbind and 177*7c478bd9Sstevel@tonic-gate * the binding is not good. 178*7c478bd9Sstevel@tonic-gate * 179*7c478bd9Sstevel@tonic-gate * An optimization could be to check to see if the cache 180*7c478bd9Sstevel@tonic-gate * file has changed (ypbind is pointing at a new server) and 181*7c478bd9Sstevel@tonic-gate * reload the binding from it. But that is too much work 182*7c478bd9Sstevel@tonic-gate * for now. 183*7c478bd9Sstevel@tonic-gate */ 184*7c478bd9Sstevel@tonic-gate for (prev = &bound_domains; (p = *prev) != 0; prev = &p->dom_pnext) { 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate if (strcmp(domain, p->dom_domain) == 0) { 187*7c478bd9Sstevel@tonic-gate if (!p->cache_bad) { 188*7c478bd9Sstevel@tonic-gate p->cache_bad = 1; 189*7c478bd9Sstevel@tonic-gate break; 190*7c478bd9Sstevel@tonic-gate } 191*7c478bd9Sstevel@tonic-gate *prev = p->dom_pnext; 192*7c478bd9Sstevel@tonic-gate free_dom_binding(p); 193*7c478bd9Sstevel@tonic-gate break; 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate void 201*7c478bd9Sstevel@tonic-gate yp_unbind(domain) 202*7c478bd9Sstevel@tonic-gate char *domain; 203*7c478bd9Sstevel@tonic-gate { 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate trace1(TR_yp_unbind, 0); 206*7c478bd9Sstevel@tonic-gate mutex_lock(&bound_domains_lock); 207*7c478bd9Sstevel@tonic-gate __yp_unbind_nolock(domain); 208*7c478bd9Sstevel@tonic-gate mutex_unlock(&bound_domains_lock); 209*7c478bd9Sstevel@tonic-gate trace1(TR_yp_unbind, 1); 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate /* 214*7c478bd9Sstevel@tonic-gate * This checks to see if this is a new process incarnation which has 215*7c478bd9Sstevel@tonic-gate * inherited bindings from a parent, and unbinds the world if so. 216*7c478bd9Sstevel@tonic-gate * 217*7c478bd9Sstevel@tonic-gate * MT-safe because it is only invoked from __yp_dobind(), which serializes 218*7c478bd9Sstevel@tonic-gate * all requests. 219*7c478bd9Sstevel@tonic-gate */ 220*7c478bd9Sstevel@tonic-gate static void 221*7c478bd9Sstevel@tonic-gate newborn() 222*7c478bd9Sstevel@tonic-gate { 223*7c478bd9Sstevel@tonic-gate static pid_t mypid; /* Cached to detect forks */ 224*7c478bd9Sstevel@tonic-gate pid_t testpid; 225*7c478bd9Sstevel@tonic-gate struct dom_binding *p, *q; 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate trace1(TR_newborn, 0); 228*7c478bd9Sstevel@tonic-gate if ((testpid = getpid()) != mypid) { 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate mypid = testpid; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate for (p = bound_domains; p != 0; p = q) { 233*7c478bd9Sstevel@tonic-gate q = p->dom_pnext; 234*7c478bd9Sstevel@tonic-gate free_dom_binding(p); 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate bound_domains = 0; 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate trace1(TR_newborn, 1); 239*7c478bd9Sstevel@tonic-gate } 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate /* 242*7c478bd9Sstevel@tonic-gate * This checks that the socket for a domain which has already been bound 243*7c478bd9Sstevel@tonic-gate * hasn't been closed or changed under us. If it has, unbind the domain 244*7c478bd9Sstevel@tonic-gate * without closing the socket, which may be in use by some higher level 245*7c478bd9Sstevel@tonic-gate * code. This returns TRUE and points the binding parameter at the found 246*7c478bd9Sstevel@tonic-gate * dom_binding if the binding is found and the socket looks OK, and FALSE 247*7c478bd9Sstevel@tonic-gate * otherwise. 248*7c478bd9Sstevel@tonic-gate * 249*7c478bd9Sstevel@tonic-gate * MT-safe because it is only invoked from __yp_dobind(), which serializes 250*7c478bd9Sstevel@tonic-gate * all requests. 251*7c478bd9Sstevel@tonic-gate */ 252*7c478bd9Sstevel@tonic-gate static bool 253*7c478bd9Sstevel@tonic-gate check_binding(domain, binding) 254*7c478bd9Sstevel@tonic-gate char *domain; 255*7c478bd9Sstevel@tonic-gate struct dom_binding **binding; 256*7c478bd9Sstevel@tonic-gate { 257*7c478bd9Sstevel@tonic-gate struct dom_binding *pdomb; 258*7c478bd9Sstevel@tonic-gate struct ypbind_resp *ypbind_resp; 259*7c478bd9Sstevel@tonic-gate int status; 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gate trace1(TR_check_binding, 0); 262*7c478bd9Sstevel@tonic-gate for (pdomb = bound_domains; pdomb != NULL; pdomb = pdomb->dom_pnext) { 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate if (strcmp(domain, pdomb->dom_domain) == 0) { 265*7c478bd9Sstevel@tonic-gate /* 266*7c478bd9Sstevel@tonic-gate * XXX How do we really make sure the udp connection hasn't 267*7c478bd9Sstevel@tonic-gate * changes under us ? If it happens and we can't detect it, 268*7c478bd9Sstevel@tonic-gate * the appliction is doomed ! 269*7c478bd9Sstevel@tonic-gate * POLICY: Let nobody do a yp_bind or __yp_dobind explicitly 270*7c478bd9Sstevel@tonic-gate * and forget to to yp_unbind it. All apps should go 271*7c478bd9Sstevel@tonic-gate * through the standard yp_match/first etc. functions. 272*7c478bd9Sstevel@tonic-gate */ 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate *binding = pdomb; 275*7c478bd9Sstevel@tonic-gate trace1(TR_check_binding, 1); 276*7c478bd9Sstevel@tonic-gate return (TRUE); 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate /* 281*7c478bd9Sstevel@tonic-gate * We check to see if we can do a quick bind to ypserv. 282*7c478bd9Sstevel@tonic-gate * If we can, then we load the binding (i.e., add it to our 283*7c478bd9Sstevel@tonic-gate * cache of bindings) and then return it. 284*7c478bd9Sstevel@tonic-gate */ 285*7c478bd9Sstevel@tonic-gate if ((ypbind_resp = get_cached_domain(domain)) != 0) { 286*7c478bd9Sstevel@tonic-gate pdomb = load_dom_binding(ypbind_resp, domain, &status); 287*7c478bd9Sstevel@tonic-gate if (pdomb == 0) { 288*7c478bd9Sstevel@tonic-gate trace1(TR_check_binding, 1); 289*7c478bd9Sstevel@tonic-gate return (FALSE); 290*7c478bd9Sstevel@tonic-gate } 291*7c478bd9Sstevel@tonic-gate *binding = pdomb; 292*7c478bd9Sstevel@tonic-gate trace1(TR_check_binding, 1); 293*7c478bd9Sstevel@tonic-gate return (TRUE); 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate trace1(TR_check_binding, 1); 296*7c478bd9Sstevel@tonic-gate return (FALSE); 297*7c478bd9Sstevel@tonic-gate } 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate /* 300*7c478bd9Sstevel@tonic-gate * This routine adds a binding for a particular server to our 301*7c478bd9Sstevel@tonic-gate * list of bound domains. We check to see if there is actually 302*7c478bd9Sstevel@tonic-gate * a yp server at the given address. If not, or if there is 303*7c478bd9Sstevel@tonic-gate * any other error, we return 0. We have to malloc the binding 304*7c478bd9Sstevel@tonic-gate * structure because that is what a call to ypbind returns and 305*7c478bd9Sstevel@tonic-gate * we are basically doing what a call to ypbind would do. 306*7c478bd9Sstevel@tonic-gate */ 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate #define SOCKADDR_SIZE (sizeof (struct sockaddr_in6)) 309*7c478bd9Sstevel@tonic-gate static int 310*7c478bd9Sstevel@tonic-gate __yp_add_binding_netid(char *domain, char *addr, char *netid) 311*7c478bd9Sstevel@tonic-gate { 312*7c478bd9Sstevel@tonic-gate struct netconfig *nconf = 0; 313*7c478bd9Sstevel@tonic-gate struct netbuf *svcaddr = 0; 314*7c478bd9Sstevel@tonic-gate struct ypbind_binding *binding = 0; 315*7c478bd9Sstevel@tonic-gate int status; 316*7c478bd9Sstevel@tonic-gate struct ypbind_resp resp; 317*7c478bd9Sstevel@tonic-gate struct dom_binding *pdomb; 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate nconf = getnetconfigent(netid); 320*7c478bd9Sstevel@tonic-gate if (nconf == 0) 321*7c478bd9Sstevel@tonic-gate goto err; 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate svcaddr = (struct netbuf *)malloc(sizeof (struct netbuf)); 324*7c478bd9Sstevel@tonic-gate if (svcaddr == 0) 325*7c478bd9Sstevel@tonic-gate goto err; 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate svcaddr->maxlen = SOCKADDR_SIZE; 328*7c478bd9Sstevel@tonic-gate svcaddr->buf = (char *)malloc(SOCKADDR_SIZE); 329*7c478bd9Sstevel@tonic-gate if (svcaddr->buf == 0) 330*7c478bd9Sstevel@tonic-gate goto err; 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate if (!rpcb_getaddr(YPPROG, YPVERS, nconf, svcaddr, addr)) 333*7c478bd9Sstevel@tonic-gate goto err; 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate binding = (struct ypbind_binding *) 336*7c478bd9Sstevel@tonic-gate malloc(sizeof (struct ypbind_binding)); 337*7c478bd9Sstevel@tonic-gate if (binding == 0) 338*7c478bd9Sstevel@tonic-gate goto err; 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate binding->ypbind_hi_vers = YPVERS; 341*7c478bd9Sstevel@tonic-gate binding->ypbind_lo_vers = YPVERS; 342*7c478bd9Sstevel@tonic-gate binding->ypbind_nconf = nconf; 343*7c478bd9Sstevel@tonic-gate binding->ypbind_svcaddr = svcaddr; 344*7c478bd9Sstevel@tonic-gate binding->ypbind_servername = (char *)strdup(addr); 345*7c478bd9Sstevel@tonic-gate if (binding->ypbind_servername == 0) 346*7c478bd9Sstevel@tonic-gate goto err; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate resp.ypbind_status = YPBIND_SUCC_VAL; 349*7c478bd9Sstevel@tonic-gate resp.ypbind_resp_u.ypbind_bindinfo = binding; 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate mutex_lock(&bound_domains_lock); 352*7c478bd9Sstevel@tonic-gate newborn(); 353*7c478bd9Sstevel@tonic-gate pdomb = load_dom_binding(&resp, domain, &status); 354*7c478bd9Sstevel@tonic-gate mutex_unlock(&bound_domains_lock); 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate return (pdomb != 0); 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate err: 359*7c478bd9Sstevel@tonic-gate if (nconf) 360*7c478bd9Sstevel@tonic-gate freenetconfigent(nconf); 361*7c478bd9Sstevel@tonic-gate if (svcaddr) { 362*7c478bd9Sstevel@tonic-gate if (svcaddr->buf) 363*7c478bd9Sstevel@tonic-gate free((void *)svcaddr->buf); 364*7c478bd9Sstevel@tonic-gate free((void *)svcaddr); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate if (binding) { 367*7c478bd9Sstevel@tonic-gate if (binding->ypbind_servername) 368*7c478bd9Sstevel@tonic-gate free(binding->ypbind_servername); 369*7c478bd9Sstevel@tonic-gate free(binding); 370*7c478bd9Sstevel@tonic-gate } 371*7c478bd9Sstevel@tonic-gate return (0); 372*7c478bd9Sstevel@tonic-gate } 373*7c478bd9Sstevel@tonic-gate 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate int 376*7c478bd9Sstevel@tonic-gate __yp_add_binding(char *domain, char *addr) { 377*7c478bd9Sstevel@tonic-gate 378*7c478bd9Sstevel@tonic-gate int ret = __yp_add_binding_netid(domain, addr, "udp6"); 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate if (ret == 0) 381*7c478bd9Sstevel@tonic-gate ret = __yp_add_binding_netid(domain, addr, "udp"); 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate return (ret); 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate /* 388*7c478bd9Sstevel@tonic-gate * This allocates some memory for a domain binding, initialize it, and 389*7c478bd9Sstevel@tonic-gate * returns a pointer to it. Based on the program version we ended up 390*7c478bd9Sstevel@tonic-gate * talking to ypbind with, fill out an opvector of appropriate protocol 391*7c478bd9Sstevel@tonic-gate * modules. 392*7c478bd9Sstevel@tonic-gate * 393*7c478bd9Sstevel@tonic-gate * MT-safe because it is only invoked from __yp_dobind(), which serializes 394*7c478bd9Sstevel@tonic-gate * all requests. 395*7c478bd9Sstevel@tonic-gate */ 396*7c478bd9Sstevel@tonic-gate static struct dom_binding * 397*7c478bd9Sstevel@tonic-gate load_dom_binding(ypbind_res, domain, err) 398*7c478bd9Sstevel@tonic-gate struct ypbind_resp *ypbind_res; 399*7c478bd9Sstevel@tonic-gate char *domain; 400*7c478bd9Sstevel@tonic-gate int *err; 401*7c478bd9Sstevel@tonic-gate { 402*7c478bd9Sstevel@tonic-gate int fd; 403*7c478bd9Sstevel@tonic-gate struct dom_binding *pdomb; 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate trace1(TR_load_dom_binding, 0); 406*7c478bd9Sstevel@tonic-gate pdomb = (struct dom_binding *)NULL; 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate if ((pdomb = (struct dom_binding *)malloc(sizeof (struct dom_binding))) 409*7c478bd9Sstevel@tonic-gate == NULL) { 410*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "load_dom_binding: malloc failure."); 411*7c478bd9Sstevel@tonic-gate *err = YPERR_RESRC; 412*7c478bd9Sstevel@tonic-gate trace1(TR_load_dom_binding, 1); 413*7c478bd9Sstevel@tonic-gate return (struct dom_binding *)(NULL); 414*7c478bd9Sstevel@tonic-gate } 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gate pdomb->dom_binding = ypbind_res->ypbind_resp_u.ypbind_bindinfo; 417*7c478bd9Sstevel@tonic-gate /* 418*7c478bd9Sstevel@tonic-gate * Open up a path to the server, which will remain active globally. 419*7c478bd9Sstevel@tonic-gate */ 420*7c478bd9Sstevel@tonic-gate pdomb->dom_client = clnt_tli_create(RPC_ANYFD, 421*7c478bd9Sstevel@tonic-gate pdomb->dom_binding->ypbind_nconf, 422*7c478bd9Sstevel@tonic-gate pdomb->dom_binding->ypbind_svcaddr, 423*7c478bd9Sstevel@tonic-gate YPPROG, YPVERS, __ypipbufsize, 424*7c478bd9Sstevel@tonic-gate __ypipbufsize); 425*7c478bd9Sstevel@tonic-gate if (pdomb->dom_client == NULL) { 426*7c478bd9Sstevel@tonic-gate clnt_pcreateerror("yp_bind: clnt_tli_create"); 427*7c478bd9Sstevel@tonic-gate free((char *)pdomb); 428*7c478bd9Sstevel@tonic-gate *err = YPERR_RPC; 429*7c478bd9Sstevel@tonic-gate trace1(TR_load_dom_binding, 1); 430*7c478bd9Sstevel@tonic-gate return (struct dom_binding *)(NULL); 431*7c478bd9Sstevel@tonic-gate } 432*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 433*7c478bd9Sstevel@tonic-gate (void) printf("yp_bind: clnt_tli_create suceeded\n"); 434*7c478bd9Sstevel@tonic-gate #endif 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate pdomb->dom_pnext = bound_domains; /* Link this to the list as */ 437*7c478bd9Sstevel@tonic-gate pdomb->dom_domain = malloc(strlen(domain)+(unsigned)1); 438*7c478bd9Sstevel@tonic-gate if (pdomb->dom_domain == NULL) { 439*7c478bd9Sstevel@tonic-gate clnt_destroy(pdomb->dom_client); 440*7c478bd9Sstevel@tonic-gate free((char *)pdomb); 441*7c478bd9Sstevel@tonic-gate *err = YPERR_RESRC; 442*7c478bd9Sstevel@tonic-gate trace1(TR_load_dom_binding, 1); 443*7c478bd9Sstevel@tonic-gate return (struct dom_binding *)(NULL); 444*7c478bd9Sstevel@tonic-gate } 445*7c478bd9Sstevel@tonic-gate /* 446*7c478bd9Sstevel@tonic-gate * We may not have loaded from a cache file, but we assume the 447*7c478bd9Sstevel@tonic-gate * cache is good until we find out otherwise. 448*7c478bd9Sstevel@tonic-gate */ 449*7c478bd9Sstevel@tonic-gate pdomb->cache_bad = 0; 450*7c478bd9Sstevel@tonic-gate set_rdev(pdomb); 451*7c478bd9Sstevel@tonic-gate if (clnt_control(pdomb->dom_client, CLGET_FD, (char *)&fd)) 452*7c478bd9Sstevel@tonic-gate _fcntl(fd, F_SETFD, 1); /* make it "close on exec" */ 453*7c478bd9Sstevel@tonic-gate 454*7c478bd9Sstevel@tonic-gate (void) strcpy(pdomb->dom_domain, domain); /* Remember the domain name */ 455*7c478bd9Sstevel@tonic-gate pdomb->ref_count = 0; 456*7c478bd9Sstevel@tonic-gate pdomb->need_free = 0; 457*7c478bd9Sstevel@tonic-gate mutex_init(&pdomb->server_name_lock, USYNC_THREAD, 0); 458*7c478bd9Sstevel@tonic-gate bound_domains = pdomb; /* ... the head entry */ 459*7c478bd9Sstevel@tonic-gate trace1(TR_load_dom_binding, 1); 460*7c478bd9Sstevel@tonic-gate return (pdomb); 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate /* 464*7c478bd9Sstevel@tonic-gate * XXX special code for handling C2 (passwd.adjunct) lookups when we need 465*7c478bd9Sstevel@tonic-gate * a reserved port. 466*7c478bd9Sstevel@tonic-gate */ 467*7c478bd9Sstevel@tonic-gate static int 468*7c478bd9Sstevel@tonic-gate tli_open_rsvdport(nconf) 469*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; /* netconfig structure */ 470*7c478bd9Sstevel@tonic-gate { 471*7c478bd9Sstevel@tonic-gate int fd; 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate trace1(TR_tli_open_rsvdport, 0); 474*7c478bd9Sstevel@tonic-gate if (nconf == (struct netconfig *)NULL) { 475*7c478bd9Sstevel@tonic-gate trace1(TR_tli_open_rsvdport, 1); 476*7c478bd9Sstevel@tonic-gate return (-1); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate fd = t_open(nconf->nc_device, O_RDWR, NULL); 480*7c478bd9Sstevel@tonic-gate if (fd == -1) { 481*7c478bd9Sstevel@tonic-gate trace1(TR_tli_open_rsvdport, 1); 482*7c478bd9Sstevel@tonic-gate return (-1); 483*7c478bd9Sstevel@tonic-gate } 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate if (netdir_options(nconf, ND_SET_RESERVEDPORT, fd, NULL) == -1) { 486*7c478bd9Sstevel@tonic-gate if (t_bind(fd, (struct t_bind *)NULL, 487*7c478bd9Sstevel@tonic-gate (struct t_bind *)NULL) == -1) { 488*7c478bd9Sstevel@tonic-gate (void) t_close(fd); 489*7c478bd9Sstevel@tonic-gate trace1(TR_tli_open_rsvdport, 1); 490*7c478bd9Sstevel@tonic-gate return (-1); 491*7c478bd9Sstevel@tonic-gate } 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate trace1(TR_tli_open_rsvdport, 1); 494*7c478bd9Sstevel@tonic-gate return (fd); 495*7c478bd9Sstevel@tonic-gate } 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate /* 498*7c478bd9Sstevel@tonic-gate * This allocates some memory for a domain binding, initialize it, and 499*7c478bd9Sstevel@tonic-gate * returns a pointer to it. Based on the program version we ended up 500*7c478bd9Sstevel@tonic-gate * talking to ypbind with, fill out an opvector of appropriate protocol 501*7c478bd9Sstevel@tonic-gate * modules. 502*7c478bd9Sstevel@tonic-gate * 503*7c478bd9Sstevel@tonic-gate * MT-safe because it is only invoked from __yp_dobind(), which serializes 504*7c478bd9Sstevel@tonic-gate * all requests. 505*7c478bd9Sstevel@tonic-gate * 506*7c478bd9Sstevel@tonic-gate * XXX special version for handling C2 (passwd.adjunct) lookups when we need 507*7c478bd9Sstevel@tonic-gate * a reserved port. 508*7c478bd9Sstevel@tonic-gate * 509*7c478bd9Sstevel@tonic-gate * Note that the binding is not cached. The caller has to free the binding 510*7c478bd9Sstevel@tonic-gate * using free_dom_binding(). 511*7c478bd9Sstevel@tonic-gate */ 512*7c478bd9Sstevel@tonic-gate static struct dom_binding * 513*7c478bd9Sstevel@tonic-gate load_dom_binding_rsvdport(dom_binding, domain, err) 514*7c478bd9Sstevel@tonic-gate struct ypbind_binding *dom_binding; 515*7c478bd9Sstevel@tonic-gate char *domain; 516*7c478bd9Sstevel@tonic-gate int *err; 517*7c478bd9Sstevel@tonic-gate { 518*7c478bd9Sstevel@tonic-gate struct dom_binding *pdomb; 519*7c478bd9Sstevel@tonic-gate int fd; 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate trace1(TR_load_dom_binding_rsvdport, 0); 522*7c478bd9Sstevel@tonic-gate pdomb = (struct dom_binding *)NULL; 523*7c478bd9Sstevel@tonic-gate 524*7c478bd9Sstevel@tonic-gate if ((pdomb = (struct dom_binding *)malloc(sizeof (struct dom_binding))) 525*7c478bd9Sstevel@tonic-gate == NULL) { 526*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 527*7c478bd9Sstevel@tonic-gate "load_dom_binding_rsvdport: malloc failure."); 528*7c478bd9Sstevel@tonic-gate *err = YPERR_RESRC; 529*7c478bd9Sstevel@tonic-gate trace1(TR_load_dom_binding_rsvdport, 1); 530*7c478bd9Sstevel@tonic-gate return ((struct dom_binding *)NULL); 531*7c478bd9Sstevel@tonic-gate } 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate pdomb->dom_binding = dom_binding; 534*7c478bd9Sstevel@tonic-gate /* 535*7c478bd9Sstevel@tonic-gate * Open up a path to the server, which will remain active globally. 536*7c478bd9Sstevel@tonic-gate */ 537*7c478bd9Sstevel@tonic-gate fd = tli_open_rsvdport(pdomb->dom_binding->ypbind_nconf); 538*7c478bd9Sstevel@tonic-gate if (fd < 0) { 539*7c478bd9Sstevel@tonic-gate clnt_pcreateerror("yp_bind: tli_open_rsvdport"); 540*7c478bd9Sstevel@tonic-gate free((char *)pdomb); 541*7c478bd9Sstevel@tonic-gate *err = YPERR_RPC; 542*7c478bd9Sstevel@tonic-gate trace1(TR_load_dom_binding_rsvdport, 1); 543*7c478bd9Sstevel@tonic-gate return ((struct dom_binding *)NULL); 544*7c478bd9Sstevel@tonic-gate } 545*7c478bd9Sstevel@tonic-gate pdomb->dom_client = clnt_tli_create(fd, 546*7c478bd9Sstevel@tonic-gate pdomb->dom_binding->ypbind_nconf, 547*7c478bd9Sstevel@tonic-gate pdomb->dom_binding->ypbind_svcaddr, 548*7c478bd9Sstevel@tonic-gate YPPROG, YPVERS, __ypipbufsize, 549*7c478bd9Sstevel@tonic-gate __ypipbufsize); 550*7c478bd9Sstevel@tonic-gate if (pdomb->dom_client == NULL) { 551*7c478bd9Sstevel@tonic-gate clnt_pcreateerror("yp_bind: clnt_tli_create"); 552*7c478bd9Sstevel@tonic-gate free((char *)pdomb); 553*7c478bd9Sstevel@tonic-gate *err = YPERR_RPC; 554*7c478bd9Sstevel@tonic-gate trace1(TR_load_dom_binding_rsvdport, 1); 555*7c478bd9Sstevel@tonic-gate return ((struct dom_binding *)NULL); 556*7c478bd9Sstevel@tonic-gate } 557*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 558*7c478bd9Sstevel@tonic-gate (void) printf("yp_bind: clnt_tli_create suceeded\n"); 559*7c478bd9Sstevel@tonic-gate #endif 560*7c478bd9Sstevel@tonic-gate (void) CLNT_CONTROL(pdomb->dom_client, CLSET_FD_CLOSE, (char *)NULL); 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate pdomb->dom_domain = malloc(strlen(domain)+(unsigned)1); 563*7c478bd9Sstevel@tonic-gate if (pdomb->dom_domain == NULL) { 564*7c478bd9Sstevel@tonic-gate clnt_destroy(pdomb->dom_client); 565*7c478bd9Sstevel@tonic-gate free((char *)pdomb); 566*7c478bd9Sstevel@tonic-gate *err = YPERR_RESRC; 567*7c478bd9Sstevel@tonic-gate trace1(TR_load_dom_binding_rsvdport, 1); 568*7c478bd9Sstevel@tonic-gate return (struct dom_binding *)(NULL); 569*7c478bd9Sstevel@tonic-gate } 570*7c478bd9Sstevel@tonic-gate 571*7c478bd9Sstevel@tonic-gate (void) strcpy(pdomb->dom_domain, domain); /* Remember the domain name */ 572*7c478bd9Sstevel@tonic-gate pdomb->ref_count = 0; 573*7c478bd9Sstevel@tonic-gate pdomb->need_free = 0; 574*7c478bd9Sstevel@tonic-gate set_rdev(pdomb); 575*7c478bd9Sstevel@tonic-gate mutex_init(&pdomb->server_name_lock, USYNC_THREAD, 0); 576*7c478bd9Sstevel@tonic-gate trace1(TR_load_dom_binding_rsvdport, 1); 577*7c478bd9Sstevel@tonic-gate return (pdomb); 578*7c478bd9Sstevel@tonic-gate } 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate /* 581*7c478bd9Sstevel@tonic-gate * Attempts to locate a yellow pages server that serves a passed domain. If 582*7c478bd9Sstevel@tonic-gate * one is found, an entry is created on the static list of domain-server pairs 583*7c478bd9Sstevel@tonic-gate * pointed to by cell bound_domains, a udp path to the server is created and 584*7c478bd9Sstevel@tonic-gate * the function returns 0. Otherwise, the function returns a defined errorcode 585*7c478bd9Sstevel@tonic-gate * YPERR_xxxx. 586*7c478bd9Sstevel@tonic-gate * 587*7c478bd9Sstevel@tonic-gate * MT-safe because it serializes on bound_domains_lock. 588*7c478bd9Sstevel@tonic-gate * 589*7c478bd9Sstevel@tonic-gate * If hardlookup is set then loop forever until success, else try 4 590*7c478bd9Sstevel@tonic-gate * times (each try is relatively short) max. 591*7c478bd9Sstevel@tonic-gate */ 592*7c478bd9Sstevel@tonic-gate int 593*7c478bd9Sstevel@tonic-gate __yp_dobind_cflookup( 594*7c478bd9Sstevel@tonic-gate char *domain, 595*7c478bd9Sstevel@tonic-gate struct dom_binding **binding, /* if result==0, ptr to dom_binding */ 596*7c478bd9Sstevel@tonic-gate int hardlookup) 597*7c478bd9Sstevel@tonic-gate 598*7c478bd9Sstevel@tonic-gate { 599*7c478bd9Sstevel@tonic-gate struct dom_binding *pdomb; /* Ptr to new domain binding */ 600*7c478bd9Sstevel@tonic-gate struct ypbind_resp *ypbind_resp; /* Response from local ypbinder */ 601*7c478bd9Sstevel@tonic-gate struct ypbind_domain ypbd; 602*7c478bd9Sstevel@tonic-gate int status, err = YPERR_DOMAIN; 603*7c478bd9Sstevel@tonic-gate int tries = 4; /* if not hardlookup, try 4 times max to bind */ 604*7c478bd9Sstevel@tonic-gate int first_try = 1; 605*7c478bd9Sstevel@tonic-gate CLIENT *tb = (CLIENT *)NULL; 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate trace1(TR___yp_dobind, 0); 608*7c478bd9Sstevel@tonic-gate if ((domain == NULL) ||(strlen(domain) == 0)) { 609*7c478bd9Sstevel@tonic-gate trace1(TR___yp_dobind, 1); 610*7c478bd9Sstevel@tonic-gate return (YPERR_BADARGS); 611*7c478bd9Sstevel@tonic-gate } 612*7c478bd9Sstevel@tonic-gate 613*7c478bd9Sstevel@tonic-gate mutex_lock(&bound_domains_lock); 614*7c478bd9Sstevel@tonic-gate /* 615*7c478bd9Sstevel@tonic-gate * ===> 616*7c478bd9Sstevel@tonic-gate * If someone managed to fork() while we were holding this lock, 617*7c478bd9Sstevel@tonic-gate * we'll probably end up hanging on the lock. Tant pis. 618*7c478bd9Sstevel@tonic-gate */ 619*7c478bd9Sstevel@tonic-gate newborn(); 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate if (check_binding(domain, binding)) { 622*7c478bd9Sstevel@tonic-gate /* 623*7c478bd9Sstevel@tonic-gate * If the cache is okay and if the underlying file 624*7c478bd9Sstevel@tonic-gate * descriptor is okay (application did not close it). 625*7c478bd9Sstevel@tonic-gate * then use the binding. 626*7c478bd9Sstevel@tonic-gate */ 627*7c478bd9Sstevel@tonic-gate if (!(*binding)->cache_bad && check_rdev(*binding)) { 628*7c478bd9Sstevel@tonic-gate (*binding)->ref_count += 1; 629*7c478bd9Sstevel@tonic-gate mutex_unlock(&bound_domains_lock); 630*7c478bd9Sstevel@tonic-gate trace1(TR___yp_dobind, 1); 631*7c478bd9Sstevel@tonic-gate return (0); /* We are bound */ 632*7c478bd9Sstevel@tonic-gate } 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate /* 635*7c478bd9Sstevel@tonic-gate * If we get here, one of two things happened: the 636*7c478bd9Sstevel@tonic-gate * cache is bad, or the underlying file descriptor 637*7c478bd9Sstevel@tonic-gate * had changed. 638*7c478bd9Sstevel@tonic-gate * 639*7c478bd9Sstevel@tonic-gate * If the cache is bad, then we call yp_unbind to remove 640*7c478bd9Sstevel@tonic-gate * the binding. 641*7c478bd9Sstevel@tonic-gate * 642*7c478bd9Sstevel@tonic-gate * If the file descriptor has changed, then we call 643*7c478bd9Sstevel@tonic-gate * yp_unbind to remove the binding (we set cache_bad 644*7c478bd9Sstevel@tonic-gate * to force yp_unbind to do the remove), and then 645*7c478bd9Sstevel@tonic-gate * call check_binding to reload the binding from the 646*7c478bd9Sstevel@tonic-gate * cache again. 647*7c478bd9Sstevel@tonic-gate */ 648*7c478bd9Sstevel@tonic-gate if ((*binding)->cache_bad) { 649*7c478bd9Sstevel@tonic-gate __yp_unbind_nolock(domain); 650*7c478bd9Sstevel@tonic-gate } else { 651*7c478bd9Sstevel@tonic-gate (*binding)->cache_bad = 1; 652*7c478bd9Sstevel@tonic-gate mutex_unlock(&bound_domains_lock); 653*7c478bd9Sstevel@tonic-gate yp_unbind(domain); 654*7c478bd9Sstevel@tonic-gate mutex_lock(&bound_domains_lock); 655*7c478bd9Sstevel@tonic-gate if (check_binding(domain, binding)) { 656*7c478bd9Sstevel@tonic-gate (*binding)->ref_count += 1; 657*7c478bd9Sstevel@tonic-gate mutex_unlock(&bound_domains_lock); 658*7c478bd9Sstevel@tonic-gate trace1(TR___yp_dobind, 1); 659*7c478bd9Sstevel@tonic-gate return (0); 660*7c478bd9Sstevel@tonic-gate } 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate } 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate while (hardlookup ? 1 : tries--) { 665*7c478bd9Sstevel@tonic-gate if (first_try) 666*7c478bd9Sstevel@tonic-gate first_try = 0; 667*7c478bd9Sstevel@tonic-gate else { 668*7c478bd9Sstevel@tonic-gate /* 669*7c478bd9Sstevel@tonic-gate * ===> sleep() -- Ugh. And with the lock held, too. 670*7c478bd9Sstevel@tonic-gate */ 671*7c478bd9Sstevel@tonic-gate (void) sleep(_ypsleeptime); 672*7c478bd9Sstevel@tonic-gate } 673*7c478bd9Sstevel@tonic-gate tb = __clnt_create_loopback(YPBINDPROG, YPBINDVERS, &err); 674*7c478bd9Sstevel@tonic-gate if (tb == NULL) { 675*7c478bd9Sstevel@tonic-gate if (ypbind_running(err, rpc_createerr.cf_stat)) 676*7c478bd9Sstevel@tonic-gate continue; 677*7c478bd9Sstevel@tonic-gate break; 678*7c478bd9Sstevel@tonic-gate } 679*7c478bd9Sstevel@tonic-gate ypbd.ypbind_domainname = domain; 680*7c478bd9Sstevel@tonic-gate ypbd.ypbind_vers = YPVERS; 681*7c478bd9Sstevel@tonic-gate /* 682*7c478bd9Sstevel@tonic-gate * The interface to ypbindproc_domain_3 is MT-unsafe, but we're 683*7c478bd9Sstevel@tonic-gate * OK as long as we're the only ones who call it and we 684*7c478bd9Sstevel@tonic-gate * serialize all requests (for all domains). Otherwise, 685*7c478bd9Sstevel@tonic-gate * change the interface (pass in the ypbind_resp struct). 686*7c478bd9Sstevel@tonic-gate */ 687*7c478bd9Sstevel@tonic-gate ypbind_resp = ypbindproc_domain_3(&ypbd, tb); 688*7c478bd9Sstevel@tonic-gate /* 689*7c478bd9Sstevel@tonic-gate * Although we talk to ypbind on loopback, 690*7c478bd9Sstevel@tonic-gate * it gives us a udp address for the ypserv. 691*7c478bd9Sstevel@tonic-gate */ 692*7c478bd9Sstevel@tonic-gate if (ypbind_resp == NULL) { 693*7c478bd9Sstevel@tonic-gate /* lost ypbind? */ 694*7c478bd9Sstevel@tonic-gate clnt_perror(tb, 695*7c478bd9Sstevel@tonic-gate "ypbindproc_domain_3: can't contact ypbind"); 696*7c478bd9Sstevel@tonic-gate clnt_destroy(tb); 697*7c478bd9Sstevel@tonic-gate tb = (CLIENT *)NULL; 698*7c478bd9Sstevel@tonic-gate continue; 699*7c478bd9Sstevel@tonic-gate } 700*7c478bd9Sstevel@tonic-gate if (ypbind_resp->ypbind_status == YPBIND_SUCC_VAL) { 701*7c478bd9Sstevel@tonic-gate /* 702*7c478bd9Sstevel@tonic-gate * Local ypbind has let us in on the ypserv's address, 703*7c478bd9Sstevel@tonic-gate * go get in touch with it ! 704*7c478bd9Sstevel@tonic-gate */ 705*7c478bd9Sstevel@tonic-gate pdomb = load_dom_binding(ypbind_resp, domain, &status); 706*7c478bd9Sstevel@tonic-gate if (pdomb == 0) { 707*7c478bd9Sstevel@tonic-gate err = status; 708*7c478bd9Sstevel@tonic-gate clnt_destroy(tb); 709*7c478bd9Sstevel@tonic-gate tb = (CLIENT *)NULL; 710*7c478bd9Sstevel@tonic-gate continue; 711*7c478bd9Sstevel@tonic-gate } 712*7c478bd9Sstevel@tonic-gate clnt_destroy(tb); 713*7c478bd9Sstevel@tonic-gate pdomb->ref_count += 1; 714*7c478bd9Sstevel@tonic-gate mutex_unlock(&bound_domains_lock); 715*7c478bd9Sstevel@tonic-gate *binding = pdomb; /* Return ptr to the binding entry */ 716*7c478bd9Sstevel@tonic-gate trace1(TR___yp_dobind, 1); 717*7c478bd9Sstevel@tonic-gate return (0); /* This is the go path */ 718*7c478bd9Sstevel@tonic-gate } 719*7c478bd9Sstevel@tonic-gate if (ypbind_resp->ypbind_resp_u.ypbind_error == 720*7c478bd9Sstevel@tonic-gate YPBIND_ERR_NOSERV) 721*7c478bd9Sstevel@tonic-gate err = YPERR_DOMAIN; 722*7c478bd9Sstevel@tonic-gate else 723*7c478bd9Sstevel@tonic-gate err = YPERR_YPBIND; 724*7c478bd9Sstevel@tonic-gate clnt_destroy(tb); 725*7c478bd9Sstevel@tonic-gate tb = (CLIENT *)NULL; 726*7c478bd9Sstevel@tonic-gate } 727*7c478bd9Sstevel@tonic-gate if (tb != (CLIENT *)NULL) 728*7c478bd9Sstevel@tonic-gate clnt_destroy(tb); 729*7c478bd9Sstevel@tonic-gate mutex_unlock(&bound_domains_lock); 730*7c478bd9Sstevel@tonic-gate trace1(TR___yp_dobind, 1); 731*7c478bd9Sstevel@tonic-gate if (err) 732*7c478bd9Sstevel@tonic-gate return (err); 733*7c478bd9Sstevel@tonic-gate return (YPERR_DOMAIN); 734*7c478bd9Sstevel@tonic-gate } 735*7c478bd9Sstevel@tonic-gate 736*7c478bd9Sstevel@tonic-gate int 737*7c478bd9Sstevel@tonic-gate __yp_dobind( 738*7c478bd9Sstevel@tonic-gate char *domain, 739*7c478bd9Sstevel@tonic-gate struct dom_binding **binding) /* if result == 0, ptr to dom_binding */ 740*7c478bd9Sstevel@tonic-gate { 741*7c478bd9Sstevel@tonic-gate /* traditional __yp_dobind loops forever so set hardlookup */ 742*7c478bd9Sstevel@tonic-gate return (__yp_dobind_cflookup(domain, binding, 1)); 743*7c478bd9Sstevel@tonic-gate } 744*7c478bd9Sstevel@tonic-gate 745*7c478bd9Sstevel@tonic-gate void 746*7c478bd9Sstevel@tonic-gate __yp_rel_binding(binding) 747*7c478bd9Sstevel@tonic-gate struct dom_binding *binding; 748*7c478bd9Sstevel@tonic-gate { 749*7c478bd9Sstevel@tonic-gate mutex_lock(&bound_domains_lock); 750*7c478bd9Sstevel@tonic-gate binding->ref_count -= 1; 751*7c478bd9Sstevel@tonic-gate if (binding->need_free && binding->ref_count == 0) 752*7c478bd9Sstevel@tonic-gate free_dom_binding(binding); 753*7c478bd9Sstevel@tonic-gate mutex_unlock(&bound_domains_lock); 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate 756*7c478bd9Sstevel@tonic-gate /* 757*7c478bd9Sstevel@tonic-gate * Attempts to locate a yellow pages server that serves a passed domain. If 758*7c478bd9Sstevel@tonic-gate * one is found, an entry is created on the static list of domain-server pairs 759*7c478bd9Sstevel@tonic-gate * pointed to by cell bound_domains, a udp path to the server is created and 760*7c478bd9Sstevel@tonic-gate * the function returns 0. Otherwise, the function returns a defined errorcode 761*7c478bd9Sstevel@tonic-gate * YPERR_xxxx. 762*7c478bd9Sstevel@tonic-gate * 763*7c478bd9Sstevel@tonic-gate * MT-safe because it serializes on bound_domains_lock. 764*7c478bd9Sstevel@tonic-gate * 765*7c478bd9Sstevel@tonic-gate * XXX special version for handling C2 (passwd.adjunct) lookups when we need 766*7c478bd9Sstevel@tonic-gate * a reserved port. 767*7c478bd9Sstevel@tonic-gate * This returns an uncached binding which the caller has to free using 768*7c478bd9Sstevel@tonic-gate * free_dom_binding(). 769*7c478bd9Sstevel@tonic-gate */ 770*7c478bd9Sstevel@tonic-gate int 771*7c478bd9Sstevel@tonic-gate __yp_dobind_rsvdport_cflookup( 772*7c478bd9Sstevel@tonic-gate char *domain, 773*7c478bd9Sstevel@tonic-gate struct dom_binding **binding, /* if result==0, ptr to dom_binding */ 774*7c478bd9Sstevel@tonic-gate int hardlookup) 775*7c478bd9Sstevel@tonic-gate { 776*7c478bd9Sstevel@tonic-gate struct dom_binding *pdomb; /* Ptr to new domain binding */ 777*7c478bd9Sstevel@tonic-gate struct ypbind_resp *ypbind_resp; /* Response from local ypbinder */ 778*7c478bd9Sstevel@tonic-gate struct ypbind_domain ypbd; 779*7c478bd9Sstevel@tonic-gate int status, err = YPERR_DOMAIN; 780*7c478bd9Sstevel@tonic-gate int tries = 4; /* if not hardlookup, try a few times to bind */ 781*7c478bd9Sstevel@tonic-gate int first_try = 1; 782*7c478bd9Sstevel@tonic-gate CLIENT *tb = (CLIENT *)NULL; 783*7c478bd9Sstevel@tonic-gate 784*7c478bd9Sstevel@tonic-gate trace1(TR___yp_dobind_rsvdport, 0); 785*7c478bd9Sstevel@tonic-gate if ((domain == NULL) ||(strlen(domain) == 0)) { 786*7c478bd9Sstevel@tonic-gate trace1(TR___yp_dobind_rsvdport, 1); 787*7c478bd9Sstevel@tonic-gate return (YPERR_BADARGS); 788*7c478bd9Sstevel@tonic-gate } 789*7c478bd9Sstevel@tonic-gate 790*7c478bd9Sstevel@tonic-gate mutex_lock(&bound_domains_lock); 791*7c478bd9Sstevel@tonic-gate /* 792*7c478bd9Sstevel@tonic-gate * ===> 793*7c478bd9Sstevel@tonic-gate * If someone managed to fork() while we were holding this lock, 794*7c478bd9Sstevel@tonic-gate * we'll probably end up hanging on the lock. Tant pis. 795*7c478bd9Sstevel@tonic-gate */ 796*7c478bd9Sstevel@tonic-gate newborn(); 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate /* 799*7c478bd9Sstevel@tonic-gate * Check for existing bindings and use the information in the binding 800*7c478bd9Sstevel@tonic-gate * to create a transport endpoint with a reserved port. 801*7c478bd9Sstevel@tonic-gate */ 802*7c478bd9Sstevel@tonic-gate if (check_binding(domain, binding)) { 803*7c478bd9Sstevel@tonic-gate /* 804*7c478bd9Sstevel@tonic-gate * If the cache is bad, yp_unbind() the entry again and then 805*7c478bd9Sstevel@tonic-gate * talk to ypbind. 806*7c478bd9Sstevel@tonic-gate */ 807*7c478bd9Sstevel@tonic-gate if ((*binding)->cache_bad) { 808*7c478bd9Sstevel@tonic-gate __yp_unbind_nolock(domain); 809*7c478bd9Sstevel@tonic-gate } else { 810*7c478bd9Sstevel@tonic-gate pdomb = load_dom_binding_rsvdport( 811*7c478bd9Sstevel@tonic-gate (*binding)->dom_binding, 812*7c478bd9Sstevel@tonic-gate domain, &status); 813*7c478bd9Sstevel@tonic-gate if (pdomb == 0) { 814*7c478bd9Sstevel@tonic-gate mutex_unlock(&bound_domains_lock); 815*7c478bd9Sstevel@tonic-gate trace1(TR___yp_dobind_rsvdport, 1); 816*7c478bd9Sstevel@tonic-gate return (status); 817*7c478bd9Sstevel@tonic-gate } 818*7c478bd9Sstevel@tonic-gate pdomb->ref_count += 1; 819*7c478bd9Sstevel@tonic-gate mutex_unlock(&bound_domains_lock); 820*7c478bd9Sstevel@tonic-gate *binding = pdomb; /* Return ptr to the binding entry */ 821*7c478bd9Sstevel@tonic-gate trace1(TR___yp_dobind_rsvdport, 1); 822*7c478bd9Sstevel@tonic-gate return (0); 823*7c478bd9Sstevel@tonic-gate } 824*7c478bd9Sstevel@tonic-gate } 825*7c478bd9Sstevel@tonic-gate 826*7c478bd9Sstevel@tonic-gate while (hardlookup ? 1 : tries--) { 827*7c478bd9Sstevel@tonic-gate if (first_try) 828*7c478bd9Sstevel@tonic-gate first_try = 0; 829*7c478bd9Sstevel@tonic-gate else { 830*7c478bd9Sstevel@tonic-gate /* 831*7c478bd9Sstevel@tonic-gate * ===> sleep() -- Ugh. And with the lock held, too. 832*7c478bd9Sstevel@tonic-gate */ 833*7c478bd9Sstevel@tonic-gate (void) sleep(_ypsleeptime*tries); 834*7c478bd9Sstevel@tonic-gate } 835*7c478bd9Sstevel@tonic-gate tb = __clnt_create_loopback(YPBINDPROG, YPBINDVERS, &err); 836*7c478bd9Sstevel@tonic-gate if (tb == NULL) { 837*7c478bd9Sstevel@tonic-gate if (ypbind_running(err, rpc_createerr.cf_stat)) 838*7c478bd9Sstevel@tonic-gate continue; 839*7c478bd9Sstevel@tonic-gate break; 840*7c478bd9Sstevel@tonic-gate } 841*7c478bd9Sstevel@tonic-gate ypbd.ypbind_domainname = domain; 842*7c478bd9Sstevel@tonic-gate ypbd.ypbind_vers = YPVERS; 843*7c478bd9Sstevel@tonic-gate /* 844*7c478bd9Sstevel@tonic-gate * The interface to ypbindproc_domain_3 is MT-unsafe, but we're 845*7c478bd9Sstevel@tonic-gate * OK as long as we're the only ones who call it and we 846*7c478bd9Sstevel@tonic-gate * serialize all requests (for all domains). Otherwise, 847*7c478bd9Sstevel@tonic-gate * change the interface (pass in the ypbind_resp struct). 848*7c478bd9Sstevel@tonic-gate */ 849*7c478bd9Sstevel@tonic-gate ypbind_resp = ypbindproc_domain_3(&ypbd, tb); 850*7c478bd9Sstevel@tonic-gate /* 851*7c478bd9Sstevel@tonic-gate * Although we talk to ypbind on loopback, 852*7c478bd9Sstevel@tonic-gate * it gives us a udp address for the ypserv. 853*7c478bd9Sstevel@tonic-gate */ 854*7c478bd9Sstevel@tonic-gate if (ypbind_resp == NULL) { 855*7c478bd9Sstevel@tonic-gate /* lost ypbind? */ 856*7c478bd9Sstevel@tonic-gate clnt_perror(tb, 857*7c478bd9Sstevel@tonic-gate "ypbindproc_domain_3: can't contact ypbind"); 858*7c478bd9Sstevel@tonic-gate clnt_destroy(tb); 859*7c478bd9Sstevel@tonic-gate tb = (CLIENT *)NULL; 860*7c478bd9Sstevel@tonic-gate continue; 861*7c478bd9Sstevel@tonic-gate } 862*7c478bd9Sstevel@tonic-gate if (ypbind_resp->ypbind_status == YPBIND_SUCC_VAL) { 863*7c478bd9Sstevel@tonic-gate /* 864*7c478bd9Sstevel@tonic-gate * Local ypbind has let us in on the ypserv's address, 865*7c478bd9Sstevel@tonic-gate * go get in touch with it ! 866*7c478bd9Sstevel@tonic-gate */ 867*7c478bd9Sstevel@tonic-gate pdomb = load_dom_binding_rsvdport( 868*7c478bd9Sstevel@tonic-gate ypbind_resp->ypbind_resp_u.ypbind_bindinfo, 869*7c478bd9Sstevel@tonic-gate domain, &status); 870*7c478bd9Sstevel@tonic-gate if (pdomb == 0) { 871*7c478bd9Sstevel@tonic-gate err = status; 872*7c478bd9Sstevel@tonic-gate clnt_destroy(tb); 873*7c478bd9Sstevel@tonic-gate tb = (CLIENT *)NULL; 874*7c478bd9Sstevel@tonic-gate continue; 875*7c478bd9Sstevel@tonic-gate } 876*7c478bd9Sstevel@tonic-gate clnt_destroy(tb); 877*7c478bd9Sstevel@tonic-gate pdomb->ref_count += 1; 878*7c478bd9Sstevel@tonic-gate mutex_unlock(&bound_domains_lock); 879*7c478bd9Sstevel@tonic-gate *binding = pdomb; /* Return ptr to the binding entry */ 880*7c478bd9Sstevel@tonic-gate trace1(TR___yp_dobind_rsvdport, 1); 881*7c478bd9Sstevel@tonic-gate return (0); /* This is the go path */ 882*7c478bd9Sstevel@tonic-gate } 883*7c478bd9Sstevel@tonic-gate if (ypbind_resp->ypbind_resp_u.ypbind_error == 884*7c478bd9Sstevel@tonic-gate YPBIND_ERR_NOSERV) 885*7c478bd9Sstevel@tonic-gate err = YPERR_DOMAIN; 886*7c478bd9Sstevel@tonic-gate else 887*7c478bd9Sstevel@tonic-gate err = YPERR_YPBIND; 888*7c478bd9Sstevel@tonic-gate clnt_destroy(tb); 889*7c478bd9Sstevel@tonic-gate tb = (CLIENT *)NULL; 890*7c478bd9Sstevel@tonic-gate } 891*7c478bd9Sstevel@tonic-gate if (tb != (CLIENT *)NULL) 892*7c478bd9Sstevel@tonic-gate clnt_destroy(tb); 893*7c478bd9Sstevel@tonic-gate mutex_unlock(&bound_domains_lock); 894*7c478bd9Sstevel@tonic-gate trace1(TR___yp_dobind_rsvdport, 1); 895*7c478bd9Sstevel@tonic-gate if (err) 896*7c478bd9Sstevel@tonic-gate return (err); 897*7c478bd9Sstevel@tonic-gate return (YPERR_DOMAIN); 898*7c478bd9Sstevel@tonic-gate } 899*7c478bd9Sstevel@tonic-gate 900*7c478bd9Sstevel@tonic-gate int 901*7c478bd9Sstevel@tonic-gate __yp_dobind_rsvdport( 902*7c478bd9Sstevel@tonic-gate char *domain, 903*7c478bd9Sstevel@tonic-gate struct dom_binding **binding) /* if result==0, ptr to dom_binding */ 904*7c478bd9Sstevel@tonic-gate { 905*7c478bd9Sstevel@tonic-gate /* traditional __yp_dobind_rsvdport loops forever so set hardlookup */ 906*7c478bd9Sstevel@tonic-gate return (__yp_dobind_rsvdport_cflookup(domain, binding, 1)); 907*7c478bd9Sstevel@tonic-gate } 908*7c478bd9Sstevel@tonic-gate 909*7c478bd9Sstevel@tonic-gate /* 910*7c478bd9Sstevel@tonic-gate * This is a "wrapper" function for __yp_dobind for vanilla user-level 911*7c478bd9Sstevel@tonic-gate * functions which neither know nor care about struct dom_bindings. 912*7c478bd9Sstevel@tonic-gate */ 913*7c478bd9Sstevel@tonic-gate int 914*7c478bd9Sstevel@tonic-gate yp_bind(domain) 915*7c478bd9Sstevel@tonic-gate char *domain; 916*7c478bd9Sstevel@tonic-gate { 917*7c478bd9Sstevel@tonic-gate 918*7c478bd9Sstevel@tonic-gate struct dom_binding *binding; 919*7c478bd9Sstevel@tonic-gate int dummy; 920*7c478bd9Sstevel@tonic-gate 921*7c478bd9Sstevel@tonic-gate trace1(TR_yp_bind, 0); 922*7c478bd9Sstevel@tonic-gate dummy = __yp_dobind(domain, &binding); 923*7c478bd9Sstevel@tonic-gate if (dummy == 0) 924*7c478bd9Sstevel@tonic-gate __yp_rel_binding(binding); 925*7c478bd9Sstevel@tonic-gate trace1(TR_yp_bind, 1); 926*7c478bd9Sstevel@tonic-gate 927*7c478bd9Sstevel@tonic-gate return (dummy); 928*7c478bd9Sstevel@tonic-gate } 929*7c478bd9Sstevel@tonic-gate 930*7c478bd9Sstevel@tonic-gate static char * 931*7c478bd9Sstevel@tonic-gate __default_domain() 932*7c478bd9Sstevel@tonic-gate { 933*7c478bd9Sstevel@tonic-gate char temp[256]; 934*7c478bd9Sstevel@tonic-gate 935*7c478bd9Sstevel@tonic-gate trace1(TR___default_domain, 0); 936*7c478bd9Sstevel@tonic-gate 937*7c478bd9Sstevel@tonic-gate mutex_lock(&default_domain_lock); 938*7c478bd9Sstevel@tonic-gate 939*7c478bd9Sstevel@tonic-gate if (default_domain) { 940*7c478bd9Sstevel@tonic-gate mutex_unlock(&default_domain_lock); 941*7c478bd9Sstevel@tonic-gate trace1(TR___default_domain, 1); 942*7c478bd9Sstevel@tonic-gate return (default_domain); 943*7c478bd9Sstevel@tonic-gate } 944*7c478bd9Sstevel@tonic-gate if (getdomainname(temp, sizeof (temp)) < 0) { 945*7c478bd9Sstevel@tonic-gate mutex_unlock(&default_domain_lock); 946*7c478bd9Sstevel@tonic-gate trace1(TR___default_domain, 1); 947*7c478bd9Sstevel@tonic-gate return (0); 948*7c478bd9Sstevel@tonic-gate } 949*7c478bd9Sstevel@tonic-gate if (strlen(temp) > 0) { 950*7c478bd9Sstevel@tonic-gate default_domain = (char *)malloc((strlen(temp) + 1)); 951*7c478bd9Sstevel@tonic-gate if (default_domain == 0) { 952*7c478bd9Sstevel@tonic-gate mutex_unlock(&default_domain_lock); 953*7c478bd9Sstevel@tonic-gate trace1(TR___default_domain, 1); 954*7c478bd9Sstevel@tonic-gate return (0); 955*7c478bd9Sstevel@tonic-gate } 956*7c478bd9Sstevel@tonic-gate (void) strcpy(default_domain, temp); 957*7c478bd9Sstevel@tonic-gate mutex_unlock(&default_domain_lock); 958*7c478bd9Sstevel@tonic-gate trace1(TR___default_domain, 1); 959*7c478bd9Sstevel@tonic-gate return (default_domain); 960*7c478bd9Sstevel@tonic-gate } 961*7c478bd9Sstevel@tonic-gate mutex_unlock(&default_domain_lock); 962*7c478bd9Sstevel@tonic-gate trace1(TR___default_domain, 1); 963*7c478bd9Sstevel@tonic-gate return (0); 964*7c478bd9Sstevel@tonic-gate } 965*7c478bd9Sstevel@tonic-gate 966*7c478bd9Sstevel@tonic-gate /* 967*7c478bd9Sstevel@tonic-gate * This is a wrapper for the system call getdomainname which returns a 968*7c478bd9Sstevel@tonic-gate * ypclnt.h error code in the failure case. It also checks to see that 969*7c478bd9Sstevel@tonic-gate * the domain name is non-null, knowing that the null string is going to 970*7c478bd9Sstevel@tonic-gate * get rejected elsewhere in the yp client package. 971*7c478bd9Sstevel@tonic-gate */ 972*7c478bd9Sstevel@tonic-gate int 973*7c478bd9Sstevel@tonic-gate yp_get_default_domain(domain) 974*7c478bd9Sstevel@tonic-gate char **domain; 975*7c478bd9Sstevel@tonic-gate { 976*7c478bd9Sstevel@tonic-gate trace1(TR_yp_get_default_domain, 0); 977*7c478bd9Sstevel@tonic-gate 978*7c478bd9Sstevel@tonic-gate if ((*domain = __default_domain()) != 0) { 979*7c478bd9Sstevel@tonic-gate trace1(TR_yp_get_default_domain, 1); 980*7c478bd9Sstevel@tonic-gate return (0); 981*7c478bd9Sstevel@tonic-gate } 982*7c478bd9Sstevel@tonic-gate trace1(TR_yp_get_default_domain, 1); 983*7c478bd9Sstevel@tonic-gate return (YPERR_YPERR); 984*7c478bd9Sstevel@tonic-gate } 985*7c478bd9Sstevel@tonic-gate 986*7c478bd9Sstevel@tonic-gate /* 987*7c478bd9Sstevel@tonic-gate * ===> Nobody uses this, do they? Can we nuke it? 988*7c478bd9Sstevel@tonic-gate */ 989*7c478bd9Sstevel@tonic-gate int 990*7c478bd9Sstevel@tonic-gate usingypmap(ddn, map) 991*7c478bd9Sstevel@tonic-gate char **ddn; /* the default domainname set by this routine */ 992*7c478bd9Sstevel@tonic-gate char *map; /* the map we are interested in. */ 993*7c478bd9Sstevel@tonic-gate { 994*7c478bd9Sstevel@tonic-gate char in, *outval = NULL; 995*7c478bd9Sstevel@tonic-gate int outvallen, stat; 996*7c478bd9Sstevel@tonic-gate char *domain; 997*7c478bd9Sstevel@tonic-gate 998*7c478bd9Sstevel@tonic-gate trace1(TR_usingypmap, 0); 999*7c478bd9Sstevel@tonic-gate if ((domain = __default_domain()) == 0) { 1000*7c478bd9Sstevel@tonic-gate trace1(TR_usingypmap, 1); 1001*7c478bd9Sstevel@tonic-gate return (FALSE); 1002*7c478bd9Sstevel@tonic-gate } 1003*7c478bd9Sstevel@tonic-gate *ddn = domain; 1004*7c478bd9Sstevel@tonic-gate /* does the map exist ? */ 1005*7c478bd9Sstevel@tonic-gate in = (char)0xff; 1006*7c478bd9Sstevel@tonic-gate stat = yp_match(domain, map, &in, 1, &outval, &outvallen); 1007*7c478bd9Sstevel@tonic-gate if (outval != NULL) 1008*7c478bd9Sstevel@tonic-gate free(outval); 1009*7c478bd9Sstevel@tonic-gate switch (stat) { 1010*7c478bd9Sstevel@tonic-gate 1011*7c478bd9Sstevel@tonic-gate case 0: /* it actually succeeded! */ 1012*7c478bd9Sstevel@tonic-gate case YPERR_KEY: /* no such key in map */ 1013*7c478bd9Sstevel@tonic-gate case YPERR_NOMORE: 1014*7c478bd9Sstevel@tonic-gate case YPERR_BUSY: 1015*7c478bd9Sstevel@tonic-gate trace1(TR_usingypmap, 1); 1016*7c478bd9Sstevel@tonic-gate return (TRUE); 1017*7c478bd9Sstevel@tonic-gate } 1018*7c478bd9Sstevel@tonic-gate trace1(TR_usingypmap, 1); 1019*7c478bd9Sstevel@tonic-gate return (FALSE); 1020*7c478bd9Sstevel@tonic-gate } 1021*7c478bd9Sstevel@tonic-gate 1022*7c478bd9Sstevel@tonic-gate /* 1023*7c478bd9Sstevel@tonic-gate * Creates a quick connection on a connection oriented loopback 1024*7c478bd9Sstevel@tonic-gate * transport. Fails quickly without timeout. Only naming service 1025*7c478bd9Sstevel@tonic-gate * it goes to is straddr.so. 1026*7c478bd9Sstevel@tonic-gate */ 1027*7c478bd9Sstevel@tonic-gate CLIENT * 1028*7c478bd9Sstevel@tonic-gate __clnt_create_loopback(prog, vers, err) 1029*7c478bd9Sstevel@tonic-gate rpcprog_t prog; /* program number */ 1030*7c478bd9Sstevel@tonic-gate rpcvers_t vers; /* version number */ 1031*7c478bd9Sstevel@tonic-gate int *err; /* return the YP sepcific error code */ 1032*7c478bd9Sstevel@tonic-gate { 1033*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 1034*7c478bd9Sstevel@tonic-gate CLIENT *clnt = NULL; 1035*7c478bd9Sstevel@tonic-gate void *nc_handle; /* Net config handle */ 1036*7c478bd9Sstevel@tonic-gate 1037*7c478bd9Sstevel@tonic-gate trace3(TR___clnt_create_loopback, 0, prog, vers); 1038*7c478bd9Sstevel@tonic-gate *err = 0; 1039*7c478bd9Sstevel@tonic-gate nc_handle = setnetconfig(); 1040*7c478bd9Sstevel@tonic-gate if (nc_handle == (void *) NULL) { 1041*7c478bd9Sstevel@tonic-gate /* fails to open netconfig file */ 1042*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_FAILED; 1043*7c478bd9Sstevel@tonic-gate *err = YPERR_RPC; 1044*7c478bd9Sstevel@tonic-gate trace1(TR___clnt_create_loopback, 1); 1045*7c478bd9Sstevel@tonic-gate return ((CLIENT *) NULL); 1046*7c478bd9Sstevel@tonic-gate } 1047*7c478bd9Sstevel@tonic-gate while (nconf = getnetconfig(nc_handle)) 1048*7c478bd9Sstevel@tonic-gate /* Try only one connection oriented loopback transport */ 1049*7c478bd9Sstevel@tonic-gate if ((strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) && 1050*7c478bd9Sstevel@tonic-gate ((nconf->nc_semantics == NC_TPI_COTS) || 1051*7c478bd9Sstevel@tonic-gate (nconf->nc_semantics == NC_TPI_COTS_ORD))) { 1052*7c478bd9Sstevel@tonic-gate clnt = getclnt(prog, vers, nconf, err); 1053*7c478bd9Sstevel@tonic-gate break; 1054*7c478bd9Sstevel@tonic-gate } 1055*7c478bd9Sstevel@tonic-gate endnetconfig(nc_handle); 1056*7c478bd9Sstevel@tonic-gate 1057*7c478bd9Sstevel@tonic-gate if (clnt == (CLIENT *) NULL) { /* no loopback transport available */ 1058*7c478bd9Sstevel@tonic-gate if (rpc_createerr.cf_stat == 0) 1059*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; 1060*7c478bd9Sstevel@tonic-gate if (*err == 0) *err = YPERR_RPC; 1061*7c478bd9Sstevel@tonic-gate } 1062*7c478bd9Sstevel@tonic-gate trace1(TR___clnt_create_loopback, 1); 1063*7c478bd9Sstevel@tonic-gate return (clnt); 1064*7c478bd9Sstevel@tonic-gate } 1065*7c478bd9Sstevel@tonic-gate 1066*7c478bd9Sstevel@tonic-gate static CLIENT * 1067*7c478bd9Sstevel@tonic-gate getclnt(prog, vers, nconf, err) 1068*7c478bd9Sstevel@tonic-gate rpcprog_t prog; /* program number */ 1069*7c478bd9Sstevel@tonic-gate rpcvers_t vers; /* version number */ 1070*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 1071*7c478bd9Sstevel@tonic-gate int *err; 1072*7c478bd9Sstevel@tonic-gate { 1073*7c478bd9Sstevel@tonic-gate int fd; 1074*7c478bd9Sstevel@tonic-gate struct netbuf *svcaddr; /* servers address */ 1075*7c478bd9Sstevel@tonic-gate CLIENT *cl; 1076*7c478bd9Sstevel@tonic-gate struct nd_addrlist *nas; 1077*7c478bd9Sstevel@tonic-gate struct nd_hostserv rpcbind_hs; 1078*7c478bd9Sstevel@tonic-gate struct t_call sndcall; 1079*7c478bd9Sstevel@tonic-gate char uaddress[1024]; /* XXX maxlen ?? */ 1080*7c478bd9Sstevel@tonic-gate RPCB parms; 1081*7c478bd9Sstevel@tonic-gate enum clnt_stat clnt_st; 1082*7c478bd9Sstevel@tonic-gate char *ua; 1083*7c478bd9Sstevel@tonic-gate struct timeval tv = { 30, 0 }; 1084*7c478bd9Sstevel@tonic-gate 1085*7c478bd9Sstevel@tonic-gate trace3(TR_getclnt, 0, prog, vers); 1086*7c478bd9Sstevel@tonic-gate if (nconf == (struct netconfig *)NULL) { 1087*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_TLIERROR; 1088*7c478bd9Sstevel@tonic-gate *err = YPERR_RPC; 1089*7c478bd9Sstevel@tonic-gate trace1(TR_getclnt, 1); 1090*7c478bd9Sstevel@tonic-gate return ((CLIENT *)NULL); 1091*7c478bd9Sstevel@tonic-gate } 1092*7c478bd9Sstevel@tonic-gate 1093*7c478bd9Sstevel@tonic-gate /* 1094*7c478bd9Sstevel@tonic-gate * The ypbind process might cache its transport address. 1095*7c478bd9Sstevel@tonic-gate * If we can get at it, then we will use it and avoid 1096*7c478bd9Sstevel@tonic-gate * wasting time talking to rpcbind. 1097*7c478bd9Sstevel@tonic-gate */ 1098*7c478bd9Sstevel@tonic-gate 1099*7c478bd9Sstevel@tonic-gate if (get_cached_transport(nconf, vers, uaddress, sizeof (uaddress))) { 1100*7c478bd9Sstevel@tonic-gate goto create_client; 1101*7c478bd9Sstevel@tonic-gate } 1102*7c478bd9Sstevel@tonic-gate 1103*7c478bd9Sstevel@tonic-gate /* 1104*7c478bd9Sstevel@tonic-gate * Check to see if local rpcbind is up or not. If it 1105*7c478bd9Sstevel@tonic-gate * isn't, it is best that the application should realize 1106*7c478bd9Sstevel@tonic-gate * yp is not up and take a remedial action. This is to 1107*7c478bd9Sstevel@tonic-gate * avoid the minute long timeout incurred by rpcbind_getaddr. 1108*7c478bd9Sstevel@tonic-gate * Looks like the only way to accomplish this it is to unfold 1109*7c478bd9Sstevel@tonic-gate * rpcb_getaddr and make a few changes. Alas ! 1110*7c478bd9Sstevel@tonic-gate */ 1111*7c478bd9Sstevel@tonic-gate rpcbind_hs.h_host = HOST_SELF_CONNECT; 1112*7c478bd9Sstevel@tonic-gate rpcbind_hs.h_serv = "rpcbind"; 1113*7c478bd9Sstevel@tonic-gate if (netdir_getbyname(nconf, &rpcbind_hs, &nas) != ND_OK) { 1114*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE; 1115*7c478bd9Sstevel@tonic-gate *err = YPERR_RPC; 1116*7c478bd9Sstevel@tonic-gate trace1(TR_getclnt, 1); 1117*7c478bd9Sstevel@tonic-gate return ((CLIENT *)NULL); 1118*7c478bd9Sstevel@tonic-gate } 1119*7c478bd9Sstevel@tonic-gate if ((fd = t_open(nconf->nc_device, O_RDWR, NULL)) == -1) { 1120*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_TLIERROR; 1121*7c478bd9Sstevel@tonic-gate *err = YPERR_RPC; 1122*7c478bd9Sstevel@tonic-gate trace1(TR_getclnt, 1); 1123*7c478bd9Sstevel@tonic-gate return ((CLIENT *)NULL); 1124*7c478bd9Sstevel@tonic-gate } 1125*7c478bd9Sstevel@tonic-gate if (t_bind(fd, (struct t_bind *)NULL, (struct t_bind *)NULL) == -1) { 1126*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_TLIERROR; 1127*7c478bd9Sstevel@tonic-gate *err = YPERR_RPC; 1128*7c478bd9Sstevel@tonic-gate (void) t_close(fd); 1129*7c478bd9Sstevel@tonic-gate trace1(TR_getclnt, 1); 1130*7c478bd9Sstevel@tonic-gate return ((CLIENT *)NULL); 1131*7c478bd9Sstevel@tonic-gate } 1132*7c478bd9Sstevel@tonic-gate sndcall.addr = *(nas->n_addrs); 1133*7c478bd9Sstevel@tonic-gate sndcall.opt.len = 0; 1134*7c478bd9Sstevel@tonic-gate sndcall.udata.len = 0; 1135*7c478bd9Sstevel@tonic-gate if (t_connect(fd, &sndcall, NULL) == -1) { 1136*7c478bd9Sstevel@tonic-gate netdir_free((char *)nas, ND_ADDRLIST); 1137*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_TLIERROR; 1138*7c478bd9Sstevel@tonic-gate (void) t_close(fd); 1139*7c478bd9Sstevel@tonic-gate *err = YPERR_PMAP; 1140*7c478bd9Sstevel@tonic-gate trace1(TR_getclnt, 1); 1141*7c478bd9Sstevel@tonic-gate return ((CLIENT *)NULL); 1142*7c478bd9Sstevel@tonic-gate } 1143*7c478bd9Sstevel@tonic-gate 1144*7c478bd9Sstevel@tonic-gate /* 1145*7c478bd9Sstevel@tonic-gate * Get the address of the server 1146*7c478bd9Sstevel@tonic-gate */ 1147*7c478bd9Sstevel@tonic-gate cl = clnt_tli_create(fd, nconf, nas->n_addrs, 1148*7c478bd9Sstevel@tonic-gate RPCBPROG, RPCBVERS, __ypipbufsize, __ypipbufsize); 1149*7c478bd9Sstevel@tonic-gate netdir_free((char *)nas, ND_ADDRLIST); 1150*7c478bd9Sstevel@tonic-gate if (cl == (CLIENT *)NULL) { 1151*7c478bd9Sstevel@tonic-gate (void) t_close(fd); 1152*7c478bd9Sstevel@tonic-gate *err = YPERR_PMAP; 1153*7c478bd9Sstevel@tonic-gate trace1(TR_getclnt, 1); 1154*7c478bd9Sstevel@tonic-gate return ((CLIENT *)NULL); 1155*7c478bd9Sstevel@tonic-gate } 1156*7c478bd9Sstevel@tonic-gate parms.r_prog = prog; 1157*7c478bd9Sstevel@tonic-gate parms.r_vers = vers; 1158*7c478bd9Sstevel@tonic-gate parms.r_netid = nconf->nc_netid; 1159*7c478bd9Sstevel@tonic-gate parms.r_addr = nullstring; 1160*7c478bd9Sstevel@tonic-gate parms.r_owner = nullstring; 1161*7c478bd9Sstevel@tonic-gate ua = uaddress; 1162*7c478bd9Sstevel@tonic-gate clnt_st = CLNT_CALL(cl, RPCBPROC_GETADDR, xdr_rpcb, (char *)&parms, 1163*7c478bd9Sstevel@tonic-gate xdr_wrapstring, (char *)&ua, tv); 1164*7c478bd9Sstevel@tonic-gate (void) t_close(fd); 1165*7c478bd9Sstevel@tonic-gate clnt_destroy(cl); 1166*7c478bd9Sstevel@tonic-gate if (clnt_st != RPC_SUCCESS) { 1167*7c478bd9Sstevel@tonic-gate *err = YPERR_YPBIND; 1168*7c478bd9Sstevel@tonic-gate trace1(TR_getclnt, 1); 1169*7c478bd9Sstevel@tonic-gate return ((CLIENT *)NULL); 1170*7c478bd9Sstevel@tonic-gate } 1171*7c478bd9Sstevel@tonic-gate if (strlen(uaddress) == 0) { 1172*7c478bd9Sstevel@tonic-gate *err = YPERR_YPBIND; 1173*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; 1174*7c478bd9Sstevel@tonic-gate return ((CLIENT *)NULL); 1175*7c478bd9Sstevel@tonic-gate } 1176*7c478bd9Sstevel@tonic-gate 1177*7c478bd9Sstevel@tonic-gate create_client: 1178*7c478bd9Sstevel@tonic-gate svcaddr = uaddr2taddr(nconf, uaddress); 1179*7c478bd9Sstevel@tonic-gate cl = clnt_tli_create(RPC_ANYFD, nconf, svcaddr, prog, vers, 1180*7c478bd9Sstevel@tonic-gate __ypipbufsize, __ypipbufsize); 1181*7c478bd9Sstevel@tonic-gate netdir_free((char *)svcaddr, ND_ADDR); 1182*7c478bd9Sstevel@tonic-gate if (cl == (CLIENT *)NULL) { 1183*7c478bd9Sstevel@tonic-gate *err = YPERR_YPBIND; 1184*7c478bd9Sstevel@tonic-gate trace1(TR_getclnt, 1); 1185*7c478bd9Sstevel@tonic-gate return ((CLIENT *)NULL); 1186*7c478bd9Sstevel@tonic-gate } 1187*7c478bd9Sstevel@tonic-gate /* 1188*7c478bd9Sstevel@tonic-gate * The fd should be closed while destroying the handle. 1189*7c478bd9Sstevel@tonic-gate */ 1190*7c478bd9Sstevel@tonic-gate trace1(TR_getclnt, 1); 1191*7c478bd9Sstevel@tonic-gate return (cl); 1192*7c478bd9Sstevel@tonic-gate } 1193*7c478bd9Sstevel@tonic-gate 1194*7c478bd9Sstevel@tonic-gate static 1195*7c478bd9Sstevel@tonic-gate int 1196*7c478bd9Sstevel@tonic-gate get_cached_transport(nconf, vers, uaddress, ulen) 1197*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 1198*7c478bd9Sstevel@tonic-gate int vers; 1199*7c478bd9Sstevel@tonic-gate char *uaddress; 1200*7c478bd9Sstevel@tonic-gate int ulen; 1201*7c478bd9Sstevel@tonic-gate { 1202*7c478bd9Sstevel@tonic-gate ssize_t st; 1203*7c478bd9Sstevel@tonic-gate int fd; 1204*7c478bd9Sstevel@tonic-gate 1205*7c478bd9Sstevel@tonic-gate (void) sprintf(uaddress, "%s/xprt.%s.%d", BINDING, nconf->nc_netid, 1206*7c478bd9Sstevel@tonic-gate vers); 1207*7c478bd9Sstevel@tonic-gate fd = open(uaddress, O_RDONLY); 1208*7c478bd9Sstevel@tonic-gate if (fd == -1) 1209*7c478bd9Sstevel@tonic-gate return (0); 1210*7c478bd9Sstevel@tonic-gate 1211*7c478bd9Sstevel@tonic-gate /* if first byte is not locked, then ypbind must not be running */ 1212*7c478bd9Sstevel@tonic-gate st = lockf(fd, F_TEST, 1); 1213*7c478bd9Sstevel@tonic-gate if (st != -1 || (errno != EAGAIN && errno != EACCES)) { 1214*7c478bd9Sstevel@tonic-gate (void) close(fd); 1215*7c478bd9Sstevel@tonic-gate return (0); 1216*7c478bd9Sstevel@tonic-gate } 1217*7c478bd9Sstevel@tonic-gate 1218*7c478bd9Sstevel@tonic-gate st = read(fd, uaddress, ulen); 1219*7c478bd9Sstevel@tonic-gate if (st == -1) { 1220*7c478bd9Sstevel@tonic-gate (void) close(fd); 1221*7c478bd9Sstevel@tonic-gate return (0); 1222*7c478bd9Sstevel@tonic-gate } 1223*7c478bd9Sstevel@tonic-gate 1224*7c478bd9Sstevel@tonic-gate (void) close(fd); 1225*7c478bd9Sstevel@tonic-gate return (1); 1226*7c478bd9Sstevel@tonic-gate } 1227*7c478bd9Sstevel@tonic-gate 1228*7c478bd9Sstevel@tonic-gate static 1229*7c478bd9Sstevel@tonic-gate ypbind_resp * 1230*7c478bd9Sstevel@tonic-gate get_cached_domain(domain) 1231*7c478bd9Sstevel@tonic-gate char *domain; 1232*7c478bd9Sstevel@tonic-gate { 1233*7c478bd9Sstevel@tonic-gate __NSL_FILE *fp; 1234*7c478bd9Sstevel@tonic-gate int st; 1235*7c478bd9Sstevel@tonic-gate char filename[300]; 1236*7c478bd9Sstevel@tonic-gate static ypbind_resp res; 1237*7c478bd9Sstevel@tonic-gate XDR xdrs; 1238*7c478bd9Sstevel@tonic-gate 1239*7c478bd9Sstevel@tonic-gate (void) sprintf(filename, "%s/%s/cache_binding", BINDING, domain); 1240*7c478bd9Sstevel@tonic-gate fp = __nsl_fopen(filename, "r"); 1241*7c478bd9Sstevel@tonic-gate if (fp == 0) 1242*7c478bd9Sstevel@tonic-gate return (0); 1243*7c478bd9Sstevel@tonic-gate 1244*7c478bd9Sstevel@tonic-gate /* if first byte is not locked, then ypbind must not be running */ 1245*7c478bd9Sstevel@tonic-gate st = lockf(__nsl_fileno(fp), F_TEST, 1); 1246*7c478bd9Sstevel@tonic-gate if (st != -1 || (errno != EAGAIN && errno != EACCES)) { 1247*7c478bd9Sstevel@tonic-gate (void) __nsl_fclose(fp); 1248*7c478bd9Sstevel@tonic-gate return (0); 1249*7c478bd9Sstevel@tonic-gate } 1250*7c478bd9Sstevel@tonic-gate 1251*7c478bd9Sstevel@tonic-gate __nsl_xdrstdio_create(&xdrs, fp, XDR_DECODE); 1252*7c478bd9Sstevel@tonic-gate 1253*7c478bd9Sstevel@tonic-gate (void) memset((char *)&res, 0, sizeof (res)); 1254*7c478bd9Sstevel@tonic-gate st = xdr_ypbind_resp(&xdrs, &res); 1255*7c478bd9Sstevel@tonic-gate 1256*7c478bd9Sstevel@tonic-gate xdr_destroy(&xdrs); 1257*7c478bd9Sstevel@tonic-gate (void) __nsl_fclose(fp); 1258*7c478bd9Sstevel@tonic-gate 1259*7c478bd9Sstevel@tonic-gate if (st) 1260*7c478bd9Sstevel@tonic-gate return (&res); 1261*7c478bd9Sstevel@tonic-gate 1262*7c478bd9Sstevel@tonic-gate return (0); 1263*7c478bd9Sstevel@tonic-gate } 1264*7c478bd9Sstevel@tonic-gate 1265*7c478bd9Sstevel@tonic-gate static 1266*7c478bd9Sstevel@tonic-gate int 1267*7c478bd9Sstevel@tonic-gate ypbind_running(err, status) 1268*7c478bd9Sstevel@tonic-gate int err; 1269*7c478bd9Sstevel@tonic-gate int status; 1270*7c478bd9Sstevel@tonic-gate { 1271*7c478bd9Sstevel@tonic-gate char filename[300]; 1272*7c478bd9Sstevel@tonic-gate int st; 1273*7c478bd9Sstevel@tonic-gate int fd; 1274*7c478bd9Sstevel@tonic-gate 1275*7c478bd9Sstevel@tonic-gate (void) sprintf(filename, "%s/ypbind.pid", BINDING); 1276*7c478bd9Sstevel@tonic-gate fd = open(filename, O_RDONLY); 1277*7c478bd9Sstevel@tonic-gate if (fd == -1) { 1278*7c478bd9Sstevel@tonic-gate if ((err == YPERR_YPBIND) && (status != RPC_PROGNOTREGISTERED)) 1279*7c478bd9Sstevel@tonic-gate return (1); 1280*7c478bd9Sstevel@tonic-gate return (0); 1281*7c478bd9Sstevel@tonic-gate } 1282*7c478bd9Sstevel@tonic-gate 1283*7c478bd9Sstevel@tonic-gate /* if first byte is not locked, then ypbind must not be running */ 1284*7c478bd9Sstevel@tonic-gate st = lockf(fd, F_TEST, 1); 1285*7c478bd9Sstevel@tonic-gate if (st != -1 || (errno != EAGAIN && errno != EACCES)) { 1286*7c478bd9Sstevel@tonic-gate (void) close(fd); 1287*7c478bd9Sstevel@tonic-gate return (0); 1288*7c478bd9Sstevel@tonic-gate } 1289*7c478bd9Sstevel@tonic-gate 1290*7c478bd9Sstevel@tonic-gate (void) close(fd); 1291*7c478bd9Sstevel@tonic-gate return (1); 1292*7c478bd9Sstevel@tonic-gate } 1293*7c478bd9Sstevel@tonic-gate 1294*7c478bd9Sstevel@tonic-gate static 1295*7c478bd9Sstevel@tonic-gate void 1296*7c478bd9Sstevel@tonic-gate set_rdev(pdomb) 1297*7c478bd9Sstevel@tonic-gate struct dom_binding *pdomb; 1298*7c478bd9Sstevel@tonic-gate { 1299*7c478bd9Sstevel@tonic-gate int fd; 1300*7c478bd9Sstevel@tonic-gate struct stat stbuf; 1301*7c478bd9Sstevel@tonic-gate 1302*7c478bd9Sstevel@tonic-gate if (clnt_control(pdomb->dom_client, CLGET_FD, (char *)&fd) != TRUE || 1303*7c478bd9Sstevel@tonic-gate _FSTAT(fd, &stbuf) == -1) { 1304*7c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "ypbind client: can't get rdev"); 1305*7c478bd9Sstevel@tonic-gate pdomb->fd = -1; 1306*7c478bd9Sstevel@tonic-gate return; 1307*7c478bd9Sstevel@tonic-gate } 1308*7c478bd9Sstevel@tonic-gate pdomb->fd = fd; 1309*7c478bd9Sstevel@tonic-gate pdomb->rdev = stbuf.st_rdev; 1310*7c478bd9Sstevel@tonic-gate } 1311*7c478bd9Sstevel@tonic-gate 1312*7c478bd9Sstevel@tonic-gate static 1313*7c478bd9Sstevel@tonic-gate int 1314*7c478bd9Sstevel@tonic-gate check_rdev(pdomb) 1315*7c478bd9Sstevel@tonic-gate struct dom_binding *pdomb; 1316*7c478bd9Sstevel@tonic-gate { 1317*7c478bd9Sstevel@tonic-gate struct stat stbuf; 1318*7c478bd9Sstevel@tonic-gate 1319*7c478bd9Sstevel@tonic-gate if (pdomb->fd == -1) 1320*7c478bd9Sstevel@tonic-gate return (1); /* can't check it, assume it is okay */ 1321*7c478bd9Sstevel@tonic-gate 1322*7c478bd9Sstevel@tonic-gate if (_FSTAT(pdomb->fd, &stbuf) == -1) { 1323*7c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "yp_bind client: can't stat %d", pdomb->fd); 1324*7c478bd9Sstevel@tonic-gate /* could be because file descriptor was closed */ 1325*7c478bd9Sstevel@tonic-gate /* it's not our file descriptor, so don't try to close it */ 1326*7c478bd9Sstevel@tonic-gate clnt_control(pdomb->dom_client, CLSET_FD_NCLOSE, (char *)NULL); 1327*7c478bd9Sstevel@tonic-gate return (0); 1328*7c478bd9Sstevel@tonic-gate } 1329*7c478bd9Sstevel@tonic-gate if (pdomb->rdev != stbuf.st_rdev) { 1330*7c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 1331*7c478bd9Sstevel@tonic-gate "yp_bind client: fd %d changed, old=0x%x, new=0x%x", 1332*7c478bd9Sstevel@tonic-gate pdomb->fd, pdomb->rdev, stbuf.st_rdev); 1333*7c478bd9Sstevel@tonic-gate /* it's not our file descriptor, so don't try to close it */ 1334*7c478bd9Sstevel@tonic-gate clnt_control(pdomb->dom_client, CLSET_FD_NCLOSE, (char *)NULL); 1335*7c478bd9Sstevel@tonic-gate return (0); 1336*7c478bd9Sstevel@tonic-gate } 1337*7c478bd9Sstevel@tonic-gate return (1); /* fd is okay */ 1338*7c478bd9Sstevel@tonic-gate } 1339