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 36struct group *root_group; 37group_hash_t *group_name_hash; 38int (*group_write_hook) (struct group_object *); 39 40isc_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 79isc_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 135int 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