xref: /onnv-gate/usr/src/lib/libnisdb/yptol/map_ctrl.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * DESCRIPTION:	Contains functions relating to the creation and manipulation
31*0Sstevel@tonic-gate  *		of map_ctrl structures. These are used to hold information
32*0Sstevel@tonic-gate  *		specific to one NIS map.
33*0Sstevel@tonic-gate  *
34*0Sstevel@tonic-gate  *		Because each of these contains a significant amount of state
35*0Sstevel@tonic-gate  *		information about an individual map they are created (on the
36*0Sstevel@tonic-gate  *		heap) when a map is opened and destroyed when it is closed.
37*0Sstevel@tonic-gate  *		The overhead of doing this is less than maintaining a pool
38*0Sstevel@tonic-gate  *		of map_ctrls.
39*0Sstevel@tonic-gate  *
40*0Sstevel@tonic-gate  *		If two processes access the same map two map_ctrls will be
41*0Sstevel@tonic-gate  *		created with similar contents (but differing DBM pointers).
42*0Sstevel@tonic-gate  *		Both will have the same hash value so when one is locked
43*0Sstevel@tonic-gate  *		access to the other will also be prevented.
44*0Sstevel@tonic-gate  */
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate #include <unistd.h>
47*0Sstevel@tonic-gate #include <syslog.h>
48*0Sstevel@tonic-gate #include <ndbm.h>
49*0Sstevel@tonic-gate #include <string.h>
50*0Sstevel@tonic-gate #include "ypsym.h"
51*0Sstevel@tonic-gate #include "ypdefs.h"
52*0Sstevel@tonic-gate #include "shim.h"
53*0Sstevel@tonic-gate #include "yptol.h"
54*0Sstevel@tonic-gate #include "../ldap_util.h"
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate /* Switch on parts of ypdefs.h */
57*0Sstevel@tonic-gate USE_DBM
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate /*
60*0Sstevel@tonic-gate  * FUNCTION: 	create_map_ctrl();
61*0Sstevel@tonic-gate  *
62*0Sstevel@tonic-gate  * DESCRIPTION: Create and a new map_ctrl in a non opened state.
63*0Sstevel@tonic-gate  *
64*0Sstevel@tonic-gate  * INPUTS:	Fully qualified map name
65*0Sstevel@tonic-gate  *
66*0Sstevel@tonic-gate  * OUTPUTS:	Pointer to map_ctrl
67*0Sstevel@tonic-gate  *		NULL on failure.
68*0Sstevel@tonic-gate  *
69*0Sstevel@tonic-gate  */
70*0Sstevel@tonic-gate map_ctrl *
71*0Sstevel@tonic-gate create_map_ctrl(char *name)
72*0Sstevel@tonic-gate {
73*0Sstevel@tonic-gate 	char *myself = "create_map_ctrl";
74*0Sstevel@tonic-gate 	map_ctrl *map;
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate 	map = (map_ctrl *)am(myself, sizeof (map_ctrl));
77*0Sstevel@tonic-gate 	if (NULL == map) {
78*0Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR, "Could not alloc map_ctrl");
79*0Sstevel@tonic-gate 		return (NULL);
80*0Sstevel@tonic-gate 	}
81*0Sstevel@tonic-gate 
82*0Sstevel@tonic-gate 	/* Clear new map (in case we have to free it) */
83*0Sstevel@tonic-gate 	map->entries = NULL;
84*0Sstevel@tonic-gate 	map->hash_val = 0;
85*0Sstevel@tonic-gate 	map->map_name = NULL;
86*0Sstevel@tonic-gate 	map->domain = NULL;
87*0Sstevel@tonic-gate 	map->map_path = NULL;
88*0Sstevel@tonic-gate 	map->ttl = NULL;
89*0Sstevel@tonic-gate 	map->ttl_path = NULL;
90*0Sstevel@tonic-gate 	map->trad_map_path = NULL;
91*0Sstevel@tonic-gate 	map->key_data.dptr = NULL;
92*0Sstevel@tonic-gate 	map->open_mode = 0;
93*0Sstevel@tonic-gate 	map->open_flags = 0;
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate 	/*
96*0Sstevel@tonic-gate 	 * Initialize the fields of the map_ctrl. By doing this once here we
97*0Sstevel@tonic-gate 	 * can save a lot of work as map entries are accessed.
98*0Sstevel@tonic-gate 	 */
99*0Sstevel@tonic-gate 	if (SUCCESS != map_ctrl_init(map, name)) {
100*0Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR,
101*0Sstevel@tonic-gate 				"Could not initialize map_ctrl for %s", name);
102*0Sstevel@tonic-gate 		free_map_ctrl(map);
103*0Sstevel@tonic-gate 		return (NULL);
104*0Sstevel@tonic-gate 	}
105*0Sstevel@tonic-gate 
106*0Sstevel@tonic-gate 	return (map);
107*0Sstevel@tonic-gate }
108*0Sstevel@tonic-gate 
109*0Sstevel@tonic-gate /*
110*0Sstevel@tonic-gate  * FUNCTION :	map_ctrl_init()
111*0Sstevel@tonic-gate  *
112*0Sstevel@tonic-gate  * DESCRIPTION:	Initializes the fields of a map_ctrl structure.
113*0Sstevel@tonic-gate  *
114*0Sstevel@tonic-gate  *		By doing this once (when the map_ctrl is created) we avoid
115*0Sstevel@tonic-gate  *		numerous other function having to repeat this string
116*0Sstevel@tonic-gate  *		manipulation.
117*0Sstevel@tonic-gate  *
118*0Sstevel@tonic-gate  * GIVEN :	Pointer to the structure
119*0Sstevel@tonic-gate  *		Fully qualified name of the map
120*0Sstevel@tonic-gate  *
121*0Sstevel@tonic-gate  * RETURNS :	SUCCESS = map_ctrl fully set up.
122*0Sstevel@tonic-gate  *		FAILURE = map_ctrl not set up CALLER MUST FREE.
123*0Sstevel@tonic-gate  */
124*0Sstevel@tonic-gate suc_code
125*0Sstevel@tonic-gate map_ctrl_init(map_ctrl *map, char *name)
126*0Sstevel@tonic-gate {
127*0Sstevel@tonic-gate 	char *myself = "map_ctrl_init";
128*0Sstevel@tonic-gate 	char *p, *q;
129*0Sstevel@tonic-gate 
130*0Sstevel@tonic-gate 	/* Save map path for future reference */
131*0Sstevel@tonic-gate 	map->map_path = (char *)strdup(name);
132*0Sstevel@tonic-gate 	if (NULL ==  map->map_path) {
133*0Sstevel@tonic-gate 		logmsg(MSG_NOMEM, LOG_ERR,
134*0Sstevel@tonic-gate 				"Could not duplicate map path %s", map);
135*0Sstevel@tonic-gate 		return (FAILURE);
136*0Sstevel@tonic-gate 	}
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate 	/* Work out map's unqualified name from path */
139*0Sstevel@tonic-gate 	p = strrchr(name, SEP_CHAR);
140*0Sstevel@tonic-gate 	if (NULL == p) {
141*0Sstevel@tonic-gate 		/* Must be at least a domain and name */
142*0Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR,
143*0Sstevel@tonic-gate 			"Could not find separator in map path %s", map);
144*0Sstevel@tonic-gate 		return (FAILURE);
145*0Sstevel@tonic-gate 	}
146*0Sstevel@tonic-gate 	q = p + 1;
147*0Sstevel@tonic-gate 
148*0Sstevel@tonic-gate 	/* Check for and remove N2L prefix */
149*0Sstevel@tonic-gate 	if (yptol_mode) {
150*0Sstevel@tonic-gate 		/*
151*0Sstevel@tonic-gate 		 * Check for and remove N2L prefix. If not found not a problem
152*0Sstevel@tonic-gate 		 * we open some old style maps during DIT initialization.
153*0Sstevel@tonic-gate 		 */
154*0Sstevel@tonic-gate 		if (0 == strncmp(q, NTOL_PREFIX, strlen(NTOL_PREFIX)))
155*0Sstevel@tonic-gate 			q += strlen(NTOL_PREFIX);
156*0Sstevel@tonic-gate 	} else {
157*0Sstevel@tonic-gate 		if (0 == strncmp(q, NTOL_PREFIX, strlen(NTOL_PREFIX)))
158*0Sstevel@tonic-gate 			logmsg(MSG_NOTIMECHECK, LOG_ERR,
159*0Sstevel@tonic-gate 				"Working in non N2L mode and path %s "
160*0Sstevel@tonic-gate 				"contains N2L prefix", name);
161*0Sstevel@tonic-gate 	}
162*0Sstevel@tonic-gate 
163*0Sstevel@tonic-gate 	/* Save unqualified map name */
164*0Sstevel@tonic-gate 	map->map_name = strdup(q);
165*0Sstevel@tonic-gate 	if (NULL == map->map_name) {
166*0Sstevel@tonic-gate 		logmsg(MSG_NOMEM, LOG_ERR,
167*0Sstevel@tonic-gate 				"Could not duplicate map name %s", q);
168*0Sstevel@tonic-gate 		return (FAILURE);
169*0Sstevel@tonic-gate 	}
170*0Sstevel@tonic-gate 
171*0Sstevel@tonic-gate 	/* Work out map's domain name from path */
172*0Sstevel@tonic-gate 	for (q = p-1; (SEP_CHAR != *q) && (q > name); q--);
173*0Sstevel@tonic-gate 
174*0Sstevel@tonic-gate 	if (q <= name) {
175*0Sstevel@tonic-gate 		/* Didn't find separator */
176*0Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR,
177*0Sstevel@tonic-gate 				"Could not find domain in map path %s", name);
178*0Sstevel@tonic-gate 		return (FAILURE);
179*0Sstevel@tonic-gate 	}
180*0Sstevel@tonic-gate 
181*0Sstevel@tonic-gate 	map->domain = (char *)am(myself, p - q);
182*0Sstevel@tonic-gate 	if (NULL == map->domain) {
183*0Sstevel@tonic-gate 		logmsg(MSG_NOMEM, LOG_ERR,
184*0Sstevel@tonic-gate 			"Could not alloc memory for domain in path %s", name);
185*0Sstevel@tonic-gate 		return (FAILURE);
186*0Sstevel@tonic-gate 	}
187*0Sstevel@tonic-gate 	strncpy(map->domain, q + 1, p-q-1);
188*0Sstevel@tonic-gate 	map->domain[p-q-1] = '\0';
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate 	/* Work out extra names required by N2L */
191*0Sstevel@tonic-gate 	if (yptol_mode) {
192*0Sstevel@tonic-gate 		/*
193*0Sstevel@tonic-gate 		 * Work out what old style NIS path would have been. This is
194*0Sstevel@tonic-gate 		 * used to check for date of DBM file so add the DBM
195*0Sstevel@tonic-gate 		 * extension.
196*0Sstevel@tonic-gate 		 */
197*0Sstevel@tonic-gate 		map->trad_map_path = (char *)am(myself, strlen(map->map_name) +
198*0Sstevel@tonic-gate 					+ strlen(dbm_pag) + (p - name) + 2);
199*0Sstevel@tonic-gate 		if (NULL == map->trad_map_path) {
200*0Sstevel@tonic-gate 			logmsg(MSG_NOMEM, LOG_ERR,
201*0Sstevel@tonic-gate 				"Could not alocate memory for "
202*0Sstevel@tonic-gate 				"traditional map path derived from %s", name);
203*0Sstevel@tonic-gate 			return (FAILURE);
204*0Sstevel@tonic-gate 		}
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate 		strncpy(map->trad_map_path, name, p - name + 1);
207*0Sstevel@tonic-gate 		map->trad_map_path[p - name + 1] = '\0';
208*0Sstevel@tonic-gate 		strcat(map->trad_map_path, map->map_name);
209*0Sstevel@tonic-gate 		strcat(map->trad_map_path, dbm_pag);
210*0Sstevel@tonic-gate 
211*0Sstevel@tonic-gate 		/* Generate qualified TTL file name */
212*0Sstevel@tonic-gate 		map->ttl_path = (char *)am(myself, strlen(map->map_path) +
213*0Sstevel@tonic-gate 						strlen(TTL_POSTFIX) + 1);
214*0Sstevel@tonic-gate 		if (NULL == map->ttl_path) {
215*0Sstevel@tonic-gate 			logmsg(MSG_NOMEM, LOG_ERR,
216*0Sstevel@tonic-gate 				"Could not alocate memory for "
217*0Sstevel@tonic-gate 				"ttl path derived from %s", name);
218*0Sstevel@tonic-gate 			return (FAILURE);
219*0Sstevel@tonic-gate 		}
220*0Sstevel@tonic-gate 
221*0Sstevel@tonic-gate 		strcpy(map->ttl_path, map->map_path);
222*0Sstevel@tonic-gate 		strcat(map->ttl_path, TTL_POSTFIX);
223*0Sstevel@tonic-gate 	}
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate 	/* Work out hash value */
226*0Sstevel@tonic-gate 	map->hash_val = hash(name);
227*0Sstevel@tonic-gate 
228*0Sstevel@tonic-gate 	/* Set up magic number */
229*0Sstevel@tonic-gate 	map->magic = MAP_MAGIC;
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate 	/* Null out pointers */
232*0Sstevel@tonic-gate 	map->entries = NULL;
233*0Sstevel@tonic-gate 	map->ttl = NULL;
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate 	/* No key data yet */
236*0Sstevel@tonic-gate 	map->key_data.dptr = NULL;
237*0Sstevel@tonic-gate 	map->key_data.dsize = 0;
238*0Sstevel@tonic-gate 
239*0Sstevel@tonic-gate 	return (SUCCESS);
240*0Sstevel@tonic-gate }
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate /*
243*0Sstevel@tonic-gate  * FUNCTION: 	get_map_crtl();
244*0Sstevel@tonic-gate  *
245*0Sstevel@tonic-gate  * DESCRIPTION: Find an existing map_ctrl for a map of a given DBM * (i.e.
246*0Sstevel@tonic-gate  *		handle) . If none exists return an error.
247*0Sstevel@tonic-gate  *
248*0Sstevel@tonic-gate  * INPUTS:	Map handle
249*0Sstevel@tonic-gate  *
250*0Sstevel@tonic-gate  * OUTPUTS:	Pointer to map_ctrl
251*0Sstevel@tonic-gate  *		NULL on failure.
252*0Sstevel@tonic-gate  *
253*0Sstevel@tonic-gate  */
254*0Sstevel@tonic-gate map_ctrl *
255*0Sstevel@tonic-gate get_map_ctrl(DBM *db)
256*0Sstevel@tonic-gate {
257*0Sstevel@tonic-gate 	/* Check that this really is a map_ctrl not a DBM */
258*0Sstevel@tonic-gate 	if (((map_ctrl *)db)->magic != MAP_MAGIC) {
259*0Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_ERR,
260*0Sstevel@tonic-gate 				"SHIM called with DBM ptr not map_crtl ptr");
261*0Sstevel@tonic-gate 		return (NULL);
262*0Sstevel@tonic-gate 	}
263*0Sstevel@tonic-gate 
264*0Sstevel@tonic-gate 	/* Since this is an opaque pointer just cast it */
265*0Sstevel@tonic-gate 	return ((map_ctrl *)db);
266*0Sstevel@tonic-gate }
267*0Sstevel@tonic-gate 
268*0Sstevel@tonic-gate /*
269*0Sstevel@tonic-gate  * FUNCTION:	dup_map_ctrl()
270*0Sstevel@tonic-gate  *
271*0Sstevel@tonic-gate  * DESCRIPTION:	Duplicates a map_ctrl structure
272*0Sstevel@tonic-gate  *
273*0Sstevel@tonic-gate  * GIVEN :	Map_ctrl to duplicate
274*0Sstevel@tonic-gate  *
275*0Sstevel@tonic-gate  * RETURNS :	Pointer to a new malloced map_ctrl. CALLER MUST FREE
276*0Sstevel@tonic-gate  *		NULL on failure.
277*0Sstevel@tonic-gate  */
278*0Sstevel@tonic-gate map_ctrl *
279*0Sstevel@tonic-gate dup_map_ctrl(map_ctrl *old_map)
280*0Sstevel@tonic-gate {
281*0Sstevel@tonic-gate 	map_ctrl *new_map;
282*0Sstevel@tonic-gate 
283*0Sstevel@tonic-gate 	/*
284*0Sstevel@tonic-gate 	 * Could save a little bit of time by duplicating the static parts
285*0Sstevel@tonic-gate 	 * of the old map but on balance it is cleaner to just make a new one
286*0Sstevel@tonic-gate 	 * from scratch
287*0Sstevel@tonic-gate 	 */
288*0Sstevel@tonic-gate 	new_map = create_map_ctrl(old_map->map_path);
289*0Sstevel@tonic-gate 
290*0Sstevel@tonic-gate 	if (NULL == new_map)
291*0Sstevel@tonic-gate 		return (NULL);
292*0Sstevel@tonic-gate 
293*0Sstevel@tonic-gate 	/* If old map had open handles duplicate them */
294*0Sstevel@tonic-gate 	if (NULL != old_map->entries) {
295*0Sstevel@tonic-gate 		new_map->open_flags = old_map->open_flags;
296*0Sstevel@tonic-gate 		new_map->open_mode = old_map->open_mode;
297*0Sstevel@tonic-gate 		if (FAILURE == open_yptol_files(new_map)) {
298*0Sstevel@tonic-gate 			free_map_ctrl(new_map);
299*0Sstevel@tonic-gate 			return (NULL);
300*0Sstevel@tonic-gate 		}
301*0Sstevel@tonic-gate 	}
302*0Sstevel@tonic-gate 
303*0Sstevel@tonic-gate 	return (new_map);
304*0Sstevel@tonic-gate }
305*0Sstevel@tonic-gate 
306*0Sstevel@tonic-gate /*
307*0Sstevel@tonic-gate  * FUNCTION: 	free_map_crtl();
308*0Sstevel@tonic-gate  *
309*0Sstevel@tonic-gate  * DESCRIPTION: Free contents of a map_ctr structure and closed any open
310*0Sstevel@tonic-gate  *		DBM files.
311*0Sstevel@tonic-gate  *
312*0Sstevel@tonic-gate  * INPUTS:	Pointer to pointer to a map_ctrl.
313*0Sstevel@tonic-gate  *
314*0Sstevel@tonic-gate  * OUTPUTS:	Nothing
315*0Sstevel@tonic-gate  *
316*0Sstevel@tonic-gate  */
317*0Sstevel@tonic-gate void
318*0Sstevel@tonic-gate free_map_ctrl(map_ctrl *map)
319*0Sstevel@tonic-gate {
320*0Sstevel@tonic-gate 
321*0Sstevel@tonic-gate 	if (NULL != map->entries) {
322*0Sstevel@tonic-gate 		dbm_close(map->entries);
323*0Sstevel@tonic-gate 		map->entries = NULL;
324*0Sstevel@tonic-gate 	}
325*0Sstevel@tonic-gate 
326*0Sstevel@tonic-gate 	if (NULL != map->map_name) {
327*0Sstevel@tonic-gate 		sfree(map->map_name);
328*0Sstevel@tonic-gate 		map->map_name = NULL;
329*0Sstevel@tonic-gate 	}
330*0Sstevel@tonic-gate 
331*0Sstevel@tonic-gate 	if (NULL != map->map_path) {
332*0Sstevel@tonic-gate 		sfree(map->map_path);
333*0Sstevel@tonic-gate 		map->map_path = NULL;
334*0Sstevel@tonic-gate 	}
335*0Sstevel@tonic-gate 
336*0Sstevel@tonic-gate 	if (NULL != map->domain) {
337*0Sstevel@tonic-gate 		sfree(map->domain);
338*0Sstevel@tonic-gate 		map->domain = NULL;
339*0Sstevel@tonic-gate 	}
340*0Sstevel@tonic-gate 
341*0Sstevel@tonic-gate 	if (yptol_mode) {
342*0Sstevel@tonic-gate 		if (NULL != map->ttl) {
343*0Sstevel@tonic-gate 			dbm_close(map->ttl);
344*0Sstevel@tonic-gate 			map->ttl = NULL;
345*0Sstevel@tonic-gate 		}
346*0Sstevel@tonic-gate 
347*0Sstevel@tonic-gate 		if (NULL != map->trad_map_path) {
348*0Sstevel@tonic-gate 			sfree(map->trad_map_path);
349*0Sstevel@tonic-gate 			map->trad_map_path = NULL;
350*0Sstevel@tonic-gate 		}
351*0Sstevel@tonic-gate 
352*0Sstevel@tonic-gate 		if (NULL != map->ttl_path) {
353*0Sstevel@tonic-gate 			sfree(map->ttl_path);
354*0Sstevel@tonic-gate 			map->ttl_path = NULL;
355*0Sstevel@tonic-gate 		}
356*0Sstevel@tonic-gate 
357*0Sstevel@tonic-gate 		if (NULL != map->key_data.dptr) {
358*0Sstevel@tonic-gate 			sfree(map->key_data.dptr);
359*0Sstevel@tonic-gate 			map->key_data.dptr = NULL;
360*0Sstevel@tonic-gate 			map->key_data.dsize = 0;
361*0Sstevel@tonic-gate 		}
362*0Sstevel@tonic-gate 	}
363*0Sstevel@tonic-gate 
364*0Sstevel@tonic-gate 	map->magic = 0;
365*0Sstevel@tonic-gate 
366*0Sstevel@tonic-gate 	/* Since map_ctrls are now always in malloced memory */
367*0Sstevel@tonic-gate 	sfree(map);
368*0Sstevel@tonic-gate 
369*0Sstevel@tonic-gate }
370*0Sstevel@tonic-gate 
371*0Sstevel@tonic-gate /*
372*0Sstevel@tonic-gate  * FUNCTION :	get_map_name()
373*0Sstevel@tonic-gate  *
374*0Sstevel@tonic-gate  * DESCRIPTION:	Get the name of a map from its map_ctrl. This could be done
375*0Sstevel@tonic-gate  *		as a simple dereference but this function hides the internal
376*0Sstevel@tonic-gate  *		implementation of map_ctrl from higher layers.
377*0Sstevel@tonic-gate  *
378*0Sstevel@tonic-gate  * GIVEN :	A map_ctrl pointer
379*0Sstevel@tonic-gate  *
380*0Sstevel@tonic-gate  * RETURNS :	A pointer to the map_ctrl. Higher levels treat this as an
381*0Sstevel@tonic-gate  *		opaque DBM pointer.
382*0Sstevel@tonic-gate  *		NULL on failure.
383*0Sstevel@tonic-gate  */
384*0Sstevel@tonic-gate char *
385*0Sstevel@tonic-gate get_map_name(DBM *db)
386*0Sstevel@tonic-gate {
387*0Sstevel@tonic-gate 	map_ctrl *map = (map_ctrl *)db;
388*0Sstevel@tonic-gate 
389*0Sstevel@tonic-gate 	if (NULL == map)
390*0Sstevel@tonic-gate 		return (NULL);
391*0Sstevel@tonic-gate 
392*0Sstevel@tonic-gate 	return (map->map_name);
393*0Sstevel@tonic-gate }
394*0Sstevel@tonic-gate 
395*0Sstevel@tonic-gate /*
396*0Sstevel@tonic-gate  * FUNCTION :	set_key_data()
397*0Sstevel@tonic-gate  *
398*0Sstevel@tonic-gate  * DESCRIPTION:	Sets up the key data freeing any that already exists.
399*0Sstevel@tonic-gate  *
400*0Sstevel@tonic-gate  * GIVEN :	Pointer to the map_ctrl to set up.
401*0Sstevel@tonic-gate  *		Datum containing the key. The dptr of this will be set to
402*0Sstevel@tonic-gate  *		point to the key data.
403*0Sstevel@tonic-gate  *
404*0Sstevel@tonic-gate  * RETURNS :	Nothing
405*0Sstevel@tonic-gate  */
406*0Sstevel@tonic-gate void
407*0Sstevel@tonic-gate set_key_data(map_ctrl *map, datum *data)
408*0Sstevel@tonic-gate {
409*0Sstevel@tonic-gate 	char *myself = "set_key_data";
410*0Sstevel@tonic-gate 
411*0Sstevel@tonic-gate 	/*
412*0Sstevel@tonic-gate 	 * Free up any existing key data. Because each dbm file can only have
413*0Sstevel@tonic-gate 	 * one enumeration going at a time this is safe.
414*0Sstevel@tonic-gate 	 */
415*0Sstevel@tonic-gate 	if (NULL != map->key_data.dptr) {
416*0Sstevel@tonic-gate 		sfree(map->key_data.dptr);
417*0Sstevel@tonic-gate 		map->key_data.dptr = NULL;
418*0Sstevel@tonic-gate 		map->key_data.dsize = 0;
419*0Sstevel@tonic-gate 	}
420*0Sstevel@tonic-gate 
421*0Sstevel@tonic-gate 	/* If nothing in key just return */
422*0Sstevel@tonic-gate 	if (NULL == data->dptr)
423*0Sstevel@tonic-gate 		return;
424*0Sstevel@tonic-gate 
425*0Sstevel@tonic-gate 	/* Something is in the key so must duplicate out of static memory */
426*0Sstevel@tonic-gate 	map->key_data.dptr = (char *)am(myself, data->dsize);
427*0Sstevel@tonic-gate 	if (NULL == map->key_data.dptr) {
428*0Sstevel@tonic-gate 		logmsg(MSG_NOMEM, LOG_ERR, "Cannot alloc memory for key data");
429*0Sstevel@tonic-gate 	} else {
430*0Sstevel@tonic-gate 		memcpy(map->key_data.dptr, data->dptr, data->dsize);
431*0Sstevel@tonic-gate 		map->key_data.dsize = data->dsize;
432*0Sstevel@tonic-gate 	}
433*0Sstevel@tonic-gate 
434*0Sstevel@tonic-gate 	/* Set datum to point to malloced version of the data */
435*0Sstevel@tonic-gate 	data->dptr = map->key_data.dptr;
436*0Sstevel@tonic-gate 
437*0Sstevel@tonic-gate 	return;
438*0Sstevel@tonic-gate 
439*0Sstevel@tonic-gate }
440*0Sstevel@tonic-gate 
441*0Sstevel@tonic-gate /*
442*0Sstevel@tonic-gate  * FUNCTION :	open_yptol_files()
443*0Sstevel@tonic-gate  *
444*0Sstevel@tonic-gate  * DESCRIPTION:	Opens both yptol files for a map. This is called both when a
445*0Sstevel@tonic-gate  *		map is opened and when it is reopened as a result of an update
446*0Sstevel@tonic-gate  *		operation. Must be called with map locked.
447*0Sstevel@tonic-gate  *
448*0Sstevel@tonic-gate  * GIVEN :	Initialized map_ctrl
449*0Sstevel@tonic-gate  *
450*0Sstevel@tonic-gate  * RETURNS :	SUCCESS = Maps opened
451*0Sstevel@tonic-gate  *		FAILURE = Maps not opened (and mess tidied up)
452*0Sstevel@tonic-gate  */
453*0Sstevel@tonic-gate suc_code
454*0Sstevel@tonic-gate open_yptol_files(map_ctrl *map)
455*0Sstevel@tonic-gate {
456*0Sstevel@tonic-gate 
457*0Sstevel@tonic-gate 	/* Open entries map */
458*0Sstevel@tonic-gate 	map->entries = dbm_open(map->map_path, map->open_flags, map->open_mode);
459*0Sstevel@tonic-gate 
460*0Sstevel@tonic-gate 	if (NULL == map->entries) {
461*0Sstevel@tonic-gate 		/* Maybe we were asked to open a non-existent map. No problem */
462*0Sstevel@tonic-gate 		return (FAILURE);
463*0Sstevel@tonic-gate 	}
464*0Sstevel@tonic-gate 
465*0Sstevel@tonic-gate 	if (yptol_mode) {
466*0Sstevel@tonic-gate 		/* Open TTLs map. Must always be writable */
467*0Sstevel@tonic-gate 		map->ttl = dbm_open(map->ttl_path, O_RDWR | O_CREAT, 0644);
468*0Sstevel@tonic-gate 		if (NULL == map->ttl) {
469*0Sstevel@tonic-gate 			logmsg(MSG_NOTIMECHECK, LOG_ERR,
470*0Sstevel@tonic-gate 				"Cannot open TTL file %s", map->ttl_path);
471*0Sstevel@tonic-gate 			dbm_close(map->entries);
472*0Sstevel@tonic-gate 			map->entries = NULL;
473*0Sstevel@tonic-gate 			return (FAILURE);
474*0Sstevel@tonic-gate 		}
475*0Sstevel@tonic-gate 	}
476*0Sstevel@tonic-gate 
477*0Sstevel@tonic-gate 	return (SUCCESS);
478*0Sstevel@tonic-gate }
479