Exemple #1
0
static void proxy_write_reply(const DBusError *derr, void *user_data)
{
	struct proxy_write_data *wdata = user_data;
	int err;

	/*
	 * Security requirements shall be handled by the core. If external
	 * applications returns an error, the reasons will be restricted to
	 * invalid argument or application specific errors.
	 */

	if (!dbus_error_is_set(derr)) {
		err = 0;
		goto done;
	}

	DBG("Write reply: %s", derr->message);

	if (dbus_error_has_name(derr, DBUS_ERROR_NO_REPLY))
		err = -ETIMEDOUT;
	else if (dbus_error_has_name(derr, ERROR_INTERFACE ".InvalidArguments"))
		err = -EINVAL;
	else
		err = -EPROTO;

done:
	if (wdata && wdata->result_cb)
		wdata->result_cb(err, wdata->user_data);
}
Exemple #2
0
static dbus_bool_t
handle_reload_watch (DBusWatch    *watch,
		     unsigned int  flags,
		     void         *data)
{
  DBusError error;
  DBusString str;
  _dbus_string_init (&str);
  if ((reload_pipe[RELOAD_READ_END] > 0) &&
      _dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1)
    {
      _dbus_warn ("Couldn't read from reload pipe.\n");
      close_reload_pipe ();
      return TRUE;
    }
  _dbus_string_free (&str);

  /* this can only fail if we don't understand the config file
   * or OOM.  Either way we should just stick with the currently
   * loaded config.
   */
  dbus_error_init (&error);
  if (! bus_context_reload_config (context, &error))
    {
      _DBUS_ASSERT_ERROR_IS_SET (&error);
      _dbus_assert (dbus_error_has_name (&error, DBUS_ERROR_FAILED) ||
		    dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY));
      _dbus_warn ("Unable to reload configuration: %s\n",
		  error.message);
      dbus_error_free (&error);
    }
  return TRUE;
}
static dbus_bool_t
check_spawn_exit (void *data)
{
  char *argv[4] = { NULL, NULL, NULL, NULL };
  DBusBabysitter *sitter;
  DBusError error;
  
  sitter = NULL;
  
  dbus_error_init (&error);

  /*** Test launching exit failure binary */
  
  argv[0] = TEST_EXIT_BINARY;
  if (_dbus_spawn_async_with_babysitter (&sitter, argv,
                                         NULL, NULL,
                                         &error))
    {
    #ifdef __SYMBIAN32__
    if(sitter)
    {
    #endif
      _dbus_babysitter_block_for_child_exit (sitter);
      _dbus_babysitter_set_child_exit_error (sitter, &error);
      
    #ifdef __SYMBIAN32__
    }
    #endif
      /* no baby sitter support in Symbian */
    }

  if (sitter)
    _dbus_babysitter_unref (sitter);

  if (!dbus_error_is_set (&error))
    {
      _dbus_warn ("Did not get an error launching binary that exited with failure code\n");
      return FALSE;
    }

  if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
        dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
    {
      _dbus_warn ("Not expecting error when launching exiting executable: %s: %s\n",
                  error.name, error.message);
      dbus_error_free (&error);
      return FALSE;
    }

  dbus_error_free (&error);
  
  return TRUE;
}
Exemple #4
0
static dbus_bool_t
check_spawn_and_kill (void *data)
{
  char *argv[4] = { NULL, NULL, NULL, NULL };
  DBusBabysitter *sitter = NULL;
  DBusError error = DBUS_ERROR_INIT;
  DBusString argv0;

  /*** Test launching sleeping binary then killing it */

  argv[0] = get_test_exec ("test-sleep-forever", &argv0);

  if (argv[0] == NULL)
    {
      /* OOM was simulated, never mind */
      return TRUE;
    }

  if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_and_kill", argv,
                                         NULL, NULL, NULL,
                                         &error))
    {
      _dbus_babysitter_kill_child (sitter);
      
      _dbus_babysitter_block_for_child_exit (sitter);
      
      _dbus_babysitter_set_child_exit_error (sitter, &error);
    }

  _dbus_string_free (&argv0);

  if (sitter)
    _dbus_babysitter_unref (sitter);

  if (!dbus_error_is_set (&error))
    {
      _dbus_warn ("Did not get an error after killing spawned binary\n");
      return FALSE;
    }

  if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
        dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
    {
      _dbus_warn ("Not expecting error when killing executable: %s: %s\n",
                  error.name, error.message);
      dbus_error_free (&error);
      return FALSE;
    }

  dbus_error_free (&error);
  
  return TRUE;
}
Exemple #5
0
static void simple_agent_reply(DBusPendingCall *call, void *user_data)
{
	struct agent_request *req = user_data;
	struct agent *agent = req->agent;
	DBusMessage *message;
	DBusError err;
	agent_cb cb = req->cb;

	/* steal_reply will always return non-NULL since the callback
	 * is only called after a reply has been received */
	message = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, message)) {
		error("Agent replied with an error: %s, %s",
				err.name, err.message);

		cb(agent, &err, req->user_data);

		if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) {
			agent_cancel(agent);
			dbus_message_unref(message);
			dbus_error_free(&err);
			return;
		}
// +s LGBT_COMMON_TEMPORARY [email protected] 120829
		if (dbus_error_has_name(&err, "org.bluez.Error.Canceled")) {
			DBG("User cancel the pairing");
			DBG("->device_set_temporary");
			device_set_temporary(((struct authentication_req*) req->user_data)->device, TRUE);
		}
