isc_result_t omapi_protocol_send_open (omapi_object_t *po,
				       omapi_object_t *id,
				       const char *type,
				       omapi_object_t *object,
				       unsigned flags)
{
	isc_result_t status;
	omapi_message_object_t *message = (omapi_message_object_t *)0;
	omapi_object_t *mo;

	if (po -> type != omapi_type_protocol)
		return ISC_R_INVALIDARG;

	status = omapi_message_new ((omapi_object_t **)&message, MDL);
	mo = (omapi_object_t *)message;

	if (status == ISC_R_SUCCESS)
		status = omapi_set_int_value (mo, (omapi_object_t *)0,
					      "op", OMAPI_OP_OPEN);

	if (status == ISC_R_SUCCESS)
		status = omapi_set_object_value (mo, (omapi_object_t *)0,
						 "object", object);

	if ((flags & OMAPI_CREATE) && (status == ISC_R_SUCCESS))
		status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
						  "create", 1);

	if ((flags & OMAPI_UPDATE) && (status == ISC_R_SUCCESS))
		status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
						  "update", 1);

	if ((flags & OMAPI_EXCL) && (status == ISC_R_SUCCESS))
		status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
						  "exclusive", 1);

	if ((flags & OMAPI_NOTIFY_PROTOCOL) && (status == ISC_R_SUCCESS))
		status = omapi_set_object_value (mo, (omapi_object_t *)0,
						 "notify-object", po);

	if (type && (status == ISC_R_SUCCESS))
		status = omapi_set_string_value (mo, (omapi_object_t *)0,
						 "type", type);

	if (status == ISC_R_SUCCESS)
		status = omapi_message_register (mo);

	if (status == ISC_R_SUCCESS) {
		status = omapi_protocol_send_message (po, id, mo,
						      (omapi_object_t *)0);
		if (status != ISC_R_SUCCESS)
			omapi_message_unregister (mo);
	}

	if (message)
		omapi_message_dereference (&message, MDL);

	return status;
}
Beispiel #2
0
isc_result_t omapi_message_destroy (omapi_object_t *h,
				    const char *file, int line)
{
	omapi_message_object_t *m;
	if (h -> type != omapi_type_message)
		return DHCP_R_INVALIDARG;
	m = (omapi_message_object_t *)h;
	if (m -> authenticator) {
		omapi_typed_data_dereference (&m -> authenticator, file, line);
	}
	if (!m -> prev && omapi_registered_messages != m)
		omapi_message_unregister (h);
	if (m -> id_object)
		omapi_object_dereference (&m -> id_object, file, line);
	if (m -> object)
		omapi_object_dereference (&m -> object, file, line);
	if (m -> notify_object)
		omapi_object_dereference (&m -> notify_object, file, line);
	if (m -> protocol_object)
		omapi_protocol_dereference (&m -> protocol_object, file, line);
	return ISC_R_SUCCESS;
}
Beispiel #3
0
dhcpctl_status dhcpctl_open_object (dhcpctl_handle h,
				    dhcpctl_handle connection,
				    int flags)
{
	isc_result_t status;
	omapi_object_t *message = (omapi_object_t *)0;
	dhcpctl_remote_object_t *remote;

	if (h -> type != dhcpctl_remote_type)
		return DHCP_R_INVALIDARG;
	remote = (dhcpctl_remote_object_t *)h;

	status = omapi_message_new (&message, MDL);
	if (status != ISC_R_SUCCESS)
		return status;
	status = omapi_set_int_value (message, (omapi_object_t *)0,
				      "op", OMAPI_OP_OPEN);
	if (status != ISC_R_SUCCESS) {
		omapi_object_dereference (&message, MDL);
		return status;
	}
	status = omapi_set_object_value (message, (omapi_object_t *)0,
					 "object", h);
	if (status != ISC_R_SUCCESS) {
		omapi_object_dereference (&message, MDL);
		return status;
	}
	if (flags & DHCPCTL_CREATE) {
		status = omapi_set_boolean_value (message, (omapi_object_t *)0,
						  "create", 1);
		if (status != ISC_R_SUCCESS) {
			omapi_object_dereference (&message, MDL);
			return status;
		}
	}
	if (flags & DHCPCTL_UPDATE) {
		status = omapi_set_boolean_value (message, (omapi_object_t *)0,
						  "update", 1);
		if (status != ISC_R_SUCCESS) {
			omapi_object_dereference (&message, MDL);
			return status;
		}
	}
	if (flags & DHCPCTL_EXCL) {
		status = omapi_set_boolean_value (message, (omapi_object_t *)0,
						  "exclusive", 1);
		if (status != ISC_R_SUCCESS) {
			omapi_object_dereference (&message, MDL);
			return status;
		}
	}

	if (remote -> rtype) {
		status = omapi_set_value_str (message, (omapi_object_t *)0,
					      "type", remote -> rtype);
		if (status != ISC_R_SUCCESS) {
			omapi_object_dereference (&message, MDL);
			return status;
		}
	}

	status = omapi_message_register (message);
	if (status != ISC_R_SUCCESS) {
		omapi_object_dereference (&message, MDL);
		return status;
	}

	status = omapi_protocol_send_message (connection -> outer,
					    (omapi_object_t *)0,
					    message, (omapi_object_t *)0);

	if (status != ISC_R_SUCCESS)
		omapi_message_unregister (message);

	omapi_object_dereference (&message, MDL);
	return status;
}
Beispiel #4
0
static isc_result_t
omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po)
{
	omapi_message_object_t *message, *m;
	omapi_object_t *object = (omapi_object_t *)0;
	omapi_value_t *tv = (omapi_value_t *)0;
	unsigned long create, update, exclusive;
	unsigned long wsi;
	isc_result_t status, waitstatus;
	omapi_object_type_t *type;

	if (mo -> type != omapi_type_message)
		return DHCP_R_INVALIDARG;
	message = (omapi_message_object_t *)mo;

#ifdef DEBUG_PROTOCOL
	log_debug ("omapi_message_process(): "
		   "op=%s  handle=%#x  id=%#x  rid=%#x",
		   omapi_message_op_name (message -> op),
		   message -> h, message -> id, message -> rid);
#endif

	if (message -> rid) {
		for (m = omapi_registered_messages; m; m = m -> next)
			if (m -> id == message -> rid)
				break;
		/* If we don't have a real message corresponding to
		   the message ID to which this message claims it is a
		   response, something's fishy. */
		if (!m)
			return ISC_R_NOTFOUND;
		/* The authenticator on responses must match the initial
		   message. */
		if (message -> authid != m -> authid)
			return ISC_R_NOTFOUND;
	} else {
		m = (omapi_message_object_t *)0;

		/* All messages must have an authenticator, with the exception
		   of messages that are opening a new authenticator. */
		if (omapi_protocol_authenticated(po) &&
		    !message->id_object &&
		    message->op != OMAPI_OP_OPEN) {
			return omapi_protocol_send_status
				(po, message->id_object, DHCP_R_NOKEYS,
				 message->id, "No authenticator on message");
		}
	}

	switch (message -> op) {
	      case OMAPI_OP_OPEN:
		if (m) {
			return omapi_protocol_send_status
				(po, message->id_object, DHCP_R_INVALIDARG,
				 message->id, "OPEN can't be a response");
		}

		/* Get the type of the requested object, if one was
		   specified. */
		status = omapi_get_value_str (mo, message -> id_object,
					      "type", &tv);
		if (status == ISC_R_SUCCESS &&
		    (tv -> value -> type == omapi_datatype_data ||
		     tv -> value -> type == omapi_datatype_string)) {
			for (type = omapi_object_types;
			     type; type = type -> next)
				if (!omapi_td_strcmp (tv -> value,
						      type -> name))
					break;
		} else
			type = (omapi_object_type_t *)0;
		if (tv)
			omapi_value_dereference (&tv, MDL);

		/* If this object had no authenticator, the requested object
		   must be an authenticator object. */
		if (omapi_protocol_authenticated(po) &&
		    !message->id_object &&
		    type != omapi_type_auth_key) {
			return omapi_protocol_send_status
				(po, message->id_object, DHCP_R_NOKEYS,
				 message->id, "No authenticator on message");
		}

		/* Get the create flag. */
		status = omapi_get_value_str (mo, message -> id_object,
					      "create", &tv);
		if (status == ISC_R_SUCCESS) {
			status = omapi_get_int_value (&create, tv -> value);
			omapi_value_dereference (&tv, MDL);
			if (status != ISC_R_SUCCESS) {
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "invalid create flag value");
			}
		} else
			create = 0;

		/* Get the update flag. */
		status = omapi_get_value_str (mo, message -> id_object,
					      "update", &tv);
		if (status == ISC_R_SUCCESS) {
			status = omapi_get_int_value (&update, tv -> value);
			omapi_value_dereference (&tv, MDL);
			if (status != ISC_R_SUCCESS) {
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "invalid update flag value");
			}
		} else
			update = 0;

		/* Get the exclusive flag. */
		status = omapi_get_value_str (mo, message -> id_object,
					      "exclusive", &tv);
		if (status == ISC_R_SUCCESS) {
			status = omapi_get_int_value (&exclusive, tv -> value);
			omapi_value_dereference (&tv, MDL);
			if (status != ISC_R_SUCCESS) {
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "invalid exclusive flag value");
			}
		} else
			exclusive = 0;

		/* If we weren't given a type, look the object up with
                   the handle. */
		if (!type) {
			if (create) {
				return omapi_protocol_send_status
					(po, message->id_object,
					 DHCP_R_INVALIDARG,
					 message->id,
					 "type required on create");
			}
			goto refresh;
		}

		/* If the type doesn't provide a lookup method, we can't
		   look up the object. */
		if (!type -> lookup) {
			return omapi_protocol_send_status
				(po, message -> id_object,
				 ISC_R_NOTIMPLEMENTED, message -> id,
				 "unsearchable object type");
		}

		status = (*(type -> lookup)) (&object, message -> id_object,
					      message -> object);

		if (status != ISC_R_SUCCESS &&
		    status != ISC_R_NOTFOUND &&
		    status != DHCP_R_NOKEYS) {
			return omapi_protocol_send_status
				(po, message -> id_object,
				 status, message -> id,
				 "object lookup failed");
		}

		/* If we didn't find the object and we aren't supposed to
		   create it, return an error. */
		if (status == ISC_R_NOTFOUND && !create) {
			return omapi_protocol_send_status
				(po, message -> id_object,
				 ISC_R_NOTFOUND, message -> id,
				 "no object matches specification");
		}			

		/* If we found an object, we're supposed to be creating an
		   object, and we're not supposed to have found an object,
		   return an error. */
		if (status == ISC_R_SUCCESS && create && exclusive) {
			omapi_object_dereference (&object, MDL);
			return omapi_protocol_send_status
				(po, message -> id_object,
				 ISC_R_EXISTS, message -> id,
				 "specified object already exists");
		}

		/* If we're creating the object, do it now. */
		if (!object) {
			status = omapi_object_create (&object,
						      message -> id_object,
						      type);
			if (status != ISC_R_SUCCESS) {
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "can't create new object");
			}
		}

		/* If we're updating it, do so now. */
		if (create || update) {
			/* This check does not belong here. */
			if (object -> type == omapi_type_auth_key) {
				omapi_object_dereference (&object, MDL);
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "can't update object");
			}

			status = omapi_object_update (object,
						      message -> id_object,
						      message -> object,
						      message -> h);
			if (status != ISC_R_SUCCESS) {
				omapi_object_dereference (&object, MDL);
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "can't update object");
			}
		}

		/* If this is an authenticator object, add it to the active
		   set for the connection. */
		if (object -> type == omapi_type_auth_key) {
			omapi_handle_t handle;
			status = omapi_object_handle (&handle, object);
			if (status != ISC_R_SUCCESS) {
				omapi_object_dereference (&object, MDL);
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "can't select authenticator");
			}

			status = omapi_protocol_add_auth (po, object, handle);
			if (status != ISC_R_SUCCESS) {
				omapi_object_dereference (&object, MDL);
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "can't select authenticator");
			}
		}
		
		/* Now send the new contents of the object back in
		   response. */
		goto send;

	      case OMAPI_OP_REFRESH:
	      refresh:
		status = omapi_handle_lookup (&object, message -> h);
		if (status != ISC_R_SUCCESS) {
			return omapi_protocol_send_status
				(po, message -> id_object,
				 status, message -> id,
				 "no matching handle");
		}
	      send:		
		status = omapi_protocol_send_update (po, message -> id_object,
						     message -> id, object);
		omapi_object_dereference (&object, MDL);
		return status;

	      case OMAPI_OP_UPDATE:
		if (m && m -> object) {
			status = omapi_object_reference (&object, m -> object,
									MDL);
		} else {
			status = omapi_handle_lookup (&object, message -> h);
			if (status != ISC_R_SUCCESS) {
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "no matching handle");
			}
		}

		if (object -> type == omapi_type_auth_key ||
		    (object -> inner &&
		     object -> inner -> type == omapi_type_auth_key)) {
			if (!m) {
				omapi_object_dereference (&object, MDL);
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "cannot update authenticator");
			}
			
			status = omapi_protocol_add_auth (po, object,
							  message -> h);
		} else {
			status = omapi_object_update (object,
						      message -> id_object,
						      message -> object,
						      message -> h);
		}
		if (status != ISC_R_SUCCESS) {
			omapi_object_dereference (&object, MDL);
			if (!message -> rid)
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "can't update object");
			if (m)
				omapi_signal ((omapi_object_t *)m,
					      "status", status,
					      (omapi_typed_data_t *)0);
			return ISC_R_SUCCESS;
		}
		if (!message -> rid)
			status = omapi_protocol_send_status
				(po, message -> id_object, ISC_R_SUCCESS,
				 message -> id, (char *)0);
		if (m) {
			omapi_signal ((omapi_object_t *)m,
				      "status", ISC_R_SUCCESS,
				      (omapi_typed_data_t *)0);
			omapi_message_unregister ((omapi_object_t *)m);
		}

		omapi_object_dereference (&object, MDL);

		return status;

	      case OMAPI_OP_NOTIFY:
		return omapi_protocol_send_status
			(po, message -> id_object, ISC_R_NOTIMPLEMENTED,
			 message -> id, "notify not implemented yet");

	      case OMAPI_OP_STATUS:
		/* The return status of a request. */
		if (!m)
			return ISC_R_UNEXPECTED;

		/* Get the wait status. */
		status = omapi_get_value_str (mo, message -> id_object,
					      "result", &tv);
		if (status == ISC_R_SUCCESS) {
			status = omapi_get_int_value (&wsi, tv -> value);
			waitstatus = wsi;
			omapi_value_dereference (&tv, MDL);
			if (status != ISC_R_SUCCESS)
				waitstatus = ISC_R_UNEXPECTED;
		} else
			waitstatus = ISC_R_UNEXPECTED;

		status = omapi_get_value_str (mo, message -> id_object,
					      "message", &tv);
		omapi_signal ((omapi_object_t *)m, "status", waitstatus, tv);
		if (status == ISC_R_SUCCESS)
			omapi_value_dereference (&tv, MDL);

		omapi_message_unregister((omapi_object_t *)m);

		return ISC_R_SUCCESS;

	      case OMAPI_OP_DELETE:
		status = omapi_handle_lookup (&object, message -> h);
		if (status != ISC_R_SUCCESS) {
			return omapi_protocol_send_status
				(po, message -> id_object,
				 status, message -> id,
				 "no matching handle");
		}

		if (!object -> type -> remove)
			return omapi_protocol_send_status
				(po, message -> id_object,
				 ISC_R_NOTIMPLEMENTED, message -> id,
				 "no remove method for object");

		status = (*(object -> type -> remove)) (object,
							message -> id_object);
		omapi_object_dereference (&object, MDL);

		return omapi_protocol_send_status (po, message -> id_object,
						   status, message -> id,
						   (char *)0);
	}
	return ISC_R_NOTIMPLEMENTED;
}