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