// +e LGBT_COMMON_TEMPORARY	
		dbus_error_free(&err);
		goto done;
	}

	dbus_error_init(&err);
	if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) {
		error("Wrong reply signature: %s", err.message);
		cb(agent, &err, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

	cb(agent, NULL, req->user_data);
done:
	dbus_message_unref(message);

	agent->request = NULL;
	agent_request_free(req, TRUE);
}
Exemple #6
0
static void remove_connection_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError error;

	if (dbus_pending_call_get_completed(call) == FALSE)
		return;

	DBG("");

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == TRUE) {
		/*
		 * If the returned error is NotFound, it means that we
		 * have actually removed the provider in vpnd already.
		 */
		if (dbus_error_has_name(&error, CONNMAN_ERROR_INTERFACE
						".NotFound") == FALSE)
			connman_error("%s", error.message);

		dbus_error_free(&error);
	}

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}
Exemple #7
0
/* returns true if good things happen, or if we get OOM */
static dbus_bool_t
bus_activation_helper_oom_test (void        *data,
                                dbus_bool_t  have_memory)
{
  const char *service;
  DBusError error;
  dbus_bool_t retval;

  service = (const char *) data;
  retval = TRUE;

  dbus_error_init (&error);

  if (!run_launch_helper (service, &error))
    {
      _DBUS_ASSERT_ERROR_IS_SET (&error);
      /* we failed, but a OOM is good */
      if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
        {
          _dbus_warn ("FAILED SELF TEST: Error: %s", error.message);
          retval = FALSE;
        }
      dbus_error_free (&error);
    }
  else
    {
      /* we succeeded, yay! */
      _DBUS_ASSERT_ERROR_IS_CLEAR (&error);
    }
  return retval;
}
Exemple #8
0
/**
 * Reads (and optionally writes) a uuid to a file. Initializes the uuid
 * unless an error is returned.
 *
 * @param filename the name of the file
 * @param uuid uuid to be initialized with the loaded uuid
 * @param create_if_not_found #TRUE to create a new uuid and save it if the file doesn't exist
 * @param error the error return
 * @returns #FALSE if the error is set
 */
dbus_bool_t
_dbus_read_uuid_file (const DBusString *filename,
                      DBusGUID         *uuid,
                      dbus_bool_t       create_if_not_found,
                      DBusError        *error)
{
  DBusError read_error = DBUS_ERROR_INIT;

  if (_dbus_read_uuid_file_without_creating (filename, uuid, &read_error))
    return TRUE;

  if (!create_if_not_found)
    {
      dbus_move_error (&read_error, error);
      return FALSE;
    }

  /* If the file exists and contains junk, we want to keep that error
   * message instead of overwriting it with a "file exists" error
   * message when we try to write
   */
  if (dbus_error_has_name (&read_error, DBUS_ERROR_INVALID_FILE_CONTENT))
    {
      dbus_move_error (&read_error, error);
      return FALSE;
    }
  else
    {
      dbus_error_free (&read_error);
      return _dbus_create_uuid_file_exclusively (filename, uuid, error);
    }
}
gboolean
gkr_operation_handle_errors (GkrOperation *op, DBusMessage *reply)
{
	DBusError derr = DBUS_ERROR_INIT;
	MateKeyringResult res;
	gboolean was_keyring;

	g_assert (op);
	g_assert (reply);

	was_keyring = op->was_keyring;
	op->was_keyring = FALSE;

	if (dbus_set_error_from_message (&derr, reply)) {
		if (dbus_error_has_name (&derr, ERROR_NO_SUCH_OBJECT)) {
			if (was_keyring)
				res = MATE_KEYRING_RESULT_NO_SUCH_KEYRING;
			else
				res = MATE_KEYRING_RESULT_BAD_ARGUMENTS;
		} else {
			g_message ("secret service operation failed: %s", derr.message);
			res = MATE_KEYRING_RESULT_IO_ERROR;
		}

		dbus_error_free (&derr);
		gkr_operation_complete (op, res);
		return TRUE;
	}

	return FALSE;
}
/**
 * thunar_dbus_client_terminate:
 * @error : Return location for errors or %NULL.
 *
 * Tells a running Thunar instance, connected to the D-BUS
 * session bus, to terminate immediately.
 *
 * Return value: %TRUE if any instance was terminated, else
 *               %FALSE and @error is set.
 **/
