xref: /titanic_44/usr/src/lib/libnisdb/yptol/dit_access.c (revision 803376f094adaaf2e4d9aa1c1d0efd56b642d838)
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 /*
22*ea10ff14SBen Chang  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate /*
267c478bd9Sstevel@tonic-gate  * DESCRIPTION: Contains top level functions to read/write to the DIT. These
277c478bd9Sstevel@tonic-gate  *		are the API between the shim and the mapping system.
287c478bd9Sstevel@tonic-gate  *		Things calling these should have no knowledge of LDAP. Things
297c478bd9Sstevel@tonic-gate  *		called by them should have no knowledge of NIS.
307c478bd9Sstevel@tonic-gate  *
317c478bd9Sstevel@tonic-gate  *		Error handling here may appear to be limited but, because the
327c478bd9Sstevel@tonic-gate  *		NIS protocol cannot carry meaningful information about why a
337c478bd9Sstevel@tonic-gate  *		N2L operation failed, functions that don't work log
347c478bd9Sstevel@tonic-gate  *		an error and then just return FAILURE.
357c478bd9Sstevel@tonic-gate  *
367c478bd9Sstevel@tonic-gate  */
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate  * Includes. WE WANT TO USE REAL DBM FUNCTIONS SO DO NOT INCLUDE SHIM_HOOKS.H.
407c478bd9Sstevel@tonic-gate  */
417c478bd9Sstevel@tonic-gate #include <unistd.h>
427c478bd9Sstevel@tonic-gate #include <syslog.h>
437c478bd9Sstevel@tonic-gate #include <ndbm.h>
447c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
457c478bd9Sstevel@tonic-gate #include <string.h>
467c478bd9Sstevel@tonic-gate #include <lber.h>
477c478bd9Sstevel@tonic-gate #include <ldap.h>
487c478bd9Sstevel@tonic-gate #include <errno.h>
497c478bd9Sstevel@tonic-gate #include "ypsym.h"
507c478bd9Sstevel@tonic-gate #include "ypdefs.h"
517c478bd9Sstevel@tonic-gate #include "shim.h"
527c478bd9Sstevel@tonic-gate #include "../ldap_structs.h"
537c478bd9Sstevel@tonic-gate #include "../ldap_parse.h"
547c478bd9Sstevel@tonic-gate #include "../nisdb_ldap.h"
557c478bd9Sstevel@tonic-gate #include "../ldap_util.h"
567c478bd9Sstevel@tonic-gate #include "../ldap_op.h"
577c478bd9Sstevel@tonic-gate #include "../ldap_attr.h"
587c478bd9Sstevel@tonic-gate #include "../nis_parse_ldap_conf.h"
597c478bd9Sstevel@tonic-gate #include "../nisdb_mt.h"
607c478bd9Sstevel@tonic-gate #include "yptol.h"
617c478bd9Sstevel@tonic-gate #include "dit_access_utils.h"
627c478bd9Sstevel@tonic-gate #include "stdio.h"
637c478bd9Sstevel@tonic-gate 
644a190493Ssdussud extern bool delete_map(char *name);
654a190493Ssdussud extern bool rename_map(char *from, char *to, bool_t secure_map);
664a190493Ssdussud 
677c478bd9Sstevel@tonic-gate /* Enable standard YP code features defined in ypdefs.h */
687c478bd9Sstevel@tonic-gate USE_YP_MASTER_NAME
697c478bd9Sstevel@tonic-gate USE_YP_DOMAIN_NAME
707c478bd9Sstevel@tonic-gate USE_YP_SECURE
717c478bd9Sstevel@tonic-gate USE_YP_INTERDOMAIN
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate /*
747c478bd9Sstevel@tonic-gate  * Decs
757c478bd9Sstevel@tonic-gate  */
767c478bd9Sstevel@tonic-gate suc_code add_special_entries(DBM *, map_ctrl *, bool_t *);
777c478bd9Sstevel@tonic-gate void free_null_terminated_list(char **list);
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate /*
817c478bd9Sstevel@tonic-gate  * FUNCTION:    is_yptol_mode();
827c478bd9Sstevel@tonic-gate  *
837c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Determines if we should run in N2L or traditional mode based
847c478bd9Sstevel@tonic-gate  *		on the presence of the N2L mapping file. If there are problems
857c478bd9Sstevel@tonic-gate  *		with the file, e.g. unreadable, this will be picked up latter.
867c478bd9Sstevel@tonic-gate  *
877c478bd9Sstevel@tonic-gate  * INPUTS:     	Nothing
887c478bd9Sstevel@tonic-gate  *
897c478bd9Sstevel@tonic-gate  * OUTPUTS:   	TRUE = Run in N2L mode
907c478bd9Sstevel@tonic-gate  *		FALSE = Run in traditional mode.
917c478bd9Sstevel@tonic-gate  */
927c478bd9Sstevel@tonic-gate bool_t
is_yptol_mode()937c478bd9Sstevel@tonic-gate is_yptol_mode()
947c478bd9Sstevel@tonic-gate {
957c478bd9Sstevel@tonic-gate 	struct stat filestat;
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	if (stat(YP_DEFAULTCONFFILE, &filestat) != -1)
987c478bd9Sstevel@tonic-gate 		return (TRUE);
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 	return (FALSE);
1017c478bd9Sstevel@tonic-gate }
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate /*
1047c478bd9Sstevel@tonic-gate  * FUNCTION:    read_from_dit();
1057c478bd9Sstevel@tonic-gate  *
1067c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Read (i.e. get and map) a single NIS entry from the LDAP DIT.
1077c478bd9Sstevel@tonic-gate  *		Also handles retry attempts, on failure, and interpretation of
1087c478bd9Sstevel@tonic-gate  *		internal error codes.
1097c478bd9Sstevel@tonic-gate  *
1107c478bd9Sstevel@tonic-gate  * INPUTS:     	Map name (unqualified)
1117c478bd9Sstevel@tonic-gate  *		Domain name
1127c478bd9Sstevel@tonic-gate  *		Entry key
1137c478bd9Sstevel@tonic-gate  *		Pointer to return location
1147c478bd9Sstevel@tonic-gate  *
1157c478bd9Sstevel@tonic-gate  * OUTPUTS:   	If successful DBM datum containing result.
1167c478bd9Sstevel@tonic-gate  *		On error DBM datum pointing to NULL and, if the cached value
1177c478bd9Sstevel@tonic-gate  *		is not to be used, an error code.
1187c478bd9Sstevel@tonic-gate  */
1197c478bd9Sstevel@tonic-gate int
read_from_dit(char * map,char * domain,datum * key,datum * value)1207c478bd9Sstevel@tonic-gate read_from_dit(char *map, char *domain, datum *key, datum *value)
1217c478bd9Sstevel@tonic-gate {
1227c478bd9Sstevel@tonic-gate 	int count;
1237c478bd9Sstevel@tonic-gate 	int res;
1247c478bd9Sstevel@tonic-gate 	__nisdb_retry_t	*retrieveRetry;
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 	/* Initialize tsd */
1277c478bd9Sstevel@tonic-gate 	__nisdb_get_tsd()->domainContext = 0;
1287c478bd9Sstevel@tonic-gate 	__nisdb_get_tsd()->escapeFlag = '\0';
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 	for (count = 0; count < ypDomains.numDomains; count++) {
1317c478bd9Sstevel@tonic-gate 		if (0 == ypDomains.domainLabels[count])
1327c478bd9Sstevel@tonic-gate 			continue;
1337c478bd9Sstevel@tonic-gate 		if (0 == strcasecmp(domain, ypDomains.domainLabels[count])) {
1347c478bd9Sstevel@tonic-gate 			__nisdb_get_tsd()->domainContext =
1357c478bd9Sstevel@tonic-gate 			    ypDomains.domains[count];
1367c478bd9Sstevel@tonic-gate 			break;
1377c478bd9Sstevel@tonic-gate 		}
1387c478bd9Sstevel@tonic-gate 	}
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate 	retrieveRetry = &ldapDBTableMapping.retrieveErrorRetry;
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 	/* Loop 'attempts' times of forever if -1 */
1437c478bd9Sstevel@tonic-gate 	for (count = retrieveRetry->attempts; (0 <= count) ||
1447c478bd9Sstevel@tonic-gate 	    (-1 == retrieveRetry->attempts); count --) {
1457c478bd9Sstevel@tonic-gate 		if (TRUE == singleReadFromDIT(map, domain, key, value, &res))
1467c478bd9Sstevel@tonic-gate 			/* It worked, return value irrelevant */
1477c478bd9Sstevel@tonic-gate 			return (0);
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 		if (LDAP_TIMEOUT == res) { /* Exceeded search timeout */
1507c478bd9Sstevel@tonic-gate 			value->dptr = NULL;
1517c478bd9Sstevel@tonic-gate 			return (0);
1527c478bd9Sstevel@tonic-gate 		}
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 		if (is_fatal_error(res))
1557c478bd9Sstevel@tonic-gate 			break;
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 		/*
1587c478bd9Sstevel@tonic-gate 		 * Didn't work. If not the special case where no repeats are
1597c478bd9Sstevel@tonic-gate 		 * done sleep.
1607c478bd9Sstevel@tonic-gate 		 */
1617c478bd9Sstevel@tonic-gate 		if (0 != retrieveRetry->attempts)
1627c478bd9Sstevel@tonic-gate 			(void) poll(NULL, 0, retrieveRetry->timeout*1000);
1637c478bd9Sstevel@tonic-gate 	}
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate 	/* Make sure returned pointer is NULL */
1667c478bd9Sstevel@tonic-gate 	value->dptr = NULL;
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 	/* If we get here access failed work out what to return */
1697c478bd9Sstevel@tonic-gate 	if (ldapDBTableMapping.retrieveError == use_cached)
1707c478bd9Sstevel@tonic-gate 		return (0);
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 	return (res);
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate /*
1767c478bd9Sstevel@tonic-gate  * FUNCTION:    write_to_dit();
1777c478bd9Sstevel@tonic-gate  *
1787c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Maps and writes a NIS entry to the LDAP DIT.
1797c478bd9Sstevel@tonic-gate  *		Also handles retry attempts, on failure, and interpretation of
1807c478bd9Sstevel@tonic-gate  *		internal error codes.
1817c478bd9Sstevel@tonic-gate  *
1827c478bd9Sstevel@tonic-gate  * INPUTS:     	Pointer to (unqualified) map name
1837c478bd9Sstevel@tonic-gate  *		Pointer to domain name
1847c478bd9Sstevel@tonic-gate  *		The entries key
1857c478bd9Sstevel@tonic-gate  *		What to write
1867c478bd9Sstevel@tonic-gate  *		Replace flag indicating
1877c478bd9Sstevel@tonic-gate  *			TRUE = Replace (overwrite) any existing entries
1887c478bd9Sstevel@tonic-gate  *			FALSE = Return error if there are existing entries
1897c478bd9Sstevel@tonic-gate  *		Flag indicating if we should tolerate mapping errors.
1907c478bd9Sstevel@tonic-gate  *
1917c478bd9Sstevel@tonic-gate  * OUTPUTS:   	SUCCESS = Write was successful
1927c478bd9Sstevel@tonic-gate  *		FAILURE = Write failed
1937c478bd9Sstevel@tonic-gate  *
1947c478bd9Sstevel@tonic-gate  */
1957c478bd9Sstevel@tonic-gate suc_code
write_to_dit(char * map,char * domain,datum key,datum value,bool_t replace,bool_t ignore_map_errs)1967c478bd9Sstevel@tonic-gate write_to_dit(char *map, char *domain, datum key, datum value,
1977c478bd9Sstevel@tonic-gate 					bool_t replace, bool_t ignore_map_errs)
1987c478bd9Sstevel@tonic-gate {
1997c478bd9Sstevel@tonic-gate 	int count;
2007c478bd9Sstevel@tonic-gate 	int res;
2017c478bd9Sstevel@tonic-gate 	__nisdb_retry_t	*storeRetry = &ldapDBTableMapping.storeErrorRetry;
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	/* Initialize tsd */
2047c478bd9Sstevel@tonic-gate 	__nisdb_get_tsd()->domainContext = 0;
2057c478bd9Sstevel@tonic-gate 	__nisdb_get_tsd()->escapeFlag = '\0';
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	for (count = 0; count < ypDomains.numDomains; count++) {
2087c478bd9Sstevel@tonic-gate 		if (0 == ypDomains.domainLabels[count])
2097c478bd9Sstevel@tonic-gate 			continue;
2107c478bd9Sstevel@tonic-gate 		if (0 == strcasecmp(domain, ypDomains.domainLabels[count])) {
2117c478bd9Sstevel@tonic-gate 			__nisdb_get_tsd()->domainContext =
2127c478bd9Sstevel@tonic-gate 			    ypDomains.domains[count];
2137c478bd9Sstevel@tonic-gate 			break;
2147c478bd9Sstevel@tonic-gate 		}
2157c478bd9Sstevel@tonic-gate 	}
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	storeRetry = &ldapDBTableMapping.storeErrorRetry;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	/* Loop 'attempts' times of forever if -1 */
2207c478bd9Sstevel@tonic-gate 	for (count = storeRetry->attempts; (0 <= count) ||
2217c478bd9Sstevel@tonic-gate 	    (-1 == storeRetry->attempts); count --) {
2227c478bd9Sstevel@tonic-gate 		res = singleWriteToDIT(map, domain, &key, &value, replace);
2237c478bd9Sstevel@tonic-gate 		if (LDAP_SUCCESS == res)
2247c478bd9Sstevel@tonic-gate 			return (SUCCESS);
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 		if (is_fatal_error(res)) {
2277c478bd9Sstevel@tonic-gate 			/*
2287c478bd9Sstevel@tonic-gate 			 * The mapping failed and will fail again if it is
2297c478bd9Sstevel@tonic-gate 			 * retried. However there are some cases where an
2307c478bd9Sstevel@tonic-gate 			 * actual mapping fault (rather than a LDAP problem)
2317c478bd9Sstevel@tonic-gate 			 * may be ignored.
2327c478bd9Sstevel@tonic-gate 			 */
2337c478bd9Sstevel@tonic-gate 			if (ignore_map_errs) {
2347c478bd9Sstevel@tonic-gate 				switch (res) {
2357c478bd9Sstevel@tonic-gate 					case LDAP_INVALID_DN_SYNTAX:
2367c478bd9Sstevel@tonic-gate 					case LDAP_OBJECT_CLASS_VIOLATION:
2377c478bd9Sstevel@tonic-gate 					case LDAP_NOT_ALLOWED_ON_RDN:
2387c478bd9Sstevel@tonic-gate 					case MAP_NAMEFIELD_MATCH_ERROR:
2397c478bd9Sstevel@tonic-gate 					case MAP_NO_DN:
2407c478bd9Sstevel@tonic-gate 						return (SUCCESS);
2417c478bd9Sstevel@tonic-gate 					default:
2427c478bd9Sstevel@tonic-gate 						break;
2437c478bd9Sstevel@tonic-gate 				}
2447c478bd9Sstevel@tonic-gate 			}
2457c478bd9Sstevel@tonic-gate 			return (FAILURE);
2467c478bd9Sstevel@tonic-gate 		}
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate 		if (ldapDBTableMapping.storeError != sto_retry)
2497c478bd9Sstevel@tonic-gate 			return (FAILURE);
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 		/*
2527c478bd9Sstevel@tonic-gate 		 * Didn't work. If not the special case where no repeats are
2537c478bd9Sstevel@tonic-gate 		 * done sleep.
2547c478bd9Sstevel@tonic-gate 		 */
2557c478bd9Sstevel@tonic-gate 		if (0 != storeRetry->attempts)
2567c478bd9Sstevel@tonic-gate 			(void) poll(NULL, 0, storeRetry->timeout*1000);
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	}
2597c478bd9Sstevel@tonic-gate 	return (FAILURE);
2607c478bd9Sstevel@tonic-gate }
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate /*
2637c478bd9Sstevel@tonic-gate  * FUNCTION :	get_ttl_value()
2647c478bd9Sstevel@tonic-gate  *
2657c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Get the TTL value, derived from mapping file or DIT, for a
2667c478bd9Sstevel@tonic-gate  *		entry.
2677c478bd9Sstevel@tonic-gate  *
2687c478bd9Sstevel@tonic-gate  * GIVEN :	Pointer to map
2697c478bd9Sstevel@tonic-gate  *		A flag indication if TTL should be max, min or random
2707c478bd9Sstevel@tonic-gate  *
2717c478bd9Sstevel@tonic-gate  * RETURNS :	TTL value in seconds.
2727c478bd9Sstevel@tonic-gate  *		-1 on failure
2737c478bd9Sstevel@tonic-gate  */
2747c478bd9Sstevel@tonic-gate int
get_ttl_value(map_ctrl * map,TTL_TYPE type)2757c478bd9Sstevel@tonic-gate get_ttl_value(map_ctrl *map, TTL_TYPE type)
2767c478bd9Sstevel@tonic-gate {
2777c478bd9Sstevel@tonic-gate 	__nis_table_mapping_t *table_map;
2787c478bd9Sstevel@tonic-gate 	int interval, res;
2797c478bd9Sstevel@tonic-gate 	char *myself = "get_ttl_value";
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 	/*  Get the mapping structure corresponding to `map.domain' */
2827c478bd9Sstevel@tonic-gate 	table_map = mappingFromMap(map->map_name, map->domain, &res);
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 	if (0 == table_map) {
2857c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR,
2867c478bd9Sstevel@tonic-gate 		    "Get TTL request could not access map %s in domain %s "
2877c478bd9Sstevel@tonic-gate 		    "(error %d)", map->map_name, map->domain, res);
2887c478bd9Sstevel@tonic-gate 		return (-1);
2897c478bd9Sstevel@tonic-gate 	}
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate 	switch (type) {
2927c478bd9Sstevel@tonic-gate 		case TTL_MAX:
2937c478bd9Sstevel@tonic-gate 			return (table_map->initTtlHi);
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 		case TTL_MIN:
2967c478bd9Sstevel@tonic-gate 			return (table_map->initTtlLo);
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 		default:
2997c478bd9Sstevel@tonic-gate 			logmsg(MSG_NOTIMECHECK, LOG_INFO,
3007c478bd9Sstevel@tonic-gate 			"%s passed illegal TTL type (%d)", myself, type);
3017c478bd9Sstevel@tonic-gate 			/* If unknown TTL type drop through to TTL_RAND */
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 		case TTL_RAND:
3047c478bd9Sstevel@tonic-gate 			interval = table_map->initTtlHi - table_map->initTtlLo;
3057c478bd9Sstevel@tonic-gate 			if (0 >= interval)
3067c478bd9Sstevel@tonic-gate 				return (table_map->initTtlLo);
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 			/*
3097c478bd9Sstevel@tonic-gate 			 * Must get a random value. We assume srand48() got
3107c478bd9Sstevel@tonic-gate 			 * called at initialization.
3117c478bd9Sstevel@tonic-gate 			 */
3127c478bd9Sstevel@tonic-gate 			return (lrand48() % interval);
3137c478bd9Sstevel@tonic-gate 
3147c478bd9Sstevel@tonic-gate 		case TTL_RUNNING:
3157c478bd9Sstevel@tonic-gate 			return (table_map->ttl);
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	}
3197c478bd9Sstevel@tonic-gate }
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate /*
3227c478bd9Sstevel@tonic-gate  * FUNCTION :	get_mapping_domain_list()
3237c478bd9Sstevel@tonic-gate  *
3247c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Gets a list of domain names specified, by nisLDAPdomainContext
3257c478bd9Sstevel@tonic-gate  *		attributes, in the mapping file. This is used only for initial
3267c478bd9Sstevel@tonic-gate  *		DIT setup. Once the DIT has been set up get_domain_list() is
3277c478bd9Sstevel@tonic-gate  *		used instead.
3287c478bd9Sstevel@tonic-gate  *
3297c478bd9Sstevel@tonic-gate  * GIVEN :	Pointer returned array.
3307c478bd9Sstevel@tonic-gate  *
3317c478bd9Sstevel@tonic-gate  * RETURNS :	Number of element in returned array.
3327c478bd9Sstevel@tonic-gate  *		Array of elements this is in static memory
3337c478bd9Sstevel@tonic-gate  *		and must not be freed by the caller.
3347c478bd9Sstevel@tonic-gate  */
3357c478bd9Sstevel@tonic-gate int
get_mapping_domain_list(char *** ptr)3367c478bd9Sstevel@tonic-gate get_mapping_domain_list(char ***ptr)
3377c478bd9Sstevel@tonic-gate {
3387c478bd9Sstevel@tonic-gate 	*ptr = ypDomains.domainLabels;
3397c478bd9Sstevel@tonic-gate 	return (ypDomains.numDomains);
3407c478bd9Sstevel@tonic-gate }
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate /*
3437c478bd9Sstevel@tonic-gate  * FUNCTION :	get_mapping_yppasswdd_domain_list()
3447c478bd9Sstevel@tonic-gate  *
3457c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Gets a list of domain names specified, by the
3467c478bd9Sstevel@tonic-gate  *		nisLDAPyppasswddDomains attribute, in the mapping file. This
3477c478bd9Sstevel@tonic-gate  *		is the list of domains for which passwords should be changed.
3487c478bd9Sstevel@tonic-gate  *
3497c478bd9Sstevel@tonic-gate  * GIVEN :	Pointer returned array
3507c478bd9Sstevel@tonic-gate  *
3517c478bd9Sstevel@tonic-gate  * RETURNS :	Number of element in returned array.
3527c478bd9Sstevel@tonic-gate  *		0 if no nisLDAPyppasswddDomains attribute is present.
3537c478bd9Sstevel@tonic-gate  *		Array of elements this is in static memory
3547c478bd9Sstevel@tonic-gate  *		and must not be freed by the caller.
3557c478bd9Sstevel@tonic-gate  */
3567c478bd9Sstevel@tonic-gate int
get_mapping_yppasswdd_domain_list(char *** ptr)3577c478bd9Sstevel@tonic-gate get_mapping_yppasswdd_domain_list(char ***ptr)
3587c478bd9Sstevel@tonic-gate {
3597c478bd9Sstevel@tonic-gate 	*ptr = ypDomains.yppasswddDomainLabels;
3607c478bd9Sstevel@tonic-gate 	return (ypDomains.numYppasswdd);
3617c478bd9Sstevel@tonic-gate }
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate /*
3647c478bd9Sstevel@tonic-gate  * FUNCTION :	free_map_list()
3657c478bd9Sstevel@tonic-gate  *
3667c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Frees a map list.
3677c478bd9Sstevel@tonic-gate  *
3687c478bd9Sstevel@tonic-gate  * GIVEN :	Pointer to the map list.
3697c478bd9Sstevel@tonic-gate  *
3707c478bd9Sstevel@tonic-gate  * RETURNS :	Nothing
3717c478bd9Sstevel@tonic-gate  */
3727c478bd9Sstevel@tonic-gate void
free_map_list(char ** map_list)3737c478bd9Sstevel@tonic-gate free_map_list(char **map_list)
3747c478bd9Sstevel@tonic-gate {
3757c478bd9Sstevel@tonic-gate 	free_null_terminated_list(map_list);
3767c478bd9Sstevel@tonic-gate }
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate /*
3797c478bd9Sstevel@tonic-gate  * FUNCTION :	get_passwd_list()
3807c478bd9Sstevel@tonic-gate  *
3817c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Gets a list of either passwd or passwd.adjunct map files
3827c478bd9Sstevel@tonic-gate  *		defined in the mapping file. These are the files which have
3837c478bd9Sstevel@tonic-gate  *		'magic' nisLDAPdatabaseIdMapping entries aliasing them to
3847c478bd9Sstevel@tonic-gate  *		passwd or passwd.adjunct. This function is required so that
3857c478bd9Sstevel@tonic-gate  *		yppasswdd can work out which maps to synchronize with any
3867c478bd9Sstevel@tonic-gate  *		password changes.
3877c478bd9Sstevel@tonic-gate  *
3887c478bd9Sstevel@tonic-gate  *		This information is not currently stored by the parser but
3897c478bd9Sstevel@tonic-gate  *		we can recover it from the hash table. This makes hard work but
3907c478bd9Sstevel@tonic-gate  *		passwords should not be changed very frequently
3917c478bd9Sstevel@tonic-gate  *
3927c478bd9Sstevel@tonic-gate  * GIVEN :	Flag indicating if a list is required for passwd or
3937c478bd9Sstevel@tonic-gate  *		passwd.adjunct
3947c478bd9Sstevel@tonic-gate  *		Domain to return the list for.
3957c478bd9Sstevel@tonic-gate  *
3967c478bd9Sstevel@tonic-gate  * RETURNS :	Null terminated list of map names in malloced memory. To be
3977c478bd9Sstevel@tonic-gate  *		freed by caller. (Possibly empty if no passwd maps found)
3987c478bd9Sstevel@tonic-gate  *		NULL on error
3997c478bd9Sstevel@tonic-gate  */
4007c478bd9Sstevel@tonic-gate char **
get_passwd_list(bool_t adjunct,char * domain)4017c478bd9Sstevel@tonic-gate get_passwd_list(bool_t adjunct, char *domain)
4027c478bd9Sstevel@tonic-gate {
4037c478bd9Sstevel@tonic-gate 	char *myself = "get_passwd_list";
4047c478bd9Sstevel@tonic-gate 	__nis_hash_item_mt *it;
4057c478bd9Sstevel@tonic-gate 	int	i, size;
4064a190493Ssdussud 	char 	*end_ptr;
4077c478bd9Sstevel@tonic-gate 	char	*target;	/* What we are looking for */
4087c478bd9Sstevel@tonic-gate 	int	target_len;
4097c478bd9Sstevel@tonic-gate 	int	domain_len;
4107c478bd9Sstevel@tonic-gate 	char	**res;		/* Result array */
4117c478bd9Sstevel@tonic-gate 	char	**res_old;	/* Old value of res during realloc */
4127c478bd9Sstevel@tonic-gate 	int	array_size;	/* Current malloced size */
4137c478bd9Sstevel@tonic-gate 	int	res_count = 0;	/* Current result count */
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate 	/*
4167c478bd9Sstevel@tonic-gate 	 * Always need an array even if just for terminator. Normally one
4177c478bd9Sstevel@tonic-gate 	 * chunk will be enough.
4187c478bd9Sstevel@tonic-gate 	 */
4197c478bd9Sstevel@tonic-gate 	res = am(myself, ARRAY_CHUNK * sizeof (char *));
4207c478bd9Sstevel@tonic-gate 	if (NULL == res)
4217c478bd9Sstevel@tonic-gate 		return (NULL);
4227c478bd9Sstevel@tonic-gate 	array_size = ARRAY_CHUNK;
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 	/* Set up target */
4257c478bd9Sstevel@tonic-gate 	if (adjunct)
4267c478bd9Sstevel@tonic-gate 		target = PASSWD_ADJUNCT_PREFIX;
4277c478bd9Sstevel@tonic-gate 	else
4287c478bd9Sstevel@tonic-gate 		target = PASSWD_PREFIX;
4297c478bd9Sstevel@tonic-gate 	target_len = strlen(target);
4307c478bd9Sstevel@tonic-gate 	domain_len = strlen(domain);
4317c478bd9Sstevel@tonic-gate 
4327c478bd9Sstevel@tonic-gate 	/* Work out hash table length */
4337c478bd9Sstevel@tonic-gate 	size = sizeof (ldapMappingList.keys) / sizeof (ldapMappingList.keys[0]);
4347c478bd9Sstevel@tonic-gate 	/* For all hash table entries */
4357c478bd9Sstevel@tonic-gate 	for (i = 0; i < size; i++) {
4367c478bd9Sstevel@tonic-gate 		/* Walk linked list for this hash table entry */
4377c478bd9Sstevel@tonic-gate 		for (it = ldapMappingList.keys[i]; NULL != it; it = it->next) {
4387c478bd9Sstevel@tonic-gate 			/* Check right map */
4397c478bd9Sstevel@tonic-gate 			if ((target_len + domain_len + 1) > strlen(it->name))
4407c478bd9Sstevel@tonic-gate 				continue;
4417c478bd9Sstevel@tonic-gate 			if (0 != strncmp(it->name, target, target_len))
4427c478bd9Sstevel@tonic-gate 				continue;
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 			/* Check right domain (minus trailing dot) */
4457c478bd9Sstevel@tonic-gate 			if (strlen(domain) >= strlen(it->name))
4467c478bd9Sstevel@tonic-gate 				continue;
4477c478bd9Sstevel@tonic-gate 			end_ptr = it->name + strlen(it->name) -
4487c478bd9Sstevel@tonic-gate 			    strlen(domain) - 1;
4497c478bd9Sstevel@tonic-gate 			if (',' != *(end_ptr - 1))
4507c478bd9Sstevel@tonic-gate 				continue;
4517c478bd9Sstevel@tonic-gate 			if (0 != strncmp(end_ptr, domain, strlen(domain)))
4527c478bd9Sstevel@tonic-gate 				continue;
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate 			/* Check if we need to enlarge array */
4557c478bd9Sstevel@tonic-gate 			if ((res_count + 1) >= array_size) {
4567c478bd9Sstevel@tonic-gate 				array_size += ARRAY_CHUNK;
4577c478bd9Sstevel@tonic-gate 				res_old = res;
4587c478bd9Sstevel@tonic-gate 				res = realloc(res, array_size *
4597c478bd9Sstevel@tonic-gate 				    sizeof (char *));
4607c478bd9Sstevel@tonic-gate 				if (NULL == res) {
4617c478bd9Sstevel@tonic-gate 					res_old[res_count] = NULL;
4627c478bd9Sstevel@tonic-gate 					free_passwd_list(res_old);
4637c478bd9Sstevel@tonic-gate 					return (NULL);
4647c478bd9Sstevel@tonic-gate 				}
4657c478bd9Sstevel@tonic-gate 			}
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate 			/* What we really need is strndup() */
4687c478bd9Sstevel@tonic-gate 			res[res_count] = am(myself, end_ptr - it->name + 1);
4697c478bd9Sstevel@tonic-gate 			if (NULL == res[res_count]) {
4707c478bd9Sstevel@tonic-gate 				free_passwd_list(res);
4717c478bd9Sstevel@tonic-gate 				return (NULL);
4727c478bd9Sstevel@tonic-gate 			}
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 			/* Copy from start to end_ptr */
4754a190493Ssdussud 			(void) memcpy(res[res_count], it->name,
4764a190493Ssdussud 			    end_ptr-it->name - 1);
4777c478bd9Sstevel@tonic-gate 			res_count ++;
4787c478bd9Sstevel@tonic-gate 		}
4797c478bd9Sstevel@tonic-gate 	}
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate 	/* Terminate array */
4827c478bd9Sstevel@tonic-gate 	res[res_count] = NULL;
4837c478bd9Sstevel@tonic-gate 	return (res);
4847c478bd9Sstevel@tonic-gate }
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate /*
4877c478bd9Sstevel@tonic-gate  * FUNCTION :	free_passwd_list()
4887c478bd9Sstevel@tonic-gate  *
4897c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Frees a password list obtained with get_passwd_list()
4907c478bd9Sstevel@tonic-gate  *
4917c478bd9Sstevel@tonic-gate  * INPUTS :	Address of list to free.
4927c478bd9Sstevel@tonic-gate  *
4937c478bd9Sstevel@tonic-gate  * OUTPUTS :	Nothing
4947c478bd9Sstevel@tonic-gate  */
4957c478bd9Sstevel@tonic-gate void
free_passwd_list(char ** list)4967c478bd9Sstevel@tonic-gate free_passwd_list(char **list)
4977c478bd9Sstevel@tonic-gate {
4987c478bd9Sstevel@tonic-gate 	free_null_terminated_list(list);
4997c478bd9Sstevel@tonic-gate }
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate /*
5027c478bd9Sstevel@tonic-gate  * FUNCTION :	free_null_terminated_list()
5037c478bd9Sstevel@tonic-gate  *
5047c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Frees a generic null terminated list.
5057c478bd9Sstevel@tonic-gate  *
5067c478bd9Sstevel@tonic-gate  * INPUTS :	Address of list to free.
5077c478bd9Sstevel@tonic-gate  *
5087c478bd9Sstevel@tonic-gate  * OUTPUTS :	Nothing
5097c478bd9Sstevel@tonic-gate  */
5107c478bd9Sstevel@tonic-gate void
free_null_terminated_list(char ** list)5117c478bd9Sstevel@tonic-gate free_null_terminated_list(char **list)
5127c478bd9Sstevel@tonic-gate {
5137c478bd9Sstevel@tonic-gate 	int index;
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate 	/* Free all the strings */
5167c478bd9Sstevel@tonic-gate 	for (index = 0; NULL != list[index]; index ++)
5177c478bd9Sstevel@tonic-gate 		sfree(list[index]);
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate 	/* Free the array */
5207c478bd9Sstevel@tonic-gate 	sfree(list);
5217c478bd9Sstevel@tonic-gate }
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate /*
5257c478bd9Sstevel@tonic-gate  * FUNCTION :	add_special_entries()
5267c478bd9Sstevel@tonic-gate  *
5277c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Adds the special (YP_*) entries to a map.
5287c478bd9Sstevel@tonic-gate  *
5297c478bd9Sstevel@tonic-gate  *		Part of dit_access because requires access to the mapping
5307c478bd9Sstevel@tonic-gate  *		file in order to work out if secure and interdomain entries
5317c478bd9Sstevel@tonic-gate  *		should be created.
5327c478bd9Sstevel@tonic-gate  *
5337c478bd9Sstevel@tonic-gate  * GIVEN :	Pointer to an open, temporary, DBM file
5347c478bd9Sstevel@tonic-gate  *		Pointer to map information (do not use DBM fields).
5357c478bd9Sstevel@tonic-gate  *		Pointer to a location in which to return security flag
5367c478bd9Sstevel@tonic-gate  *
5377c478bd9Sstevel@tonic-gate  * RETURNS :	SUCCESS = All entries created
5387c478bd9Sstevel@tonic-gate  *		FAILURE = Some entries not created
5397c478bd9Sstevel@tonic-gate  */
5407c478bd9Sstevel@tonic-gate suc_code
add_special_entries(DBM * db,map_ctrl * map,bool_t * secure_flag)5417c478bd9Sstevel@tonic-gate add_special_entries(DBM *db, map_ctrl *map, bool_t *secure_flag)
5427c478bd9Sstevel@tonic-gate {
5437c478bd9Sstevel@tonic-gate 	char local_host[MAX_MASTER_NAME];
5447c478bd9Sstevel@tonic-gate 	__nis_table_mapping_t *table_map;
5457c478bd9Sstevel@tonic-gate 	int res;
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 	/* Last modified time is now */
5487c478bd9Sstevel@tonic-gate 	update_timestamp(db);
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 	/* Add domain name */
5517c478bd9Sstevel@tonic-gate 	addpair(db, yp_domain_name, map->domain);
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 	/* For N2L mode local machine is always the master */
5547c478bd9Sstevel@tonic-gate 	sysinfo(SI_HOSTNAME, local_host, sizeof (local_host));
5557c478bd9Sstevel@tonic-gate 	addpair(db, yp_master_name, local_host);
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 	/*  Get the mapping structure corresponding to `map.domain' */
5587c478bd9Sstevel@tonic-gate 	table_map = mappingFromMap(map->map_name, map->domain, &res);
5597c478bd9Sstevel@tonic-gate 	if (0 == table_map)
5607c478bd9Sstevel@tonic-gate 		return (FAILURE);
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate 	/* Add secure and interdomain flags if required */
5637c478bd9Sstevel@tonic-gate 	if (table_map->securemap_flag) {
5647c478bd9Sstevel@tonic-gate 		addpair(db, yp_secure, "");
5657c478bd9Sstevel@tonic-gate 		*secure_flag = TRUE;
5667c478bd9Sstevel@tonic-gate 	} else {
5677c478bd9Sstevel@tonic-gate 		*secure_flag = FALSE;
5687c478bd9Sstevel@tonic-gate 	}
5697c478bd9Sstevel@tonic-gate 	if (table_map->usedns_flag)
5707c478bd9Sstevel@tonic-gate 		addpair(db, yp_interdomain, "");
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 	return (SUCCESS);
5737c478bd9Sstevel@tonic-gate }
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate /*
5767c478bd9Sstevel@tonic-gate  * FUNCTION:	update_map_from_dit()
5777c478bd9Sstevel@tonic-gate  *
5787c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Core code called to update an entire map.
5797c478bd9Sstevel@tonic-gate  *		Information is recovered from LDAP and used to build a duplicate
5807c478bd9Sstevel@tonic-gate  *		copy of the live maps. When this is complete the maps are
5817c478bd9Sstevel@tonic-gate  *		locked and then overwritten by the new copy.
5827c478bd9Sstevel@tonic-gate  *
5837c478bd9Sstevel@tonic-gate  * INPUTS:	map_ctrl containing lots of information about the map and a
5847c478bd9Sstevel@tonic-gate  *		pointer to it's lock which will be required.
5857c478bd9Sstevel@tonic-gate  *		Flag indicating if progress logging is required.
5867c478bd9Sstevel@tonic-gate  *
5877c478bd9Sstevel@tonic-gate  * OUTPUTS:	SUCCESS = Map updated
5887c478bd9Sstevel@tonic-gate  *		FAILURE = Map not updated
5897c478bd9Sstevel@tonic-gate  */
5907c478bd9Sstevel@tonic-gate suc_code
update_map_from_dit(map_ctrl * map,bool_t log_flag)5917c478bd9Sstevel@tonic-gate update_map_from_dit(map_ctrl *map, bool_t log_flag) {
5927c478bd9Sstevel@tonic-gate 	__nis_table_mapping_t	*t;
5934a190493Ssdussud 	__nis_rule_value_t	*rv;
5947c478bd9Sstevel@tonic-gate 	__nis_ldap_search_t	*ls;
5957c478bd9Sstevel@tonic-gate 	__nis_object_dn_t	*objectDN = NULL;
5967c478bd9Sstevel@tonic-gate 	datum			*datval, *datkey;
5977c478bd9Sstevel@tonic-gate 	int			nr = 0, i, j, nv, numDNs;
5987c478bd9Sstevel@tonic-gate 	int			statP = SUCCESS, flag;
5997c478bd9Sstevel@tonic-gate 	char			*objname, **dn;
6007c478bd9Sstevel@tonic-gate 	/* Name of temporary entries DBM file */
6017c478bd9Sstevel@tonic-gate 	char			*temp_entries;
6027c478bd9Sstevel@tonic-gate 	/* Name of temporary TTL DBM file */
6037c478bd9Sstevel@tonic-gate 	char			*temp_ttl;
6047c478bd9Sstevel@tonic-gate 	/* Temporary DBM handles */
6057c478bd9Sstevel@tonic-gate 	DBM			*temp_entries_db;
6067c478bd9Sstevel@tonic-gate 	DBM			*temp_ttl_db;
6077c478bd9Sstevel@tonic-gate 	map_ctrl		temp_map;
6087c478bd9Sstevel@tonic-gate 	datum			key;
6097c478bd9Sstevel@tonic-gate 	char			*myself = "update_map_from_dit";
6107c478bd9Sstevel@tonic-gate 	bool_t			secure_flag;
6117c478bd9Sstevel@tonic-gate 	int			entry_count = 1;
6127c478bd9Sstevel@tonic-gate 	int			next_print = PRINT_FREQ;
613005e8a7dSandra 	int			search_flag = SUCCESS;
6147c478bd9Sstevel@tonic-gate 
615*ea10ff14SBen Chang 	int			m;
616*ea10ff14SBen Chang 
617*ea10ff14SBen Chang 	/* list of maps whose keys will be transliterated to lowercase */
618*ea10ff14SBen Chang 	char			*xlate_to_lcase_maps[] = {
619*ea10ff14SBen Chang 		"hosts.byname",
620*ea10ff14SBen Chang 		"ipnodes.byname",
621*ea10ff14SBen Chang 		NULL
622*ea10ff14SBen Chang 	};
623*ea10ff14SBen Chang 	bool_t			xlate_to_lcase = FALSE;
624*ea10ff14SBen Chang 
6257c478bd9Sstevel@tonic-gate 	if (!map || !map->map_name || !map->domain) {
6267c478bd9Sstevel@tonic-gate 		return (FAILURE);
6277c478bd9Sstevel@tonic-gate 	}
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate 	__nisdb_get_tsd()->escapeFlag = '\0';
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate 	/*
6327c478bd9Sstevel@tonic-gate 	 * netgroup.byxxx maps are a special case. They are regenerated from
6337c478bd9Sstevel@tonic-gate 	 * the netgroup map, not the DIT, so handle special case.
6347c478bd9Sstevel@tonic-gate 	 */
6357c478bd9Sstevel@tonic-gate 	if ((0 == strcmp(map->map_name, NETGROUP_BYHOST)) ||
6367c478bd9Sstevel@tonic-gate 		0 == (strcmp(map->map_name,  NETGROUP_BYUSER))) {
6377c478bd9Sstevel@tonic-gate 		return (update_netgroup_byxxx(map));
6387c478bd9Sstevel@tonic-gate 	}
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate 	/* Get the mapping information for the map */
6417c478bd9Sstevel@tonic-gate 	if ((t = mappingFromMap(map->map_name, map->domain, &statP)) == 0) {
6427c478bd9Sstevel@tonic-gate 		if (statP == MAP_NO_MAPPING_EXISTS)
6437c478bd9Sstevel@tonic-gate 			logmsg(MSG_NOTIMECHECK, LOG_WARNING,
6447c478bd9Sstevel@tonic-gate 			"%s: No mapping information available for %s,%s",
6457c478bd9Sstevel@tonic-gate 				myself, map->map_name, map->domain);
6467c478bd9Sstevel@tonic-gate 		return (FAILURE);
6477c478bd9Sstevel@tonic-gate 	}
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate 	/* Allocate and set up names */
6507c478bd9Sstevel@tonic-gate 	if (SUCCESS != alloc_temp_names(map->map_path,
6517c478bd9Sstevel@tonic-gate 				&temp_entries, &temp_ttl)) {
6527c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR,
6537c478bd9Sstevel@tonic-gate 			"%s: Unable to create map names for %s",
6547c478bd9Sstevel@tonic-gate 			myself, map->map_path);
6557c478bd9Sstevel@tonic-gate 		return (FAILURE);
6567c478bd9Sstevel@tonic-gate 	}
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 	/* Create temp entry and TTL file */
6597c478bd9Sstevel@tonic-gate 	if ((temp_entries_db = dbm_open(temp_entries, O_RDWR | O_CREAT, 0644))
6607c478bd9Sstevel@tonic-gate 						== NULL) {
6617c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not open %s",
6627c478bd9Sstevel@tonic-gate 						myself, temp_entries);
6637c478bd9Sstevel@tonic-gate 		sfree(temp_entries);
6647c478bd9Sstevel@tonic-gate 		sfree(temp_ttl);
6657c478bd9Sstevel@tonic-gate 		return (FAILURE);
6667c478bd9Sstevel@tonic-gate 	}
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate 	if ((temp_ttl_db = dbm_open(temp_ttl, O_RDWR | O_CREAT, 0644))
6697c478bd9Sstevel@tonic-gate 						== NULL) {
6707c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not open %s",
6717c478bd9Sstevel@tonic-gate 						myself, temp_ttl);
6727c478bd9Sstevel@tonic-gate 		dbm_close(temp_entries_db);
6737c478bd9Sstevel@tonic-gate 		delete_map(temp_entries);
6747c478bd9Sstevel@tonic-gate 		sfree(temp_entries);
6757c478bd9Sstevel@tonic-gate 		sfree(temp_ttl);
6767c478bd9Sstevel@tonic-gate 		return (FAILURE);
6777c478bd9Sstevel@tonic-gate 	}
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate 	/* Initialize domainContext tsd */
6807c478bd9Sstevel@tonic-gate 	__nisdb_get_tsd()->domainContext = 0;
6817c478bd9Sstevel@tonic-gate 	for (i = 0; i < ypDomains.numDomains; i++) {
6827c478bd9Sstevel@tonic-gate 		if (0 == ypDomains.domainLabels[i])
6837c478bd9Sstevel@tonic-gate 			continue;
6847c478bd9Sstevel@tonic-gate 		if (0 == strcasecmp(map->domain, ypDomains.domainLabels[i])) {
6857c478bd9Sstevel@tonic-gate 			__nisdb_get_tsd()->domainContext = ypDomains.domains[i];
6867c478bd9Sstevel@tonic-gate 			break;
6877c478bd9Sstevel@tonic-gate 		}
6887c478bd9Sstevel@tonic-gate 	}
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate 	if (!(objname = getFullMapName(map->map_name, map->domain))) {
6917c478bd9Sstevel@tonic-gate 		if (temp_entries_db)
6927c478bd9Sstevel@tonic-gate 			dbm_close(temp_entries_db);
6937c478bd9Sstevel@tonic-gate 		if (temp_ttl_db)
6947c478bd9Sstevel@tonic-gate 			dbm_close(temp_ttl_db);
6957c478bd9Sstevel@tonic-gate 		delete_map(temp_entries);
6967c478bd9Sstevel@tonic-gate 		sfree(temp_entries);
6977c478bd9Sstevel@tonic-gate 		delete_map(temp_ttl);
6987c478bd9Sstevel@tonic-gate 		sfree(temp_ttl);
6997c478bd9Sstevel@tonic-gate 		return (FAILURE);
7007c478bd9Sstevel@tonic-gate 	}
7017c478bd9Sstevel@tonic-gate 
702*ea10ff14SBen Chang 	/*
703*ea10ff14SBen Chang 	 * set xlate_to_lcase to TRUE if map_name is found in
704*ea10ff14SBen Chang 	 * xlate_to_lcase_maps[]
705*ea10ff14SBen Chang 	 */
706*ea10ff14SBen Chang 	m = 0;
707*ea10ff14SBen Chang 	while (xlate_to_lcase_maps[m] != NULL) {
708*ea10ff14SBen Chang 		if (strncmp(map->map_name, xlate_to_lcase_maps[m],
709*ea10ff14SBen Chang 			strlen(xlate_to_lcase_maps[m])) == 0) {
710*ea10ff14SBen Chang 			xlate_to_lcase = TRUE;
711*ea10ff14SBen Chang 			break;
712*ea10ff14SBen Chang 		}
713*ea10ff14SBen Chang 		++m;
714*ea10ff14SBen Chang 	}
715*ea10ff14SBen Chang 
7167c478bd9Sstevel@tonic-gate 	/* Try each mapping for the map */
717005e8a7dSandra 	for (flag = 0; t != 0 && search_flag != FAILURE; t = t->next) {
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate 		/* Check if the mapping is the correct one */
7207c478bd9Sstevel@tonic-gate 		if (strcmp(objname, t->objName) != 0) {
7217c478bd9Sstevel@tonic-gate 			continue;
7227c478bd9Sstevel@tonic-gate 		}
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate 		/* Check if rulesFromLDAP are provided */
7257c478bd9Sstevel@tonic-gate 		if (t->numRulesFromLDAP == 0) {
7267c478bd9Sstevel@tonic-gate 			logmsg(MSG_NOTIMECHECK, LOG_ERR,
7277c478bd9Sstevel@tonic-gate 				"%s: No rulesFromLDAP available for %s (%s)",
7287c478bd9Sstevel@tonic-gate 				myself, t->dbId, map->map_name);
7297c478bd9Sstevel@tonic-gate 			continue;
7307c478bd9Sstevel@tonic-gate 		}
7317c478bd9Sstevel@tonic-gate 
7327c478bd9Sstevel@tonic-gate 		/* Set flag to indicate update is enabled */
7337c478bd9Sstevel@tonic-gate 		flag = 1;
7347c478bd9Sstevel@tonic-gate 		/* Create ldap request for enumeration */
7357c478bd9Sstevel@tonic-gate 		for (objectDN = t->objectDN;
7367c478bd9Sstevel@tonic-gate 				objectDN && objectDN->read.base;
7377c478bd9Sstevel@tonic-gate 				objectDN = objectDN->next) {
7387c478bd9Sstevel@tonic-gate 			if ((ls = createLdapRequest(t, 0, 0, 1, NULL,
7397c478bd9Sstevel@tonic-gate 						objectDN)) == 0) {
7407c478bd9Sstevel@tonic-gate 				logmsg(MSG_NOTIMECHECK, LOG_ERR,
7417c478bd9Sstevel@tonic-gate 					"%s: Failed to create "
7427c478bd9Sstevel@tonic-gate 					"ldapSearch request for "
7437c478bd9Sstevel@tonic-gate 					"%s (%s) for base %s",
7447c478bd9Sstevel@tonic-gate 					myself, t->dbId,
7457c478bd9Sstevel@tonic-gate 					map->map_name,
7467c478bd9Sstevel@tonic-gate 					objectDN->read.base);
7477c478bd9Sstevel@tonic-gate 				statP = FAILURE;
748005e8a7dSandra 				search_flag = FAILURE;
7497c478bd9Sstevel@tonic-gate 				break;
7507c478bd9Sstevel@tonic-gate 			}
7517c478bd9Sstevel@tonic-gate 
7527c478bd9Sstevel@tonic-gate 			if (log_flag) {
7537c478bd9Sstevel@tonic-gate 				printf("Waiting for LDAP search results.\n");
7547c478bd9Sstevel@tonic-gate 			}
7557c478bd9Sstevel@tonic-gate 
7567c478bd9Sstevel@tonic-gate 			/* Query LDAP */
7577c478bd9Sstevel@tonic-gate 			nr = (ls->isDN)?0:-1;
7587c478bd9Sstevel@tonic-gate 			rv = ldapSearch(ls, &nr, 0, &statP);
7597c478bd9Sstevel@tonic-gate 			freeLdapSearch(ls);
7607c478bd9Sstevel@tonic-gate 			if (rv == 0) {
7617c478bd9Sstevel@tonic-gate 				if (statP == LDAP_NO_SUCH_OBJECT) {
7627c478bd9Sstevel@tonic-gate 				/*
7637c478bd9Sstevel@tonic-gate 				 * No Entry exists in the ldap server. Not
7647c478bd9Sstevel@tonic-gate 				 * a problem. Maybe there are just no entries
7657c478bd9Sstevel@tonic-gate 				 * in this map.
7667c478bd9Sstevel@tonic-gate 				 */
7677c478bd9Sstevel@tonic-gate 					continue;
7687c478bd9Sstevel@tonic-gate 				}
7697c478bd9Sstevel@tonic-gate 				logmsg(MSG_NOTIMECHECK, LOG_ERR,
7707c478bd9Sstevel@tonic-gate 					"%s: ldapSearch error %d "
7717c478bd9Sstevel@tonic-gate 					"(%s) for %s (%s) for base %s",
7727c478bd9Sstevel@tonic-gate 					myself, statP, ldap_err2string(statP),
7737c478bd9Sstevel@tonic-gate 					t->dbId, map->map_name,
7747c478bd9Sstevel@tonic-gate 					objectDN->read.base);
7757c478bd9Sstevel@tonic-gate 				statP = FAILURE;
776005e8a7dSandra 				search_flag = FAILURE;
7777c478bd9Sstevel@tonic-gate 				break;
7787c478bd9Sstevel@tonic-gate 			}
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate 			if (log_flag) {
7817c478bd9Sstevel@tonic-gate 				printf("Processing search results.\n");
7827c478bd9Sstevel@tonic-gate 			}
7837c478bd9Sstevel@tonic-gate 
7847c478bd9Sstevel@tonic-gate 			/* Obtain list of DNs for logging */
7857c478bd9Sstevel@tonic-gate 			if ((dn = findDNs(myself, rv, nr, 0, &numDNs)) == 0) {
7867c478bd9Sstevel@tonic-gate 				statP = FAILURE;
787005e8a7dSandra 				search_flag = FAILURE;
7887c478bd9Sstevel@tonic-gate 				break;
7897c478bd9Sstevel@tonic-gate 			}
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate 			/* For each entry in the result  do the following */
7927c478bd9Sstevel@tonic-gate 			for (i = 0; i < nr; i++) {
7937c478bd9Sstevel@tonic-gate 			/* Convert LDAP data to NIS equivalents */
7947c478bd9Sstevel@tonic-gate 				statP = buildNISRuleValue(t, &rv[i],
7957c478bd9Sstevel@tonic-gate 						map->domain);
7967c478bd9Sstevel@tonic-gate 				if (statP == MAP_INDEXLIST_ERROR)
7977c478bd9Sstevel@tonic-gate 					continue;
7987c478bd9Sstevel@tonic-gate 				if (statP != SUCCESS) {
7997c478bd9Sstevel@tonic-gate 					logmsg(MSG_NOTIMECHECK, LOG_WARNING,
8007c478bd9Sstevel@tonic-gate 					    "%s: Conversion error %d (LDAP to "
8017c478bd9Sstevel@tonic-gate 					    "name=value pairs) "
8027c478bd9Sstevel@tonic-gate 					    "for (dn: %s) for "
8037c478bd9Sstevel@tonic-gate 					    "%s (%s) for base %s",
8047c478bd9Sstevel@tonic-gate 					    myself, statP, NIL(dn[i]),
8057c478bd9Sstevel@tonic-gate 					    t->dbId, map->map_name,
8067c478bd9Sstevel@tonic-gate 					    objectDN->read.base);
8077c478bd9Sstevel@tonic-gate 					continue;
8087c478bd9Sstevel@tonic-gate 				}
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate 				/* Obtain the datum for value */
8117c478bd9Sstevel@tonic-gate 				datval = ruleValueToDatum(t, &rv[i], &statP);
8127c478bd9Sstevel@tonic-gate 				if (datval == 0) {
8137c478bd9Sstevel@tonic-gate 					logmsg(MSG_NOTIMECHECK, LOG_WARNING,
8147c478bd9Sstevel@tonic-gate 						"%s: Conversion error %d "
8157c478bd9Sstevel@tonic-gate 						"(name=value pairs to NIS)"
8167c478bd9Sstevel@tonic-gate 						" for (dn: %s) for "
8177c478bd9Sstevel@tonic-gate 						"%s (%s) for base %s",
8187c478bd9Sstevel@tonic-gate 						myself, statP, NIL(dn[i]),
8197c478bd9Sstevel@tonic-gate 						t->dbId, map->map_name,
8207c478bd9Sstevel@tonic-gate 						objectDN->read.base);
8217c478bd9Sstevel@tonic-gate 					continue;
8227c478bd9Sstevel@tonic-gate 				}
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate 				/* Obtain the datum for key */
8257c478bd9Sstevel@tonic-gate 				datkey = getKeyFromRuleValue(t, &rv[i],
826*ea10ff14SBen Chang 				    &nv, &statP, xlate_to_lcase);
8277c478bd9Sstevel@tonic-gate 				if (datkey == 0) {
8287c478bd9Sstevel@tonic-gate 					logmsg(MSG_NOTIMECHECK, LOG_WARNING,
8297c478bd9Sstevel@tonic-gate 						"%s: Unable to obtain NIS "
8307c478bd9Sstevel@tonic-gate 						"key from LDAP data (dn:%s) "
8317c478bd9Sstevel@tonic-gate 						"for %s (%s) for base %s",
8327c478bd9Sstevel@tonic-gate 						myself, NIL(dn[i]), t->dbId,
8337c478bd9Sstevel@tonic-gate 						map->map_name,
8347c478bd9Sstevel@tonic-gate 						objectDN->read.base);
8357c478bd9Sstevel@tonic-gate 					sfree(datval->dptr);
8367c478bd9Sstevel@tonic-gate 					sfree(datval);
8377c478bd9Sstevel@tonic-gate 					continue;
8387c478bd9Sstevel@tonic-gate 				}
8397c478bd9Sstevel@tonic-gate 
8407c478bd9Sstevel@tonic-gate 				/* Write to the temporary map */
8417c478bd9Sstevel@tonic-gate 				for (j = 0; j < nv; j++, entry_count ++) {
8427c478bd9Sstevel@tonic-gate 					if (datkey[j].dsize == 0)
8437c478bd9Sstevel@tonic-gate 						continue;
8447c478bd9Sstevel@tonic-gate 					errno = 0;
8457c478bd9Sstevel@tonic-gate 					/* DBM_INSERT to match */
8467c478bd9Sstevel@tonic-gate 					/* singleReadFromDIT */
8477c478bd9Sstevel@tonic-gate 					if (dbm_store(temp_entries_db,
8487c478bd9Sstevel@tonic-gate 						datkey[j],
8497c478bd9Sstevel@tonic-gate 						*datval,
8507c478bd9Sstevel@tonic-gate 						DBM_INSERT) < 0) {
8517c478bd9Sstevel@tonic-gate 						/*
8527c478bd9Sstevel@tonic-gate 						 * For some cases errno may
8537c478bd9Sstevel@tonic-gate 						 * still be 0 but dbm_error
8547c478bd9Sstevel@tonic-gate 						 * isn't informative at all.
8557c478bd9Sstevel@tonic-gate 						 */
8567c478bd9Sstevel@tonic-gate 						logmsg(MSG_NOTIMECHECK,
8577c478bd9Sstevel@tonic-gate 						    LOG_WARNING,
8587c478bd9Sstevel@tonic-gate 						    "%s: dbm store error "
8597c478bd9Sstevel@tonic-gate 						    "(errno=%d) "
8607c478bd9Sstevel@tonic-gate 						    "for (key=%s, value=%s) "
8617c478bd9Sstevel@tonic-gate 						    "for %s (%s) for base %s",
8627c478bd9Sstevel@tonic-gate 						    myself,
8637c478bd9Sstevel@tonic-gate 						    errno,
8647c478bd9Sstevel@tonic-gate 						    datkey[j].dptr,
8657c478bd9Sstevel@tonic-gate 						    datval->dptr, t->dbId,
8667c478bd9Sstevel@tonic-gate 						    map->map_name,
8677c478bd9Sstevel@tonic-gate 						    objectDN->read.base);
8687c478bd9Sstevel@tonic-gate 						/* clear the error */
8697c478bd9Sstevel@tonic-gate 						dbm_clearerr(temp_entries_db);
8707c478bd9Sstevel@tonic-gate 					}
8717c478bd9Sstevel@tonic-gate 					sfree(datkey[j].dptr);
8727c478bd9Sstevel@tonic-gate 
8737c478bd9Sstevel@tonic-gate 					if (log_flag && (entry_count >=
8747c478bd9Sstevel@tonic-gate 							next_print)) {
8757c478bd9Sstevel@tonic-gate 						printf("%d entries processed\n",
8767c478bd9Sstevel@tonic-gate 							entry_count);
8777c478bd9Sstevel@tonic-gate 						next_print *= 2;
8787c478bd9Sstevel@tonic-gate 					}
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate 				}
8817c478bd9Sstevel@tonic-gate 				sfree(datkey);
8827c478bd9Sstevel@tonic-gate 				sfree(datval->dptr);
8837c478bd9Sstevel@tonic-gate 				sfree(datval);
8847c478bd9Sstevel@tonic-gate 			}
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate 			freeRuleValue(rv, nr);
8877c478bd9Sstevel@tonic-gate 			freeDNs(dn, numDNs);
8887c478bd9Sstevel@tonic-gate 		} /* End of for over objectDN */
8897c478bd9Sstevel@tonic-gate 	}
8907c478bd9Sstevel@tonic-gate 	sfree(objname);
8917c478bd9Sstevel@tonic-gate 
892005e8a7dSandra 	if (t != 0 || flag == 0 || search_flag == FAILURE) {
8937c478bd9Sstevel@tonic-gate 		if (temp_entries_db)
8947c478bd9Sstevel@tonic-gate 			dbm_close(temp_entries_db);
8957c478bd9Sstevel@tonic-gate 		if (temp_ttl_db)
8967c478bd9Sstevel@tonic-gate 			dbm_close(temp_ttl_db);
8977c478bd9Sstevel@tonic-gate 		delete_map(temp_entries);
8987c478bd9Sstevel@tonic-gate 		sfree(temp_entries);
8997c478bd9Sstevel@tonic-gate 		delete_map(temp_ttl);
9007c478bd9Sstevel@tonic-gate 		sfree(temp_ttl);
9017c478bd9Sstevel@tonic-gate 		return (statP);
9027c478bd9Sstevel@tonic-gate 	}
9037c478bd9Sstevel@tonic-gate 	/* Set up enough of map_ctrl to call update_entry_ttl */
9047c478bd9Sstevel@tonic-gate 	temp_map.map_name = map->map_name;
9057c478bd9Sstevel@tonic-gate 	temp_map.domain = map->domain;
9067c478bd9Sstevel@tonic-gate 	temp_map.ttl = temp_ttl_db;
9077c478bd9Sstevel@tonic-gate 
9087c478bd9Sstevel@tonic-gate 	/* Generate new TTL file */
9097c478bd9Sstevel@tonic-gate 	key = dbm_firstkey(temp_entries_db);
9107c478bd9Sstevel@tonic-gate 	while (key.dptr != 0) {
9117c478bd9Sstevel@tonic-gate 		if (!is_special_key(&key))
9127c478bd9Sstevel@tonic-gate 			/*
9137c478bd9Sstevel@tonic-gate 			 * We don't want all the entries to time out at the
9147c478bd9Sstevel@tonic-gate 			 * same time so create random TTLs.
9157c478bd9Sstevel@tonic-gate 			 */
9167c478bd9Sstevel@tonic-gate 			if (FAILURE == update_entry_ttl(&temp_map, &key,
9177c478bd9Sstevel@tonic-gate 								TTL_RAND))
9187c478bd9Sstevel@tonic-gate 				logmsg(MSG_NOTIMECHECK, LOG_ERR,
9197c478bd9Sstevel@tonic-gate 					"%s: Could not update TTL for "
9207c478bd9Sstevel@tonic-gate 					"(key=%s) for map %s,%s",
9217c478bd9Sstevel@tonic-gate 					myself, NIL(key.dptr), map->map_name,
9227c478bd9Sstevel@tonic-gate 					map->domain);
9237c478bd9Sstevel@tonic-gate 		key = dbm_nextkey(temp_entries_db);
9247c478bd9Sstevel@tonic-gate 	}
9257c478bd9Sstevel@tonic-gate 
9267c478bd9Sstevel@tonic-gate 	/* Update map TTL */
9277c478bd9Sstevel@tonic-gate 	if (SUCCESS != update_map_ttl(&temp_map)) {
9287c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not update map TTL "
9297c478bd9Sstevel@tonic-gate 			"for %s,%s", myself, map->map_name, map->domain);
9307c478bd9Sstevel@tonic-gate 	}
9317c478bd9Sstevel@tonic-gate 
9327c478bd9Sstevel@tonic-gate 	/* Set up 'special' nis entries */
9337c478bd9Sstevel@tonic-gate 	add_special_entries(temp_entries_db, map, &secure_flag);
9347c478bd9Sstevel@tonic-gate 
9357c478bd9Sstevel@tonic-gate 	/* Close temp DBM files */
9367c478bd9Sstevel@tonic-gate 	dbm_close(temp_entries_db);
9377c478bd9Sstevel@tonic-gate 	dbm_close(temp_ttl_db);
9387c478bd9Sstevel@tonic-gate 
9397c478bd9Sstevel@tonic-gate 	/* Lock access to the map for copy */
9407c478bd9Sstevel@tonic-gate 	lock_map_ctrl(map);
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate 	/* Move temp maps to real ones */
9437c478bd9Sstevel@tonic-gate 	rename_map(temp_entries, map->map_path, secure_flag);
9447c478bd9Sstevel@tonic-gate 	rename_map(temp_ttl, map->ttl_path, secure_flag);
9457c478bd9Sstevel@tonic-gate 
9467c478bd9Sstevel@tonic-gate 	/* Free file names */
9477c478bd9Sstevel@tonic-gate 	sfree(temp_entries);
9487c478bd9Sstevel@tonic-gate 	sfree(temp_ttl);
9497c478bd9Sstevel@tonic-gate 
9507c478bd9Sstevel@tonic-gate 	/* Unlock map */
9517c478bd9Sstevel@tonic-gate 	unlock_map_ctrl(map);
9527c478bd9Sstevel@tonic-gate 
9537c478bd9Sstevel@tonic-gate 	return (SUCCESS);
9547c478bd9Sstevel@tonic-gate }
9557c478bd9Sstevel@tonic-gate 
9567c478bd9Sstevel@tonic-gate /*
9577c478bd9Sstevel@tonic-gate  * FUNCTION :	get_mapping_map_list()
9587c478bd9Sstevel@tonic-gate  *
9597c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Gets a list of nis maps for a given domain specified in the
9607c478bd9Sstevel@tonic-gate  *		mapping file. This information is not saved so have to go
9617c478bd9Sstevel@tonic-gate  *		through the entire hash table. At least this is only done at
9627c478bd9Sstevel@tonic-gate  *		initialization time.
9637c478bd9Sstevel@tonic-gate  *
9647c478bd9Sstevel@tonic-gate  * GIVEN :	Domain name
9657c478bd9Sstevel@tonic-gate  *
9667c478bd9Sstevel@tonic-gate  * RETURNS :	List of map names in malloced memory. MUST BE FREED BY CALLER.
9677c478bd9Sstevel@tonic-gate  */
9687c478bd9Sstevel@tonic-gate char **
get_mapping_map_list(char * domain)9697c478bd9Sstevel@tonic-gate get_mapping_map_list(char *domain)
9707c478bd9Sstevel@tonic-gate {
9717c478bd9Sstevel@tonic-gate 	char *myself = "get_mapping_map_list";
9727c478bd9Sstevel@tonic-gate 	__nis_hash_item_mt *it;
9737c478bd9Sstevel@tonic-gate 	int	i, j, size;
9744a190493Ssdussud 	char 	*end_ptr;
9757c478bd9Sstevel@tonic-gate 	char	**res;		/* Result array */
9767c478bd9Sstevel@tonic-gate 	char	**res_old;	/* Old value of res during realloc */
9777c478bd9Sstevel@tonic-gate 	int	array_size;	/* Current malloced size */
9787c478bd9Sstevel@tonic-gate 	int	res_count = 0;	/* Current result count */
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate 	/*
9817c478bd9Sstevel@tonic-gate 	 * Always need an array even if just for terminator. Normally one
9827c478bd9Sstevel@tonic-gate 	 * chunk will be enough.
9837c478bd9Sstevel@tonic-gate 	 */
9847c478bd9Sstevel@tonic-gate 	res = am(myself, ARRAY_CHUNK * sizeof (char *));
9857c478bd9Sstevel@tonic-gate 	if (NULL == res)
9867c478bd9Sstevel@tonic-gate 		return (NULL);
9877c478bd9Sstevel@tonic-gate 	array_size = ARRAY_CHUNK;
9887c478bd9Sstevel@tonic-gate 
9897c478bd9Sstevel@tonic-gate 	/* Work out hash table length */
9907c478bd9Sstevel@tonic-gate 	size = sizeof (ldapMappingList.keys) / sizeof (ldapMappingList.keys[0]);
9917c478bd9Sstevel@tonic-gate 	/* For all hash table entries */
9927c478bd9Sstevel@tonic-gate 	for (i = 0; i < size; i++) {
9937c478bd9Sstevel@tonic-gate 		/* Walk linked list for this hash table entry */
9947c478bd9Sstevel@tonic-gate 		for (it = ldapMappingList.keys[i]; NULL != it; it = it->next) {
9957c478bd9Sstevel@tonic-gate 
9967c478bd9Sstevel@tonic-gate 			/* Check it's not a split field entry */
9977c478bd9Sstevel@tonic-gate 			if (0 != ((__nis_table_mapping_t *)it)->numSplits)
9987c478bd9Sstevel@tonic-gate 				continue;
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate 			/* Check right domain (minus trailing dot) */
10017c478bd9Sstevel@tonic-gate 			if (strlen(domain) >= strlen(it->name))
10027c478bd9Sstevel@tonic-gate 				continue;
10037c478bd9Sstevel@tonic-gate 			end_ptr = it->name + strlen(it->name) -
10047c478bd9Sstevel@tonic-gate 			    strlen(domain) - 1;
10057c478bd9Sstevel@tonic-gate 			if (',' != *(end_ptr - 1))
10067c478bd9Sstevel@tonic-gate 				continue;
10077c478bd9Sstevel@tonic-gate 			if (0 != strncmp(end_ptr, domain, strlen(domain)))
10087c478bd9Sstevel@tonic-gate 				continue;
10097c478bd9Sstevel@tonic-gate 
10107c478bd9Sstevel@tonic-gate 			/* Check if we need to enlarge array */
10117c478bd9Sstevel@tonic-gate 			if ((res_count + 1) >= array_size) {
10127c478bd9Sstevel@tonic-gate 				array_size += ARRAY_CHUNK;
10137c478bd9Sstevel@tonic-gate 				res_old = res;
10147c478bd9Sstevel@tonic-gate 				res = realloc(res, array_size *
10157c478bd9Sstevel@tonic-gate 				    sizeof (char *));
10167c478bd9Sstevel@tonic-gate 				if (NULL == res) {
10177c478bd9Sstevel@tonic-gate 					res_old[res_count] = NULL;
10187c478bd9Sstevel@tonic-gate 					free_passwd_list(res_old);
10197c478bd9Sstevel@tonic-gate 					return (NULL);
10207c478bd9Sstevel@tonic-gate 				}
10217c478bd9Sstevel@tonic-gate 			}
10227c478bd9Sstevel@tonic-gate 
10237c478bd9Sstevel@tonic-gate 			/*
10247c478bd9Sstevel@tonic-gate 			 * We will need the sequence number when we come to
10257c478bd9Sstevel@tonic-gate 			 * sort the entries so for now store a pointer to
10267c478bd9Sstevel@tonic-gate 			 * the __nis_hash_item_mt.
10277c478bd9Sstevel@tonic-gate 			 */
10287c478bd9Sstevel@tonic-gate 			res[res_count] = (char *)it;
10297c478bd9Sstevel@tonic-gate 			res_count ++;
10307c478bd9Sstevel@tonic-gate 		}
10317c478bd9Sstevel@tonic-gate 	}
10327c478bd9Sstevel@tonic-gate 
10337c478bd9Sstevel@tonic-gate 	/* Terminate array */
10347c478bd9Sstevel@tonic-gate 	res[res_count] = NULL;
10357c478bd9Sstevel@tonic-gate 
10367c478bd9Sstevel@tonic-gate 	/* Bubble sort entries into the same order as mapping file */
10377c478bd9Sstevel@tonic-gate 	for (i = res_count - 2; 0 <= i; i--) {
10387c478bd9Sstevel@tonic-gate 		for (j = 0; j <= i; j++) {
10397c478bd9Sstevel@tonic-gate 			if (((__nis_table_mapping_t *)res[j + 1])->seq_num <
10407c478bd9Sstevel@tonic-gate 			    ((__nis_table_mapping_t *)res[j])->seq_num) {
10417c478bd9Sstevel@tonic-gate 				end_ptr = res[j];
10427c478bd9Sstevel@tonic-gate 				res[j] = res[j+1];
10437c478bd9Sstevel@tonic-gate 				res[j + 1] = end_ptr;
10447c478bd9Sstevel@tonic-gate 			}
10457c478bd9Sstevel@tonic-gate 		}
10467c478bd9Sstevel@tonic-gate 	}
10477c478bd9Sstevel@tonic-gate 
10487c478bd9Sstevel@tonic-gate 	/* Finally copy the real strings in to each entry */
10497c478bd9Sstevel@tonic-gate 	for (i = 0; NULL != res[i]; i ++) {
10507c478bd9Sstevel@tonic-gate 
10517c478bd9Sstevel@tonic-gate 		/* Get hash table entry back */
10527c478bd9Sstevel@tonic-gate 		it = (__nis_hash_item_mt *)res[i];
10537c478bd9Sstevel@tonic-gate 
10547c478bd9Sstevel@tonic-gate 		end_ptr = it->name + strlen(it->name) - strlen(domain) - 1;
10557c478bd9Sstevel@tonic-gate 
10567c478bd9Sstevel@tonic-gate 		/* What we really need is strndup() */
10577c478bd9Sstevel@tonic-gate 		res[i] = am(myself, end_ptr - it->name + 1);
10587c478bd9Sstevel@tonic-gate 		if (NULL == res[i]) {
10597c478bd9Sstevel@tonic-gate 			free_map_list(res);
10607c478bd9Sstevel@tonic-gate 			return (NULL);
10617c478bd9Sstevel@tonic-gate 		}
10627c478bd9Sstevel@tonic-gate 
10637c478bd9Sstevel@tonic-gate 		/* Copy from start to end_ptr */
10644a190493Ssdussud 		(void) memcpy(res[i], it->name, end_ptr-it->name - 1);
10657c478bd9Sstevel@tonic-gate 	}
10667c478bd9Sstevel@tonic-gate 
10677c478bd9Sstevel@tonic-gate 	return (res);
10687c478bd9Sstevel@tonic-gate }
10697c478bd9Sstevel@tonic-gate 
10707c478bd9Sstevel@tonic-gate /*
10717c478bd9Sstevel@tonic-gate  * FUNCTION :	make_nis_container()
10727c478bd9Sstevel@tonic-gate  *
10737c478bd9Sstevel@tonic-gate  * DESCRIPTION: Sets up container for map_name in the DIT.
10747c478bd9Sstevel@tonic-gate  *
10757c478bd9Sstevel@tonic-gate  * GIVEN :	Map name
10767c478bd9Sstevel@tonic-gate  *		The domain name.
10777c478bd9Sstevel@tonic-gate  *		Flag indicating if container should be created.
10787c478bd9Sstevel@tonic-gate  *
10797c478bd9Sstevel@tonic-gate  * RETURNS :	SUCCESS	= It worked
10807c478bd9Sstevel@tonic-gate  *		FAILURE	= There was a problem.
10817c478bd9Sstevel@tonic-gate  */
10827c478bd9Sstevel@tonic-gate suc_code
make_nis_container(char * map_name,char * domain,bool_t init_containers)10837c478bd9Sstevel@tonic-gate make_nis_container(char *map_name, char *domain, bool_t init_containers) {
10847c478bd9Sstevel@tonic-gate 	int			i, rc, statP = SUCCESS;
10857c478bd9Sstevel@tonic-gate 	__nis_table_mapping_t	*t;
10867c478bd9Sstevel@tonic-gate 	char			*dn;
10877c478bd9Sstevel@tonic-gate 	char			*myself = "make_nis_container";
10887c478bd9Sstevel@tonic-gate 
10897c478bd9Sstevel@tonic-gate 	if (!map_name || !domain)
10907c478bd9Sstevel@tonic-gate 		return (FAILURE);
10917c478bd9Sstevel@tonic-gate 
10927c478bd9Sstevel@tonic-gate 	if (FALSE == init_containers) {
10937c478bd9Sstevel@tonic-gate 		/*
10947c478bd9Sstevel@tonic-gate 		 * If we are not creating containers it is debatable what we
10957c478bd9Sstevel@tonic-gate 		 * should do . Maybe we should check for a pre-
10967c478bd9Sstevel@tonic-gate 		 * existing container and return failure if it does not exist.
10977c478bd9Sstevel@tonic-gate 		 *
10987c478bd9Sstevel@tonic-gate 		 * For now we assume the user will not have called us in this
10997c478bd9Sstevel@tonic-gate 		 * mode unless they know what they are doing. So return
11007c478bd9Sstevel@tonic-gate 		 * success. If they have got it wrong then latter writes will
11017c478bd9Sstevel@tonic-gate 		 * fail.
11027c478bd9Sstevel@tonic-gate 		 */
11037c478bd9Sstevel@tonic-gate 		return (SUCCESS);
11047c478bd9Sstevel@tonic-gate 	}
11057c478bd9Sstevel@tonic-gate 
11067c478bd9Sstevel@tonic-gate 	/* Get the mapping information for the map */
11077c478bd9Sstevel@tonic-gate 	if ((t = mappingFromMap(map_name, domain, &statP)) == 0) {
11087c478bd9Sstevel@tonic-gate 		if (statP == MAP_NO_MAPPING_EXISTS)
11097c478bd9Sstevel@tonic-gate 			logmsg(MSG_NOTIMECHECK, LOG_ERR,
11107c478bd9Sstevel@tonic-gate 			"%s: No mapping information available for %s,%s",
11117c478bd9Sstevel@tonic-gate 				myself, NIL(map_name), NIL(domain));
11127c478bd9Sstevel@tonic-gate 		return (FAILURE);
11137c478bd9Sstevel@tonic-gate 	}
11147c478bd9Sstevel@tonic-gate 
11157c478bd9Sstevel@tonic-gate 	/* Two times. One for readDN and other for writeDN */
11167c478bd9Sstevel@tonic-gate 	for (i = 0; i < 2; i++) {
11177c478bd9Sstevel@tonic-gate 		if (i == 0)
11187c478bd9Sstevel@tonic-gate 			dn = t->objectDN->read.base;
11197c478bd9Sstevel@tonic-gate 		else {
11207c478bd9Sstevel@tonic-gate 			if (t->objectDN->write.base == 0) {
11217c478bd9Sstevel@tonic-gate 				logmsg(MSG_NOTIMECHECK, LOG_INFO,
11227c478bd9Sstevel@tonic-gate 					"%s: No baseDN in writespec. Write "
11237c478bd9Sstevel@tonic-gate 					"disabled for %s,%s",
11247c478bd9Sstevel@tonic-gate 					myself, map_name, domain);
11257c478bd9Sstevel@tonic-gate 				break;
11267c478bd9Sstevel@tonic-gate 			}
11277c478bd9Sstevel@tonic-gate 			if (!strcasecmp(dn, t->objectDN->write.base))
11287c478bd9Sstevel@tonic-gate 				break;
11297c478bd9Sstevel@tonic-gate 			dn = t->objectDN->write.base;
11307c478bd9Sstevel@tonic-gate 		}
11317c478bd9Sstevel@tonic-gate 
11327c478bd9Sstevel@tonic-gate 		if ((rc = makeNISObject(0, dn)) == FAILURE) {
11337c478bd9Sstevel@tonic-gate 			logmsg(MSG_NOTIMECHECK, LOG_ERR,
11347c478bd9Sstevel@tonic-gate 				"%s: Unable to create ldap container (dn: %s) "
11357c478bd9Sstevel@tonic-gate 				"for %s,%s", myself, dn, map_name, domain);
11367c478bd9Sstevel@tonic-gate 			return (FAILURE);
11377c478bd9Sstevel@tonic-gate 		}
11387c478bd9Sstevel@tonic-gate 	}
11397c478bd9Sstevel@tonic-gate 	return (SUCCESS);
11407c478bd9Sstevel@tonic-gate }
11417c478bd9Sstevel@tonic-gate 
11427c478bd9Sstevel@tonic-gate /*
11437c478bd9Sstevel@tonic-gate  * FUNCTION :	make_nis_domain()
11447c478bd9Sstevel@tonic-gate  *
11457c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Sets up a nisDomainObject in the DIT
11467c478bd9Sstevel@tonic-gate  *
11477c478bd9Sstevel@tonic-gate  * GIVEN:	Name of the domain
11487c478bd9Sstevel@tonic-gate  *		Flag indicating if domain should be create or possibly just
11497c478bd9Sstevel@tonic-gate  *		checked for.
11507c478bd9Sstevel@tonic-gate  */
11517c478bd9Sstevel@tonic-gate suc_code
make_nis_domain(char * domain,bool_t init_containers)11527c478bd9Sstevel@tonic-gate make_nis_domain(char *domain, bool_t init_containers) {
11537c478bd9Sstevel@tonic-gate 
11547c478bd9Sstevel@tonic-gate 	if (FALSE == init_containers) {
11557c478bd9Sstevel@tonic-gate 		/*
11567c478bd9Sstevel@tonic-gate 		 * If we are not creating containers it is debatable what we
11577c478bd9Sstevel@tonic-gate 		 * should do with domains. Maybe we should check for a pre-
11587c478bd9Sstevel@tonic-gate 		 * existing domain and return failure if it does not exist.
11597c478bd9Sstevel@tonic-gate 		 *
11607c478bd9Sstevel@tonic-gate 		 * For now we assume the user will not have called us in this
11617c478bd9Sstevel@tonic-gate 		 * mode unless they know what they are doing. So return
11627c478bd9Sstevel@tonic-gate 		 * success. If they have got it wrong then latter writes will
11637c478bd9Sstevel@tonic-gate 		 * fail.
11647c478bd9Sstevel@tonic-gate 		 */
11657c478bd9Sstevel@tonic-gate 		return (SUCCESS);
11667c478bd9Sstevel@tonic-gate 	}
11677c478bd9Sstevel@tonic-gate 
11687c478bd9Sstevel@tonic-gate 	/* Create the domain */
11697c478bd9Sstevel@tonic-gate 	return (makeNISObject(domain, 0));
11707c478bd9Sstevel@tonic-gate }
11717c478bd9Sstevel@tonic-gate 
11727c478bd9Sstevel@tonic-gate /*
11737c478bd9Sstevel@tonic-gate  * FUNCTION:	update_netgroup_byxxx()
11747c478bd9Sstevel@tonic-gate  *
11757c478bd9Sstevel@tonic-gate  * DESCRIPTION:	Updates the netgroup.byxxx series of maps based on the current
11767c478bd9Sstevel@tonic-gate  *		netgroup file. We invoke revnetgroup so that if any changes
11777c478bd9Sstevel@tonic-gate  *		are made to this utility the same changes are made here.
11787c478bd9Sstevel@tonic-gate  *
11797c478bd9Sstevel@tonic-gate  * INPUTS:	map_ctrl containing lots of information about the map and a
11807c478bd9Sstevel@tonic-gate  *		pointer to it's lock which will be required.
11817c478bd9Sstevel@tonic-gate  *
11827c478bd9Sstevel@tonic-gate  * OUTPUTS:	SUCCESS = Map updated
11837c478bd9Sstevel@tonic-gate  *		FAILURE = Map not updated
11847c478bd9Sstevel@tonic-gate  */
11857c478bd9Sstevel@tonic-gate suc_code
update_netgroup_byxxx(map_ctrl * map)11867c478bd9Sstevel@tonic-gate update_netgroup_byxxx(map_ctrl *map) {
11877c478bd9Sstevel@tonic-gate 	/* Name of temporary entries DBM file */
11887c478bd9Sstevel@tonic-gate 	char			*temp_entries;
11897c478bd9Sstevel@tonic-gate 	/* Name of temporary TTL DBM file */
11907c478bd9Sstevel@tonic-gate 	char			*temp_ttl;
11917c478bd9Sstevel@tonic-gate 	/* Temporary DBM handles */
11927c478bd9Sstevel@tonic-gate 	DBM			*temp_entries_db;
11937c478bd9Sstevel@tonic-gate 	DBM			*temp_ttl_db;
11947c478bd9Sstevel@tonic-gate 	map_ctrl		temp_map;
11957c478bd9Sstevel@tonic-gate 	char			*myself = "update_netgroup_byxxx";
11967c478bd9Sstevel@tonic-gate 	char			*cmdbuf;
11977c478bd9Sstevel@tonic-gate 	int			cmd_length;
11987c478bd9Sstevel@tonic-gate 	datum			key;
11997c478bd9Sstevel@tonic-gate 	map_ctrl		*netgroupmap;
12007c478bd9Sstevel@tonic-gate 	int			res;
12017c478bd9Sstevel@tonic-gate 	/* Temporary revnetgroup files */
12027c478bd9Sstevel@tonic-gate 	const char 		*byhost = NETGROUP_BYHOST "_REV" TEMP_POSTFIX;
12037c478bd9Sstevel@tonic-gate 	const char 		*byuser = NETGROUP_BYUSER "_REV" TEMP_POSTFIX;
12047c478bd9Sstevel@tonic-gate 	const char		*temp_file_name;
12057c478bd9Sstevel@tonic-gate 
12067c478bd9Sstevel@tonic-gate 
12077c478bd9Sstevel@tonic-gate 	/*
12087c478bd9Sstevel@tonic-gate 	 * We need to use two different temporary files: one for netgroup.byhost
12097c478bd9Sstevel@tonic-gate 	 * and other for netgroup.byuser, since these two maps can be updated
12107c478bd9Sstevel@tonic-gate 	 * simultaneously. These temporary files will hold the output of
12117c478bd9Sstevel@tonic-gate 	 * revnetgroup [-h|-u] command. They are then used to generate the
12127c478bd9Sstevel@tonic-gate 	 * corresponding dbm files and thereafter deleted.
12137c478bd9Sstevel@tonic-gate 	 */
12147c478bd9Sstevel@tonic-gate 	if (0 == strcmp(map->map_name, NETGROUP_BYHOST))
12157c478bd9Sstevel@tonic-gate 		temp_file_name = byhost;
12167c478bd9Sstevel@tonic-gate 	else
12177c478bd9Sstevel@tonic-gate 		temp_file_name = byuser;
12187c478bd9Sstevel@tonic-gate 
12197c478bd9Sstevel@tonic-gate 	/* Alloc enough cmd buf for revnet cmd */
12207c478bd9Sstevel@tonic-gate 	cmd_length = strlen("/usr/sbin/makedbm -u ") +
12217c478bd9Sstevel@tonic-gate 			(strlen(map->map_path) - strlen(map->map_name)) +
12227c478bd9Sstevel@tonic-gate 			strlen(NETGROUP_MAP) +
12237c478bd9Sstevel@tonic-gate 			strlen(" | /usr/sbin/revnetgroup -h > ") +
12247c478bd9Sstevel@tonic-gate 			(strlen(map->map_path) - strlen(map->map_name)) +
12257c478bd9Sstevel@tonic-gate 			strlen(temp_file_name) + 1;
12267c478bd9Sstevel@tonic-gate 	cmdbuf = am(myself, cmd_length);
12277c478bd9Sstevel@tonic-gate 
12287c478bd9Sstevel@tonic-gate 	if (NULL == cmdbuf) {
12297c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR,
12307c478bd9Sstevel@tonic-gate 				"%s: Could not alloc cmdbuf.", myself);
12317c478bd9Sstevel@tonic-gate 		return (FAILURE);
12327c478bd9Sstevel@tonic-gate 	}
12337c478bd9Sstevel@tonic-gate 
12347c478bd9Sstevel@tonic-gate 	/*
12357c478bd9Sstevel@tonic-gate 	 * If necessary update (and wait for) netgroups map. This is a lot of
12367c478bd9Sstevel@tonic-gate 	 * work but if the netgroup map itself is not being accessed it may
12377c478bd9Sstevel@tonic-gate 	 * contain information that is not up to date with the DIT.
12387c478bd9Sstevel@tonic-gate 	 *
12397c478bd9Sstevel@tonic-gate 	 * We use the cmdbuf to store the qualified netgroup map name there will
12407c478bd9Sstevel@tonic-gate 	 * be enough space for this but we are not yet creating the cmd.
12417c478bd9Sstevel@tonic-gate 	 */
12427c478bd9Sstevel@tonic-gate 	strlcpy(cmdbuf, map->map_path, strlen(map->map_path) -
12437c478bd9Sstevel@tonic-gate 						strlen(map->map_name) + 1);
12447c478bd9Sstevel@tonic-gate 	strcat(cmdbuf, NETGROUP_MAP);
12457c478bd9Sstevel@tonic-gate 	netgroupmap = (map_ctrl *)shim_dbm_open(cmdbuf,
12467c478bd9Sstevel@tonic-gate 						O_RDWR | O_CREAT, 0644);
12477c478bd9Sstevel@tonic-gate 	if (NULL == netgroupmap) {
12487c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR,
12497c478bd9Sstevel@tonic-gate 				"%s: Could not update %s.", myself, cmdbuf);
12507c478bd9Sstevel@tonic-gate 		sfree(cmdbuf);
12517c478bd9Sstevel@tonic-gate 		return (FAILURE);
12527c478bd9Sstevel@tonic-gate 	}
12537c478bd9Sstevel@tonic-gate 
12547c478bd9Sstevel@tonic-gate 	if (has_map_expired(netgroupmap)) {
12557c478bd9Sstevel@tonic-gate 		lock_map_ctrl(netgroupmap);
12567c478bd9Sstevel@tonic-gate 		update_map_if_required(netgroupmap, TRUE);
12577c478bd9Sstevel@tonic-gate 		unlock_map_ctrl(netgroupmap);
12587c478bd9Sstevel@tonic-gate 	}
12597c478bd9Sstevel@tonic-gate 	shim_dbm_close((DBM *)netgroupmap);
12607c478bd9Sstevel@tonic-gate 
12617c478bd9Sstevel@tonic-gate 	/* Dump netgroup file through revnetgroup to a temp file */
12627c478bd9Sstevel@tonic-gate 	strcpy(cmdbuf, "/usr/sbin/makedbm -u ");
12637c478bd9Sstevel@tonic-gate 
12647c478bd9Sstevel@tonic-gate 	/* Unmake the netgroup file in same domain as map */
12657c478bd9Sstevel@tonic-gate 	strncat(cmdbuf, map->map_path, strlen(map->map_path) -
12667c478bd9Sstevel@tonic-gate 						strlen(map->map_name));
12677c478bd9Sstevel@tonic-gate 	strcat(cmdbuf, NETGROUP_MAP);
12687c478bd9Sstevel@tonic-gate 
12697c478bd9Sstevel@tonic-gate 	if (0 == strcmp(map->map_name, NETGROUP_BYHOST)) {
12707c478bd9Sstevel@tonic-gate 		strcat(cmdbuf, " | /usr/sbin/revnetgroup -h > ");
12717c478bd9Sstevel@tonic-gate 	} else {
12727c478bd9Sstevel@tonic-gate 		strcat(cmdbuf, " | /usr/sbin/revnetgroup -u > ");
12737c478bd9Sstevel@tonic-gate 	}
12747c478bd9Sstevel@tonic-gate 
12757c478bd9Sstevel@tonic-gate 	/* Create temp file file in same domain as map */
12767c478bd9Sstevel@tonic-gate 	strncat(cmdbuf, map->map_path, strlen(map->map_path) -
12777c478bd9Sstevel@tonic-gate 						strlen(map->map_name));
12787c478bd9Sstevel@tonic-gate 	strcat(cmdbuf, temp_file_name);
12797c478bd9Sstevel@tonic-gate 
12807c478bd9Sstevel@tonic-gate 	if (0 > system(cmdbuf)) {
12817c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not run \"%s\" "
12827c478bd9Sstevel@tonic-gate 			"(errno=%d)", myself, cmdbuf, errno);
12837c478bd9Sstevel@tonic-gate 		sfree(cmdbuf);
12847c478bd9Sstevel@tonic-gate 		return (FAILURE);
12857c478bd9Sstevel@tonic-gate 	}
12867c478bd9Sstevel@tonic-gate 	sfree(cmdbuf);
12877c478bd9Sstevel@tonic-gate 
12887c478bd9Sstevel@tonic-gate 	/* Allocate and set up names */
12897c478bd9Sstevel@tonic-gate 	if (SUCCESS != alloc_temp_names(map->map_path,
12907c478bd9Sstevel@tonic-gate 				&temp_entries, &temp_ttl)) {
12917c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR,
12927c478bd9Sstevel@tonic-gate 			"%s: Unable to create map names for %s",
12937c478bd9Sstevel@tonic-gate 			myself, map->map_path);
12947c478bd9Sstevel@tonic-gate 		return (FAILURE);
12957c478bd9Sstevel@tonic-gate 	}
12967c478bd9Sstevel@tonic-gate 
12977c478bd9Sstevel@tonic-gate 	/* Make the temporary DBM file */
12987c478bd9Sstevel@tonic-gate 	cmdbuf = am(myself, strlen("/usr/sbin/makedbm") +
12997c478bd9Sstevel@tonic-gate 			(strlen(map->map_path) - strlen(map->map_name)) +
13007c478bd9Sstevel@tonic-gate 			strlen(temp_file_name) +
13017c478bd9Sstevel@tonic-gate 			strlen(temp_entries) + 3);
13027c478bd9Sstevel@tonic-gate 	if (NULL == cmdbuf) {
13037c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR,
13047c478bd9Sstevel@tonic-gate 				"%s: Could not allocate cmdbuf.", myself);
13057c478bd9Sstevel@tonic-gate 		sfree(temp_entries);
13067c478bd9Sstevel@tonic-gate 		sfree(temp_ttl);
13077c478bd9Sstevel@tonic-gate 		return (FAILURE);
13087c478bd9Sstevel@tonic-gate 	}
13097c478bd9Sstevel@tonic-gate 
13107c478bd9Sstevel@tonic-gate 	strcpy(cmdbuf, "/usr/sbin/makedbm ");
13117c478bd9Sstevel@tonic-gate 	strncat(cmdbuf, map->map_path, strlen(map->map_path) -
13127c478bd9Sstevel@tonic-gate 						strlen(map->map_name));
13137c478bd9Sstevel@tonic-gate 	strcat(cmdbuf, temp_file_name);
13147c478bd9Sstevel@tonic-gate 	strcat(cmdbuf, " ");
13157c478bd9Sstevel@tonic-gate 	strcat(cmdbuf, temp_entries);
13167c478bd9Sstevel@tonic-gate 
13177c478bd9Sstevel@tonic-gate 	if (0 > system(cmdbuf)) {
13187c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not run \"%s\" "
13197c478bd9Sstevel@tonic-gate 			"(errno=%d)", myself, cmdbuf, errno);
13207c478bd9Sstevel@tonic-gate 		sfree(cmdbuf);
13217c478bd9Sstevel@tonic-gate 		sfree(temp_entries);
13227c478bd9Sstevel@tonic-gate 		sfree(temp_ttl);
13237c478bd9Sstevel@tonic-gate 		return (FAILURE);
13247c478bd9Sstevel@tonic-gate 	}
13257c478bd9Sstevel@tonic-gate 
13267c478bd9Sstevel@tonic-gate 	/* Already have enough command buffer to rm temporary file */
13277c478bd9Sstevel@tonic-gate 	strlcpy(cmdbuf, map->map_path, strlen(map->map_path) -
13287c478bd9Sstevel@tonic-gate 						strlen(map->map_name) + 1);
13297c478bd9Sstevel@tonic-gate 	strcat(cmdbuf, temp_file_name);
13307c478bd9Sstevel@tonic-gate 	res = unlink(cmdbuf);
13317c478bd9Sstevel@tonic-gate 	/* If the temp file did not exist no problem. Probably had no entries */
13327c478bd9Sstevel@tonic-gate 	if ((0 != res) && (ENOENT != errno)) {
13337c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not delete \"%s\" "
13347c478bd9Sstevel@tonic-gate 			"(errno=%d)", myself, cmdbuf, errno);
13357c478bd9Sstevel@tonic-gate 		sfree(temp_entries);
13367c478bd9Sstevel@tonic-gate 		sfree(temp_ttl);
13377c478bd9Sstevel@tonic-gate 		sfree(cmdbuf);
13387c478bd9Sstevel@tonic-gate 		return (FAILURE);
13397c478bd9Sstevel@tonic-gate 	}
13407c478bd9Sstevel@tonic-gate 	sfree(cmdbuf);
13417c478bd9Sstevel@tonic-gate 
13427c478bd9Sstevel@tonic-gate 	if ((temp_entries_db = dbm_open(temp_entries, O_RDWR | O_CREAT, 0644))
13437c478bd9Sstevel@tonic-gate 						== NULL) {
13447c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not open %s",
13457c478bd9Sstevel@tonic-gate 						myself, temp_entries);
13467c478bd9Sstevel@tonic-gate 		sfree(temp_entries);
13477c478bd9Sstevel@tonic-gate 		sfree(temp_ttl);
13487c478bd9Sstevel@tonic-gate 		return (FAILURE);
13497c478bd9Sstevel@tonic-gate 	}
13507c478bd9Sstevel@tonic-gate 
13517c478bd9Sstevel@tonic-gate 	if ((temp_ttl_db = dbm_open(temp_ttl, O_RDWR | O_CREAT, 0644))
13527c478bd9Sstevel@tonic-gate 						== NULL) {
13537c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not open %s",
13547c478bd9Sstevel@tonic-gate 						myself, temp_ttl);
13557c478bd9Sstevel@tonic-gate 		dbm_close(temp_entries_db);
13567c478bd9Sstevel@tonic-gate 		sfree(temp_entries);
13577c478bd9Sstevel@tonic-gate 		sfree(temp_ttl);
13587c478bd9Sstevel@tonic-gate 		return (FAILURE);
13597c478bd9Sstevel@tonic-gate 	}
13607c478bd9Sstevel@tonic-gate 
13617c478bd9Sstevel@tonic-gate 	/*
13627c478bd9Sstevel@tonic-gate 	 * Set up enough of map_ctrl to call update_entry_ttl. Since there is
13637c478bd9Sstevel@tonic-gate 	 * no mapping, and thus not TTL, defined for these maps use the TTL
13647c478bd9Sstevel@tonic-gate 	 * values for netgroup map
13657c478bd9Sstevel@tonic-gate 	 */
13667c478bd9Sstevel@tonic-gate 	temp_map.map_name = NETGROUP_MAP;
13677c478bd9Sstevel@tonic-gate 	temp_map.domain = map->domain;
13687c478bd9Sstevel@tonic-gate 	temp_map.ttl = temp_ttl_db;
13697c478bd9Sstevel@tonic-gate 
13707c478bd9Sstevel@tonic-gate 	/*
13717c478bd9Sstevel@tonic-gate 	 * Generate new TTL file.  Since these maps work only on the whole map
13727c478bd9Sstevel@tonic-gate 	 * expiry these will not actually be used but there presence makes it
13737c478bd9Sstevel@tonic-gate 	 * easier to handle these maps in the same way as other maps.
13747c478bd9Sstevel@tonic-gate 	 */
13757c478bd9Sstevel@tonic-gate 	key = dbm_firstkey(temp_entries_db);
13767c478bd9Sstevel@tonic-gate 	while (key.dptr != 0) {
13777c478bd9Sstevel@tonic-gate 		if (!is_special_key(&key))
13787c478bd9Sstevel@tonic-gate 			/*
13797c478bd9Sstevel@tonic-gate 			 * For these maps want all timouts to be maximum
13807c478bd9Sstevel@tonic-gate 			 */
13817c478bd9Sstevel@tonic-gate 			if (FAILURE == update_entry_ttl(&temp_map, &key,
13827c478bd9Sstevel@tonic-gate 								TTL_MAX))
13837c478bd9Sstevel@tonic-gate 				logmsg(MSG_NOTIMECHECK, LOG_ERR,
13847c478bd9Sstevel@tonic-gate 					"%s: Could not update TTL for "
13857c478bd9Sstevel@tonic-gate 					"(key=%s) for map %s,%s",
13867c478bd9Sstevel@tonic-gate 					myself, NIL(key.dptr), map->map_name,
13877c478bd9Sstevel@tonic-gate 					map->domain);
13887c478bd9Sstevel@tonic-gate 		key = dbm_nextkey(temp_entries_db);
13897c478bd9Sstevel@tonic-gate 	}
13907c478bd9Sstevel@tonic-gate 
13917c478bd9Sstevel@tonic-gate 	/* Update map TTL */
13927c478bd9Sstevel@tonic-gate 	update_map_ttl(&temp_map);
13937c478bd9Sstevel@tonic-gate 
13947c478bd9Sstevel@tonic-gate 	/* Close temp DBM files */
13957c478bd9Sstevel@tonic-gate 	dbm_close(temp_entries_db);
13967c478bd9Sstevel@tonic-gate 	dbm_close(temp_ttl_db);
13977c478bd9Sstevel@tonic-gate 
13987c478bd9Sstevel@tonic-gate 	/* Lock access to the map for copy */
13997c478bd9Sstevel@tonic-gate 	lock_map_ctrl(map);
14007c478bd9Sstevel@tonic-gate 
14017c478bd9Sstevel@tonic-gate 	/* Move temp maps to real ones */
14027c478bd9Sstevel@tonic-gate 	rename_map(temp_entries, map->map_path, FALSE);
14037c478bd9Sstevel@tonic-gate 	rename_map(temp_ttl, map->ttl_path, FALSE);
14047c478bd9Sstevel@tonic-gate 
14057c478bd9Sstevel@tonic-gate 	/* Free file names */
14067c478bd9Sstevel@tonic-gate 	sfree(temp_entries);
14077c478bd9Sstevel@tonic-gate 	sfree(temp_ttl);
14087c478bd9Sstevel@tonic-gate 
14097c478bd9Sstevel@tonic-gate 	/* Unlock map */
14107c478bd9Sstevel@tonic-gate 	unlock_map_ctrl(map);
14117c478bd9Sstevel@tonic-gate 
14127c478bd9Sstevel@tonic-gate 	return (SUCCESS);
14137c478bd9Sstevel@tonic-gate }
1414