00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "dhcpd.h"
00038 #include <omapip/omapip_p.h>
00039
00040 static isc_result_t class_lookup (omapi_object_t **,
00041 omapi_object_t *, omapi_object_t *,
00042 omapi_object_type_t *);
00043
00044 omapi_object_type_t *dhcp_type_lease;
00045 omapi_object_type_t *dhcp_type_pool;
00046 omapi_object_type_t *dhcp_type_class;
00047 omapi_object_type_t *dhcp_type_subclass;
00048 omapi_object_type_t *dhcp_type_host;
00049 #if defined (FAILOVER_PROTOCOL)
00050 omapi_object_type_t *dhcp_type_failover_state;
00051 omapi_object_type_t *dhcp_type_failover_link;
00052 omapi_object_type_t *dhcp_type_failover_listener;
00053 #endif
00054
00055 void dhcp_db_objects_setup ()
00056 {
00057 isc_result_t status;
00058
00059 status = omapi_object_type_register (&dhcp_type_lease,
00060 "lease",
00061 dhcp_lease_set_value,
00062 dhcp_lease_get_value,
00063 dhcp_lease_destroy,
00064 dhcp_lease_signal_handler,
00065 dhcp_lease_stuff_values,
00066 dhcp_lease_lookup,
00067 dhcp_lease_create,
00068 dhcp_lease_remove,
00069 #if defined (COMPACT_LEASES)
00070 dhcp_lease_free,
00071 dhcp_lease_get,
00072 #else
00073 0, 0,
00074 #endif
00075 0,
00076 sizeof (struct lease),
00077 0, RC_LEASE);
00078 if (status != ISC_R_SUCCESS)
00079 log_fatal ("Can't register lease object type: %s",
00080 isc_result_totext (status));
00081
00082 status = omapi_object_type_register (&dhcp_type_class,
00083 "class",
00084 dhcp_class_set_value,
00085 dhcp_class_get_value,
00086 dhcp_class_destroy,
00087 dhcp_class_signal_handler,
00088 dhcp_class_stuff_values,
00089 dhcp_class_lookup,
00090 dhcp_class_create,
00091 dhcp_class_remove, 0, 0, 0,
00092 sizeof (struct class), 0,
00093 RC_MISC);
00094 if (status != ISC_R_SUCCESS)
00095 log_fatal ("Can't register class object type: %s",
00096 isc_result_totext (status));
00097
00098 status = omapi_object_type_register (&dhcp_type_subclass,
00099 "subclass",
00100 dhcp_subclass_set_value,
00101 dhcp_subclass_get_value,
00102 dhcp_class_destroy,
00103 dhcp_subclass_signal_handler,
00104 dhcp_subclass_stuff_values,
00105 dhcp_subclass_lookup,
00106 dhcp_subclass_create,
00107 dhcp_subclass_remove, 0, 0, 0,
00108 sizeof (struct class), 0, RC_MISC);
00109 if (status != ISC_R_SUCCESS)
00110 log_fatal ("Can't register subclass object type: %s",
00111 isc_result_totext (status));
00112
00113 status = omapi_object_type_register (&dhcp_type_pool,
00114 "pool",
00115 dhcp_pool_set_value,
00116 dhcp_pool_get_value,
00117 dhcp_pool_destroy,
00118 dhcp_pool_signal_handler,
00119 dhcp_pool_stuff_values,
00120 dhcp_pool_lookup,
00121 dhcp_pool_create,
00122 dhcp_pool_remove, 0, 0, 0,
00123 sizeof (struct pool), 0, RC_MISC);
00124
00125 if (status != ISC_R_SUCCESS)
00126 log_fatal ("Can't register pool object type: %s",
00127 isc_result_totext (status));
00128
00129 status = omapi_object_type_register (&dhcp_type_host,
00130 "host",
00131 dhcp_host_set_value,
00132 dhcp_host_get_value,
00133 dhcp_host_destroy,
00134 dhcp_host_signal_handler,
00135 dhcp_host_stuff_values,
00136 dhcp_host_lookup,
00137 dhcp_host_create,
00138 dhcp_host_remove, 0, 0, 0,
00139 sizeof (struct host_decl),
00140 0, RC_MISC);
00141
00142 if (status != ISC_R_SUCCESS)
00143 log_fatal ("Can't register host object type: %s",
00144 isc_result_totext (status));
00145
00146 #if defined (FAILOVER_PROTOCOL)
00147 status = omapi_object_type_register (&dhcp_type_failover_state,
00148 "failover-state",
00149 dhcp_failover_state_set_value,
00150 dhcp_failover_state_get_value,
00151 dhcp_failover_state_destroy,
00152 dhcp_failover_state_signal,
00153 dhcp_failover_state_stuff,
00154 dhcp_failover_state_lookup,
00155 dhcp_failover_state_create,
00156 dhcp_failover_state_remove,
00157 0, 0, 0,
00158 sizeof (dhcp_failover_state_t),
00159 0, RC_MISC);
00160
00161 if (status != ISC_R_SUCCESS)
00162 log_fatal ("Can't register failover state object type: %s",
00163 isc_result_totext (status));
00164
00165 status = omapi_object_type_register (&dhcp_type_failover_link,
00166 "failover-link",
00167 dhcp_failover_link_set_value,
00168 dhcp_failover_link_get_value,
00169 dhcp_failover_link_destroy,
00170 dhcp_failover_link_signal,
00171 dhcp_failover_link_stuff_values,
00172 0, 0, 0, 0, 0, 0,
00173 sizeof (dhcp_failover_link_t), 0,
00174 RC_MISC);
00175
00176 if (status != ISC_R_SUCCESS)
00177 log_fatal ("Can't register failover link object type: %s",
00178 isc_result_totext (status));
00179
00180 status = omapi_object_type_register (&dhcp_type_failover_listener,
00181 "failover-listener",
00182 dhcp_failover_listener_set_value,
00183 dhcp_failover_listener_get_value,
00184 dhcp_failover_listener_destroy,
00185 dhcp_failover_listener_signal,
00186 dhcp_failover_listener_stuff,
00187 0, 0, 0, 0, 0, 0,
00188 sizeof
00189 (dhcp_failover_listener_t), 0,
00190 RC_MISC);
00191
00192 if (status != ISC_R_SUCCESS)
00193 log_fatal ("Can't register failover listener object type: %s",
00194 isc_result_totext (status));
00195 #endif
00196 }
00197
00198 isc_result_t dhcp_lease_set_value (omapi_object_t *h,
00199 omapi_object_t *id,
00200 omapi_data_string_t *name,
00201 omapi_typed_data_t *value)
00202 {
00203 struct lease *lease;
00204 isc_result_t status;
00205
00206 if (h -> type != dhcp_type_lease)
00207 return DHCP_R_INVALIDARG;
00208 lease = (struct lease *)h;
00209
00210
00211
00212 if (!omapi_ds_strcmp (name, "state")) {
00213 unsigned long bar;
00214 const char *ols, *nls;
00215 status = omapi_get_int_value (&bar, value);
00216 if (status != ISC_R_SUCCESS)
00217 return status;
00218
00219 if (bar < 1 || bar > FTS_LAST)
00220 return DHCP_R_INVALIDARG;
00221 nls = binding_state_names [bar - 1];
00222 if (lease -> binding_state >= 1 &&
00223 lease -> binding_state <= FTS_LAST)
00224 ols = binding_state_names [lease -> binding_state - 1];
00225 else
00226 ols = "unknown state";
00227
00228 if (lease -> binding_state != bar) {
00229 lease -> next_binding_state = bar;
00230 if (supersede_lease (lease, 0, 1, 1, 1)) {
00231 log_info ("lease %s state changed from %s to %s",
00232 piaddr(lease->ip_addr), ols, nls);
00233 return ISC_R_SUCCESS;
00234 }
00235 log_info ("lease %s state change from %s to %s failed.",
00236 piaddr (lease -> ip_addr), ols, nls);
00237 return ISC_R_IOERROR;
00238 }
00239 return DHCP_R_UNCHANGED;
00240 } else if (!omapi_ds_strcmp (name, "ip-address")) {
00241 return ISC_R_NOPERM;
00242 } else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
00243 return DHCP_R_UNCHANGED;
00244 } else if (!omapi_ds_strcmp (name, "hostname")) {
00245 return DHCP_R_UNCHANGED;
00246 } else if (!omapi_ds_strcmp (name, "client-hostname")) {
00247 return DHCP_R_UNCHANGED;
00248 } else if (!omapi_ds_strcmp (name, "host")) {
00249 return DHCP_R_UNCHANGED;
00250 } else if (!omapi_ds_strcmp (name, "subnet")) {
00251 return DHCP_R_INVALIDARG;
00252 } else if (!omapi_ds_strcmp (name, "pool")) {
00253 return ISC_R_NOPERM;
00254 } else if (!omapi_ds_strcmp (name, "starts")) {
00255 return ISC_R_NOPERM;
00256 } else if (!omapi_ds_strcmp (name, "ends")) {
00257 unsigned long lease_end, old_lease_end;
00258 status = omapi_get_int_value (&lease_end, value);
00259 if (status != ISC_R_SUCCESS)
00260 return status;
00261 old_lease_end = lease->ends;
00262 lease->ends = lease_end;
00263 if (supersede_lease (lease, 0, 1, 1, 1)) {
00264 log_info ("lease %s end changed from %lu to %lu",
00265 piaddr(lease->ip_addr), old_lease_end, lease_end);
00266 return ISC_R_SUCCESS;
00267 }
00268 log_info ("lease %s end change from %lu to %lu failed",
00269 piaddr(lease->ip_addr), old_lease_end, lease_end);
00270 return ISC_R_IOERROR;
00271 } else if (!omapi_ds_strcmp(name, "flags")) {
00272 u_int8_t oldflags;
00273
00274 if (value->type != omapi_datatype_data)
00275 return DHCP_R_INVALIDARG;
00276
00277 oldflags = lease->flags;
00278 lease->flags = (value->u.buffer.value[0] & EPHEMERAL_FLAGS) |
00279 (lease->flags & ~EPHEMERAL_FLAGS);
00280 if(oldflags == lease->flags)
00281 return ISC_R_SUCCESS;
00282 if (!supersede_lease(lease, NULL, 1, 1, 1)) {
00283 log_error("Failed to update flags for lease %s.",
00284 piaddr(lease->ip_addr));
00285 return ISC_R_IOERROR;
00286 }
00287 return ISC_R_SUCCESS;
00288 } else if (!omapi_ds_strcmp (name, "billing-class")) {
00289 return DHCP_R_UNCHANGED;
00290 } else if (!omapi_ds_strcmp (name, "hardware-address")) {
00291 return DHCP_R_UNCHANGED;
00292 } else if (!omapi_ds_strcmp (name, "hardware-type")) {
00293 return DHCP_R_UNCHANGED;
00294 } else if (lease -> scope) {
00295 status = binding_scope_set_value (lease -> scope, 0, name, value);
00296 if (status == ISC_R_SUCCESS) {
00297 if (write_lease (lease) && commit_leases ())
00298 return ISC_R_SUCCESS;
00299 return ISC_R_IOERROR;
00300 }
00301 }
00302
00303
00304 if (h -> inner && h -> inner -> type -> set_value) {
00305 status = ((*(h -> inner -> type -> set_value))
00306 (h -> inner, id, name, value));
00307 if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
00308 return status;
00309 }
00310
00311 if (!lease -> scope) {
00312 if (!binding_scope_allocate (&lease -> scope, MDL))
00313 return ISC_R_NOMEMORY;
00314 }
00315 status = binding_scope_set_value (lease -> scope, 1, name, value);
00316 if (status != ISC_R_SUCCESS)
00317 return status;
00318
00319 if (write_lease (lease) && commit_leases ())
00320 return ISC_R_SUCCESS;
00321 return ISC_R_IOERROR;
00322 }
00323
00324
00325 isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id,
00326 omapi_data_string_t *name,
00327 omapi_value_t **value)
00328 {
00329 struct lease *lease;
00330 isc_result_t status;
00331
00332 if (h -> type != dhcp_type_lease)
00333 return DHCP_R_INVALIDARG;
00334 lease = (struct lease *)h;
00335
00336 if (!omapi_ds_strcmp (name, "state"))
00337 return omapi_make_int_value (value, name,
00338 (int)lease -> binding_state, MDL);
00339 else if (!omapi_ds_strcmp (name, "ip-address"))
00340 return omapi_make_const_value (value, name,
00341 lease -> ip_addr.iabuf,
00342 lease -> ip_addr.len, MDL);
00343 else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
00344 return omapi_make_const_value (value, name,
00345 lease -> uid,
00346 lease -> uid_len, MDL);
00347 } else if (!omapi_ds_strcmp (name, "client-hostname")) {
00348 if (lease -> client_hostname)
00349 return omapi_make_string_value
00350 (value, name, lease -> client_hostname, MDL);
00351 return ISC_R_NOTFOUND;
00352 } else if (!omapi_ds_strcmp (name, "host")) {
00353 if (lease -> host)
00354 return omapi_make_handle_value
00355 (value, name,
00356 ((omapi_object_t *)lease -> host), MDL);
00357 } else if (!omapi_ds_strcmp (name, "subnet"))
00358 return omapi_make_handle_value (value, name,
00359 ((omapi_object_t *)
00360 lease -> subnet), MDL);
00361 else if (!omapi_ds_strcmp (name, "pool"))
00362 return omapi_make_handle_value (value, name,
00363 ((omapi_object_t *)
00364 lease -> pool), MDL);
00365 else if (!omapi_ds_strcmp (name, "billing-class")) {
00366 if (lease -> billing_class)
00367 return omapi_make_handle_value
00368 (value, name,
00369 ((omapi_object_t *)lease -> billing_class),
00370 MDL);
00371 return ISC_R_NOTFOUND;
00372 } else if (!omapi_ds_strcmp (name, "hardware-address")) {
00373 if (lease -> hardware_addr.hlen)
00374 return omapi_make_const_value
00375 (value, name, &lease -> hardware_addr.hbuf [1],
00376 (unsigned)(lease -> hardware_addr.hlen - 1),
00377 MDL);
00378 return ISC_R_NOTFOUND;
00379 } else if (!omapi_ds_strcmp (name, "hardware-type")) {
00380 if (lease -> hardware_addr.hlen)
00381 return omapi_make_int_value
00382 (value, name, lease -> hardware_addr.hbuf [0],
00383 MDL);
00384 return ISC_R_NOTFOUND;
00385 } else if (lease -> scope) {
00386 status = binding_scope_get_value (value, lease -> scope, name);
00387 if (status != ISC_R_NOTFOUND)
00388 return status;
00389 }
00390
00391
00392 if (h -> inner && h -> inner -> type -> get_value) {
00393 status = ((*(h -> inner -> type -> get_value))
00394 (h -> inner, id, name, value));
00395 if (status == ISC_R_SUCCESS)
00396 return status;
00397 }
00398 return DHCP_R_UNKNOWNATTRIBUTE;
00399 }
00400
00401 isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line)
00402 {
00403 struct lease *lease;
00404
00405 if (h->type != dhcp_type_lease)
00406 return DHCP_R_INVALIDARG;
00407 lease = (struct lease *)h;
00408
00409 if (lease-> uid)
00410 uid_hash_delete (lease);
00411 hw_hash_delete (lease);
00412
00413 if (lease->on_star.on_release)
00414 executable_statement_dereference (&lease->on_star.on_release,
00415 file, line);
00416 if (lease->on_star.on_expiry)
00417 executable_statement_dereference (&lease->on_star.on_expiry,
00418 file, line);
00419 if (lease->on_star.on_commit)
00420 executable_statement_dereference (&lease->on_star.on_commit,
00421 file, line);
00422 if (lease->scope)
00423 binding_scope_dereference (&lease->scope, file, line);
00424
00425 if (lease->agent_options)
00426 option_chain_head_dereference (&lease->agent_options,
00427 file, line);
00428 if (lease->uid && lease->uid != lease->uid_buf) {
00429 dfree (lease->uid, MDL);
00430 lease->uid = &lease->uid_buf [0];
00431 lease->uid_len = 0;
00432 }
00433
00434 if (lease->client_hostname) {
00435 dfree (lease->client_hostname, MDL);
00436 lease->client_hostname = (char *)0;
00437 }
00438
00439 if (lease->host)
00440 host_dereference (&lease->host, file, line);
00441 if (lease->subnet)
00442 subnet_dereference (&lease->subnet, file, line);
00443 if (lease->pool)
00444 pool_dereference (&lease->pool, file, line);
00445
00446 if (lease->state) {
00447 free_lease_state (lease->state, file, line);
00448 lease->state = (struct lease_state *)0;
00449
00450 cancel_timeout (lease_ping_timeout, lease);
00451 --outstanding_pings;
00452 }
00453
00454 if (lease->billing_class)
00455 class_dereference
00456 (&lease->billing_class, file, line);
00457
00458 #if defined (DEBUG_MEMORY_LEAKAGE) || \
00459 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
00460
00461
00462 if (lease->next)
00463 lease_dereference (&lease->next, file, line);
00464 if (lease->n_hw)
00465 lease_dereference (&lease->n_hw, file, line);
00466 if (lease->n_uid)
00467 lease_dereference (&lease->n_uid, file, line);
00468 if (lease->next_pending)
00469 lease_dereference (&lease->next_pending, file, line);
00470 #endif
00471
00472 return ISC_R_SUCCESS;
00473 }
00474
00475 isc_result_t dhcp_lease_signal_handler (omapi_object_t *h,
00476 const char *name, va_list ap)
00477 {
00478
00479 isc_result_t status;
00480
00481 if (h -> type != dhcp_type_lease)
00482 return DHCP_R_INVALIDARG;
00483
00484 if (!strcmp (name, "updated"))
00485 return ISC_R_SUCCESS;
00486
00487
00488 if (h -> inner && h -> inner -> type -> signal_handler) {
00489 status = ((*(h -> inner -> type -> signal_handler))
00490 (h -> inner, name, ap));
00491 if (status == ISC_R_SUCCESS)
00492 return status;
00493 }
00494 return ISC_R_NOTFOUND;
00495 }
00496
00497 isc_result_t dhcp_lease_stuff_values (omapi_object_t *c,
00498 omapi_object_t *id,
00499 omapi_object_t *h)
00500 {
00501 u_int32_t bouncer;
00502 struct lease *lease;
00503 isc_result_t status;
00504 u_int8_t flagbuf;
00505
00506 if (h -> type != dhcp_type_lease)
00507 return DHCP_R_INVALIDARG;
00508 lease = (struct lease *)h;
00509
00510
00511
00512 status = omapi_connection_put_named_uint32(c, "state",
00513 lease->binding_state);
00514 if (status != ISC_R_SUCCESS)
00515 return (status);
00516
00517 status = omapi_connection_put_name (c, "ip-address");
00518 if (status != ISC_R_SUCCESS)
00519 return status;
00520 status = omapi_connection_put_uint32 (c, lease -> ip_addr.len);
00521 if (status != ISC_R_SUCCESS)
00522 return status;
00523 status = omapi_connection_copyin (c, lease -> ip_addr.iabuf,
00524 lease -> ip_addr.len);
00525 if (status != ISC_R_SUCCESS)
00526 return status;
00527
00528 if (lease -> uid_len) {
00529 status = omapi_connection_put_name (c,
00530 "dhcp-client-identifier");
00531 if (status != ISC_R_SUCCESS)
00532 return status;
00533 status = omapi_connection_put_uint32 (c, lease -> uid_len);
00534 if (status != ISC_R_SUCCESS)
00535 return status;
00536 if (lease -> uid_len) {
00537 status = omapi_connection_copyin (c, lease -> uid,
00538 lease -> uid_len);
00539 if (status != ISC_R_SUCCESS)
00540 return status;
00541 }
00542 }
00543
00544 if (lease -> client_hostname) {
00545 status = omapi_connection_put_name (c, "client-hostname");
00546 if (status != ISC_R_SUCCESS)
00547 return status;
00548 status =
00549 omapi_connection_put_string (c,
00550 lease -> client_hostname);
00551 if (status != ISC_R_SUCCESS)
00552 return status;
00553 }
00554
00555 if (lease -> host) {
00556 status = omapi_connection_put_name (c, "host");
00557 if (status != ISC_R_SUCCESS)
00558 return status;
00559 status = omapi_connection_put_handle (c,
00560 (omapi_object_t *)
00561 lease -> host);
00562 if (status != ISC_R_SUCCESS)
00563 return status;
00564 }
00565
00566 status = omapi_connection_put_name (c, "subnet");
00567 if (status != ISC_R_SUCCESS)
00568 return status;
00569 status = omapi_connection_put_handle
00570 (c, (omapi_object_t *)lease -> subnet);
00571 if (status != ISC_R_SUCCESS)
00572 return status;
00573
00574 status = omapi_connection_put_name (c, "pool");
00575 if (status != ISC_R_SUCCESS)
00576 return status;
00577 status = omapi_connection_put_handle (c,
00578 (omapi_object_t *)lease -> pool);
00579 if (status != ISC_R_SUCCESS)
00580 return status;
00581
00582 if (lease -> billing_class) {
00583 status = omapi_connection_put_name (c, "billing-class");
00584 if (status != ISC_R_SUCCESS)
00585 return status;
00586 status = omapi_connection_put_handle
00587 (c, (omapi_object_t *)lease -> billing_class);
00588 if (status != ISC_R_SUCCESS)
00589 return status;
00590 }
00591
00592 if (lease -> hardware_addr.hlen) {
00593 status = omapi_connection_put_name (c, "hardware-address");
00594 if (status != ISC_R_SUCCESS)
00595 return status;
00596 status = (omapi_connection_put_uint32
00597 (c,
00598 (unsigned long)(lease -> hardware_addr.hlen - 1)));
00599 if (status != ISC_R_SUCCESS)
00600 return status;
00601 status = (omapi_connection_copyin
00602 (c, &lease -> hardware_addr.hbuf [1],
00603 (unsigned long)(lease -> hardware_addr.hlen - 1)));
00604
00605 if (status != ISC_R_SUCCESS)
00606 return status;
00607
00608 status = omapi_connection_put_named_uint32(c, "hardware-type",
00609 lease->hardware_addr.hbuf[0]);
00610 if (status != ISC_R_SUCCESS)
00611 return (status);
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 bouncer = (u_int32_t)lease->ends;
00625 status = omapi_connection_put_named_uint32(c, "ends", bouncer);
00626 if (status != ISC_R_SUCCESS)
00627 return (status);
00628
00629 bouncer = (u_int32_t)lease->starts;
00630 status = omapi_connection_put_named_uint32(c, "starts", bouncer);
00631 if (status != ISC_R_SUCCESS)
00632 return (status);
00633
00634 bouncer = (u_int32_t)lease->tstp;
00635 status = omapi_connection_put_named_uint32(c, "tstp", bouncer);
00636 if (status != ISC_R_SUCCESS)
00637 return (status);
00638
00639 bouncer = (u_int32_t)lease->tsfp;
00640 status = omapi_connection_put_named_uint32(c, "tsfp", bouncer);
00641 if (status != ISC_R_SUCCESS)
00642 return status;
00643
00644 bouncer = (u_int32_t)lease->atsfp;
00645 status = omapi_connection_put_named_uint32(c, "atsfp", bouncer);
00646 if (status != ISC_R_SUCCESS)
00647 return status;
00648
00649 bouncer = (u_int32_t)lease->cltt;
00650 status = omapi_connection_put_named_uint32(c, "cltt", bouncer);
00651 if (status != ISC_R_SUCCESS)
00652 return status;
00653
00654 status = omapi_connection_put_name (c, "flags");
00655 if (status != ISC_R_SUCCESS)
00656 return status;
00657 status = omapi_connection_put_uint32(c, sizeof(flagbuf));
00658 if (status != ISC_R_SUCCESS)
00659 return status;
00660 flagbuf = lease->flags & EPHEMERAL_FLAGS;
00661 status = omapi_connection_copyin(c, &flagbuf, sizeof(flagbuf));
00662 if (status != ISC_R_SUCCESS)
00663 return status;
00664
00665 if (lease -> scope) {
00666 status = binding_scope_stuff_values (c, lease -> scope);
00667 if (status != ISC_R_SUCCESS)
00668 return status;
00669 }
00670
00671
00672 if (h -> inner && h -> inner -> type -> stuff_values) {
00673 status = ((*(h -> inner -> type -> stuff_values))
00674 (c, id, h -> inner));
00675 if (status == ISC_R_SUCCESS)
00676 return status;
00677 }
00678
00679 return ISC_R_SUCCESS;
00680 }
00681
00682 isc_result_t dhcp_lease_lookup (omapi_object_t **lp,
00683 omapi_object_t *id, omapi_object_t *ref)
00684 {
00685 omapi_value_t *tv = (omapi_value_t *)0;
00686 isc_result_t status;
00687 struct lease *lease;
00688
00689 if (!ref)
00690 return DHCP_R_NOKEYS;
00691
00692
00693 status = omapi_get_value_str (ref, id, "handle", &tv);
00694 if (status == ISC_R_SUCCESS) {
00695 status = omapi_handle_td_lookup (lp, tv -> value);
00696
00697 omapi_value_dereference (&tv, MDL);
00698 if (status != ISC_R_SUCCESS)
00699 return status;
00700
00701
00702 if ((*lp) -> type != dhcp_type_lease) {
00703 omapi_object_dereference (lp, MDL);
00704 return DHCP_R_INVALIDARG;
00705 }
00706 }
00707
00708
00709 status = omapi_get_value_str (ref, id, "ip-address", &tv);
00710 if (status == ISC_R_SUCCESS) {
00711 lease = (struct lease *)0;
00712 lease_ip_hash_lookup(&lease, lease_ip_addr_hash,
00713 tv->value->u.buffer.value,
00714 tv->value->u.buffer.len, MDL);
00715
00716 omapi_value_dereference (&tv, MDL);
00717
00718
00719
00720 if (*lp && *lp != (omapi_object_t *)lease) {
00721 omapi_object_dereference (lp, MDL);
00722 lease_dereference (&lease, MDL);
00723 return DHCP_R_KEYCONFLICT;
00724 } else if (!lease) {
00725 if (*lp)
00726 omapi_object_dereference (lp, MDL);
00727 return ISC_R_NOTFOUND;
00728 } else if (!*lp) {
00729
00730
00731 omapi_object_reference (lp,
00732 (omapi_object_t *)lease, MDL);
00733 lease_dereference (&lease, MDL);
00734 }
00735 }
00736
00737
00738 status = omapi_get_value_str (ref, id, "dhcp-client-identifier", &tv);
00739 if (status == ISC_R_SUCCESS) {
00740 lease = (struct lease *)0;
00741 lease_id_hash_lookup(&lease, lease_uid_hash,
00742 tv->value->u.buffer.value,
00743 tv->value->u.buffer.len, MDL);
00744 omapi_value_dereference (&tv, MDL);
00745
00746 if (*lp && *lp != (omapi_object_t *)lease) {
00747 omapi_object_dereference (lp, MDL);
00748 lease_dereference (&lease, MDL);
00749 return DHCP_R_KEYCONFLICT;
00750 } else if (!lease) {
00751 if (*lp)
00752 omapi_object_dereference (lp, MDL);
00753 return ISC_R_NOTFOUND;
00754 } else if (lease -> n_uid) {
00755 if (*lp)
00756 omapi_object_dereference (lp, MDL);
00757 return DHCP_R_MULTIPLE;
00758 } else if (!*lp) {
00759
00760
00761 omapi_object_reference (lp,
00762 (omapi_object_t *)lease, MDL);
00763 lease_dereference (&lease, MDL);
00764 }
00765 }
00766
00767
00768 status = omapi_get_value_str (ref, id, "hardware-address", &tv);
00769 if (status == ISC_R_SUCCESS) {
00770 unsigned char *haddr;
00771 unsigned int len;
00772
00773 len = tv -> value -> u.buffer.len + 1;
00774 haddr = dmalloc (len, MDL);
00775 if (!haddr) {
00776 omapi_value_dereference (&tv, MDL);
00777 return ISC_R_NOMEMORY;
00778 }
00779
00780 memcpy (haddr + 1, tv -> value -> u.buffer.value, len - 1);
00781 omapi_value_dereference (&tv, MDL);
00782
00783 status = omapi_get_value_str (ref, id, "hardware-type", &tv);
00784 if (status == ISC_R_SUCCESS) {
00785 if (tv -> value -> type == omapi_datatype_data) {
00786 if ((tv -> value -> u.buffer.len != 4) ||
00787 (tv -> value -> u.buffer.value[0] != 0) ||
00788 (tv -> value -> u.buffer.value[1] != 0) ||
00789 (tv -> value -> u.buffer.value[2] != 0)) {
00790 omapi_value_dereference (&tv, MDL);
00791 dfree (haddr, MDL);
00792 return DHCP_R_INVALIDARG;
00793 }
00794
00795 haddr[0] = tv -> value -> u.buffer.value[3];
00796 } else if (tv -> value -> type == omapi_datatype_int) {
00797 haddr[0] = (unsigned char)
00798 tv -> value -> u.integer;
00799 } else {
00800 omapi_value_dereference (&tv, MDL);
00801 dfree (haddr, MDL);
00802 return DHCP_R_INVALIDARG;
00803 }
00804
00805 omapi_value_dereference (&tv, MDL);
00806 } else {
00807
00808
00809
00810
00811 haddr[0] = HTYPE_ETHER;
00812 }
00813
00814 lease = (struct lease *)0;
00815 lease_id_hash_lookup(&lease, lease_hw_addr_hash, haddr, len,
00816 MDL);
00817 dfree (haddr, MDL);
00818
00819 if (*lp && *lp != (omapi_object_t *)lease) {
00820 omapi_object_dereference (lp, MDL);
00821 lease_dereference (&lease, MDL);
00822 return DHCP_R_KEYCONFLICT;
00823 } else if (!lease) {
00824 if (*lp)
00825 omapi_object_dereference (lp, MDL);
00826 return ISC_R_NOTFOUND;
00827 } else if (lease -> n_hw) {
00828 if (*lp)
00829 omapi_object_dereference (lp, MDL);
00830 lease_dereference (&lease, MDL);
00831 return DHCP_R_MULTIPLE;
00832 } else if (!*lp) {
00833
00834
00835 omapi_object_reference (lp,
00836 (omapi_object_t *)lease, MDL);
00837 lease_dereference (&lease, MDL);
00838 }
00839 }
00840
00841
00842
00843 if (!*lp)
00844 return DHCP_R_NOKEYS;
00845 return ISC_R_SUCCESS;
00846 }
00847
00848 isc_result_t dhcp_lease_create (omapi_object_t **lp,
00849 omapi_object_t *id)
00850 {
00851 return ISC_R_NOTIMPLEMENTED;
00852 }
00853
00854 isc_result_t dhcp_lease_remove (omapi_object_t *lp,
00855 omapi_object_t *id)
00856 {
00857 return ISC_R_NOTIMPLEMENTED;
00858 }
00859
00860 isc_result_t dhcp_host_set_value (omapi_object_t *h,
00861 omapi_object_t *id,
00862 omapi_data_string_t *name,
00863 omapi_typed_data_t *value)
00864 {
00865 struct host_decl *host;
00866 isc_result_t status;
00867
00868 if (h -> type != dhcp_type_host)
00869 return DHCP_R_INVALIDARG;
00870 host = (struct host_decl *)h;
00871
00872
00873
00874 if (!omapi_ds_strcmp (name, "name")) {
00875 if (host -> name)
00876 return ISC_R_EXISTS;
00877 if (value && (value -> type == omapi_datatype_data ||
00878 value -> type == omapi_datatype_string)) {
00879 host -> name = dmalloc (value -> u.buffer.len + 1,
00880 MDL);
00881 if (!host -> name)
00882 return ISC_R_NOMEMORY;
00883 memcpy (host -> name,
00884 value -> u.buffer.value,
00885 value -> u.buffer.len);
00886 host -> name [value -> u.buffer.len] = 0;
00887 } else
00888 return DHCP_R_INVALIDARG;
00889 return ISC_R_SUCCESS;
00890 }
00891
00892 if (!omapi_ds_strcmp (name, "group")) {
00893 if (value && (value -> type == omapi_datatype_data ||
00894 value -> type == omapi_datatype_string)) {
00895 struct group_object *group;
00896 group = (struct group_object *)0;
00897 group_hash_lookup (&group, group_name_hash,
00898 (char *)value -> u.buffer.value,
00899 value -> u.buffer.len, MDL);
00900 if (!group || (group -> flags & GROUP_OBJECT_DELETED))
00901 return ISC_R_NOTFOUND;
00902 if (host -> group)
00903 group_dereference (&host -> group, MDL);
00904 group_reference (&host -> group, group -> group, MDL);
00905 if (host -> named_group)
00906 group_object_dereference (&host -> named_group,
00907 MDL);
00908 group_object_reference (&host -> named_group,
00909 group, MDL);
00910 group_object_dereference (&group, MDL);
00911 } else
00912 return DHCP_R_INVALIDARG;
00913 return ISC_R_SUCCESS;
00914 }
00915
00916 if (!omapi_ds_strcmp (name, "hardware-address")) {
00917 if (host -> interface.hlen)
00918 return ISC_R_EXISTS;
00919 if (value && (value -> type == omapi_datatype_data ||
00920 value -> type == omapi_datatype_string)) {
00921 if (value -> u.buffer.len >
00922 (sizeof host -> interface.hbuf) - 1)
00923 return DHCP_R_INVALIDARG;
00924 memcpy (&host -> interface.hbuf [1],
00925 value -> u.buffer.value,
00926 value -> u.buffer.len);
00927 host -> interface.hlen = value -> u.buffer.len + 1;
00928 } else
00929 return DHCP_R_INVALIDARG;
00930 return ISC_R_SUCCESS;
00931 }
00932
00933 if (!omapi_ds_strcmp (name, "hardware-type")) {
00934 int type;
00935 if ((value != NULL) &&
00936 ((value->type == omapi_datatype_data) &&
00937 (value->u.buffer.len == sizeof(type)))) {
00938 if (value->u.buffer.len > sizeof(type))
00939 return (DHCP_R_INVALIDARG);
00940 memcpy(&type, value->u.buffer.value,
00941 value->u.buffer.len);
00942 type = ntohl(type);
00943 } else if ((value != NULL) &&
00944 (value->type == omapi_datatype_int))
00945 type = value->u.integer;
00946 else
00947 return (DHCP_R_INVALIDARG);
00948 host->interface.hbuf[0] = type;
00949 return (ISC_R_SUCCESS);
00950 }
00951
00952 if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
00953 if (host -> client_identifier.data)
00954 return ISC_R_EXISTS;
00955 if (value && (value -> type == omapi_datatype_data ||
00956 value -> type == omapi_datatype_string)) {
00957 if (!buffer_allocate (&host -> client_identifier.buffer,
00958 value -> u.buffer.len, MDL))
00959 return ISC_R_NOMEMORY;
00960 host -> client_identifier.data =
00961 &host -> client_identifier.buffer -> data [0];
00962 memcpy (host -> client_identifier.buffer -> data,
00963 value -> u.buffer.value,
00964 value -> u.buffer.len);
00965 host -> client_identifier.len = value -> u.buffer.len;
00966 } else
00967 return DHCP_R_INVALIDARG;
00968 return ISC_R_SUCCESS;
00969 }
00970
00971 if (!omapi_ds_strcmp (name, "ip-address")) {
00972 if (host -> fixed_addr)
00973 option_cache_dereference (&host -> fixed_addr, MDL);
00974 if (!value)
00975 return ISC_R_SUCCESS;
00976 if (value && (value -> type == omapi_datatype_data ||
00977 value -> type == omapi_datatype_string)) {
00978 struct data_string ds;
00979 memset (&ds, 0, sizeof ds);
00980 ds.len = value -> u.buffer.len;
00981 if (!buffer_allocate (&ds.buffer, ds.len, MDL))
00982 return ISC_R_NOMEMORY;
00983 ds.data = (&ds.buffer -> data [0]);
00984 memcpy (ds.buffer -> data,
00985 value -> u.buffer.value, ds.len);
00986 if (!option_cache (&host -> fixed_addr,
00987 &ds, (struct expression *)0,
00988 (struct option *)0, MDL)) {
00989 data_string_forget (&ds, MDL);
00990 return ISC_R_NOMEMORY;
00991 }
00992 data_string_forget (&ds, MDL);
00993 } else
00994 return DHCP_R_INVALIDARG;
00995 return ISC_R_SUCCESS;
00996 }
00997
00998 if (!omapi_ds_strcmp (name, "statements")) {
00999 if (!host -> group) {
01000 if (!clone_group (&host -> group, root_group, MDL))
01001 return ISC_R_NOMEMORY;
01002 } else {
01003 if (host -> group -> statements &&
01004 (!host -> named_group ||
01005 host -> group != host -> named_group -> group) &&
01006 host -> group != root_group)
01007 return ISC_R_EXISTS;
01008 if (!clone_group (&host -> group, host -> group, MDL))
01009 return ISC_R_NOMEMORY;
01010 }
01011 if (!host -> group)
01012 return ISC_R_NOMEMORY;
01013 if (value && (value -> type == omapi_datatype_data ||
01014 value -> type == omapi_datatype_string)) {
01015 struct parse *parse;
01016 int lose = 0;
01017 parse = (struct parse *)0;
01018 status = new_parse(&parse, -1,
01019 (char *) value->u.buffer.value,
01020 value->u.buffer.len,
01021 "network client", 0);
01022 if (status != ISC_R_SUCCESS || parse == NULL)
01023 return status;
01024
01025 if (!(parse_executable_statements
01026 (&host -> group -> statements, parse, &lose,
01027 context_any))) {
01028 end_parse (&parse);
01029 return DHCP_R_BADPARSE;
01030 }
01031 end_parse (&parse);
01032 } else
01033 return DHCP_R_INVALIDARG;
01034 return ISC_R_SUCCESS;
01035 }
01036
01037
01038
01039 if (!omapi_ds_strcmp (name, "known")) {
01040 return ISC_R_SUCCESS;
01041 }
01042
01043
01044 if (h -> inner && h -> inner -> type -> set_value) {
01045 status = ((*(h -> inner -> type -> set_value))
01046 (h -> inner, id, name, value));
01047 if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
01048 return status;
01049 }
01050
01051 return DHCP_R_UNKNOWNATTRIBUTE;
01052 }
01053
01054
01055 isc_result_t dhcp_host_get_value (omapi_object_t *h, omapi_object_t *id,
01056 omapi_data_string_t *name,
01057 omapi_value_t **value)
01058 {
01059 struct host_decl *host;
01060 isc_result_t status;
01061 struct data_string ip_addrs;
01062
01063 if (h -> type != dhcp_type_host)
01064 return DHCP_R_INVALIDARG;
01065 host = (struct host_decl *)h;
01066
01067 if (!omapi_ds_strcmp (name, "ip-addresses")) {
01068 memset (&ip_addrs, 0, sizeof ip_addrs);
01069 if (host -> fixed_addr &&
01070 evaluate_option_cache (&ip_addrs, (struct packet *)0,
01071 (struct lease *)0,
01072 (struct client_state *)0,
01073 (struct option_state *)0,
01074 (struct option_state *)0,
01075 &global_scope,
01076 host -> fixed_addr, MDL)) {
01077 status = omapi_make_const_value (value, name,
01078 ip_addrs.data,
01079 ip_addrs.len, MDL);
01080 data_string_forget (&ip_addrs, MDL);
01081 return status;
01082 }
01083 return ISC_R_NOTFOUND;
01084 }
01085
01086 if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
01087 if (!host -> client_identifier.len)
01088 return ISC_R_NOTFOUND;
01089 return omapi_make_const_value (value, name,
01090 host -> client_identifier.data,
01091 host -> client_identifier.len,
01092 MDL);
01093 }
01094
01095 if (!omapi_ds_strcmp (name, "name"))
01096 return omapi_make_string_value (value, name, host -> name,
01097 MDL);
01098
01099 if (!omapi_ds_strcmp (name, "hardware-address")) {
01100 if (!host -> interface.hlen)
01101 return ISC_R_NOTFOUND;
01102 return (omapi_make_const_value
01103 (value, name, &host -> interface.hbuf [1],
01104 (unsigned long)(host -> interface.hlen - 1), MDL));
01105 }
01106
01107 if (!omapi_ds_strcmp (name, "hardware-type")) {
01108 if (!host -> interface.hlen)
01109 return ISC_R_NOTFOUND;
01110 return omapi_make_int_value (value, name,
01111 host -> interface.hbuf [0], MDL);
01112 }
01113
01114
01115 if (h -> inner && h -> inner -> type -> get_value) {
01116 status = ((*(h -> inner -> type -> get_value))
01117 (h -> inner, id, name, value));
01118 if (status == ISC_R_SUCCESS)
01119 return status;
01120 }
01121 return DHCP_R_UNKNOWNATTRIBUTE;
01122 }
01123
01124 isc_result_t dhcp_host_destroy (omapi_object_t *h, const char *file, int line)
01125 {
01126
01127 if (h -> type != dhcp_type_host)
01128 return DHCP_R_INVALIDARG;
01129
01130 struct host_decl *host = (struct host_decl *)h;
01131 if (host -> n_ipaddr)
01132 host_dereference (&host -> n_ipaddr, file, line);
01133 if (host -> n_dynamic)
01134 host_dereference (&host -> n_dynamic, file, line);
01135 if (host -> name) {
01136 dfree (host -> name, file, line);
01137 host -> name = (char *)0;
01138 }
01139 data_string_forget (&host -> client_identifier, file, line);
01140 if (host -> fixed_addr)
01141 option_cache_dereference (&host -> fixed_addr, file, line);
01142 if (host -> group)
01143 group_dereference (&host -> group, file, line);
01144 if (host -> named_group)
01145 omapi_object_dereference ((omapi_object_t **)
01146 &host -> named_group, file, line);
01147 data_string_forget (&host -> auth_key_id, file, line);
01148
01149 return ISC_R_SUCCESS;
01150 }
01151
01152 isc_result_t dhcp_host_signal_handler (omapi_object_t *h,
01153 const char *name, va_list ap)
01154 {
01155 struct host_decl *host;
01156 isc_result_t status;
01157 int updatep = 0;
01158
01159 if (h -> type != dhcp_type_host)
01160 return DHCP_R_INVALIDARG;
01161 host = (struct host_decl *)h;
01162
01163 if (!strcmp (name, "updated")) {
01164
01165 if (host -> interface.hlen == 0 &&
01166 !host -> client_identifier.len)
01167 return DHCP_R_INVALIDARG;
01168
01169 if (!host -> name) {
01170 char hnbuf [64];
01171 sprintf (hnbuf, "nh%08lx%08lx",
01172 (unsigned long)cur_time, (unsigned long)host);
01173 host -> name = dmalloc (strlen (hnbuf) + 1, MDL);
01174 if (!host -> name)
01175 return ISC_R_NOMEMORY;
01176 strcpy (host -> name, hnbuf);
01177 }
01178
01179 #ifdef DEBUG_OMAPI
01180 log_debug ("OMAPI added host %s", host -> name);
01181 #endif
01182 status = enter_host (host, 1, 1);
01183 if (status != ISC_R_SUCCESS)
01184 return status;
01185 updatep = 1;
01186 }
01187
01188
01189 if (h -> inner && h -> inner -> type -> signal_handler) {
01190 status = ((*(h -> inner -> type -> signal_handler))
01191 (h -> inner, name, ap));
01192 if (status == ISC_R_SUCCESS)
01193 return status;
01194 }
01195 if (updatep)
01196 return ISC_R_SUCCESS;
01197 return ISC_R_NOTFOUND;
01198 }
01199
01200 isc_result_t dhcp_host_stuff_values (omapi_object_t *c,
01201 omapi_object_t *id,
01202 omapi_object_t *h)
01203 {
01204 struct host_decl *host;
01205 isc_result_t status;
01206 struct data_string ip_addrs;
01207
01208 if (h -> type != dhcp_type_host)
01209 return DHCP_R_INVALIDARG;
01210 host = (struct host_decl *)h;
01211
01212
01213
01214 memset (&ip_addrs, 0, sizeof ip_addrs);
01215 if (host -> fixed_addr &&
01216 evaluate_option_cache (&ip_addrs, (struct packet *)0,
01217 (struct lease *)0,
01218 (struct client_state *)0,
01219 (struct option_state *)0,
01220 (struct option_state *)0,
01221 &global_scope,
01222 host -> fixed_addr, MDL)) {
01223 status = omapi_connection_put_name (c, "ip-address");
01224 if (status != ISC_R_SUCCESS)
01225 return status;
01226 status = omapi_connection_put_uint32 (c, ip_addrs.len);
01227 if (status != ISC_R_SUCCESS)
01228 return status;
01229 status = omapi_connection_copyin (c,
01230 ip_addrs.data, ip_addrs.len);
01231 if (status != ISC_R_SUCCESS)
01232 return status;
01233 data_string_forget (&ip_addrs, MDL);
01234 }
01235
01236 if (host -> client_identifier.len) {
01237 status = omapi_connection_put_name (c,
01238 "dhcp-client-identifier");
01239 if (status != ISC_R_SUCCESS)
01240 return status;
01241 status = (omapi_connection_put_uint32
01242 (c, host -> client_identifier.len));
01243 if (status != ISC_R_SUCCESS)
01244 return status;
01245 status = (omapi_connection_copyin
01246 (c,
01247 host -> client_identifier.data,
01248 host -> client_identifier.len));
01249 if (status != ISC_R_SUCCESS)
01250 return status;
01251 }
01252
01253 if (host -> name) {
01254 status = omapi_connection_put_name (c, "name");
01255 if (status != ISC_R_SUCCESS)
01256 return status;
01257 status = omapi_connection_put_string (c, host -> name);
01258 if (status != ISC_R_SUCCESS)
01259 return status;
01260 }
01261
01262 if (host -> interface.hlen) {
01263 status = omapi_connection_put_name (c, "hardware-address");
01264 if (status != ISC_R_SUCCESS)
01265 return status;
01266 status = (omapi_connection_put_uint32
01267 (c, (unsigned long)(host -> interface.hlen - 1)));
01268 if (status != ISC_R_SUCCESS)
01269 return status;
01270 status = (omapi_connection_copyin
01271 (c, &host -> interface.hbuf [1],
01272 (unsigned long)(host -> interface.hlen - 1)));
01273 if (status != ISC_R_SUCCESS)
01274 return status;
01275
01276 status = omapi_connection_put_named_uint32(c, "hardware-type",
01277 host->interface.hbuf[0]);
01278 if (status != ISC_R_SUCCESS)
01279 return status;
01280 }
01281
01282
01283 if (h -> inner && h -> inner -> type -> stuff_values) {
01284 status = ((*(h -> inner -> type -> stuff_values))
01285 (c, id, h -> inner));
01286 if (status == ISC_R_SUCCESS)
01287 return status;
01288 }
01289
01290 return ISC_R_SUCCESS;
01291 }
01292
01293 isc_result_t dhcp_host_lookup (omapi_object_t **lp,
01294 omapi_object_t *id, omapi_object_t *ref)
01295 {
01296 omapi_value_t *tv = (omapi_value_t *)0;
01297 isc_result_t status;
01298 struct host_decl *host;
01299
01300 if (!ref)
01301 return DHCP_R_NOKEYS;
01302
01303
01304 status = omapi_get_value_str (ref, id, "handle", &tv);
01305 if (status == ISC_R_SUCCESS) {
01306 status = omapi_handle_td_lookup (lp, tv -> value);
01307
01308 omapi_value_dereference (&tv, MDL);
01309 if (status != ISC_R_SUCCESS)
01310 return status;
01311
01312
01313 if ((*lp) -> type != dhcp_type_host) {
01314 omapi_object_dereference (lp, MDL);
01315 return DHCP_R_INVALIDARG;
01316 }
01317 if (((struct host_decl *)(*lp)) -> flags & HOST_DECL_DELETED) {
01318 omapi_object_dereference (lp, MDL);
01319 }
01320 }
01321
01322
01323 status = omapi_get_value_str (ref, id, "dhcp-client-identifier", &tv);
01324 if (status == ISC_R_SUCCESS) {
01325 host = (struct host_decl *)0;
01326 host_hash_lookup (&host, host_uid_hash,
01327 tv -> value -> u.buffer.value,
01328 tv -> value -> u.buffer.len, MDL);
01329 omapi_value_dereference (&tv, MDL);
01330
01331 if (*lp && *lp != (omapi_object_t *)host) {
01332 omapi_object_dereference (lp, MDL);
01333 if (host)
01334 host_dereference (&host, MDL);
01335 return DHCP_R_KEYCONFLICT;
01336 } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
01337 if (*lp)
01338 omapi_object_dereference (lp, MDL);
01339 if (host)
01340 host_dereference (&host, MDL);
01341 return ISC_R_NOTFOUND;
01342 } else if (!*lp) {
01343
01344
01345 omapi_object_reference (lp,
01346 (omapi_object_t *)host, MDL);
01347 host_dereference (&host, MDL);
01348 }
01349 }
01350
01351
01352 status = omapi_get_value_str (ref, id, "hardware-address", &tv);
01353 if (status == ISC_R_SUCCESS) {
01354 unsigned char *haddr;
01355 unsigned int len;
01356
01357 len = tv -> value -> u.buffer.len + 1;
01358 haddr = dmalloc (len, MDL);
01359 if (!haddr) {
01360 omapi_value_dereference (&tv, MDL);
01361 return ISC_R_NOMEMORY;
01362 }
01363
01364 memcpy (haddr + 1, tv -> value -> u.buffer.value, len - 1);
01365 omapi_value_dereference (&tv, MDL);
01366
01367 status = omapi_get_value_str (ref, id, "hardware-type", &tv);
01368 if (status == ISC_R_SUCCESS) {
01369 if (tv -> value -> type == omapi_datatype_data) {
01370 if ((tv -> value -> u.buffer.len != 4) ||
01371 (tv -> value -> u.buffer.value[0] != 0) ||
01372 (tv -> value -> u.buffer.value[1] != 0) ||
01373 (tv -> value -> u.buffer.value[2] != 0)) {
01374 omapi_value_dereference (&tv, MDL);
01375 dfree (haddr, MDL);
01376 return DHCP_R_INVALIDARG;
01377 }
01378
01379 haddr[0] = tv -> value -> u.buffer.value[3];
01380 } else if (tv -> value -> type == omapi_datatype_int) {
01381 haddr[0] = (unsigned char)
01382 tv -> value -> u.integer;
01383 } else {
01384 omapi_value_dereference (&tv, MDL);
01385 dfree (haddr, MDL);
01386 return DHCP_R_INVALIDARG;
01387 }
01388
01389 omapi_value_dereference (&tv, MDL);
01390 } else {
01391
01392
01393
01394
01395 haddr[0] = HTYPE_ETHER;
01396 }
01397
01398 host = (struct host_decl *)0;
01399 host_hash_lookup (&host, host_hw_addr_hash, haddr, len, MDL);
01400 dfree (haddr, MDL);
01401
01402 if (*lp && *lp != (omapi_object_t *)host) {
01403 omapi_object_dereference (lp, MDL);
01404 if (host)
01405 host_dereference (&host, MDL);
01406 return DHCP_R_KEYCONFLICT;
01407 } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
01408 if (*lp)
01409 omapi_object_dereference (lp, MDL);
01410 if (host)
01411 host_dereference (&host, MDL);
01412 return ISC_R_NOTFOUND;
01413 } else if (!*lp) {
01414
01415
01416 omapi_object_reference (lp,
01417 (omapi_object_t *)host, MDL);
01418 host_dereference (&host, MDL);
01419 }
01420 }
01421
01422
01423 status = omapi_get_value_str (ref, id, "ip-address", &tv);
01424 if (status == ISC_R_SUCCESS) {
01425 struct lease *l;
01426
01427
01428 l = (struct lease *)0;
01429 lease_ip_hash_lookup(&l, lease_ip_addr_hash,
01430 tv->value->u.buffer.value,
01431 tv->value->u.buffer.len, MDL);
01432 omapi_value_dereference (&tv, MDL);
01433
01434 if (!l && !*lp)
01435 return ISC_R_NOTFOUND;
01436
01437 if (l) {
01438
01439 host = (struct host_decl *)0;
01440 host_hash_lookup (&host, host_hw_addr_hash,
01441 l -> hardware_addr.hbuf,
01442 l -> hardware_addr.hlen, MDL);
01443
01444 if (host && *lp && *lp != (omapi_object_t *)host) {
01445 omapi_object_dereference (lp, MDL);
01446 if (host)
01447 host_dereference (&host, MDL);
01448 return DHCP_R_KEYCONFLICT;
01449 } else if (!host || (host -> flags &
01450 HOST_DECL_DELETED)) {
01451 if (host)
01452 host_dereference (&host, MDL);
01453 if (!*lp)
01454 return ISC_R_NOTFOUND;
01455 } else if (!*lp) {
01456
01457
01458 omapi_object_reference (lp, (omapi_object_t *)host,
01459 MDL);
01460 host_dereference (&host, MDL);
01461 }
01462 lease_dereference (&l, MDL);
01463 }
01464 }
01465
01466
01467 status = omapi_get_value_str (ref, id, "name", &tv);
01468 if (status == ISC_R_SUCCESS) {
01469 host = (struct host_decl *)0;
01470 host_hash_lookup (&host, host_name_hash,
01471 tv -> value -> u.buffer.value,
01472 tv -> value -> u.buffer.len, MDL);
01473 omapi_value_dereference (&tv, MDL);
01474
01475 if (*lp && *lp != (omapi_object_t *)host) {
01476 omapi_object_dereference (lp, MDL);
01477 if (host)
01478 host_dereference (&host, MDL);
01479 return DHCP_R_KEYCONFLICT;
01480 } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
01481 if (host)
01482 host_dereference (&host, MDL);
01483 return ISC_R_NOTFOUND;
01484 } else if (!*lp) {
01485
01486
01487 omapi_object_reference (lp,
01488 (omapi_object_t *)host, MDL);
01489 host_dereference (&host, MDL);
01490 }
01491 }
01492
01493
01494
01495 if (!*lp)
01496 return DHCP_R_NOKEYS;
01497 return ISC_R_SUCCESS;
01498 }
01499
01500 isc_result_t dhcp_host_create (omapi_object_t **lp,
01501 omapi_object_t *id)
01502 {
01503 struct host_decl *hp;
01504 isc_result_t status;
01505 hp = (struct host_decl *)0;
01506 status = host_allocate (&hp, MDL);
01507 if (status != ISC_R_SUCCESS)
01508 return status;
01509 group_reference (&hp -> group, root_group, MDL);
01510 hp -> flags = HOST_DECL_DYNAMIC;
01511 status = omapi_object_reference (lp, (omapi_object_t *)hp, MDL);
01512 host_dereference (&hp, MDL);
01513 return status;
01514 }
01515
01516 isc_result_t dhcp_host_remove (omapi_object_t *lp,
01517 omapi_object_t *id)
01518 {
01519 struct host_decl *hp;
01520 if (lp -> type != dhcp_type_host)
01521 return DHCP_R_INVALIDARG;
01522 hp = (struct host_decl *)lp;
01523
01524 #ifdef DEBUG_OMAPI
01525 log_debug ("OMAPI delete host %s", hp -> name);
01526 #endif
01527 delete_host (hp, 1);
01528 return ISC_R_SUCCESS;
01529 }
01530
01531 isc_result_t dhcp_pool_set_value (omapi_object_t *h,
01532 omapi_object_t *id,
01533 omapi_data_string_t *name,
01534 omapi_typed_data_t *value)
01535 {
01536
01537 isc_result_t status;
01538
01539 if (h -> type != dhcp_type_pool)
01540 return DHCP_R_INVALIDARG;
01541
01542
01543
01544
01545 if (h -> inner && h -> inner -> type -> set_value) {
01546 status = ((*(h -> inner -> type -> set_value))
01547 (h -> inner, id, name, value));
01548 if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
01549 return status;
01550 }
01551
01552 return DHCP_R_UNKNOWNATTRIBUTE;
01553 }
01554
01555
01556 isc_result_t dhcp_pool_get_value (omapi_object_t *h, omapi_object_t *id,
01557 omapi_data_string_t *name,
01558 omapi_value_t **value)
01559 {
01560
01561 isc_result_t status;
01562
01563 if (h -> type != dhcp_type_pool)
01564 return DHCP_R_INVALIDARG;
01565
01566
01567
01568
01569 if (h -> inner && h -> inner -> type -> get_value) {
01570 status = ((*(h -> inner -> type -> get_value))
01571 (h -> inner, id, name, value));
01572 if (status == ISC_R_SUCCESS)
01573 return status;
01574 }
01575 return DHCP_R_UNKNOWNATTRIBUTE;
01576 }
01577
01578 isc_result_t dhcp_pool_destroy (omapi_object_t *h, const char *file, int line)
01579 {
01580 #if defined (DEBUG_MEMORY_LEAKAGE) || \
01581 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
01582 struct permit *pc, *pn;
01583 #endif
01584
01585 if (h -> type != dhcp_type_pool)
01586 return DHCP_R_INVALIDARG;
01587
01588 #if defined (DEBUG_MEMORY_LEAKAGE) || \
01589 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
01590 struct pool *pool = (struct pool *)h;
01591 if (pool -> next)
01592 pool_dereference (&pool -> next, file, line);
01593 if (pool -> group)
01594 group_dereference (&pool -> group, file, line);
01595 if (pool -> shared_network)
01596 shared_network_dereference (&pool -> shared_network, file, line);
01597 if (pool -> active)
01598 lease_dereference (&pool -> active, file, line);
01599 if (pool -> expired)
01600 lease_dereference (&pool -> expired, file, line);
01601 if (pool -> free)
01602 lease_dereference (&pool -> free, file, line);
01603 if (pool -> backup)
01604 lease_dereference (&pool -> backup, file, line);
01605 if (pool -> abandoned)
01606 lease_dereference (&pool -> abandoned, file, line);
01607 #if defined (FAILOVER_PROTOCOL)
01608 if (pool -> failover_peer)
01609 dhcp_failover_state_dereference (&pool -> failover_peer,
01610 file, line);
01611 #endif
01612 for (pc = pool -> permit_list; pc; pc = pn) {
01613 pn = pc -> next;
01614 free_permit (pc, file, line);
01615 }
01616 pool -> permit_list = (struct permit *)0;
01617
01618 for (pc = pool -> prohibit_list; pc; pc = pn) {
01619 pn = pc -> next;
01620 free_permit (pc, file, line);
01621 }
01622 pool -> prohibit_list = (struct permit *)0;
01623 #endif
01624
01625 return ISC_R_SUCCESS;
01626 }
01627
01628 isc_result_t dhcp_pool_signal_handler (omapi_object_t *h,
01629 const char *name, va_list ap)
01630 {
01631
01632 isc_result_t status;
01633
01634 if (h -> type != dhcp_type_pool)
01635 return DHCP_R_INVALIDARG;
01636
01637
01638
01639
01640 if (h -> inner && h -> inner -> type -> signal_handler) {
01641 status = ((*(h -> inner -> type -> signal_handler))
01642 (h -> inner, name, ap));
01643 if (status == ISC_R_SUCCESS)
01644 return status;
01645 }
01646
01647 return ISC_R_NOTFOUND;
01648 }
01649
01650 isc_result_t dhcp_pool_stuff_values (omapi_object_t *c,
01651 omapi_object_t *id,
01652 omapi_object_t *h)
01653 {
01654 struct pool *pool;
01655 isc_result_t status;
01656
01657 if (h->type != dhcp_type_pool)
01658 return (DHCP_R_INVALIDARG);
01659 pool = (struct pool *)h;
01660
01661
01662
01663
01664
01665
01666 status = omapi_connection_put_named_uint32(c, "lease-count",
01667 ((u_int32_t)
01668 pool->lease_count));
01669 if (status != ISC_R_SUCCESS)
01670 return (status);
01671
01672 status = omapi_connection_put_named_uint32(c, "free-leases",
01673 ((u_int32_t)
01674 pool->free_leases));
01675 if (status != ISC_R_SUCCESS)
01676 return (status);
01677
01678 status = omapi_connection_put_named_uint32(c, "backup-leases",
01679 ((u_int32_t)
01680 pool->backup_leases));
01681 if (status != ISC_R_SUCCESS)
01682 return (status);
01683
01684
01685
01686 if (h->inner && h->inner->type->stuff_values) {
01687 status = ((*(h->inner->type->stuff_values))
01688 (c, id, h->inner));
01689 if (status == ISC_R_SUCCESS)
01690 return (status);
01691 }
01692
01693 return (ISC_R_SUCCESS);
01694 }
01695
01696 isc_result_t dhcp_pool_lookup (omapi_object_t **lp,
01697 omapi_object_t *id, omapi_object_t *ref)
01698 {
01699
01700
01701
01702
01703 if (!*lp)
01704 return DHCP_R_NOKEYS;
01705 return ISC_R_SUCCESS;
01706 }
01707
01708 isc_result_t dhcp_pool_create (omapi_object_t **lp,
01709 omapi_object_t *id)
01710 {
01711 return ISC_R_NOTIMPLEMENTED;
01712 }
01713
01714 isc_result_t dhcp_pool_remove (omapi_object_t *lp,
01715 omapi_object_t *id)
01716 {
01717 return ISC_R_NOTIMPLEMENTED;
01718 }
01719
01720 static isc_result_t
01721 class_set_value (omapi_object_t *h,
01722 omapi_object_t *id,
01723 omapi_data_string_t *name,
01724 omapi_typed_data_t *value)
01725 {
01726 struct class *class;
01727 struct class *superclass = 0;
01728 isc_result_t status;
01729 int issubclass = (h -> type == dhcp_type_subclass);
01730
01731 class = (struct class *)h;
01732
01733 if (!omapi_ds_strcmp(name, "name")) {
01734 char *tname;
01735
01736 if (class->name)
01737 return ISC_R_EXISTS;
01738
01739 if ((tname = dmalloc(value->u.buffer.len + 1, MDL)) == NULL) {
01740 return ISC_R_NOMEMORY;
01741 }
01742
01743
01744 memcpy(tname, value->u.buffer.value, value->u.buffer.len);
01745
01746 if (issubclass) {
01747 status = find_class(&superclass, tname, MDL);
01748 dfree(tname, MDL);
01749
01750 if (status == ISC_R_NOTFOUND)
01751 return status;
01752
01753 if (class->superclass != NULL)
01754 class_dereference(&class->superclass, MDL);
01755 class_reference(&class->superclass, superclass, MDL);
01756
01757 if (class->group != NULL)
01758 group_dereference(&class->group, MDL);
01759 group_reference(&class->group, superclass->group, MDL);
01760
01761 class->lease_limit = superclass->lease_limit;
01762 if (class->lease_limit != 0) {
01763 class->billed_leases =
01764 dmalloc(class->lease_limit *
01765 sizeof(struct lease *),
01766 MDL);
01767 if (class->billed_leases == NULL) {
01768 return ISC_R_NOMEMORY;
01769 }
01770 }
01771
01772 } else if (value->type == omapi_datatype_data ||
01773 value->type == omapi_datatype_string) {
01774 class->name = dmalloc(value->u.buffer.len + 1, MDL);
01775 if (!class->name)
01776 return ISC_R_NOMEMORY;
01777
01778
01779 memcpy(class->name, value->u.buffer.value,
01780 value->u.buffer.len);
01781 } else
01782 return DHCP_R_INVALIDARG;
01783
01784 return ISC_R_SUCCESS;
01785 }
01786
01787
01788 if (issubclass && !omapi_ds_strcmp(name, "hashstring")) {
01789 if (class->hash_string.data)
01790 return ISC_R_EXISTS;
01791
01792 if (value->type == omapi_datatype_data ||
01793 value->type == omapi_datatype_string) {
01794 if (!buffer_allocate(&class->hash_string.buffer,
01795 value->u.buffer.len, MDL))
01796 return ISC_R_NOMEMORY;
01797 class->hash_string.data =
01798 class->hash_string.buffer->data;
01799 memcpy(class->hash_string.buffer->data,
01800 value->u.buffer.value, value->u.buffer.len);
01801 class->hash_string.len = value->u.buffer.len;
01802 } else
01803 return DHCP_R_INVALIDARG;
01804
01805 return ISC_R_SUCCESS;
01806 }
01807
01808 if (!omapi_ds_strcmp(name, "group")) {
01809 if (value->type == omapi_datatype_data ||
01810 value->type == omapi_datatype_string) {
01811 struct group_object *group = NULL;
01812
01813 group_hash_lookup(&group, group_name_hash,
01814 (char *)value->u.buffer.value,
01815 value->u.buffer.len, MDL);
01816 if (!group || (group->flags & GROUP_OBJECT_DELETED))
01817 return ISC_R_NOTFOUND;
01818 if (class->group)
01819 group_dereference(&class->group, MDL);
01820 group_reference(&class->group, group->group, MDL);
01821 group_object_dereference(&group, MDL);
01822 } else
01823 return DHCP_R_INVALIDARG;
01824
01825 return ISC_R_SUCCESS;
01826 }
01827
01828
01829
01830
01831
01832
01833 if (!omapi_ds_strcmp(name, "match")) {
01834 if (value->type == omapi_datatype_data ||
01835 value->type == omapi_datatype_string) {
01836 unsigned minlen = (value->u.buffer.len > 8 ?
01837 8 : value->u.buffer.len);
01838
01839 if (!strncmp("hardware",
01840 (char *)value->u.buffer.value, minlen))
01841 {
01842 if (!expression_allocate(&class->submatch, MDL))
01843 return ISC_R_NOMEMORY;
01844
01845 class->submatch->op = expr_hardware;
01846 } else
01847 return DHCP_R_INVALIDARG;
01848 } else
01849 return DHCP_R_INVALIDARG;
01850
01851 return ISC_R_SUCCESS;
01852 }
01853
01854
01855 if (!omapi_ds_strcmp(name, "option")) {
01856 if (value->type == omapi_datatype_data ||
01857 value->type == omapi_datatype_string) {
01858
01859
01860 return DHCP_R_INVALIDARG;
01861 } else
01862 return DHCP_R_INVALIDARG;
01863
01864
01865
01866
01867
01868
01869
01870 }
01871
01872
01873
01874 if (h->inner && h->inner->type->set_value) {
01875 status = ((*(h->inner->type->set_value))
01876 (h->inner, id, name, value));
01877 if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
01878 return status;
01879 }
01880
01881 return DHCP_R_UNKNOWNATTRIBUTE;
01882 }
01883
01884
01885
01886 isc_result_t dhcp_class_set_value (omapi_object_t *h,
01887 omapi_object_t *id,
01888 omapi_data_string_t *name,
01889 omapi_typed_data_t *value)
01890 {
01891 if (h -> type != dhcp_type_class)
01892 return DHCP_R_INVALIDARG;
01893
01894 return class_set_value(h, id, name, value);
01895 }
01896
01897 isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id,
01898 omapi_data_string_t *name,
01899 omapi_value_t **value)
01900 {
01901 struct class *class;
01902 isc_result_t status;
01903
01904 if (h -> type != dhcp_type_class)
01905 return DHCP_R_INVALIDARG;
01906 class = (struct class *)h;
01907
01908 if (!omapi_ds_strcmp (name, "name"))
01909 return omapi_make_string_value (value, name, class -> name,
01910 MDL);
01911
01912
01913 if (h -> inner && h -> inner -> type -> get_value) {
01914 status = ((*(h -> inner -> type -> get_value))
01915 (h -> inner, id, name, value));
01916 if (status == ISC_R_SUCCESS)
01917 return status;
01918 }
01919 return DHCP_R_UNKNOWNATTRIBUTE;
01920 }
01921
01922 isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line)
01923 {
01924
01925 if (h -> type != dhcp_type_class && h -> type != dhcp_type_subclass)
01926 return DHCP_R_INVALIDARG;
01927 struct class *class = (struct class *)h;
01928
01929 if (class -> nic)
01930 class_dereference (&class -> nic, file, line);
01931 if (class -> superclass)
01932 class_dereference (&class -> superclass, file, line);
01933 if (class -> name) {
01934 dfree (class -> name, file, line);
01935 class -> name = (char *)0;
01936 }
01937 if (class -> billed_leases) {
01938 int i;
01939 for (i = 0; i < class -> lease_limit; i++) {
01940 if (class -> billed_leases [i]) {
01941 lease_dereference (&class -> billed_leases [i],
01942 file, line);
01943 }
01944 }
01945 dfree (class -> billed_leases, file, line);
01946 class -> billed_leases = (struct lease **)0;
01947 }
01948 if (class -> hash) {
01949 class_free_hash_table (&class -> hash, file, line);
01950 class -> hash = (class_hash_t *)0;
01951 }
01952 data_string_forget (&class -> hash_string, file, line);
01953
01954 if (class -> expr)
01955 expression_dereference (&class -> expr, file, line);
01956 if (class -> submatch)
01957 expression_dereference (&class -> submatch, file, line);
01958 if (class -> group)
01959 group_dereference (&class -> group, file, line);
01960 if (class -> statements)
01961 executable_statement_dereference (&class -> statements,
01962 file, line);
01963 if (class -> superclass)
01964 class_dereference (&class -> superclass, file, line);
01965
01966 return ISC_R_SUCCESS;
01967 }
01968
01969 static isc_result_t
01970 class_signal_handler(omapi_object_t *h,
01971 const char *name, va_list ap)
01972 {
01973 struct class *class = (struct class *)h;
01974 isc_result_t status;
01975 int updatep = 0;
01976 int issubclass;
01977
01978 issubclass = (h->type == dhcp_type_subclass);
01979
01980 if (!strcmp (name, "updated")) {
01981
01982 if (!issubclass) {
01983 if (class->name == 0 || strlen(class->name) == 0) {
01984 return DHCP_R_INVALIDARG;
01985 }
01986 } else {
01987 if (class->superclass == 0) {
01988 return DHCP_R_INVALIDARG;
01989 }
01990
01991 if (class->hash_string.data == NULL) {
01992 return DHCP_R_INVALIDARG;
01993 }
01994 }
01995
01996
01997 if (issubclass) {
01998 if (!class->superclass->hash)
01999 class_new_hash(&class->superclass->hash,
02000 SCLASS_HASH_SIZE, MDL);
02001
02002 class_hash_add(class->superclass->hash,
02003 (const char *)class->hash_string.data,
02004 class->hash_string.len,
02005 (void *)class, MDL);
02006 }
02007
02008 #ifdef DEBUG_OMAPI
02009 if (issubclass) {
02010 log_debug ("OMAPI added subclass %s",
02011 class->superclass->name);
02012 } else {
02013 log_debug ("OMAPI added class %s", class->name);
02014 }
02015 #endif
02016
02017 status = enter_class (class, 1, 1);
02018 if (status != ISC_R_SUCCESS)
02019 return status;
02020 updatep = 1;
02021 }
02022
02023
02024 if (h->inner && h->inner->type->signal_handler) {
02025 status = ((*(h->inner->type->signal_handler))
02026 (h->inner, name, ap));
02027 if (status == ISC_R_SUCCESS)
02028 return status;
02029 }
02030
02031 if (updatep)
02032 return ISC_R_SUCCESS;
02033
02034 return ISC_R_NOTFOUND;
02035 }
02036
02037
02038 isc_result_t dhcp_class_signal_handler (omapi_object_t *h,
02039 const char *name, va_list ap)
02040 {
02041 if (h -> type != dhcp_type_class)
02042 return DHCP_R_INVALIDARG;
02043
02044 return class_signal_handler(h, name, ap);
02045 }
02046
02047
02048
02049
02050
02051 isc_result_t class_stuff_values (omapi_object_t *c,
02052 omapi_object_t *id,
02053 omapi_object_t *h)
02054 {
02055 struct class *class;
02056 isc_result_t status;
02057
02058 class = (struct class *)h;
02059
02060 status = omapi_connection_put_named_uint32(c, "lease-limit",
02061 ((u_int32_t)
02062 class->lease_limit));
02063 if (status != ISC_R_SUCCESS)
02064 return (status);
02065
02066 status = omapi_connection_put_named_uint32(c, "leases-used",
02067 ((u_int32_t)
02068 class->leases_consumed));
02069 if (status != ISC_R_SUCCESS)
02070 return (status);
02071
02072
02073 if (h->inner && h->inner->type->stuff_values) {
02074 status = ((*(h->inner->type->stuff_values))
02075 (c, id, h->inner));
02076 if (status == ISC_R_SUCCESS)
02077 return (status);
02078 }
02079
02080 return (ISC_R_SUCCESS);
02081 }
02082
02083
02084 isc_result_t dhcp_class_stuff_values (omapi_object_t *c,
02085 omapi_object_t *id,
02086 omapi_object_t *h)
02087 {
02088 if (h->type != dhcp_type_class)
02089 return (DHCP_R_INVALIDARG);
02090
02091
02092
02093 return (class_stuff_values(c, id, h));
02094 }
02095
02096 static isc_result_t class_lookup (omapi_object_t **lp,
02097 omapi_object_t *id, omapi_object_t *ref,
02098 omapi_object_type_t *typewanted)
02099 {
02100 omapi_value_t *nv = NULL;
02101 omapi_value_t *hv = NULL;
02102 isc_result_t status;
02103 struct class *class = 0;
02104 struct class *subclass = 0;
02105
02106 *lp = NULL;
02107
02108 if (ref == NULL)
02109 return (DHCP_R_NOKEYS);
02110
02111
02112 status = omapi_get_value_str(ref, id, "name", &nv);
02113 if (status == ISC_R_SUCCESS) {
02114 char *name = dmalloc(nv->value->u.buffer.len + 1, MDL);
02115 memcpy (name,
02116 nv->value->u.buffer.value,
02117 nv->value->u.buffer.len);
02118
02119 omapi_value_dereference(&nv, MDL);
02120
02121 find_class(&class, name, MDL);
02122
02123 dfree(name, MDL);
02124
02125 if (class == NULL) {
02126 return (ISC_R_NOTFOUND);
02127 }
02128
02129 if (typewanted == dhcp_type_subclass) {
02130 status = omapi_get_value_str(ref, id,
02131 "hashstring", &hv);
02132 if (status != ISC_R_SUCCESS) {
02133 class_dereference(&class, MDL);
02134 return (DHCP_R_NOKEYS);
02135 }
02136
02137 if (hv->value->type != omapi_datatype_data &&
02138 hv->value->type != omapi_datatype_string) {
02139 class_dereference(&class, MDL);
02140 omapi_value_dereference(&hv, MDL);
02141 return (DHCP_R_NOKEYS);
02142 }
02143
02144 class_hash_lookup(&subclass, class->hash,
02145 (const char *)
02146 hv->value->u.buffer.value,
02147 hv->value->u.buffer.len, MDL);
02148
02149 omapi_value_dereference(&hv, MDL);
02150
02151 class_dereference(&class, MDL);
02152
02153 if (subclass == NULL) {
02154 return (ISC_R_NOTFOUND);
02155 }
02156
02157 class_reference(&class, subclass, MDL);
02158 class_dereference(&subclass, MDL);
02159 }
02160
02161
02162 if (class->type != typewanted) {
02163 class_dereference(&class, MDL);
02164 return (DHCP_R_INVALIDARG);
02165 }
02166
02167 if (class->flags & CLASS_DECL_DELETED) {
02168 class_dereference(&class, MDL);
02169 return (ISC_R_NOTFOUND);
02170 }
02171
02172 omapi_object_reference(lp, (omapi_object_t *)class, MDL);
02173 class_dereference(&class, MDL);
02174
02175 return (ISC_R_SUCCESS);
02176 }
02177
02178 return (DHCP_R_NOKEYS);
02179 }
02180
02181
02182 isc_result_t dhcp_class_lookup (omapi_object_t **lp,
02183 omapi_object_t *id, omapi_object_t *ref)
02184 {
02185 return class_lookup(lp, id, ref, dhcp_type_class);
02186 }
02187
02188 isc_result_t dhcp_class_create (omapi_object_t **lp,
02189 omapi_object_t *id)
02190 {
02191 struct class *cp = 0;
02192 isc_result_t status;
02193
02194 status = class_allocate(&cp, MDL);
02195 if (status != ISC_R_SUCCESS)
02196 return (status);
02197
02198 clone_group(&cp->group, root_group, MDL);
02199 cp->flags = CLASS_DECL_DYNAMIC;
02200 status = omapi_object_reference(lp, (omapi_object_t *)cp, MDL);
02201 class_dereference(&cp, MDL);
02202 return (status);
02203 }
02204
02205 isc_result_t dhcp_class_remove (omapi_object_t *lp,
02206 omapi_object_t *id)
02207 {
02208 struct class *cp;
02209 if (lp -> type != dhcp_type_class)
02210 return DHCP_R_INVALIDARG;
02211 cp = (struct class *)lp;
02212
02213 #ifdef DEBUG_OMAPI
02214 log_debug ("OMAPI delete class %s", cp -> name);
02215 #endif
02216
02217 delete_class (cp, 1);
02218 return ISC_R_SUCCESS;
02219 }
02220
02221 isc_result_t dhcp_subclass_set_value (omapi_object_t *h,
02222 omapi_object_t *id,
02223 omapi_data_string_t *name,
02224 omapi_typed_data_t *value)
02225 {
02226 if (h -> type != dhcp_type_subclass)
02227 return DHCP_R_INVALIDARG;
02228
02229 return class_set_value(h, id, name, value);
02230 }
02231
02232
02233 isc_result_t dhcp_subclass_get_value (omapi_object_t *h, omapi_object_t *id,
02234 omapi_data_string_t *name,
02235 omapi_value_t **value)
02236 {
02237 struct class *subclass;
02238 isc_result_t status;
02239
02240 if (h -> type != dhcp_type_class)
02241 return DHCP_R_INVALIDARG;
02242 subclass = (struct class *)h;
02243 if (subclass -> name != 0)
02244 return DHCP_R_INVALIDARG;
02245
02246
02247
02248
02249 if (h -> inner && h -> inner -> type -> get_value) {
02250 status = ((*(h -> inner -> type -> get_value))
02251 (h -> inner, id, name, value));
02252 if (status == ISC_R_SUCCESS)
02253 return status;
02254 }
02255 return DHCP_R_UNKNOWNATTRIBUTE;
02256 }
02257
02258 isc_result_t dhcp_subclass_signal_handler (omapi_object_t *h,
02259 const char *name, va_list ap)
02260 {
02261 if (h -> type != dhcp_type_subclass)
02262 return DHCP_R_INVALIDARG;
02263
02264 return class_signal_handler(h, name, ap);
02265 }
02266
02267
02268 isc_result_t dhcp_subclass_stuff_values (omapi_object_t *c,
02269 omapi_object_t *id,
02270 omapi_object_t *h)
02271 {
02272 struct class *subclass;
02273
02274 if (h->type != dhcp_type_subclass)
02275 return (DHCP_R_INVALIDARG);
02276 subclass = (struct class *)h;
02277 if (subclass->name != 0)
02278 return (DHCP_R_INVALIDARG);
02279
02280
02281
02282 return (class_stuff_values(c, id, h));
02283 }
02284
02285 isc_result_t dhcp_subclass_lookup (omapi_object_t **lp,
02286 omapi_object_t *id, omapi_object_t *ref)
02287 {
02288 return class_lookup(lp, id, ref, dhcp_type_subclass);
02289 }
02290
02291
02292
02293
02294 isc_result_t dhcp_subclass_create (omapi_object_t **lp,
02295 omapi_object_t *id)
02296 {
02297 struct class *cp = 0;
02298 isc_result_t status;
02299
02300 status = subclass_allocate(&cp, MDL);
02301 if (status != ISC_R_SUCCESS)
02302 return status;
02303 group_reference (&cp->group, root_group, MDL);
02304
02305 cp->flags = CLASS_DECL_DYNAMIC;
02306
02307 status = omapi_object_reference (lp, (omapi_object_t *)cp, MDL);
02308 subclass_dereference (&cp, MDL);
02309 return status;
02310 }
02311
02312 isc_result_t dhcp_subclass_remove (omapi_object_t *lp,
02313 omapi_object_t *id)
02314 {
02315 struct class *cp;
02316 if (lp -> type != dhcp_type_subclass)
02317 return DHCP_R_INVALIDARG;
02318 cp = (struct class *)lp;
02319
02320 #ifdef DEBUG_OMAPI
02321 log_debug ("OMAPI delete subclass %s", cp -> name);
02322 #endif
02323
02324 delete_class (cp, 1);
02325
02326 return ISC_R_SUCCESS;
02327 }
02328
02329 isc_result_t binding_scope_set_value (struct binding_scope *scope, int createp,
02330 omapi_data_string_t *name,
02331 omapi_typed_data_t *value)
02332 {
02333 struct binding *bp;
02334 char *nname;
02335 struct binding_value *nv;
02336 nname = dmalloc (name -> len + 1, MDL);
02337 if (!nname)
02338 return ISC_R_NOMEMORY;
02339 memcpy (nname, name -> value, name -> len);
02340 nname [name -> len] = 0;
02341 bp = find_binding (scope, nname);
02342 if (!bp && !createp) {
02343 dfree (nname, MDL);
02344 return DHCP_R_UNKNOWNATTRIBUTE;
02345 }
02346 if (!value) {
02347 dfree (nname, MDL);
02348 if (!bp)
02349 return DHCP_R_UNKNOWNATTRIBUTE;
02350 binding_value_dereference (&bp -> value, MDL);
02351 return ISC_R_SUCCESS;
02352 }
02353
02354 nv = (struct binding_value *)0;
02355 if (!binding_value_allocate (&nv, MDL)) {
02356 dfree (nname, MDL);
02357 return ISC_R_NOMEMORY;
02358 }
02359 switch (value -> type) {
02360 case omapi_datatype_int:
02361 nv -> type = binding_numeric;
02362 nv -> value.intval = value -> u.integer;
02363 break;
02364
02365 case omapi_datatype_string:
02366 case omapi_datatype_data:
02367 if (!buffer_allocate (&nv -> value.data.buffer,
02368 value -> u.buffer.len, MDL)) {
02369 binding_value_dereference (&nv, MDL);
02370 dfree (nname, MDL);
02371 return ISC_R_NOMEMORY;
02372 }
02373 memcpy (&nv -> value.data.buffer -> data [1],
02374 value -> u.buffer.value, value -> u.buffer.len);
02375 nv -> value.data.len = value -> u.buffer.len;
02376 break;
02377
02378 case omapi_datatype_object:
02379 binding_value_dereference (&nv, MDL);
02380 dfree (nname, MDL);
02381 return DHCP_R_INVALIDARG;
02382 }
02383
02384 if (!bp) {
02385 bp = dmalloc (sizeof *bp, MDL);
02386 if (!bp) {
02387 binding_value_dereference (&nv, MDL);
02388 dfree (nname, MDL);
02389 return ISC_R_NOMEMORY;
02390 }
02391 memset (bp, 0, sizeof *bp);
02392 bp -> name = nname;
02393 bp -> next = scope -> bindings;
02394 scope -> bindings = bp;
02395 } else {
02396 if (bp -> value)
02397 binding_value_dereference (&bp -> value, MDL);
02398 dfree (nname, MDL);
02399 }
02400 binding_value_reference (&bp -> value, nv, MDL);
02401 binding_value_dereference (&nv, MDL);
02402 return ISC_R_SUCCESS;
02403 }
02404
02405 isc_result_t binding_scope_get_value (omapi_value_t **value,
02406 struct binding_scope *scope,
02407 omapi_data_string_t *name)
02408 {
02409 struct binding *bp;
02410 omapi_typed_data_t *td;
02411 isc_result_t status;
02412 char *nname;
02413 nname = dmalloc (name -> len + 1, MDL);
02414 if (!nname)
02415 return ISC_R_NOMEMORY;
02416 memcpy (nname, name -> value, name -> len);
02417 nname [name -> len] = 0;
02418 bp = find_binding (scope, nname);
02419 dfree (nname, MDL);
02420 if (!bp)
02421 return DHCP_R_UNKNOWNATTRIBUTE;
02422 if (!bp -> value)
02423 return DHCP_R_UNKNOWNATTRIBUTE;
02424
02425 switch (bp -> value -> type) {
02426 case binding_boolean:
02427 td = (omapi_typed_data_t *)0;
02428 status = omapi_typed_data_new (MDL, &td, omapi_datatype_int,
02429 bp -> value -> value.boolean);
02430 break;
02431
02432 case binding_numeric:
02433 td = (omapi_typed_data_t *)0;
02434 status = omapi_typed_data_new (MDL, &td, omapi_datatype_int,
02435 (int)
02436 bp -> value -> value.intval);
02437 break;
02438
02439 case binding_data:
02440 td = (omapi_typed_data_t *)0;
02441 status = omapi_typed_data_new (MDL, &td, omapi_datatype_data,
02442 bp -> value -> value.data.len);
02443 if (status != ISC_R_SUCCESS)
02444 return status;
02445 memcpy (&td -> u.buffer.value [0],
02446 bp -> value -> value.data.data,
02447 bp -> value -> value.data.len);
02448 break;
02449
02450
02451 case binding_dns:
02452 case binding_function:
02453 return DHCP_R_INVALIDARG;
02454
02455 default:
02456 log_fatal ("Impossible case at %s:%d.", MDL);
02457 return ISC_R_FAILURE;
02458 }
02459
02460 if (status != ISC_R_SUCCESS)
02461 return status;
02462 status = omapi_value_new (value, MDL);
02463 if (status != ISC_R_SUCCESS) {
02464 omapi_typed_data_dereference (&td, MDL);
02465 return status;
02466 }
02467
02468 omapi_data_string_reference (&(*value) -> name, name, MDL);
02469 omapi_typed_data_reference (&(*value) -> value, td, MDL);
02470 omapi_typed_data_dereference (&td, MDL);
02471
02472 return ISC_R_SUCCESS;
02473 }
02474
02475 isc_result_t binding_scope_stuff_values (omapi_object_t *c,
02476 struct binding_scope *scope)
02477 {
02478 struct binding *bp;
02479 unsigned len;
02480 isc_result_t status;
02481
02482 for (bp = scope -> bindings; bp; bp = bp -> next) {
02483 if (bp -> value) {
02484 if (bp -> value -> type == binding_dns ||
02485 bp -> value -> type == binding_function)
02486 continue;
02487
02488
02489 len = strlen (bp -> name);
02490 status = omapi_connection_put_uint16 (c, len);
02491 if (status != ISC_R_SUCCESS)
02492 return status;
02493 status = omapi_connection_copyin (c,
02494 (unsigned char *)bp -> name,
02495 len);
02496 if (status != ISC_R_SUCCESS)
02497 return status;
02498
02499 switch (bp -> value -> type) {
02500 case binding_boolean:
02501 status = omapi_connection_put_uint32 (c,
02502 sizeof (u_int32_t));
02503 if (status != ISC_R_SUCCESS)
02504 return status;
02505 status = (omapi_connection_put_uint32
02506 (c,
02507 ((u_int32_t)(bp -> value -> value.boolean))));
02508 if (status != ISC_R_SUCCESS)
02509 return status;
02510 break;
02511
02512 case binding_data:
02513 status = (omapi_connection_put_uint32
02514 (c, bp -> value -> value.data.len));
02515 if (status != ISC_R_SUCCESS)
02516 return status;
02517 if (bp -> value -> value.data.len) {
02518 status = (omapi_connection_copyin
02519 (c, bp -> value -> value.data.data,
02520 bp -> value -> value.data.len));
02521 if (status != ISC_R_SUCCESS)
02522 return status;
02523 }
02524 break;
02525
02526 case binding_numeric:
02527 status = (omapi_connection_put_uint32
02528 (c, sizeof (u_int32_t)));
02529 if (status != ISC_R_SUCCESS)
02530 return status;
02531 status = (omapi_connection_put_uint32
02532 (c, ((u_int32_t)
02533 (bp -> value -> value.intval))));
02534 if (status != ISC_R_SUCCESS)
02535 return status;
02536 break;
02537
02538
02539
02540 case binding_dns:
02541 case binding_function:
02542 break;
02543 }
02544 }
02545 }
02546 return ISC_R_SUCCESS;
02547 }
02548
02549