]>
Commit | Line | Data |
---|---|---|
61b844bf TL |
1 | /* message.c |
2 | ||
3 | Subroutines for dealing with message objects. */ | |
4 | ||
5 | /* | |
edad9be5 | 6 | * Copyright (c) 2004,2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC") |
98311e4b | 7 | * Copyright (c) 1999-2003 by Internet Software Consortium |
61b844bf | 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. | |
61b844bf | 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. | |
61b844bf | 20 | * |
98311e4b DH |
21 | * Internet Systems Consortium, Inc. |
22 | * 950 Charter Street | |
23 | * Redwood City, CA 94063 | |
24 | * <info@isc.org> | |
2c85ac9b | 25 | * https://www.isc.org/ |
49733f31 | 26 | * |
61b844bf TL |
27 | */ |
28 | ||
fe5b0fdd DH |
29 | #include "dhcpd.h" |
30 | ||
6a4c4be8 | 31 | #include <omapip/omapip_p.h> |
61b844bf | 32 | |
20916cae TL |
33 | OMAPI_OBJECT_ALLOC (omapi_message, |
34 | omapi_message_object_t, omapi_type_message) | |
35 | ||
61b844bf TL |
36 | omapi_message_object_t *omapi_registered_messages; |
37 | ||
5edcb334 | 38 | isc_result_t omapi_message_new (omapi_object_t **o, const char *file, int line) |
61b844bf TL |
39 | { |
40 | omapi_message_object_t *m; | |
581e37e4 | 41 | omapi_object_t *g; |
61b844bf TL |
42 | isc_result_t status; |
43 | ||
31bbee78 TL |
44 | m = (omapi_message_object_t *)0; |
45 | status = omapi_message_allocate (&m, file, line); | |
46 | if (status != ISC_R_SUCCESS) | |
47 | return status; | |
61b844bf | 48 | |
581e37e4 | 49 | g = (omapi_object_t *)0; |
5edcb334 | 50 | status = omapi_generic_new (&g, file, line); |
581e37e4 | 51 | if (status != ISC_R_SUCCESS) { |
4bd8800e | 52 | dfree (m, file, line); |
581e37e4 TL |
53 | return status; |
54 | } | |
5edcb334 | 55 | status = omapi_object_reference (&m -> inner, g, file, line); |
581e37e4 | 56 | if (status != ISC_R_SUCCESS) { |
5edcb334 | 57 | omapi_object_dereference ((omapi_object_t **)&m, file, line); |
4bd8800e | 58 | omapi_object_dereference (&g, file, line); |
581e37e4 TL |
59 | return status; |
60 | } | |
61 | status = omapi_object_reference (&g -> outer, | |
5edcb334 | 62 | (omapi_object_t *)m, file, line); |
581e37e4 TL |
63 | |
64 | if (status != ISC_R_SUCCESS) { | |
5edcb334 | 65 | omapi_object_dereference ((omapi_object_t **)&m, file, line); |
4bd8800e | 66 | omapi_object_dereference (&g, file, line); |
581e37e4 TL |
67 | return status; |
68 | } | |
69 | ||
5edcb334 | 70 | status = omapi_object_reference (o, (omapi_object_t *)m, file, line); |
31bbee78 | 71 | omapi_message_dereference (&m, file, line); |
5edcb334 | 72 | omapi_object_dereference (&g, file, line); |
581e37e4 TL |
73 | if (status != ISC_R_SUCCESS) |
74 | return status; | |
75 | ||
61b844bf TL |
76 | return status; |
77 | } | |
78 | ||
79 | isc_result_t omapi_message_set_value (omapi_object_t *h, | |
80 | omapi_object_t *id, | |
81 | omapi_data_string_t *name, | |
82 | omapi_typed_data_t *value) | |
83 | { | |
84 | omapi_message_object_t *m; | |
85 | isc_result_t status; | |
86 | ||
87 | if (h -> type != omapi_type_message) | |
98bf1607 | 88 | return DHCP_R_INVALIDARG; |
61b844bf TL |
89 | m = (omapi_message_object_t *)h; |
90 | ||
91 | /* Can't set authlen. */ | |
92 | ||
93 | /* Can set authenticator, but the value must be typed data. */ | |
94 | if (!omapi_ds_strcmp (name, "authenticator")) { | |
95 | if (m -> authenticator) | |
4bd8800e TL |
96 | omapi_typed_data_dereference (&m -> authenticator, |
97 | MDL); | |
98 | omapi_typed_data_reference (&m -> authenticator, value, MDL); | |
61b844bf TL |
99 | return ISC_R_SUCCESS; |
100 | ||
581e37e4 TL |
101 | } else if (!omapi_ds_strcmp (name, "object")) { |
102 | if (value -> type != omapi_datatype_object) | |
98bf1607 | 103 | return DHCP_R_INVALIDARG; |
581e37e4 | 104 | if (m -> object) |
4bd8800e TL |
105 | omapi_object_dereference (&m -> object, MDL); |
106 | omapi_object_reference (&m -> object, value -> u.object, MDL); | |
581e37e4 TL |
107 | return ISC_R_SUCCESS; |
108 | ||
47e746b7 TL |
109 | } else if (!omapi_ds_strcmp (name, "notify-object")) { |
110 | if (value -> type != omapi_datatype_object) | |
98bf1607 | 111 | return DHCP_R_INVALIDARG; |
47e746b7 | 112 | if (m -> notify_object) |
4bd8800e | 113 | omapi_object_dereference (&m -> notify_object, MDL); |
47e746b7 | 114 | omapi_object_reference (&m -> notify_object, |
5edcb334 | 115 | value -> u.object, MDL); |
47e746b7 TL |
116 | return ISC_R_SUCCESS; |
117 | ||
61b844bf TL |
118 | /* Can set authid, but it has to be an integer. */ |
119 | } else if (!omapi_ds_strcmp (name, "authid")) { | |
120 | if (value -> type != omapi_datatype_int) | |
98bf1607 | 121 | return DHCP_R_INVALIDARG; |
61b844bf | 122 | m -> authid = value -> u.integer; |
581e37e4 | 123 | return ISC_R_SUCCESS; |
61b844bf TL |
124 | |
125 | /* Can set op, but it has to be an integer. */ | |
126 | } else if (!omapi_ds_strcmp (name, "op")) { | |
127 | if (value -> type != omapi_datatype_int) | |
98bf1607 | 128 | return DHCP_R_INVALIDARG; |
61b844bf | 129 | m -> op = value -> u.integer; |
581e37e4 | 130 | return ISC_R_SUCCESS; |
61b844bf TL |
131 | |
132 | /* Handle also has to be an integer. */ | |
133 | } else if (!omapi_ds_strcmp (name, "handle")) { | |
134 | if (value -> type != omapi_datatype_int) | |
98bf1607 | 135 | return DHCP_R_INVALIDARG; |
61b844bf | 136 | m -> h = value -> u.integer; |
581e37e4 | 137 | return ISC_R_SUCCESS; |
61b844bf TL |
138 | |
139 | /* Transaction ID has to be an integer. */ | |
140 | } else if (!omapi_ds_strcmp (name, "id")) { | |
141 | if (value -> type != omapi_datatype_int) | |
98bf1607 | 142 | return DHCP_R_INVALIDARG; |
61b844bf | 143 | m -> id = value -> u.integer; |
581e37e4 | 144 | return ISC_R_SUCCESS; |
61b844bf TL |
145 | |
146 | /* Remote transaction ID has to be an integer. */ | |
147 | } else if (!omapi_ds_strcmp (name, "rid")) { | |
148 | if (value -> type != omapi_datatype_int) | |
98bf1607 | 149 | return DHCP_R_INVALIDARG; |
61b844bf | 150 | m -> rid = value -> u.integer; |
581e37e4 | 151 | return ISC_R_SUCCESS; |
61b844bf TL |
152 | } |
153 | ||
154 | /* Try to find some inner object that can take the value. */ | |
155 | if (h -> inner && h -> inner -> type -> set_value) { | |
156 | status = ((*(h -> inner -> type -> set_value)) | |
157 | (h -> inner, id, name, value)); | |
158 | if (status == ISC_R_SUCCESS) | |
159 | return status; | |
160 | } | |
161 | ||
162 | return ISC_R_NOTFOUND; | |
163 | } | |
164 | ||
165 | isc_result_t omapi_message_get_value (omapi_object_t *h, | |
166 | omapi_object_t *id, | |
167 | omapi_data_string_t *name, | |
168 | omapi_value_t **value) | |
169 | { | |
170 | omapi_message_object_t *m; | |
171 | if (h -> type != omapi_type_message) | |
98bf1607 | 172 | return DHCP_R_INVALIDARG; |
61b844bf TL |
173 | m = (omapi_message_object_t *)h; |
174 | ||
175 | /* Look for values that are in the message data structure. */ | |
176 | if (!omapi_ds_strcmp (name, "authlen")) | |
b1b7b521 | 177 | return omapi_make_int_value (value, name, (int)m -> authlen, |
5edcb334 | 178 | MDL); |
61b844bf TL |
179 | else if (!omapi_ds_strcmp (name, "authenticator")) { |
180 | if (m -> authenticator) | |
5edcb334 TL |
181 | return omapi_make_value (value, name, |
182 | m -> authenticator, MDL); | |
61b844bf TL |
183 | else |
184 | return ISC_R_NOTFOUND; | |
185 | } else if (!omapi_ds_strcmp (name, "authid")) { | |
5edcb334 TL |
186 | return omapi_make_int_value (value, |
187 | name, (int)m -> authid, MDL); | |
61b844bf | 188 | } else if (!omapi_ds_strcmp (name, "op")) { |
5edcb334 | 189 | return omapi_make_int_value (value, name, (int)m -> op, MDL); |
61b844bf | 190 | } else if (!omapi_ds_strcmp (name, "handle")) { |
5edcb334 | 191 | return omapi_make_int_value (value, name, (int)m -> h, MDL); |
61b844bf | 192 | } else if (!omapi_ds_strcmp (name, "id")) { |
5edcb334 | 193 | return omapi_make_int_value (value, name, (int)m -> id, MDL); |
61b844bf | 194 | } else if (!omapi_ds_strcmp (name, "rid")) { |
5edcb334 | 195 | return omapi_make_int_value (value, name, (int)m -> rid, MDL); |
61b844bf TL |
196 | } |
197 | ||
198 | /* See if there's an inner object that has the value. */ | |
199 | if (h -> inner && h -> inner -> type -> get_value) | |
200 | return (*(h -> inner -> type -> get_value)) | |
201 | (h -> inner, id, name, value); | |
202 | return ISC_R_NOTFOUND; | |
203 | } | |
204 | ||
5edcb334 TL |
205 | isc_result_t omapi_message_destroy (omapi_object_t *h, |
206 | const char *file, int line) | |
61b844bf | 207 | { |
61b844bf TL |
208 | omapi_message_object_t *m; |
209 | if (h -> type != omapi_type_message) | |
98bf1607 | 210 | return DHCP_R_INVALIDARG; |
4bd8800e | 211 | m = (omapi_message_object_t *)h; |
61b844bf | 212 | if (m -> authenticator) { |
5edcb334 | 213 | omapi_typed_data_dereference (&m -> authenticator, file, line); |
61b844bf TL |
214 | } |
215 | if (!m -> prev && omapi_registered_messages != m) | |
216 | omapi_message_unregister (h); | |
61b844bf | 217 | if (m -> id_object) |
d758ad8c | 218 | omapi_object_dereference (&m -> id_object, file, line); |
61b844bf | 219 | if (m -> object) |
d758ad8c TL |
220 | omapi_object_dereference (&m -> object, file, line); |
221 | if (m -> notify_object) | |
222 | omapi_object_dereference (&m -> notify_object, file, line); | |
223 | if (m -> protocol_object) | |
224 | omapi_protocol_dereference (&m -> protocol_object, file, line); | |
61b844bf TL |
225 | return ISC_R_SUCCESS; |
226 | } | |
227 | ||
228 | isc_result_t omapi_message_signal_handler (omapi_object_t *h, | |
b1b7b521 | 229 | const char *name, va_list ap) |
61b844bf | 230 | { |
aca22287 | 231 | omapi_message_object_t *m; |
61b844bf | 232 | if (h -> type != omapi_type_message) |
98bf1607 | 233 | return DHCP_R_INVALIDARG; |
aca22287 | 234 | m = (omapi_message_object_t *)h; |
61b844bf | 235 | |
49146f3c DN |
236 | if (!strcmp (name, "status")) { |
237 | if (m -> notify_object && | |
238 | m -> notify_object -> type -> signal_handler) | |
47e746b7 TL |
239 | return ((m -> notify_object -> type -> signal_handler)) |
240 | (m -> notify_object, name, ap); | |
49146f3c DN |
241 | else if (m -> object && m -> object -> type -> signal_handler) |
242 | return ((m -> object -> type -> signal_handler)) | |
243 | (m -> object, name, ap); | |
aca22287 | 244 | } |
61b844bf TL |
245 | if (h -> inner && h -> inner -> type -> signal_handler) |
246 | return (*(h -> inner -> type -> signal_handler)) (h -> inner, | |
247 | name, ap); | |
248 | return ISC_R_NOTFOUND; | |
249 | } | |
250 | ||
251 | /* Write all the published values associated with the object through the | |
252 | specified connection. */ | |
253 | ||
254 | isc_result_t omapi_message_stuff_values (omapi_object_t *c, | |
255 | omapi_object_t *id, | |
256 | omapi_object_t *m) | |
257 | { | |
61b844bf | 258 | if (m -> type != omapi_type_message) |
98bf1607 | 259 | return DHCP_R_INVALIDARG; |
61b844bf TL |
260 | |
261 | if (m -> inner && m -> inner -> type -> stuff_values) | |
262 | return (*(m -> inner -> type -> stuff_values)) (c, id, | |
263 | m -> inner); | |
264 | return ISC_R_SUCCESS; | |
265 | } | |
266 | ||
267 | isc_result_t omapi_message_register (omapi_object_t *mo) | |
268 | { | |
269 | omapi_message_object_t *m; | |
270 | ||
271 | if (mo -> type != omapi_type_message) | |
98bf1607 | 272 | return DHCP_R_INVALIDARG; |
61b844bf TL |
273 | m = (omapi_message_object_t *)mo; |
274 | ||
275 | /* Already registered? */ | |
276 | if (m -> prev || m -> next || omapi_registered_messages == m) | |
98bf1607 | 277 | return DHCP_R_INVALIDARG; |
61b844bf TL |
278 | |
279 | if (omapi_registered_messages) { | |
280 | omapi_object_reference | |
281 | ((omapi_object_t **)&m -> next, | |
4bd8800e | 282 | (omapi_object_t *)omapi_registered_messages, MDL); |
61b844bf TL |
283 | omapi_object_reference |
284 | ((omapi_object_t **)&omapi_registered_messages -> prev, | |
4bd8800e | 285 | (omapi_object_t *)m, MDL); |
61b844bf | 286 | omapi_object_dereference |
4bd8800e | 287 | ((omapi_object_t **)&omapi_registered_messages, MDL); |
61b844bf TL |
288 | } |
289 | omapi_object_reference | |
290 | ((omapi_object_t **)&omapi_registered_messages, | |
4bd8800e | 291 | (omapi_object_t *)m, MDL); |
61b844bf TL |
292 | return ISC_R_SUCCESS;; |
293 | } | |
294 | ||
295 | isc_result_t omapi_message_unregister (omapi_object_t *mo) | |
296 | { | |
297 | omapi_message_object_t *m; | |
298 | omapi_message_object_t *n; | |
299 | ||
300 | if (mo -> type != omapi_type_message) | |
98bf1607 | 301 | return DHCP_R_INVALIDARG; |
61b844bf TL |
302 | m = (omapi_message_object_t *)mo; |
303 | ||
304 | /* Not registered? */ | |
305 | if (!m -> prev && omapi_registered_messages != m) | |
98bf1607 | 306 | return DHCP_R_INVALIDARG; |
61b844bf TL |
307 | |
308 | n = (omapi_message_object_t *)0; | |
309 | if (m -> next) { | |
310 | omapi_object_reference ((omapi_object_t **)&n, | |
5edcb334 TL |
311 | (omapi_object_t *)m -> next, MDL); |
312 | omapi_object_dereference ((omapi_object_t **)&m -> next, MDL); | |
98311e4b | 313 | omapi_object_dereference ((omapi_object_t **)&n -> prev, MDL); |
61b844bf TL |
314 | } |
315 | if (m -> prev) { | |
316 | omapi_message_object_t *tmp = (omapi_message_object_t *)0; | |
317 | omapi_object_reference ((omapi_object_t **)&tmp, | |
5edcb334 TL |
318 | (omapi_object_t *)m -> prev, MDL); |
319 | omapi_object_dereference ((omapi_object_t **)&m -> prev, MDL); | |
61b844bf TL |
320 | if (tmp -> next) |
321 | omapi_object_dereference | |
5edcb334 | 322 | ((omapi_object_t **)&tmp -> next, MDL); |
61b844bf TL |
323 | if (n) |
324 | omapi_object_reference | |
325 | ((omapi_object_t **)&tmp -> next, | |
5edcb334 TL |
326 | (omapi_object_t *)n, MDL); |
327 | omapi_object_dereference ((omapi_object_t **)&tmp, MDL); | |
61b844bf TL |
328 | } else { |
329 | omapi_object_dereference | |
5edcb334 | 330 | ((omapi_object_t **)&omapi_registered_messages, MDL); |
61b844bf TL |
331 | if (n) |
332 | omapi_object_reference | |
333 | ((omapi_object_t **)&omapi_registered_messages, | |
5edcb334 | 334 | (omapi_object_t *)n, MDL); |
61b844bf TL |
335 | } |
336 | if (n) | |
5edcb334 | 337 | omapi_object_dereference ((omapi_object_t **)&n, MDL); |
61b844bf TL |
338 | return ISC_R_SUCCESS; |
339 | } | |
581e37e4 | 340 | |
e11a162f DN |
341 | #ifdef DEBUG_PROTOCOL |
342 | static const char *omapi_message_op_name(int op) { | |
343 | switch (op) { | |
344 | case OMAPI_OP_OPEN: return "OMAPI_OP_OPEN"; | |
345 | case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH"; | |
346 | case OMAPI_OP_UPDATE: return "OMAPI_OP_UPDATE"; | |
347 | case OMAPI_OP_STATUS: return "OMAPI_OP_STATUS"; | |
348 | case OMAPI_OP_DELETE: return "OMAPI_OP_DELETE"; | |
349 | case OMAPI_OP_NOTIFY: return "OMAPI_OP_NOTIFY"; | |
350 | default: return "(unknown op)"; | |
351 | } | |
352 | } | |
353 | #endif | |
354 | ||
31bbee78 TL |
355 | static isc_result_t |
356 | omapi_message_process_internal (omapi_object_t *, omapi_object_t *); | |
357 | ||
581e37e4 | 358 | isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po) |
31bbee78 TL |
359 | { |
360 | isc_result_t status; | |
95fd7038 | 361 | #if defined (DEBUG_MEMORY_LEAKAGE) && 0 |
31bbee78 TL |
362 | unsigned long previous_outstanding = dmalloc_outstanding; |
363 | #endif | |
364 | ||
365 | status = omapi_message_process_internal (mo, po); | |
366 | ||
367 | #if defined (DEBUG_MEMORY_LEAKAGE) && 0 | |
368 | log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term", | |
369 | dmalloc_generation, | |
370 | dmalloc_outstanding - previous_outstanding, | |
371 | dmalloc_outstanding, dmalloc_longterm); | |
372 | #endif | |
d758ad8c | 373 | #if defined (DEBUG_MEMORY_LEAKAGE) && 0 |
31bbee78 TL |
374 | dmalloc_dump_outstanding (); |
375 | #endif | |
376 | #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) && 0 | |
377 | dump_rc_history (); | |
378 | #endif | |
379 | ||
380 | return status; | |
381 | } | |
382 | ||
383 | static isc_result_t | |
384 | omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po) | |
581e37e4 TL |
385 | { |
386 | omapi_message_object_t *message, *m; | |
387 | omapi_object_t *object = (omapi_object_t *)0; | |
aca22287 | 388 | omapi_value_t *tv = (omapi_value_t *)0; |
013be24d TL |
389 | unsigned long create, update, exclusive; |
390 | unsigned long wsi; | |
581e37e4 TL |
391 | isc_result_t status, waitstatus; |
392 | omapi_object_type_t *type; | |
393 | ||
394 | if (mo -> type != omapi_type_message) | |
98bf1607 | 395 | return DHCP_R_INVALIDARG; |
581e37e4 TL |
396 | message = (omapi_message_object_t *)mo; |
397 | ||
e11a162f DN |
398 | #ifdef DEBUG_PROTOCOL |
399 | log_debug ("omapi_message_process(): " | |
400 | "op=%s handle=%#x id=%#x rid=%#x", | |
401 | omapi_message_op_name (message -> op), | |
402 | message -> h, message -> id, message -> rid); | |
403 | #endif | |
404 | ||
581e37e4 TL |
405 | if (message -> rid) { |
406 | for (m = omapi_registered_messages; m; m = m -> next) | |
407 | if (m -> id == message -> rid) | |
408 | break; | |
409 | /* If we don't have a real message corresponding to | |
410 | the message ID to which this message claims it is a | |
411 | response, something's fishy. */ | |
412 | if (!m) | |
413 | return ISC_R_NOTFOUND; | |
49146f3c DN |
414 | /* The authenticator on responses must match the initial |
415 | message. */ | |
416 | if (message -> authid != m -> authid) | |
417 | return ISC_R_NOTFOUND; | |
418 | } else { | |
aca22287 | 419 | m = (omapi_message_object_t *)0; |
581e37e4 | 420 | |
49146f3c DN |
421 | /* All messages must have an authenticator, with the exception |
422 | of messages that are opening a new authenticator. */ | |
98bf1607 SR |
423 | if (omapi_protocol_authenticated(po) && |
424 | !message->id_object && | |
425 | message->op != OMAPI_OP_OPEN) { | |
49146f3c | 426 | return omapi_protocol_send_status |
98bf1607 SR |
427 | (po, message->id_object, DHCP_R_NOKEYS, |
428 | message->id, "No authenticator on message"); | |
49146f3c DN |
429 | } |
430 | } | |
431 | ||
581e37e4 TL |
432 | switch (message -> op) { |
433 | case OMAPI_OP_OPEN: | |
434 | if (m) { | |
aca22287 | 435 | return omapi_protocol_send_status |
98bf1607 SR |
436 | (po, message->id_object, DHCP_R_INVALIDARG, |
437 | message->id, "OPEN can't be a response"); | |
581e37e4 TL |
438 | } |
439 | ||
440 | /* Get the type of the requested object, if one was | |
441 | specified. */ | |
49146f3c | 442 | status = omapi_get_value_str (mo, message -> id_object, |
581e37e4 TL |
443 | "type", &tv); |
444 | if (status == ISC_R_SUCCESS && | |
445 | (tv -> value -> type == omapi_datatype_data || | |
446 | tv -> value -> type == omapi_datatype_string)) { | |
447 | for (type = omapi_object_types; | |
448 | type; type = type -> next) | |
449 | if (!omapi_td_strcmp (tv -> value, | |
450 | type -> name)) | |
451 | break; | |
452 | } else | |
453 | type = (omapi_object_type_t *)0; | |
454 | if (tv) | |
5edcb334 | 455 | omapi_value_dereference (&tv, MDL); |
581e37e4 | 456 | |
49146f3c DN |
457 | /* If this object had no authenticator, the requested object |
458 | must be an authenticator object. */ | |
98bf1607 SR |
459 | if (omapi_protocol_authenticated(po) && |
460 | !message->id_object && | |
49146f3c DN |
461 | type != omapi_type_auth_key) { |
462 | return omapi_protocol_send_status | |
98bf1607 SR |
463 | (po, message->id_object, DHCP_R_NOKEYS, |
464 | message->id, "No authenticator on message"); | |
49146f3c DN |
465 | } |
466 | ||
581e37e4 | 467 | /* Get the create flag. */ |
49146f3c | 468 | status = omapi_get_value_str (mo, message -> id_object, |
581e37e4 TL |
469 | "create", &tv); |
470 | if (status == ISC_R_SUCCESS) { | |
aca22287 | 471 | status = omapi_get_int_value (&create, tv -> value); |
5edcb334 | 472 | omapi_value_dereference (&tv, MDL); |
581e37e4 | 473 | if (status != ISC_R_SUCCESS) { |
aca22287 | 474 | return omapi_protocol_send_status |
49146f3c | 475 | (po, message -> id_object, |
aca22287 | 476 | status, message -> id, |
581e37e4 | 477 | "invalid create flag value"); |
581e37e4 TL |
478 | } |
479 | } else | |
480 | create = 0; | |
481 | ||
482 | /* Get the update flag. */ | |
49146f3c | 483 | status = omapi_get_value_str (mo, message -> id_object, |
581e37e4 TL |
484 | "update", &tv); |
485 | if (status == ISC_R_SUCCESS) { | |
aca22287 | 486 | status = omapi_get_int_value (&update, tv -> value); |
5edcb334 | 487 | omapi_value_dereference (&tv, MDL); |
581e37e4 | 488 | if (status != ISC_R_SUCCESS) { |
aca22287 | 489 | return omapi_protocol_send_status |
49146f3c | 490 | (po, message -> id_object, |
aca22287 | 491 | status, message -> id, |
581e37e4 | 492 | "invalid update flag value"); |
581e37e4 TL |
493 | } |
494 | } else | |
495 | update = 0; | |
496 | ||
497 | /* Get the exclusive flag. */ | |
49146f3c | 498 | status = omapi_get_value_str (mo, message -> id_object, |
581e37e4 TL |
499 | "exclusive", &tv); |
500 | if (status == ISC_R_SUCCESS) { | |
aca22287 | 501 | status = omapi_get_int_value (&exclusive, tv -> value); |
5edcb334 | 502 | omapi_value_dereference (&tv, MDL); |
581e37e4 | 503 | if (status != ISC_R_SUCCESS) { |
aca22287 | 504 | return omapi_protocol_send_status |
49146f3c | 505 | (po, message -> id_object, |
aca22287 | 506 | status, message -> id, |
581e37e4 | 507 | "invalid exclusive flag value"); |
581e37e4 TL |
508 | } |
509 | } else | |
510 | exclusive = 0; | |
511 | ||
512 | /* If we weren't given a type, look the object up with | |
513 | the handle. */ | |
514 | if (!type) { | |
515 | if (create) { | |
aca22287 | 516 | return omapi_protocol_send_status |
98bf1607 SR |
517 | (po, message->id_object, |
518 | DHCP_R_INVALIDARG, | |
519 | message->id, | |
581e37e4 | 520 | "type required on create"); |
581e37e4 TL |
521 | } |
522 | goto refresh; | |
523 | } | |
524 | ||
525 | /* If the type doesn't provide a lookup method, we can't | |
526 | look up the object. */ | |
527 | if (!type -> lookup) { | |
aca22287 | 528 | return omapi_protocol_send_status |
49146f3c | 529 | (po, message -> id_object, |
aca22287 | 530 | ISC_R_NOTIMPLEMENTED, message -> id, |
581e37e4 | 531 | "unsearchable object type"); |
581e37e4 | 532 | } |
06feb756 | 533 | |
49146f3c | 534 | status = (*(type -> lookup)) (&object, message -> id_object, |
581e37e4 TL |
535 | message -> object); |
536 | ||
3c4358e7 TL |
537 | if (status != ISC_R_SUCCESS && |
538 | status != ISC_R_NOTFOUND && | |
98bf1607 | 539 | status != DHCP_R_NOKEYS) { |
aca22287 | 540 | return omapi_protocol_send_status |
49146f3c | 541 | (po, message -> id_object, |
aca22287 | 542 | status, message -> id, |
581e37e4 | 543 | "object lookup failed"); |
581e37e4 TL |
544 | } |
545 | ||
546 | /* If we didn't find the object and we aren't supposed to | |
547 | create it, return an error. */ | |
548 | if (status == ISC_R_NOTFOUND && !create) { | |
aca22287 | 549 | return omapi_protocol_send_status |
49146f3c | 550 | (po, message -> id_object, |
aca22287 | 551 | ISC_R_NOTFOUND, message -> id, |
581e37e4 | 552 | "no object matches specification"); |
581e37e4 TL |
553 | } |
554 | ||
555 | /* If we found an object, we're supposed to be creating an | |
556 | object, and we're not supposed to have found an object, | |
557 | return an error. */ | |
558 | if (status == ISC_R_SUCCESS && create && exclusive) { | |
5edcb334 | 559 | omapi_object_dereference (&object, MDL); |
aca22287 | 560 | return omapi_protocol_send_status |
49146f3c | 561 | (po, message -> id_object, |
aca22287 | 562 | ISC_R_EXISTS, message -> id, |
581e37e4 | 563 | "specified object already exists"); |
581e37e4 TL |
564 | } |
565 | ||
566 | /* If we're creating the object, do it now. */ | |
567 | if (!object) { | |
aca22287 | 568 | status = omapi_object_create (&object, |
49146f3c | 569 | message -> id_object, |
aca22287 | 570 | type); |
581e37e4 | 571 | if (status != ISC_R_SUCCESS) { |
aca22287 | 572 | return omapi_protocol_send_status |
49146f3c | 573 | (po, message -> id_object, |
aca22287 | 574 | status, message -> id, |
581e37e4 | 575 | "can't create new object"); |
581e37e4 TL |
576 | } |
577 | } | |
578 | ||
579 | /* If we're updating it, do so now. */ | |
580 | if (create || update) { | |
49146f3c DN |
581 | /* This check does not belong here. */ |
582 | if (object -> type == omapi_type_auth_key) { | |
583 | omapi_object_dereference (&object, MDL); | |
584 | return omapi_protocol_send_status | |
585 | (po, message -> id_object, | |
586 | status, message -> id, | |
587 | "can't update object"); | |
588 | } | |
589 | ||
581e37e4 | 590 | status = omapi_object_update (object, |
49146f3c | 591 | message -> id_object, |
47e746b7 | 592 | message -> object, |
5edcb334 | 593 | message -> h); |
581e37e4 | 594 | if (status != ISC_R_SUCCESS) { |
5edcb334 | 595 | omapi_object_dereference (&object, MDL); |
aca22287 | 596 | return omapi_protocol_send_status |
49146f3c | 597 | (po, message -> id_object, |
aca22287 | 598 | status, message -> id, |
581e37e4 | 599 | "can't update object"); |
581e37e4 TL |
600 | } |
601 | } | |
49146f3c DN |
602 | |
603 | /* If this is an authenticator object, add it to the active | |
604 | set for the connection. */ | |
605 | if (object -> type == omapi_type_auth_key) { | |
606 | omapi_handle_t handle; | |
607 | status = omapi_object_handle (&handle, object); | |
608 | if (status != ISC_R_SUCCESS) { | |
609 | omapi_object_dereference (&object, MDL); | |
610 | return omapi_protocol_send_status | |
611 | (po, message -> id_object, | |
612 | status, message -> id, | |
613 | "can't select authenticator"); | |
614 | } | |
615 | ||
616 | status = omapi_protocol_add_auth (po, object, handle); | |
617 | if (status != ISC_R_SUCCESS) { | |
618 | omapi_object_dereference (&object, MDL); | |
619 | return omapi_protocol_send_status | |
620 | (po, message -> id_object, | |
621 | status, message -> id, | |
622 | "can't select authenticator"); | |
623 | } | |
624 | } | |
581e37e4 TL |
625 | |
626 | /* Now send the new contents of the object back in | |
627 | response. */ | |
628 | goto send; | |
629 | ||
630 | case OMAPI_OP_REFRESH: | |
631 | refresh: | |
5edcb334 | 632 | status = omapi_handle_lookup (&object, message -> h); |
581e37e4 | 633 | if (status != ISC_R_SUCCESS) { |
aca22287 | 634 | return omapi_protocol_send_status |
49146f3c | 635 | (po, message -> id_object, |
aca22287 | 636 | status, message -> id, |
581e37e4 | 637 | "no matching handle"); |
581e37e4 TL |
638 | } |
639 | send: | |
49146f3c | 640 | status = omapi_protocol_send_update (po, message -> id_object, |
aca22287 | 641 | message -> id, object); |
5edcb334 | 642 | omapi_object_dereference (&object, MDL); |
aca22287 | 643 | return status; |
581e37e4 TL |
644 | |
645 | case OMAPI_OP_UPDATE: | |
49146f3c | 646 | if (m && m -> object) { |
98311e4b DH |
647 | status = omapi_object_reference (&object, m -> object, |
648 | MDL); | |
581e37e4 | 649 | } else { |
5edcb334 | 650 | status = omapi_handle_lookup (&object, message -> h); |
581e37e4 | 651 | if (status != ISC_R_SUCCESS) { |
aca22287 | 652 | return omapi_protocol_send_status |
49146f3c | 653 | (po, message -> id_object, |
aca22287 | 654 | status, message -> id, |
581e37e4 | 655 | "no matching handle"); |
581e37e4 TL |
656 | } |
657 | } | |
658 | ||
49146f3c DN |
659 | if (object -> type == omapi_type_auth_key || |
660 | (object -> inner && | |
661 | object -> inner -> type == omapi_type_auth_key)) { | |
662 | if (!m) { | |
663 | omapi_object_dereference (&object, MDL); | |
664 | return omapi_protocol_send_status | |
665 | (po, message -> id_object, | |
666 | status, message -> id, | |
667 | "cannot update authenticator"); | |
668 | } | |
669 | ||
670 | status = omapi_protocol_add_auth (po, object, | |
671 | message -> h); | |
672 | } else { | |
673 | status = omapi_object_update (object, | |
674 | message -> id_object, | |
675 | message -> object, | |
676 | message -> h); | |
677 | } | |
581e37e4 | 678 | if (status != ISC_R_SUCCESS) { |
5edcb334 | 679 | omapi_object_dereference (&object, MDL); |
581e37e4 | 680 | if (!message -> rid) |
aca22287 | 681 | return omapi_protocol_send_status |
49146f3c | 682 | (po, message -> id_object, |
aca22287 | 683 | status, message -> id, |
581e37e4 TL |
684 | "can't update object"); |
685 | if (m) | |
686 | omapi_signal ((omapi_object_t *)m, | |
aca22287 TL |
687 | "status", status, |
688 | (omapi_typed_data_t *)0); | |
581e37e4 TL |
689 | return ISC_R_SUCCESS; |
690 | } | |
691 | if (!message -> rid) | |
aca22287 | 692 | status = omapi_protocol_send_status |
49146f3c | 693 | (po, message -> id_object, ISC_R_SUCCESS, |
aca22287 | 694 | message -> id, (char *)0); |
98311e4b | 695 | if (m) { |
581e37e4 | 696 | omapi_signal ((omapi_object_t *)m, |
aca22287 TL |
697 | "status", ISC_R_SUCCESS, |
698 | (omapi_typed_data_t *)0); | |
98311e4b DH |
699 | omapi_message_unregister ((omapi_object_t *)m); |
700 | } | |
701 | ||
702 | omapi_object_dereference (&object, MDL); | |
703 | ||
aca22287 | 704 | return status; |
581e37e4 TL |
705 | |
706 | case OMAPI_OP_NOTIFY: | |
aca22287 | 707 | return omapi_protocol_send_status |
49146f3c | 708 | (po, message -> id_object, ISC_R_NOTIMPLEMENTED, |
aca22287 | 709 | message -> id, "notify not implemented yet"); |
581e37e4 | 710 | |
aca22287 TL |
711 | case OMAPI_OP_STATUS: |
712 | /* The return status of a request. */ | |
581e37e4 TL |
713 | if (!m) |
714 | return ISC_R_UNEXPECTED; | |
715 | ||
716 | /* Get the wait status. */ | |
49146f3c | 717 | status = omapi_get_value_str (mo, message -> id_object, |
581e37e4 TL |
718 | "result", &tv); |
719 | if (status == ISC_R_SUCCESS) { | |
013be24d TL |
720 | status = omapi_get_int_value (&wsi, tv -> value); |
721 | waitstatus = wsi; | |
5edcb334 | 722 | omapi_value_dereference (&tv, MDL); |
581e37e4 TL |
723 | if (status != ISC_R_SUCCESS) |
724 | waitstatus = ISC_R_UNEXPECTED; | |
725 | } else | |
726 | waitstatus = ISC_R_UNEXPECTED; | |
581e37e4 | 727 | |
49146f3c | 728 | status = omapi_get_value_str (mo, message -> id_object, |
aca22287 TL |
729 | "message", &tv); |
730 | omapi_signal ((omapi_object_t *)m, "status", waitstatus, tv); | |
731 | if (status == ISC_R_SUCCESS) | |
5edcb334 | 732 | omapi_value_dereference (&tv, MDL); |
98311e4b DH |
733 | |
734 | omapi_message_unregister((omapi_object_t *)m); | |
735 | ||
581e37e4 | 736 | return ISC_R_SUCCESS; |
47e746b7 TL |
737 | |
738 | case OMAPI_OP_DELETE: | |
5edcb334 | 739 | status = omapi_handle_lookup (&object, message -> h); |
47e746b7 TL |
740 | if (status != ISC_R_SUCCESS) { |
741 | return omapi_protocol_send_status | |
49146f3c | 742 | (po, message -> id_object, |
47e746b7 TL |
743 | status, message -> id, |
744 | "no matching handle"); | |
745 | } | |
746 | ||
ccce1cc6 | 747 | if (!object -> type -> remove) |
47e746b7 | 748 | return omapi_protocol_send_status |
49146f3c | 749 | (po, message -> id_object, |
47e746b7 | 750 | ISC_R_NOTIMPLEMENTED, message -> id, |
ccce1cc6 | 751 | "no remove method for object"); |
47e746b7 | 752 | |
ccce1cc6 | 753 | status = (*(object -> type -> remove)) (object, |
49146f3c | 754 | message -> id_object); |
5edcb334 | 755 | omapi_object_dereference (&object, MDL); |
47e746b7 | 756 | |
49146f3c | 757 | return omapi_protocol_send_status (po, message -> id_object, |
47e746b7 TL |
758 | status, message -> id, |
759 | (char *)0); | |
581e37e4 TL |
760 | } |
761 | return ISC_R_NOTIMPLEMENTED; | |
762 | } |