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