]>
Commit | Line | Data |
---|---|---|
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 | |
43 | static 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 |
50 | static isc_result_t class_lookup (omapi_object_t **, |
51 | omapi_object_t *, omapi_object_t *, | |
52 | omapi_object_type_t *); | |
53 | ||
1c522252 | 54 | omapi_object_type_t *dhcp_type_lease; |
1c522252 | 55 | omapi_object_type_t *dhcp_type_pool; |
1c522252 | 56 | omapi_object_type_t *dhcp_type_class; |
5aa40fc5 | 57 | omapi_object_type_t *dhcp_type_subclass; |
4e9f1404 | 58 | omapi_object_type_t *dhcp_type_host; |
d9eefc5d | 59 | #if defined (FAILOVER_PROTOCOL) |
1edfbf5e TL |
60 | omapi_object_type_t *dhcp_type_failover_state; |
61 | omapi_object_type_t *dhcp_type_failover_link; | |
62 | omapi_object_type_t *dhcp_type_failover_listener; | |
d9eefc5d | 63 | #endif |
1c522252 TL |
64 | |
65 | void 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 | ||
208 | isc_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 | ||
306 | isc_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 | 382 | isc_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 | ||
457 | isc_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 | ||
481 | isc_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 | ||
701 | isc_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 | ||
866 | isc_result_t dhcp_lease_create (omapi_object_t **lp, | |
867 | omapi_object_t *id) | |
868 | { | |
869 | return ISC_R_NOTIMPLEMENTED; | |
870 | } | |
871 | ||
ccce1cc6 | 872 | isc_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 |
878 | isc_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 | ||
1072 | isc_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 | 1141 | isc_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 | ||
1174 | isc_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 | ||
1222 | isc_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 | ||
1320 | isc_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 | ||
1527 | isc_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 | 1543 | isc_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 | 1558 | isc_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 | ||
1585 | isc_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 | 1608 | isc_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 | ||
1657 | isc_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 | ||
1682 | isc_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 | ||
1706 | isc_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 | ||
1722 | isc_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 | 1728 | isc_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 |
1734 | static isc_result_t |
1735 | class_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 |
1881 | isc_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 |
1897 | isc_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 | ||
1922 | isc_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 |
1974 | static isc_result_t |
1975 | class_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 | |
2044 | isc_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 |
2053 | isc_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 |
2077 | static 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 | ||
2159 | isc_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 | ||
2165 | isc_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 | ||
2182 | isc_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 |
2198 | isc_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 | ||
2215 | isc_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 | ||
2240 | isc_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 |
2250 | isc_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 | ||
2277 | isc_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 | |
2286 | isc_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 | ||
2317 | isc_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 |
2343 | isc_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 | ||
2420 | isc_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 | ||
2490 | isc_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: */ |