gboolean
thunar_dbus_client_terminate (GError **error)
{
  DBusConnection *connection;
  DBusMessage    *message;
  DBusMessage    *result;
  DBusError       derror;

  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  /* initialize the DBusError struct */
  dbus_error_init (&derror);

  /* try to connect to the session bus */
  connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
  if (G_UNLIKELY (connection == NULL))
    {
      dbus_set_g_error (error, &derror);
      dbus_error_free (&derror);
      return FALSE;
    }

  /* generate the LaunchFiles() method (disable activation!) */
  message = dbus_message_new_method_call ("org.xfce.Thunar", "/org/xfce/FileManager", "org.xfce.Thunar", "Terminate");
  dbus_message_set_auto_start (message, FALSE);

  /* send the message and release our references on connection and message */
  result = dbus_connection_send_with_reply_and_block (connection, message, -1, &derror);
  dbus_message_unref (message);

  /* check if no reply was received */
  if (G_UNLIKELY (result == NULL))
    {
      /* check if there was nothing to terminate */
      if (dbus_error_has_name (&derror, DBUS_ERROR_NAME_HAS_NO_OWNER))
        {
          dbus_error_free (&derror);
          return TRUE;
        }

      /* Looks like there was a real error */
      dbus_set_g_error (error, &derror);
      dbus_error_free (&derror);
      return FALSE;
    }

  /* but maybe we received an error */
  if (dbus_message_get_type (result) == DBUS_MESSAGE_TYPE_ERROR)
    {
      dbus_set_error_from_message (&derror, result);
      dbus_set_g_error (error, &derror);
      dbus_message_unref (result);
      dbus_error_free (&derror);
      return FALSE;
    }

  /* let's asume that it worked */
  dbus_message_unref (result);
  return TRUE;
}
Exemple #11
0
static dbus_bool_t
check_spawn_and_kill (void *data)
{
  char *argv[4] = { NULL, NULL, NULL, NULL };
  DBusBabysitter *sitter;
  DBusError error;

  sitter = NULL;

  dbus_error_init (&error);

  /*** Test launching sleeping binary then killing it */

  argv[0] = TEST_SLEEP_FOREVER_BINARY;
  if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL,
                                         NULL, NULL,
                                         &error))
    {
      _dbus_babysitter_kill_child (sitter);

      _dbus_babysitter_block_for_child_exit (sitter);

      _dbus_babysitter_set_child_exit_error (sitter, &error);
    }

  if (sitter)
    _dbus_babysitter_unref (sitter);

  if (!dbus_error_is_set (&error))
    {
      _dbus_warn ("Did not get an error after killing spawned binary\n");
      return FALSE;
    }

  if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
        dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
    {
      _dbus_warn ("Not expecting error when killing executable: %s: %s\n",
                  error.name, error.message);
      dbus_error_free (&error);
      return FALSE;
    }

  dbus_error_free (&error);

  return TRUE;
}
Exemple #12
0
static dbus_bool_t
become_monitor (DBusConnection *connection,
    int numFilters,
    const char * const *filters)
{
  DBusError error = DBUS_ERROR_INIT;
  DBusMessage *m;
  DBusMessage *r;
  int i;
  dbus_uint32_t zero = 0;
  DBusMessageIter appender, array_appender;

  m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
      DBUS_PATH_DBUS, DBUS_INTERFACE_MONITORING, "BecomeMonitor");

  if (m == NULL)
    tool_oom ("becoming a monitor");

  dbus_message_iter_init_append (m, &appender);

  if (!dbus_message_iter_open_container (&appender, DBUS_TYPE_ARRAY, "s",
        &array_appender))
    tool_oom ("opening string array");

  for (i = 0; i < numFilters; i++)
    {
      if (!dbus_message_iter_append_basic (&array_appender, DBUS_TYPE_STRING,
            &filters[i]))
        tool_oom ("adding filter to array");
    }

  if (!dbus_message_iter_close_container (&appender, &array_appender) ||
      !dbus_message_iter_append_basic (&appender, DBUS_TYPE_UINT32, &zero))
    tool_oom ("finishing arguments");

  r = dbus_connection_send_with_reply_and_block (connection, m, -1, &error);

  if (r != NULL)
    {
      dbus_message_unref (r);
    }
  else if (dbus_error_has_name (&error, DBUS_ERROR_UNKNOWN_INTERFACE))
    {
      fprintf (stderr, "dbus-monitor: unable to enable new-style monitoring, "
          "your dbus-daemon is too old. Falling back to eavesdropping.\n");
      dbus_error_free (&error);
    }
  else
    {
      fprintf (stderr, "dbus-monitor: unable to enable new-style monitoring: "
          "%s: \"%s\". Falling back to eavesdropping.\n",
          error.name, error.message);
      dbus_error_free (&error);
    }

  dbus_message_unref (m);

  return (r != NULL);
}
Exemple #13
0
static void start_target(const char *target) {
        DBusMessage *m = NULL, *reply = NULL;
        DBusError error;
        const char *mode = "replace", *basic_target = "basic.target";
        DBusConnection *bus = NULL;

        assert(target);

        dbus_error_init(&error);

        if (bus_connect(DBUS_BUS_SYSTEM, &bus, NULL, &error) < 0) {
                log_error("Failed to get D-Bus connection: %s", bus_error_message(&error));
                goto finish;
        }

        log_info("Running request %s/start/%s", target, mode);

        if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnitReplace"))) {
                log_error("Could not allocate message.");
                goto finish;
        }

        /* Start these units only if we can replace base.target with it */

        if (!dbus_message_append_args(m,
                                      DBUS_TYPE_STRING, &basic_target,
                                      DBUS_TYPE_STRING, &target,
                                      DBUS_TYPE_STRING, &mode,
                                      DBUS_TYPE_INVALID)) {
                log_error("Could not attach target and flag information to message.");
                goto finish;
        }

        if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {

                /* Don't print a warning if we aren't called during
                 * startup */
                if (!dbus_error_has_name(&error, BUS_ERROR_NO_SUCH_JOB))
                        log_error("Failed to start unit: %s", bus_error_message(&error));

                goto finish;
        }

