common/memory.c

Go to the documentation of this file.
00001 /* memory.c
00002 
00003    Memory-resident database... */
00004 
00005 /*
00006  * Copyright (c) 2004,2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC")
00007  * Copyright (c) 1995-2003 by Internet Software Consortium
00008  *
00009  * Permission to use, copy, modify, and distribute this software for any
00010  * purpose with or without fee is hereby granted, provided that the above
00011  * copyright notice and this permission notice appear in all copies.
00012  *
00013  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
00014  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00015  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
00016  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00017  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00018  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
00019  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00020  *
00021  *   Internet Systems Consortium, Inc.
00022  *   950 Charter Street
00023  *   Redwood City, CA 94063
00024  *   <info@isc.org>
00025  *   https://www.isc.org/
00026  *
00027  */
00028 
00029 #include "dhcpd.h"
00030 
00031 struct group *root_group;
00032 group_hash_t *group_name_hash;
00033 int (*group_write_hook) (struct group_object *);
00034 
00035 isc_result_t delete_group (struct group_object *group, int writep)
00036 {
00037         struct group_object *d;
00038 
00039         /* The group should exist and be hashed - if not, it's invalid. */
00040         if (group_name_hash) {
00041                 d = (struct group_object *)0;
00042                 group_hash_lookup (&d, group_name_hash, group -> name,
00043                                    strlen (group -> name), MDL);
00044         } else
00045                 return DHCP_R_INVALIDARG;
00046         if (!d)
00047                 return DHCP_R_INVALIDARG;
00048 
00049         /* Also not okay to delete a group that's not the one in
00050            the hash table. */
00051         if (d != group)
00052                 return DHCP_R_INVALIDARG;
00053 
00054         /* If it's dynamic, and we're deleting it, we can just blow away the
00055            hash table entry. */
00056         if ((group -> flags & GROUP_OBJECT_DYNAMIC) &&
00057             !(group -> flags & GROUP_OBJECT_STATIC)) {
00058                 group_hash_delete (group_name_hash,
00059                                    group -> name, strlen (group -> name), MDL);
00060         } else {
00061                 group -> flags |= GROUP_OBJECT_DELETED;
00062                 if (group -> group)
00063                         group_dereference (&group -> group, MDL);
00064         }
00065 
00066         /* Store the group declaration in the lease file. */
00067         if (writep && group_write_hook) {
00068                 if (!(*group_write_hook) (group))
00069                         return ISC_R_IOERROR;
00070         }
00071         return ISC_R_SUCCESS;
00072 }
00073 
00074 isc_result_t supersede_group (struct group_object *group, int writep)
00075 {
00076         struct group_object *t;
00077 
00078         /* Register the group in the group name hash table,
00079            so we can look it up later. */
00080         if (group_name_hash) {
00081                 t = (struct group_object *)0;
00082                 group_hash_lookup (&t, group_name_hash,
00083                         group -> name,
00084                              strlen (group -> name), MDL);
00085                 if (t && t != group) {
00086                         /* If this isn't a dynamic entry, then we need to flag
00087                            the replacement as not dynamic either - otherwise,
00088                            if the dynamic entry is deleted later, the static
00089                            entry will come back next time the server is stopped
00090                            and restarted. */
00091                         if (!(t -> flags & GROUP_OBJECT_DYNAMIC))
00092                                 group -> flags |= GROUP_OBJECT_STATIC;
00093 
00094                         /* Delete the old object if it hasn't already been
00095                            deleted.  If it has already been deleted, get rid of
00096                            the hash table entry.  This is a legitimate
00097                            situation - a deleted static object needs to be kept
00098                            around so we remember it's deleted. */
00099                         if (!(t -> flags & GROUP_OBJECT_DELETED))
00100                                 delete_group (t, 0);
00101                         else {
00102                                 group_hash_delete (group_name_hash,
00103                                                    group -> name,
00104                                                    strlen (group -> name),
00105                                                    MDL);
00106                                 group_object_dereference (&t, MDL);
00107                         }
00108                 }
00109         } else {
00110                 group_new_hash(&group_name_hash, GROUP_HASH_SIZE, MDL);
00111                 t = (struct group_object *)0;
00112         }
00113 
00114         /* Add the group to the group name hash if it's not
00115            already there, and also thread it into the list of
00116            dynamic groups if appropriate. */
00117         if (!t) {
00118                 group_hash_add (group_name_hash, group -> name,
00119                                 strlen (group -> name), group, MDL);
00120         }
00121 
00122         /* Store the group declaration in the lease file. */
00123         if (writep && group_write_hook) {
00124                 if (!(*group_write_hook) (group))
00125                         return ISC_R_IOERROR;
00126         }
00127         return ISC_R_SUCCESS;
00128 }
00129 
00130 int clone_group (struct group **gp, struct group *group,
00131                  const char *file, int line)
00132 {
00133         struct group *g = (struct group *)0;
00134 
00135         /* Normally gp should contain the null pointer, but for convenience
00136            it's permissible to clone a group into itself. */
00137         if (*gp && *gp != group)
00138                 return 0;
00139         if (!group_allocate (&g, file, line))
00140                 return 0;
00141         if (group == *gp)
00142                 *gp = (struct group *)0;
00143         group_reference (gp, g, file, line);
00144         g -> authoritative = group -> authoritative;
00145         group_reference (&g -> next, group, file, line);
00146         group_dereference (&g, file, line);
00147         return 1;
00148 }

Generated on 5 Apr 2014 for ISC DHCP by  doxygen 1.6.1