xref: /minix3/external/bsd/dhcp/dist/common/memory.c (revision 83ee113ee0d94f3844d44065af2311604e9a30ad)
1*83ee113eSDavid van Moolenbroek /*	$NetBSD: memory.c,v 1.1.1.2 2014/07/12 11:57:44 spz Exp $	*/
2*83ee113eSDavid van Moolenbroek /* memory.c
3*83ee113eSDavid van Moolenbroek 
4*83ee113eSDavid van Moolenbroek    Memory-resident database... */
5*83ee113eSDavid van Moolenbroek 
6*83ee113eSDavid van Moolenbroek /*
7*83ee113eSDavid van Moolenbroek  * Copyright (c) 2004,2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC")
8*83ee113eSDavid van Moolenbroek  * Copyright (c) 1995-2003 by Internet Software Consortium
9*83ee113eSDavid van Moolenbroek  *
10*83ee113eSDavid van Moolenbroek  * Permission to use, copy, modify, and distribute this software for any
11*83ee113eSDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
12*83ee113eSDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
13*83ee113eSDavid van Moolenbroek  *
14*83ee113eSDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15*83ee113eSDavid van Moolenbroek  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16*83ee113eSDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
17*83ee113eSDavid van Moolenbroek  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18*83ee113eSDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19*83ee113eSDavid van Moolenbroek  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20*83ee113eSDavid van Moolenbroek  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21*83ee113eSDavid van Moolenbroek  *
22*83ee113eSDavid van Moolenbroek  *   Internet Systems Consortium, Inc.
23*83ee113eSDavid van Moolenbroek  *   950 Charter Street
24*83ee113eSDavid van Moolenbroek  *   Redwood City, CA 94063
25*83ee113eSDavid van Moolenbroek  *   <info@isc.org>
26*83ee113eSDavid van Moolenbroek  *   https://www.isc.org/
27*83ee113eSDavid van Moolenbroek  *
28*83ee113eSDavid van Moolenbroek  */
29*83ee113eSDavid van Moolenbroek 
30*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
31*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: memory.c,v 1.1.1.2 2014/07/12 11:57:44 spz Exp $");
32*83ee113eSDavid van Moolenbroek 
33*83ee113eSDavid van Moolenbroek #include "dhcpd.h"
34*83ee113eSDavid van Moolenbroek 
35*83ee113eSDavid van Moolenbroek struct group *root_group;
36*83ee113eSDavid van Moolenbroek group_hash_t *group_name_hash;
37*83ee113eSDavid van Moolenbroek int (*group_write_hook) (struct group_object *);
38*83ee113eSDavid van Moolenbroek 
delete_group(struct group_object * group,int writep)39*83ee113eSDavid van Moolenbroek isc_result_t delete_group (struct group_object *group, int writep)
40*83ee113eSDavid van Moolenbroek {
41*83ee113eSDavid van Moolenbroek 	struct group_object *d;
42*83ee113eSDavid van Moolenbroek 
43*83ee113eSDavid van Moolenbroek 	/* The group should exist and be hashed - if not, it's invalid. */
44*83ee113eSDavid van Moolenbroek 	if (group_name_hash) {
45*83ee113eSDavid van Moolenbroek 		d = (struct group_object *)0;
46*83ee113eSDavid van Moolenbroek 		group_hash_lookup (&d, group_name_hash, group -> name,
47*83ee113eSDavid van Moolenbroek 				   strlen (group -> name), MDL);
48*83ee113eSDavid van Moolenbroek 	} else
49*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
50*83ee113eSDavid van Moolenbroek 	if (!d)
51*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
52*83ee113eSDavid van Moolenbroek 
53*83ee113eSDavid van Moolenbroek 	/* Also not okay to delete a group that's not the one in
54*83ee113eSDavid van Moolenbroek 	   the hash table. */
55*83ee113eSDavid van Moolenbroek 	if (d != group)
56*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
57*83ee113eSDavid van Moolenbroek 
58*83ee113eSDavid van Moolenbroek 	/* If it's dynamic, and we're deleting it, we can just blow away the
59*83ee113eSDavid van Moolenbroek 	   hash table entry. */
60*83ee113eSDavid van Moolenbroek 	if ((group -> flags & GROUP_OBJECT_DYNAMIC) &&
61*83ee113eSDavid van Moolenbroek 	    !(group -> flags & GROUP_OBJECT_STATIC)) {
62*83ee113eSDavid van Moolenbroek 		group_hash_delete (group_name_hash,
63*83ee113eSDavid van Moolenbroek 				   group -> name, strlen (group -> name), MDL);
64*83ee113eSDavid van Moolenbroek 	} else {
65*83ee113eSDavid van Moolenbroek 		group -> flags |= GROUP_OBJECT_DELETED;
66*83ee113eSDavid van Moolenbroek 		if (group -> group)
67*83ee113eSDavid van Moolenbroek 			group_dereference (&group -> group, MDL);
68*83ee113eSDavid van Moolenbroek 	}
69*83ee113eSDavid van Moolenbroek 
70*83ee113eSDavid van Moolenbroek 	/* Store the group declaration in the lease file. */
71*83ee113eSDavid van Moolenbroek 	if (writep && group_write_hook) {
72*83ee113eSDavid van Moolenbroek 		if (!(*group_write_hook) (group))
73*83ee113eSDavid van Moolenbroek 			return ISC_R_IOERROR;
74*83ee113eSDavid van Moolenbroek 	}
75*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
76*83ee113eSDavid van Moolenbroek }
77*83ee113eSDavid van Moolenbroek 
supersede_group(struct group_object * group,int writep)78*83ee113eSDavid van Moolenbroek isc_result_t supersede_group (struct group_object *group, int writep)
79*83ee113eSDavid van Moolenbroek {
80*83ee113eSDavid van Moolenbroek 	struct group_object *t;
81*83ee113eSDavid van Moolenbroek 
82*83ee113eSDavid van Moolenbroek 	/* Register the group in the group name hash table,
83*83ee113eSDavid van Moolenbroek 	   so we can look it up later. */
84*83ee113eSDavid van Moolenbroek 	if (group_name_hash) {
85*83ee113eSDavid van Moolenbroek 		t = (struct group_object *)0;
86*83ee113eSDavid van Moolenbroek 		group_hash_lookup (&t, group_name_hash,
87*83ee113eSDavid van Moolenbroek 			group -> name,
88*83ee113eSDavid van Moolenbroek 			     strlen (group -> name), MDL);
89*83ee113eSDavid van Moolenbroek 		if (t && t != group) {
90*83ee113eSDavid van Moolenbroek 			/* If this isn't a dynamic entry, then we need to flag
91*83ee113eSDavid van Moolenbroek 			   the replacement as not dynamic either - otherwise,
92*83ee113eSDavid van Moolenbroek 			   if the dynamic entry is deleted later, the static
93*83ee113eSDavid van Moolenbroek 			   entry will come back next time the server is stopped
94*83ee113eSDavid van Moolenbroek 			   and restarted. */
95*83ee113eSDavid van Moolenbroek 			if (!(t -> flags & GROUP_OBJECT_DYNAMIC))
96*83ee113eSDavid van Moolenbroek 				group -> flags |= GROUP_OBJECT_STATIC;
97*83ee113eSDavid van Moolenbroek 
98*83ee113eSDavid van Moolenbroek 			/* Delete the old object if it hasn't already been
99*83ee113eSDavid van Moolenbroek 			   deleted.  If it has already been deleted, get rid of
100*83ee113eSDavid van Moolenbroek 			   the hash table entry.  This is a legitimate
101*83ee113eSDavid van Moolenbroek 			   situation - a deleted static object needs to be kept
102*83ee113eSDavid van Moolenbroek 			   around so we remember it's deleted. */
103*83ee113eSDavid van Moolenbroek 			if (!(t -> flags & GROUP_OBJECT_DELETED))
104*83ee113eSDavid van Moolenbroek 				delete_group (t, 0);
105*83ee113eSDavid van Moolenbroek 			else {
106*83ee113eSDavid van Moolenbroek 				group_hash_delete (group_name_hash,
107*83ee113eSDavid van Moolenbroek 						   group -> name,
108*83ee113eSDavid van Moolenbroek 						   strlen (group -> name),
109*83ee113eSDavid van Moolenbroek 						   MDL);
110*83ee113eSDavid van Moolenbroek 				group_object_dereference (&t, MDL);
111*83ee113eSDavid van Moolenbroek 			}
112*83ee113eSDavid van Moolenbroek 		}
113*83ee113eSDavid van Moolenbroek 	} else {
114*83ee113eSDavid van Moolenbroek 		group_new_hash(&group_name_hash, GROUP_HASH_SIZE, MDL);
115*83ee113eSDavid van Moolenbroek 		t = (struct group_object *)0;
116*83ee113eSDavid van Moolenbroek 	}
117*83ee113eSDavid van Moolenbroek 
118*83ee113eSDavid van Moolenbroek 	/* Add the group to the group name hash if it's not
119*83ee113eSDavid van Moolenbroek 	   already there, and also thread it into the list of
120*83ee113eSDavid van Moolenbroek 	   dynamic groups if appropriate. */
121*83ee113eSDavid van Moolenbroek 	if (!t) {
122*83ee113eSDavid van Moolenbroek 		group_hash_add (group_name_hash, group -> name,
123*83ee113eSDavid van Moolenbroek 				strlen (group -> name), group, MDL);
124*83ee113eSDavid van Moolenbroek 	}
125*83ee113eSDavid van Moolenbroek 
126*83ee113eSDavid van Moolenbroek 	/* Store the group declaration in the lease file. */
127*83ee113eSDavid van Moolenbroek 	if (writep && group_write_hook) {
128*83ee113eSDavid van Moolenbroek 		if (!(*group_write_hook) (group))
129*83ee113eSDavid van Moolenbroek 			return ISC_R_IOERROR;
130*83ee113eSDavid van Moolenbroek 	}
131*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
132*83ee113eSDavid van Moolenbroek }
133*83ee113eSDavid van Moolenbroek 
clone_group(struct group ** gp,struct group * group,const char * file,int line)134*83ee113eSDavid van Moolenbroek int clone_group (struct group **gp, struct group *group,
135*83ee113eSDavid van Moolenbroek 		 const char *file, int line)
136*83ee113eSDavid van Moolenbroek {
137*83ee113eSDavid van Moolenbroek 	struct group *g = (struct group *)0;
138*83ee113eSDavid van Moolenbroek 
139*83ee113eSDavid van Moolenbroek 	/* Normally gp should contain the null pointer, but for convenience
140*83ee113eSDavid van Moolenbroek 	   it's permissible to clone a group into itself. */
141*83ee113eSDavid van Moolenbroek 	if (*gp && *gp != group)
142*83ee113eSDavid van Moolenbroek 		return 0;
143*83ee113eSDavid van Moolenbroek 	if (!group_allocate (&g, file, line))
144*83ee113eSDavid van Moolenbroek 		return 0;
145*83ee113eSDavid van Moolenbroek 	if (group == *gp)
146*83ee113eSDavid van Moolenbroek 		*gp = (struct group *)0;
147*83ee113eSDavid van Moolenbroek 	group_reference (gp, g, file, line);
148*83ee113eSDavid van Moolenbroek 	g -> authoritative = group -> authoritative;
149*83ee113eSDavid van Moolenbroek 	group_reference (&g -> next, group, file, line);
150*83ee113eSDavid van Moolenbroek 	group_dereference (&g, file, line);
151*83ee113eSDavid van Moolenbroek 	return 1;
152*83ee113eSDavid van Moolenbroek }
153