finish:
        if (m)
                dbus_message_unref(m);

        if (reply)
                dbus_message_unref(reply);

        if (bus) {
                dbus_connection_flush(bus);
                dbus_connection_close(bus);
                dbus_connection_unref(bus);
        }

        dbus_error_free(&error);
}
Exemple #14
0
static dbus_bool_t
check_spawn_nonexistent (void *data)
{
  char *argv[4] = { NULL, NULL, NULL, NULL };
  DBusBabysitter *sitter;
  DBusError error;

  sitter = NULL;

  dbus_error_init (&error);

  /*** Test launching nonexistent binary */

  argv[0] = "/this/does/not/exist/32542sdgafgafdg";
  if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL,
                                         NULL, NULL,
                                         &error))
    {
      _dbus_babysitter_block_for_child_exit (sitter);
      _dbus_babysitter_set_child_exit_error (sitter, &error);
    }

  if (sitter)
    _dbus_babysitter_unref (sitter);

  if (!dbus_error_is_set (&error))
    {
      _dbus_warn ("Did not get an error launching nonexistent executable\n");
      return FALSE;
    }

  if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
        dbus_error_has_name (&error, DBUS_ERROR_SPAWN_EXEC_FAILED)))
    {
      _dbus_warn ("Not expecting error when launching nonexistent executable: %s: %s\n",
                  error.name, error.message);
      dbus_error_free (&error);
      return FALSE;
    }

  dbus_error_free (&error);

  return TRUE;
}
Exemple #15
0
int rd_dbus_get_name_owner(
	DBusConnection *connection,
	const char *name,
	char **name_owner,
	DBusError *error) {

	DBusMessage *msg, *reply;
	int r;

	*name_owner = NULL;

	if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "GetNameOwner"))) {
		r = -ENOMEM;
		goto fail;
	}

	if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) {
		r = -ENOMEM;
		goto fail;
	}

	reply = dbus_connection_send_with_reply_and_block(connection, msg, DBUS_TIMEOUT_USE_DEFAULT, error);
	dbus_message_unref(msg);
	msg = NULL;

	if (reply) {
		if (!dbus_message_get_args(reply, error, DBUS_TYPE_STRING, name_owner, DBUS_TYPE_INVALID)) {
			dbus_message_unref(reply);
			r = -EIO;
			goto fail;
		}

		*name_owner = strdup(*name_owner);
		dbus_message_unref(reply);

		if (!*name_owner) {
			r = -ENOMEM;
			goto fail;
		}

	} else if (dbus_error_has_name(error, "org.freedesktop.DBus.Error.NameHasNoOwner"))
		dbus_error_free(error);
	else {
		r = -EIO;
		goto fail;
	}

	return 0;

fail:
	if (msg)
		dbus_message_unref(msg);

	return r;
}
Exemple #16
0
static dbus_bool_t
check_spawn_segfault (void *data)
{
    char *argv[4] = { NULL, NULL, NULL, NULL };
    DBusBabysitter *sitter = NULL;
    DBusError error = DBUS_ERROR_INIT;

    /*** Test launching segfault binary */

    argv[0] = TEST_SEGFAULT_BINARY;
    if (_dbus_spawn_async_with_babysitter (&sitter, argv,
                                           NULL, NULL, NULL,
                                           &error))
    {
        _dbus_babysitter_block_for_child_exit (sitter);
        _dbus_babysitter_set_child_exit_error (sitter, &error);
    }

    if (sitter)
        _dbus_babysitter_unref (sitter);

    if (!dbus_error_is_set (&error))
    {
        _dbus_warn ("Did not get an error launching segfaulting binary\n");
        return FALSE;
    }

    if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
            dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
    {
        _dbus_warn ("Not expecting error when launching segfaulting executable: %s: %s\n",
                    error.name, error.message);
        dbus_error_free (&error);
        return FALSE;
    }

    dbus_error_free (&error);

    return TRUE;
}
Exemple #17
0
static void simple_agent_reply(DBusPendingCall *call, void *user_data)
{
	struct agent_request *req = user_data;
	struct agent *agent = req->agent;
	DBusMessage *message;
	DBusError err;
	agent_cb cb = req->cb;

	/* steal_reply will always return non-NULL since the callback
	 * is only called after a reply has been received */
	message = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, message)) {
		if ((g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err.name) ||
				g_str_equal(DBUS_ERROR_NO_REPLY, err.name)) &&
				request_fallback(req, simple_agent_reply) == 0) {
			dbus_error_free(&err);
			return;
		}

		error("Agent replied with an error: %s, %s",
				err.name, err.message);

		cb(agent, &err, req->user_data);

		if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) {
			agent_cancel(agent);
			dbus_message_unref(message);
			dbus_error_free(&err);
			return;
		}

		dbus_error_free(&err);
		goto done;
	}

	dbus_error_init(&err);
	if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) {
		error("Wrong reply signature: %s", err.message);
		cb(agent, &err, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

	cb(agent, NULL, req->user_data);
done:
	dbus_message_unref(message);

	agent->request = NULL;
	agent_request_free(req, TRUE);
}
static dbus_bool_t
do_load (const DBusString *full_path,
         Validity          validity,
         dbus_bool_t       oom_possible)
{
  BusConfigParser *parser;
  DBusError error;

  dbus_error_init (&error);

  parser = bus_config_load (full_path, TRUE, NULL, &error);
  if (parser == NULL)
    {
      _DBUS_ASSERT_ERROR_IS_SET (&error);

      if (oom_possible &&
          dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
        {
          _dbus_verbose ("Failed to load valid file due to OOM\n");
          dbus_error_free (&error);
          return TRUE;
        }
      else if (validity == VALID)
        {
          _dbus_warn ("Failed to load valid file but still had memory: %s\n",
                      error.message);

          dbus_error_free (&error);
          return FALSE;
        }
      else
        {
          dbus_error_free (&error);
          return TRUE;
        }
    }
  else
    {
      _DBUS_ASSERT_ERROR_IS_CLEAR (&error);

      bus_config_parser_unref (parser);

      if (validity == INVALID)
        {
          _dbus_warn ("Accepted invalid file\n");
          return FALSE;
        }

      return TRUE;
    }
}
Exemple #19
0
static void auth_agent_req_reply(DBusPendingCall *call, void *data)
{
	struct auth_agent_req *req = data;
	struct authorization_agent *agent = req->agent;
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	DBusMessage *message;
	DBusError err;

	debug("authorize reply");

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, reply)) {
		if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY))
			auth_agent_call_cancel(req);
		error("Authorization agent replied with an error: %s, %s",
				err.name, err.message);
		dbus_error_free(&err);
		goto reject;
	}

	dbus_error_init(&err);
	if (!dbus_message_get_args(reply, &err,	DBUS_TYPE_INVALID)) {
		error("Wrong authorization agent reply signature: %s",
			err.message);
		dbus_error_free(&err);
		goto reject;
	}

	message = dbus_message_new_method_return(req->msg);
	if (!message)
		goto reject;

	send_message_and_unref(agent->conn, message);

	debug("successfull reply was sent");

	goto done;

