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