omapip/message.c

Go to the documentation of this file.
00001 /* message.c
00002 
00003    Subroutines for dealing with message objects. */
00004 
00005 /*
00006  * Copyright (c) 2004,2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC")
00007  * Copyright (c) 1999-2003 by Internet Software Consortium
00008  *
00009  * Permission to use, copy, modify, and distribute this software for any
00010  * purpose with or without fee is hereby granted, provided that the above
00011  * copyright notice and this permission notice appear in all copies.
00012  *
00013  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
00014  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00015  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
00016  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00017  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00018  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
00019  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00020  *
00021  *   Internet Systems Consortium, Inc.
00022  *   950 Charter Street
00023  *   Redwood City, CA 94063
00024  *   <info@isc.org>
00025  *   https://www.isc.org/
00026  *
00027  */
00028 
00029 #include "dhcpd.h"
00030 
00031 #include <omapip/omapip_p.h>
00032 
00033 OMAPI_OBJECT_ALLOC (omapi_message,
00034                     omapi_message_object_t, omapi_type_message)
00035 
00036 omapi_message_object_t *omapi_registered_messages;
00037 
00038 isc_result_t omapi_message_new (omapi_object_t **o, const char *file, int line)
00039 {
00040         omapi_message_object_t *m;
00041         omapi_object_t *g;
00042         isc_result_t status;
00043 
00044         m = (omapi_message_object_t *)0;
00045         status = omapi_message_allocate (&m, file, line);
00046         if (status != ISC_R_SUCCESS)
00047                 return status;
00048 
00049         g = (omapi_object_t *)0;
00050         status = omapi_generic_new (&g, file, line);
00051         if (status != ISC_R_SUCCESS) {
00052                 dfree (m, file, line);
00053                 return status;
00054         }
00055         status = omapi_object_reference (&m -> inner, g, file, line);
00056         if (status != ISC_R_SUCCESS) {
00057                 omapi_object_dereference ((omapi_object_t **)&m, file, line);
00058                 omapi_object_dereference (&g, file, line);
00059                 return status;
00060         }
00061         status = omapi_object_reference (&g -> outer,
00062                                          (omapi_object_t *)m, file, line);
00063 
00064         if (status != ISC_R_SUCCESS) {
00065                 omapi_object_dereference ((omapi_object_t **)&m, file, line);
00066                 omapi_object_dereference (&g, file, line);
00067                 return status;
00068         }
00069 
00070         status = omapi_object_reference (o, (omapi_object_t *)m, file, line);
00071         omapi_message_dereference (&m, file, line);
00072         omapi_object_dereference (&g, file, line);
00073         if (status != ISC_R_SUCCESS)
00074                 return status;
00075 
00076         return status;
00077 }
00078 
00079 isc_result_t omapi_message_set_value (omapi_object_t *h,
00080                                       omapi_object_t *id,
00081                                       omapi_data_string_t *name,
00082                                       omapi_typed_data_t *value)
00083 {
00084         omapi_message_object_t *m;
00085         isc_result_t status;
00086 
00087         if (h -> type != omapi_type_message)
00088                 return DHCP_R_INVALIDARG;
00089         m = (omapi_message_object_t *)h;
00090 
00091         /* Can't set authlen. */
00092 
00093         /* Can set authenticator, but the value must be typed data. */
00094         if (!omapi_ds_strcmp (name, "authenticator")) {
00095                 if (m -> authenticator)
00096                         omapi_typed_data_dereference (&m -> authenticator,
00097                                                       MDL);
00098                 omapi_typed_data_reference (&m -> authenticator, value, MDL);
00099                 return ISC_R_SUCCESS;
00100 
00101         } else if (!omapi_ds_strcmp (name, "object")) {
00102                 if (value -> type != omapi_datatype_object)
00103                         return DHCP_R_INVALIDARG;
00104                 if (m -> object)
00105                         omapi_object_dereference (&m -> object, MDL);
00106                 omapi_object_reference (&m -> object, value -> u.object, MDL);
00107                 return ISC_R_SUCCESS;
00108 
00109         } else if (!omapi_ds_strcmp (name, "notify-object")) {
00110                 if (value -> type != omapi_datatype_object)
00111                         return DHCP_R_INVALIDARG;
00112                 if (m -> notify_object)
00113                         omapi_object_dereference (&m -> notify_object, MDL);
00114                 omapi_object_reference (&m -> notify_object,
00115                                         value -> u.object, MDL);
00116                 return ISC_R_SUCCESS;
00117 
00118         /* Can set authid, but it has to be an integer. */
00119         } else if (!omapi_ds_strcmp (name, "authid")) {
00120                 if (value -> type != omapi_datatype_int)
00121                         return DHCP_R_INVALIDARG;
00122                 m -> authid = value -> u.integer;
00123                 return ISC_R_SUCCESS;
00124 
00125         /* Can set op, but it has to be an integer. */
00126         } else if (!omapi_ds_strcmp (name, "op")) {
00127                 if (value -> type != omapi_datatype_int)
00128                         return DHCP_R_INVALIDARG;
00129                 m -> op = value -> u.integer;
00130                 return ISC_R_SUCCESS;
00131 
00132         /* Handle also has to be an integer. */
00133         } else if (!omapi_ds_strcmp (name, "handle")) {
00134                 if (value -> type != omapi_datatype_int)
00135                         return DHCP_R_INVALIDARG;
00136                 m -> h = value -> u.integer;
00137                 return ISC_R_SUCCESS;
00138 
00139         /* Transaction ID has to be an integer. */
00140         } else if (!omapi_ds_strcmp (name, "id")) {
00141                 if (value -> type != omapi_datatype_int)
00142                         return DHCP_R_INVALIDARG;
00143                 m -> id = value -> u.integer;
00144                 return ISC_R_SUCCESS;
00145 
00146         /* Remote transaction ID has to be an integer. */
00147         } else if (!omapi_ds_strcmp (name, "rid")) {
00148                 if (value -> type != omapi_datatype_int)
00149                         return DHCP_R_INVALIDARG;
00150                 m -> rid = value -> u.integer;
00151                 return ISC_R_SUCCESS;
00152         }
00153 
00154         /* Try to find some inner object that can take the value. */
00155         if (h -> inner && h -> inner -> type -> set_value) {
00156                 status = ((*(h -> inner -> type -> set_value))
00157                           (h -> inner, id, name, value));
00158                 if (status == ISC_R_SUCCESS)
00159                         return status;
00160         }
00161                           
00162         return ISC_R_NOTFOUND;
00163 }
00164 
00165 isc_result_t omapi_message_get_value (omapi_object_t *h,
00166                                       omapi_object_t *id,
00167                                       omapi_data_string_t *name,
00168                                       omapi_value_t **value)
00169 {
00170         omapi_message_object_t *m;
00171         if (h -> type != omapi_type_message)
00172                 return DHCP_R_INVALIDARG;
00173         m = (omapi_message_object_t *)h;
00174 
00175         /* Look for values that are in the message data structure. */
00176         if (!omapi_ds_strcmp (name, "authlen"))
00177                 return omapi_make_int_value (value, name, (int)m -> authlen,
00178                                              MDL);
00179         else if (!omapi_ds_strcmp (name, "authenticator")) {
00180                 if (m -> authenticator)
00181                         return omapi_make_value (value, name,
00182                                                  m -> authenticator, MDL);
00183                 else
00184                         return ISC_R_NOTFOUND;
00185         } else if (!omapi_ds_strcmp (name, "authid")) {
00186                 return omapi_make_int_value (value,
00187                                              name, (int)m -> authid, MDL);
00188         } else if (!omapi_ds_strcmp (name, "op")) {
00189                 return omapi_make_int_value (value, name, (int)m -> op, MDL);
00190         } else if (!omapi_ds_strcmp (name, "handle")) {
00191                 return omapi_make_int_value (value, name, (int)m -> h, MDL);
00192         } else if (!omapi_ds_strcmp (name, "id")) {
00193                 return omapi_make_int_value (value, name, (int)m -> id, MDL);
00194         } else if (!omapi_ds_strcmp (name, "rid")) {
00195                 return omapi_make_int_value (value, name, (int)m -> rid, MDL);
00196         }
00197 
00198         /* See if there's an inner object that has the value. */
00199         if (h -> inner && h -> inner -> type -> get_value)
00200                 return (*(h -> inner -> type -> get_value))
00201                         (h -> inner, id, name, value);
00202         return ISC_R_NOTFOUND;
00203 }
00204 
00205 isc_result_t omapi_message_destroy (omapi_object_t *h,
00206                                     const char *file, int line)
00207 {
00208         omapi_message_object_t *m;
00209         if (h -> type != omapi_type_message)
00210                 return DHCP_R_INVALIDARG;
00211         m = (omapi_message_object_t *)h;
00212         if (m -> authenticator) {
00213                 omapi_typed_data_dereference (&m -> authenticator, file, line);
00214         }
00215         if (!m -> prev && omapi_registered_messages != m)
00216                 omapi_message_unregister (h);
00217         if (m -> id_object)
00218                 omapi_object_dereference (&m -> id_object, file, line);
00219         if (m -> object)
00220                 omapi_object_dereference (&m -> object, file, line);
00221         if (m -> notify_object)
00222                 omapi_object_dereference (&m -> notify_object, file, line);
00223         if (m -> protocol_object)
00224                 omapi_protocol_dereference (&m -> protocol_object, file, line);
00225         return ISC_R_SUCCESS;
00226 }
00227 
00228 isc_result_t omapi_message_signal_handler (omapi_object_t *h,
00229                                            const char *name, va_list ap)
00230 {
00231         omapi_message_object_t *m;
00232         if (h -> type != omapi_type_message)
00233                 return DHCP_R_INVALIDARG;
00234         m = (omapi_message_object_t *)h;
00235         
00236         if (!strcmp (name, "status")) {
00237                 if (m -> notify_object &&
00238                     m -> notify_object -> type -> signal_handler)
00239                         return ((m -> notify_object -> type -> signal_handler))
00240                                 (m -> notify_object, name, ap);
00241                 else if (m -> object && m -> object -> type -> signal_handler)
00242                         return ((m -> object -> type -> signal_handler))
00243                                 (m -> object, name, ap);
00244         }
00245         if (h -> inner && h -> inner -> type -> signal_handler)
00246                 return (*(h -> inner -> type -> signal_handler)) (h -> inner,
00247                                                                   name, ap);
00248         return ISC_R_NOTFOUND;
00249 }
00250 
00251 /* Write all the published values associated with the object through the
00252    specified connection. */
00253 
00254 isc_result_t omapi_message_stuff_values (omapi_object_t *c,
00255                                          omapi_object_t *id,
00256                                          omapi_object_t *m)
00257 {
00258         if (m -> type != omapi_type_message)
00259                 return DHCP_R_INVALIDARG;
00260 
00261         if (m -> inner && m -> inner -> type -> stuff_values)
00262                 return (*(m -> inner -> type -> stuff_values)) (c, id,
00263                                                                 m -> inner);
00264         return ISC_R_SUCCESS;
00265 }
00266 
00267 isc_result_t omapi_message_register (omapi_object_t *mo)
00268 {
00269         omapi_message_object_t *m;
00270 
00271         if (mo -> type != omapi_type_message)
00272                 return DHCP_R_INVALIDARG;
00273         m = (omapi_message_object_t *)mo;
00274         
00275         /* Already registered? */
00276         if (m -> prev || m -> next || omapi_registered_messages == m)
00277                 return DHCP_R_INVALIDARG;
00278 
00279         if (omapi_registered_messages) {
00280                 omapi_object_reference
00281                         ((omapi_object_t **)&m -> next,
00282                          (omapi_object_t *)omapi_registered_messages, MDL);
00283                 omapi_object_reference
00284                         ((omapi_object_t **)&omapi_registered_messages -> prev,
00285                          (omapi_object_t *)m, MDL);
00286                 omapi_object_dereference
00287                         ((omapi_object_t **)&omapi_registered_messages, MDL);
00288         }
00289         omapi_object_reference
00290                 ((omapi_object_t **)&omapi_registered_messages,
00291                  (omapi_object_t *)m, MDL);
00292         return ISC_R_SUCCESS;;
00293 }
00294 
00295 isc_result_t omapi_message_unregister (omapi_object_t *mo)
00296 {
00297         omapi_message_object_t *m;
00298         omapi_message_object_t *n;
00299 
00300         if (mo -> type != omapi_type_message)
00301                 return DHCP_R_INVALIDARG;
00302         m = (omapi_message_object_t *)mo;
00303         
00304         /* Not registered? */
00305         if (!m -> prev && omapi_registered_messages != m)
00306                 return DHCP_R_INVALIDARG;
00307 
00308         n = (omapi_message_object_t *)0;
00309         if (m -> next) {
00310                 omapi_object_reference ((omapi_object_t **)&n,
00311                                         (omapi_object_t *)m -> next, MDL);
00312                 omapi_object_dereference ((omapi_object_t **)&m -> next, MDL);
00313                 omapi_object_dereference ((omapi_object_t **)&n -> prev, MDL);
00314         }
00315         if (m -> prev) {
00316                 omapi_message_object_t *tmp = (omapi_message_object_t *)0;
00317                 omapi_object_reference ((omapi_object_t **)&tmp,
00318                                         (omapi_object_t *)m -> prev, MDL);
00319                 omapi_object_dereference ((omapi_object_t **)&m -> prev, MDL);
00320                 if (tmp -> next)
00321                         omapi_object_dereference
00322                                 ((omapi_object_t **)&tmp -> next, MDL);
00323                 if (n)
00324                         omapi_object_reference
00325                                 ((omapi_object_t **)&tmp -> next,
00326                                  (omapi_object_t *)n, MDL);
00327                 omapi_object_dereference ((omapi_object_t **)&tmp, MDL);
00328         } else {
00329                 omapi_object_dereference
00330                         ((omapi_object_t **)&omapi_registered_messages, MDL);
00331                 if (n)
00332                         omapi_object_reference
00333                                 ((omapi_object_t **)&omapi_registered_messages,
00334                                  (omapi_object_t *)n, MDL);
00335         }
00336         if (n)
00337                 omapi_object_dereference ((omapi_object_t **)&n, MDL);
00338         return ISC_R_SUCCESS;
00339 }
00340 
00341 #ifdef DEBUG_PROTOCOL
00342 static const char *omapi_message_op_name(int op) {
00343         switch (op) {
00344         case OMAPI_OP_OPEN:    return "OMAPI_OP_OPEN";
00345         case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH";
00346         case OMAPI_OP_UPDATE:  return "OMAPI_OP_UPDATE";
00347         case OMAPI_OP_STATUS:  return "OMAPI_OP_STATUS";
00348         case OMAPI_OP_DELETE:  return "OMAPI_OP_DELETE";
00349         case OMAPI_OP_NOTIFY:  return "OMAPI_OP_NOTIFY";
00350         default:               return "(unknown op)";
00351         }
00352 }
00353 #endif
00354 
00355 static isc_result_t
00356 omapi_message_process_internal (omapi_object_t *, omapi_object_t *);
00357 
00358 isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
00359 {
00360         isc_result_t status;
00361 #if defined (DEBUG_MEMORY_LEAKAGE) && 0
00362         unsigned long previous_outstanding = dmalloc_outstanding;
00363 #endif
00364 
00365         status = omapi_message_process_internal (mo, po);
00366 
00367 #if defined (DEBUG_MEMORY_LEAKAGE) && 0
00368         log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",
00369                   dmalloc_generation,
00370                   dmalloc_outstanding - previous_outstanding,
00371                   dmalloc_outstanding, dmalloc_longterm);
00372 #endif
00373 #if defined (DEBUG_MEMORY_LEAKAGE) && 0
00374         dmalloc_dump_outstanding ();
00375 #endif
00376 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) && 0
00377         dump_rc_history ();
00378 #endif
00379 
00380         return status;
00381 }
00382 
00383 static isc_result_t
00384 omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po)
00385 {
00386         omapi_message_object_t *message, *m;
00387         omapi_object_t *object = (omapi_object_t *)0;
00388         omapi_value_t *tv = (omapi_value_t *)0;
00389         unsigned long create, update, exclusive;
00390         unsigned long wsi;
00391         isc_result_t status, waitstatus;
00392         omapi_object_type_t *type;
00393 
00394         if (mo -> type != omapi_type_message)
00395                 return DHCP_R_INVALIDARG;
00396         message = (omapi_message_object_t *)mo;
00397 
00398 #ifdef DEBUG_PROTOCOL
00399         log_debug ("omapi_message_process(): "
00400                    "op=%s  handle=%#x  id=%#x  rid=%#x",
00401                    omapi_message_op_name (message -> op),
00402                    message -> h, message -> id, message -> rid);
00403 #endif
00404 
00405         if (message -> rid) {
00406                 for (m = omapi_registered_messages; m; m = m -> next)
00407                         if (m -> id == message -> rid)
00408                                 break;
00409                 /* If we don't have a real message corresponding to
00410                    the message ID to which this message claims it is a
00411                    response, something's fishy. */
00412                 if (!m)
00413                         return ISC_R_NOTFOUND;
00414                 /* The authenticator on responses must match the initial
00415                    message. */
00416                 if (message -> authid != m -> authid)
00417                         return ISC_R_NOTFOUND;
00418         } else {
00419                 m = (omapi_message_object_t *)0;
00420 
00421                 /* All messages must have an authenticator, with the exception
00422                    of messages that are opening a new authenticator. */
00423                 if (omapi_protocol_authenticated(po) &&
00424                     !message->id_object &&
00425                     message->op != OMAPI_OP_OPEN) {
00426                         return omapi_protocol_send_status
00427                                 (po, message->id_object, DHCP_R_NOKEYS,
00428                                  message->id, "No authenticator on message");
00429                 }
00430         }
00431 
00432         switch (message -> op) {
00433               case OMAPI_OP_OPEN:
00434                 if (m) {
00435                         return omapi_protocol_send_status
00436                                 (po, message->id_object, DHCP_R_INVALIDARG,
00437                                  message->id, "OPEN can't be a response");
00438                 }
00439 
00440                 /* Get the type of the requested object, if one was
00441                    specified. */
00442                 status = omapi_get_value_str (mo, message -> id_object,
00443                                               "type", &tv);
00444                 if (status == ISC_R_SUCCESS &&
00445                     (tv -> value -> type == omapi_datatype_data ||
00446                      tv -> value -> type == omapi_datatype_string)) {
00447                         for (type = omapi_object_types;
00448                              type; type = type -> next)
00449                                 if (!omapi_td_strcmp (tv -> value,
00450                                                       type -> name))
00451                                         break;
00452                 } else
00453                         type = (omapi_object_type_t *)0;
00454                 if (tv)
00455                         omapi_value_dereference (&tv, MDL);
00456 
00457                 /* If this object had no authenticator, the requested object
00458                    must be an authenticator object. */
00459                 if (omapi_protocol_authenticated(po) &&
00460                     !message->id_object &&
00461                     type != omapi_type_auth_key) {
00462                         return omapi_protocol_send_status
00463                                 (po, message->id_object, DHCP_R_NOKEYS,
00464                                  message->id, "No authenticator on message");
00465                 }
00466 
00467                 /* Get the create flag. */
00468                 status = omapi_get_value_str (mo, message -> id_object,
00469                                               "create", &tv);
00470                 if (status == ISC_R_SUCCESS) {
00471                         status = omapi_get_int_value (&create, tv -> value);
00472                         omapi_value_dereference (&tv, MDL);
00473                         if (status != ISC_R_SUCCESS) {
00474                                 return omapi_protocol_send_status
00475                                         (po, message -> id_object,
00476                                          status, message -> id,
00477                                          "invalid create flag value");
00478                         }
00479                 } else
00480                         create = 0;
00481 
00482                 /* Get the update flag. */
00483                 status = omapi_get_value_str (mo, message -> id_object,
00484                                               "update", &tv);
00485                 if (status == ISC_R_SUCCESS) {
00486                         status = omapi_get_int_value (&update, tv -> value);
00487                         omapi_value_dereference (&tv, MDL);
00488                         if (status != ISC_R_SUCCESS) {
00489                                 return omapi_protocol_send_status
00490                                         (po, message -> id_object,
00491                                          status, message -> id,
00492                                          "invalid update flag value");
00493                         }
00494                 } else
00495                         update = 0;
00496 
00497                 /* Get the exclusive flag. */
00498                 status = omapi_get_value_str (mo, message -> id_object,
00499                                               "exclusive", &tv);
00500                 if (status == ISC_R_SUCCESS) {
00501                         status = omapi_get_int_value (&exclusive, tv -> value);
00502                         omapi_value_dereference (&tv, MDL);
00503                         if (status != ISC_R_SUCCESS) {
00504                                 return omapi_protocol_send_status
00505                                         (po, message -> id_object,
00506                                          status, message -> id,
00507                                          "invalid exclusive flag value");
00508                         }
00509                 } else
00510                         exclusive = 0;
00511 
00512                 /* If we weren't given a type, look the object up with
00513                    the handle. */
00514                 if (!type) {
00515                         if (create) {
00516                                 return omapi_protocol_send_status
00517                                         (po, message->id_object,
00518                                          DHCP_R_INVALIDARG,
00519                                          message->id,
00520                                          "type required on create");
00521                         }
00522                         goto refresh;
00523                 }
00524 
00525                 /* If the type doesn't provide a lookup method, we can't
00526                    look up the object. */
00527                 if (!type -> lookup) {
00528                         return omapi_protocol_send_status
00529                                 (po, message -> id_object,
00530                                  ISC_R_NOTIMPLEMENTED, message -> id,
00531                                  "unsearchable object type");
00532                 }
00533 
00534                 status = (*(type -> lookup)) (&object, message -> id_object,
00535                                               message -> object);
00536 
00537                 if (status != ISC_R_SUCCESS &&
00538                     status != ISC_R_NOTFOUND &&
00539                     status != DHCP_R_NOKEYS) {
00540                         return omapi_protocol_send_status
00541                                 (po, message -> id_object,
00542                                  status, message -> id,
00543                                  "object lookup failed");
00544                 }
00545 
00546                 /* If we didn't find the object and we aren't supposed to
00547                    create it, return an error. */
00548                 if (status == ISC_R_NOTFOUND && !create) {
00549                         return omapi_protocol_send_status
00550                                 (po, message -> id_object,
00551                                  ISC_R_NOTFOUND, message -> id,
00552                                  "no object matches specification");
00553                 }                       
00554 
00555                 /* If we found an object, we're supposed to be creating an
00556                    object, and we're not supposed to have found an object,
00557                    return an error. */
00558                 if (status == ISC_R_SUCCESS && create && exclusive) {
00559                         omapi_object_dereference (&object, MDL);
00560                         return omapi_protocol_send_status
00561                                 (po, message -> id_object,
00562                                  ISC_R_EXISTS, message -> id,
00563                                  "specified object already exists");
00564                 }
00565 
00566                 /* If we're creating the object, do it now. */
00567                 if (!object) {
00568                         status = omapi_object_create (&object,
00569                                                       message -> id_object,
00570                                                       type);
00571                         if (status != ISC_R_SUCCESS) {
00572                                 return omapi_protocol_send_status
00573                                         (po, message -> id_object,
00574                                          status, message -> id,
00575                                          "can't create new object");
00576                         }
00577                 }
00578 
00579                 /* If we're updating it, do so now. */
00580                 if (create || update) {
00581                         /* This check does not belong here. */
00582                         if (object -> type == omapi_type_auth_key) {
00583                                 omapi_object_dereference (&object, MDL);
00584                                 return omapi_protocol_send_status
00585                                         (po, message -> id_object,
00586                                          status, message -> id,
00587                                          "can't update object");
00588                         }
00589 
00590                         status = omapi_object_update (object,
00591                                                       message -> id_object,
00592                                                       message -> object,
00593                                                       message -> h);
00594                         if (status != ISC_R_SUCCESS) {
00595                                 omapi_object_dereference (&object, MDL);
00596                                 return omapi_protocol_send_status
00597                                         (po, message -> id_object,
00598                                          status, message -> id,
00599                                          "can't update object");
00600                         }
00601                 }
00602 
00603                 /* If this is an authenticator object, add it to the active
00604                    set for the connection. */
00605                 if (object -> type == omapi_type_auth_key) {
00606                         omapi_handle_t handle;
00607                         status = omapi_object_handle (&handle, object);
00608                         if (status != ISC_R_SUCCESS) {
00609                                 omapi_object_dereference (&object, MDL);
00610                                 return omapi_protocol_send_status
00611                                         (po, message -> id_object,
00612                                          status, message -> id,
00613                                          "can't select authenticator");
00614                         }
00615 
00616                         status = omapi_protocol_add_auth (po, object, handle);
00617                         if (status != ISC_R_SUCCESS) {
00618                                 omapi_object_dereference (&object, MDL);
00619                                 return omapi_protocol_send_status
00620                                         (po, message -> id_object,
00621                                          status, message -> id,
00622                                          "can't select authenticator");
00623                         }
00624                 }
00625                 
00626                 /* Now send the new contents of the object back in
00627                    response. */
00628                 goto send;
00629 
00630               case OMAPI_OP_REFRESH:
00631               refresh:
00632                 status = omapi_handle_lookup (&object, message -> h);
00633                 if (status != ISC_R_SUCCESS) {
00634                         return omapi_protocol_send_status
00635                                 (po, message -> id_object,
00636                                  status, message -> id,
00637                                  "no matching handle");
00638                 }
00639               send:             
00640                 status = omapi_protocol_send_update (po, message -> id_object,
00641                                                      message -> id, object);
00642                 omapi_object_dereference (&object, MDL);
00643                 return status;
00644 
00645               case OMAPI_OP_UPDATE:
00646                 if (m && m -> object) {
00647                         status = omapi_object_reference (&object, m -> object,
00648                                                                         MDL);
00649                 } else {
00650                         status = omapi_handle_lookup (&object, message -> h);
00651                         if (status != ISC_R_SUCCESS) {
00652                                 return omapi_protocol_send_status
00653                                         (po, message -> id_object,
00654                                          status, message -> id,
00655                                          "no matching handle");
00656                         }
00657                 }
00658 
00659                 if (object -> type == omapi_type_auth_key ||
00660                     (object -> inner &&
00661                      object -> inner -> type == omapi_type_auth_key)) {
00662                         if (!m) {
00663                                 omapi_object_dereference (&object, MDL);
00664                                 return omapi_protocol_send_status
00665                                         (po, message -> id_object,
00666                                          status, message -> id,
00667                                          "cannot update authenticator");
00668                         }
00669                         
00670                         status = omapi_protocol_add_auth (po, object,
00671                                                           message -> h);
00672                 } else {
00673                         status = omapi_object_update (object,
00674                                                       message -> id_object,
00675                                                       message -> object,
00676                                                       message -> h);
00677                 }
00678                 if (status != ISC_R_SUCCESS) {
00679                         omapi_object_dereference (&object, MDL);
00680                         if (!message -> rid)
00681                                 return omapi_protocol_send_status
00682                                         (po, message -> id_object,
00683                                          status, message -> id,
00684                                          "can't update object");
00685                         if (m)
00686                                 omapi_signal ((omapi_object_t *)m,
00687                                               "status", status,
00688                                               (omapi_typed_data_t *)0);
00689                         return ISC_R_SUCCESS;
00690                 }
00691                 if (!message -> rid)
00692                         status = omapi_protocol_send_status
00693                                 (po, message -> id_object, ISC_R_SUCCESS,
00694                                  message -> id, (char *)0);
00695                 if (m) {
00696                         omapi_signal ((omapi_object_t *)m,
00697                                       "status", ISC_R_SUCCESS,
00698                                       (omapi_typed_data_t *)0);
00699                         omapi_message_unregister ((omapi_object_t *)m);
00700                 }
00701 
00702                 omapi_object_dereference (&object, MDL);
00703 
00704                 return status;
00705 
00706               case OMAPI_OP_NOTIFY:
00707                 return omapi_protocol_send_status
00708                         (po, message -> id_object, ISC_R_NOTIMPLEMENTED,
00709                          message -> id, "notify not implemented yet");
00710 
00711               case OMAPI_OP_STATUS:
00712                 /* The return status of a request. */
00713                 if (!m)
00714                         return ISC_R_UNEXPECTED;
00715 
00716                 /* Get the wait status. */
00717                 status = omapi_get_value_str (mo, message -> id_object,
00718                                               "result", &tv);
00719                 if (status == ISC_R_SUCCESS) {
00720                         status = omapi_get_int_value (&wsi, tv -> value);
00721                         waitstatus = wsi;
00722                         omapi_value_dereference (&tv, MDL);
00723                         if (status != ISC_R_SUCCESS)
00724                                 waitstatus = ISC_R_UNEXPECTED;
00725                 } else
00726                         waitstatus = ISC_R_UNEXPECTED;
00727 
00728                 status = omapi_get_value_str (mo, message -> id_object,
00729                                               "message", &tv);
00730                 omapi_signal ((omapi_object_t *)m, "status", waitstatus, tv);
00731                 if (status == ISC_R_SUCCESS)
00732                         omapi_value_dereference (&tv, MDL);
00733 
00734                 omapi_message_unregister((omapi_object_t *)m);
00735 
00736                 return ISC_R_SUCCESS;
00737 
00738               case OMAPI_OP_DELETE:
00739                 status = omapi_handle_lookup (&object, message -> h);
00740                 if (status != ISC_R_SUCCESS) {
00741                         return omapi_protocol_send_status
00742                                 (po, message -> id_object,
00743                                  status, message -> id,
00744                                  "no matching handle");
00745                 }
00746 
00747                 if (!object -> type -> remove)
00748                         return omapi_protocol_send_status
00749                                 (po, message -> id_object,
00750                                  ISC_R_NOTIMPLEMENTED, message -> id,
00751                                  "no remove method for object");
00752 
00753                 status = (*(object -> type -> remove)) (object,
00754                                                         message -> id_object);
00755                 omapi_object_dereference (&object, MDL);
00756 
00757                 return omapi_protocol_send_status (po, message -> id_object,
00758                                                    status, message -> id,
00759                                                    (char *)0);
00760         }
00761         return ISC_R_NOTIMPLEMENTED;
00762 }

Generated on 5 Apr 2014 for ISC DHCP by  doxygen 1.6.1