]> git.ipfire.org Git - thirdparty/dhcp.git/blame - server/omapi.c
- Merge changes between 3.0.3RC1 and 3.0.4-BETA-3 into HEAD (silence
[thirdparty/dhcp.git] / server / omapi.c
CommitLineData
1c522252
TL
1/* omapi.c
2
3 OMAPI object interfaces for the DHCP server. */
4
5/*
88cd8aca 6 * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
98311e4b 7 * Copyright (c) 1999-2003 by Internet Software Consortium
1c522252 8 *
98311e4b
DH
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
1c522252 12 *
98311e4b
DH
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1c522252 20 *
98311e4b
DH
21 * Internet Systems Consortium, Inc.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
25 * http://www.isc.org/
49733f31 26 *
98311e4b 27 * This software has been written for Internet Systems Consortium
49733f31 28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
98311e4b 29 * To learn more about Internet Systems Consortium, see
49733f31
TL
30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
1c522252
TL
33 */
34
35/* Many, many thanks to Brian Murrell and BCtel for this code - BCtel
36 provided the funding that resulted in this code and the entire
37 OMAPI support library being written, and Brian helped brainstorm
38 and refine the requirements. To the extent that this code is
39 useful, you have Brian and BCtel to thank. Any limitations in the
40 code are a result of mistakes on my part. -- Ted Lemon */
41
42#ifndef lint
43static char copyright[] =
88cd8aca 44"$Id: omapi.c,v 1.55 2006/02/24 23:16:32 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
1c522252
TL
45#endif /* not lint */
46
47#include "dhcpd.h"
6a4c4be8 48#include <omapip/omapip_p.h>
1c522252 49
d758ad8c
TL
50static isc_result_t class_lookup (omapi_object_t **,
51 omapi_object_t *, omapi_object_t *,
52 omapi_object_type_t *);
53
1c522252 54omapi_object_type_t *dhcp_type_lease;
1c522252 55omapi_object_type_t *dhcp_type_pool;
1c522252 56omapi_object_type_t *dhcp_type_class;
5aa40fc5 57omapi_object_type_t *dhcp_type_subclass;
4e9f1404 58omapi_object_type_t *dhcp_type_host;
d9eefc5d 59#if defined (FAILOVER_PROTOCOL)
1edfbf5e
TL
60omapi_object_type_t *dhcp_type_failover_state;
61omapi_object_type_t *dhcp_type_failover_link;
62omapi_object_type_t *dhcp_type_failover_listener;
d9eefc5d 63#endif
1c522252
TL
64
65void dhcp_db_objects_setup ()
66{
67 isc_result_t status;
68
69 status = omapi_object_type_register (&dhcp_type_lease,
70 "lease",
71 dhcp_lease_set_value,
72 dhcp_lease_get_value,
73 dhcp_lease_destroy,
74 dhcp_lease_signal_handler,
75 dhcp_lease_stuff_values,
76 dhcp_lease_lookup,
110d0522 77 dhcp_lease_create,
20916cae 78 dhcp_lease_remove,
e9f0d7c3
TL
79#if defined (COMPACT_LEASES)
80 dhcp_lease_free,
0b1e395f 81 dhcp_lease_get,
e9f0d7c3 82#else
0b1e395f 83 0, 0,
e9f0d7c3
TL
84#endif
85 0,
98311e4b
DH
86 sizeof (struct lease),
87 0, RC_LEASE);
1c522252
TL
88 if (status != ISC_R_SUCCESS)
89 log_fatal ("Can't register lease object type: %s",
90 isc_result_totext (status));
91
20916cae
TL
92 status = omapi_object_type_register (&dhcp_type_class,
93 "class",
94 dhcp_class_set_value,
95 dhcp_class_get_value,
96 dhcp_class_destroy,
97 dhcp_class_signal_handler,
98 dhcp_class_stuff_values,
99 dhcp_class_lookup,
100 dhcp_class_create,
0b1e395f 101 dhcp_class_remove, 0, 0, 0,
98311e4b
DH
102 sizeof (struct class), 0,
103 RC_MISC);
b9626cbb 104 if (status != ISC_R_SUCCESS)
20916cae 105 log_fatal ("Can't register class object type: %s",
1c522252
TL
106 isc_result_totext (status));
107
5aa40fc5
TL
108 status = omapi_object_type_register (&dhcp_type_subclass,
109 "subclass",
110 dhcp_subclass_set_value,
111 dhcp_subclass_get_value,
d758ad8c 112 dhcp_class_destroy,
5aa40fc5
TL
113 dhcp_subclass_signal_handler,
114 dhcp_subclass_stuff_values,
115 dhcp_subclass_lookup,
116 dhcp_subclass_create,
117 dhcp_subclass_remove, 0, 0, 0,
98311e4b 118 sizeof (struct class), 0, RC_MISC);
5aa40fc5
TL
119 if (status != ISC_R_SUCCESS)
120 log_fatal ("Can't register subclass object type: %s",
121 isc_result_totext (status));
122
1c522252
TL
123 status = omapi_object_type_register (&dhcp_type_pool,
124 "pool",
125 dhcp_pool_set_value,
126 dhcp_pool_get_value,
127 dhcp_pool_destroy,
128 dhcp_pool_signal_handler,
129 dhcp_pool_stuff_values,
130 dhcp_pool_lookup,
110d0522 131 dhcp_pool_create,
0b1e395f 132 dhcp_pool_remove, 0, 0, 0,
98311e4b 133 sizeof (struct pool), 0, RC_MISC);
1edfbf5e 134
1c522252
TL
135 if (status != ISC_R_SUCCESS)
136 log_fatal ("Can't register pool object type: %s",
137 isc_result_totext (status));
1edfbf5e 138
4e9f1404
TL
139 status = omapi_object_type_register (&dhcp_type_host,
140 "host",
141 dhcp_host_set_value,
142 dhcp_host_get_value,
143 dhcp_host_destroy,
144 dhcp_host_signal_handler,
145 dhcp_host_stuff_values,
146 dhcp_host_lookup,
147 dhcp_host_create,
0b1e395f 148 dhcp_host_remove, 0, 0, 0,
98311e4b
DH
149 sizeof (struct host_decl),
150 0, RC_MISC);
4e9f1404
TL
151
152 if (status != ISC_R_SUCCESS)
153 log_fatal ("Can't register host object type: %s",
154 isc_result_totext (status));
155
1edfbf5e
TL
156#if defined (FAILOVER_PROTOCOL)
157 status = omapi_object_type_register (&dhcp_type_failover_state,
158 "failover-state",
159 dhcp_failover_state_set_value,
160 dhcp_failover_state_get_value,
161 dhcp_failover_state_destroy,
162 dhcp_failover_state_signal,
81694b6c 163 dhcp_failover_state_stuff,
1edfbf5e
TL
164 dhcp_failover_state_lookup,
165 dhcp_failover_state_create,
20916cae 166 dhcp_failover_state_remove,
0b1e395f 167 0, 0, 0,
f7172639 168 sizeof (dhcp_failover_state_t),
98311e4b 169 0, RC_MISC);
1edfbf5e
TL
170
171 if (status != ISC_R_SUCCESS)
172 log_fatal ("Can't register failover state object type: %s",
173 isc_result_totext (status));
174
175 status = omapi_object_type_register (&dhcp_type_failover_link,
176 "failover-link",
177 dhcp_failover_link_set_value,
178 dhcp_failover_link_get_value,
179 dhcp_failover_link_destroy,
180 dhcp_failover_link_signal,
81694b6c 181 dhcp_failover_link_stuff_values,
0b1e395f 182 0, 0, 0, 0, 0, 0,
98311e4b
DH
183 sizeof (dhcp_failover_link_t), 0,
184 RC_MISC);
1edfbf5e
TL
185
186 if (status != ISC_R_SUCCESS)
187 log_fatal ("Can't register failover link object type: %s",
188 isc_result_totext (status));
189
190 status = omapi_object_type_register (&dhcp_type_failover_listener,
191 "failover-listener",
192 dhcp_failover_listener_set_value,
193 dhcp_failover_listener_get_value,
194 dhcp_failover_listener_destroy,
195 dhcp_failover_listener_signal,
196 dhcp_failover_listener_stuff,
0b1e395f 197 0, 0, 0, 0, 0, 0,
20916cae 198 sizeof
98311e4b
DH
199 (dhcp_failover_listener_t), 0,
200 RC_MISC);
1edfbf5e
TL
201
202 if (status != ISC_R_SUCCESS)
203 log_fatal ("Can't register failover listener object type: %s",
204 isc_result_totext (status));
205#endif /* FAILOVER_PROTOCOL */
1c522252
TL
206}
207
208isc_result_t dhcp_lease_set_value (omapi_object_t *h,
209 omapi_object_t *id,
210 omapi_data_string_t *name,
211 omapi_typed_data_t *value)
212{
213 struct lease *lease;
214 isc_result_t status;
215 int foo;
216
808db3d3 217 if (h -> type != dhcp_type_lease)
1c522252
TL
218 return ISC_R_INVALIDARG;
219 lease = (struct lease *)h;
220
221 /* We're skipping a lot of things it might be interesting to
007e3ee4
TL
222 set - for now, we just make it possible to whack the state. */
223 if (!omapi_ds_strcmp (name, "state")) {
d758ad8c 224 unsigned long bar;
98311e4b 225 const char *ols, *nls;
d758ad8c
TL
226 status = omapi_get_int_value (&bar, value);
227 if (status != ISC_R_SUCCESS)
228 return status;
229
98311e4b 230 if (bar < 1 || bar > FTS_LAST)
d758ad8c 231 return ISC_R_INVALIDARG;
98311e4b
DH
232 nls = binding_state_names [bar - 1];
233 if (lease -> binding_state >= 1 &&
234 lease -> binding_state <= FTS_LAST)
235 ols = binding_state_names [lease -> binding_state - 1];
236 else
237 ols = "unknown state";
238
d758ad8c
TL
239 if (lease -> binding_state != bar) {
240 lease -> next_binding_state = bar;
98311e4b
DH
241 if (supersede_lease (lease, 0, 1, 1, 1)) {
242 log_info ("lease %s state changed from %s to %s",
243 piaddr(lease->ip_addr), ols, nls);
d758ad8c 244 return ISC_R_SUCCESS;
98311e4b
DH
245 }
246 log_info ("lease %s state change from %s to %s failed.",
247 piaddr (lease -> ip_addr), ols, nls);
d758ad8c
TL
248 return ISC_R_IOERROR;
249 }
250 return ISC_R_UNCHANGED;
8c63dd89 251 } else if (!omapi_ds_strcmp (name, "ip-address")) {
d758ad8c 252 return ISC_R_NOPERM;
8c63dd89 253 } else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
d758ad8c 254 return ISC_R_UNCHANGED; /* XXX take change. */
8c63dd89 255 } else if (!omapi_ds_strcmp (name, "hostname")) {
d758ad8c 256 return ISC_R_UNCHANGED; /* XXX take change. */
8c63dd89 257 } else if (!omapi_ds_strcmp (name, "client-hostname")) {
d758ad8c 258 return ISC_R_UNCHANGED; /* XXX take change. */
8c63dd89 259 } else if (!omapi_ds_strcmp (name, "host")) {
d758ad8c 260 return ISC_R_UNCHANGED; /* XXX take change. */
8c63dd89 261 } else if (!omapi_ds_strcmp (name, "subnet")) {
d758ad8c 262 return ISC_R_INVALIDARG;
8c63dd89 263 } else if (!omapi_ds_strcmp (name, "pool")) {
d758ad8c 264 return ISC_R_NOPERM;
8c63dd89 265 } else if (!omapi_ds_strcmp (name, "starts")) {
d758ad8c 266 return ISC_R_NOPERM;
8c63dd89 267 } else if (!omapi_ds_strcmp (name, "ends")) {
d758ad8c 268 return ISC_R_NOPERM;
8c63dd89 269 } else if (!omapi_ds_strcmp (name, "billing-class")) {
d758ad8c 270 return ISC_R_UNCHANGED; /* XXX carefully allow change. */
8c63dd89 271 } else if (!omapi_ds_strcmp (name, "hardware-address")) {
d758ad8c 272 return ISC_R_UNCHANGED; /* XXX take change. */
8c63dd89 273 } else if (!omapi_ds_strcmp (name, "hardware-type")) {
d758ad8c
TL
274 return ISC_R_UNCHANGED; /* XXX take change. */
275 } else if (lease -> scope) {
276 status = binding_scope_set_value (lease -> scope, 0, name, value);
277 if (status == ISC_R_SUCCESS) {
278 if (write_lease (lease) && commit_leases ())
279 return ISC_R_SUCCESS;
280 return ISC_R_IOERROR;
281 }
1c522252
TL
282 }
283
284 /* Try to find some inner object that can take the value. */
285 if (h -> inner && h -> inner -> type -> set_value) {
286 status = ((*(h -> inner -> type -> set_value))
287 (h -> inner, id, name, value));
288 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
289 return status;
290 }
291
d758ad8c
TL
292 if (!lease -> scope) {
293 if (!binding_scope_allocate (&lease -> scope, MDL))
294 return ISC_R_NOMEMORY;
295 }
296 status = binding_scope_set_value (lease -> scope, 1, name, value);
297 if (status != ISC_R_SUCCESS)
298 return status;
299
300 if (write_lease (lease) && commit_leases ())
301 return ISC_R_SUCCESS;
302 return ISC_R_IOERROR;
1c522252
TL
303}
304
305
306isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id,
307 omapi_data_string_t *name,
308 omapi_value_t **value)
309{
310 struct lease *lease;
311 isc_result_t status;
312
313 if (h -> type != dhcp_type_lease)
314 return ISC_R_INVALIDARG;
315 lease = (struct lease *)h;
316
007e3ee4 317 if (!omapi_ds_strcmp (name, "state"))
1c522252 318 return omapi_make_int_value (value, name,
007e3ee4 319 (int)lease -> binding_state, MDL);
1c522252
TL
320 else if (!omapi_ds_strcmp (name, "ip-address"))
321 return omapi_make_const_value (value, name,
322 lease -> ip_addr.iabuf,
4bd8800e 323 lease -> ip_addr.len, MDL);
c7775a73 324 else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
1c522252
TL
325 return omapi_make_const_value (value, name,
326 lease -> uid,
4bd8800e 327 lease -> uid_len, MDL);
c7775a73
TL
328 } else if (!omapi_ds_strcmp (name, "client-hostname")) {
329 if (lease -> client_hostname)
330 return omapi_make_string_value
4bd8800e 331 (value, name, lease -> client_hostname, MDL);
c7775a73 332 return ISC_R_NOTFOUND;
c7775a73
TL
333 } else if (!omapi_ds_strcmp (name, "host")) {
334 if (lease -> host)
335 return omapi_make_handle_value
336 (value, name,
4bd8800e 337 ((omapi_object_t *)lease -> host), MDL);
c7775a73 338 } else if (!omapi_ds_strcmp (name, "subnet"))
1c522252
TL
339 return omapi_make_handle_value (value, name,
340 ((omapi_object_t *)
4bd8800e 341 lease -> subnet), MDL);
1c522252
TL
342 else if (!omapi_ds_strcmp (name, "pool"))
343 return omapi_make_handle_value (value, name,
344 ((omapi_object_t *)
4bd8800e 345 lease -> pool), MDL);
c7775a73
TL
346 else if (!omapi_ds_strcmp (name, "billing-class")) {
347 if (lease -> billing_class)
348 return omapi_make_handle_value
349 (value, name,
350 ((omapi_object_t *)lease -> billing_class),
4bd8800e 351 MDL);
c7775a73 352 return ISC_R_NOTFOUND;
4244dfb7
DN
353 } else if (!omapi_ds_strcmp (name, "hardware-address")) {
354 if (lease -> hardware_addr.hlen)
355 return omapi_make_const_value
356 (value, name, &lease -> hardware_addr.hbuf [1],
357 (unsigned)(lease -> hardware_addr.hlen - 1),
358 MDL);
359 return ISC_R_NOTFOUND;
360 } else if (!omapi_ds_strcmp (name, "hardware-type")) {
361 if (lease -> hardware_addr.hlen)
362 return omapi_make_int_value
363 (value, name, lease -> hardware_addr.hbuf [0],
364 MDL);
365 return ISC_R_NOTFOUND;
d758ad8c
TL
366 } else if (lease -> scope) {
367 status = binding_scope_get_value (value, lease -> scope, name);
368 if (status != ISC_R_NOTFOUND)
369 return status;
4244dfb7 370 }
1c522252
TL
371
372 /* Try to find some inner object that can take the value. */
373 if (h -> inner && h -> inner -> type -> get_value) {
374 status = ((*(h -> inner -> type -> get_value))
375 (h -> inner, id, name, value));
376 if (status == ISC_R_SUCCESS)
377 return status;
378 }
d758ad8c 379 return ISC_R_UNKNOWNATTRIBUTE;
1c522252
TL
380}
381
4bd8800e 382isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line)
1c522252
TL
383{
384 struct lease *lease;
385 isc_result_t status;
386
387 if (h -> type != dhcp_type_lease)
388 return ISC_R_INVALIDARG;
389 lease = (struct lease *)h;
390
31bbee78
TL
391 if (lease -> uid)
392 uid_hash_delete (lease);
1c522252 393 hw_hash_delete (lease);
31bbee78
TL
394
395 if (lease -> on_release)
396 executable_statement_dereference (&lease -> on_release,
397 file, line);
398 if (lease -> on_expiry)
399 executable_statement_dereference (&lease -> on_expiry,
400 file, line);
401 if (lease -> on_commit)
402 executable_statement_dereference (&lease -> on_commit,
403 file, line);
404 if (lease -> scope)
405 binding_scope_dereference (&lease -> scope, file, line);
406
407 if (lease -> agent_options)
408 option_chain_head_dereference (&lease -> agent_options,
409 file, line);
410 if (lease -> uid && lease -> uid != lease -> uid_buf) {
4bd8800e 411 dfree (lease -> uid, MDL);
1c522252
TL
412 lease -> uid = &lease -> uid_buf [0];
413 lease -> uid_len = 0;
414 }
31bbee78 415
1c522252 416 if (lease -> client_hostname) {
4bd8800e 417 dfree (lease -> client_hostname, MDL);
e42c3826 418 lease -> client_hostname = (char *)0;
1c522252 419 }
31bbee78 420
1c522252 421 if (lease -> host)
20916cae 422 host_dereference (&lease -> host, file, line);
1c522252 423 if (lease -> subnet)
20916cae 424 subnet_dereference (&lease -> subnet, file, line);
1c522252 425 if (lease -> pool)
20916cae 426 pool_dereference (&lease -> pool, file, line);
31bbee78 427
1c522252 428 if (lease -> state) {
4bd8800e 429 free_lease_state (lease -> state, file, line);
1c522252
TL
430 lease -> state = (struct lease_state *)0;
431
432 cancel_timeout (lease_ping_timeout, lease);
433 --outstanding_pings; /* XXX */
434 }
31bbee78
TL
435
436 if (lease -> billing_class)
437 class_dereference
438 (&lease -> billing_class, file, line);
439
d758ad8c
TL
440#if defined (DEBUG_MEMORY_LEAKAGE) || \
441 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
442 /* XXX we should never be destroying a lease with a next
443 XXX pointer except on exit... */
444 if (lease -> next)
445 lease_dereference (&lease -> next, file, line);
446 if (lease -> n_hw)
447 lease_dereference (&lease -> n_hw, file, line);
448 if (lease -> n_uid)
449 lease_dereference (&lease -> n_uid, file, line);
450 if (lease -> next_pending)
451 lease_dereference (&lease -> next_pending, file, line);
452#endif
453
1c522252
TL
454 return ISC_R_SUCCESS;
455}
456
457isc_result_t dhcp_lease_signal_handler (omapi_object_t *h,
b1b7b521 458 const char *name, va_list ap)
1c522252
TL
459{
460 struct lease *lease;
461 isc_result_t status;
b9626cbb 462 int updatep = 0;
1c522252
TL
463
464 if (h -> type != dhcp_type_lease)
465 return ISC_R_INVALIDARG;
466 lease = (struct lease *)h;
467
d758ad8c
TL
468 if (!strcmp (name, "updated"))
469 return ISC_R_SUCCESS;
1c522252
TL
470
471 /* Try to find some inner object that can take the value. */
19f7a4d7 472 if (h -> inner && h -> inner -> type -> signal_handler) {
1c522252
TL
473 status = ((*(h -> inner -> type -> signal_handler))
474 (h -> inner, name, ap));
475 if (status == ISC_R_SUCCESS)
476 return status;
477 }
478 return ISC_R_NOTFOUND;
479}
480
481isc_result_t dhcp_lease_stuff_values (omapi_object_t *c,
482 omapi_object_t *id,
483 omapi_object_t *h)
484{
88cd8aca 485 u_int32_t bouncer;
1c522252
TL
486 struct lease *lease;
487 isc_result_t status;
488
489 if (h -> type != dhcp_type_lease)
490 return ISC_R_INVALIDARG;
491 lease = (struct lease *)h;
492
493 /* Write out all the values. */
494
007e3ee4 495 status = omapi_connection_put_name (c, "state");
1c522252
TL
496 if (status != ISC_R_SUCCESS)
497 return status;
498 status = omapi_connection_put_uint32 (c, sizeof (int));
499 if (status != ISC_R_SUCCESS)
500 return status;
007e3ee4 501 status = omapi_connection_put_uint32 (c, lease -> binding_state);
1c522252
TL
502 if (status != ISC_R_SUCCESS)
503 return status;
504
505 status = omapi_connection_put_name (c, "ip-address");
506 if (status != ISC_R_SUCCESS)
507 return status;
508 status = omapi_connection_put_uint32 (c, lease -> ip_addr.len);
509 if (status != ISC_R_SUCCESS)
510 return status;
511 status = omapi_connection_copyin (c, lease -> ip_addr.iabuf,
512 lease -> ip_addr.len);
513 if (status != ISC_R_SUCCESS)
514 return status;
515
1c522252 516 if (lease -> uid_len) {
8c63dd89
TL
517 status = omapi_connection_put_name (c,
518 "dhcp-client-identifier");
519 if (status != ISC_R_SUCCESS)
520 return status;
521 status = omapi_connection_put_uint32 (c, lease -> uid_len);
1c522252
TL
522 if (status != ISC_R_SUCCESS)
523 return status;
8c63dd89
TL
524 if (lease -> uid_len) {
525 status = omapi_connection_copyin (c, lease -> uid,
526 lease -> uid_len);
527 if (status != ISC_R_SUCCESS)
528 return status;
529 }
1c522252
TL
530 }
531
8c63dd89
TL
532 if (lease -> client_hostname) {
533 status = omapi_connection_put_name (c, "client-hostname");
534 if (status != ISC_R_SUCCESS)
535 return status;
536 status =
537 omapi_connection_put_string (c,
538 lease -> client_hostname);
539 if (status != ISC_R_SUCCESS)
540 return status;
541 }
1c522252 542
8c63dd89
TL
543 if (lease -> host) {
544 status = omapi_connection_put_name (c, "host");
545 if (status != ISC_R_SUCCESS)
546 return status;
547 status = omapi_connection_put_handle (c,
548 (omapi_object_t *)
549 lease -> host);
550 if (status != ISC_R_SUCCESS)
551 return status;
552 }
1c522252
TL
553
554 status = omapi_connection_put_name (c, "subnet");
555 if (status != ISC_R_SUCCESS)
556 return status;
557 status = omapi_connection_put_handle
558 (c, (omapi_object_t *)lease -> subnet);
559 if (status != ISC_R_SUCCESS)
560 return status;
561
562 status = omapi_connection_put_name (c, "pool");
563 if (status != ISC_R_SUCCESS)
564 return status;
565 status = omapi_connection_put_handle (c,
566 (omapi_object_t *)lease -> pool);
567 if (status != ISC_R_SUCCESS)
568 return status;
569
8c63dd89
TL
570 if (lease -> billing_class) {
571 status = omapi_connection_put_name (c, "billing-class");
572 if (status != ISC_R_SUCCESS)
573 return status;
574 status = omapi_connection_put_handle
575 (c, (omapi_object_t *)lease -> billing_class);
576 if (status != ISC_R_SUCCESS)
577 return status;
578 }
1c522252 579
4244dfb7
DN
580 if (lease -> hardware_addr.hlen) {
581 status = omapi_connection_put_name (c, "hardware-address");
582 if (status != ISC_R_SUCCESS)
583 return status;
584 status = (omapi_connection_put_uint32
585 (c,
586 (unsigned long)(lease -> hardware_addr.hlen - 1)));
587 if (status != ISC_R_SUCCESS)
588 return status;
589 status = (omapi_connection_copyin
590 (c, &lease -> hardware_addr.hbuf [1],
591 (unsigned long)(lease -> hardware_addr.hlen - 1)));
1c522252 592
4244dfb7
DN
593 if (status != ISC_R_SUCCESS)
594 return status;
595
596 status = omapi_connection_put_name (c, "hardware-type");
597 if (status != ISC_R_SUCCESS)
598 return status;
599 status = omapi_connection_put_uint32 (c, sizeof (int));
600 if (status != ISC_R_SUCCESS)
601 return status;
602 status = omapi_connection_put_uint32
603 (c, lease -> hardware_addr.hbuf [0]);
604 if (status != ISC_R_SUCCESS)
605 return status;
606 }
1c522252 607
88cd8aca
DH
608 /* TIME values may be 64-bit, depending on system architecture.
609 * OMAPI must be system independent, both in terms of transmitting
610 * bytes on the wire in network byte order, and in terms of being
611 * readable and usable by both systems.
612 *
613 * XXX: In a future feature release, a put_int64() should be made
614 * to exist, and perhaps a put_time() wrapper that selects which
615 * to use based upon sizeof(TIME). In the meantime, use existing,
616 * 32-bit, code.
617 */
618 bouncer = (u_int32_t)lease->ends;
619 status = omapi_connection_put_name(c, "ends");
620 if (status != ISC_R_SUCCESS)
621 return status;
622 status = omapi_connection_put_uint32(c, sizeof(bouncer));
623 if (status != ISC_R_SUCCESS)
624 return status;
625 status = omapi_connection_put_uint32(c, bouncer);
626 if (status != ISC_R_SUCCESS)
627 return status;
0d124b66 628
88cd8aca
DH
629 bouncer = (u_int32_t)lease->starts;
630 status = omapi_connection_put_name(c, "starts");
0d124b66
TL
631 if (status != ISC_R_SUCCESS)
632 return status;
88cd8aca 633 status = omapi_connection_put_uint32(c, sizeof(bouncer));
0d124b66
TL
634 if (status != ISC_R_SUCCESS)
635 return status;
88cd8aca 636 status = omapi_connection_put_uint32(c, bouncer);
0d124b66
TL
637 if (status != ISC_R_SUCCESS)
638 return status;
639
88cd8aca
DH
640 bouncer = (u_int32_t)lease->tstp;
641 status = omapi_connection_put_name(c, "tstp");
0d124b66
TL
642 if (status != ISC_R_SUCCESS)
643 return status;
88cd8aca 644 status = omapi_connection_put_uint32(c, sizeof(bouncer));
0d124b66
TL
645 if (status != ISC_R_SUCCESS)
646 return status;
88cd8aca 647 status = omapi_connection_put_uint32(c, bouncer);
0d124b66
TL
648 if (status != ISC_R_SUCCESS)
649 return status;
650
88cd8aca
DH
651 bouncer = (u_int32_t)lease->tsfp;
652 status = omapi_connection_put_name(c, "tsfp");
19f7a4d7
TL
653 if (status != ISC_R_SUCCESS)
654 return status;
88cd8aca 655 status = omapi_connection_put_uint32(c, sizeof(bouncer));
19f7a4d7
TL
656 if (status != ISC_R_SUCCESS)
657 return status;
88cd8aca 658 status = omapi_connection_put_uint32(c, bouncer);
19f7a4d7
TL
659 if (status != ISC_R_SUCCESS)
660 return status;
661
88cd8aca
DH
662 bouncer = (u_int32_t)lease->atsfp;
663 status = omapi_connection_put_name(c, "atsfp");
19f7a4d7
TL
664 if (status != ISC_R_SUCCESS)
665 return status;
88cd8aca 666 status = omapi_connection_put_uint32(c, sizeof(bouncer));
19f7a4d7
TL
667 if (status != ISC_R_SUCCESS)
668 return status;
88cd8aca 669 status = omapi_connection_put_uint32(c, bouncer);
19f7a4d7
TL
670 if (status != ISC_R_SUCCESS)
671 return status;
672
88cd8aca
DH
673 bouncer = (u_int32_t)lease->cltt;
674 status = omapi_connection_put_name(c, "cltt");
19f7a4d7
TL
675 if (status != ISC_R_SUCCESS)
676 return status;
88cd8aca 677 status = omapi_connection_put_uint32(c, sizeof(bouncer));
19f7a4d7
TL
678 if (status != ISC_R_SUCCESS)
679 return status;
88cd8aca 680 status = omapi_connection_put_uint32(c, bouncer);
19f7a4d7
TL
681 if (status != ISC_R_SUCCESS)
682 return status;
683
d758ad8c
TL
684 if (lease -> scope) {
685 status = binding_scope_stuff_values (c, lease -> scope);
686 if (status != ISC_R_SUCCESS)
687 return status;
688 }
689
1c522252
TL
690 /* Write out the inner object, if any. */
691 if (h -> inner && h -> inner -> type -> stuff_values) {
692 status = ((*(h -> inner -> type -> stuff_values))
693 (c, id, h -> inner));
694 if (status == ISC_R_SUCCESS)
695 return status;
696 }
697
698 return ISC_R_SUCCESS;
699}
700
701isc_result_t dhcp_lease_lookup (omapi_object_t **lp,
702 omapi_object_t *id, omapi_object_t *ref)
703{
704 omapi_value_t *tv = (omapi_value_t *)0;
705 isc_result_t status;
706 struct lease *lease;
707
d758ad8c
TL
708 if (!ref)
709 return ISC_R_NOKEYS;
710
1c522252
TL
711 /* First see if we were sent a handle. */
712 status = omapi_get_value_str (ref, id, "handle", &tv);
713 if (status == ISC_R_SUCCESS) {
714 status = omapi_handle_td_lookup (lp, tv -> value);
715
4bd8800e 716 omapi_value_dereference (&tv, MDL);
1c522252
TL
717 if (status != ISC_R_SUCCESS)
718 return status;
719
720 /* Don't return the object if the type is wrong. */
721 if ((*lp) -> type != dhcp_type_lease) {
4bd8800e 722 omapi_object_dereference (lp, MDL);
1c522252
TL
723 return ISC_R_INVALIDARG;
724 }
725 }
726
727 /* Now look for an IP address. */
8ac1b7ba 728 status = omapi_get_value_str (ref, id, "ip-address", &tv);
1c522252 729 if (status == ISC_R_SUCCESS) {
20916cae
TL
730 lease = (struct lease *)0;
731 lease_hash_lookup (&lease, lease_ip_addr_hash,
732 tv -> value -> u.buffer.value,
733 tv -> value -> u.buffer.len, MDL);
1c522252 734
4bd8800e 735 omapi_value_dereference (&tv, MDL);
1c522252 736
b9626cbb
TL
737 /* If we already have a lease, and it's not the same one,
738 then the query was invalid. */
739 if (*lp && *lp != (omapi_object_t *)lease) {
4bd8800e 740 omapi_object_dereference (lp, MDL);
20916cae 741 lease_dereference (&lease, MDL);
b9626cbb
TL
742 return ISC_R_KEYCONFLICT;
743 } else if (!lease) {
744 if (*lp)
4bd8800e 745 omapi_object_dereference (lp, MDL);
1c522252 746 return ISC_R_NOTFOUND;
20916cae 747 } else if (!*lp) {
b9626cbb
TL
748 /* XXX fix so that hash lookup itself creates
749 XXX the reference. */
4bd8800e
TL
750 omapi_object_reference (lp,
751 (omapi_object_t *)lease, MDL);
20916cae
TL
752 lease_dereference (&lease, MDL);
753 }
1c522252
TL
754 }
755
756 /* Now look for a client identifier. */
757 status = omapi_get_value_str (ref, id, "dhcp-client-identifier", &tv);
758 if (status == ISC_R_SUCCESS) {
20916cae
TL
759 lease = (struct lease *)0;
760 lease_hash_lookup (&lease, lease_uid_hash,
761 tv -> value -> u.buffer.value,
762 tv -> value -> u.buffer.len, MDL);
4bd8800e 763 omapi_value_dereference (&tv, MDL);
1c522252 764
b9626cbb 765 if (*lp && *lp != (omapi_object_t *)lease) {
4bd8800e 766 omapi_object_dereference (lp, MDL);
20916cae 767 lease_dereference (&lease, MDL);
b9626cbb
TL
768 return ISC_R_KEYCONFLICT;
769 } else if (!lease) {
770 if (*lp)
4bd8800e 771 omapi_object_dereference (lp, MDL);
1c522252 772 return ISC_R_NOTFOUND;
b9626cbb
TL
773 } else if (lease -> n_uid) {
774 if (*lp)
4bd8800e 775 omapi_object_dereference (lp, MDL);
1c522252 776 return ISC_R_MULTIPLE;
b9626cbb
TL
777 } else if (!*lp) {
778 /* XXX fix so that hash lookup itself creates
779 XXX the reference. */
4bd8800e
TL
780 omapi_object_reference (lp,
781 (omapi_object_t *)lease, MDL);
20916cae 782 lease_dereference (&lease, MDL);
b9626cbb 783 }
1c522252
TL
784 }
785
786 /* Now look for a hardware address. */
787 status = omapi_get_value_str (ref, id, "hardware-address", &tv);
788 if (status == ISC_R_SUCCESS) {
98311e4b
DH
789 unsigned char *haddr;
790 unsigned int len;
791
792 len = tv -> value -> u.buffer.len + 1;
793 haddr = dmalloc (len, MDL);
794 if (!haddr) {
795 omapi_value_dereference (&tv, MDL);
796 return ISC_R_NOMEMORY;
797 }
798
799 memcpy (haddr + 1, tv -> value -> u.buffer.value, len - 1);
4bd8800e 800 omapi_value_dereference (&tv, MDL);
98311e4b
DH
801
802 status = omapi_get_value_str (ref, id, "hardware-type", &tv);
803 if (status == ISC_R_SUCCESS) {
804 if (tv -> value -> type == omapi_datatype_data) {
805 if ((tv -> value -> u.buffer.len != 4) ||
806 (tv -> value -> u.buffer.value[0] != 0) ||
807 (tv -> value -> u.buffer.value[1] != 0) ||
808 (tv -> value -> u.buffer.value[2] != 0)) {
809 omapi_value_dereference (&tv, MDL);
810 dfree (haddr, MDL);
811 return ISC_R_INVALIDARG;
812 }
813
814 haddr[0] = tv -> value -> u.buffer.value[3];
815 } else if (tv -> value -> type == omapi_datatype_int) {
816 haddr[0] = (unsigned char)
817 tv -> value -> u.integer;
818 } else {
819 omapi_value_dereference (&tv, MDL);
820 dfree (haddr, MDL);
821 return ISC_R_INVALIDARG;
822 }
823
824 omapi_value_dereference (&tv, MDL);
825 } else {
826 /* If no hardware-type is specified, default to
827 ethernet. This may or may not be a good idea,
828 but Telus is currently relying on this behavior.
829 - DPN */
830 haddr[0] = HTYPE_ETHER;
831 }
832
833 lease = (struct lease *)0;
834 lease_hash_lookup (&lease, lease_hw_addr_hash, haddr, len, MDL);
835 dfree (haddr, MDL);
836
b9626cbb 837 if (*lp && *lp != (omapi_object_t *)lease) {
4bd8800e 838 omapi_object_dereference (lp, MDL);
20916cae 839 lease_dereference (&lease, MDL);
b9626cbb
TL
840 return ISC_R_KEYCONFLICT;
841 } else if (!lease) {
842 if (*lp)
4bd8800e 843 omapi_object_dereference (lp, MDL);
1c522252 844 return ISC_R_NOTFOUND;
b9626cbb
TL
845 } else if (lease -> n_hw) {
846 if (*lp)
4bd8800e 847 omapi_object_dereference (lp, MDL);
20916cae 848 lease_dereference (&lease, MDL);
1c522252 849 return ISC_R_MULTIPLE;
b9626cbb
TL
850 } else if (!*lp) {
851 /* XXX fix so that hash lookup itself creates
852 XXX the reference. */
4bd8800e
TL
853 omapi_object_reference (lp,
854 (omapi_object_t *)lease, MDL);
20916cae 855 lease_dereference (&lease, MDL);
b9626cbb 856 }
1c522252
TL
857 }
858
859 /* If we get to here without finding a lease, no valid key was
860 specified. */
861 if (!*lp)
5a0931a1 862 return ISC_R_NOKEYS;
1c522252
TL
863 return ISC_R_SUCCESS;
864}
865
866isc_result_t dhcp_lease_create (omapi_object_t **lp,
867 omapi_object_t *id)
868{
869 return ISC_R_NOTIMPLEMENTED;
870}
871
ccce1cc6 872isc_result_t dhcp_lease_remove (omapi_object_t *lp,
110d0522
TL
873 omapi_object_t *id)
874{
875 return ISC_R_NOTIMPLEMENTED;
876}
877
b9626cbb
TL
878isc_result_t dhcp_host_set_value (omapi_object_t *h,
879 omapi_object_t *id,
880 omapi_data_string_t *name,
881 omapi_typed_data_t *value)
1c522252 882{
d758ad8c 883 struct host_decl *host, *hp;
1c522252
TL
884 isc_result_t status;
885 int foo;
886
808db3d3 887 if (h -> type != dhcp_type_host)
1c522252
TL
888 return ISC_R_INVALIDARG;
889 host = (struct host_decl *)h;
890
891 /* XXX For now, we can only set these values on new host objects.
892 XXX Soon, we need to be able to update host objects. */
893 if (!omapi_ds_strcmp (name, "name")) {
894 if (host -> name)
895 return ISC_R_EXISTS;
98311e4b
DH
896 if (value && (value -> type == omapi_datatype_data ||
897 value -> type == omapi_datatype_string)) {
4bd8800e
TL
898 host -> name = dmalloc (value -> u.buffer.len + 1,
899 MDL);
1c522252
TL
900 if (!host -> name)
901 return ISC_R_NOMEMORY;
902 memcpy (host -> name,
903 value -> u.buffer.value,
904 value -> u.buffer.len);
905 host -> name [value -> u.buffer.len] = 0;
906 } else
907 return ISC_R_INVALIDARG;
908 return ISC_R_SUCCESS;
909 }
910
b9626cbb 911 if (!omapi_ds_strcmp (name, "group")) {
98311e4b
DH
912 if (value && (value -> type == omapi_datatype_data ||
913 value -> type == omapi_datatype_string)) {
b9626cbb 914 struct group_object *group;
20916cae
TL
915 group = (struct group_object *)0;
916 group_hash_lookup (&group, group_name_hash,
229a47a8 917 (char *)value -> u.buffer.value,
20916cae 918 value -> u.buffer.len, MDL);
b9626cbb
TL
919 if (!group || (group -> flags & GROUP_OBJECT_DELETED))
920 return ISC_R_NOTFOUND;
72c7d498
TL
921 if (host -> group)
922 group_dereference (&host -> group, MDL);
20916cae 923 group_reference (&host -> group, group -> group, MDL);
b9626cbb 924 if (host -> named_group)
20916cae
TL
925 group_object_dereference (&host -> named_group,
926 MDL);
927 group_object_reference (&host -> named_group,
928 group, MDL);
929 group_object_dereference (&group, MDL);
b9626cbb
TL
930 } else
931 return ISC_R_INVALIDARG;
932 return ISC_R_SUCCESS;
933 }
934
1c522252
TL
935 if (!omapi_ds_strcmp (name, "hardware-address")) {
936 if (host -> interface.hlen)
937 return ISC_R_EXISTS;
98311e4b
DH
938 if (value && (value -> type == omapi_datatype_data ||
939 value -> type == omapi_datatype_string)) {
1c522252 940 if (value -> u.buffer.len >
180b8f2b 941 (sizeof host -> interface.hbuf) - 1)
1c522252 942 return ISC_R_INVALIDARG;
180b8f2b 943 memcpy (&host -> interface.hbuf [1],
1c522252
TL
944 value -> u.buffer.value,
945 value -> u.buffer.len);
180b8f2b 946 host -> interface.hlen = value -> u.buffer.len + 1;
1c522252
TL
947 } else
948 return ISC_R_INVALIDARG;
949 return ISC_R_SUCCESS;
950 }
951
952 if (!omapi_ds_strcmp (name, "hardware-type")) {
953 int type;
98311e4b
DH
954 if (value && (value -> type == omapi_datatype_data &&
955 value -> u.buffer.len == sizeof type)) {
180b8f2b 956 if (value -> u.buffer.len > sizeof type)
1c522252
TL
957 return ISC_R_INVALIDARG;
958 memcpy (&type,
959 value -> u.buffer.value,
960 value -> u.buffer.len);
36b1ebcf 961 type = ntohl (type);
1c522252
TL
962 } else if (value -> type == omapi_datatype_int)
963 type = value -> u.integer;
964 else
965 return ISC_R_INVALIDARG;
180b8f2b 966 host -> interface.hbuf [0] = type;
1c522252
TL
967 return ISC_R_SUCCESS;
968 }
969
970 if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
971 if (host -> client_identifier.data)
972 return ISC_R_EXISTS;
98311e4b
DH
973 if (value && (value -> type == omapi_datatype_data ||
974 value -> type == omapi_datatype_string)) {
4bd8800e
TL
975 if (!buffer_allocate (&host -> client_identifier.buffer,
976 value -> u.buffer.len, MDL))
977 return ISC_R_NOMEMORY;
978 host -> client_identifier.data =
979 &host -> client_identifier.buffer -> data [0];
980 memcpy (host -> client_identifier.buffer -> data,
981 value -> u.buffer.value,
982 value -> u.buffer.len);
983 host -> client_identifier.len = value -> u.buffer.len;
1c522252 984 } else
4bd8800e 985 return ISC_R_INVALIDARG;
1c522252
TL
986 return ISC_R_SUCCESS;
987 }
988
989 if (!omapi_ds_strcmp (name, "ip-address")) {
990 if (host -> fixed_addr)
d758ad8c
TL
991 option_cache_dereference (&host -> fixed_addr, MDL);
992 if (!value)
993 return ISC_R_SUCCESS;
98311e4b
DH
994 if (value && (value -> type == omapi_datatype_data ||
995 value -> type == omapi_datatype_string)) {
1c522252
TL
996 struct data_string ds;
997 memset (&ds, 0, sizeof ds);
998 ds.len = value -> u.buffer.len;
4bd8800e 999 if (!buffer_allocate (&ds.buffer, ds.len, MDL))
1c522252 1000 return ISC_R_NOMEMORY;
b9626cbb 1001 ds.data = (&ds.buffer -> data [0]);
b1b7b521
TL
1002 memcpy (ds.buffer -> data,
1003 value -> u.buffer.value, ds.len);
1c522252
TL
1004 if (!option_cache (&host -> fixed_addr,
1005 &ds, (struct expression *)0,
d758ad8c 1006 (struct option *)0, MDL)) {
4bd8800e 1007 data_string_forget (&ds, MDL);
1c522252
TL
1008 return ISC_R_NOMEMORY;
1009 }
4bd8800e 1010 data_string_forget (&ds, MDL);
1c522252
TL
1011 } else
1012 return ISC_R_INVALIDARG;
1013 return ISC_R_SUCCESS;
1014 }
1015
dc667e92 1016 if (!omapi_ds_strcmp (name, "statements")) {
20916cae
TL
1017 if (!host -> group) {
1018 if (!clone_group (&host -> group, root_group, MDL))
1019 return ISC_R_NOMEMORY;
1020 } else {
b74d3c6e
TL
1021 if (host -> group -> statements &&
1022 (!host -> named_group ||
1023 host -> group != host -> named_group -> group) &&
20916cae 1024 host -> group != root_group)
b74d3c6e 1025 return ISC_R_EXISTS;
20916cae
TL
1026 if (!clone_group (&host -> group, host -> group, MDL))
1027 return ISC_R_NOMEMORY;
dc667e92
TL
1028 }
1029 if (!host -> group)
1030 return ISC_R_NOMEMORY;
98311e4b
DH
1031 if (value && (value -> type == omapi_datatype_data ||
1032 value -> type == omapi_datatype_string)) {
dc667e92
TL
1033 struct parse *parse;
1034 int lose = 0;
1035 parse = (struct parse *)0;
1036 status = new_parse (&parse, -1,
1037 (char *)value -> u.buffer.value,
1038 value -> u.buffer.len,
dc66a995 1039 "network client", 0);
dc667e92
TL
1040 if (status != ISC_R_SUCCESS)
1041 return status;
1042 if (!(parse_executable_statements
301453ab
TL
1043 (&host -> group -> statements, parse, &lose,
1044 context_any))) {
dc667e92
TL
1045 end_parse (&parse);
1046 return ISC_R_BADPARSE;
1047 }
1048 end_parse (&parse);
1049 } else
1050 return ISC_R_INVALIDARG;
1051 return ISC_R_SUCCESS;
1052 }
1053
808db3d3
TL
1054 /* The "known" flag isn't supported in the database yet, but it's
1055 legitimate. */
1056 if (!omapi_ds_strcmp (name, "known")) {
1057 return ISC_R_SUCCESS;
1058 }
1059
1c522252
TL
1060 /* Try to find some inner object that can take the value. */
1061 if (h -> inner && h -> inner -> type -> set_value) {
1062 status = ((*(h -> inner -> type -> set_value))
1063 (h -> inner, id, name, value));
1064 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
1065 return status;
1066 }
1067
d758ad8c 1068 return ISC_R_UNKNOWNATTRIBUTE;
1c522252
TL
1069}
1070
1071
1072isc_result_t dhcp_host_get_value (omapi_object_t *h, omapi_object_t *id,
1073 omapi_data_string_t *name,
1074 omapi_value_t **value)
1075{
1076 struct host_decl *host;
1077 isc_result_t status;
1078 struct data_string ip_addrs;
1079
1080 if (h -> type != dhcp_type_host)
1081 return ISC_R_INVALIDARG;
1082 host = (struct host_decl *)h;
1083
1084 if (!omapi_ds_strcmp (name, "ip-addresses")) {
4bd8800e
TL
1085 memset (&ip_addrs, 0, sizeof ip_addrs);
1086 if (host -> fixed_addr &&
1087 evaluate_option_cache (&ip_addrs, (struct packet *)0,
1088 (struct lease *)0,
9e383163 1089 (struct client_state *)0,
4bd8800e
TL
1090 (struct option_state *)0,
1091 (struct option_state *)0,
1092 &global_scope,
1093 host -> fixed_addr, MDL)) {
1094 status = omapi_make_const_value (value, name,
1095 ip_addrs.data,
1096 ip_addrs.len, MDL);
1097 data_string_forget (&ip_addrs, MDL);
1098 return status;
1099 }
1100 return ISC_R_NOTFOUND;
1c522252
TL
1101 }
1102
1103 if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
1104 if (!host -> client_identifier.len)
1105 return ISC_R_NOTFOUND;
1106 return omapi_make_const_value (value, name,
1107 host -> client_identifier.data,
1108 host -> client_identifier.len,
4bd8800e 1109 MDL);
1c522252
TL
1110 }
1111
1112 if (!omapi_ds_strcmp (name, "name"))
1113 return omapi_make_string_value (value, name, host -> name,
4bd8800e 1114 MDL);
1c522252
TL
1115
1116 if (!omapi_ds_strcmp (name, "hardware-address")) {
1117 if (!host -> interface.hlen)
1118 return ISC_R_NOTFOUND;
180b8f2b
TL
1119 return (omapi_make_const_value
1120 (value, name, &host -> interface.hbuf [1],
4bd8800e 1121 (unsigned long)(host -> interface.hlen - 1), MDL));
1c522252
TL
1122 }
1123
1124 if (!omapi_ds_strcmp (name, "hardware-type")) {
1125 if (!host -> interface.hlen)
1126 return ISC_R_NOTFOUND;
1127 return omapi_make_int_value (value, name,
4bd8800e 1128 host -> interface.hbuf [0], MDL);
1c522252
TL
1129 }
1130
1131 /* Try to find some inner object that can take the value. */
1132 if (h -> inner && h -> inner -> type -> get_value) {
1133 status = ((*(h -> inner -> type -> get_value))
1134 (h -> inner, id, name, value));
1135 if (status == ISC_R_SUCCESS)
1136 return status;
1137 }
d758ad8c 1138 return ISC_R_UNKNOWNATTRIBUTE;
1c522252
TL
1139}
1140
4bd8800e 1141isc_result_t dhcp_host_destroy (omapi_object_t *h, const char *file, int line)
1c522252
TL
1142{
1143 struct host_decl *host;
1144 isc_result_t status;
1145
1146 if (h -> type != dhcp_type_host)
1147 return ISC_R_INVALIDARG;
1148 host = (struct host_decl *)h;
1149
d758ad8c
TL
1150#if defined (DEBUG_MEMORY_LEAKAGE) || \
1151 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1152 if (host -> n_ipaddr)
1153 host_dereference (&host -> n_ipaddr, file, line);
1154 if (host -> n_dynamic)
1155 host_dereference (&host -> n_dynamic, file, line);
1156 if (host -> name) {
1157 dfree (host -> name, file, line);
1158 host -> name = (char *)0;
1159 }
1160 data_string_forget (&host -> client_identifier, file, line);
1161 if (host -> fixed_addr)
1162 option_cache_dereference (&host -> fixed_addr, file, line);
1163 if (host -> group)
1164 group_dereference (&host -> group, file, line);
1165 if (host -> named_group)
1166 omapi_object_dereference ((omapi_object_t **)
1167 &host -> named_group, file, line);
1168 data_string_forget (&host -> auth_key_id, file, line);
1169#endif
1c522252
TL
1170
1171 return ISC_R_SUCCESS;
1172}
1173
1174isc_result_t dhcp_host_signal_handler (omapi_object_t *h,
b1b7b521 1175 const char *name, va_list ap)
1c522252
TL
1176{
1177 struct host_decl *host;
1178 isc_result_t status;
b9626cbb 1179 int updatep = 0;
1c522252
TL
1180
1181 if (h -> type != dhcp_type_host)
1182 return ISC_R_INVALIDARG;
1183 host = (struct host_decl *)h;
1184
1185 if (!strcmp (name, "updated")) {
eadee396
TL
1186 /* There must be a client identifier of some sort. */
1187 if (host -> interface.hlen == 0 &&
b9626cbb 1188 !host -> client_identifier.len)
92ce3f81
TL
1189 return ISC_R_INVALIDARG;
1190
1c522252
TL
1191 if (!host -> name) {
1192 char hnbuf [64];
e92653f1 1193 sprintf (hnbuf, "nh%08lx%08lx",
c4661845 1194 (unsigned long)cur_time, (unsigned long)host);
4bd8800e 1195 host -> name = dmalloc (strlen (hnbuf) + 1, MDL);
1c522252
TL
1196 if (!host -> name)
1197 return ISC_R_NOMEMORY;
1198 strcpy (host -> name, hnbuf);
1199 }
92ce3f81 1200
c7775a73
TL
1201#ifdef DEBUG_OMAPI
1202 log_debug ("OMAPI added host %s", host -> name);
1203#endif
92ce3f81
TL
1204 status = enter_host (host, 1, 1);
1205 if (status != ISC_R_SUCCESS)
1206 return status;
b9626cbb 1207 updatep = 1;
1c522252
TL
1208 }
1209
1210 /* Try to find some inner object that can take the value. */
19f7a4d7 1211 if (h -> inner && h -> inner -> type -> signal_handler) {
1c522252
TL
1212 status = ((*(h -> inner -> type -> signal_handler))
1213 (h -> inner, name, ap));
1214 if (status == ISC_R_SUCCESS)
1215 return status;
1216 }
b9626cbb
TL
1217 if (updatep)
1218 return ISC_R_SUCCESS;
1c522252
TL
1219 return ISC_R_NOTFOUND;
1220}
1221
1222isc_result_t dhcp_host_stuff_values (omapi_object_t *c,
1223 omapi_object_t *id,
1224 omapi_object_t *h)
1225{
1226 struct host_decl *host;
1227 isc_result_t status;
1228 struct data_string ip_addrs;
1229
1230 if (h -> type != dhcp_type_host)
1231 return ISC_R_INVALIDARG;
1232 host = (struct host_decl *)h;
1233
1234 /* Write out all the values. */
1235
1236 memset (&ip_addrs, 0, sizeof ip_addrs);
1237 if (host -> fixed_addr &&
1238 evaluate_option_cache (&ip_addrs, (struct packet *)0,
1239 (struct lease *)0,
9e383163 1240 (struct client_state *)0,
1c522252
TL
1241 (struct option_state *)0,
1242 (struct option_state *)0,
502e9f89 1243 &global_scope,
4bd8800e 1244 host -> fixed_addr, MDL)) {
1c522252
TL
1245 status = omapi_connection_put_name (c, "ip-address");
1246 if (status != ISC_R_SUCCESS)
1247 return status;
1248 status = omapi_connection_put_uint32 (c, ip_addrs.len);
1249 if (status != ISC_R_SUCCESS)
1250 return status;
1251 status = omapi_connection_copyin (c,
1252 ip_addrs.data, ip_addrs.len);
1253 if (status != ISC_R_SUCCESS)
1254 return status;
1255 }
1256
1257 if (host -> client_identifier.len) {
1258 status = omapi_connection_put_name (c,
1259 "dhcp-client-identifier");
1260 if (status != ISC_R_SUCCESS)
1261 return status;
1262 status = (omapi_connection_put_uint32
1263 (c, host -> client_identifier.len));
1264 if (status != ISC_R_SUCCESS)
1265 return status;
808db3d3
TL
1266 status = (omapi_connection_copyin
1267 (c,
1268 host -> client_identifier.data,
1269 host -> client_identifier.len));
1270 if (status != ISC_R_SUCCESS)
1271 return status;
1c522252
TL
1272 }
1273
b9626cbb
TL
1274 if (host -> name) {
1275 status = omapi_connection_put_name (c, "name");
1276 if (status != ISC_R_SUCCESS)
1277 return status;
1278 status = omapi_connection_put_string (c, host -> name);
1279 if (status != ISC_R_SUCCESS)
1280 return status;
1281 }
1c522252 1282
b9626cbb
TL
1283 if (host -> interface.hlen) {
1284 status = omapi_connection_put_name (c, "hardware-address");
1285 if (status != ISC_R_SUCCESS)
1286 return status;
180b8f2b
TL
1287 status = (omapi_connection_put_uint32
1288 (c, (unsigned long)(host -> interface.hlen - 1)));
b9626cbb
TL
1289 if (status != ISC_R_SUCCESS)
1290 return status;
180b8f2b
TL
1291 status = (omapi_connection_copyin
1292 (c, &host -> interface.hbuf [1],
f7172639 1293 (unsigned long)(host -> interface.hlen - 1)));
b9626cbb
TL
1294 if (status != ISC_R_SUCCESS)
1295 return status;
1c522252 1296
b9626cbb
TL
1297 status = omapi_connection_put_name (c, "hardware-type");
1298 if (status != ISC_R_SUCCESS)
1299 return status;
1300 status = omapi_connection_put_uint32 (c, sizeof (int));
1301 if (status != ISC_R_SUCCESS)
1302 return status;
180b8f2b
TL
1303 status = (omapi_connection_put_uint32
1304 (c, host -> interface.hbuf [0]));
b9626cbb
TL
1305 if (status != ISC_R_SUCCESS)
1306 return status;
1307 }
1c522252
TL
1308
1309 /* Write out the inner object, if any. */
1310 if (h -> inner && h -> inner -> type -> stuff_values) {
1311 status = ((*(h -> inner -> type -> stuff_values))
1312 (c, id, h -> inner));
1313 if (status == ISC_R_SUCCESS)
1314 return status;
1315 }
1316
1317 return ISC_R_SUCCESS;
1318}
1319
1320isc_result_t dhcp_host_lookup (omapi_object_t **lp,
899d754f 1321 omapi_object_t *id, omapi_object_t *ref)
1c522252
TL
1322{
1323 omapi_value_t *tv = (omapi_value_t *)0;
1324 isc_result_t status;
1325 struct host_decl *host;
1326
d758ad8c
TL
1327 if (!ref)
1328 return ISC_R_NOKEYS;
1329
1c522252
TL
1330 /* First see if we were sent a handle. */
1331 status = omapi_get_value_str (ref, id, "handle", &tv);
1332 if (status == ISC_R_SUCCESS) {
1333 status = omapi_handle_td_lookup (lp, tv -> value);
1334
4bd8800e 1335 omapi_value_dereference (&tv, MDL);
1c522252
TL
1336 if (status != ISC_R_SUCCESS)
1337 return status;
1338
1339 /* Don't return the object if the type is wrong. */
1340 if ((*lp) -> type != dhcp_type_host) {
4bd8800e 1341 omapi_object_dereference (lp, MDL);
1c522252
TL
1342 return ISC_R_INVALIDARG;
1343 }
63c8c1dc 1344 if (((struct host_decl *)(*lp)) -> flags & HOST_DECL_DELETED) {
4bd8800e 1345 omapi_object_dereference (lp, MDL);
63c8c1dc 1346 }
1c522252
TL
1347 }
1348
1349 /* Now look for a client identifier. */
1350 status = omapi_get_value_str (ref, id, "dhcp-client-identifier", &tv);
1351 if (status == ISC_R_SUCCESS) {
20916cae
TL
1352 host = (struct host_decl *)0;
1353 host_hash_lookup (&host, host_uid_hash,
1354 tv -> value -> u.buffer.value,
1355 tv -> value -> u.buffer.len, MDL);
4bd8800e 1356 omapi_value_dereference (&tv, MDL);
1c522252 1357
b9626cbb 1358 if (*lp && *lp != (omapi_object_t *)host) {
4bd8800e 1359 omapi_object_dereference (lp, MDL);
20916cae
TL
1360 if (host)
1361 host_dereference (&host, MDL);
b9626cbb 1362 return ISC_R_KEYCONFLICT;
63c8c1dc 1363 } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
b9626cbb 1364 if (*lp)
4bd8800e 1365 omapi_object_dereference (lp, MDL);
20916cae
TL
1366 if (host)
1367 host_dereference (&host, MDL);
1c522252 1368 return ISC_R_NOTFOUND;
b9626cbb
TL
1369 } else if (!*lp) {
1370 /* XXX fix so that hash lookup itself creates
1371 XXX the reference. */
4bd8800e
TL
1372 omapi_object_reference (lp,
1373 (omapi_object_t *)host, MDL);
20916cae 1374 host_dereference (&host, MDL);
b9626cbb 1375 }
1c522252
TL
1376 }
1377
1378 /* Now look for a hardware address. */
1379 status = omapi_get_value_str (ref, id, "hardware-address", &tv);
1380 if (status == ISC_R_SUCCESS) {
2e3e0f92
DN
1381 unsigned char *haddr;
1382 unsigned int len;
1383
1384 len = tv -> value -> u.buffer.len + 1;
1385 haddr = dmalloc (len, MDL);
1386 if (!haddr) {
1387 omapi_value_dereference (&tv, MDL);
1388 return ISC_R_NOMEMORY;
1389 }
1390
1391 memcpy (haddr + 1, tv -> value -> u.buffer.value, len - 1);
4bd8800e 1392 omapi_value_dereference (&tv, MDL);
2e3e0f92
DN
1393
1394 status = omapi_get_value_str (ref, id, "hardware-type", &tv);
1395 if (status == ISC_R_SUCCESS) {
1396 if (tv -> value -> type == omapi_datatype_data) {
1397 if ((tv -> value -> u.buffer.len != 4) ||
1398 (tv -> value -> u.buffer.value[0] != 0) ||
1399 (tv -> value -> u.buffer.value[1] != 0) ||
1400 (tv -> value -> u.buffer.value[2] != 0)) {
1401 omapi_value_dereference (&tv, MDL);
1402 dfree (haddr, MDL);
1403 return ISC_R_INVALIDARG;
1404 }
1405
1406 haddr[0] = tv -> value -> u.buffer.value[3];
1407 } else if (tv -> value -> type == omapi_datatype_int) {
1408 haddr[0] = (unsigned char)
1409 tv -> value -> u.integer;
1410 } else {
1411 omapi_value_dereference (&tv, MDL);
1412 dfree (haddr, MDL);
1413 return ISC_R_INVALIDARG;
1414 }
1415
1416 omapi_value_dereference (&tv, MDL);
1417 } else {
1418 /* If no hardware-type is specified, default to
1419 ethernet. This may or may not be a good idea,
1420 but Telus is currently relying on this behavior.
1421 - DPN */
1422 haddr[0] = HTYPE_ETHER;
1423 }
1424
1425 host = (struct host_decl *)0;
1426 host_hash_lookup (&host, host_hw_addr_hash, haddr, len, MDL);
1427 dfree (haddr, MDL);
1c522252 1428
b9626cbb 1429 if (*lp && *lp != (omapi_object_t *)host) {
4bd8800e 1430 omapi_object_dereference (lp, MDL);
20916cae
TL
1431 if (host)
1432 host_dereference (&host, MDL);
b9626cbb 1433 return ISC_R_KEYCONFLICT;
63c8c1dc 1434 } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
b9626cbb 1435 if (*lp)
4bd8800e 1436 omapi_object_dereference (lp, MDL);
20916cae
TL
1437 if (host)
1438 host_dereference (&host, MDL);
1c522252 1439 return ISC_R_NOTFOUND;
b9626cbb
TL
1440 } else if (!*lp) {
1441 /* XXX fix so that hash lookup itself creates
1442 XXX the reference. */
4bd8800e
TL
1443 omapi_object_reference (lp,
1444 (omapi_object_t *)host, MDL);
20916cae 1445 host_dereference (&host, MDL);
b9626cbb 1446 }
8ac1b7ba
TL
1447 }
1448
1449 /* Now look for an ip address. */
1450 status = omapi_get_value_str (ref, id, "ip-address", &tv);
1451 if (status == ISC_R_SUCCESS) {
1452 struct lease *l;
8ac1b7ba
TL
1453
1454 /* first find the lease for this ip address */
20916cae
TL
1455 l = (struct lease *)0;
1456 lease_hash_lookup (&l, lease_ip_addr_hash,
1457 tv -> value -> u.buffer.value,
1458 tv -> value -> u.buffer.len, MDL);
4bd8800e 1459 omapi_value_dereference (&tv, MDL);
8ac1b7ba 1460
b9626cbb 1461 if (!l && !*lp)
8ac1b7ba
TL
1462 return ISC_R_NOTFOUND;
1463
b9626cbb
TL
1464 if (l) {
1465 /* now use that to get a host */
20916cae
TL
1466 host = (struct host_decl *)0;
1467 host_hash_lookup (&host, host_hw_addr_hash,
1468 l -> hardware_addr.hbuf,
1469 l -> hardware_addr.hlen, MDL);
8ac1b7ba 1470
b9626cbb 1471 if (host && *lp && *lp != (omapi_object_t *)host) {
4bd8800e 1472 omapi_object_dereference (lp, MDL);
20916cae
TL
1473 if (host)
1474 host_dereference (&host, MDL);
b9626cbb 1475 return ISC_R_KEYCONFLICT;
63c8c1dc
TL
1476 } else if (!host || (host -> flags &
1477 HOST_DECL_DELETED)) {
20916cae
TL
1478 if (host)
1479 host_dereference (&host, MDL);
b9626cbb
TL
1480 if (!*lp)
1481 return ISC_R_NOTFOUND;
c7775a73
TL
1482 } else if (!*lp) {
1483 /* XXX fix so that hash lookup itself creates
1484 XXX the reference. */
20916cae
TL
1485 omapi_object_reference (lp, (omapi_object_t *)host,
1486 MDL);
1487 host_dereference (&host, MDL);
b9626cbb 1488 }
20916cae 1489 lease_dereference (&l, MDL);
dc667e92
TL
1490 }
1491 }
1492
1493 /* Now look for a name. */
1494 status = omapi_get_value_str (ref, id, "name", &tv);
1495 if (status == ISC_R_SUCCESS) {
20916cae
TL
1496 host = (struct host_decl *)0;
1497 host_hash_lookup (&host, host_name_hash,
1498 tv -> value -> u.buffer.value,
1499 tv -> value -> u.buffer.len, MDL);
4bd8800e 1500 omapi_value_dereference (&tv, MDL);
dc667e92
TL
1501
1502 if (*lp && *lp != (omapi_object_t *)host) {
4bd8800e 1503 omapi_object_dereference (lp, MDL);
20916cae
TL
1504 if (host)
1505 host_dereference (&host, MDL);
dc667e92 1506 return ISC_R_KEYCONFLICT;
63c8c1dc 1507 } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
20916cae
TL
1508 if (host)
1509 host_dereference (&host, MDL);
dc667e92
TL
1510 return ISC_R_NOTFOUND;
1511 } else if (!*lp) {
1512 /* XXX fix so that hash lookup itself creates
1513 XXX the reference. */
4bd8800e
TL
1514 omapi_object_reference (lp,
1515 (omapi_object_t *)host, MDL);
20916cae 1516 host_dereference (&host, MDL);
b9626cbb 1517 }
1c522252
TL
1518 }
1519
1520 /* If we get to here without finding a host, no valid key was
1521 specified. */
1522 if (!*lp)
5a0931a1 1523 return ISC_R_NOKEYS;
1c522252
TL
1524 return ISC_R_SUCCESS;
1525}
1526
1527isc_result_t dhcp_host_create (omapi_object_t **lp,
1528 omapi_object_t *id)
1529{
1530 struct host_decl *hp;
20916cae
TL
1531 isc_result_t status;
1532 hp = (struct host_decl *)0;
1533 status = host_allocate (&hp, MDL);
1534 if (status != ISC_R_SUCCESS)
1535 return status;
1536 group_reference (&hp -> group, root_group, MDL);
63c8c1dc 1537 hp -> flags = HOST_DECL_DYNAMIC;
20916cae
TL
1538 status = omapi_object_reference (lp, (omapi_object_t *)hp, MDL);
1539 host_dereference (&hp, MDL);
1540 return status;
1c522252
TL
1541}
1542
ccce1cc6 1543isc_result_t dhcp_host_remove (omapi_object_t *lp,
110d0522
TL
1544 omapi_object_t *id)
1545{
1546 struct host_decl *hp;
1547 if (lp -> type != dhcp_type_host)
1548 return ISC_R_INVALIDARG;
1549 hp = (struct host_decl *)lp;
1550
c7775a73
TL
1551#ifdef DEBUG_OMAPI
1552 log_debug ("OMAPI delete host %s", hp -> name);
1553#endif
110d0522
TL
1554 delete_host (hp, 1);
1555 return ISC_R_SUCCESS;
1556}
1557
1c522252 1558isc_result_t dhcp_pool_set_value (omapi_object_t *h,
20916cae
TL
1559 omapi_object_t *id,
1560 omapi_data_string_t *name,
1561 omapi_typed_data_t *value)
1c522252
TL
1562{
1563 struct pool *pool;
1564 isc_result_t status;
1565 int foo;
1566
808db3d3 1567 if (h -> type != dhcp_type_pool)
1c522252
TL
1568 return ISC_R_INVALIDARG;
1569 pool = (struct pool *)h;
1570
1571 /* No values to set yet. */
1572
1573 /* Try to find some inner object that can take the value. */
1574 if (h -> inner && h -> inner -> type -> set_value) {
1575 status = ((*(h -> inner -> type -> set_value))
1576 (h -> inner, id, name, value));
1577 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
1578 return status;
1579 }
1580
d758ad8c 1581 return ISC_R_UNKNOWNATTRIBUTE;
1c522252
TL
1582}
1583
1584
1585isc_result_t dhcp_pool_get_value (omapi_object_t *h, omapi_object_t *id,
20916cae
TL
1586 omapi_data_string_t *name,
1587 omapi_value_t **value)
1c522252
TL
1588{
1589 struct pool *pool;
1590 isc_result_t status;
1591
1592 if (h -> type != dhcp_type_pool)
1593 return ISC_R_INVALIDARG;
1594 pool = (struct pool *)h;
1595
1596 /* No values to get yet. */
1597
1598 /* Try to find some inner object that can provide the value. */
1599 if (h -> inner && h -> inner -> type -> get_value) {
1600 status = ((*(h -> inner -> type -> get_value))
1601 (h -> inner, id, name, value));
1602 if (status == ISC_R_SUCCESS)
1603 return status;
1604 }
d758ad8c 1605 return ISC_R_UNKNOWNATTRIBUTE;
1c522252
TL
1606}
1607
4bd8800e 1608isc_result_t dhcp_pool_destroy (omapi_object_t *h, const char *file, int line)
1c522252
TL
1609{
1610 struct pool *pool;
1611 isc_result_t status;
d758ad8c 1612 struct permit *pc, *pn;
1c522252
TL
1613
1614 if (h -> type != dhcp_type_pool)
1615 return ISC_R_INVALIDARG;
1616 pool = (struct pool *)h;
1617
d758ad8c
TL
1618#if defined (DEBUG_MEMORY_LEAKAGE) || \
1619 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1620 if (pool -> next)
1621 pool_dereference (&pool -> next, file, line);
1622 if (pool -> group)
1623 group_dereference (&pool -> group, file, line);
1624 if (pool -> shared_network)
1625 shared_network_dereference (&pool -> shared_network, file, line);
1626 if (pool -> active)
1627 lease_dereference (&pool -> active, file, line);
1628 if (pool -> expired)
1629 lease_dereference (&pool -> expired, file, line);
1630 if (pool -> free)
1631 lease_dereference (&pool -> free, file, line);
1632 if (pool -> backup)
1633 lease_dereference (&pool -> backup, file, line);
1634 if (pool -> abandoned)
1635 lease_dereference (&pool -> abandoned, file, line);
1636#if defined (FAILOVER_PROTOCOL)
1637 if (pool -> failover_peer)
1638 dhcp_failover_state_dereference (&pool -> failover_peer,
1639 file, line);
1640#endif
1641 for (pc = pool -> permit_list; pc; pc = pn) {
1642 pn = pc -> next;
1643 free_permit (pc, file, line);
1644 }
1645 pool -> permit_list = (struct permit *)0;
1646
1647 for (pc = pool -> prohibit_list; pc; pc = pn) {
1648 pn = pc -> next;
1649 free_permit (pc, file, line);
1650 }
1651 pool -> prohibit_list = (struct permit *)0;
1652#endif
1c522252
TL
1653
1654 return ISC_R_SUCCESS;
1655}
1656
1657isc_result_t dhcp_pool_signal_handler (omapi_object_t *h,
b1b7b521 1658 const char *name, va_list ap)
1c522252
TL
1659{
1660 struct pool *pool;
1661 isc_result_t status;
b9626cbb 1662 int updatep = 0;
1c522252
TL
1663
1664 if (h -> type != dhcp_type_pool)
1665 return ISC_R_INVALIDARG;
1666 pool = (struct pool *)h;
1667
1668 /* Can't write pools yet. */
1669
1670 /* Try to find some inner object that can take the value. */
19f7a4d7 1671 if (h -> inner && h -> inner -> type -> signal_handler) {
1c522252
TL
1672 status = ((*(h -> inner -> type -> signal_handler))
1673 (h -> inner, name, ap));
1674 if (status == ISC_R_SUCCESS)
1675 return status;
1676 }
b9626cbb
TL
1677 if (updatep)
1678 return ISC_R_SUCCESS;
1c522252
TL
1679 return ISC_R_NOTFOUND;
1680}
1681
1682isc_result_t dhcp_pool_stuff_values (omapi_object_t *c,
20916cae
TL
1683 omapi_object_t *id,
1684 omapi_object_t *h)
1c522252
TL
1685{
1686 struct pool *pool;
1687 isc_result_t status;
1688
1689 if (h -> type != dhcp_type_pool)
1690 return ISC_R_INVALIDARG;
1691 pool = (struct pool *)h;
1692
1693 /* Can't stuff pool values yet. */
1694
1695 /* Write out the inner object, if any. */
1696 if (h -> inner && h -> inner -> type -> stuff_values) {
1697 status = ((*(h -> inner -> type -> stuff_values))
1698 (c, id, h -> inner));
1699 if (status == ISC_R_SUCCESS)
1700 return status;
1701 }
1702
1703 return ISC_R_SUCCESS;
1704}
1705
1706isc_result_t dhcp_pool_lookup (omapi_object_t **lp,
20916cae 1707 omapi_object_t *id, omapi_object_t *ref)
1c522252
TL
1708{
1709 omapi_value_t *tv = (omapi_value_t *)0;
1710 isc_result_t status;
1711 struct pool *pool;
1712
1713 /* Can't look up pools yet. */
1714
1715 /* If we get to here without finding a pool, no valid key was
1716 specified. */
1717 if (!*lp)
5a0931a1 1718 return ISC_R_NOKEYS;
1c522252
TL
1719 return ISC_R_SUCCESS;
1720}
1721
1722isc_result_t dhcp_pool_create (omapi_object_t **lp,
20916cae 1723 omapi_object_t *id)
1c522252
TL
1724{
1725 return ISC_R_NOTIMPLEMENTED;
1726}
1727
ccce1cc6 1728isc_result_t dhcp_pool_remove (omapi_object_t *lp,
110d0522
TL
1729 omapi_object_t *id)
1730{
1731 return ISC_R_NOTIMPLEMENTED;
1732}
1733
899d754f
JB
1734static isc_result_t
1735class_set_value (omapi_object_t *h,
1736 omapi_object_t *id,
1737 omapi_data_string_t *name,
1738 omapi_typed_data_t *value)
20916cae
TL
1739{
1740 struct class *class;
899d754f 1741 struct class *superclass = 0;
20916cae 1742 isc_result_t status;
899d754f 1743 int issubclass = (h -> type == dhcp_type_subclass);
20916cae 1744
20916cae
TL
1745 class = (struct class *)h;
1746
06e77c34 1747 if (!omapi_ds_strcmp(name, "name")) {
899d754f
JB
1748 char *tname;
1749
06e77c34 1750 if (class->name)
899d754f
JB
1751 return ISC_R_EXISTS;
1752
06e77c34 1753 if ((tname = dmalloc(value->u.buffer.len + 1, MDL)) == NULL) {
899d754f
JB
1754 return ISC_R_NOMEMORY;
1755 }
06e77c34
DH
1756
1757 /* tname is null terminated from dmalloc() */
1758 memcpy(tname, value->u.buffer.value, value->u.buffer.len);
899d754f
JB
1759
1760 if (issubclass) {
1761 status = find_class(&superclass, tname, MDL);
1762 dfree(tname, MDL);
06e77c34 1763
899d754f
JB
1764 if (status == ISC_R_NOTFOUND)
1765 return status;
06e77c34
DH
1766
1767 if (class->superclass != NULL)
1768 class_dereference(&class->superclass, MDL);
1769
1770 class_reference(&class->superclass, superclass, MDL);
899d754f
JB
1771 } else if (value -> type == omapi_datatype_data ||
1772 value -> type == omapi_datatype_string) {
06e77c34
DH
1773 class->name = dmalloc(value->u.buffer.len + 1, MDL);
1774 if (!class->name)
899d754f
JB
1775 return ISC_R_NOMEMORY;
1776
06e77c34
DH
1777 /* class->name is null-terminated from dmalloc() */
1778 memcpy(class->name, value->u.buffer.value,
1779 value->u.buffer.len);
1780 } else
899d754f 1781 return ISC_R_INVALIDARG;
06e77c34 1782
899d754f
JB
1783 return ISC_R_SUCCESS;
1784 }
1785
1786
1787 if (issubclass && !omapi_ds_strcmp(name, "hashstring")) {
06e77c34 1788 if (class->hash_string.data)
899d754f 1789 return ISC_R_EXISTS;
06e77c34
DH
1790
1791 if (value->type == omapi_datatype_data ||
1792 value->type == omapi_datatype_string) {
1793 if (!buffer_allocate(&class->hash_string.buffer,
1794 value->u.buffer.len, MDL))
899d754f
JB
1795 return ISC_R_NOMEMORY;
1796 class->hash_string.data =
06e77c34
DH
1797 class->hash_string.buffer->data;
1798 memcpy(class->hash_string.data, value->u.buffer.value,
1799 value->u.buffer.len);
1800 class->hash_string.len = value->u.buffer.len;
899d754f 1801 } else
06e77c34
DH
1802 return ISC_R_INVALIDARG;
1803
899d754f
JB
1804 return ISC_R_SUCCESS;
1805 }
1806
06e77c34
DH
1807 if (!omapi_ds_strcmp(name, "group")) {
1808 if (value->type == omapi_datatype_data ||
1809 value->type == omapi_datatype_string) {
1810 struct group_object *group = NULL;
899d754f 1811
06e77c34
DH
1812 group_hash_lookup(&group, group_name_hash,
1813 (char *)value->u.buffer.value,
1814 value->u.buffer.len, MDL);
1815 if (!group || (group->flags & GROUP_OBJECT_DELETED))
899d754f 1816 return ISC_R_NOTFOUND;
06e77c34
DH
1817 if (class->group)
1818 group_dereference(&class->group, MDL);
1819 group_reference(&class->group, group->group, MDL);
1820 group_object_dereference(&group, MDL);
899d754f
JB
1821 } else
1822 return ISC_R_INVALIDARG;
06e77c34 1823
899d754f
JB
1824 return ISC_R_SUCCESS;
1825 }
1826
1827
f3fe382d
JB
1828 /* note we do not support full expressions via omapi because the
1829 expressions parser needs to be re-done to support parsing from
1830 strings and not just files. */
06e77c34
DH
1831
1832 if (!omapi_ds_strcmp(name, "match")) {
1833 if (value->type == omapi_datatype_data ||
1834 value->type == omapi_datatype_string) {
1835 unsigned minlen = (value->u.buffer.len > 8 ?
1836 8 : value->u.buffer.len);
1837
09636c65 1838 if (!strncmp("hardware",
06e77c34 1839 (char *)value->u.buffer.value, minlen))
09636c65 1840 {
f3fe382d 1841 if (!expression_allocate(&class->submatch,
06e77c34 1842 MDL))
f3fe382d 1843 return ISC_R_NOMEMORY;
06e77c34 1844
f3fe382d 1845 class->expr->op = expr_hardware;
06e77c34 1846 } else
f3fe382d 1847 return ISC_R_INVALIDARG;
06e77c34 1848 } else
899d754f 1849 return ISC_R_INVALIDARG;
06e77c34 1850
899d754f
JB
1851 return ISC_R_SUCCESS;
1852 }
1853
1854
06e77c34
DH
1855 if (!omapi_ds_strcmp(name, "option")) {
1856 if (value->type == omapi_datatype_data ||
1857 value->type == omapi_datatype_string) {
899d754f
JB
1858 /* XXXJAB support 'options' here. */
1859 /* XXXJAB specifically 'bootfile-name' */
1860 return ISC_R_INVALIDARG; /* XXX tmp */
06e77c34 1861 } else
899d754f 1862 return ISC_R_INVALIDARG;
06e77c34 1863
899d754f
JB
1864 return ISC_R_SUCCESS;
1865 }
1866
1867
20916cae 1868 /* Try to find some inner object that can take the value. */
06e77c34
DH
1869 if (h->inner && h->inner->type->set_value) {
1870 status = ((*(h->inner->type->set_value))
1871 (h->inner, id, name, value));
20916cae
TL
1872 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
1873 return status;
1874 }
06e77c34 1875
d758ad8c 1876 return ISC_R_UNKNOWNATTRIBUTE;
20916cae
TL
1877}
1878
1879
899d754f 1880
899d754f
JB
1881isc_result_t dhcp_class_set_value (omapi_object_t *h,
1882 omapi_object_t *id,
1883 omapi_data_string_t *name,
1884 omapi_typed_data_t *value)
1885{
1886 struct class *class;
1887 struct class *superclass = 0;
1888 isc_result_t status;
1889 int foo;
1890
1891 if (h -> type != dhcp_type_class)
1892 return ISC_R_INVALIDARG;
1893
1894 return class_set_value(h, id, name, value);
1895}
1896
20916cae
TL
1897isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id,
1898 omapi_data_string_t *name,
1899 omapi_value_t **value)
1900{
1901 struct class *class;
1902 isc_result_t status;
1903
1904 if (h -> type != dhcp_type_class)
1905 return ISC_R_INVALIDARG;
1906 class = (struct class *)h;
1907
899d754f
JB
1908 if (!omapi_ds_strcmp (name, "name"))
1909 return omapi_make_string_value (value, name, class -> name,
1910 MDL);
20916cae
TL
1911
1912 /* Try to find some inner object that can provide the value. */
1913 if (h -> inner && h -> inner -> type -> get_value) {
1914 status = ((*(h -> inner -> type -> get_value))
1915 (h -> inner, id, name, value));
1916 if (status == ISC_R_SUCCESS)
1917 return status;
1918 }
d758ad8c 1919 return ISC_R_UNKNOWNATTRIBUTE;
20916cae
TL
1920}
1921
1922isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line)
1923{
1924 struct class *class;
1925 isc_result_t status;
d758ad8c 1926 int i;
20916cae 1927
a609e69b 1928 if (h -> type != dhcp_type_class && h -> type != dhcp_type_subclass)
20916cae
TL
1929 return ISC_R_INVALIDARG;
1930 class = (struct class *)h;
1931
98311e4b
DH
1932#if defined (DEBUG_MEMORY_LEAKAGE) || \
1933 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
d758ad8c
TL
1934 if (class -> nic)
1935 class_dereference (&class -> nic, file, line);
1936 if (class -> superclass)
1937 class_dereference (&class -> superclass, file, line);
1938 if (class -> name) {
1939 dfree (class -> name, file, line);
1940 class -> name = (char *)0;
1941 }
1942 if (class -> billed_leases) {
1943 for (i = 0; i < class -> lease_limit; i++) {
1944 if (class -> billed_leases [i]) {
1945 lease_dereference (&class -> billed_leases [i],
1946 file, line);
1947 }
1948 }
1949 dfree (class -> billed_leases, file, line);
1950 class -> billed_leases = (struct lease **)0;
1951 }
1952 if (class -> hash) {
98311e4b
DH
1953 class_free_hash_table (&class -> hash, file, line);
1954 class -> hash = (class_hash_t *)0;
d758ad8c
TL
1955 }
1956 data_string_forget (&class -> hash_string, file, line);
1957
1958 if (class -> expr)
1959 expression_dereference (&class -> expr, file, line);
1960 if (class -> submatch)
1961 expression_dereference (&class -> submatch, file, line);
1962 if (class -> group)
1963 group_dereference (&class -> group, file, line);
1964 if (class -> statements)
1965 executable_statement_dereference (&class -> statements,
1966 file, line);
1967 if (class -> superclass)
1968 class_dereference (&class -> superclass, file, line);
98311e4b 1969#endif
20916cae
TL
1970
1971 return ISC_R_SUCCESS;
1972}
1973
899d754f
JB
1974static isc_result_t
1975class_signal_handler(omapi_object_t *h,
1976 const char *name, va_list ap)
20916cae 1977{
899d754f 1978 struct class *class = (struct class *)h;
20916cae
TL
1979 isc_result_t status;
1980 int updatep = 0;
899d754f 1981 int issubclass;
20916cae 1982
899d754f
JB
1983 issubclass = (h -> type == dhcp_type_subclass);
1984
1985 if (!strcmp (name, "updated")) {
1986
1987 if (!issubclass) {
1988 if (class -> name == 0 || strlen(class -> name) == 0) {
1989 return ISC_R_INVALIDARG;
1990 }
1991 } else {
1992 if (class -> superclass == 0) {
1993 return ISC_R_INVALIDARG; /* didn't give name */
1994 }
20916cae 1995
899d754f
JB
1996 if (class -> hash_string.data == NULL) {
1997 return ISC_R_INVALIDARG;
1998 }
1999 }
2000
2001
2002 if (issubclass) {
98311e4b
DH
2003 if (!class -> superclass -> hash)
2004 class_new_hash(&class->superclass->hash,
2005 0, MDL);
2006
899d754f
JB
2007 add_hash (class -> superclass -> hash,
2008 class -> hash_string.data,
2009 class -> hash_string.len,
2010 (void *)class, MDL);
2011 }
2012
2013
2014#ifdef DEBUG_OMAPI
2015 if (issubclass) {
2016 log_debug ("OMAPI added subclass %s",
2017 class -> superclass -> name);
2018 } else {
2019 log_debug ("OMAPI added class %s", class -> name);
2020 }
2021#endif
2022
2023 status = enter_class (class, 1, 1);
2024 if (status != ISC_R_SUCCESS)
2025 return status;
2026 updatep = 1;
2027 }
20916cae
TL
2028
2029 /* Try to find some inner object that can take the value. */
19f7a4d7 2030 if (h -> inner && h -> inner -> type -> signal_handler) {
20916cae
TL
2031 status = ((*(h -> inner -> type -> signal_handler))
2032 (h -> inner, name, ap));
2033 if (status == ISC_R_SUCCESS)
2034 return status;
2035 }
899d754f 2036
20916cae
TL
2037 if (updatep)
2038 return ISC_R_SUCCESS;
899d754f 2039
20916cae
TL
2040 return ISC_R_NOTFOUND;
2041}
2042
899d754f
JB
2043
2044isc_result_t dhcp_class_signal_handler (omapi_object_t *h,
2045 const char *name, va_list ap)
2046{
2047 if (h -> type != dhcp_type_class)
2048 return ISC_R_INVALIDARG;
2049
2050 return class_signal_handler(h, name, ap);
2051}
2052
20916cae
TL
2053isc_result_t dhcp_class_stuff_values (omapi_object_t *c,
2054 omapi_object_t *id,
2055 omapi_object_t *h)
2056{
2057 struct class *class;
2058 isc_result_t status;
2059
2060 if (h -> type != dhcp_type_class)
2061 return ISC_R_INVALIDARG;
2062 class = (struct class *)h;
2063
2064 /* Can't stuff class values yet. */
2065
2066 /* Write out the inner object, if any. */
2067 if (h -> inner && h -> inner -> type -> stuff_values) {
2068 status = ((*(h -> inner -> type -> stuff_values))
2069 (c, id, h -> inner));
2070 if (status == ISC_R_SUCCESS)
2071 return status;
2072 }
2073
2074 return ISC_R_SUCCESS;
2075}
2076
d758ad8c
TL
2077static isc_result_t class_lookup (omapi_object_t **lp,
2078 omapi_object_t *id, omapi_object_t *ref,
2079 omapi_object_type_t *typewanted)
20916cae 2080{
899d754f
JB
2081 omapi_value_t *nv = (omapi_value_t *)0;
2082 omapi_value_t *hv = (omapi_value_t *)0;
20916cae 2083 isc_result_t status;
899d754f
JB
2084 struct class *class = 0;
2085 struct class *subclass = 0;
20916cae 2086
899d754f
JB
2087 *lp = NULL;
2088
2089 /* see if we have a name */
2090 status = omapi_get_value_str (ref, id, "name", &nv);
2091 if (status == ISC_R_SUCCESS) {
2092 char *name = dmalloc(nv -> value -> u.buffer.len + 1, MDL);
2093 memcpy (name,
2094 nv -> value -> u.buffer.value,
2095 nv -> value -> u.buffer.len);
20916cae 2096
899d754f
JB
2097 omapi_value_dereference (&nv, MDL);
2098
2099 find_class(&class, name, MDL);
2100
2101 dfree(name, MDL);
2102
2103 if (class == NULL) {
2104 return ISC_R_NOTFOUND;
2105 }
2106
2107 if (typewanted == dhcp_type_subclass) {
2108 status = omapi_get_value_str (ref, id,
2109 "hashstring", &hv);
2110 if (status != ISC_R_SUCCESS) {
2111 class_dereference(&class, MDL);
2112 return ISC_R_NOKEYS;
2113 }
2114
2115 if (hv -> value -> type != omapi_datatype_data &&
2116 hv -> value -> type != omapi_datatype_string) {
2117 class_dereference(&class, MDL);
2118 omapi_value_dereference (&hv, MDL);
2119 return ISC_R_NOKEYS;
2120 }
2121
2122 class_hash_lookup (&subclass, class -> hash,
d758ad8c
TL
2123 (const char *)
2124 hv -> value -> u.buffer.value,
899d754f
JB
2125 hv -> value -> u.buffer.len, MDL);
2126
2127 omapi_value_dereference (&hv, MDL);
2128
2129 class_dereference(&class, MDL);
2130
2131 if (subclass == NULL) {
2132 return ISC_R_NOTFOUND;
2133 }
2134
2135 class_reference(&class, subclass, MDL);
2136 class_dereference(&subclass, MDL);
2137 }
2138
2139
2140 /* Don't return the object if the type is wrong. */
2141 if (class -> type != typewanted) {
2142 class_dereference (&class, MDL);
2143 return ISC_R_INVALIDARG;
2144 }
2145
2146 if (class -> flags & CLASS_DECL_DELETED) {
2147 class_dereference (&class, MDL);
2148 }
2149
2150 omapi_object_reference(lp, (omapi_object_t *)class, MDL);
2151
2152 return ISC_R_SUCCESS;
2153 }
2154
2155 return ISC_R_NOKEYS;
2156}
2157
2158
2159isc_result_t dhcp_class_lookup (omapi_object_t **lp,
2160 omapi_object_t *id, omapi_object_t *ref)
2161{
2162 return class_lookup(lp, id, ref, dhcp_type_class);
20916cae
TL
2163}
2164
2165isc_result_t dhcp_class_create (omapi_object_t **lp,
2166 omapi_object_t *id)
2167{
899d754f
JB
2168 struct class *cp = 0;
2169 isc_result_t status;
2170
2171 status = class_allocate(&cp, MDL);
2172 if (status != ISC_R_SUCCESS)
2173 return status;
2174
2175 group_reference (&cp -> group, root_group, MDL);
2176 cp -> flags = CLASS_DECL_DYNAMIC;
2177 status = omapi_object_reference (lp, (omapi_object_t *)cp, MDL);
2178 class_dereference (&cp, MDL);
2179 return status;
20916cae
TL
2180}
2181
2182isc_result_t dhcp_class_remove (omapi_object_t *lp,
2183 omapi_object_t *id)
2184{
899d754f
JB
2185 struct class *cp;
2186 if (lp -> type != dhcp_type_class)
2187 return ISC_R_INVALIDARG;
2188 cp = (struct class *)lp;
2189
2190#ifdef DEBUG_OMAPI
2191 log_debug ("OMAPI delete class %s", cp -> name);
2192#endif
2193
2194 delete_class (cp, 1);
2195 return ISC_R_SUCCESS;
20916cae
TL
2196}
2197
5aa40fc5
TL
2198isc_result_t dhcp_subclass_set_value (omapi_object_t *h,
2199 omapi_object_t *id,
2200 omapi_data_string_t *name,
2201 omapi_typed_data_t *value)
2202{
899d754f
JB
2203 struct class *subclass = 0;
2204 struct class *superclass = 0;
5aa40fc5
TL
2205 isc_result_t status;
2206 int foo;
2207
2208 if (h -> type != dhcp_type_subclass)
2209 return ISC_R_INVALIDARG;
5aa40fc5 2210
899d754f 2211 return class_set_value(h, id, name, value);
5aa40fc5
TL
2212}
2213
2214
2215isc_result_t dhcp_subclass_get_value (omapi_object_t *h, omapi_object_t *id,
2216 omapi_data_string_t *name,
2217 omapi_value_t **value)
2218{
899d754f 2219 struct class *subclass;
5aa40fc5
TL
2220 isc_result_t status;
2221
899d754f 2222 if (h -> type != dhcp_type_class)
5aa40fc5 2223 return ISC_R_INVALIDARG;
899d754f
JB
2224 subclass = (struct class *)h;
2225 if (subclass -> name != 0)
2226 return ISC_R_INVALIDARG;
2227
2228 /* XXXJAB No values to get yet. */
5aa40fc5
TL
2229
2230 /* Try to find some inner object that can provide the value. */
2231 if (h -> inner && h -> inner -> type -> get_value) {
2232 status = ((*(h -> inner -> type -> get_value))
2233 (h -> inner, id, name, value));
2234 if (status == ISC_R_SUCCESS)
2235 return status;
2236 }
d758ad8c 2237 return ISC_R_UNKNOWNATTRIBUTE;
5aa40fc5
TL
2238}
2239
2240isc_result_t dhcp_subclass_signal_handler (omapi_object_t *h,
2241 const char *name, va_list ap)
2242{
5aa40fc5
TL
2243 if (h -> type != dhcp_type_subclass)
2244 return ISC_R_INVALIDARG;
5aa40fc5 2245
899d754f 2246 return class_signal_handler(h, name, ap);
5aa40fc5
TL
2247}
2248
899d754f 2249
5aa40fc5
TL
2250isc_result_t dhcp_subclass_stuff_values (omapi_object_t *c,
2251 omapi_object_t *id,
2252 omapi_object_t *h)
2253{
899d754f 2254 struct class *subclass;
5aa40fc5
TL
2255 isc_result_t status;
2256
899d754f 2257 if (h -> type != dhcp_type_class)
5aa40fc5 2258 return ISC_R_INVALIDARG;
899d754f
JB
2259 subclass = (struct class *)h;
2260 if (subclass -> name != 0)
2261 return ISC_R_INVALIDARG;
2262
5aa40fc5
TL
2263
2264 /* Can't stuff subclass values yet. */
2265
2266 /* Write out the inner object, if any. */
2267 if (h -> inner && h -> inner -> type -> stuff_values) {
2268 status = ((*(h -> inner -> type -> stuff_values))
2269 (c, id, h -> inner));
2270 if (status == ISC_R_SUCCESS)
2271 return status;
2272 }
2273
2274 return ISC_R_SUCCESS;
2275}
2276
2277isc_result_t dhcp_subclass_lookup (omapi_object_t **lp,
2278 omapi_object_t *id, omapi_object_t *ref)
2279{
899d754f
JB
2280 return class_lookup(lp, id, ref, dhcp_type_subclass);
2281}
2282
5aa40fc5 2283
5aa40fc5 2284
5aa40fc5
TL
2285
2286isc_result_t dhcp_subclass_create (omapi_object_t **lp,
2287 omapi_object_t *id)
2288{
899d754f
JB
2289 struct class *cp = 0;
2290 isc_result_t status;
2291
2292/*
2293 * XXX
2294 * NOTE: subclasses and classes have the same internal type, which makes it
2295 * difficult to tell them apart. Specifically, in this function we need to
2296 * create a class object (because there is no such thing as a subclass
2297 * object), but one field of the class object is the type (which has the
2298 * value dhcp_type_class), and it is from here that all the other omapi
2299 * functions are accessed. So, even though there's a whole suite of
2300 * subclass functions registered, they won't get used. Now we could change
2301 * the type pointer after creating the class object, but I'm not certain
2302 * that won't break something else.
2303 */
2304
2305 status = subclass_allocate(&cp, MDL);
2306 if (status != ISC_R_SUCCESS)
2307 return status;
2308 group_reference (&cp -> group, root_group, MDL);
2309
2310 cp -> flags = CLASS_DECL_DYNAMIC;
2311
2312 status = omapi_object_reference (lp, (omapi_object_t *)cp, MDL);
2313 subclass_dereference (&cp, MDL);
2314 return status;
5aa40fc5
TL
2315}
2316
2317isc_result_t dhcp_subclass_remove (omapi_object_t *lp,
2318 omapi_object_t *id)
2319{
899d754f
JB
2320#if 1
2321
2322 log_fatal("calling dhcp_subclass_set_value");
2323 /* this should never be called see dhcp_subclass_create for why */
2324
2325#else
2326
2327 struct class *cp;
2328 if (lp -> type != dhcp_type_subclass)
2329 return ISC_R_INVALIDARG;
2330 cp = (struct class *)lp;
2331
2332#ifdef DEBUG_OMAPI
2333 log_debug ("OMAPI delete subclass %s", cp -> name);
2334#endif
2335
2336 delete_class (cp, 1);
2337
2338#endif
2339
2340 return ISC_R_SUCCESS;
5aa40fc5
TL
2341}
2342
d758ad8c
TL
2343isc_result_t binding_scope_set_value (struct binding_scope *scope, int createp,
2344 omapi_data_string_t *name,
2345 omapi_typed_data_t *value)
2346{
2347 struct binding *bp;
2348 char *nname;
2349 struct binding_value *nv;
2350 nname = dmalloc (name -> len + 1, MDL);
2351 if (!nname)
2352 return ISC_R_NOMEMORY;
2353 memcpy (nname, name -> value, name -> len);
2354 nname [name -> len] = 0;
2355 bp = find_binding (scope, nname);
2356 if (!bp && !createp) {
2357 dfree (nname, MDL);
2358 return ISC_R_UNKNOWNATTRIBUTE;
2359 }
2360 if (!value) {
2361 dfree (nname, MDL);
2362 if (!bp)
2363 return ISC_R_UNKNOWNATTRIBUTE;
2364 binding_value_dereference (&bp -> value, MDL);
2365 return ISC_R_SUCCESS;
2366 }
2367
2368 nv = (struct binding_value *)0;
2369 if (!binding_value_allocate (&nv, MDL)) {
2370 dfree (nname, MDL);
2371 return ISC_R_NOMEMORY;
2372 }
2373 switch (value -> type) {
2374 case omapi_datatype_int:
2375 nv -> type = binding_numeric;
2376 nv -> value.intval = value -> u.integer;
2377 break;
2378
2379 case omapi_datatype_string:
2380 case omapi_datatype_data:
2381 if (!buffer_allocate (&nv -> value.data.buffer,
2382 value -> u.buffer.len, MDL)) {
2383 binding_value_dereference (&nv, MDL);
2384 dfree (nname, MDL);
2385 return ISC_R_NOMEMORY;
2386 }
2387 memcpy (&nv -> value.data.buffer -> data [1],
2388 value -> u.buffer.value, value -> u.buffer.len);
2389 nv -> value.data.len = value -> u.buffer.len;
2390 break;
2391
2392 case omapi_datatype_object:
2393 binding_value_dereference (&nv, MDL);
2394 dfree (nname, MDL);
2395 return ISC_R_INVALIDARG;
2396 }
2397
2398 if (!bp) {
2399 bp = dmalloc (sizeof *bp, MDL);
2400 if (!bp) {
2401 binding_value_dereference (&nv, MDL);
2402 dfree (nname, MDL);
2403 return ISC_R_NOMEMORY;
2404 }
2405 memset (bp, 0, sizeof *bp);
2406 bp -> name = nname;
2407 nname = (char *)0;
2408 bp -> next = scope -> bindings;
2409 scope -> bindings = bp;
2410 } else {
2411 if (bp -> value)
2412 binding_value_dereference (&bp -> value, MDL);
2413 dfree (nname, MDL);
2414 }
2415 binding_value_reference (&bp -> value, nv, MDL);
2416 binding_value_dereference (&nv, MDL);
2417 return ISC_R_SUCCESS;
2418}
2419
2420isc_result_t binding_scope_get_value (omapi_value_t **value,
2421 struct binding_scope *scope,
2422 omapi_data_string_t *name)
2423{
2424 struct binding *bp;
2425 omapi_typed_data_t *td;
2426 isc_result_t status;
2427 char *nname;
2428 nname = dmalloc (name -> len + 1, MDL);
2429 if (!nname)
2430 return ISC_R_NOMEMORY;
2431 memcpy (nname, name -> value, name -> len);
2432 nname [name -> len] = 0;
2433 bp = find_binding (scope, nname);
2434 dfree (nname, MDL);
2435 if (!bp)
2436 return ISC_R_UNKNOWNATTRIBUTE;
2437 if (!bp -> value)
2438 return ISC_R_UNKNOWNATTRIBUTE;
2439
2440 switch (bp -> value -> type) {
2441 case binding_boolean:
2442 td = (omapi_typed_data_t *)0;
2443 status = omapi_typed_data_new (MDL, &td, omapi_datatype_int,
2444 bp -> value -> value.boolean);
2445 break;
2446
2447 case binding_numeric:
2448 td = (omapi_typed_data_t *)0;
2449 status = omapi_typed_data_new (MDL, &td, omapi_datatype_int,
2450 (int)
2451 bp -> value -> value.intval);
2452 break;
2453
2454 case binding_data:
2455 td = (omapi_typed_data_t *)0;
2456 status = omapi_typed_data_new (MDL, &td, omapi_datatype_data,
2457 bp -> value -> value.data.len);
2458 if (status != ISC_R_SUCCESS)
2459 return status;
2460 memcpy (&td -> u.buffer.value [0],
2461 bp -> value -> value.data.data,
2462 bp -> value -> value.data.len);
2463 break;
2464
2465 /* Can't return values for these two (yet?). */
2466 case binding_dns:
2467 case binding_function:
2468 return ISC_R_INVALIDARG;
98311e4b
DH
2469
2470 default:
2471 log_fatal ("Impossible case at %s:%d.", MDL);
2472 return ISC_R_FAILURE;
d758ad8c
TL
2473 }
2474
2475 if (status != ISC_R_SUCCESS)
2476 return status;
2477 status = omapi_value_new (value, MDL);
2478 if (status != ISC_R_SUCCESS) {
2479 omapi_typed_data_dereference (&td, MDL);
2480 return status;
2481 }
2482
2483 omapi_data_string_reference (&(*value) -> name, name, MDL);
2484 omapi_typed_data_reference (&(*value) -> value, td, MDL);
2485 omapi_typed_data_dereference (&td, MDL);
2486
2487 return ISC_R_SUCCESS;
2488}
2489
2490isc_result_t binding_scope_stuff_values (omapi_object_t *c,
2491 struct binding_scope *scope)
2492{
2493 struct binding *bp;
2494 unsigned len;
2495 isc_result_t status;
2496
2497 for (bp = scope -> bindings; bp; bp = bp -> next) {
2498 if (bp -> value) {
2499 if (bp -> value -> type == binding_dns ||
2500 bp -> value -> type == binding_function)
2501 continue;
2502
2503 /* Stuff the name. */
2504 len = strlen (bp -> name);
2505 status = omapi_connection_put_uint16 (c, len);
2506 if (status != ISC_R_SUCCESS)
2507 return status;
2508 status = omapi_connection_copyin (c,
2509 (unsigned char *)bp -> name,
2510 len);
2511 if (status != ISC_R_SUCCESS)
2512 return status;
2513
2514 switch (bp -> value -> type) {
2515 case binding_boolean:
2516 status = omapi_connection_put_uint32 (c,
2517 sizeof (u_int32_t));
2518 if (status != ISC_R_SUCCESS)
2519 return status;
2520 status = (omapi_connection_put_uint32
2521 (c,
2522 ((u_int32_t)(bp -> value -> value.boolean))));
2523 break;
2524
2525 case binding_data:
2526 status = (omapi_connection_put_uint32
2527 (c, bp -> value -> value.data.len));
2528 if (status != ISC_R_SUCCESS)
2529 return status;
2530 if (bp -> value -> value.data.len) {
2531 status = (omapi_connection_copyin
2532 (c, bp -> value -> value.data.data,
2533 bp -> value -> value.data.len));
2534 if (status != ISC_R_SUCCESS)
2535 return status;
2536 }
2537 break;
2538
2539 case binding_numeric:
2540 status = (omapi_connection_put_uint32
2541 (c, sizeof (u_int32_t)));
2542 if (status != ISC_R_SUCCESS)
2543 return status;
2544 status = (omapi_connection_put_uint32
2545 (c, ((u_int32_t)
2546 (bp -> value -> value.intval))));
2547 break;
2548
2549
2550 /* NOTREACHED */
2551 case binding_dns:
2552 case binding_function:
2553 break;
2554 }
2555 }
2556 }
2557 return ISC_R_SUCCESS;
2558}
2559
c7775a73 2560/* vim: set tabstop=8: */