reject:
	error_rejected(agent->conn, req->msg);

done:
	dbus_message_unref(reply);

	agent->pending_requests = g_slist_remove(agent->pending_requests, req);

	auth_agent_req_free(req);

	debug("auth_agent_reply: returning");
}
Exemple #20
0
static void simple_agent_reply(DBusPendingCall *call, void *user_data)
{
	struct agent_request *req = user_data;
	struct agent *agent = req->agent;
	DBusMessage *message;
	DBusError err;
	agent_cb cb = req->cb;

	/* steal_reply will always return non-NULL since the callback
	 * is only called after a reply has been received */
	message = dbus_pending_call_steal_reply(call);

	/* Protect from the callback freeing the agent */
	agent_ref(agent);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, message)) {
		DBG("agent error reply: %s, %s", err.name, err.message);

		cb(agent, &err, req->user_data);

		if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) {
			error("Timed out waiting for reply from agent");
			agent_cancel(agent);
			dbus_message_unref(message);
			dbus_error_free(&err);
			agent_unref(agent);
			return;
		}

		dbus_error_free(&err);
		goto done;
	}

	if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) {
		error("Wrong reply signature: %s", err.message);
		cb(agent, &err, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

	cb(agent, NULL, req->user_data);
done:
	dbus_message_unref(message);

	agent->request = NULL;
	agent_request_free(req, TRUE);
	agent_unref(agent);
}
static int
launcher_logind_take_control(struct launcher_logind *wl)
{
	DBusError err;
	DBusMessage *m, *reply;
	dbus_bool_t force;
	bool b;
	int r;

	dbus_error_init(&err);

	m = dbus_message_new_method_call("org.freedesktop.login1",
					 wl->spath,
					 "org.freedesktop.login1.Session",
					 "TakeControl");
	if (!m)
		return -ENOMEM;

	force = false;
	b = dbus_message_append_args(m,
				     DBUS_TYPE_BOOLEAN, &force,
				     DBUS_TYPE_INVALID);
	if (!b) {
		r = -ENOMEM;
		goto err_unref;
	}

	reply = dbus_connection_send_with_reply_and_block(wl->dbus,
							  m, -1, &err);
	if (!reply) {
		if (dbus_error_has_name(&err, DBUS_ERROR_UNKNOWN_METHOD))
			weston_log("logind: old systemd version detected\n");
		else
			weston_log("logind: cannot take control over session %s\n", wl->sid);

		dbus_error_free(&err);
		r = -EIO;
		goto err_unref;
	}

	dbus_message_unref(reply);
	dbus_message_unref(m);
	return 0;

err_unref:
	dbus_message_unref(m);
	return r;
}
Exemple #22
0
static void display_pincode_reply(DBusPendingCall *call, void *user_data)
{
	struct agent_request *req = user_data;
	struct agent *agent = req->agent;
	DBusMessage *message;
	DBusError err;
	agent_cb cb = req->cb;

	/* clear agent->request early; our callback will likely try
	 * another request */
	agent->request = NULL;

	/* steal_reply will always return non-NULL since the callback
	 * is only called after a reply has been received */
	message = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, message)) {
		error("Agent replied with an error: %s, %s",
						err.name, err.message);

		cb(agent, &err, req->user_data);

		if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) {
			agent_cancel(agent);
			dbus_message_unref(message);
			dbus_error_free(&err);
			return;
		}

		dbus_error_free(&err);
		goto done;
	}

	if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) {
		error("Wrong reply signature: %s", err.message);
		cb(agent, &err, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

	cb(agent, NULL, req->user_data);
done:
	dbus_message_unref(message);

	agent_request_free(req, TRUE);
}
Exemple #23
0
static void agent_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	const char *name;
	DBusError derr;
	gboolean *got_reply = user_data;

	*got_reply = TRUE;

	/* Received a reply after the agent exited */
	if (!agent)
		return;

	agent->auth_pending = FALSE;

	dbus_error_init(&derr);
	if (dbus_set_error_from_message(&derr, reply)) {
		error("Agent replied with an error: %s, %s",
				derr.name, derr.message);

		if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY))
			agent_cancel();

		dbus_error_free(&derr);
		dbus_message_unref(reply);
		return;
	}

	if (dbus_message_get_args(reply, NULL,
				DBUS_TYPE_STRING, &name,
				DBUS_TYPE_INVALID)) {
		/* Splits folder and name */
		const char *slash = strrchr(name, '/');
		DBG("Agent replied with %s", name);
		if (!slash) {
			agent->new_name = g_strdup(name);
			agent->new_folder = NULL;
		} else {
			agent->new_name = g_strdup(slash + 1);
			agent->new_folder = g_strndup(name, slash - name);
		}
	}

	dbus_message_unref(reply);
}
Exemple #24
0
gchar*
gkd_dbus_singleton_control (void)
{
	DBusError derr = DBUS_ERROR_INIT;
	DBusMessage *msg, *reply;
	gchar *control = NULL;
	const char *path;

	/* If tried to aquire the service must have failed */
	g_return_val_if_fail (!acquired_service, NULL);

	if (!connect_to_session_bus ())
		return NULL;

	msg = dbus_message_new_method_call (GNOME_KEYRING_DAEMON_SERVICE,
	                                    GNOME_KEYRING_DAEMON_PATH,
	                                    GNOME_KEYRING_DAEMON_INTERFACE,
	                                    "GetControlDirectory");
	g_return_val_if_fail (msg, NULL);
	dbus_message_set_auto_start (msg, FALSE);

	/* Send message and get a handle for a reply */
	reply = dbus_connection_send_with_reply_and_block (dbus_conn, msg, 1000, &derr);
	dbus_message_unref (msg);

	if (!reply) {
		if (!dbus_error_has_name (&derr, "org.freedesktop.DBus.Error.NameHasNoOwner"))
			g_message ("couldn't communicate with already running daemon: %s", derr.message);
		dbus_error_free (&derr);
		return NULL;
	}

	/* Get out our client path */
	if (!dbus_message_get_args (reply, &derr, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) {
		g_message ("couldn't parse response from already running daemon: %s", derr.message);
		dbus_error_free (&derr);
		control = NULL;
	} else {
		control = g_strdup (path);
	}

	dbus_message_unref (reply);
	return control;
}
Exemple #25
0
static void new_conn_reply(DBusPendingCall *call, void *user_data)
{
	struct ext_io *conn = user_data;
	struct ext_profile *ext = conn->ext;
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	DBusError err;

	dbus_error_init(&err);
	dbus_set_error_from_message(&err, reply);

	dbus_message_unref(reply);

	dbus_pending_call_unref(conn->new_conn);
	conn->new_conn = NULL;

	if (!dbus_error_is_set(&err)) {
		if (conn->cb) {
			conn->cb(&ext->p, conn->device, 0);
			conn->cb = NULL;
		}
		return;
	}

	error("%s replied with an error: %s, %s", ext->name,
						err.name, err.message);

	if (conn->cb) {
		conn->cb(&ext->p, conn->device, -ECONNREFUSED);
		conn->cb = NULL;
	}

	if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY))
		ext_cancel(ext);

	dbus_error_free(&err);

	ext->conns = g_slist_remove(ext->conns, conn);
	ext_io_destroy(conn);
}
static void auth_cb(DBusError *derr, void *user_data)
{
	struct avctp *session = user_data;

	if (!g_slist_find(sessions, session)) {
		error("avctp auth_cb: session no longer exists");
		return;
	}

	if (derr && dbus_error_is_set(derr)) {
		error("Access denied: %s", derr->message);
		if (dbus_error_has_name(derr, DBUS_ERROR_NO_REPLY)) {
			debug("Canceling authorization request");
			service_cancel_auth(&session->src, &session->dst);
		}

		avctp_unref(session);
		return;
	}

	avctp_connect_session(session);
}
Exemple #27
0
static void hfp_connect_reply(DBusPendingCall *call, gpointer user_data)
{
	struct ofono_modem *modem = user_data;
	struct hfp_data *data = ofono_modem_get_data(modem);
	DBusError derr;
	DBusMessage *reply, *msg;

	reply = dbus_pending_call_steal_reply(call);

	if (ofono_modem_get_powered(modem))
		goto done;

	dbus_error_init(&derr);
	if (!dbus_set_error_from_message(&derr, reply))
		goto done;

	DBG("Connect reply: %s", derr.message);

	if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) {
		msg = dbus_message_new_method_call(BLUEZ_SERVICE,
				data->handsfree_path,
				BLUEZ_GATEWAY_INTERFACE, "Disconnect");
		if (msg == NULL)
			ofono_error("Disconnect failed");
		else
			g_dbus_send_message(connection, msg);
	}

	ofono_modem_set_powered(modem, FALSE);

	dbus_error_free(&derr);

