Home | History | Annotate | Line # | Download | only in common
comapi.c revision 1.1
      1  1.1  christos /*	$NetBSD: comapi.c,v 1.1 2018/04/07 22:34:25 christos Exp $	*/
      2  1.1  christos 
      3  1.1  christos /* omapi.c
      4  1.1  christos 
      5  1.1  christos    OMAPI object interfaces for the DHCP server. */
      6  1.1  christos 
      7  1.1  christos /*
      8  1.1  christos  * Copyright (c) 2004-2017 Internet Systems Consortium, Inc. ("ISC")
      9  1.1  christos  * Copyright (c) 1999-2003 by Internet Software Consortium
     10  1.1  christos  *
     11  1.1  christos  * This Source Code Form is subject to the terms of the Mozilla Public
     12  1.1  christos  * License, v. 2.0. If a copy of the MPL was not distributed with this
     13  1.1  christos  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
     14  1.1  christos  *
     15  1.1  christos  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
     16  1.1  christos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     17  1.1  christos  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
     18  1.1  christos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     19  1.1  christos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     20  1.1  christos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
     21  1.1  christos  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     22  1.1  christos  *
     23  1.1  christos  *   Internet Systems Consortium, Inc.
     24  1.1  christos  *   950 Charter Street
     25  1.1  christos  *   Redwood City, CA 94063
     26  1.1  christos  *   <info (at) isc.org>
     27  1.1  christos  *   https://www.isc.org/
     28  1.1  christos  *
     29  1.1  christos  */
     30  1.1  christos 
     31  1.1  christos #include <sys/cdefs.h>
     32  1.1  christos __RCSID("$NetBSD: comapi.c,v 1.1 2018/04/07 22:34:25 christos Exp $");
     33  1.1  christos 
     34  1.1  christos /* Many, many thanks to Brian Murrell and BCtel for this code - BCtel
     35  1.1  christos    provided the funding that resulted in this code and the entire
     36  1.1  christos    OMAPI support library being written, and Brian helped brainstorm
     37  1.1  christos    and refine the requirements.  To the extent that this code is
     38  1.1  christos    useful, you have Brian and BCtel to thank.  Any limitations in the
     39  1.1  christos    code are a result of mistakes on my part.  -- Ted Lemon */
     40  1.1  christos 
     41  1.1  christos #include "dhcpd.h"
     42  1.1  christos #include <omapip/omapip_p.h>
     43  1.1  christos 
     44  1.1  christos OMAPI_OBJECT_ALLOC (subnet, struct subnet, dhcp_type_subnet)
     45  1.1  christos OMAPI_OBJECT_ALLOC (shared_network, struct shared_network,
     46  1.1  christos 		    dhcp_type_shared_network)
     47  1.1  christos OMAPI_OBJECT_ALLOC (group_object, struct group_object, dhcp_type_group)
     48  1.1  christos OMAPI_OBJECT_ALLOC (dhcp_control, dhcp_control_object_t, dhcp_type_control)
     49  1.1  christos 
     50  1.1  christos omapi_object_type_t *dhcp_type_group;
     51  1.1  christos omapi_object_type_t *dhcp_type_shared_network;
     52  1.1  christos omapi_object_type_t *dhcp_type_subnet;
     53  1.1  christos omapi_object_type_t *dhcp_type_control;
     54  1.1  christos dhcp_control_object_t *dhcp_control_object;
     55  1.1  christos 
     56  1.1  christos void dhcp_common_objects_setup ()
     57  1.1  christos {
     58  1.1  christos 	isc_result_t status;
     59  1.1  christos 
     60  1.1  christos 	status = omapi_object_type_register (&dhcp_type_control,
     61  1.1  christos 					     "control",
     62  1.1  christos 					     dhcp_control_set_value,
     63  1.1  christos 					     dhcp_control_get_value,
     64  1.1  christos 					     dhcp_control_destroy,
     65  1.1  christos 					     dhcp_control_signal_handler,
     66  1.1  christos 					     dhcp_control_stuff_values,
     67  1.1  christos 					     dhcp_control_lookup,
     68  1.1  christos 					     dhcp_control_create,
     69  1.1  christos 					     dhcp_control_remove, 0, 0, 0,
     70  1.1  christos 					     sizeof (dhcp_control_object_t),
     71  1.1  christos 					     0, RC_MISC);
     72  1.1  christos 	if (status != ISC_R_SUCCESS)
     73  1.1  christos 		log_fatal ("Can't register control object type: %s",
     74  1.1  christos 			   isc_result_totext (status));
     75  1.1  christos 	status = dhcp_control_allocate (&dhcp_control_object, MDL);
     76  1.1  christos 	if (status != ISC_R_SUCCESS)
     77  1.1  christos 		log_fatal ("Can't make initial control object: %s",
     78  1.1  christos 			   isc_result_totext (status));
     79  1.1  christos 	dhcp_control_object -> state = server_startup;
     80  1.1  christos 
     81  1.1  christos 	status = omapi_object_type_register (&dhcp_type_group,
     82  1.1  christos 					     "group",
     83  1.1  christos 					     dhcp_group_set_value,
     84  1.1  christos 					     dhcp_group_get_value,
     85  1.1  christos 					     dhcp_group_destroy,
     86  1.1  christos 					     dhcp_group_signal_handler,
     87  1.1  christos 					     dhcp_group_stuff_values,
     88  1.1  christos 					     dhcp_group_lookup,
     89  1.1  christos 					     dhcp_group_create,
     90  1.1  christos 					     dhcp_group_remove, 0, 0, 0,
     91  1.1  christos 					     sizeof (struct group_object), 0,
     92  1.1  christos 					     RC_MISC);
     93  1.1  christos 	if (status != ISC_R_SUCCESS)
     94  1.1  christos 		log_fatal ("Can't register group object type: %s",
     95  1.1  christos 			   isc_result_totext (status));
     96  1.1  christos 
     97  1.1  christos 	status = omapi_object_type_register (&dhcp_type_subnet,
     98  1.1  christos 					     "subnet",
     99  1.1  christos 					     dhcp_subnet_set_value,
    100  1.1  christos 					     dhcp_subnet_get_value,
    101  1.1  christos 					     dhcp_subnet_destroy,
    102  1.1  christos 					     dhcp_subnet_signal_handler,
    103  1.1  christos 					     dhcp_subnet_stuff_values,
    104  1.1  christos 					     dhcp_subnet_lookup,
    105  1.1  christos 					     dhcp_subnet_create,
    106  1.1  christos 					     dhcp_subnet_remove, 0, 0, 0,
    107  1.1  christos 					     sizeof (struct subnet), 0,
    108  1.1  christos 					     RC_MISC);
    109  1.1  christos 	if (status != ISC_R_SUCCESS)
    110  1.1  christos 		log_fatal ("Can't register subnet object type: %s",
    111  1.1  christos 			   isc_result_totext (status));
    112  1.1  christos 
    113  1.1  christos 	status = omapi_object_type_register
    114  1.1  christos 		(&dhcp_type_shared_network,
    115  1.1  christos 		 "shared-network",
    116  1.1  christos 		 dhcp_shared_network_set_value,
    117  1.1  christos 		 dhcp_shared_network_get_value,
    118  1.1  christos 		 dhcp_shared_network_destroy,
    119  1.1  christos 		 dhcp_shared_network_signal_handler,
    120  1.1  christos 		 dhcp_shared_network_stuff_values,
    121  1.1  christos 		 dhcp_shared_network_lookup,
    122  1.1  christos 		 dhcp_shared_network_create,
    123  1.1  christos 		 dhcp_shared_network_remove, 0, 0, 0,
    124  1.1  christos 		 sizeof (struct shared_network), 0, RC_MISC);
    125  1.1  christos 	if (status != ISC_R_SUCCESS)
    126  1.1  christos 		log_fatal ("Can't register shared network object type: %s",
    127  1.1  christos 			   isc_result_totext (status));
    128  1.1  christos 
    129  1.1  christos 	interface_setup ();
    130  1.1  christos }
    131  1.1  christos 
    132  1.1  christos isc_result_t dhcp_group_set_value  (omapi_object_t *h,
    133  1.1  christos 				    omapi_object_t *id,
    134  1.1  christos 				    omapi_data_string_t *name,
    135  1.1  christos 				    omapi_typed_data_t *value)
    136  1.1  christos {
    137  1.1  christos 	struct group_object *group;
    138  1.1  christos 	isc_result_t status;
    139  1.1  christos 
    140  1.1  christos 	if (h -> type != dhcp_type_group)
    141  1.1  christos 		return DHCP_R_INVALIDARG;
    142  1.1  christos 	group = (struct group_object *)h;
    143  1.1  christos 
    144  1.1  christos 	/* XXX For now, we can only set these values on new group objects.
    145  1.1  christos 	   XXX Soon, we need to be able to update group objects. */
    146  1.1  christos 	if (!omapi_ds_strcmp (name, "name")) {
    147  1.1  christos 		if (group -> name)
    148  1.1  christos 			return ISC_R_EXISTS;
    149  1.1  christos 		if (value -> type == omapi_datatype_data ||
    150  1.1  christos 		    value -> type == omapi_datatype_string) {
    151  1.1  christos 			group -> name = dmalloc (value -> u.buffer.len + 1,
    152  1.1  christos 						 MDL);
    153  1.1  christos 			if (!group -> name)
    154  1.1  christos 				return ISC_R_NOMEMORY;
    155  1.1  christos 			memcpy (group -> name,
    156  1.1  christos 				value -> u.buffer.value,
    157  1.1  christos 				value -> u.buffer.len);
    158  1.1  christos 			group -> name [value -> u.buffer.len] = 0;
    159  1.1  christos 		} else
    160  1.1  christos 			return DHCP_R_INVALIDARG;
    161  1.1  christos 		return ISC_R_SUCCESS;
    162  1.1  christos 	}
    163  1.1  christos 
    164  1.1  christos 	if (!omapi_ds_strcmp (name, "statements")) {
    165  1.1  christos 		if (group -> group && group -> group -> statements)
    166  1.1  christos 			return ISC_R_EXISTS;
    167  1.1  christos 		if (!group -> group) {
    168  1.1  christos 			if (!clone_group (&group -> group, root_group, MDL))
    169  1.1  christos 				return ISC_R_NOMEMORY;
    170  1.1  christos 		}
    171  1.1  christos 		if (value -> type == omapi_datatype_data ||
    172  1.1  christos 		    value -> type == omapi_datatype_string) {
    173  1.1  christos 			struct parse *parse;
    174  1.1  christos 			int lose = 0;
    175  1.1  christos 			parse = NULL;
    176  1.1  christos 			status = new_parse(&parse, -1,
    177  1.1  christos 					    (char *) value->u.buffer.value,
    178  1.1  christos 					    value->u.buffer.len,
    179  1.1  christos 					    "network client", 0);
    180  1.1  christos 			if (status != ISC_R_SUCCESS || parse == NULL)
    181  1.1  christos 				return status;
    182  1.1  christos 			if (!(parse_executable_statements
    183  1.1  christos 			      (&group -> group -> statements, parse, &lose,
    184  1.1  christos 			       context_any))) {
    185  1.1  christos 				end_parse (&parse);
    186  1.1  christos 				return DHCP_R_BADPARSE;
    187  1.1  christos 			}
    188  1.1  christos 			end_parse (&parse);
    189  1.1  christos 			return ISC_R_SUCCESS;
    190  1.1  christos 		} else
    191  1.1  christos 			return DHCP_R_INVALIDARG;
    192  1.1  christos 	}
    193  1.1  christos 
    194  1.1  christos 	/* Try to find some inner object that can take the value. */
    195  1.1  christos 	if (h -> inner && h -> inner -> type -> set_value) {
    196  1.1  christos 		status = ((*(h -> inner -> type -> set_value))
    197  1.1  christos 			  (h -> inner, id, name, value));
    198  1.1  christos 		if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
    199  1.1  christos 			return status;
    200  1.1  christos 	}
    201  1.1  christos 
    202  1.1  christos 	return ISC_R_NOTFOUND;
    203  1.1  christos }
    204  1.1  christos 
    205  1.1  christos 
    206  1.1  christos isc_result_t dhcp_group_get_value (omapi_object_t *h, omapi_object_t *id,
    207  1.1  christos 				   omapi_data_string_t *name,
    208  1.1  christos 				   omapi_value_t **value)
    209  1.1  christos {
    210  1.1  christos 	struct group_object *group;
    211  1.1  christos 	isc_result_t status;
    212  1.1  christos 
    213  1.1  christos 	if (h -> type != dhcp_type_group)
    214  1.1  christos 		return DHCP_R_INVALIDARG;
    215  1.1  christos 	group = (struct group_object *)h;
    216  1.1  christos 
    217  1.1  christos 	if (!omapi_ds_strcmp (name, "name"))
    218  1.1  christos 		return omapi_make_string_value (value,
    219  1.1  christos 						name, group -> name, MDL);
    220  1.1  christos 
    221  1.1  christos 	/* Try to find some inner object that can take the value. */
    222  1.1  christos 	if (h -> inner && h -> inner -> type -> get_value) {
    223  1.1  christos 		status = ((*(h -> inner -> type -> get_value))
    224  1.1  christos 			  (h -> inner, id, name, value));
    225  1.1  christos 		if (status == ISC_R_SUCCESS)
    226  1.1  christos 			return status;
    227  1.1  christos 	}
    228  1.1  christos 	return ISC_R_NOTFOUND;
    229  1.1  christos }
    230  1.1  christos 
    231  1.1  christos isc_result_t dhcp_group_destroy (omapi_object_t *h, const char *file, int line)
    232  1.1  christos {
    233  1.1  christos 	struct group_object *group, *t;
    234  1.1  christos 
    235  1.1  christos 	if (h -> type != dhcp_type_group)
    236  1.1  christos 		return DHCP_R_INVALIDARG;
    237  1.1  christos 	group = (struct group_object *)h;
    238  1.1  christos 
    239  1.1  christos 	if (group -> name) {
    240  1.1  christos 		if (group_name_hash) {
    241  1.1  christos 			t = (struct group_object *)0;
    242  1.1  christos 			if (group_hash_lookup (&t, group_name_hash,
    243  1.1  christos 					       group -> name,
    244  1.1  christos 					       strlen (group -> name), MDL)) {
    245  1.1  christos 				group_hash_delete (group_name_hash,
    246  1.1  christos 						   group -> name,
    247  1.1  christos 						   strlen (group -> name),
    248  1.1  christos 						   MDL);
    249  1.1  christos 				group_object_dereference (&t, MDL);
    250  1.1  christos 			}
    251  1.1  christos 		}
    252  1.1  christos 		dfree (group -> name, file, line);
    253  1.1  christos 		group -> name = (char *)0;
    254  1.1  christos 	}
    255  1.1  christos 	if (group -> group)
    256  1.1  christos 		group_dereference (&group -> group, MDL);
    257  1.1  christos 
    258  1.1  christos 	return ISC_R_SUCCESS;
    259  1.1  christos }
    260  1.1  christos 
    261  1.1  christos isc_result_t dhcp_group_signal_handler (omapi_object_t *h,
    262  1.1  christos 					const char *name, va_list ap)
    263  1.1  christos {
    264  1.1  christos 	struct group_object *group;
    265  1.1  christos 	isc_result_t status;
    266  1.1  christos 	int updatep = 0;
    267  1.1  christos 
    268  1.1  christos 	if (h -> type != dhcp_type_group)
    269  1.1  christos 		return DHCP_R_INVALIDARG;
    270  1.1  christos 	group = (struct group_object *)h;
    271  1.1  christos 
    272  1.1  christos 	if (!strcmp (name, "updated")) {
    273  1.1  christos 		/* A group object isn't valid if a subgroup hasn't yet been
    274  1.1  christos 		   associated with it. */
    275  1.1  christos 		if (!group -> group)
    276  1.1  christos 			return DHCP_R_INVALIDARG;
    277  1.1  christos 
    278  1.1  christos 		/* Group objects always have to have names. */
    279  1.1  christos 		if (!group -> name) {
    280  1.1  christos 			char hnbuf [64];
    281  1.1  christos 			sprintf (hnbuf, "ng%08lx%08lx",
    282  1.1  christos 				 (unsigned long)cur_time,
    283  1.1  christos 				 (unsigned long)group);
    284  1.1  christos 			group -> name = dmalloc (strlen (hnbuf) + 1, MDL);
    285  1.1  christos 			if (!group -> name)
    286  1.1  christos 				return ISC_R_NOMEMORY;
    287  1.1  christos 			strcpy (group -> name, hnbuf);
    288  1.1  christos 		}
    289  1.1  christos 
    290  1.1  christos 		supersede_group (group, 1);
    291  1.1  christos 		updatep = 1;
    292  1.1  christos 	}
    293  1.1  christos 
    294  1.1  christos 	/* Try to find some inner object that can take the value. */
    295  1.1  christos 	if (h -> inner && h -> inner -> type -> get_value) {
    296  1.1  christos 		status = ((*(h -> inner -> type -> signal_handler))
    297  1.1  christos 			  (h -> inner, name, ap));
    298  1.1  christos 		if (status == ISC_R_SUCCESS)
    299  1.1  christos 			return status;
    300  1.1  christos 	}
    301  1.1  christos 	if (updatep)
    302  1.1  christos 		return ISC_R_SUCCESS;
    303  1.1  christos 	return ISC_R_NOTFOUND;
    304  1.1  christos }
    305  1.1  christos 
    306  1.1  christos isc_result_t dhcp_group_stuff_values (omapi_object_t *c,
    307  1.1  christos 				      omapi_object_t *id,
    308  1.1  christos 				      omapi_object_t *h)
    309  1.1  christos {
    310  1.1  christos 	struct group_object *group;
    311  1.1  christos 	isc_result_t status;
    312  1.1  christos 
    313  1.1  christos 	if (h -> type != dhcp_type_group)
    314  1.1  christos 		return DHCP_R_INVALIDARG;
    315  1.1  christos 	group = (struct group_object *)h;
    316  1.1  christos 
    317  1.1  christos 	/* Write out all the values. */
    318  1.1  christos 	if (group -> name) {
    319  1.1  christos 		status = omapi_connection_put_name (c, "name");
    320  1.1  christos 		if (status != ISC_R_SUCCESS)
    321  1.1  christos 			return status;
    322  1.1  christos 		status = omapi_connection_put_string (c, group -> name);
    323  1.1  christos 		if (status != ISC_R_SUCCESS)
    324  1.1  christos 			return status;
    325  1.1  christos 	}
    326  1.1  christos 
    327  1.1  christos 	/* Write out the inner object, if any. */
    328  1.1  christos 	if (h -> inner && h -> inner -> type -> stuff_values) {
    329  1.1  christos 		status = ((*(h -> inner -> type -> stuff_values))
    330  1.1  christos 			  (c, id, h -> inner));
    331  1.1  christos 		if (status == ISC_R_SUCCESS)
    332  1.1  christos 			return status;
    333  1.1  christos 	}
    334  1.1  christos 
    335  1.1  christos 	return ISC_R_SUCCESS;
    336  1.1  christos }
    337  1.1  christos 
    338  1.1  christos isc_result_t dhcp_group_lookup (omapi_object_t **lp,
    339  1.1  christos 				omapi_object_t *id, omapi_object_t *ref)
    340  1.1  christos {
    341  1.1  christos 	omapi_value_t *tv = (omapi_value_t *)0;
    342  1.1  christos 	isc_result_t status;
    343  1.1  christos 	struct group_object *group;
    344  1.1  christos 
    345  1.1  christos 	if (!ref)
    346  1.1  christos 		return DHCP_R_NOKEYS;
    347  1.1  christos 
    348  1.1  christos 	/* First see if we were sent a handle. */
    349  1.1  christos 	status = omapi_get_value_str (ref, id, "handle", &tv);
    350  1.1  christos 	if (status == ISC_R_SUCCESS) {
    351  1.1  christos 		status = omapi_handle_td_lookup (lp, tv -> value);
    352  1.1  christos 
    353  1.1  christos 		omapi_value_dereference (&tv, MDL);
    354  1.1  christos 		if (status != ISC_R_SUCCESS)
    355  1.1  christos 			return status;
    356  1.1  christos 
    357  1.1  christos 		/* Don't return the object if the type is wrong. */
    358  1.1  christos 		if ((*lp) -> type != dhcp_type_group) {
    359  1.1  christos 			omapi_object_dereference (lp, MDL);
    360  1.1  christos 			return DHCP_R_INVALIDARG;
    361  1.1  christos 		}
    362  1.1  christos 	}
    363  1.1  christos 
    364  1.1  christos 	/* Now look for a name. */
    365  1.1  christos 	status = omapi_get_value_str (ref, id, "name", &tv);
    366  1.1  christos 	if (status == ISC_R_SUCCESS) {
    367  1.1  christos 		group = (struct group_object *)0;
    368  1.1  christos 		if (group_name_hash &&
    369  1.1  christos 		    group_hash_lookup (&group, group_name_hash,
    370  1.1  christos 				       (const char *)
    371  1.1  christos 				       tv -> value -> u.buffer.value,
    372  1.1  christos 				       tv -> value -> u.buffer.len, MDL)) {
    373  1.1  christos 			omapi_value_dereference (&tv, MDL);
    374  1.1  christos 
    375  1.1  christos 			if (*lp && *lp != (omapi_object_t *)group) {
    376  1.1  christos 			    group_object_dereference (&group, MDL);
    377  1.1  christos 			    omapi_object_dereference (lp, MDL);
    378  1.1  christos 			    return DHCP_R_KEYCONFLICT;
    379  1.1  christos 			} else if (!*lp) {
    380  1.1  christos 			    /* XXX fix so that hash lookup itself creates
    381  1.1  christos 			       XXX the reference. */
    382  1.1  christos 			    omapi_object_reference (lp,
    383  1.1  christos 						    (omapi_object_t *)group,
    384  1.1  christos 						    MDL);
    385  1.1  christos 			    group_object_dereference (&group, MDL);
    386  1.1  christos 			}
    387  1.1  christos 		} else if (!*lp)
    388  1.1  christos 			return ISC_R_NOTFOUND;
    389  1.1  christos 	}
    390  1.1  christos 
    391  1.1  christos 	/* If we get to here without finding a group, no valid key was
    392  1.1  christos 	   specified. */
    393  1.1  christos 	if (!*lp)
    394  1.1  christos 		return DHCP_R_NOKEYS;
    395  1.1  christos 
    396  1.1  christos 	if (((struct group_object *)(*lp)) -> flags & GROUP_OBJECT_DELETED) {
    397  1.1  christos 		omapi_object_dereference (lp, MDL);
    398  1.1  christos 		return ISC_R_NOTFOUND;
    399  1.1  christos 	}
    400  1.1  christos 	return ISC_R_SUCCESS;
    401  1.1  christos }
    402  1.1  christos 
    403  1.1  christos isc_result_t dhcp_group_create (omapi_object_t **lp,
    404  1.1  christos 			       omapi_object_t *id)
    405  1.1  christos {
    406  1.1  christos 	struct group_object *group;
    407  1.1  christos 	isc_result_t status;
    408  1.1  christos 	group = (struct group_object *)0;
    409  1.1  christos 
    410  1.1  christos 	status = group_object_allocate (&group, MDL);
    411  1.1  christos 	if (status != ISC_R_SUCCESS)
    412  1.1  christos 		return status;
    413  1.1  christos 	group -> flags = GROUP_OBJECT_DYNAMIC;
    414  1.1  christos 	status = omapi_object_reference (lp, (omapi_object_t *)group, MDL);
    415  1.1  christos 	group_object_dereference (&group, MDL);
    416  1.1  christos 	return status;
    417  1.1  christos }
    418  1.1  christos 
    419  1.1  christos isc_result_t dhcp_group_remove (omapi_object_t *lp,
    420  1.1  christos 				omapi_object_t *id)
    421  1.1  christos {
    422  1.1  christos 	struct group_object *group;
    423  1.1  christos 	isc_result_t status;
    424  1.1  christos 	if (lp -> type != dhcp_type_group)
    425  1.1  christos 		return DHCP_R_INVALIDARG;
    426  1.1  christos 	group = (struct group_object *)lp;
    427  1.1  christos 
    428  1.1  christos 	group -> flags |= GROUP_OBJECT_DELETED;
    429  1.1  christos 	if (group_write_hook) {
    430  1.1  christos 		if (!(*group_write_hook) (group))
    431  1.1  christos 			return ISC_R_IOERROR;
    432  1.1  christos 	}
    433  1.1  christos 
    434  1.1  christos 	status = dhcp_group_destroy ((omapi_object_t *)group, MDL);
    435  1.1  christos 
    436  1.1  christos 	return status;
    437  1.1  christos }
    438  1.1  christos 
    439  1.1  christos isc_result_t dhcp_control_set_value  (omapi_object_t *h,
    440  1.1  christos 				      omapi_object_t *id,
    441  1.1  christos 				      omapi_data_string_t *name,
    442  1.1  christos 				      omapi_typed_data_t *value)
    443  1.1  christos {
    444  1.1  christos 	dhcp_control_object_t *control;
    445  1.1  christos 	isc_result_t status;
    446  1.1  christos 	unsigned long newstate;
    447  1.1  christos 
    448  1.1  christos 	if (h -> type != dhcp_type_control)
    449  1.1  christos 		return DHCP_R_INVALIDARG;
    450  1.1  christos 	control = (dhcp_control_object_t *)h;
    451  1.1  christos 
    452  1.1  christos 	if (!omapi_ds_strcmp (name, "state")) {
    453  1.1  christos 		status = omapi_get_int_value (&newstate, value);
    454  1.1  christos 		if (status != ISC_R_SUCCESS)
    455  1.1  christos 			return status;
    456  1.1  christos 		status = dhcp_set_control_state (control -> state, newstate);
    457  1.1  christos 		if (status == ISC_R_SUCCESS)
    458  1.1  christos 			control -> state = value -> u.integer;
    459  1.1  christos 		return status;
    460  1.1  christos 	}
    461  1.1  christos 
    462  1.1  christos 	/* Try to find some inner object that can take the value. */
    463  1.1  christos 	if (h -> inner && h -> inner -> type -> set_value) {
    464  1.1  christos 		status = ((*(h -> inner -> type -> set_value))
    465  1.1  christos 			  (h -> inner, id, name, value));
    466  1.1  christos 		if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
    467  1.1  christos 			return status;
    468  1.1  christos 	}
    469  1.1  christos 
    470  1.1  christos 	return ISC_R_NOTFOUND;
    471  1.1  christos }
    472  1.1  christos 
    473  1.1  christos 
    474  1.1  christos isc_result_t dhcp_control_get_value (omapi_object_t *h, omapi_object_t *id,
    475  1.1  christos 				   omapi_data_string_t *name,
    476  1.1  christos 				   omapi_value_t **value)
    477  1.1  christos {
    478  1.1  christos 	dhcp_control_object_t *control;
    479  1.1  christos 	isc_result_t status;
    480  1.1  christos 
    481  1.1  christos 	if (h -> type != dhcp_type_control)
    482  1.1  christos 		return DHCP_R_INVALIDARG;
    483  1.1  christos 	control = (dhcp_control_object_t *)h;
    484  1.1  christos 
    485  1.1  christos 	if (!omapi_ds_strcmp (name, "state"))
    486  1.1  christos 		return omapi_make_int_value (value,
    487  1.1  christos 					     name, (int)control -> state, MDL);
    488  1.1  christos 
    489  1.1  christos 	/* Try to find some inner object that can take the value. */
    490  1.1  christos 	if (h -> inner && h -> inner -> type -> get_value) {
    491  1.1  christos 		status = ((*(h -> inner -> type -> get_value))
    492  1.1  christos 			  (h -> inner, id, name, value));
    493  1.1  christos 		if (status == ISC_R_SUCCESS)
    494  1.1  christos 			return status;
    495  1.1  christos 	}
    496  1.1  christos 	return ISC_R_NOTFOUND;
    497  1.1  christos }
    498  1.1  christos 
    499  1.1  christos isc_result_t dhcp_control_destroy (omapi_object_t *h,
    500  1.1  christos 				   const char *file, int line)
    501  1.1  christos {
    502  1.1  christos 	if (h -> type != dhcp_type_control)
    503  1.1  christos 		return DHCP_R_INVALIDARG;
    504  1.1  christos 
    505  1.1  christos 	/* Can't destroy the control object. */
    506  1.1  christos 	return ISC_R_NOPERM;
    507  1.1  christos }
    508  1.1  christos 
    509  1.1  christos isc_result_t dhcp_control_signal_handler (omapi_object_t *h,
    510  1.1  christos 					const char *name, va_list ap)
    511  1.1  christos {
    512  1.1  christos 	/* In this function h should be a (dhcp_control_object_t *) */
    513  1.1  christos 
    514  1.1  christos 	isc_result_t status;
    515  1.1  christos 
    516  1.1  christos 	if (h -> type != dhcp_type_control)
    517  1.1  christos 		return DHCP_R_INVALIDARG;
    518  1.1  christos 
    519  1.1  christos 	/* Try to find some inner object that can take the value. */
    520  1.1  christos 	if (h -> inner && h -> inner -> type -> get_value) {
    521  1.1  christos 		status = ((*(h -> inner -> type -> signal_handler))
    522  1.1  christos 			  (h -> inner, name, ap));
    523  1.1  christos 		if (status == ISC_R_SUCCESS)
    524  1.1  christos 			return status;
    525  1.1  christos 	}
    526  1.1  christos 	return ISC_R_NOTFOUND;
    527  1.1  christos }
    528  1.1  christos 
    529  1.1  christos isc_result_t dhcp_control_stuff_values (omapi_object_t *c,
    530  1.1  christos 					omapi_object_t *id,
    531  1.1  christos 					omapi_object_t *h)
    532  1.1  christos {
    533  1.1  christos 	dhcp_control_object_t *control;
    534  1.1  christos 	isc_result_t status;
    535  1.1  christos 
    536  1.1  christos 	if (h -> type != dhcp_type_control)
    537  1.1  christos 		return DHCP_R_INVALIDARG;
    538  1.1  christos 	control = (dhcp_control_object_t *)h;
    539  1.1  christos 
    540  1.1  christos 	/* Write out all the values. */
    541  1.1  christos 	status = omapi_connection_put_name (c, "state");
    542  1.1  christos 	if (status != ISC_R_SUCCESS)
    543  1.1  christos 		return status;
    544  1.1  christos 	status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
    545  1.1  christos 	if (status != ISC_R_SUCCESS)
    546  1.1  christos 		return status;
    547  1.1  christos 	status = omapi_connection_put_uint32 (c, control -> state);
    548  1.1  christos 	if (status != ISC_R_SUCCESS)
    549  1.1  christos 		return status;
    550  1.1  christos 
    551  1.1  christos 	/* Write out the inner object, if any. */
    552  1.1  christos 	if (h -> inner && h -> inner -> type -> stuff_values) {
    553  1.1  christos 		status = ((*(h -> inner -> type -> stuff_values))
    554  1.1  christos 			  (c, id, h -> inner));
    555  1.1  christos 		if (status == ISC_R_SUCCESS)
    556  1.1  christos 			return status;
    557  1.1  christos 	}
    558  1.1  christos 
    559  1.1  christos 	return ISC_R_SUCCESS;
    560  1.1  christos }
    561  1.1  christos 
    562  1.1  christos isc_result_t dhcp_control_lookup (omapi_object_t **lp,
    563  1.1  christos 				  omapi_object_t *id, omapi_object_t *ref)
    564  1.1  christos {
    565  1.1  christos 	omapi_value_t *tv = (omapi_value_t *)0;
    566  1.1  christos 	isc_result_t status;
    567  1.1  christos 
    568  1.1  christos 	/* First see if we were sent a handle. */
    569  1.1  christos 	if (ref) {
    570  1.1  christos 		status = omapi_get_value_str (ref, id, "handle", &tv);
    571  1.1  christos 		if (status == ISC_R_SUCCESS) {
    572  1.1  christos 			status = omapi_handle_td_lookup (lp, tv -> value);
    573  1.1  christos 
    574  1.1  christos 			omapi_value_dereference (&tv, MDL);
    575  1.1  christos 			if (status != ISC_R_SUCCESS)
    576  1.1  christos 				return status;
    577  1.1  christos 
    578  1.1  christos 			/* Don't return the object if the type is wrong. */
    579  1.1  christos 			if ((*lp) -> type != dhcp_type_control) {
    580  1.1  christos 				omapi_object_dereference (lp, MDL);
    581  1.1  christos 				return DHCP_R_INVALIDARG;
    582  1.1  christos 			}
    583  1.1  christos 		}
    584  1.1  christos 	}
    585  1.1  christos 
    586  1.1  christos 	/* Otherwise, stop playing coy - there's only one control object,
    587  1.1  christos 	   so we can just return it. */
    588  1.1  christos 	dhcp_control_reference ((dhcp_control_object_t **)lp,
    589  1.1  christos 				dhcp_control_object, MDL);
    590  1.1  christos 	return ISC_R_SUCCESS;
    591  1.1  christos }
    592  1.1  christos 
    593  1.1  christos isc_result_t dhcp_control_create (omapi_object_t **lp,
    594  1.1  christos 				  omapi_object_t *id)
    595  1.1  christos {
    596  1.1  christos 	/* Can't create a control object - there can be only one. */
    597  1.1  christos 	return ISC_R_NOPERM;
    598  1.1  christos }
    599  1.1  christos 
    600  1.1  christos isc_result_t dhcp_control_remove (omapi_object_t *lp,
    601  1.1  christos 				omapi_object_t *id)
    602  1.1  christos {
    603  1.1  christos 	/* Form is emptiness; emptiness form.   The control object
    604  1.1  christos 	   cannot go out of existance. */
    605  1.1  christos 	return ISC_R_NOPERM;
    606  1.1  christos }
    607  1.1  christos 
    608  1.1  christos isc_result_t dhcp_subnet_set_value  (omapi_object_t *h,
    609  1.1  christos 				     omapi_object_t *id,
    610  1.1  christos 				     omapi_data_string_t *name,
    611  1.1  christos 				     omapi_typed_data_t *value)
    612  1.1  christos {
    613  1.1  christos 	/* In this function h should be a (struct subnet *) */
    614  1.1  christos 
    615  1.1  christos 	isc_result_t status;
    616  1.1  christos 
    617  1.1  christos 	if (h -> type != dhcp_type_subnet)
    618  1.1  christos 		return DHCP_R_INVALIDARG;
    619  1.1  christos 
    620  1.1  christos 	/* No values to set yet. */
    621  1.1  christos 
    622  1.1  christos 	/* Try to find some inner object that can take the value. */
    623  1.1  christos 	if (h -> inner && h -> inner -> type -> set_value) {
    624  1.1  christos 		status = ((*(h -> inner -> type -> set_value))
    625  1.1  christos 			  (h -> inner, id, name, value));
    626  1.1  christos 		if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
    627  1.1  christos 			return status;
    628  1.1  christos 	}
    629  1.1  christos 
    630  1.1  christos 	return ISC_R_NOTFOUND;
    631  1.1  christos }
    632  1.1  christos 
    633  1.1  christos 
    634  1.1  christos isc_result_t dhcp_subnet_get_value (omapi_object_t *h, omapi_object_t *id,
    635  1.1  christos 				    omapi_data_string_t *name,
    636  1.1  christos 				    omapi_value_t **value)
    637  1.1  christos {
    638  1.1  christos 	/* In this function h should be a (struct subnet *) */
    639  1.1  christos 
    640  1.1  christos 	isc_result_t status;
    641  1.1  christos 
    642  1.1  christos 	if (h -> type != dhcp_type_subnet)
    643  1.1  christos 		return DHCP_R_INVALIDARG;
    644  1.1  christos 
    645  1.1  christos 	/* No values to get yet. */
    646  1.1  christos 
    647  1.1  christos 	/* Try to find some inner object that can provide the value. */
    648  1.1  christos 	if (h -> inner && h -> inner -> type -> get_value) {
    649  1.1  christos 		status = ((*(h -> inner -> type -> get_value))
    650  1.1  christos 			  (h -> inner, id, name, value));
    651  1.1  christos 		if (status == ISC_R_SUCCESS)
    652  1.1  christos 			return status;
    653  1.1  christos 	}
    654  1.1  christos 	return ISC_R_NOTFOUND;
    655  1.1  christos }
    656  1.1  christos 
    657  1.1  christos isc_result_t dhcp_subnet_destroy (omapi_object_t *h, const char *file, int line)
    658  1.1  christos {
    659  1.1  christos 	struct subnet *subnet;
    660  1.1  christos 
    661  1.1  christos 	if (h -> type != dhcp_type_subnet)
    662  1.1  christos 		return DHCP_R_INVALIDARG;
    663  1.1  christos 
    664  1.1  christos 	subnet = (struct subnet *)h;
    665  1.1  christos 	if (subnet -> next_subnet)
    666  1.1  christos 		subnet_dereference (&subnet -> next_subnet, file, line);
    667  1.1  christos 	if (subnet -> next_sibling)
    668  1.1  christos 		subnet_dereference (&subnet -> next_sibling, file, line);
    669  1.1  christos 	if (subnet -> shared_network)
    670  1.1  christos 		shared_network_dereference (&subnet -> shared_network,
    671  1.1  christos 					    file, line);
    672  1.1  christos 	if (subnet -> interface)
    673  1.1  christos 		interface_dereference (&subnet -> interface, file, line);
    674  1.1  christos 	if (subnet -> group)
    675  1.1  christos 		group_dereference (&subnet -> group, file, line);
    676  1.1  christos 
    677  1.1  christos 	return ISC_R_SUCCESS;
    678  1.1  christos }
    679  1.1  christos 
    680  1.1  christos isc_result_t dhcp_subnet_signal_handler (omapi_object_t *h,
    681  1.1  christos 					 const char *name, va_list ap)
    682  1.1  christos {
    683  1.1  christos 	/* In this function h should be a (struct subnet *) */
    684  1.1  christos 
    685  1.1  christos 	isc_result_t status;
    686  1.1  christos 
    687  1.1  christos 	if (h -> type != dhcp_type_subnet)
    688  1.1  christos 		return DHCP_R_INVALIDARG;
    689  1.1  christos 
    690  1.1  christos 	/* Can't write subnets yet. */
    691  1.1  christos 
    692  1.1  christos 	/* Try to find some inner object that can take the value. */
    693  1.1  christos 	if (h -> inner && h -> inner -> type -> get_value) {
    694  1.1  christos 		status = ((*(h -> inner -> type -> signal_handler))
    695  1.1  christos 			  (h -> inner, name, ap));
    696  1.1  christos 		if (status == ISC_R_SUCCESS)
    697  1.1  christos 			return status;
    698  1.1  christos 	}
    699  1.1  christos 
    700  1.1  christos 	return ISC_R_NOTFOUND;
    701  1.1  christos }
    702  1.1  christos 
    703  1.1  christos isc_result_t dhcp_subnet_stuff_values (omapi_object_t *c,
    704  1.1  christos 				       omapi_object_t *id,
    705  1.1  christos 				       omapi_object_t *h)
    706  1.1  christos {
    707  1.1  christos 	/* In this function h should be a (struct subnet *) */
    708  1.1  christos 
    709  1.1  christos 	isc_result_t status;
    710  1.1  christos 
    711  1.1  christos 	if (h -> type != dhcp_type_subnet)
    712  1.1  christos 		return DHCP_R_INVALIDARG;
    713  1.1  christos 
    714  1.1  christos 	/* Can't stuff subnet values yet. */
    715  1.1  christos 
    716  1.1  christos 	/* Write out the inner object, if any. */
    717  1.1  christos 	if (h -> inner && h -> inner -> type -> stuff_values) {
    718  1.1  christos 		status = ((*(h -> inner -> type -> stuff_values))
    719  1.1  christos 			  (c, id, h -> inner));
    720  1.1  christos 		if (status == ISC_R_SUCCESS)
    721  1.1  christos 			return status;
    722  1.1  christos 	}
    723  1.1  christos 
    724  1.1  christos 	return ISC_R_SUCCESS;
    725  1.1  christos }
    726  1.1  christos 
    727  1.1  christos isc_result_t dhcp_subnet_lookup (omapi_object_t **lp,
    728  1.1  christos 				 omapi_object_t *id,
    729  1.1  christos 				 omapi_object_t *ref)
    730  1.1  christos {
    731  1.1  christos 	/* Can't look up subnets yet. */
    732  1.1  christos 
    733  1.1  christos 	/* If we get to here without finding a subnet, no valid key was
    734  1.1  christos 	   specified. */
    735  1.1  christos 	if (!*lp)
    736  1.1  christos 		return DHCP_R_NOKEYS;
    737  1.1  christos 	return ISC_R_SUCCESS;
    738  1.1  christos }
    739  1.1  christos 
    740  1.1  christos isc_result_t dhcp_subnet_create (omapi_object_t **lp,
    741  1.1  christos 				 omapi_object_t *id)
    742  1.1  christos {
    743  1.1  christos 	return ISC_R_NOTIMPLEMENTED;
    744  1.1  christos }
    745  1.1  christos 
    746  1.1  christos isc_result_t dhcp_subnet_remove (omapi_object_t *lp,
    747  1.1  christos 			       omapi_object_t *id)
    748  1.1  christos {
    749  1.1  christos 	return ISC_R_NOTIMPLEMENTED;
    750  1.1  christos }
    751  1.1  christos 
    752  1.1  christos isc_result_t dhcp_shared_network_set_value  (omapi_object_t *h,
    753  1.1  christos 					     omapi_object_t *id,
    754  1.1  christos 					     omapi_data_string_t *name,
    755  1.1  christos 					     omapi_typed_data_t *value)
    756  1.1  christos {
    757  1.1  christos 	/* In this function h should be a (struct shared_network *) */
    758  1.1  christos 
    759  1.1  christos 	isc_result_t status;
    760  1.1  christos 
    761  1.1  christos 	if (h -> type != dhcp_type_shared_network)
    762  1.1  christos 		return DHCP_R_INVALIDARG;
    763  1.1  christos 
    764  1.1  christos 	/* No values to set yet. */
    765  1.1  christos 
    766  1.1  christos 	/* Try to find some inner object that can take the value. */
    767  1.1  christos 	if (h -> inner && h -> inner -> type -> set_value) {
    768  1.1  christos 		status = ((*(h -> inner -> type -> set_value))
    769  1.1  christos 			  (h -> inner, id, name, value));
    770  1.1  christos 		if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
    771  1.1  christos 			return status;
    772  1.1  christos 	}
    773  1.1  christos 
    774  1.1  christos 	return ISC_R_NOTFOUND;
    775  1.1  christos }
    776  1.1  christos 
    777  1.1  christos 
    778  1.1  christos isc_result_t dhcp_shared_network_get_value (omapi_object_t *h,
    779  1.1  christos 					    omapi_object_t *id,
    780  1.1  christos 					    omapi_data_string_t *name,
    781  1.1  christos 					    omapi_value_t **value)
    782  1.1  christos {
    783  1.1  christos 	/* In this function h should be a (struct shared_network *) */
    784  1.1  christos 
    785  1.1  christos 	isc_result_t status;
    786  1.1  christos 
    787  1.1  christos 	if (h -> type != dhcp_type_shared_network)
    788  1.1  christos 		return DHCP_R_INVALIDARG;
    789  1.1  christos 
    790  1.1  christos 	/* No values to get yet. */
    791  1.1  christos 
    792  1.1  christos 	/* Try to find some inner object that can provide the value. */
    793  1.1  christos 	if (h -> inner && h -> inner -> type -> get_value) {
    794  1.1  christos 		status = ((*(h -> inner -> type -> get_value))
    795  1.1  christos 			  (h -> inner, id, name, value));
    796  1.1  christos 		if (status == ISC_R_SUCCESS)
    797  1.1  christos 			return status;
    798  1.1  christos 	}
    799  1.1  christos 	return ISC_R_NOTFOUND;
    800  1.1  christos }
    801  1.1  christos 
    802  1.1  christos isc_result_t dhcp_shared_network_destroy (omapi_object_t *h,
    803  1.1  christos 					  const char *file, int line)
    804  1.1  christos {
    805  1.1  christos 	/* In this function h should be a (struct shared_network *) */
    806  1.1  christos 
    807  1.1  christos 	struct shared_network *shared_network;
    808  1.1  christos 
    809  1.1  christos 	if (h -> type != dhcp_type_shared_network)
    810  1.1  christos 		return DHCP_R_INVALIDARG;
    811  1.1  christos 
    812  1.1  christos 	shared_network = (struct shared_network *)h;
    813  1.1  christos 	if (shared_network -> next)
    814  1.1  christos 		shared_network_dereference (&shared_network -> next,
    815  1.1  christos 					    file, line);
    816  1.1  christos 	if (shared_network -> name) {
    817  1.1  christos 		dfree (shared_network -> name, file, line);
    818  1.1  christos 		shared_network -> name = 0;
    819  1.1  christos 	}
    820  1.1  christos 	if (shared_network -> subnets)
    821  1.1  christos 		subnet_dereference (&shared_network -> subnets, file, line);
    822  1.1  christos 	if (shared_network -> interface)
    823  1.1  christos 		interface_dereference (&shared_network -> interface,
    824  1.1  christos 				       file, line);
    825  1.1  christos 	if (shared_network -> pools)
    826  1.1  christos 	    omapi_object_dereference ((omapi_object_t **)
    827  1.1  christos 				      &shared_network -> pools, file, line);
    828  1.1  christos 	if (shared_network -> group)
    829  1.1  christos 		group_dereference (&shared_network -> group, file, line);
    830  1.1  christos #if defined (FAILOVER_PROTOCOL)
    831  1.1  christos 	if (shared_network -> failover_peer)
    832  1.1  christos 	    omapi_object_dereference ((omapi_object_t **)
    833  1.1  christos 				      &shared_network -> failover_peer,
    834  1.1  christos 				      file, line);
    835  1.1  christos #endif
    836  1.1  christos 
    837  1.1  christos 	return ISC_R_SUCCESS;
    838  1.1  christos }
    839  1.1  christos 
    840  1.1  christos isc_result_t dhcp_shared_network_signal_handler (omapi_object_t *h,
    841  1.1  christos 						 const char *name,
    842  1.1  christos 						 va_list ap)
    843  1.1  christos {
    844  1.1  christos 	/* In this function h should be a (struct shared_network *) */
    845  1.1  christos 
    846  1.1  christos 	isc_result_t status;
    847  1.1  christos 
    848  1.1  christos 	if (h -> type != dhcp_type_shared_network)
    849  1.1  christos 		return DHCP_R_INVALIDARG;
    850  1.1  christos 
    851  1.1  christos 	/* Can't write shared_networks yet. */
    852  1.1  christos 
    853  1.1  christos 	/* Try to find some inner object that can take the value. */
    854  1.1  christos 	if (h -> inner && h -> inner -> type -> get_value) {
    855  1.1  christos 		status = ((*(h -> inner -> type -> signal_handler))
    856  1.1  christos 			  (h -> inner, name, ap));
    857  1.1  christos 		if (status == ISC_R_SUCCESS)
    858  1.1  christos 			return status;
    859  1.1  christos 	}
    860  1.1  christos 
    861  1.1  christos 	return ISC_R_NOTFOUND;
    862  1.1  christos }
    863  1.1  christos 
    864  1.1  christos isc_result_t dhcp_shared_network_stuff_values (omapi_object_t *c,
    865  1.1  christos 					       omapi_object_t *id,
    866  1.1  christos 					       omapi_object_t *h)
    867  1.1  christos {
    868  1.1  christos 	/* In this function h should be a (struct shared_network *) */
    869  1.1  christos 
    870  1.1  christos 	isc_result_t status;
    871  1.1  christos 
    872  1.1  christos 	if (h -> type != dhcp_type_shared_network)
    873  1.1  christos 		return DHCP_R_INVALIDARG;
    874  1.1  christos 
    875  1.1  christos 	/* Can't stuff shared_network values yet. */
    876  1.1  christos 
    877  1.1  christos 	/* Write out the inner object, if any. */
    878  1.1  christos 	if (h -> inner && h -> inner -> type -> stuff_values) {
    879  1.1  christos 		status = ((*(h -> inner -> type -> stuff_values))
    880  1.1  christos 			  (c, id, h -> inner));
    881  1.1  christos 		if (status == ISC_R_SUCCESS)
    882  1.1  christos 			return status;
    883  1.1  christos 	}
    884  1.1  christos 
    885  1.1  christos 	return ISC_R_SUCCESS;
    886  1.1  christos }
    887  1.1  christos 
    888  1.1  christos isc_result_t dhcp_shared_network_lookup (omapi_object_t **lp,
    889  1.1  christos 					 omapi_object_t *id,
    890  1.1  christos 					 omapi_object_t *ref)
    891  1.1  christos {
    892  1.1  christos 	/* Can't look up shared_networks yet. */
    893  1.1  christos 
    894  1.1  christos 	/* If we get to here without finding a shared_network, no valid key was
    895  1.1  christos 	   specified. */
    896  1.1  christos 	if (!*lp)
    897  1.1  christos 		return DHCP_R_NOKEYS;
    898  1.1  christos 	return ISC_R_SUCCESS;
    899  1.1  christos }
    900  1.1  christos 
    901  1.1  christos isc_result_t dhcp_shared_network_create (omapi_object_t **lp,
    902  1.1  christos 					 omapi_object_t *id)
    903  1.1  christos {
    904  1.1  christos 	return ISC_R_NOTIMPLEMENTED;
    905  1.1  christos }
    906  1.1  christos 
    907  1.1  christos isc_result_t dhcp_shared_network_remove (omapi_object_t *lp,
    908  1.1  christos 					 omapi_object_t *id)
    909  1.1  christos {
    910  1.1  christos 	return ISC_R_NOTIMPLEMENTED;
    911  1.1  christos }
    912  1.1  christos 
    913