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