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