1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1992 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <errno.h> 31 #include <sys/time.h> 32 #include <rpc/rpc.h> 33 #include <rpc/pmap_prot.h> 34 #include <sys/socket.h> 35 #include <sys/file.h> 36 #include <sys/syslog.h> 37 38 #include "yp_prot.h" 39 #include "ypv1_prot.h" 40 #include "ypclnt.h" 41 42 /* 43 * This is the same as struct dom_binding used by the base __yp_dobind(). 44 * Named differently here to avoid name conflict with the compat 45 * struct dom_binding. 46 */ 47 48 /* Copied from base <sys/netconfig.h> */ 49 50 struct netconfig { 51 char *nc_netid; /* network identifier */ 52 unsigned long nc_semantics; /* defined below */ 53 unsigned long nc_flag; /* defined below */ 54 char *nc_protofmly; /* protocol family name */ 55 char *nc_proto; /* protocol name */ 56 char *nc_device; /* device name for network id */ 57 unsigned long nc_nlookups; /* # of entries in nc_lookups */ 58 char **nc_lookups; /* list of lookup directories */ 59 unsigned long nc_unused[8]; 60 }; 61 62 /* Copied from base <sys/tiuser.h> */ 63 64 struct netbuf { 65 unsigned int maxlen; 66 unsigned int len; 67 char *buf; 68 }; 69 70 struct s5_dom_binding { 71 struct s5_dom_binding *dom_next; 72 char *dom_domain; 73 struct s5_ypbind_binding *dom_binding; 74 CLIENT *dom_client; 75 }; 76 77 struct s5_ypbind_binding { 78 struct netconfig *ypbind_conf; 79 struct netbuf *ypbind_svcaddr; 80 char *ypbind_servername; 81 long ypbind_hi_vers; 82 long ypbind_lo_vers; 83 }; 84 85 static void _yp_unbind(); 86 static struct dom_binding *load_dom_binding_cache(); 87 88 static struct dom_binding *bound_domains; /* List of bound domains */ 89 90 /* 91 * This is a "wrapper" function that is implemented by the yp_bind() 92 * function in base libnsl/yp. 93 */ 94 #ifdef NOTDEFINED 95 int 96 yp_bind(domain) 97 char *domain; 98 { 99 /* XXX */ 100 _yp_bind(domain); 101 } 102 #endif 103 104 /* 105 * Attempts to find a dom_binding in the list at bound_domains having the 106 * domain name field equal to the passed domain name, and removes it if found. 107 * The domain-server binding will not exist after the call to this function. 108 * All resources associated with the binding will be freed. 109 */ 110 #ifdef NOTDEFINED 111 void 112 yp_unbind (domain) 113 char *domain; 114 { 115 _yp_unbind(domain); /* clean our local cache */ 116 /* XXX */ 117 _yp_unbind(domain); 118 } 119 #endif 120 121 /* 122 * This is a wrapper around the yp_get_default_domain() 123 * function in base libnsl/yp. 124 */ 125 #ifdef NOTDEFINED 126 int 127 yp_get_default_domain(domain) 128 char **domain; 129 { 130 /* XXX */ 131 _yp_get_default_domain(domain); 132 } 133 #endif 134 135 /* 136 * Attempts to locate a NIS server that serves a passed domain. 137 * This is a wrapper around the __yp_dobind() function in base 138 * libnsl/yp; it converts the libnsl [netbuf based] dom_binding structure into 139 * the [sockaddr based] one that is expected by binary compat apps. Note that, 140 * the wrapper must allocate memory resources in order to hold 141 * the 142 */ 143 int 144 _yp_dobind(domain, binding) 145 char *domain; 146 struct dom_binding **binding; /* if result == 0, ptr to dom_binding */ 147 { 148 int retval; 149 struct s5_dom_binding *dom_binding; /* Ptr to dom_binding from libnsl __yp_dobind() */ 150 int status; 151 152 /* XXX */ 153 retval = __yp_dobind(domain, &dom_binding); 154 if (retval != 0) 155 return(retval); 156 157 if ((*binding = load_dom_binding_cache(domain, dom_binding)) == NULL) 158 return (YPERR_RESRC); /* make sure it is in our cache */ 159 return (0); /* This is the go path */ 160 } 161 162 163 /* 164 * This allocates some memory for a domain binding, initialize it, and 165 * returns a pointer to it. Based on the program version we ended up 166 * talking to ypbind with, fill out an opvector of appropriate protocol 167 * modules. 168 */ 169 static struct dom_binding * 170 load_dom_binding_cache(domain, dom_binding) 171 char *domain; 172 struct s5_dom_binding *dom_binding; 173 { 174 struct dom_binding *pdomb = NULL; 175 struct sockaddr_in *sa; /* To get a port bound to socket */ 176 struct sockaddr_in local_name; 177 int local_name_len = sizeof(struct sockaddr_in); 178 179 180 for (pdomb = bound_domains; pdomb != NULL; pdomb = pdomb->dom_pnext) { 181 if (strcmp(domain, pdomb->dom_domain) == 0) 182 return (pdomb); 183 } 184 185 if ((pdomb = (struct dom_binding *) malloc(sizeof(struct dom_binding))) 186 == NULL) { 187 (void) syslog(LOG_ERR, "load_dom_binding_cache: malloc failure."); 188 return (struct dom_binding *) (NULL); 189 } 190 191 sa = (struct sockaddr_in *)dom_binding->dom_binding->ypbind_svcaddr->buf; 192 pdomb->dom_server_addr.sin_family = sa->sin_family; 193 pdomb->dom_server_addr.sin_port = sa->sin_port; 194 pdomb->dom_server_addr.sin_addr.s_addr = sa->sin_addr.s_addr; 195 bzero(pdomb->dom_server_addr.sin_zero, 8); 196 pdomb->dom_server_port = sa->sin_port; 197 pdomb->dom_socket = RPC_ANYSOCK; 198 pdomb->dom_vers = dom_binding->dom_binding->ypbind_hi_vers; 199 /* the claim is 5.0 CLIENT * can be used by a 4.x RPC user */ 200 pdomb->dom_client = dom_binding->dom_client; 201 202 (void) strcpy(pdomb->dom_domain, domain);/* Remember the domain name */ 203 pdomb->dom_pnext = bound_domains; /* Link this to the list as */ 204 bound_domains = pdomb; /* ... the head entry */ 205 206 return (pdomb); 207 } 208 209 static void 210 _yp_unbind (domain) 211 char *domain; 212 { 213 struct dom_binding *pdomb; 214 struct dom_binding *ptrail = 0; 215 216 217 if ( (domain == NULL) ||(strlen(domain) == 0) ) { 218 return; 219 } 220 221 for (pdomb = bound_domains; pdomb != NULL; 222 ptrail = pdomb, pdomb = pdomb->dom_pnext) { 223 224 if (strcmp(domain, pdomb->dom_domain) == 0) { 225 if (pdomb == bound_domains) 226 bound_domains = pdomb->dom_pnext; 227 else 228 ptrail->dom_pnext = pdomb->dom_pnext; 229 free((char *) pdomb); 230 break; 231 } 232 } 233 } 234 235 int 236 yp_ismapthere(stat) 237 int stat; 238 { 239 240 switch (stat) { 241 242 case 0: /* it actually succeeded! */ 243 case YPERR_KEY: /* no such key in map */ 244 case YPERR_NOMORE: 245 case YPERR_BUSY: 246 return (TRUE); 247 } 248 return (FALSE); 249 } 250