]> git.ipfire.org Git - thirdparty/dhcp.git/blame - omapip/message.c
[master] Add patch to limit the value of an fd we accept for a connection.
[thirdparty/dhcp.git] / omapip / message.c
CommitLineData
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
33OMAPI_OBJECT_ALLOC (omapi_message,
34 omapi_message_object_t, omapi_type_message)
35
61b844bf
TL
36omapi_message_object_t *omapi_registered_messages;
37
5edcb334 38isc_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
79isc_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
165isc_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
205isc_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
228isc_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
254isc_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
267isc_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
295isc_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
342static 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
355static isc_result_t
356omapi_message_process_internal (omapi_object_t *, omapi_object_t *);
357
581e37e4 358isc_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
383static isc_result_t
384omapi_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}