Home | History | Annotate | Line # | Download | only in common
      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 (at) 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 
     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 
     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 
    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