done:
	dbus_message_unref(reply);
	data->call = NULL;
}
Exemple #28
0
static dbus_bool_t
handle_reload_watch (DBusWatch    *watch,
		     unsigned int  flags,
		     void         *data)
{
  DBusError error;
  DBusString str;
  char *action_str;
  char action = '\0';

  while (!_dbus_string_init (&str))
    _dbus_wait_for_memory ();

  if ((reload_pipe[RELOAD_READ_END] > 0) &&
      _dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1)
    {
      _dbus_warn ("Couldn't read from reload pipe.\n");
      close_reload_pipe (&watch);
      return TRUE;
    }

  action_str = _dbus_string_get_data (&str);
  if (action_str != NULL)
    {
      action = action_str[0];
    }
  _dbus_string_free (&str);

  /* this can only fail if we don't understand the config file
   * or OOM.  Either way we should just stick with the currently
   * loaded config.
   */
  dbus_error_init (&error);

  switch (action)
    {
    case ACTION_RELOAD:
      if (! bus_context_reload_config (context, &error))
        {
          _DBUS_ASSERT_ERROR_IS_SET (&error);
          _dbus_assert (dbus_error_has_name (&error, DBUS_ERROR_FAILED) ||
                        dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY));
          _dbus_warn ("Unable to reload configuration: %s\n",
                      error.message);
          dbus_error_free (&error);
        }
      break;

    case ACTION_QUIT:
      {
        DBusLoop *loop;
        /*
         * On OSs without abstract sockets, we want to quit
         * gracefully rather than being killed by SIGTERM,
         * so that DBusServer gets a chance to clean up the
         * sockets from the filesystem. fd.o #38656
         */
        loop = bus_context_get_loop (context);
        if (loop != NULL)
          {
            _dbus_loop_quit (loop);
          }
      }
      break;

    default:
      break;
    }

  return TRUE;
}
Exemple #29
0
int rd_acquire(
	rd_device **_d,
	DBusConnection *connection,
	const char *device_name,
	const char *application_name,
	int32_t priority,
	rd_request_cb_t request_cb,
	DBusError *error) {

	rd_device *d = NULL;
	int r, k;
	DBusError _error;
	DBusMessage *m = NULL, *reply = NULL;
	dbus_bool_t good;

	if (!error)
		error = &_error;

	dbus_error_init(error);

	if (!_d)
		return -EINVAL;

	if (!connection)
		return -EINVAL;

	if (!device_name)
		return -EINVAL;

	if (!request_cb && priority != INT32_MAX)
		return -EINVAL;

	if (!(d = calloc(sizeof(rd_device), 1)))
		return -ENOMEM;

	d->ref = 1;

	if (!(d->device_name = strdup(device_name))) {
		r = -ENOMEM;
		goto fail;
	}

	if (!(d->application_name = strdup(application_name))) {
		r = -ENOMEM;
		goto fail;
	}

	d->priority = priority;
	d->connection = dbus_connection_ref(connection);
	d->request_cb = request_cb;

	if (!(d->service_name = malloc(sizeof(SERVICE_PREFIX) + strlen(device_name)))) {
		r = -ENOMEM;
		goto fail;
	}
	sprintf(d->service_name, SERVICE_PREFIX "%s", d->device_name);

	if (!(d->object_path = malloc(sizeof(OBJECT_PREFIX) + strlen(device_name)))) {
		r = -ENOMEM;
		goto fail;
	}
	sprintf(d->object_path, OBJECT_PREFIX "%s", d->device_name);

	if ((k = dbus_bus_request_name(
		     d->connection,
		     d->service_name,
		     DBUS_NAME_FLAG_DO_NOT_QUEUE|
		     (priority < INT32_MAX ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT : 0),
		     error)) < 0) {
		r = -EIO;
		goto fail;
	}

	if (k == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
		goto success;

	if (k != DBUS_REQUEST_NAME_REPLY_EXISTS) {
		r = -EIO;
		goto fail;
	}

	if (priority <= INT32_MIN) {
		r = -EBUSY;
		goto fail;
	}

	if (!(m = dbus_message_new_method_call(
		      d->service_name,
		      d->object_path,
		      "org.freedesktop.ReserveDevice1",
		      "RequestRelease"))) {
		r = -ENOMEM;
		goto fail;
	}

	if (!dbus_message_append_args(
		    m,
		    DBUS_TYPE_INT32, &d->priority,
		    DBUS_TYPE_INVALID)) {
		r = -ENOMEM;
		goto fail;
	}

	if (!(reply = dbus_connection_send_with_reply_and_block(
		      d->connection,
		      m,
		      5000, /* 5s */
		      error))) {

		if (dbus_error_has_name(error, DBUS_ERROR_TIMED_OUT) ||
		    dbus_error_has_name(error, DBUS_ERROR_UNKNOWN_METHOD) ||
		    dbus_error_has_name(error, DBUS_ERROR_NO_REPLY)) {
			/* This must be treated as denied. */
			r = -EBUSY;
			goto fail;
		}

		r = -EIO;
		goto fail;
	}

	if (!dbus_message_get_args(
		    reply,
		    error,
		    DBUS_TYPE_BOOLEAN, &good,
		    DBUS_TYPE_INVALID)) {
		r = -EIO;
		goto fail;
	}

	if (!good) {
		r = -EBUSY;
		goto fail;
	}

	if ((k = dbus_bus_request_name(
		     d->connection,
		     d->service_name,
		     DBUS_NAME_FLAG_DO_NOT_QUEUE|
		     (priority < INT32_MAX ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT : 0)|
		     DBUS_NAME_FLAG_REPLACE_EXISTING,
		     error)) < 0) {
		r = -EIO;
		goto fail;
	}

	if (k != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
		r = -EIO;
		goto fail;
	}

success:
	d->owning = 1;

	if (!(dbus_connection_register_object_path(
		      d->connection,
		      d->object_path,
		      &vtable,
		      d))) {
		r = -ENOMEM;
		goto fail;
	}

	d->registered = 1;

	if (!dbus_connection_add_filter(
		    d->connection,
		    filter_handler,
		    d,
		    NULL)) {
		r = -ENOMEM;
		goto fail;
	}

	d->filtering = 1;

	*_d = d;
	return 0;

fail:
	if (m)
		dbus_message_unref(m);

	if (reply)
		dbus_message_unref(reply);

	if (&_error == error)
		dbus_error_free(&_error);

	if (d)
		rd_release(d);

	return r;
}
Exemple #30
0
dbus_bool_t
bus_registry_acquire_service (BusRegistry      *registry,
                              DBusConnection   *connection,
                              const DBusString *service_name,
                              dbus_uint32_t     flags,
                              dbus_uint32_t    *result,
                              BusTransaction   *transaction,
                              DBusError        *error)
{
  dbus_bool_t retval;
  DBusConnection *old_owner_conn;
  BusClientPolicy *policy;
  BusService *service;
  BusActivation  *activation;
  BusSELinuxID *sid;
  BusOwner *primary_owner;
 
  retval = FALSE;

  if (!_dbus_validate_bus_name (service_name, 0,
                                _dbus_string_get_length (service_name)))
    {
      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
                      "Requested bus name \"%s\" is not valid",
                      _dbus_string_get_const_data (service_name));
      
      _dbus_verbose ("Attempt to acquire invalid service name\n");
      
      goto out;
    }
  
  if (_dbus_string_get_byte (service_name, 0) == ':')
    {
      /* Not allowed; only base services can start with ':' */
      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
                      "Cannot acquire a service starting with ':' such as \"%s\"",
                      _dbus_string_get_const_data (service_name));
      
      _dbus_verbose ("Attempt to acquire invalid base service name \"%s\"",
                     _dbus_string_get_const_data (service_name));
      
      goto out;
    }

  if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
    {
      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
                      "Connection \"%s\" is not allowed to own the service \"%s\"because "
                      "it is reserved for D-Bus' use only",
                      bus_connection_is_active (connection) ?
                      bus_connection_get_name (connection) :
                      "(inactive)",
                      DBUS_SERVICE_DBUS);
      goto out;
    }

  policy = bus_connection_get_policy (connection);
  _dbus_assert (policy != NULL);

  /* Note that if sid is #NULL then the bus's own context gets used
   * in bus_connection_selinux_allows_acquire_service()
   */
  sid = bus_selinux_id_table_lookup (registry->service_sid_table,
                                     service_name);

  if (!bus_selinux_allows_acquire_service (connection, sid,
					   _dbus_string_get_const_data (service_name), error))
    {

      if (dbus_error_is_set (error) &&
	  dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY))
	{
	  goto out;
	}

      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
                      "Connection \"%s\" is not allowed to own the service \"%s\" due "
                      "to SELinux policy",
                      bus_connection_is_active (connection) ?
                      bus_connection_get_name (connection) :
                      "(inactive)",
                      _dbus_string_get_const_data (service_name));
      goto out;
    }
  
  if (!bus_client_policy_check_can_own (policy, service_name))
    {
      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
                      "Connection \"%s\" is not allowed to own the service \"%s\" due "
                      "to security policies in the configuration file",
                      bus_connection_is_active (connection) ?
                      bus_connection_get_name (connection) :
                      "(inactive)",
                      _dbus_string_get_const_data (service_name));
      goto out;
    }

  if (bus_connection_get_n_services_owned (connection) >=
      bus_context_get_max_services_per_connection (registry->context))
    {
      dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
                      "Connection \"%s\" is not allowed to own more services "
                      "(increase limits in configuration file if required)",
                      bus_connection_is_active (connection) ?
                      bus_connection_get_name (connection) :
                      "(inactive)");
      goto out;
    }
  
  service = bus_registry_lookup (registry, service_name);

  if (service != NULL)
    {
      primary_owner = bus_service_get_primary_owner (service);
      if (primary_owner != NULL)
        old_owner_conn = primary_owner->conn;
      else
        old_owner_conn = NULL;
    }
  else
    old_owner_conn = NULL;
      
  if (service == NULL)
    {
      service = bus_registry_ensure (registry,
                                     service_name, connection, flags,
                                     transaction, error);
      if (service == NULL)
        goto out;
    }

  primary_owner = bus_service_get_primary_owner (service);
  if (primary_owner == NULL)
    goto out;

  if (old_owner_conn == NULL)
    {
      _dbus_assert (primary_owner->conn == connection);

      *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;      
    }
  else if (old_owner_conn == connection)
    {
      bus_owner_set_flags (primary_owner, flags);
      *result = DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
    }
  else if (((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
           !(bus_service_get_allow_replacement (service))) ||
	   ((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
           !(flags & DBUS_NAME_FLAG_REPLACE_EXISTING))) 
    {
      DBusList *link;
      BusOwner *temp_owner;
    /* Since we can't be queued if we are already in the queue
       remove us */

      link = _bus_service_find_owner_link (service, connection);
      if (link != NULL)
        {
          _dbus_list_unlink (&service->owners, link);
          temp_owner = (BusOwner *)link->data;
          bus_owner_unref (temp_owner); 
          _dbus_list_free_link (link);
        }
      
      *result = DBUS_REQUEST_NAME_REPLY_EXISTS;
    }
  else if (!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
           (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) ||
	    !(bus_service_get_allow_replacement (service))))
    {
      /* Queue the connection */
      if (!bus_service_add_owner (service, connection, 
                                  flags,
                                  transaction, error))
        goto out;
      
      *result = DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
    }
  else
    {
      /* Replace the current owner */

      /* We enqueue the new owner and remove the first one because
       * that will cause NameAcquired and NameLost messages to
       * be sent.
       */
      
      if (!bus_service_add_owner (service, connection,
                                  flags,
                                  transaction, error))
        goto out;

      if (primary_owner->do_not_queue)
        {
          if (!bus_service_remove_owner (service, old_owner_conn,
                                         transaction, error))
            goto out;
        }
      else
        {
          if (!bus_service_swap_owner (service, old_owner_conn,
                                       transaction, error))
            goto out;
        }
        
    
      _dbus_assert (connection == bus_service_get_primary_owner (service)->conn);
      *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
    }

  activation = bus_context_get_activation (registry->context);
  retval = bus_activation_send_pending_auto_activation_messages (activation,
								 service,
								 transaction);
  if (!retval)
    BUS_SET_OOM (error);
  
 out:
  return retval;
}