/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Portions of this source code were derived from Berkeley 4.3 BSD * under license from the Regents of the University of California. */ #include #include #include #include #include "ypsym.h" #include "ypdefs.h" /* Use N2L version of DBM calls */ #include "shim_hooks.h" USE_YP_MASTER_NAME USE_YP_LAST_MODIFIED USE_YPDBPATH USE_YP_SECURE USE_DBM #include static DBM *cur_fdb; /* will be passwd back up by ypset_current_map */ static enum { UNKNOWN, SECURE, PUBLIC } current_map_access = UNKNOWN; static char map_owner[MAX_MASTER_NAME + 1]; extern unsigned int ypcheck_domain(); int check_secure_net_ti(struct netbuf *caller, char *ypname); /* * The retrieves the order number of a named map from the order number datum * in the map data base. */ bool ypget_map_order(char *map, char *domain, uint_t *order) { datum key; datum val; char toconvert[MAX_ASCII_ORDER_NUMBER_LENGTH + 1]; uint_t error; DBM *fdb; if ((fdb = ypset_current_map(map, domain, &error)) != NULL) { key.dptr = yp_last_modified; key.dsize = yp_last_modified_sz; val = dbm_fetch(fdb, key); if (val.dptr != (char *)NULL) { if (val.dsize > MAX_ASCII_ORDER_NUMBER_LENGTH) { return (FALSE); } /* * This is getting recopied here because val.dptr * points to static memory owned by the dbm package, * and we have no idea whether numeric characters * follow the order number characters, nor whether * the mess is null-terminated at all. */ memcpy(toconvert, val.dptr, val.dsize); toconvert[val.dsize] = '\0'; *order = (unsigned long) atol(toconvert); return (TRUE); } else { return (FALSE); } } else { return (FALSE); } } /* * The retrieves the master server name of a named map from the master datum * in the map data base. */ bool ypget_map_master(char **owner, DBM *fdb) { datum key; datum val; key.dptr = yp_master_name; key.dsize = yp_master_name_sz; val = dbm_fetch(fdb, key); if (val.dptr != (char *)NULL) { if (val.dsize > MAX_MASTER_NAME) { return (FALSE); } /* * This is getting recopied here because val.dptr * points to static memory owned by the dbm package. */ memcpy(map_owner, val.dptr, val.dsize); map_owner[val.dsize] = '\0'; *owner = map_owner; return (TRUE); } else { return (FALSE); } } /* * This makes a map into the current map, and calls dbminit on that map * and returns the DBM pointer to the map. Procedures called by * ypserv dispatch routine would use this pointer for successive * ndbm operations. Returns an YP_xxxx error code in error if FALSE. */ DBM * ypset_current_map(char *map, char *domain, uint_t *error) { char mapname[MAXNAMLEN + 1]; int lenm, lend; /* Do not allow any path as a domain name or a map name. */ if (!map || ((lenm = (int)strlen(map)) == 0) || (lenm > YPMAXMAP) || !domain || ((lend = (int)strlen(domain)) == 0) || (lend > YPMAXDOMAIN) || (strchr(map, '/') != NULL) || (strchr(domain, '/') != NULL)) { *error = YP_BADARGS; return (FALSE); } if (FALSE == ypmkfilename(domain, map, mapname)) return (FALSE); if ((cur_fdb) && (strcmp(mapname, get_map_name(cur_fdb)) == 0)) { return (cur_fdb); } /* If there was a previous open map close it */ if (NULL != cur_fdb) dbm_close(cur_fdb); /* Set the map access as "unknown" as the new map has not been loaded */ current_map_access = UNKNOWN; /* All the map locking is now handled inside the dbm_open shim */ if ((cur_fdb = dbm_open(mapname, O_RDWR, 0644)) != NULL) { return (cur_fdb); } if (ypcheck_domain(domain)) { if (ypcheck_map_existence(mapname)) { *error = YP_BADDB; } else { *error = YP_NOMAP; } } else { *error = YP_NODOM; } return (NULL); } /* * This checks to see if there is a current map, and, if there is, does a * dbmclose on it and sets the current map name and its DBM ptr to null. */ void ypclr_current_map(void) { if (cur_fdb != NULL) { (void) dbm_close(cur_fdb); cur_fdb = NULL; } current_map_access = UNKNOWN; } /* * Checks to see if caller has permission to query the current map (as * set by ypset_current_map()). Returns TRUE if access is granted and * FALSE otherwise. If FALSE then sets *error to YP_xxxxxxxx. */ bool yp_map_access(SVCXPRT *transp, uint_t *error, DBM *fdb) { char *ypname = "ypserv"; struct netbuf *nbuf; sa_family_t af; in_port_t port; nbuf = svc_getrpccaller(transp); af = ((struct sockaddr_storage *)nbuf->buf)->ss_family; if (af != AF_INET && af != AF_INET6) return (FALSE); if (!(check_secure_net_ti(nbuf, ypname))) { *error = YP_NOMAP; return (FALSE); } /* XXX - I expect that this won't happen much */ if (current_map_access == PUBLIC) { return (TRUE); } if (af == AF_INET6) { port = ntohs(((struct sockaddr_in6 *)nbuf->buf)->sin6_port); } else { port = ntohs(((struct sockaddr_in *)nbuf->buf)->sin_port); } if (port < IPPORT_RESERVED) { return (TRUE); } if (current_map_access == UNKNOWN) { datum key; datum val; key.dptr = yp_secure; key.dsize = yp_secure_sz; val = dbm_fetch(fdb, key); if (val.dptr == (char *)NULL) { current_map_access = PUBLIC; return (TRUE); } current_map_access = SECURE; } /* current_map_access == SECURE and non-priviledged caller */ *error = YP_NOMAP; return (FALSE); }