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