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 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Portions of this source code were derived from Berkeley 4.3 BSD 32 * under license from the Regents of the University of California. 33 */ 34 35 #pragma ident "%Z%%M% %I% %E% SMI" 36 37 #include <stdlib.h> 38 #include <dirent.h> 39 #include <string.h> 40 #include <malloc.h> 41 #include "ypsym.h" 42 #include "ypdefs.h" 43 44 /* Use N2L version of DBM calls */ 45 #include "shim_hooks.h" 46 47 USE_YP_MASTER_NAME 48 USE_YP_LAST_MODIFIED 49 USE_YPDBPATH 50 USE_YP_SECURE 51 USE_DBM 52 53 #include <ctype.h> 54 55 static DBM *cur_fdb; /* will be passwd back up by ypset_current_map */ 56 static enum { UNKNOWN, SECURE, PUBLIC } current_map_access = UNKNOWN; 57 static char map_owner[MAX_MASTER_NAME + 1]; 58 59 extern unsigned int ypcheck_domain(); 60 int check_secure_net_ti(struct netbuf *caller, char *ypname); 61 62 /* 63 * The retrieves the order number of a named map from the order number datum 64 * in the map data base. 65 */ 66 bool 67 ypget_map_order(char *map, char *domain, uint_t *order) 68 { 69 datum key; 70 datum val; 71 char toconvert[MAX_ASCII_ORDER_NUMBER_LENGTH + 1]; 72 uint_t error; 73 DBM *fdb; 74 75 if ((fdb = ypset_current_map(map, domain, &error)) != NULL) { 76 key.dptr = yp_last_modified; 77 key.dsize = yp_last_modified_sz; 78 val = dbm_fetch(fdb, key); 79 80 if (val.dptr != (char *)NULL) { 81 82 if (val.dsize > MAX_ASCII_ORDER_NUMBER_LENGTH) { 83 return (FALSE); 84 } 85 86 /* 87 * This is getting recopied here because val.dptr 88 * points to static memory owned by the dbm package, 89 * and we have no idea whether numeric characters 90 * follow the order number characters, nor whether 91 * the mess is null-terminated at all. 92 */ 93 94 memcpy(toconvert, val.dptr, val.dsize); 95 toconvert[val.dsize] = '\0'; 96 *order = (unsigned long) atol(toconvert); 97 return (TRUE); 98 } else { 99 return (FALSE); 100 } 101 102 } else { 103 return (FALSE); 104 } 105 } 106 107 /* 108 * The retrieves the master server name of a named map from the master datum 109 * in the map data base. 110 */ 111 bool 112 ypget_map_master(char **owner, DBM *fdb) 113 { 114 datum key; 115 datum val; 116 117 key.dptr = yp_master_name; 118 key.dsize = yp_master_name_sz; 119 val = dbm_fetch(fdb, key); 120 121 if (val.dptr != (char *)NULL) { 122 123 if (val.dsize > MAX_MASTER_NAME) { 124 return (FALSE); 125 } 126 127 /* 128 * This is getting recopied here because val.dptr 129 * points to static memory owned by the dbm package. 130 */ 131 memcpy(map_owner, val.dptr, val.dsize); 132 map_owner[val.dsize] = '\0'; 133 *owner = map_owner; 134 return (TRUE); 135 } else { 136 return (FALSE); 137 } 138 } 139 140 /* 141 * This makes a map into the current map, and calls dbminit on that map 142 * and returns the DBM pointer to the map. Procedures called by 143 * ypserv dispatch routine would use this pointer for successive 144 * ndbm operations. Returns an YP_xxxx error code in error if FALSE. 145 */ 146 DBM * 147 ypset_current_map(char *map, char *domain, uint_t *error) 148 { 149 char mapname[MAXNAMLEN + 1]; 150 int lenm, lend; 151 152 /* Do not allow any path as a domain name or a map name. */ 153 if (!map || ((lenm = (int)strlen(map)) == 0) || (lenm > YPMAXMAP) || 154 !domain || ((lend = (int)strlen(domain)) == 0) || 155 (lend > YPMAXDOMAIN) || (strchr(map, '/') != NULL) || 156 (strchr(domain, '/') != NULL)) { 157 *error = YP_BADARGS; 158 return (FALSE); 159 } 160 161 if (FALSE == ypmkfilename(domain, map, mapname)) 162 return (FALSE); 163 164 if ((cur_fdb) && (strcmp(mapname, get_map_name(cur_fdb)) == 0)) { 165 return (cur_fdb); 166 } 167 168 /* If there was a previous open map close it */ 169 if (NULL != cur_fdb) 170 dbm_close(cur_fdb); 171 172 /* Set the map access as "unknown" as the new map has not been loaded */ 173 current_map_access = UNKNOWN; 174 175 /* All the map locking is now handled inside the dbm_open shim */ 176 if ((cur_fdb = dbm_open(mapname, O_RDWR, 0644)) != NULL) { 177 return (cur_fdb); 178 } 179 180 if (ypcheck_domain(domain)) { 181 182 if (ypcheck_map_existence(mapname)) { 183 *error = YP_BADDB; 184 } else { 185 *error = YP_NOMAP; 186 } 187 188 } else { 189 *error = YP_NODOM; 190 } 191 192 return (NULL); 193 } 194 195 /* 196 * This checks to see if there is a current map, and, if there is, does a 197 * dbmclose on it and sets the current map name and its DBM ptr to null. 198 */ 199 void 200 ypclr_current_map(void) 201 { 202 if (cur_fdb != NULL) { 203 (void) dbm_close(cur_fdb); 204 cur_fdb = NULL; 205 } 206 current_map_access = UNKNOWN; 207 } 208 209 /* 210 * Checks to see if caller has permission to query the current map (as 211 * set by ypset_current_map()). Returns TRUE if access is granted and 212 * FALSE otherwise. If FALSE then sets *error to YP_xxxxxxxx. 213 */ 214 bool 215 yp_map_access(SVCXPRT *transp, uint_t *error, DBM *fdb) 216 { 217 char *ypname = "ypserv"; 218 struct netbuf *nbuf; 219 sa_family_t af; 220 in_port_t port; 221 222 nbuf = svc_getrpccaller(transp); 223 af = ((struct sockaddr_storage *)nbuf->buf)->ss_family; 224 if (af != AF_INET && af != AF_INET6) 225 return (FALSE); 226 227 if (!(check_secure_net_ti(nbuf, ypname))) { 228 *error = YP_NOMAP; 229 return (FALSE); 230 } 231 232 /* XXX - I expect that this won't happen much */ 233 if (current_map_access == PUBLIC) { 234 return (TRUE); 235 } 236 237 if (af == AF_INET6) { 238 port = ntohs(((struct sockaddr_in6 *)nbuf->buf)->sin6_port); 239 } else { 240 port = ntohs(((struct sockaddr_in *)nbuf->buf)->sin_port); 241 } 242 if (port < IPPORT_RESERVED) { 243 return (TRUE); 244 } 245 246 if (current_map_access == UNKNOWN) { 247 datum key; 248 datum val; 249 250 key.dptr = yp_secure; 251 key.dsize = yp_secure_sz; 252 val = dbm_fetch(fdb, key); 253 if (val.dptr == (char *)NULL) { 254 current_map_access = PUBLIC; 255 return (TRUE); 256 } 257 current_map_access = SECURE; 258 } 259 260 /* current_map_access == SECURE and non-priviledged caller */ 261 *error = YP_NOMAP; 262 return (FALSE); 263 } 264