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