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