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