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