/**
 * 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;
}
示例#2
0
static char *
gconf_address_for_caller (GConfDefaults          *mechanism,
			  DBusGMethodInvocation  *context,
			  GError                **gerror)
{
        char *sender;
	DBusConnection *conn;
	uid_t uid;
	struct passwd *pwd;
	char *result;
	DBusError error;

	conn = dbus_g_connection_get_connection (mechanism->priv->system_bus_connection);
        sender = dbus_g_method_get_sender (context);

	dbus_error_init (&error);
	uid = dbus_bus_get_unix_user (conn, sender, &error);
	g_free (sender);
	if (uid == (unsigned)-1) {
		dbus_set_g_error (gerror, &error);
		dbus_error_free (&error);
		return NULL;
	}

	pwd = getpwuid (uid);
	if (pwd == NULL) {
		g_set_error (gerror,
			     0, 0,
			     "Failed to get passwd information for uid %d", uid);
		return NULL;
	}

	result = g_strconcat ("xml:merged:", pwd->pw_dir, "/.gconf", NULL);
	return result;
}
static char *
_fprint_device_check_for_username (FprintDevice *rdev,
				   DBusGMethodInvocation *context,
				   const char *username,
				   char **ret_sender,
				   GError **error)
{
	DBusConnection *conn;
	DBusError dbus_error;
	char *sender;
	unsigned long uid;
	struct passwd *user;
	char *client_username;

	/* Get details about the current sender, and username/uid */
	conn = dbus_g_connection_get_connection (fprintd_dbus_conn);
	sender = dbus_g_method_get_sender (context);
	dbus_error_init (&dbus_error);
	uid = dbus_bus_get_unix_user (conn, sender, &dbus_error);

	if (dbus_error_is_set(&dbus_error)) {
		g_free (sender);
		dbus_set_g_error (error, &dbus_error);
		return NULL;
	}

	user = getpwuid (uid);
	if (user == NULL) {
		g_free (sender);
		g_set_error(error, FPRINT_ERROR, FPRINT_ERROR_INTERNAL,
			    "Failed to get information about user UID %lu", uid);
		return NULL;
	}
	client_username = g_strdup (user->pw_name);

	/* The current user is usually allowed to access their
	 * own data, this should be followed by PolicyKit checks
	 * anyway */
	if (username == NULL || *username == '\0' || g_str_equal (username, client_username)) {
		if (ret_sender != NULL)
			*ret_sender = sender;
		else
			g_free (sender);
		return client_username;
	}

	/* If we're not allowed to set a different username,
	 * then fail */
	if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.setusername", error) == FALSE) {
		g_free (sender);
		return NULL;
	}

	if (ret_sender != NULL)
		*ret_sender = sender;
	else
		g_free (sender);

	return g_strdup (username);
}
示例#4
0
static gboolean
check_polkit_for_action (GConfDefaults         *mechanism,
                         DBusGMethodInvocation *context,
                         const char            *action)
{
	const char *sender;
	GError *error;
	DBusError dbus_error;
	PolKitCaller *pk_caller;
	PolKitAction *pk_action;
	PolKitResult pk_result;

	error = NULL;

	/* Check that caller is privileged */
	sender = dbus_g_method_get_sender (context);
	dbus_error_init (&dbus_error);
	pk_caller = polkit_caller_new_from_dbus_name (
	dbus_g_connection_get_connection (mechanism->priv->system_bus_connection),
					  sender,
					  &dbus_error);
	if (pk_caller == NULL) {
		error = g_error_new (GCONF_DEFAULTS_ERROR,
				     GCONF_DEFAULTS_ERROR_GENERAL,
				     "Error getting information about caller: %s: %s",
				     dbus_error.name, dbus_error.message);
		dbus_error_free (&dbus_error);
		dbus_g_method_return_error (context, error);
		g_error_free (error);
		return FALSE;
	}

	pk_action = polkit_action_new ();
	polkit_action_set_action_id (pk_action, action);
	pk_result = polkit_context_is_caller_authorized (mechanism->priv->pol_ctx, pk_action, pk_caller, TRUE, NULL);
	polkit_caller_unref (pk_caller);

	if (pk_result != POLKIT_RESULT_YES) {
		dbus_error_init (&dbus_error);
		polkit_dbus_error_generate (pk_action, pk_result, &dbus_error);
		dbus_set_g_error (&error, &dbus_error);
		dbus_g_method_return_error (context, error);
		dbus_error_free (&dbus_error);
		g_error_free (error);
		polkit_action_unref (pk_action);
		return FALSE;
	}

	polkit_action_unref (pk_action);
	return TRUE;
}
/**
 * @ingroup DBusGLibInternals
 * Unit test for general glib stuff
 * @returns #TRUE on success.
 */
