17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 54a190493Ssdussud * Common Development and Distribution License (the "License"). 64a190493Ssdussud * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 224a190493Ssdussud * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate /* 297c478bd9Sstevel@tonic-gate * DESCRIPTION: Contains functions relating to the creation and manipulation 307c478bd9Sstevel@tonic-gate * of map_ctrl structures. These are used to hold information 317c478bd9Sstevel@tonic-gate * specific to one NIS map. 327c478bd9Sstevel@tonic-gate * 337c478bd9Sstevel@tonic-gate * Because each of these contains a significant amount of state 347c478bd9Sstevel@tonic-gate * information about an individual map they are created (on the 357c478bd9Sstevel@tonic-gate * heap) when a map is opened and destroyed when it is closed. 367c478bd9Sstevel@tonic-gate * The overhead of doing this is less than maintaining a pool 377c478bd9Sstevel@tonic-gate * of map_ctrls. 387c478bd9Sstevel@tonic-gate * 397c478bd9Sstevel@tonic-gate * If two processes access the same map two map_ctrls will be 407c478bd9Sstevel@tonic-gate * created with similar contents (but differing DBM pointers). 417c478bd9Sstevel@tonic-gate * Both will have the same hash value so when one is locked 427c478bd9Sstevel@tonic-gate * access to the other will also be prevented. 437c478bd9Sstevel@tonic-gate */ 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate #include <unistd.h> 464a190493Ssdussud #include <stdlib.h> 477c478bd9Sstevel@tonic-gate #include <syslog.h> 487c478bd9Sstevel@tonic-gate #include <ndbm.h> 497c478bd9Sstevel@tonic-gate #include <string.h> 504a190493Ssdussud #include <sys/param.h> 517c478bd9Sstevel@tonic-gate #include "ypsym.h" 527c478bd9Sstevel@tonic-gate #include "ypdefs.h" 537c478bd9Sstevel@tonic-gate #include "shim.h" 547c478bd9Sstevel@tonic-gate #include "yptol.h" 557c478bd9Sstevel@tonic-gate #include "../ldap_util.h" 567c478bd9Sstevel@tonic-gate 574a190493Ssdussud extern int hash(char *s); 584a190493Ssdussud extern bool_t add_map_domain_to_list(char *domain, char ***map_list); 594a190493Ssdussud 604a190493Ssdussud /* 614a190493Ssdussud * Static variables for locking mechanism in 624a190493Ssdussud * N2L mode. 634a190493Ssdussud * map_id_list: hash table for map lists 644a190493Ssdussud * max_map: max number of maps in map_id_list 654a190493Ssdussud * it is also used as the map ID for 664a190493Ssdussud * unknown maps, see get_map_id() 674a190493Ssdussud * in usr/src/cmd/ypcmd/shared/lockmap.c 684a190493Ssdussud */ 694a190493Ssdussud static map_id_elt_t *map_id_list[MAXHASH]; 704a190493Ssdussud static int max_map = 0; 714a190493Ssdussud 727c478bd9Sstevel@tonic-gate /* Switch on parts of ypdefs.h */ 737c478bd9Sstevel@tonic-gate USE_DBM 744a190493Ssdussud USE_YPDBPATH 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate /* 777c478bd9Sstevel@tonic-gate * FUNCTION: create_map_ctrl(); 787c478bd9Sstevel@tonic-gate * 797c478bd9Sstevel@tonic-gate * DESCRIPTION: Create and a new map_ctrl in a non opened state. 807c478bd9Sstevel@tonic-gate * 817c478bd9Sstevel@tonic-gate * INPUTS: Fully qualified map name 827c478bd9Sstevel@tonic-gate * 837c478bd9Sstevel@tonic-gate * OUTPUTS: Pointer to map_ctrl 847c478bd9Sstevel@tonic-gate * NULL on failure. 857c478bd9Sstevel@tonic-gate * 867c478bd9Sstevel@tonic-gate */ 877c478bd9Sstevel@tonic-gate map_ctrl * 887c478bd9Sstevel@tonic-gate create_map_ctrl(char *name) 897c478bd9Sstevel@tonic-gate { 907c478bd9Sstevel@tonic-gate char *myself = "create_map_ctrl"; 917c478bd9Sstevel@tonic-gate map_ctrl *map; 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate map = (map_ctrl *)am(myself, sizeof (map_ctrl)); 947c478bd9Sstevel@tonic-gate if (NULL == map) { 957c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, "Could not alloc map_ctrl"); 967c478bd9Sstevel@tonic-gate return (NULL); 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate /* Clear new map (in case we have to free it) */ 1007c478bd9Sstevel@tonic-gate map->entries = NULL; 1017c478bd9Sstevel@tonic-gate map->hash_val = 0; 1027c478bd9Sstevel@tonic-gate map->map_name = NULL; 1037c478bd9Sstevel@tonic-gate map->domain = NULL; 1047c478bd9Sstevel@tonic-gate map->map_path = NULL; 1057c478bd9Sstevel@tonic-gate map->ttl = NULL; 1067c478bd9Sstevel@tonic-gate map->ttl_path = NULL; 1077c478bd9Sstevel@tonic-gate map->trad_map_path = NULL; 1087c478bd9Sstevel@tonic-gate map->key_data.dptr = NULL; 1097c478bd9Sstevel@tonic-gate map->open_mode = 0; 1107c478bd9Sstevel@tonic-gate map->open_flags = 0; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate /* 1137c478bd9Sstevel@tonic-gate * Initialize the fields of the map_ctrl. By doing this once here we 1147c478bd9Sstevel@tonic-gate * can save a lot of work as map entries are accessed. 1157c478bd9Sstevel@tonic-gate */ 1167c478bd9Sstevel@tonic-gate if (SUCCESS != map_ctrl_init(map, name)) { 1177c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1187c478bd9Sstevel@tonic-gate "Could not initialize map_ctrl for %s", name); 1197c478bd9Sstevel@tonic-gate free_map_ctrl(map); 1207c478bd9Sstevel@tonic-gate return (NULL); 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate return (map); 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate /* 1277c478bd9Sstevel@tonic-gate * FUNCTION : map_ctrl_init() 1287c478bd9Sstevel@tonic-gate * 1297c478bd9Sstevel@tonic-gate * DESCRIPTION: Initializes the fields of a map_ctrl structure. 1307c478bd9Sstevel@tonic-gate * 1317c478bd9Sstevel@tonic-gate * By doing this once (when the map_ctrl is created) we avoid 1327c478bd9Sstevel@tonic-gate * numerous other function having to repeat this string 1337c478bd9Sstevel@tonic-gate * manipulation. 1347c478bd9Sstevel@tonic-gate * 1357c478bd9Sstevel@tonic-gate * GIVEN : Pointer to the structure 1367c478bd9Sstevel@tonic-gate * Fully qualified name of the map 1377c478bd9Sstevel@tonic-gate * 1387c478bd9Sstevel@tonic-gate * RETURNS : SUCCESS = map_ctrl fully set up. 1397c478bd9Sstevel@tonic-gate * FAILURE = map_ctrl not set up CALLER MUST FREE. 1407c478bd9Sstevel@tonic-gate */ 1417c478bd9Sstevel@tonic-gate suc_code 1427c478bd9Sstevel@tonic-gate map_ctrl_init(map_ctrl *map, char *name) 1437c478bd9Sstevel@tonic-gate { 1447c478bd9Sstevel@tonic-gate char *myself = "map_ctrl_init"; 1457c478bd9Sstevel@tonic-gate char *p, *q; 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate /* Save map path for future reference */ 1487c478bd9Sstevel@tonic-gate map->map_path = (char *)strdup(name); 1497c478bd9Sstevel@tonic-gate if (NULL == map->map_path) { 1507c478bd9Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 1517c478bd9Sstevel@tonic-gate "Could not duplicate map path %s", map); 1527c478bd9Sstevel@tonic-gate return (FAILURE); 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate /* Work out map's unqualified name from path */ 1567c478bd9Sstevel@tonic-gate p = strrchr(name, SEP_CHAR); 1577c478bd9Sstevel@tonic-gate if (NULL == p) { 1587c478bd9Sstevel@tonic-gate /* Must be at least a domain and name */ 1597c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1607c478bd9Sstevel@tonic-gate "Could not find separator in map path %s", map); 1617c478bd9Sstevel@tonic-gate return (FAILURE); 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate q = p + 1; 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate /* Check for and remove N2L prefix */ 1667c478bd9Sstevel@tonic-gate if (yptol_mode) { 1677c478bd9Sstevel@tonic-gate /* 1687c478bd9Sstevel@tonic-gate * Check for and remove N2L prefix. If not found not a problem 1697c478bd9Sstevel@tonic-gate * we open some old style maps during DIT initialization. 1707c478bd9Sstevel@tonic-gate */ 1717c478bd9Sstevel@tonic-gate if (0 == strncmp(q, NTOL_PREFIX, strlen(NTOL_PREFIX))) 1727c478bd9Sstevel@tonic-gate q += strlen(NTOL_PREFIX); 1737c478bd9Sstevel@tonic-gate } else { 1747c478bd9Sstevel@tonic-gate if (0 == strncmp(q, NTOL_PREFIX, strlen(NTOL_PREFIX))) 1757c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1767c478bd9Sstevel@tonic-gate "Working in non N2L mode and path %s " 1777c478bd9Sstevel@tonic-gate "contains N2L prefix", name); 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate /* Save unqualified map name */ 1817c478bd9Sstevel@tonic-gate map->map_name = strdup(q); 1827c478bd9Sstevel@tonic-gate if (NULL == map->map_name) { 1837c478bd9Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 1847c478bd9Sstevel@tonic-gate "Could not duplicate map name %s", q); 1857c478bd9Sstevel@tonic-gate return (FAILURE); 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate /* Work out map's domain name from path */ 1897c478bd9Sstevel@tonic-gate for (q = p-1; (SEP_CHAR != *q) && (q > name); q--); 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate if (q <= name) { 1927c478bd9Sstevel@tonic-gate /* Didn't find separator */ 1937c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1947c478bd9Sstevel@tonic-gate "Could not find domain in map path %s", name); 1957c478bd9Sstevel@tonic-gate return (FAILURE); 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate map->domain = (char *)am(myself, p - q); 1997c478bd9Sstevel@tonic-gate if (NULL == map->domain) { 2007c478bd9Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 2017c478bd9Sstevel@tonic-gate "Could not alloc memory for domain in path %s", name); 2027c478bd9Sstevel@tonic-gate return (FAILURE); 2037c478bd9Sstevel@tonic-gate } 2044a190493Ssdussud (void) strncpy(map->domain, q + 1, p-q-1); 2057c478bd9Sstevel@tonic-gate map->domain[p-q-1] = '\0'; 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate /* Work out extra names required by N2L */ 2087c478bd9Sstevel@tonic-gate if (yptol_mode) { 2097c478bd9Sstevel@tonic-gate /* 2107c478bd9Sstevel@tonic-gate * Work out what old style NIS path would have been. This is 2117c478bd9Sstevel@tonic-gate * used to check for date of DBM file so add the DBM 2127c478bd9Sstevel@tonic-gate * extension. 2137c478bd9Sstevel@tonic-gate */ 2147c478bd9Sstevel@tonic-gate map->trad_map_path = (char *)am(myself, strlen(map->map_name) + 2157c478bd9Sstevel@tonic-gate + strlen(dbm_pag) + (p - name) + 2); 2167c478bd9Sstevel@tonic-gate if (NULL == map->trad_map_path) { 2177c478bd9Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 2187c478bd9Sstevel@tonic-gate "Could not alocate memory for " 2197c478bd9Sstevel@tonic-gate "traditional map path derived from %s", name); 2207c478bd9Sstevel@tonic-gate return (FAILURE); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate strncpy(map->trad_map_path, name, p - name + 1); 2247c478bd9Sstevel@tonic-gate map->trad_map_path[p - name + 1] = '\0'; 2257c478bd9Sstevel@tonic-gate strcat(map->trad_map_path, map->map_name); 2267c478bd9Sstevel@tonic-gate strcat(map->trad_map_path, dbm_pag); 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate /* Generate qualified TTL file name */ 2297c478bd9Sstevel@tonic-gate map->ttl_path = (char *)am(myself, strlen(map->map_path) + 2307c478bd9Sstevel@tonic-gate strlen(TTL_POSTFIX) + 1); 2317c478bd9Sstevel@tonic-gate if (NULL == map->ttl_path) { 2327c478bd9Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 2337c478bd9Sstevel@tonic-gate "Could not alocate memory for " 2347c478bd9Sstevel@tonic-gate "ttl path derived from %s", name); 2357c478bd9Sstevel@tonic-gate return (FAILURE); 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate strcpy(map->ttl_path, map->map_path); 2397c478bd9Sstevel@tonic-gate strcat(map->ttl_path, TTL_POSTFIX); 2407c478bd9Sstevel@tonic-gate } 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate /* Work out hash value */ 2437c478bd9Sstevel@tonic-gate map->hash_val = hash(name); 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate /* Set up magic number */ 2467c478bd9Sstevel@tonic-gate map->magic = MAP_MAGIC; 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate /* Null out pointers */ 2497c478bd9Sstevel@tonic-gate map->entries = NULL; 2507c478bd9Sstevel@tonic-gate map->ttl = NULL; 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate /* No key data yet */ 2537c478bd9Sstevel@tonic-gate map->key_data.dptr = NULL; 2547c478bd9Sstevel@tonic-gate map->key_data.dsize = 0; 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate return (SUCCESS); 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate /* 2607c478bd9Sstevel@tonic-gate * FUNCTION: get_map_crtl(); 2617c478bd9Sstevel@tonic-gate * 2627c478bd9Sstevel@tonic-gate * DESCRIPTION: Find an existing map_ctrl for a map of a given DBM * (i.e. 2637c478bd9Sstevel@tonic-gate * handle) . If none exists return an error. 2647c478bd9Sstevel@tonic-gate * 2657c478bd9Sstevel@tonic-gate * INPUTS: Map handle 2667c478bd9Sstevel@tonic-gate * 2677c478bd9Sstevel@tonic-gate * OUTPUTS: Pointer to map_ctrl 2687c478bd9Sstevel@tonic-gate * NULL on failure. 2697c478bd9Sstevel@tonic-gate * 2707c478bd9Sstevel@tonic-gate */ 2717c478bd9Sstevel@tonic-gate map_ctrl * 2727c478bd9Sstevel@tonic-gate get_map_ctrl(DBM *db) 2737c478bd9Sstevel@tonic-gate { 2747c478bd9Sstevel@tonic-gate /* Check that this really is a map_ctrl not a DBM */ 2757c478bd9Sstevel@tonic-gate if (((map_ctrl *)db)->magic != MAP_MAGIC) { 2767c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 2777c478bd9Sstevel@tonic-gate "SHIM called with DBM ptr not map_crtl ptr"); 2787c478bd9Sstevel@tonic-gate return (NULL); 2797c478bd9Sstevel@tonic-gate } 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate /* Since this is an opaque pointer just cast it */ 2827c478bd9Sstevel@tonic-gate return ((map_ctrl *)db); 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate /* 2867c478bd9Sstevel@tonic-gate * FUNCTION: dup_map_ctrl() 2877c478bd9Sstevel@tonic-gate * 2887c478bd9Sstevel@tonic-gate * DESCRIPTION: Duplicates a map_ctrl structure 2897c478bd9Sstevel@tonic-gate * 2907c478bd9Sstevel@tonic-gate * GIVEN : Map_ctrl to duplicate 2917c478bd9Sstevel@tonic-gate * 2927c478bd9Sstevel@tonic-gate * RETURNS : Pointer to a new malloced map_ctrl. CALLER MUST FREE 2937c478bd9Sstevel@tonic-gate * NULL on failure. 2947c478bd9Sstevel@tonic-gate */ 2957c478bd9Sstevel@tonic-gate map_ctrl * 2967c478bd9Sstevel@tonic-gate dup_map_ctrl(map_ctrl *old_map) 2977c478bd9Sstevel@tonic-gate { 2987c478bd9Sstevel@tonic-gate map_ctrl *new_map; 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate /* 3017c478bd9Sstevel@tonic-gate * Could save a little bit of time by duplicating the static parts 3027c478bd9Sstevel@tonic-gate * of the old map but on balance it is cleaner to just make a new one 3037c478bd9Sstevel@tonic-gate * from scratch 3047c478bd9Sstevel@tonic-gate */ 3057c478bd9Sstevel@tonic-gate new_map = create_map_ctrl(old_map->map_path); 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate if (NULL == new_map) 3087c478bd9Sstevel@tonic-gate return (NULL); 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate /* If old map had open handles duplicate them */ 3117c478bd9Sstevel@tonic-gate if (NULL != old_map->entries) { 3127c478bd9Sstevel@tonic-gate new_map->open_flags = old_map->open_flags; 3137c478bd9Sstevel@tonic-gate new_map->open_mode = old_map->open_mode; 3147c478bd9Sstevel@tonic-gate if (FAILURE == open_yptol_files(new_map)) { 3157c478bd9Sstevel@tonic-gate free_map_ctrl(new_map); 3167c478bd9Sstevel@tonic-gate return (NULL); 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate return (new_map); 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate /* 3247c478bd9Sstevel@tonic-gate * FUNCTION: free_map_crtl(); 3257c478bd9Sstevel@tonic-gate * 3267c478bd9Sstevel@tonic-gate * DESCRIPTION: Free contents of a map_ctr structure and closed any open 3277c478bd9Sstevel@tonic-gate * DBM files. 3287c478bd9Sstevel@tonic-gate * 3297c478bd9Sstevel@tonic-gate * INPUTS: Pointer to pointer to a map_ctrl. 3307c478bd9Sstevel@tonic-gate * 3317c478bd9Sstevel@tonic-gate * OUTPUTS: Nothing 3327c478bd9Sstevel@tonic-gate * 3337c478bd9Sstevel@tonic-gate */ 3347c478bd9Sstevel@tonic-gate void 3357c478bd9Sstevel@tonic-gate free_map_ctrl(map_ctrl *map) 3367c478bd9Sstevel@tonic-gate { 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate if (NULL != map->entries) { 3397c478bd9Sstevel@tonic-gate dbm_close(map->entries); 3407c478bd9Sstevel@tonic-gate map->entries = NULL; 3417c478bd9Sstevel@tonic-gate } 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate if (NULL != map->map_name) { 3447c478bd9Sstevel@tonic-gate sfree(map->map_name); 3457c478bd9Sstevel@tonic-gate map->map_name = NULL; 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate if (NULL != map->map_path) { 3497c478bd9Sstevel@tonic-gate sfree(map->map_path); 3507c478bd9Sstevel@tonic-gate map->map_path = NULL; 3517c478bd9Sstevel@tonic-gate } 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate if (NULL != map->domain) { 3547c478bd9Sstevel@tonic-gate sfree(map->domain); 3557c478bd9Sstevel@tonic-gate map->domain = NULL; 3567c478bd9Sstevel@tonic-gate } 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate if (yptol_mode) { 3597c478bd9Sstevel@tonic-gate if (NULL != map->ttl) { 3607c478bd9Sstevel@tonic-gate dbm_close(map->ttl); 3617c478bd9Sstevel@tonic-gate map->ttl = NULL; 3627c478bd9Sstevel@tonic-gate } 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate if (NULL != map->trad_map_path) { 3657c478bd9Sstevel@tonic-gate sfree(map->trad_map_path); 3667c478bd9Sstevel@tonic-gate map->trad_map_path = NULL; 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate if (NULL != map->ttl_path) { 3707c478bd9Sstevel@tonic-gate sfree(map->ttl_path); 3717c478bd9Sstevel@tonic-gate map->ttl_path = NULL; 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate if (NULL != map->key_data.dptr) { 3757c478bd9Sstevel@tonic-gate sfree(map->key_data.dptr); 3767c478bd9Sstevel@tonic-gate map->key_data.dptr = NULL; 3777c478bd9Sstevel@tonic-gate map->key_data.dsize = 0; 3787c478bd9Sstevel@tonic-gate } 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate map->magic = 0; 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate /* Since map_ctrls are now always in malloced memory */ 3847c478bd9Sstevel@tonic-gate sfree(map); 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate /* 3897c478bd9Sstevel@tonic-gate * FUNCTION : get_map_name() 3907c478bd9Sstevel@tonic-gate * 3917c478bd9Sstevel@tonic-gate * DESCRIPTION: Get the name of a map from its map_ctrl. This could be done 3927c478bd9Sstevel@tonic-gate * as a simple dereference but this function hides the internal 3937c478bd9Sstevel@tonic-gate * implementation of map_ctrl from higher layers. 3947c478bd9Sstevel@tonic-gate * 3957c478bd9Sstevel@tonic-gate * GIVEN : A map_ctrl pointer 3967c478bd9Sstevel@tonic-gate * 3977c478bd9Sstevel@tonic-gate * RETURNS : A pointer to the map_ctrl. Higher levels treat this as an 3987c478bd9Sstevel@tonic-gate * opaque DBM pointer. 3997c478bd9Sstevel@tonic-gate * NULL on failure. 4007c478bd9Sstevel@tonic-gate */ 4017c478bd9Sstevel@tonic-gate char * 4027c478bd9Sstevel@tonic-gate get_map_name(DBM *db) 4037c478bd9Sstevel@tonic-gate { 4047c478bd9Sstevel@tonic-gate map_ctrl *map = (map_ctrl *)db; 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate if (NULL == map) 4077c478bd9Sstevel@tonic-gate return (NULL); 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate return (map->map_name); 4107c478bd9Sstevel@tonic-gate } 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate /* 4137c478bd9Sstevel@tonic-gate * FUNCTION : set_key_data() 4147c478bd9Sstevel@tonic-gate * 4157c478bd9Sstevel@tonic-gate * DESCRIPTION: Sets up the key data freeing any that already exists. 4167c478bd9Sstevel@tonic-gate * 4177c478bd9Sstevel@tonic-gate * GIVEN : Pointer to the map_ctrl to set up. 4187c478bd9Sstevel@tonic-gate * Datum containing the key. The dptr of this will be set to 4197c478bd9Sstevel@tonic-gate * point to the key data. 4207c478bd9Sstevel@tonic-gate * 4217c478bd9Sstevel@tonic-gate * RETURNS : Nothing 4227c478bd9Sstevel@tonic-gate */ 4237c478bd9Sstevel@tonic-gate void 4247c478bd9Sstevel@tonic-gate set_key_data(map_ctrl *map, datum *data) 4257c478bd9Sstevel@tonic-gate { 4267c478bd9Sstevel@tonic-gate char *myself = "set_key_data"; 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate /* 4297c478bd9Sstevel@tonic-gate * Free up any existing key data. Because each dbm file can only have 4307c478bd9Sstevel@tonic-gate * one enumeration going at a time this is safe. 4317c478bd9Sstevel@tonic-gate */ 4327c478bd9Sstevel@tonic-gate if (NULL != map->key_data.dptr) { 4337c478bd9Sstevel@tonic-gate sfree(map->key_data.dptr); 4347c478bd9Sstevel@tonic-gate map->key_data.dptr = NULL; 4357c478bd9Sstevel@tonic-gate map->key_data.dsize = 0; 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate /* If nothing in key just return */ 4397c478bd9Sstevel@tonic-gate if (NULL == data->dptr) 4407c478bd9Sstevel@tonic-gate return; 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate /* Something is in the key so must duplicate out of static memory */ 4437c478bd9Sstevel@tonic-gate map->key_data.dptr = (char *)am(myself, data->dsize); 4447c478bd9Sstevel@tonic-gate if (NULL == map->key_data.dptr) { 4457c478bd9Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, "Cannot alloc memory for key data"); 4467c478bd9Sstevel@tonic-gate } else { 4477c478bd9Sstevel@tonic-gate memcpy(map->key_data.dptr, data->dptr, data->dsize); 4487c478bd9Sstevel@tonic-gate map->key_data.dsize = data->dsize; 4497c478bd9Sstevel@tonic-gate } 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate /* Set datum to point to malloced version of the data */ 4527c478bd9Sstevel@tonic-gate data->dptr = map->key_data.dptr; 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate return; 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate /* 4597c478bd9Sstevel@tonic-gate * FUNCTION : open_yptol_files() 4607c478bd9Sstevel@tonic-gate * 4617c478bd9Sstevel@tonic-gate * DESCRIPTION: Opens both yptol files for a map. This is called both when a 4627c478bd9Sstevel@tonic-gate * map is opened and when it is reopened as a result of an update 4637c478bd9Sstevel@tonic-gate * operation. Must be called with map locked. 4647c478bd9Sstevel@tonic-gate * 4657c478bd9Sstevel@tonic-gate * GIVEN : Initialized map_ctrl 4667c478bd9Sstevel@tonic-gate * 4677c478bd9Sstevel@tonic-gate * RETURNS : SUCCESS = Maps opened 4687c478bd9Sstevel@tonic-gate * FAILURE = Maps not opened (and mess tidied up) 4697c478bd9Sstevel@tonic-gate */ 4707c478bd9Sstevel@tonic-gate suc_code 4717c478bd9Sstevel@tonic-gate open_yptol_files(map_ctrl *map) 4727c478bd9Sstevel@tonic-gate { 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate /* Open entries map */ 4757c478bd9Sstevel@tonic-gate map->entries = dbm_open(map->map_path, map->open_flags, map->open_mode); 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate if (NULL == map->entries) { 4787c478bd9Sstevel@tonic-gate /* Maybe we were asked to open a non-existent map. No problem */ 4797c478bd9Sstevel@tonic-gate return (FAILURE); 4807c478bd9Sstevel@tonic-gate } 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate if (yptol_mode) { 4837c478bd9Sstevel@tonic-gate /* Open TTLs map. Must always be writable */ 4847c478bd9Sstevel@tonic-gate map->ttl = dbm_open(map->ttl_path, O_RDWR | O_CREAT, 0644); 4857c478bd9Sstevel@tonic-gate if (NULL == map->ttl) { 4867c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 4877c478bd9Sstevel@tonic-gate "Cannot open TTL file %s", map->ttl_path); 4887c478bd9Sstevel@tonic-gate dbm_close(map->entries); 4897c478bd9Sstevel@tonic-gate map->entries = NULL; 4907c478bd9Sstevel@tonic-gate return (FAILURE); 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate return (SUCCESS); 4957c478bd9Sstevel@tonic-gate } 4964a190493Ssdussud 4974a190493Ssdussud /* 4984a190493Ssdussud * FUNCTION : insert_map_in_list() 4994a190493Ssdussud * 5004a190493Ssdussud * DESCRIPTION: add a map in map_id_list[] 5014a190493Ssdussud * 5024a190493Ssdussud * GIVEN : map name 5034a190493Ssdussud * map unique ID 5044a190493Ssdussud * 5054a190493Ssdussud * RETURNS : SUCCESS = map added 5064a190493Ssdussud * FAILURE = map not added 5074a190493Ssdussud */ 5084a190493Ssdussud suc_code 5094a190493Ssdussud insert_map_in_list(char *map_name, int unique_value) 5104a190493Ssdussud { 5114a190493Ssdussud int index; 5124a190493Ssdussud bool_t yptol_nl_sav = yptol_newlock; 5134a190493Ssdussud map_id_elt_t *new_elt; 5144a190493Ssdussud 5154a190493Ssdussud /* 5164a190493Ssdussud * Index in the hash table is computed from the original 5174a190493Ssdussud * hash function: make sure yptol_newlock is set to false. 5184a190493Ssdussud */ 5194a190493Ssdussud yptol_newlock = FALSE; 5204a190493Ssdussud index = hash(map_name); 5214a190493Ssdussud yptol_newlock = yptol_nl_sav; 5224a190493Ssdussud 5234a190493Ssdussud new_elt = (map_id_elt_t *)calloc(1, sizeof (map_id_elt_t)); 5244a190493Ssdussud if (new_elt == NULL) { 5254a190493Ssdussud return (FAILURE); 5264a190493Ssdussud } 5274a190493Ssdussud new_elt->map_name = strdup(map_name); 5284a190493Ssdussud if (new_elt->map_name == NULL) { /* strdup() failed */ 529*c5a865cbSsdussud sfree(new_elt); 5304a190493Ssdussud return (FAILURE); 5314a190493Ssdussud } 5324a190493Ssdussud new_elt->map_id = unique_value; 5334a190493Ssdussud 5344a190493Ssdussud if (map_id_list[index] == NULL) { 5354a190493Ssdussud new_elt->next = NULL; 5364a190493Ssdussud } else { 5374a190493Ssdussud new_elt->next = map_id_list[index]; 5384a190493Ssdussud } 5394a190493Ssdussud /* insert at begining */ 5404a190493Ssdussud map_id_list[index] = new_elt; 5414a190493Ssdussud 5424a190493Ssdussud return (SUCCESS); 5434a190493Ssdussud } 5444a190493Ssdussud 5454a190493Ssdussud #ifdef NISDB_LDAP_DEBUG 5464a190493Ssdussud /* 5474a190493Ssdussud * FUNCTION : dump_map_id_list() 5484a190493Ssdussud * 5494a190493Ssdussud * DESCRIPTION: display max_map and dump map_id_list[] 5504a190493Ssdussud * not called, here for debug convenience only 5514a190493Ssdussud * 5524a190493Ssdussud * GIVEN : nothing 5534a190493Ssdussud * 5544a190493Ssdussud * RETURNS : nothing 5554a190493Ssdussud */ 5564a190493Ssdussud void 5574a190493Ssdussud dump_map_id_list() 5584a190493Ssdussud { 5594a190493Ssdussud int i; 5604a190493Ssdussud map_id_elt_t *cur_elt; 5614a190493Ssdussud 5624a190493Ssdussud logmsg(MSG_NOTIMECHECK, LOG_DEBUG, 5634a190493Ssdussud "dump_map_id_list: max_map is: %d, dumping map_idlist ...", 5644a190493Ssdussud max_map); 5654a190493Ssdussud 5664a190493Ssdussud for (i = 0; i < MAXHASH; i++) { 5674a190493Ssdussud if (map_id_list[i] == NULL) { 5684a190493Ssdussud logmsg(MSG_NOTIMECHECK, LOG_DEBUG, 5694a190493Ssdussud "no map for index %d", i); 5704a190493Ssdussud } else { 5714a190493Ssdussud logmsg(MSG_NOTIMECHECK, LOG_DEBUG, 5724a190493Ssdussud "index %d has the following maps", i); 5734a190493Ssdussud cur_elt = map_id_list[i]; 5744a190493Ssdussud do { 5754a190493Ssdussud logmsg(MSG_NOTIMECHECK, LOG_DEBUG, 5764a190493Ssdussud "%s, unique id: %d", 5774a190493Ssdussud cur_elt->map_name, 5784a190493Ssdussud cur_elt->map_id); 5794a190493Ssdussud cur_elt = cur_elt->next; 5804a190493Ssdussud } while (cur_elt != NULL); 5814a190493Ssdussud } 5824a190493Ssdussud } 5834a190493Ssdussud } 5844a190493Ssdussud #endif 5854a190493Ssdussud 5864a190493Ssdussud /* 5874a190493Ssdussud * FUNCTION : free_map_id_list() 5884a190493Ssdussud * 5894a190493Ssdussud * DESCRIPTION: free all previously allocated elements of map_id_list[] 5904a190493Ssdussud * reset max_map to 0 5914a190493Ssdussud * 5924a190493Ssdussud * GIVEN : nothing 5934a190493Ssdussud * 5944a190493Ssdussud * RETURNS : nothing 5954a190493Ssdussud */ 5964a190493Ssdussud void 5974a190493Ssdussud free_map_id_list() 5984a190493Ssdussud { 5994a190493Ssdussud int i; 6004a190493Ssdussud map_id_elt_t *cur_elt, *next_elt; 6014a190493Ssdussud 6024a190493Ssdussud for (i = 0; i < MAXHASH; i++) { 6034a190493Ssdussud if (map_id_list[i] != NULL) { 6044a190493Ssdussud cur_elt = map_id_list[i]; 6054a190493Ssdussud do { 6064a190493Ssdussud next_elt = cur_elt->next; 6074a190493Ssdussud if (cur_elt->map_name) 6084a190493Ssdussud sfree(cur_elt->map_name); 6094a190493Ssdussud sfree(cur_elt); 6104a190493Ssdussud cur_elt = next_elt; 6114a190493Ssdussud } while (cur_elt != NULL); 6124a190493Ssdussud map_id_list[i] = NULL; 6134a190493Ssdussud } 6144a190493Ssdussud } 6154a190493Ssdussud max_map = 0; 6164a190493Ssdussud } 6174a190493Ssdussud 6184a190493Ssdussud /* 6194a190493Ssdussud * FUNCTION : map_id_list_init() 6204a190493Ssdussud * 6214a190493Ssdussud * DESCRIPTION: initializes map_id_list[] and max_map 6224a190493Ssdussud * 6234a190493Ssdussud * GIVEN : nothing 6244a190493Ssdussud * 6254a190493Ssdussud * RETURNS : 0 if OK 6264a190493Ssdussud * -1 if failure 6274a190493Ssdussud */ 6284a190493Ssdussud int 6294a190493Ssdussud map_id_list_init() 6304a190493Ssdussud { 6314a190493Ssdussud char **domain_list, **map_list = NULL; 6324a190493Ssdussud int domain_num; 6334a190493Ssdussud int i, j; 6344a190493Ssdussud char *myself = "map_id_list_init"; 6354a190493Ssdussud char mapbuf[MAXPATHLEN]; 6364a190493Ssdussud int mapbuf_len = sizeof (mapbuf); 6374a190493Ssdussud int map_name_len; 6384a190493Ssdussud int seqnum = 0; 6394a190493Ssdussud int rc = 0; 6404a190493Ssdussud 6414a190493Ssdussud for (i = 0; i < MAXHASH; i++) { 6424a190493Ssdussud map_id_list[i] = NULL; 6434a190493Ssdussud } 6444a190493Ssdussud 6454a190493Ssdussud domain_num = get_mapping_domain_list(&domain_list); 6464a190493Ssdussud for (i = 0; i < domain_num; i++) { 6474a190493Ssdussud if (map_list) { 6484a190493Ssdussud free_map_list(map_list); 6494a190493Ssdussud map_list = NULL; 6504a190493Ssdussud } 6514a190493Ssdussud 6524a190493Ssdussud /* get map list from mapping file */ 6534a190493Ssdussud map_list = get_mapping_map_list(domain_list[i]); 6544a190493Ssdussud if (map_list == NULL) { 6554a190493Ssdussud /* no map for this domain in mapping file */ 6564a190493Ssdussud logmsg(MSG_NOTIMECHECK, LOG_DEBUG, 6574a190493Ssdussud "%s: get_mapping_map_list()" 6584a190493Ssdussud " found no map for domain %s", 6594a190493Ssdussud myself, domain_list[i]); 6604a190493Ssdussud } 6614a190493Ssdussud 6624a190493Ssdussud /* add maps from /var/yp/<domain> */ 6634a190493Ssdussud if (add_map_domain_to_list(domain_list[i], &map_list) == 6644a190493Ssdussud FALSE) { 6654a190493Ssdussud logmsg(MSG_NOTIMECHECK, LOG_ERR, 6664a190493Ssdussud "%s: add_map_domain_to_list() failed", myself); 6674a190493Ssdussud free_map_id_list(); 6684a190493Ssdussud if (map_list) free_map_list(map_list); 6694a190493Ssdussud return (-1); 6704a190493Ssdussud } 6714a190493Ssdussud 6724a190493Ssdussud if (map_list == NULL || map_list[0] == NULL) { 6734a190493Ssdussud logmsg(MSG_NOTIMECHECK, LOG_DEBUG, 6744a190493Ssdussud "%s: no map in domain %s", 6754a190493Ssdussud myself, domain_list[i]); 6764a190493Ssdussud continue; 6774a190493Ssdussud } 6784a190493Ssdussud 6794a190493Ssdussud for (j = 0; map_list[j] != NULL; j++) { 6804a190493Ssdussud /* build long name */ 6814a190493Ssdussud map_name_len = ypdbpath_sz + 1 + 6824a190493Ssdussud strlen(domain_list[i]) + 1 + 6834a190493Ssdussud strlen(NTOL_PREFIX) + 6844a190493Ssdussud strlen(map_list[j]) + 1; 6854a190493Ssdussud if (map_name_len > mapbuf_len) { 6864a190493Ssdussud logmsg(MSG_NOTIMECHECK, LOG_ERR, 6874a190493Ssdussud "%s: map name too long for %s", 6884a190493Ssdussud " in domain %s", myself, map_list[j], 6894a190493Ssdussud domain_list[i]); 6904a190493Ssdussud free_map_id_list(); 6914a190493Ssdussud if (map_list) free_map_list(map_list); 6924a190493Ssdussud return (-1); 6934a190493Ssdussud } 6944a190493Ssdussud (void) memset(mapbuf, 0, mapbuf_len); 6954a190493Ssdussud (void) snprintf(mapbuf, map_name_len, "%s%c%s%c%s%s", 6964a190493Ssdussud ypdbpath, SEP_CHAR, domain_list[i], SEP_CHAR, 6974a190493Ssdussud NTOL_PREFIX, map_list[j]); 6984a190493Ssdussud 6994a190493Ssdussud if (insert_map_in_list(mapbuf, seqnum) 7004a190493Ssdussud == FAILURE) { 7014a190493Ssdussud logmsg(MSG_NOTIMECHECK, LOG_ERR, 7024a190493Ssdussud "%s: failed to insert map %s", 7034a190493Ssdussud " in domain %s", myself, map_list[j]); 7044a190493Ssdussud free_map_id_list(); 7054a190493Ssdussud if (map_list) free_map_list(map_list); 7064a190493Ssdussud return (-1); 7074a190493Ssdussud } 7084a190493Ssdussud seqnum++; 7094a190493Ssdussud } 7104a190493Ssdussud } 7114a190493Ssdussud 7124a190493Ssdussud max_map = seqnum; 7134a190493Ssdussud 7144a190493Ssdussud #ifdef NISDB_LDAP_DEBUG 7154a190493Ssdussud dump_map_id_list(); 7164a190493Ssdussud #endif 7174a190493Ssdussud 7184a190493Ssdussud /* 7194a190493Ssdussud * If more maps than allocated spaces in shared memory, that's a failure 7204a190493Ssdussud * probably need to free previously allocated memory if failure, 7214a190493Ssdussud * before returning. 7224a190493Ssdussud */ 7234a190493Ssdussud if (max_map > MAXHASH) { 7244a190493Ssdussud rc = -1; 7254a190493Ssdussud logmsg(MSG_NOTIMECHECK, LOG_ERR, 7264a190493Ssdussud "%s: too many maps (%d)", 7274a190493Ssdussud myself, max_map); 7284a190493Ssdussud free_map_id_list(); 7294a190493Ssdussud } 7304a190493Ssdussud if (map_list) free_map_list(map_list); 7314a190493Ssdussud return (rc); 7324a190493Ssdussud } 7334a190493Ssdussud 7344a190493Ssdussud /* 7354a190493Ssdussud * FUNCTION : get_list_max() 7364a190493Ssdussud * 7374a190493Ssdussud * DESCRIPTION: return references to static variables map_id_list 7384a190493Ssdussud * and max_map; 7394a190493Ssdussud * 7404a190493Ssdussud * GIVEN : address for referencing map_id_list 7414a190493Ssdussud * address for referencing max_map 7424a190493Ssdussud * 7434a190493Ssdussud * RETURNS : nothing 7444a190493Ssdussud */ 7454a190493Ssdussud void 7464a190493Ssdussud get_list_max(map_id_elt_t ***list, int *max) 7474a190493Ssdussud { 7484a190493Ssdussud *list = map_id_list; 7494a190493Ssdussud *max = max_map; 7504a190493Ssdussud } 751