10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*2189Ssdussud * Common Development and Distribution License (the "License"). 6*2189Ssdussud * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*2189Ssdussud * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate /* 290Sstevel@tonic-gate * DESCRIPTION: Contains functions relating to the creation and manipulation 300Sstevel@tonic-gate * of map_ctrl structures. These are used to hold information 310Sstevel@tonic-gate * specific to one NIS map. 320Sstevel@tonic-gate * 330Sstevel@tonic-gate * Because each of these contains a significant amount of state 340Sstevel@tonic-gate * information about an individual map they are created (on the 350Sstevel@tonic-gate * heap) when a map is opened and destroyed when it is closed. 360Sstevel@tonic-gate * The overhead of doing this is less than maintaining a pool 370Sstevel@tonic-gate * of map_ctrls. 380Sstevel@tonic-gate * 390Sstevel@tonic-gate * If two processes access the same map two map_ctrls will be 400Sstevel@tonic-gate * created with similar contents (but differing DBM pointers). 410Sstevel@tonic-gate * Both will have the same hash value so when one is locked 420Sstevel@tonic-gate * access to the other will also be prevented. 430Sstevel@tonic-gate */ 440Sstevel@tonic-gate 450Sstevel@tonic-gate #include <unistd.h> 46*2189Ssdussud #include <stdlib.h> 470Sstevel@tonic-gate #include <syslog.h> 480Sstevel@tonic-gate #include <ndbm.h> 490Sstevel@tonic-gate #include <string.h> 50*2189Ssdussud #include <sys/param.h> 510Sstevel@tonic-gate #include "ypsym.h" 520Sstevel@tonic-gate #include "ypdefs.h" 530Sstevel@tonic-gate #include "shim.h" 540Sstevel@tonic-gate #include "yptol.h" 550Sstevel@tonic-gate #include "../ldap_util.h" 560Sstevel@tonic-gate 57*2189Ssdussud extern int hash(char *s); 58*2189Ssdussud extern bool_t add_map_domain_to_list(char *domain, char ***map_list); 59*2189Ssdussud 60*2189Ssdussud /* 61*2189Ssdussud * Static variables for locking mechanism in 62*2189Ssdussud * N2L mode. 63*2189Ssdussud * map_id_list: hash table for map lists 64*2189Ssdussud * max_map: max number of maps in map_id_list 65*2189Ssdussud * it is also used as the map ID for 66*2189Ssdussud * unknown maps, see get_map_id() 67*2189Ssdussud * in usr/src/cmd/ypcmd/shared/lockmap.c 68*2189Ssdussud */ 69*2189Ssdussud static map_id_elt_t *map_id_list[MAXHASH]; 70*2189Ssdussud static int max_map = 0; 71*2189Ssdussud 720Sstevel@tonic-gate /* Switch on parts of ypdefs.h */ 730Sstevel@tonic-gate USE_DBM 74*2189Ssdussud USE_YPDBPATH 750Sstevel@tonic-gate 760Sstevel@tonic-gate /* 770Sstevel@tonic-gate * FUNCTION: create_map_ctrl(); 780Sstevel@tonic-gate * 790Sstevel@tonic-gate * DESCRIPTION: Create and a new map_ctrl in a non opened state. 800Sstevel@tonic-gate * 810Sstevel@tonic-gate * INPUTS: Fully qualified map name 820Sstevel@tonic-gate * 830Sstevel@tonic-gate * OUTPUTS: Pointer to map_ctrl 840Sstevel@tonic-gate * NULL on failure. 850Sstevel@tonic-gate * 860Sstevel@tonic-gate */ 870Sstevel@tonic-gate map_ctrl * 880Sstevel@tonic-gate create_map_ctrl(char *name) 890Sstevel@tonic-gate { 900Sstevel@tonic-gate char *myself = "create_map_ctrl"; 910Sstevel@tonic-gate map_ctrl *map; 920Sstevel@tonic-gate 930Sstevel@tonic-gate map = (map_ctrl *)am(myself, sizeof (map_ctrl)); 940Sstevel@tonic-gate if (NULL == map) { 950Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, "Could not alloc map_ctrl"); 960Sstevel@tonic-gate return (NULL); 970Sstevel@tonic-gate } 980Sstevel@tonic-gate 990Sstevel@tonic-gate /* Clear new map (in case we have to free it) */ 1000Sstevel@tonic-gate map->entries = NULL; 1010Sstevel@tonic-gate map->hash_val = 0; 1020Sstevel@tonic-gate map->map_name = NULL; 1030Sstevel@tonic-gate map->domain = NULL; 1040Sstevel@tonic-gate map->map_path = NULL; 1050Sstevel@tonic-gate map->ttl = NULL; 1060Sstevel@tonic-gate map->ttl_path = NULL; 1070Sstevel@tonic-gate map->trad_map_path = NULL; 1080Sstevel@tonic-gate map->key_data.dptr = NULL; 1090Sstevel@tonic-gate map->open_mode = 0; 1100Sstevel@tonic-gate map->open_flags = 0; 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate /* 1130Sstevel@tonic-gate * Initialize the fields of the map_ctrl. By doing this once here we 1140Sstevel@tonic-gate * can save a lot of work as map entries are accessed. 1150Sstevel@tonic-gate */ 1160Sstevel@tonic-gate if (SUCCESS != map_ctrl_init(map, name)) { 1170Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1180Sstevel@tonic-gate "Could not initialize map_ctrl for %s", name); 1190Sstevel@tonic-gate free_map_ctrl(map); 1200Sstevel@tonic-gate return (NULL); 1210Sstevel@tonic-gate } 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate return (map); 1240Sstevel@tonic-gate } 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate /* 1270Sstevel@tonic-gate * FUNCTION : map_ctrl_init() 1280Sstevel@tonic-gate * 1290Sstevel@tonic-gate * DESCRIPTION: Initializes the fields of a map_ctrl structure. 1300Sstevel@tonic-gate * 1310Sstevel@tonic-gate * By doing this once (when the map_ctrl is created) we avoid 1320Sstevel@tonic-gate * numerous other function having to repeat this string 1330Sstevel@tonic-gate * manipulation. 1340Sstevel@tonic-gate * 1350Sstevel@tonic-gate * GIVEN : Pointer to the structure 1360Sstevel@tonic-gate * Fully qualified name of the map 1370Sstevel@tonic-gate * 1380Sstevel@tonic-gate * RETURNS : SUCCESS = map_ctrl fully set up. 1390Sstevel@tonic-gate * FAILURE = map_ctrl not set up CALLER MUST FREE. 1400Sstevel@tonic-gate */ 1410Sstevel@tonic-gate suc_code 1420Sstevel@tonic-gate map_ctrl_init(map_ctrl *map, char *name) 1430Sstevel@tonic-gate { 1440Sstevel@tonic-gate char *myself = "map_ctrl_init"; 1450Sstevel@tonic-gate char *p, *q; 1460Sstevel@tonic-gate 1470Sstevel@tonic-gate /* Save map path for future reference */ 1480Sstevel@tonic-gate map->map_path = (char *)strdup(name); 1490Sstevel@tonic-gate if (NULL == map->map_path) { 1500Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 1510Sstevel@tonic-gate "Could not duplicate map path %s", map); 1520Sstevel@tonic-gate return (FAILURE); 1530Sstevel@tonic-gate } 1540Sstevel@tonic-gate 1550Sstevel@tonic-gate /* Work out map's unqualified name from path */ 1560Sstevel@tonic-gate p = strrchr(name, SEP_CHAR); 1570Sstevel@tonic-gate if (NULL == p) { 1580Sstevel@tonic-gate /* Must be at least a domain and name */ 1590Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1600Sstevel@tonic-gate "Could not find separator in map path %s", map); 1610Sstevel@tonic-gate return (FAILURE); 1620Sstevel@tonic-gate } 1630Sstevel@tonic-gate q = p + 1; 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate /* Check for and remove N2L prefix */ 1660Sstevel@tonic-gate if (yptol_mode) { 1670Sstevel@tonic-gate /* 1680Sstevel@tonic-gate * Check for and remove N2L prefix. If not found not a problem 1690Sstevel@tonic-gate * we open some old style maps during DIT initialization. 1700Sstevel@tonic-gate */ 1710Sstevel@tonic-gate if (0 == strncmp(q, NTOL_PREFIX, strlen(NTOL_PREFIX))) 1720Sstevel@tonic-gate q += strlen(NTOL_PREFIX); 1730Sstevel@tonic-gate } else { 1740Sstevel@tonic-gate if (0 == strncmp(q, NTOL_PREFIX, strlen(NTOL_PREFIX))) 1750Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1760Sstevel@tonic-gate "Working in non N2L mode and path %s " 1770Sstevel@tonic-gate "contains N2L prefix", name); 1780Sstevel@tonic-gate } 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate /* Save unqualified map name */ 1810Sstevel@tonic-gate map->map_name = strdup(q); 1820Sstevel@tonic-gate if (NULL == map->map_name) { 1830Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 1840Sstevel@tonic-gate "Could not duplicate map name %s", q); 1850Sstevel@tonic-gate return (FAILURE); 1860Sstevel@tonic-gate } 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate /* Work out map's domain name from path */ 1890Sstevel@tonic-gate for (q = p-1; (SEP_CHAR != *q) && (q > name); q--); 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate if (q <= name) { 1920Sstevel@tonic-gate /* Didn't find separator */ 1930Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1940Sstevel@tonic-gate "Could not find domain in map path %s", name); 1950Sstevel@tonic-gate return (FAILURE); 1960Sstevel@tonic-gate } 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate map->domain = (char *)am(myself, p - q); 1990Sstevel@tonic-gate if (NULL == map->domain) { 2000Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 2010Sstevel@tonic-gate "Could not alloc memory for domain in path %s", name); 2020Sstevel@tonic-gate return (FAILURE); 2030Sstevel@tonic-gate } 204*2189Ssdussud (void) strncpy(map->domain, q + 1, p-q-1); 2050Sstevel@tonic-gate map->domain[p-q-1] = '\0'; 2060Sstevel@tonic-gate 2070Sstevel@tonic-gate /* Work out extra names required by N2L */ 2080Sstevel@tonic-gate if (yptol_mode) { 2090Sstevel@tonic-gate /* 2100Sstevel@tonic-gate * Work out what old style NIS path would have been. This is 2110Sstevel@tonic-gate * used to check for date of DBM file so add the DBM 2120Sstevel@tonic-gate * extension. 2130Sstevel@tonic-gate */ 2140Sstevel@tonic-gate map->trad_map_path = (char *)am(myself, strlen(map->map_name) + 2150Sstevel@tonic-gate + strlen(dbm_pag) + (p - name) + 2); 2160Sstevel@tonic-gate if (NULL == map->trad_map_path) { 2170Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 2180Sstevel@tonic-gate "Could not alocate memory for " 2190Sstevel@tonic-gate "traditional map path derived from %s", name); 2200Sstevel@tonic-gate return (FAILURE); 2210Sstevel@tonic-gate } 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate strncpy(map->trad_map_path, name, p - name + 1); 2240Sstevel@tonic-gate map->trad_map_path[p - name + 1] = '\0'; 2250Sstevel@tonic-gate strcat(map->trad_map_path, map->map_name); 2260Sstevel@tonic-gate strcat(map->trad_map_path, dbm_pag); 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate /* Generate qualified TTL file name */ 2290Sstevel@tonic-gate map->ttl_path = (char *)am(myself, strlen(map->map_path) + 2300Sstevel@tonic-gate strlen(TTL_POSTFIX) + 1); 2310Sstevel@tonic-gate if (NULL == map->ttl_path) { 2320Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 2330Sstevel@tonic-gate "Could not alocate memory for " 2340Sstevel@tonic-gate "ttl path derived from %s", name); 2350Sstevel@tonic-gate return (FAILURE); 2360Sstevel@tonic-gate } 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate strcpy(map->ttl_path, map->map_path); 2390Sstevel@tonic-gate strcat(map->ttl_path, TTL_POSTFIX); 2400Sstevel@tonic-gate } 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate /* Work out hash value */ 2430Sstevel@tonic-gate map->hash_val = hash(name); 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate /* Set up magic number */ 2460Sstevel@tonic-gate map->magic = MAP_MAGIC; 2470Sstevel@tonic-gate 2480Sstevel@tonic-gate /* Null out pointers */ 2490Sstevel@tonic-gate map->entries = NULL; 2500Sstevel@tonic-gate map->ttl = NULL; 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate /* No key data yet */ 2530Sstevel@tonic-gate map->key_data.dptr = NULL; 2540Sstevel@tonic-gate map->key_data.dsize = 0; 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate return (SUCCESS); 2570Sstevel@tonic-gate } 2580Sstevel@tonic-gate 2590Sstevel@tonic-gate /* 2600Sstevel@tonic-gate * FUNCTION: get_map_crtl(); 2610Sstevel@tonic-gate * 2620Sstevel@tonic-gate * DESCRIPTION: Find an existing map_ctrl for a map of a given DBM * (i.e. 2630Sstevel@tonic-gate * handle) . If none exists return an error. 2640Sstevel@tonic-gate * 2650Sstevel@tonic-gate * INPUTS: Map handle 2660Sstevel@tonic-gate * 2670Sstevel@tonic-gate * OUTPUTS: Pointer to map_ctrl 2680Sstevel@tonic-gate * NULL on failure. 2690Sstevel@tonic-gate * 2700Sstevel@tonic-gate */ 2710Sstevel@tonic-gate map_ctrl * 2720Sstevel@tonic-gate get_map_ctrl(DBM *db) 2730Sstevel@tonic-gate { 2740Sstevel@tonic-gate /* Check that this really is a map_ctrl not a DBM */ 2750Sstevel@tonic-gate if (((map_ctrl *)db)->magic != MAP_MAGIC) { 2760Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 2770Sstevel@tonic-gate "SHIM called with DBM ptr not map_crtl ptr"); 2780Sstevel@tonic-gate return (NULL); 2790Sstevel@tonic-gate } 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate /* Since this is an opaque pointer just cast it */ 2820Sstevel@tonic-gate return ((map_ctrl *)db); 2830Sstevel@tonic-gate } 2840Sstevel@tonic-gate 2850Sstevel@tonic-gate /* 2860Sstevel@tonic-gate * FUNCTION: dup_map_ctrl() 2870Sstevel@tonic-gate * 2880Sstevel@tonic-gate * DESCRIPTION: Duplicates a map_ctrl structure 2890Sstevel@tonic-gate * 2900Sstevel@tonic-gate * GIVEN : Map_ctrl to duplicate 2910Sstevel@tonic-gate * 2920Sstevel@tonic-gate * RETURNS : Pointer to a new malloced map_ctrl. CALLER MUST FREE 2930Sstevel@tonic-gate * NULL on failure. 2940Sstevel@tonic-gate */ 2950Sstevel@tonic-gate map_ctrl * 2960Sstevel@tonic-gate dup_map_ctrl(map_ctrl *old_map) 2970Sstevel@tonic-gate { 2980Sstevel@tonic-gate map_ctrl *new_map; 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate /* 3010Sstevel@tonic-gate * Could save a little bit of time by duplicating the static parts 3020Sstevel@tonic-gate * of the old map but on balance it is cleaner to just make a new one 3030Sstevel@tonic-gate * from scratch 3040Sstevel@tonic-gate */ 3050Sstevel@tonic-gate new_map = create_map_ctrl(old_map->map_path); 3060Sstevel@tonic-gate 3070Sstevel@tonic-gate if (NULL == new_map) 3080Sstevel@tonic-gate return (NULL); 3090Sstevel@tonic-gate 3100Sstevel@tonic-gate /* If old map had open handles duplicate them */ 3110Sstevel@tonic-gate if (NULL != old_map->entries) { 3120Sstevel@tonic-gate new_map->open_flags = old_map->open_flags; 3130Sstevel@tonic-gate new_map->open_mode = old_map->open_mode; 3140Sstevel@tonic-gate if (FAILURE == open_yptol_files(new_map)) { 3150Sstevel@tonic-gate free_map_ctrl(new_map); 3160Sstevel@tonic-gate return (NULL); 3170Sstevel@tonic-gate } 3180Sstevel@tonic-gate } 3190Sstevel@tonic-gate 3200Sstevel@tonic-gate return (new_map); 3210Sstevel@tonic-gate } 3220Sstevel@tonic-gate 3230Sstevel@tonic-gate /* 3240Sstevel@tonic-gate * FUNCTION: free_map_crtl(); 3250Sstevel@tonic-gate * 3260Sstevel@tonic-gate * DESCRIPTION: Free contents of a map_ctr structure and closed any open 3270Sstevel@tonic-gate * DBM files. 3280Sstevel@tonic-gate * 3290Sstevel@tonic-gate * INPUTS: Pointer to pointer to a map_ctrl. 3300Sstevel@tonic-gate * 3310Sstevel@tonic-gate * OUTPUTS: Nothing 3320Sstevel@tonic-gate * 3330Sstevel@tonic-gate */ 3340Sstevel@tonic-gate void 3350Sstevel@tonic-gate free_map_ctrl(map_ctrl *map) 3360Sstevel@tonic-gate { 3370Sstevel@tonic-gate 3380Sstevel@tonic-gate if (NULL != map->entries) { 3390Sstevel@tonic-gate dbm_close(map->entries); 3400Sstevel@tonic-gate map->entries = NULL; 3410Sstevel@tonic-gate } 3420Sstevel@tonic-gate 3430Sstevel@tonic-gate if (NULL != map->map_name) { 3440Sstevel@tonic-gate sfree(map->map_name); 3450Sstevel@tonic-gate map->map_name = NULL; 3460Sstevel@tonic-gate } 3470Sstevel@tonic-gate 3480Sstevel@tonic-gate if (NULL != map->map_path) { 3490Sstevel@tonic-gate sfree(map->map_path); 3500Sstevel@tonic-gate map->map_path = NULL; 3510Sstevel@tonic-gate } 3520Sstevel@tonic-gate 3530Sstevel@tonic-gate if (NULL != map->domain) { 3540Sstevel@tonic-gate sfree(map->domain); 3550Sstevel@tonic-gate map->domain = NULL; 3560Sstevel@tonic-gate } 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate if (yptol_mode) { 3590Sstevel@tonic-gate if (NULL != map->ttl) { 3600Sstevel@tonic-gate dbm_close(map->ttl); 3610Sstevel@tonic-gate map->ttl = NULL; 3620Sstevel@tonic-gate } 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate if (NULL != map->trad_map_path) { 3650Sstevel@tonic-gate sfree(map->trad_map_path); 3660Sstevel@tonic-gate map->trad_map_path = NULL; 3670Sstevel@tonic-gate } 3680Sstevel@tonic-gate 3690Sstevel@tonic-gate if (NULL != map->ttl_path) { 3700Sstevel@tonic-gate sfree(map->ttl_path); 3710Sstevel@tonic-gate map->ttl_path = NULL; 3720Sstevel@tonic-gate } 3730Sstevel@tonic-gate 3740Sstevel@tonic-gate if (NULL != map->key_data.dptr) { 3750Sstevel@tonic-gate sfree(map->key_data.dptr); 3760Sstevel@tonic-gate map->key_data.dptr = NULL; 3770Sstevel@tonic-gate map->key_data.dsize = 0; 3780Sstevel@tonic-gate } 3790Sstevel@tonic-gate } 3800Sstevel@tonic-gate 3810Sstevel@tonic-gate map->magic = 0; 3820Sstevel@tonic-gate 3830Sstevel@tonic-gate /* Since map_ctrls are now always in malloced memory */ 3840Sstevel@tonic-gate sfree(map); 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate } 3870Sstevel@tonic-gate 3880Sstevel@tonic-gate /* 3890Sstevel@tonic-gate * FUNCTION : get_map_name() 3900Sstevel@tonic-gate * 3910Sstevel@tonic-gate * DESCRIPTION: Get the name of a map from its map_ctrl. This could be done 3920Sstevel@tonic-gate * as a simple dereference but this function hides the internal 3930Sstevel@tonic-gate * implementation of map_ctrl from higher layers. 3940Sstevel@tonic-gate * 3950Sstevel@tonic-gate * GIVEN : A map_ctrl pointer 3960Sstevel@tonic-gate * 3970Sstevel@tonic-gate * RETURNS : A pointer to the map_ctrl. Higher levels treat this as an 3980Sstevel@tonic-gate * opaque DBM pointer. 3990Sstevel@tonic-gate * NULL on failure. 4000Sstevel@tonic-gate */ 4010Sstevel@tonic-gate char * 4020Sstevel@tonic-gate get_map_name(DBM *db) 4030Sstevel@tonic-gate { 4040Sstevel@tonic-gate map_ctrl *map = (map_ctrl *)db; 4050Sstevel@tonic-gate 4060Sstevel@tonic-gate if (NULL == map) 4070Sstevel@tonic-gate return (NULL); 4080Sstevel@tonic-gate 4090Sstevel@tonic-gate return (map->map_name); 4100Sstevel@tonic-gate } 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate /* 4130Sstevel@tonic-gate * FUNCTION : set_key_data() 4140Sstevel@tonic-gate * 4150Sstevel@tonic-gate * DESCRIPTION: Sets up the key data freeing any that already exists. 4160Sstevel@tonic-gate * 4170Sstevel@tonic-gate * GIVEN : Pointer to the map_ctrl to set up. 4180Sstevel@tonic-gate * Datum containing the key. The dptr of this will be set to 4190Sstevel@tonic-gate * point to the key data. 4200Sstevel@tonic-gate * 4210Sstevel@tonic-gate * RETURNS : Nothing 4220Sstevel@tonic-gate */ 4230Sstevel@tonic-gate void 4240Sstevel@tonic-gate set_key_data(map_ctrl *map, datum *data) 4250Sstevel@tonic-gate { 4260Sstevel@tonic-gate char *myself = "set_key_data"; 4270Sstevel@tonic-gate 4280Sstevel@tonic-gate /* 4290Sstevel@tonic-gate * Free up any existing key data. Because each dbm file can only have 4300Sstevel@tonic-gate * one enumeration going at a time this is safe. 4310Sstevel@tonic-gate */ 4320Sstevel@tonic-gate if (NULL != map->key_data.dptr) { 4330Sstevel@tonic-gate sfree(map->key_data.dptr); 4340Sstevel@tonic-gate map->key_data.dptr = NULL; 4350Sstevel@tonic-gate map->key_data.dsize = 0; 4360Sstevel@tonic-gate } 4370Sstevel@tonic-gate 4380Sstevel@tonic-gate /* If nothing in key just return */ 4390Sstevel@tonic-gate if (NULL == data->dptr) 4400Sstevel@tonic-gate return; 4410Sstevel@tonic-gate 4420Sstevel@tonic-gate /* Something is in the key so must duplicate out of static memory */ 4430Sstevel@tonic-gate map->key_data.dptr = (char *)am(myself, data->dsize); 4440Sstevel@tonic-gate if (NULL == map->key_data.dptr) { 4450Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, "Cannot alloc memory for key data"); 4460Sstevel@tonic-gate } else { 4470Sstevel@tonic-gate memcpy(map->key_data.dptr, data->dptr, data->dsize); 4480Sstevel@tonic-gate map->key_data.dsize = data->dsize; 4490Sstevel@tonic-gate } 4500Sstevel@tonic-gate 4510Sstevel@tonic-gate /* Set datum to point to malloced version of the data */ 4520Sstevel@tonic-gate data->dptr = map->key_data.dptr; 4530Sstevel@tonic-gate 4540Sstevel@tonic-gate return; 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate } 4570Sstevel@tonic-gate 4580Sstevel@tonic-gate /* 4590Sstevel@tonic-gate * FUNCTION : open_yptol_files() 4600Sstevel@tonic-gate * 4610Sstevel@tonic-gate * DESCRIPTION: Opens both yptol files for a map. This is called both when a 4620Sstevel@tonic-gate * map is opened and when it is reopened as a result of an update 4630Sstevel@tonic-gate * operation. Must be called with map locked. 4640Sstevel@tonic-gate * 4650Sstevel@tonic-gate * GIVEN : Initialized map_ctrl 4660Sstevel@tonic-gate * 4670Sstevel@tonic-gate * RETURNS : SUCCESS = Maps opened 4680Sstevel@tonic-gate * FAILURE = Maps not opened (and mess tidied up) 4690Sstevel@tonic-gate */ 4700Sstevel@tonic-gate suc_code 4710Sstevel@tonic-gate open_yptol_files(map_ctrl *map) 4720Sstevel@tonic-gate { 4730Sstevel@tonic-gate 4740Sstevel@tonic-gate /* Open entries map */ 4750Sstevel@tonic-gate map->entries = dbm_open(map->map_path, map->open_flags, map->open_mode); 4760Sstevel@tonic-gate 4770Sstevel@tonic-gate if (NULL == map->entries) { 4780Sstevel@tonic-gate /* Maybe we were asked to open a non-existent map. No problem */ 4790Sstevel@tonic-gate return (FAILURE); 4800Sstevel@tonic-gate } 4810Sstevel@tonic-gate 4820Sstevel@tonic-gate if (yptol_mode) { 4830Sstevel@tonic-gate /* Open TTLs map. Must always be writable */ 4840Sstevel@tonic-gate map->ttl = dbm_open(map->ttl_path, O_RDWR | O_CREAT, 0644); 4850Sstevel@tonic-gate if (NULL == map->ttl) { 4860Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 4870Sstevel@tonic-gate "Cannot open TTL file %s", map->ttl_path); 4880Sstevel@tonic-gate dbm_close(map->entries); 4890Sstevel@tonic-gate map->entries = NULL; 4900Sstevel@tonic-gate return (FAILURE); 4910Sstevel@tonic-gate } 4920Sstevel@tonic-gate } 4930Sstevel@tonic-gate 4940Sstevel@tonic-gate return (SUCCESS); 4950Sstevel@tonic-gate } 496*2189Ssdussud 497*2189Ssdussud /* 498*2189Ssdussud * FUNCTION : insert_map_in_list() 499*2189Ssdussud * 500*2189Ssdussud * DESCRIPTION: add a map in map_id_list[] 501*2189Ssdussud * 502*2189Ssdussud * GIVEN : map name 503*2189Ssdussud * map unique ID 504*2189Ssdussud * 505*2189Ssdussud * RETURNS : SUCCESS = map added 506*2189Ssdussud * FAILURE = map not added 507*2189Ssdussud */ 508*2189Ssdussud suc_code 509*2189Ssdussud insert_map_in_list(char *map_name, int unique_value) 510*2189Ssdussud { 511*2189Ssdussud int index; 512*2189Ssdussud bool_t yptol_nl_sav = yptol_newlock; 513*2189Ssdussud map_id_elt_t *new_elt; 514*2189Ssdussud 515*2189Ssdussud /* 516*2189Ssdussud * Index in the hash table is computed from the original 517*2189Ssdussud * hash function: make sure yptol_newlock is set to false. 518*2189Ssdussud */ 519*2189Ssdussud yptol_newlock = FALSE; 520*2189Ssdussud index = hash(map_name); 521*2189Ssdussud yptol_newlock = yptol_nl_sav; 522*2189Ssdussud 523*2189Ssdussud new_elt = (map_id_elt_t *)calloc(1, sizeof (map_id_elt_t)); 524*2189Ssdussud if (new_elt == NULL) { 525*2189Ssdussud return (FAILURE); 526*2189Ssdussud } 527*2189Ssdussud new_elt->map_name = strdup(map_name); 528*2189Ssdussud if (new_elt->map_name == NULL) { /* strdup() failed */ 529*2189Ssdussud return (FAILURE); 530*2189Ssdussud } 531*2189Ssdussud new_elt->map_id = unique_value; 532*2189Ssdussud 533*2189Ssdussud if (map_id_list[index] == NULL) { 534*2189Ssdussud new_elt->next = NULL; 535*2189Ssdussud } else { 536*2189Ssdussud new_elt->next = map_id_list[index]; 537*2189Ssdussud } 538*2189Ssdussud /* insert at begining */ 539*2189Ssdussud map_id_list[index] = new_elt; 540*2189Ssdussud 541*2189Ssdussud return (SUCCESS); 542*2189Ssdussud } 543*2189Ssdussud 544*2189Ssdussud #ifdef NISDB_LDAP_DEBUG 545*2189Ssdussud /* 546*2189Ssdussud * FUNCTION : dump_map_id_list() 547*2189Ssdussud * 548*2189Ssdussud * DESCRIPTION: display max_map and dump map_id_list[] 549*2189Ssdussud * not called, here for debug convenience only 550*2189Ssdussud * 551*2189Ssdussud * GIVEN : nothing 552*2189Ssdussud * 553*2189Ssdussud * RETURNS : nothing 554*2189Ssdussud */ 555*2189Ssdussud void 556*2189Ssdussud dump_map_id_list() 557*2189Ssdussud { 558*2189Ssdussud int i; 559*2189Ssdussud map_id_elt_t *cur_elt; 560*2189Ssdussud 561*2189Ssdussud logmsg(MSG_NOTIMECHECK, LOG_DEBUG, 562*2189Ssdussud "dump_map_id_list: max_map is: %d, dumping map_idlist ...", 563*2189Ssdussud max_map); 564*2189Ssdussud 565*2189Ssdussud for (i = 0; i < MAXHASH; i++) { 566*2189Ssdussud if (map_id_list[i] == NULL) { 567*2189Ssdussud logmsg(MSG_NOTIMECHECK, LOG_DEBUG, 568*2189Ssdussud "no map for index %d", i); 569*2189Ssdussud } else { 570*2189Ssdussud logmsg(MSG_NOTIMECHECK, LOG_DEBUG, 571*2189Ssdussud "index %d has the following maps", i); 572*2189Ssdussud cur_elt = map_id_list[i]; 573*2189Ssdussud do { 574*2189Ssdussud logmsg(MSG_NOTIMECHECK, LOG_DEBUG, 575*2189Ssdussud "%s, unique id: %d", 576*2189Ssdussud cur_elt->map_name, 577*2189Ssdussud cur_elt->map_id); 578*2189Ssdussud cur_elt = cur_elt->next; 579*2189Ssdussud } while (cur_elt != NULL); 580*2189Ssdussud } 581*2189Ssdussud } 582*2189Ssdussud } 583*2189Ssdussud #endif 584*2189Ssdussud 585*2189Ssdussud /* 586*2189Ssdussud * FUNCTION : free_map_id_list() 587*2189Ssdussud * 588*2189Ssdussud * DESCRIPTION: free all previously allocated elements of map_id_list[] 589*2189Ssdussud * reset max_map to 0 590*2189Ssdussud * 591*2189Ssdussud * GIVEN : nothing 592*2189Ssdussud * 593*2189Ssdussud * RETURNS : nothing 594*2189Ssdussud */ 595*2189Ssdussud void 596*2189Ssdussud free_map_id_list() 597*2189Ssdussud { 598*2189Ssdussud int i; 599*2189Ssdussud map_id_elt_t *cur_elt, *next_elt; 600*2189Ssdussud 601*2189Ssdussud for (i = 0; i < MAXHASH; i++) { 602*2189Ssdussud if (map_id_list[i] != NULL) { 603*2189Ssdussud cur_elt = map_id_list[i]; 604*2189Ssdussud do { 605*2189Ssdussud next_elt = cur_elt->next; 606*2189Ssdussud if (cur_elt->map_name) 607*2189Ssdussud sfree(cur_elt->map_name); 608*2189Ssdussud sfree(cur_elt); 609*2189Ssdussud cur_elt = next_elt; 610*2189Ssdussud } while (cur_elt != NULL); 611*2189Ssdussud map_id_list[i] = NULL; 612*2189Ssdussud } 613*2189Ssdussud } 614*2189Ssdussud max_map = 0; 615*2189Ssdussud } 616*2189Ssdussud 617*2189Ssdussud /* 618*2189Ssdussud * FUNCTION : map_id_list_init() 619*2189Ssdussud * 620*2189Ssdussud * DESCRIPTION: initializes map_id_list[] and max_map 621*2189Ssdussud * 622*2189Ssdussud * GIVEN : nothing 623*2189Ssdussud * 624*2189Ssdussud * RETURNS : 0 if OK 625*2189Ssdussud * -1 if failure 626*2189Ssdussud */ 627*2189Ssdussud int 628*2189Ssdussud map_id_list_init() 629*2189Ssdussud { 630*2189Ssdussud char **domain_list, **map_list = NULL; 631*2189Ssdussud int domain_num; 632*2189Ssdussud int i, j; 633*2189Ssdussud char *myself = "map_id_list_init"; 634*2189Ssdussud char mapbuf[MAXPATHLEN]; 635*2189Ssdussud int mapbuf_len = sizeof (mapbuf); 636*2189Ssdussud int map_name_len; 637*2189Ssdussud int seqnum = 0; 638*2189Ssdussud int rc = 0; 639*2189Ssdussud 640*2189Ssdussud for (i = 0; i < MAXHASH; i++) { 641*2189Ssdussud map_id_list[i] = NULL; 642*2189Ssdussud } 643*2189Ssdussud 644*2189Ssdussud domain_num = get_mapping_domain_list(&domain_list); 645*2189Ssdussud for (i = 0; i < domain_num; i++) { 646*2189Ssdussud if (map_list) { 647*2189Ssdussud free_map_list(map_list); 648*2189Ssdussud map_list = NULL; 649*2189Ssdussud } 650*2189Ssdussud 651*2189Ssdussud /* get map list from mapping file */ 652*2189Ssdussud map_list = get_mapping_map_list(domain_list[i]); 653*2189Ssdussud if (map_list == NULL) { 654*2189Ssdussud /* no map for this domain in mapping file */ 655*2189Ssdussud logmsg(MSG_NOTIMECHECK, LOG_DEBUG, 656*2189Ssdussud "%s: get_mapping_map_list()" 657*2189Ssdussud " found no map for domain %s", 658*2189Ssdussud myself, domain_list[i]); 659*2189Ssdussud } 660*2189Ssdussud 661*2189Ssdussud /* add maps from /var/yp/<domain> */ 662*2189Ssdussud if (add_map_domain_to_list(domain_list[i], &map_list) == 663*2189Ssdussud FALSE) { 664*2189Ssdussud logmsg(MSG_NOTIMECHECK, LOG_ERR, 665*2189Ssdussud "%s: add_map_domain_to_list() failed", myself); 666*2189Ssdussud free_map_id_list(); 667*2189Ssdussud if (map_list) free_map_list(map_list); 668*2189Ssdussud return (-1); 669*2189Ssdussud } 670*2189Ssdussud 671*2189Ssdussud if (map_list == NULL || map_list[0] == NULL) { 672*2189Ssdussud logmsg(MSG_NOTIMECHECK, LOG_DEBUG, 673*2189Ssdussud "%s: no map in domain %s", 674*2189Ssdussud myself, domain_list[i]); 675*2189Ssdussud continue; 676*2189Ssdussud } 677*2189Ssdussud 678*2189Ssdussud for (j = 0; map_list[j] != NULL; j++) { 679*2189Ssdussud /* build long name */ 680*2189Ssdussud map_name_len = ypdbpath_sz + 1 + 681*2189Ssdussud strlen(domain_list[i]) + 1 + 682*2189Ssdussud strlen(NTOL_PREFIX) + 683*2189Ssdussud strlen(map_list[j]) + 1; 684*2189Ssdussud if (map_name_len > mapbuf_len) { 685*2189Ssdussud logmsg(MSG_NOTIMECHECK, LOG_ERR, 686*2189Ssdussud "%s: map name too long for %s", 687*2189Ssdussud " in domain %s", myself, map_list[j], 688*2189Ssdussud domain_list[i]); 689*2189Ssdussud free_map_id_list(); 690*2189Ssdussud if (map_list) free_map_list(map_list); 691*2189Ssdussud return (-1); 692*2189Ssdussud } 693*2189Ssdussud (void) memset(mapbuf, 0, mapbuf_len); 694*2189Ssdussud (void) snprintf(mapbuf, map_name_len, "%s%c%s%c%s%s", 695*2189Ssdussud ypdbpath, SEP_CHAR, domain_list[i], SEP_CHAR, 696*2189Ssdussud NTOL_PREFIX, map_list[j]); 697*2189Ssdussud 698*2189Ssdussud if (insert_map_in_list(mapbuf, seqnum) 699*2189Ssdussud == FAILURE) { 700*2189Ssdussud logmsg(MSG_NOTIMECHECK, LOG_ERR, 701*2189Ssdussud "%s: failed to insert map %s", 702*2189Ssdussud " in domain %s", myself, map_list[j]); 703*2189Ssdussud free_map_id_list(); 704*2189Ssdussud if (map_list) free_map_list(map_list); 705*2189Ssdussud return (-1); 706*2189Ssdussud } 707*2189Ssdussud seqnum++; 708*2189Ssdussud } 709*2189Ssdussud } 710*2189Ssdussud 711*2189Ssdussud max_map = seqnum; 712*2189Ssdussud 713*2189Ssdussud #ifdef NISDB_LDAP_DEBUG 714*2189Ssdussud dump_map_id_list(); 715*2189Ssdussud #endif 716*2189Ssdussud 717*2189Ssdussud /* 718*2189Ssdussud * If more maps than allocated spaces in shared memory, that's a failure 719*2189Ssdussud * probably need to free previously allocated memory if failure, 720*2189Ssdussud * before returning. 721*2189Ssdussud */ 722*2189Ssdussud if (max_map > MAXHASH) { 723*2189Ssdussud rc = -1; 724*2189Ssdussud logmsg(MSG_NOTIMECHECK, LOG_ERR, 725*2189Ssdussud "%s: too many maps (%d)", 726*2189Ssdussud myself, max_map); 727*2189Ssdussud free_map_id_list(); 728*2189Ssdussud } 729*2189Ssdussud if (map_list) free_map_list(map_list); 730*2189Ssdussud return (rc); 731*2189Ssdussud } 732*2189Ssdussud 733*2189Ssdussud /* 734*2189Ssdussud * FUNCTION : get_list_max() 735*2189Ssdussud * 736*2189Ssdussud * DESCRIPTION: return references to static variables map_id_list 737*2189Ssdussud * and max_map; 738*2189Ssdussud * 739*2189Ssdussud * GIVEN : address for referencing map_id_list 740*2189Ssdussud * address for referencing max_map 741*2189Ssdussud * 742*2189Ssdussud * RETURNS : nothing 743*2189Ssdussud */ 744*2189Ssdussud void 745*2189Ssdussud get_list_max(map_id_elt_t ***list, int *max) 746*2189Ssdussud { 747*2189Ssdussud *list = map_id_list; 748*2189Ssdussud *max = max_map; 749*2189Ssdussud } 750