gboolean
_dbus_glib_test (const char *test_data_dir)
{
  DBusError err;
  GError *gerror = NULL;

  dbus_error_init (&err);
  dbus_set_error_const (&err, DBUS_ERROR_NO_MEMORY, "Out of memory!");

  dbus_set_g_error (&gerror, &err);
  g_assert (gerror != NULL);
  g_assert (gerror->domain == DBUS_GERROR);
  g_assert (gerror->code == DBUS_GERROR_NO_MEMORY);
  g_assert (!strcmp (gerror->message, "Out of memory!"));
  
  dbus_error_init (&err);
  g_clear_error (&gerror);

  return TRUE;
}
/**
 * thunar_dbus_client_bulk_rename:
 * @working_directory : the default working directory for the bulk rename dialog.
 * @filenames         : the list of files that should be displayed by default or
 *                      the empty list to start with an empty bulk rename dialog.
 * @standalone        : whether to run the bulk renamer in standalone mode.
 * @screen            : the #GdkScreen on which to display the dialog or %NULL to
 *                      use the default #GdkScreen.
 * @error             : return location for errors or %NULL.
 *
 * Tries to invoke the BulkRename() method on a running Thunar instance, that is
 * registered with the current D-BUS session bus. Returns %TRUE if the method was
 * successfully invoked, else %FALSE.
 *
 * If %TRUE is returned, the current process may afterwards just terminate, as
 * all @filenames will be handled by the remote instance.
 *
 * Return value: %TRUE on success, else %FALSE.
 **/
gboolean
thunar_dbus_client_bulk_rename (const gchar *working_directory,
                                gchar      **filenames,
                                gboolean     standalone,
                                GdkScreen   *screen,
                                GError     **error)
{
  DBusConnection *connection;
  DBusMessage    *message;
  DBusMessage    *result;
  DBusError       derror;
  gchar          *display_name;

  _thunar_return_val_if_fail (screen == NULL || GDK_IS_SCREEN (screen), FALSE);
  _thunar_return_val_if_fail (g_path_is_absolute (working_directory), FALSE);
  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  _thunar_return_val_if_fail (filenames != NULL, FALSE);

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

  /* fallback to default screen if no other is specified */
  if (G_LIKELY (screen == NULL))
    screen = gdk_screen_get_default ();

  /* 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;
    }

  /* determine the display name for the screen */
  display_name = gdk_screen_make_display_name (screen);

  /* generate the BulkRename() method (disable activation!) */
  message = dbus_message_new_method_call ("org.xfce.Thunar", "/org/xfce/FileManager", "org.xfce.Thunar", "BulkRename");
  dbus_message_set_auto_start (message, FALSE);
  dbus_message_append_args (message,
                            DBUS_TYPE_STRING, &working_directory,
                            DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &filenames, g_strv_length (filenames),
                            DBUS_TYPE_BOOLEAN, &standalone,
                            DBUS_TYPE_STRING, &display_name,
                            DBUS_TYPE_INVALID);

  /* release the display name */
  g_free (display_name);

  /* 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))
    {
      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;
}