1 1.2 christos /* $NetBSD: comapi.c,v 1.3 2022/04/03 01:10:58 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.3 christos * Copyright (C) 2004-2022 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.3 christos * PO Box 360 25 1.3 christos * Newmarket, NH 03857 USA 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.2 christos __RCSID("$NetBSD: comapi.c,v 1.3 2022/04/03 01:10:58 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.3 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.3 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.3 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.3 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.3 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.3 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.2 christos status = libdhcp_callbacks.dhcp_set_control_state 457 1.2 christos (control -> state, newstate); 458 1.1 christos if (status == ISC_R_SUCCESS) 459 1.1 christos control -> state = value -> u.integer; 460 1.1 christos return status; 461 1.1 christos } 462 1.1 christos 463 1.1 christos /* Try to find some inner object that can take the value. */ 464 1.1 christos if (h -> inner && h -> inner -> type -> set_value) { 465 1.1 christos status = ((*(h -> inner -> type -> set_value)) 466 1.1 christos (h -> inner, id, name, value)); 467 1.1 christos if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) 468 1.1 christos return status; 469 1.1 christos } 470 1.3 christos 471 1.1 christos return ISC_R_NOTFOUND; 472 1.1 christos } 473 1.1 christos 474 1.1 christos 475 1.1 christos isc_result_t dhcp_control_get_value (omapi_object_t *h, omapi_object_t *id, 476 1.1 christos omapi_data_string_t *name, 477 1.1 christos omapi_value_t **value) 478 1.1 christos { 479 1.1 christos dhcp_control_object_t *control; 480 1.1 christos isc_result_t status; 481 1.1 christos 482 1.1 christos if (h -> type != dhcp_type_control) 483 1.1 christos return DHCP_R_INVALIDARG; 484 1.1 christos control = (dhcp_control_object_t *)h; 485 1.1 christos 486 1.1 christos if (!omapi_ds_strcmp (name, "state")) 487 1.1 christos return omapi_make_int_value (value, 488 1.1 christos name, (int)control -> state, MDL); 489 1.1 christos 490 1.1 christos /* Try to find some inner object that can take the value. */ 491 1.1 christos if (h -> inner && h -> inner -> type -> get_value) { 492 1.1 christos status = ((*(h -> inner -> type -> get_value)) 493 1.1 christos (h -> inner, id, name, value)); 494 1.1 christos if (status == ISC_R_SUCCESS) 495 1.1 christos return status; 496 1.1 christos } 497 1.1 christos return ISC_R_NOTFOUND; 498 1.1 christos } 499 1.1 christos 500 1.1 christos isc_result_t dhcp_control_destroy (omapi_object_t *h, 501 1.1 christos const char *file, int line) 502 1.1 christos { 503 1.1 christos if (h -> type != dhcp_type_control) 504 1.1 christos return DHCP_R_INVALIDARG; 505 1.1 christos 506 1.1 christos /* Can't destroy the control object. */ 507 1.1 christos return ISC_R_NOPERM; 508 1.1 christos } 509 1.1 christos 510 1.1 christos isc_result_t dhcp_control_signal_handler (omapi_object_t *h, 511 1.1 christos const char *name, va_list ap) 512 1.1 christos { 513 1.1 christos /* In this function h should be a (dhcp_control_object_t *) */ 514 1.1 christos 515 1.1 christos isc_result_t status; 516 1.1 christos 517 1.1 christos if (h -> type != dhcp_type_control) 518 1.1 christos return DHCP_R_INVALIDARG; 519 1.1 christos 520 1.1 christos /* Try to find some inner object that can take the value. */ 521 1.1 christos if (h -> inner && h -> inner -> type -> get_value) { 522 1.1 christos status = ((*(h -> inner -> type -> signal_handler)) 523 1.1 christos (h -> inner, name, ap)); 524 1.1 christos if (status == ISC_R_SUCCESS) 525 1.1 christos return status; 526 1.1 christos } 527 1.1 christos return ISC_R_NOTFOUND; 528 1.1 christos } 529 1.1 christos 530 1.1 christos isc_result_t dhcp_control_stuff_values (omapi_object_t *c, 531 1.1 christos omapi_object_t *id, 532 1.1 christos omapi_object_t *h) 533 1.1 christos { 534 1.1 christos dhcp_control_object_t *control; 535 1.1 christos isc_result_t status; 536 1.1 christos 537 1.1 christos if (h -> type != dhcp_type_control) 538 1.1 christos return DHCP_R_INVALIDARG; 539 1.1 christos control = (dhcp_control_object_t *)h; 540 1.1 christos 541 1.1 christos /* Write out all the values. */ 542 1.1 christos status = omapi_connection_put_name (c, "state"); 543 1.1 christos if (status != ISC_R_SUCCESS) 544 1.1 christos return status; 545 1.1 christos status = omapi_connection_put_uint32 (c, sizeof (u_int32_t)); 546 1.1 christos if (status != ISC_R_SUCCESS) 547 1.1 christos return status; 548 1.1 christos status = omapi_connection_put_uint32 (c, control -> state); 549 1.1 christos if (status != ISC_R_SUCCESS) 550 1.1 christos return status; 551 1.1 christos 552 1.1 christos /* Write out the inner object, if any. */ 553 1.1 christos if (h -> inner && h -> inner -> type -> stuff_values) { 554 1.1 christos status = ((*(h -> inner -> type -> stuff_values)) 555 1.1 christos (c, id, h -> inner)); 556 1.1 christos if (status == ISC_R_SUCCESS) 557 1.1 christos return status; 558 1.1 christos } 559 1.1 christos 560 1.1 christos return ISC_R_SUCCESS; 561 1.1 christos } 562 1.1 christos 563 1.1 christos isc_result_t dhcp_control_lookup (omapi_object_t **lp, 564 1.1 christos omapi_object_t *id, omapi_object_t *ref) 565 1.1 christos { 566 1.1 christos omapi_value_t *tv = (omapi_value_t *)0; 567 1.1 christos isc_result_t status; 568 1.1 christos 569 1.1 christos /* First see if we were sent a handle. */ 570 1.1 christos if (ref) { 571 1.1 christos status = omapi_get_value_str (ref, id, "handle", &tv); 572 1.1 christos if (status == ISC_R_SUCCESS) { 573 1.1 christos status = omapi_handle_td_lookup (lp, tv -> value); 574 1.1 christos 575 1.1 christos omapi_value_dereference (&tv, MDL); 576 1.1 christos if (status != ISC_R_SUCCESS) 577 1.1 christos return status; 578 1.1 christos 579 1.1 christos /* Don't return the object if the type is wrong. */ 580 1.1 christos if ((*lp) -> type != dhcp_type_control) { 581 1.1 christos omapi_object_dereference (lp, MDL); 582 1.1 christos return DHCP_R_INVALIDARG; 583 1.1 christos } 584 1.1 christos } 585 1.1 christos } 586 1.1 christos 587 1.1 christos /* Otherwise, stop playing coy - there's only one control object, 588 1.1 christos so we can just return it. */ 589 1.1 christos dhcp_control_reference ((dhcp_control_object_t **)lp, 590 1.1 christos dhcp_control_object, MDL); 591 1.1 christos return ISC_R_SUCCESS; 592 1.1 christos } 593 1.1 christos 594 1.1 christos isc_result_t dhcp_control_create (omapi_object_t **lp, 595 1.1 christos omapi_object_t *id) 596 1.1 christos { 597 1.1 christos /* Can't create a control object - there can be only one. */ 598 1.1 christos return ISC_R_NOPERM; 599 1.1 christos } 600 1.1 christos 601 1.1 christos isc_result_t dhcp_control_remove (omapi_object_t *lp, 602 1.1 christos omapi_object_t *id) 603 1.1 christos { 604 1.1 christos /* Form is emptiness; emptiness form. The control object 605 1.1 christos cannot go out of existance. */ 606 1.1 christos return ISC_R_NOPERM; 607 1.1 christos } 608 1.1 christos 609 1.1 christos isc_result_t dhcp_subnet_set_value (omapi_object_t *h, 610 1.1 christos omapi_object_t *id, 611 1.1 christos omapi_data_string_t *name, 612 1.1 christos omapi_typed_data_t *value) 613 1.1 christos { 614 1.1 christos /* In this function h should be a (struct subnet *) */ 615 1.1 christos 616 1.1 christos isc_result_t status; 617 1.1 christos 618 1.1 christos if (h -> type != dhcp_type_subnet) 619 1.1 christos return DHCP_R_INVALIDARG; 620 1.1 christos 621 1.1 christos /* No values to set yet. */ 622 1.1 christos 623 1.1 christos /* Try to find some inner object that can take the value. */ 624 1.1 christos if (h -> inner && h -> inner -> type -> set_value) { 625 1.1 christos status = ((*(h -> inner -> type -> set_value)) 626 1.1 christos (h -> inner, id, name, value)); 627 1.1 christos if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) 628 1.1 christos return status; 629 1.1 christos } 630 1.1 christos 631 1.1 christos return ISC_R_NOTFOUND; 632 1.1 christos } 633 1.1 christos 634 1.1 christos 635 1.1 christos isc_result_t dhcp_subnet_get_value (omapi_object_t *h, omapi_object_t *id, 636 1.1 christos omapi_data_string_t *name, 637 1.1 christos omapi_value_t **value) 638 1.1 christos { 639 1.1 christos /* In this function h should be a (struct subnet *) */ 640 1.1 christos 641 1.1 christos isc_result_t status; 642 1.1 christos 643 1.1 christos if (h -> type != dhcp_type_subnet) 644 1.1 christos return DHCP_R_INVALIDARG; 645 1.1 christos 646 1.1 christos /* No values to get yet. */ 647 1.1 christos 648 1.1 christos /* Try to find some inner object that can provide the value. */ 649 1.1 christos if (h -> inner && h -> inner -> type -> get_value) { 650 1.1 christos status = ((*(h -> inner -> type -> get_value)) 651 1.1 christos (h -> inner, id, name, value)); 652 1.1 christos if (status == ISC_R_SUCCESS) 653 1.1 christos return status; 654 1.1 christos } 655 1.1 christos return ISC_R_NOTFOUND; 656 1.1 christos } 657 1.1 christos 658 1.1 christos isc_result_t dhcp_subnet_destroy (omapi_object_t *h, const char *file, int line) 659 1.1 christos { 660 1.1 christos struct subnet *subnet; 661 1.1 christos 662 1.1 christos if (h -> type != dhcp_type_subnet) 663 1.1 christos return DHCP_R_INVALIDARG; 664 1.1 christos 665 1.1 christos subnet = (struct subnet *)h; 666 1.1 christos if (subnet -> next_subnet) 667 1.1 christos subnet_dereference (&subnet -> next_subnet, file, line); 668 1.1 christos if (subnet -> next_sibling) 669 1.1 christos subnet_dereference (&subnet -> next_sibling, file, line); 670 1.1 christos if (subnet -> shared_network) 671 1.1 christos shared_network_dereference (&subnet -> shared_network, 672 1.1 christos file, line); 673 1.1 christos if (subnet -> interface) 674 1.1 christos interface_dereference (&subnet -> interface, file, line); 675 1.1 christos if (subnet -> group) 676 1.1 christos group_dereference (&subnet -> group, file, line); 677 1.1 christos 678 1.1 christos return ISC_R_SUCCESS; 679 1.1 christos } 680 1.1 christos 681 1.1 christos isc_result_t dhcp_subnet_signal_handler (omapi_object_t *h, 682 1.1 christos const char *name, va_list ap) 683 1.1 christos { 684 1.1 christos /* In this function h should be a (struct subnet *) */ 685 1.1 christos 686 1.1 christos isc_result_t status; 687 1.1 christos 688 1.1 christos if (h -> type != dhcp_type_subnet) 689 1.1 christos return DHCP_R_INVALIDARG; 690 1.1 christos 691 1.1 christos /* Can't write subnets yet. */ 692 1.1 christos 693 1.1 christos /* Try to find some inner object that can take the value. */ 694 1.1 christos if (h -> inner && h -> inner -> type -> get_value) { 695 1.1 christos status = ((*(h -> inner -> type -> signal_handler)) 696 1.1 christos (h -> inner, name, ap)); 697 1.1 christos if (status == ISC_R_SUCCESS) 698 1.1 christos return status; 699 1.1 christos } 700 1.1 christos 701 1.1 christos return ISC_R_NOTFOUND; 702 1.1 christos } 703 1.1 christos 704 1.1 christos isc_result_t dhcp_subnet_stuff_values (omapi_object_t *c, 705 1.1 christos omapi_object_t *id, 706 1.1 christos omapi_object_t *h) 707 1.1 christos { 708 1.1 christos /* In this function h should be a (struct subnet *) */ 709 1.1 christos 710 1.1 christos isc_result_t status; 711 1.1 christos 712 1.1 christos if (h -> type != dhcp_type_subnet) 713 1.1 christos return DHCP_R_INVALIDARG; 714 1.1 christos 715 1.1 christos /* Can't stuff subnet values yet. */ 716 1.1 christos 717 1.1 christos /* Write out the inner object, if any. */ 718 1.1 christos if (h -> inner && h -> inner -> type -> stuff_values) { 719 1.1 christos status = ((*(h -> inner -> type -> stuff_values)) 720 1.1 christos (c, id, h -> inner)); 721 1.1 christos if (status == ISC_R_SUCCESS) 722 1.1 christos return status; 723 1.1 christos } 724 1.1 christos 725 1.1 christos return ISC_R_SUCCESS; 726 1.1 christos } 727 1.1 christos 728 1.1 christos isc_result_t dhcp_subnet_lookup (omapi_object_t **lp, 729 1.1 christos omapi_object_t *id, 730 1.1 christos omapi_object_t *ref) 731 1.1 christos { 732 1.1 christos /* Can't look up subnets yet. */ 733 1.1 christos 734 1.1 christos /* If we get to here without finding a subnet, no valid key was 735 1.1 christos specified. */ 736 1.1 christos if (!*lp) 737 1.1 christos return DHCP_R_NOKEYS; 738 1.1 christos return ISC_R_SUCCESS; 739 1.1 christos } 740 1.1 christos 741 1.1 christos isc_result_t dhcp_subnet_create (omapi_object_t **lp, 742 1.1 christos omapi_object_t *id) 743 1.1 christos { 744 1.1 christos return ISC_R_NOTIMPLEMENTED; 745 1.1 christos } 746 1.1 christos 747 1.1 christos isc_result_t dhcp_subnet_remove (omapi_object_t *lp, 748 1.1 christos omapi_object_t *id) 749 1.1 christos { 750 1.1 christos return ISC_R_NOTIMPLEMENTED; 751 1.1 christos } 752 1.1 christos 753 1.1 christos isc_result_t dhcp_shared_network_set_value (omapi_object_t *h, 754 1.1 christos omapi_object_t *id, 755 1.1 christos omapi_data_string_t *name, 756 1.1 christos omapi_typed_data_t *value) 757 1.1 christos { 758 1.1 christos /* In this function h should be a (struct shared_network *) */ 759 1.1 christos 760 1.1 christos isc_result_t status; 761 1.1 christos 762 1.1 christos if (h -> type != dhcp_type_shared_network) 763 1.1 christos return DHCP_R_INVALIDARG; 764 1.1 christos 765 1.1 christos /* No values to set yet. */ 766 1.1 christos 767 1.1 christos /* Try to find some inner object that can take the value. */ 768 1.1 christos if (h -> inner && h -> inner -> type -> set_value) { 769 1.1 christos status = ((*(h -> inner -> type -> set_value)) 770 1.1 christos (h -> inner, id, name, value)); 771 1.1 christos if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) 772 1.1 christos return status; 773 1.1 christos } 774 1.1 christos 775 1.1 christos return ISC_R_NOTFOUND; 776 1.1 christos } 777 1.1 christos 778 1.1 christos 779 1.1 christos isc_result_t dhcp_shared_network_get_value (omapi_object_t *h, 780 1.1 christos omapi_object_t *id, 781 1.1 christos omapi_data_string_t *name, 782 1.1 christos omapi_value_t **value) 783 1.1 christos { 784 1.1 christos /* In this function h should be a (struct shared_network *) */ 785 1.1 christos 786 1.1 christos isc_result_t status; 787 1.1 christos 788 1.1 christos if (h -> type != dhcp_type_shared_network) 789 1.1 christos return DHCP_R_INVALIDARG; 790 1.1 christos 791 1.1 christos /* No values to get yet. */ 792 1.1 christos 793 1.1 christos /* Try to find some inner object that can provide the value. */ 794 1.1 christos if (h -> inner && h -> inner -> type -> get_value) { 795 1.1 christos status = ((*(h -> inner -> type -> get_value)) 796 1.1 christos (h -> inner, id, name, value)); 797 1.1 christos if (status == ISC_R_SUCCESS) 798 1.1 christos return status; 799 1.1 christos } 800 1.1 christos return ISC_R_NOTFOUND; 801 1.1 christos } 802 1.1 christos 803 1.1 christos isc_result_t dhcp_shared_network_destroy (omapi_object_t *h, 804 1.1 christos const char *file, int line) 805 1.1 christos { 806 1.1 christos /* In this function h should be a (struct shared_network *) */ 807 1.1 christos 808 1.1 christos struct shared_network *shared_network; 809 1.1 christos 810 1.1 christos if (h -> type != dhcp_type_shared_network) 811 1.1 christos return DHCP_R_INVALIDARG; 812 1.1 christos 813 1.1 christos shared_network = (struct shared_network *)h; 814 1.1 christos if (shared_network -> next) 815 1.1 christos shared_network_dereference (&shared_network -> next, 816 1.1 christos file, line); 817 1.1 christos if (shared_network -> name) { 818 1.1 christos dfree (shared_network -> name, file, line); 819 1.1 christos shared_network -> name = 0; 820 1.1 christos } 821 1.1 christos if (shared_network -> subnets) 822 1.1 christos subnet_dereference (&shared_network -> subnets, file, line); 823 1.1 christos if (shared_network -> interface) 824 1.1 christos interface_dereference (&shared_network -> interface, 825 1.1 christos file, line); 826 1.1 christos if (shared_network -> pools) 827 1.1 christos omapi_object_dereference ((omapi_object_t **) 828 1.1 christos &shared_network -> pools, file, line); 829 1.1 christos if (shared_network -> group) 830 1.1 christos group_dereference (&shared_network -> group, file, line); 831 1.1 christos #if defined (FAILOVER_PROTOCOL) 832 1.1 christos if (shared_network -> failover_peer) 833 1.1 christos omapi_object_dereference ((omapi_object_t **) 834 1.1 christos &shared_network -> failover_peer, 835 1.1 christos file, line); 836 1.1 christos #endif 837 1.1 christos 838 1.1 christos return ISC_R_SUCCESS; 839 1.1 christos } 840 1.1 christos 841 1.1 christos isc_result_t dhcp_shared_network_signal_handler (omapi_object_t *h, 842 1.1 christos const char *name, 843 1.1 christos va_list ap) 844 1.1 christos { 845 1.1 christos /* In this function h should be a (struct shared_network *) */ 846 1.1 christos 847 1.1 christos isc_result_t status; 848 1.1 christos 849 1.1 christos if (h -> type != dhcp_type_shared_network) 850 1.1 christos return DHCP_R_INVALIDARG; 851 1.1 christos 852 1.1 christos /* Can't write shared_networks yet. */ 853 1.1 christos 854 1.1 christos /* Try to find some inner object that can take the value. */ 855 1.1 christos if (h -> inner && h -> inner -> type -> get_value) { 856 1.1 christos status = ((*(h -> inner -> type -> signal_handler)) 857 1.1 christos (h -> inner, name, ap)); 858 1.1 christos if (status == ISC_R_SUCCESS) 859 1.1 christos return status; 860 1.1 christos } 861 1.1 christos 862 1.1 christos return ISC_R_NOTFOUND; 863 1.1 christos } 864 1.1 christos 865 1.1 christos isc_result_t dhcp_shared_network_stuff_values (omapi_object_t *c, 866 1.1 christos omapi_object_t *id, 867 1.1 christos omapi_object_t *h) 868 1.1 christos { 869 1.1 christos /* In this function h should be a (struct shared_network *) */ 870 1.1 christos 871 1.1 christos isc_result_t status; 872 1.1 christos 873 1.1 christos if (h -> type != dhcp_type_shared_network) 874 1.1 christos return DHCP_R_INVALIDARG; 875 1.1 christos 876 1.1 christos /* Can't stuff shared_network values yet. */ 877 1.1 christos 878 1.1 christos /* Write out the inner object, if any. */ 879 1.1 christos if (h -> inner && h -> inner -> type -> stuff_values) { 880 1.1 christos status = ((*(h -> inner -> type -> stuff_values)) 881 1.1 christos (c, id, h -> inner)); 882 1.1 christos if (status == ISC_R_SUCCESS) 883 1.1 christos return status; 884 1.1 christos } 885 1.1 christos 886 1.1 christos return ISC_R_SUCCESS; 887 1.1 christos } 888 1.1 christos 889 1.1 christos isc_result_t dhcp_shared_network_lookup (omapi_object_t **lp, 890 1.1 christos omapi_object_t *id, 891 1.1 christos omapi_object_t *ref) 892 1.1 christos { 893 1.1 christos /* Can't look up shared_networks yet. */ 894 1.1 christos 895 1.1 christos /* If we get to here without finding a shared_network, no valid key was 896 1.1 christos specified. */ 897 1.1 christos if (!*lp) 898 1.1 christos return DHCP_R_NOKEYS; 899 1.1 christos return ISC_R_SUCCESS; 900 1.1 christos } 901 1.1 christos 902 1.1 christos isc_result_t dhcp_shared_network_create (omapi_object_t **lp, 903 1.1 christos omapi_object_t *id) 904 1.1 christos { 905 1.1 christos return ISC_R_NOTIMPLEMENTED; 906 1.1 christos } 907 1.1 christos 908 1.1 christos isc_result_t dhcp_shared_network_remove (omapi_object_t *lp, 909 1.1 christos omapi_object_t *id) 910 1.1 christos { 911 1.1 christos return ISC_R_NOTIMPLEMENTED; 912 1.1 christos } 913