コード例 #1
0
ファイル: gumd-dbus-server-p2p.c プロジェクト: 01org/gumd
static pid_t
_gumd_dbus_server_p2p_get_remote_pid (
        GumdDbusServer *self,
        GDBusMethodInvocation *invocation)
{
    pid_t remote_pid = 0;
    GDBusConnection *connection = NULL;
    gint peer_fd = -1;
    struct ucred peer_cred;
    socklen_t cred_size = sizeof(peer_cred);

    g_return_val_if_fail (invocation && GUMD_IS_DBUS_SERVER_P2P (self),
            remote_pid);

    connection = g_dbus_method_invocation_get_connection (invocation);
    peer_fd = g_socket_get_fd (g_socket_connection_get_socket (
            G_SOCKET_CONNECTION (g_dbus_connection_get_stream(connection))));
    if (peer_fd < 0 || getsockopt (peer_fd, SOL_SOCKET, SO_PEERCRED,
            &peer_cred, &cred_size) != 0) {
        WARN ("getsockopt() for SO_PEERCRED failed");
        return remote_pid;
    }
    DBG ("Remote p2p peer pid=%d uid=%d gid=%d", peer_cred.pid, peer_cred.uid,
            peer_cred.gid);

    return peer_cred.pid;
}
コード例 #2
0
static void _dbus_steadyflow_iapp_service_set_visible (SteadyflowIAppService* self, GVariant* parameters, GDBusMethodInvocation* invocation) {
	GError* error = NULL;
	GVariantIter _arguments_iter;
	gboolean visible = FALSE;
	GVariant* _tmp1_;
	GDBusMessage* _reply_message;
	GVariant* _reply;
	GVariantBuilder _reply_builder;
	g_variant_iter_init (&_arguments_iter, parameters);
	_tmp1_ = g_variant_iter_next_value (&_arguments_iter);
	visible = g_variant_get_boolean (_tmp1_);
	g_variant_unref (_tmp1_);
	steadyflow_iapp_service_set_visible (self, visible, &error);
	if (error) {
		g_dbus_method_invocation_return_gerror (invocation, error);
		return;
	}
	_reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation));
	g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE);
	_reply = g_variant_builder_end (&_reply_builder);
	g_dbus_message_set_body (_reply_message, _reply);
	g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL);
	g_object_unref (invocation);
	g_object_unref (_reply_message);
}
コード例 #3
0
ファイル: tasks.c プロジェクト: biddyweb/cpclient
void cpc_tasks_create_pm(cpc_task_t *task, cpc_pm_manager_t *pm_manager)
{
	CPC_ERR_MANAGE;
	gchar *path;
	GDBusConnection *connection =
		g_dbus_method_invocation_get_connection(task->invocation);
	const gchar *client_name =
		g_dbus_method_invocation_get_sender(task->invocation);

	CPC_FAIL(cpc_pm_manager_new_message(pm_manager,
						 client_name,
						 connection,
						 task->wp_message,
						 task->wp_message_len,
						 &path));

	CPC_LOGF("New Push Message object created %s", path);
	syslog(LOG_INFO, "New Push Message object created %s", path);

	g_dbus_method_invocation_return_value(
		task->invocation, g_variant_new("(o)", path));
	g_free(path);
	task->invocation = NULL;
	return;

CPC_ON_ERR:

	CPC_LOGF("Failed to create Push Message object");
	syslog(LOG_INFO, "Failed to create Push Message object");

	g_dbus_method_invocation_return_dbus_error(
		task->invocation, cpc_dbus_error_map(CPC_ERR), "");
	task->invocation = NULL;
}
コード例 #4
0
gboolean
get_caller_uid (GDBusMethodInvocation *context,
                gint                  *uid)
{
        GVariant      *reply;
        GError        *error;

        error = NULL;
        reply = g_dbus_connection_call_sync (g_dbus_method_invocation_get_connection (context),
                                             "org.freedesktop.DBus",
                                             "/org/freedesktop/DBus",
                                             "org.freedesktop.DBus",
                                             "GetConnectionUnixUser",
                                             g_variant_new ("(s)",
                                                            g_dbus_method_invocation_get_sender (context)),
                                             G_VARIANT_TYPE ("(u)"),
                                             G_DBUS_CALL_FLAGS_NONE,
                                             -1,
                                             NULL,
                                             &error);

        if (reply == NULL) {
                g_warning ("Could not talk to message bus to find uid of sender %s: %s",
                           g_dbus_method_invocation_get_sender (context),
                           error->message);
                g_error_free (error);

                return FALSE;
        }

        g_variant_get (reply, "(u)", uid);
        g_variant_unref (reply);

        return TRUE;
}
コード例 #5
0
static gboolean
subprocess_backend_handle_create_cb (EDBusSubprocessBackend *proxy,
				     GDBusMethodInvocation *invocation,
				     const gchar *uid,
				     const gchar *backend_factory_type_name,
				     const gchar *module_filename,
				     ESubprocessBookFactory *subprocess_book_factory)
{
	gchar *object_path = NULL;
	GDBusConnection *connection;
	GError *error = NULL;

	connection = g_dbus_method_invocation_get_connection (invocation);

	object_path = e_subprocess_factory_open_backend (
		E_SUBPROCESS_FACTORY (subprocess_book_factory),
		connection,
		uid,
		backend_factory_type_name,
		module_filename,
		G_DBUS_INTERFACE_SKELETON (proxy),
		NULL,
		&error);

	if (object_path != NULL) {
		e_dbus_subprocess_backend_complete_create (proxy, invocation, object_path);
		g_free (object_path);
	} else {
		g_dbus_method_invocation_take_error (invocation, error);
	}

	return TRUE;
}
コード例 #6
0
ファイル: print.c プロジェクト: grulja/xdg-desktop-portal
static gboolean
handle_prepare_print (XdpPrint *object,
                      GDBusMethodInvocation *invocation,
                      const gchar *arg_parent_window,
                      const gchar *arg_title,
                      GVariant *arg_settings,
                      GVariant *arg_page_setup,
                      GVariant *arg_options)
{
  Request *request = request_from_invocation (invocation);
  const char *app_id = xdp_app_info_get_id (request->app_info);
  g_autoptr(GError) error = NULL;
  g_autoptr(XdpImplRequest) impl_request = NULL;
  GVariantBuilder opt_builder;

  if (xdp_impl_lockdown_get_disable_printing (lockdown))
    {
      g_debug ("Printing disabled");
      g_dbus_method_invocation_return_error (invocation,
                                             XDG_DESKTOP_PORTAL_ERROR,
                                             XDG_DESKTOP_PORTAL_ERROR_NOT_ALLOWED,
                                             "Printing disabled");
      return TRUE;
    }

  REQUEST_AUTOLOCK (request);

  impl_request = xdp_impl_request_proxy_new_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (impl)),
                                                  G_DBUS_PROXY_FLAGS_NONE,
                                                  g_dbus_proxy_get_name (G_DBUS_PROXY (impl)),
                                                  request->id,
                                                  NULL, &error);
  if (!impl_request)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return TRUE;
    }

  request_set_impl_request (request, impl_request);
  request_export (request, g_dbus_method_invocation_get_connection (invocation));

  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
  xdp_filter_options (arg_options, &opt_builder,
                      prepare_print_options, G_N_ELEMENTS (prepare_print_options));
  xdp_impl_print_call_prepare_print (impl,
                                     request->id,
                                     app_id,
                                     arg_parent_window,
                                     arg_title,
                                     arg_settings,
                                     arg_page_setup,
                                     g_variant_builder_end (&opt_builder),
                                     NULL,
                                     prepare_print_done,
                                     g_object_ref (request));

  xdp_print_complete_prepare_print (object, invocation, request->id);

  return TRUE;
}
コード例 #7
0
ファイル: timedatex.c プロジェクト: AdamWill/timedatex
static void finish_set_timezone(GDBusMethodInvocation *invocation, struct method_call_data *data) {
	gchar link[PATH_MAX], tmp[PATH_MAX];

	if (snprintf(link, sizeof link, "%s%s%s", LOCALTIME_TO_ZONEINFO_PATH, ZONEINFO_PATH,
		     data->set_timezone.timezone) >= sizeof link)
		goto error;

	if (snprintf(tmp, sizeof tmp, "%s.%06u", LOCALTIME_PATH, g_random_int()) >= sizeof tmp)
		goto error;

	if (symlink(link, tmp))
		goto error;

	set_default_file_context(tmp, link);

	if (rename(tmp, LOCALTIME_PATH)) {
		unlink(tmp);
		goto error;
	}

	emit_property_change(g_dbus_method_invocation_get_connection(invocation),
			     "Timezone", g_variant_new_string(data->set_timezone.timezone));
	return_success(invocation);

	update_kernel_utc_offset();

	/* RTC in local needs to be set for the new timezone */
	if (is_rtc_local())
		start_hwclock_call(FALSE, FALSE, FALSE, NULL, NULL, NULL);

	return;
error:
	return_error(invocation, G_DBUS_ERROR_FAILED, "Failed to update %s", LOCALTIME_PATH);
}
コード例 #8
0
ファイル: udisksdaemonutil.c プロジェクト: jprvita/udisks
/**
 * udisks_daemon_util_get_caller_pid_sync:
 * @daemon: A #UDisksDaemon.
 * @invocation: A #GDBusMethodInvocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @out_pid: (out): Return location for resolved pid or %NULL.
 * @error: Return location for error.
 *
 * Gets the UNIX process id of the peer represented by @invocation.
 *
 * Returns: %TRUE if the process id was obtained, %FALSE otherwise
 */
gboolean
udisks_daemon_util_get_caller_pid_sync (UDisksDaemon            *daemon,
                                        GDBusMethodInvocation   *invocation,
                                        GCancellable            *cancellable,
                                        pid_t                   *out_pid,
                                        GError                 **error)
{
  gboolean ret;
  const gchar *caller;
  GVariant *value;
  GError *local_error;
  pid_t pid;

  /* TODO: cache this on @daemon */

  ret = FALSE;

  caller = g_dbus_method_invocation_get_sender (invocation);

  local_error = NULL;
  value = g_dbus_connection_call_sync (g_dbus_method_invocation_get_connection (invocation),
                                       "org.freedesktop.DBus",  /* bus name */
                                       "/org/freedesktop/DBus", /* object path */
                                       "org.freedesktop.DBus",  /* interface */
                                       "GetConnectionUnixProcessID", /* method */
                                       g_variant_new ("(s)", caller),
                                       G_VARIANT_TYPE ("(u)"),
                                       G_DBUS_CALL_FLAGS_NONE,
                                       -1, /* timeout_msec */
                                       cancellable,
                                       &local_error);
  if (value == NULL)
    {
      g_set_error (error,
                   UDISKS_ERROR,
                   UDISKS_ERROR_FAILED,
                   "Error determining uid of caller %s: %s (%s, %d)",
                   caller,
                   local_error->message,
                   g_quark_to_string (local_error->domain),
                   local_error->code);
      g_error_free (local_error);
      goto out;
    }

  {
    G_STATIC_ASSERT (sizeof (uid_t) == sizeof (guint32));
  }
  g_variant_get (value, "(u)", &pid);
  if (out_pid != NULL)
    *out_pid = pid;

  ret = TRUE;

 out:
  return ret;
}
コード例 #9
0
static gboolean
photos_thumbnailer_handle_cancel (PhotosThumbnailer *self,
                                  GDBusMethodInvocation *invocation,
                                  guint serial)
{
  GCancellable *cancellable;
  GDBusConnection *connection;
  GDBusMethodInvocation *invocation_ongoing;
  GHashTableIter iter;

  g_return_val_if_fail (PHOTOS_IS_THUMBNAILER (self), FALSE);
  g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);

  photos_debug (PHOTOS_DEBUG_THUMBNAILER, "Handling Cancel for %u", serial);
  g_application_hold (G_APPLICATION (self));

  connection = g_dbus_method_invocation_get_connection (invocation);

  g_hash_table_iter_init (&iter, self->cancellables);
  while (g_hash_table_iter_next (&iter, (gpointer *) &invocation_ongoing, (gpointer *) &cancellable))
    {
      GDBusConnection *connection_ongoing;
      GDBusMessage *message_ongoing;
      guint32 serial_ongoing;

      connection_ongoing = g_dbus_method_invocation_get_connection (invocation_ongoing);
      message_ongoing = g_dbus_method_invocation_get_message (invocation_ongoing);
      serial_ongoing = g_dbus_message_get_serial (message_ongoing);

      if (connection == connection_ongoing && (guint32) serial == serial_ongoing)
        {
          g_cancellable_cancel (cancellable);
          photos_thumbnailer_dbus_complete_cancel (self->skeleton, invocation);
          goto out;
        }
    }

  g_dbus_method_invocation_return_error_literal (invocation, PHOTOS_ERROR, 0, "Invalid serial");

 out:
  photos_debug (PHOTOS_DEBUG_THUMBNAILER, "Completed Cancel");
  g_application_release (G_APPLICATION (self));
  return TRUE;
}
コード例 #10
0
char *
xdp_invocation_lookup_app_id_sync (GDBusMethodInvocation *invocation,
                                   GCancellable          *cancellable,
                                   GError               **error)
{
  GDBusConnection *connection = g_dbus_method_invocation_get_connection (invocation);
  const gchar *sender = g_dbus_method_invocation_get_sender (invocation);

  return xdp_connection_lookup_app_id_sync (connection, sender, cancellable, error);
}
コード例 #11
0
static gboolean
handle_save_file (XdpFileChooser *object,
                  GDBusMethodInvocation *invocation,
                  const gchar *arg_parent_window,
                  const gchar *arg_title,
                  GVariant *arg_options)
{
  Request *request = request_from_invocation (invocation);
  const char *app_id = request->app_id;
  g_autoptr(GError) error = NULL;
  XdpImplRequest *impl_request;
  GVariantBuilder options;

  REQUEST_AUTOLOCK (request);

  g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
  xdp_filter_options (arg_options, &options,
                      save_file_options, G_N_ELEMENTS (save_file_options));

  impl_request = xdp_impl_request_proxy_new_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (impl)),
                                                  G_DBUS_PROXY_FLAGS_NONE,
                                                  g_dbus_proxy_get_name (G_DBUS_PROXY (impl)),
                                                  request->id,
                                                  NULL, &error);
  if (!impl_request)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return TRUE;
    }

  g_object_set_data (G_OBJECT (request), "for-save", GINT_TO_POINTER (TRUE));

  request_set_impl_request (request, impl_request);
  request_export (request, g_dbus_method_invocation_get_connection (invocation));

  xdp_impl_file_chooser_call_save_file (impl,
                                        request->id,
                                        app_id,
                                        arg_parent_window,
                                        arg_title,
                                        g_variant_builder_end (&options),
                                        NULL,
                                        save_file_done,
                                        g_object_ref (request));

  xdp_file_chooser_complete_open_file (object, invocation, request->id);

  return TRUE;
}
コード例 #12
0
ファイル: timedatex.c プロジェクト: AdamWill/timedatex
static void finish_set_ntp_active(GDBusMethodInvocation *invocation, struct method_call_data *data) {
	GVariantBuilder builder1, builder2;
	gchar *unit_name;
	guint i, enable, disable;

	/* Reload the list to get new NTP units installed on the system */
	update_ntp_units();

	/* Start and enable the first NTP unit if active is true. Stop and disable
	   everything else. Errors are ignored for other units than first. */

	for (i = enable = disable = 0; i < ntp_units->len; i++) {
		unit_name = get_ntp_unit(i)->name;

		if (!i && data->set_ntp_active.active) {
			if (!call_systemd_noresult("StartUnit", g_variant_new("(ss)", unit_name, "replace")))
			       if (!i)
				       goto error;
			if (!enable++)
				g_variant_builder_init(&builder1, G_VARIANT_TYPE("as"));
			g_variant_builder_add(&builder1, "s", unit_name);
		} else {
			if (!call_systemd_noresult("StopUnit", g_variant_new("(ss)", unit_name, "replace")))
				if (!i)
					goto error;
			if (!disable++)
				g_variant_builder_init(&builder2, G_VARIANT_TYPE("as"));
			g_variant_builder_add(&builder2, "s", unit_name);
		}
	}

	if (enable)
		call_systemd_noresult("EnableUnitFiles", g_variant_new("(asbb)", &builder1, FALSE, TRUE));
	if (disable)
		call_systemd_noresult("DisableUnitFiles", g_variant_new("(asb)", &builder2, FALSE));

	/* This seems to be needed to update the unit state reported by systemd */
	if (enable || disable)
		call_systemd_noresult("Reload", g_variant_new("()"));

	emit_property_change(g_dbus_method_invocation_get_connection(invocation),
			     "NTP", g_variant_new_boolean(data->set_ntp_active.active));
	return_success(invocation);
	return;
error:
	return_error(invocation, G_DBUS_ERROR_FAILED, "Failed to start/stop NTP unit");
}
コード例 #13
0
static DBusWatch *
make_dbus_watch (MetaDBusIdleMonitor   *skeleton,
                 GDBusMethodInvocation *invocation,
                 MetaIdleMonitor       *monitor)
{
  DBusWatch *watch;

  watch = g_slice_new (DBusWatch);
  watch->dbus_monitor = g_object_ref (skeleton);
  watch->monitor = g_object_ref (monitor);
  watch->dbus_name = g_strdup (g_dbus_method_invocation_get_sender (invocation));
  watch->name_watcher_id = g_bus_watch_name_on_connection (g_dbus_method_invocation_get_connection (invocation),
                                                           watch->dbus_name,
                                                           G_BUS_NAME_WATCHER_FLAGS_NONE,
                                                           NULL, /* appeared */
                                                           name_vanished_callback,
                                                           watch, NULL);

  return watch;
}
コード例 #14
0
static gboolean
handle_save_file (XdpFileChooser *object,
                  GDBusMethodInvocation *invocation,
                  const gchar *arg_parent_window,
                  const gchar *arg_title,
                  GVariant *arg_options)
{
  Request *request = request_from_invocation (invocation);
  const char *app_id = request->app_id;
  const gchar *sender = g_dbus_method_invocation_get_sender (invocation);
  g_autoptr(GError) error = NULL;
  g_autofree char *impl_handle = NULL;
  GVariantBuilder options;

  g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
  copy_options (arg_options, &options, save_file_options, G_N_ELEMENTS (save_file_options));

  if (!xdp_impl_file_chooser_call_save_file_sync (impl,
                                                  sender, app_id,
                                                  arg_parent_window,
                                                  arg_title,
                                                  g_variant_builder_end (&options),
                                                  &impl_handle,
                                                  NULL, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return TRUE;
    }

  g_object_set_data_full (G_OBJECT (request), "impl-handle", g_strdup (impl_handle), g_free);
  register_handle (impl_handle, request);

  g_signal_connect (request, "handle-close", (GCallback)handle_close, request);

  REQUEST_AUTOLOCK (request);

  request_export (request, g_dbus_method_invocation_get_connection (invocation));

  xdp_file_chooser_complete_open_file (object, invocation, request->id);
  return TRUE;
}
コード例 #15
0
ファイル: gvfsjobprogress.c プロジェクト: Alustriel/gvfs
void
g_vfs_job_progress_callback (goffset current_num_bytes,
                             goffset total_num_bytes,
                             gpointer user_data)
{
  GVfsJobProgress *job = G_VFS_JOB_PROGRESS (user_data);
  GVfsJobDBus *dbus_job = G_VFS_JOB_DBUS (job);

  g_debug ("g_vfs_job_progress_callback %" G_GOFFSET_FORMAT "/%" G_GOFFSET_FORMAT "\n", current_num_bytes, total_num_bytes);

  if (job->callback_obj_path == NULL || job->progress_proxy == NULL)
    return;

  gvfs_dbus_progress_call_progress (job->progress_proxy,
                                    current_num_bytes,
                                    total_num_bytes,
                                    NULL,
                                    NULL,
                                    NULL);
  g_dbus_connection_flush_sync (g_dbus_method_invocation_get_connection (dbus_job->invocation), NULL, NULL);
}
コード例 #16
0
/**
 * g_dbus_method_invocation_return_dbus_error:
 * @invocation: A #GDBusMethodInvocation.
 * @error_name: A valid D-Bus error name.
 * @error_message: A valid D-Bus error message.
 *
 * Finishes handling a D-Bus method call by returning an error.
 *
 * This method will free @invocation, you cannot use it afterwards.
 *
 * Since: 2.26
 */
void
g_dbus_method_invocation_return_dbus_error (GDBusMethodInvocation *invocation,
                                            const gchar           *error_name,
                                            const gchar           *error_message)
{
  GDBusMessage *reply;

  g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
  g_return_if_fail (error_name != NULL && g_dbus_is_name (error_name));
  g_return_if_fail (error_message != NULL);

  if (G_UNLIKELY (_g_dbus_debug_return ()))
    {
      _g_dbus_debug_print_lock ();
      g_print ("========================================================================\n"
               "GDBus-debug:Return:\n"
               " >>>> METHOD ERROR %s\n"
               "      message `%s'\n"
               "      in response to %s.%s()\n"
               "      on object %s\n"
               "      to name %s\n"
               "      reply-serial %d\n",
               error_name,
               error_message,
               invocation->interface_name, invocation->method_name,
               invocation->object_path,
               invocation->sender,
               g_dbus_message_get_serial (invocation->message));
      _g_dbus_debug_print_unlock ();
    }

  reply = g_dbus_message_new_method_error_literal (invocation->message,
                                                   error_name,
                                                   error_message);
  g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL);
  g_object_unref (reply);

  g_object_unref (invocation);
}
コード例 #17
0
ファイル: gvfsjobprogress.c プロジェクト: Alustriel/gvfs
void
g_vfs_job_progress_construct_proxy (GVfsJob *job)
{
  GVfsJobDBus *dbus_job = G_VFS_JOB_DBUS (job);
  GVfsJobProgress *progress_job = G_VFS_JOB_PROGRESS (job);
  GError *error = NULL;

  if (!progress_job->send_progress)
    return;
  
  progress_job->progress_proxy = gvfs_dbus_progress_proxy_new_sync (g_dbus_method_invocation_get_connection (dbus_job->invocation),
                                                                    G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
                                                                    g_dbus_method_invocation_get_sender (dbus_job->invocation),
                                                                    progress_job->callback_obj_path,
                                                                    NULL,
                                                                    &error);
  if (!progress_job->progress_proxy)
    {
      g_warning ("g_vfs_job_progress_construct_proxy: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code);
      g_error_free (error);
    }
}
コード例 #18
0
static void
g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocation,
                                                GVariant              *parameters,
                                                GUnixFDList           *fd_list)
{
  GDBusMessage *reply;
  GError *error;

  g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
  g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));

  if (parameters == NULL)
    parameters = g_variant_new_tuple (NULL, 0);

  /* if we have introspection data, check that the signature of @parameters is correct */
  if (invocation->method_info != NULL)
    {
      GVariantType *type;

      type = _g_dbus_compute_complete_signature (invocation->method_info->out_args);

      if (!g_variant_is_of_type (parameters, type))
        {
          gchar *type_string = g_variant_type_dup_string (type);

          g_warning ("Type of return value is incorrect: expected '%s', got '%s''",
		     type_string, g_variant_get_type_string (parameters));
          g_variant_type_free (type);
          g_free (type_string);
          goto out;
        }
      g_variant_type_free (type);
    }

  /* property_info is only non-NULL if set that way from
   * GDBusConnection, so this must be the case of async property
   * handling on either 'Get', 'Set' or 'GetAll'.
   */
  if (invocation->property_info != NULL)
    {
      if (g_str_equal (invocation->method_name, "Get"))
        {
          GVariant *nested;

          if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(v)")))
            {
              g_warning ("Type of return value for property 'Get' call should be '(v)' but got '%s'",
                         g_variant_get_type_string (parameters));
              goto out;
            }

          /* Go deeper and make sure that the value inside of the
           * variant matches the property type.
           */
          g_variant_get (parameters, "(v)", &nested);
          if (!g_str_equal (g_variant_get_type_string (nested), invocation->property_info->signature))
            {
              g_warning ("Value returned from property 'Get' call for '%s' should be '%s' but is '%s'",
                         invocation->property_info->name, invocation->property_info->signature,
                         g_variant_get_type_string (nested));
              g_variant_unref (nested);
              goto out;
            }
          g_variant_unref (nested);
        }

      else if (g_str_equal (invocation->method_name, "GetAll"))
        {
          if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})")))
            {
              g_warning ("Type of return value for property 'GetAll' call should be '(a{sv})' but got '%s'",
                         g_variant_get_type_string (parameters));
              goto out;
            }

          /* Could iterate the list of properties and make sure that all
           * of them are actually on the interface and with the correct
           * types, but let's not do that for now...
           */
        }

      else if (g_str_equal (invocation->method_name, "Set"))
        {
          if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE_UNIT))
            {
              g_warning ("Type of return value for property 'Set' call should be '()' but got '%s'",
                         g_variant_get_type_string (parameters));
              goto out;
            }
        }

      else
        g_assert_not_reached ();
    }

  if (G_UNLIKELY (_g_dbus_debug_return ()))
    {
      _g_dbus_debug_print_lock ();
      g_print ("========================================================================\n"
               "GDBus-debug:Return:\n"
               " >>>> METHOD RETURN\n"
               "      in response to %s.%s()\n"
               "      on object %s\n"
               "      to name %s\n"
               "      reply-serial %d\n",
               invocation->interface_name, invocation->method_name,
               invocation->object_path,
               invocation->sender,
               g_dbus_message_get_serial (invocation->message));
      _g_dbus_debug_print_unlock ();
    }

  reply = g_dbus_message_new_method_reply (invocation->message);
  g_dbus_message_set_body (reply, parameters);

#ifdef G_OS_UNIX
  if (fd_list != NULL)
    g_dbus_message_set_unix_fd_list (reply, fd_list);
#endif

  error = NULL;
  if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error))
    {
      g_warning ("Error sending message: %s", error->message);
      g_error_free (error);
    }
  g_object_unref (reply);

 out:
  g_object_unref (invocation);
}
コード例 #19
0
static gboolean
handle_access_dialog (XdpImplAccess *object,
                      GDBusMethodInvocation *invocation,
                      const char *arg_handle,
                      const char *arg_app_id,
                      const char *arg_parent_window,
                      const char *arg_title,
                      const char *arg_subtitle,
                      const char *arg_body,
                      GVariant *arg_options)
{
  g_autoptr(Request) request = NULL;
  const char *sender;
  AccessDialogHandle *handle;
  g_autoptr(GError) error = NULL;
  g_autofree char *filename = NULL;
  gboolean modal;
  GtkWidget *dialog;
  GdkWindow *foreign_parent = NULL;
  const char *deny_label;
  const char *grant_label;
  const char *icon;
  g_autoptr(GVariant) choices = NULL;
  GtkWidget *area;
  GtkWidget *image;
  GHashTable *choice_table = NULL;

  sender = g_dbus_method_invocation_get_sender (invocation);

  request = request_new (sender, arg_app_id, arg_handle);

  if (!g_variant_lookup (arg_options, "modal", "b", &modal))
    modal = TRUE;

  if (!g_variant_lookup (arg_options, "deny_label", "&s", &deny_label))
    deny_label = _("Deny Access");

  if (!g_variant_lookup (arg_options, "grant_label", "&s", &grant_label))
    grant_label = _("Grant Access");

  if (!g_variant_lookup (arg_options, "icon", "&s", &icon))
    icon = NULL;

  choices = g_variant_lookup_value (arg_options, "choices", G_VARIANT_TYPE ("a(ssa(ss)s)"));

  dialog = gtk_message_dialog_new (NULL,
                                   0,
                                   GTK_MESSAGE_QUESTION,
                                   GTK_BUTTONS_NONE,
                                   arg_title,
                                   NULL);
  gtk_window_set_modal (GTK_WINDOW (dialog), modal);
  gtk_dialog_add_button (GTK_DIALOG (dialog), deny_label, GTK_RESPONSE_CANCEL);
  gtk_dialog_add_button (GTK_DIALOG (dialog), grant_label, GTK_RESPONSE_OK);
  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", arg_subtitle);

  area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog));
  fix_up_label_alignment (area);

  if (choices)
    {
      int i;

      choice_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
      for (i = 0; i < g_variant_n_children (choices); i++)
        add_choice (area, g_variant_get_child_value (choices, i), choice_table);
    }

  if (!g_str_equal (arg_body, ""))
    {
      GtkWidget *body_label;

      body_label = gtk_label_new (arg_body);
      gtk_widget_set_halign (body_label, GTK_ALIGN_START);
      g_object_set (body_label, "margin-top", 10, NULL);
      gtk_label_set_xalign (GTK_LABEL (body_label), 0);
      gtk_label_set_line_wrap (GTK_LABEL (body_label), TRUE);
      gtk_label_set_max_width_chars (GTK_LABEL (body_label), 50);
      gtk_widget_show (body_label);
      gtk_container_add (GTK_CONTAINER (area), body_label);
    }

  image = gtk_image_new_from_icon_name (icon ? icon : "image-missing", GTK_ICON_SIZE_DIALOG);
  gtk_widget_set_opacity (image, icon ? 1.0 : 0.0);
  gtk_widget_show (image);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
G_GNUC_END_IGNORE_DEPRECATIONS

#ifdef GDK_WINDOWING_X11
  if (g_str_has_prefix (arg_parent_window, "x11:"))
    {
      int xid;

      if (sscanf (arg_parent_window, "x11:%x", &xid) != 1)
        g_warning ("invalid xid");
      else
        foreign_parent = gdk_x11_window_foreign_new_for_display (gtk_widget_get_display (dialog), xid);
    }
#endif
  else
    g_warning ("Unhandled parent window type %s", arg_parent_window);

  handle = g_new0 (AccessDialogHandle, 1);
  handle->impl = object;
  handle->invocation = invocation;
  handle->request = g_object_ref (request);
  handle->dialog = g_object_ref (dialog);
  handle->choices = choice_table;

  g_signal_connect (request, "handle-close", G_CALLBACK (handle_close), handle);

  g_signal_connect (dialog, "response", G_CALLBACK (access_dialog_response), handle);

  gtk_widget_realize (dialog);

  if (foreign_parent)
    gdk_window_set_transient_for (gtk_widget_get_window (dialog), foreign_parent);

  gtk_widget_show (dialog);

  request_export (request, g_dbus_method_invocation_get_connection (invocation));

  return TRUE;
}
コード例 #20
0
static gboolean
handle_open_file (XdpFileChooser *object,
                  GDBusMethodInvocation *invocation,
                  const gchar *arg_parent_window,
                  const gchar *arg_title,
                  GVariant *arg_options)
{
  Request *request = request_from_invocation (invocation);
  const char *app_id = request->app_id;
  g_autoptr(GError) error = NULL;
  g_autoptr(XdpImplRequest) impl_request = NULL;
  GVariantBuilder options;
  g_autoptr(GVariant) value = NULL;

  REQUEST_AUTOLOCK (request);

  value = g_variant_lookup_value (arg_options, "filters", NULL);
  if (value != NULL)
    {
      if (!check_filters (value, &error))
        {
          g_prefix_error (&error, "invalid filters: ");
          g_dbus_method_invocation_return_gerror (invocation, error);
          return TRUE;
        }
      g_variant_unref (value);
      value = NULL;
    }
  value = g_variant_lookup_value (arg_options, "choices", NULL);
  if (value != NULL)
    {
      if (!check_choices (value, &error))
        {
          g_prefix_error (&error, "invalid choices: ");
          g_dbus_method_invocation_return_gerror (invocation, error);
          return TRUE;
        }
      g_variant_unref (value);
      value = NULL;
    }

  g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
  xdp_filter_options (arg_options, &options,
                      open_file_options, G_N_ELEMENTS (open_file_options));

  impl_request = xdp_impl_request_proxy_new_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (impl)),
                                                  G_DBUS_PROXY_FLAGS_NONE,
                                                  g_dbus_proxy_get_name (G_DBUS_PROXY (impl)),
                                                  request->id,
                                                  NULL, &error);
  if (!impl_request)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return TRUE;
    }

  request_set_impl_request (request, impl_request);
  request_export (request, g_dbus_method_invocation_get_connection (invocation));

  xdp_impl_file_chooser_call_open_file (impl,
                                        request->id,
                                        app_id,
                                        arg_parent_window,
                                        arg_title,
                                        g_variant_builder_end (&options),
                                        NULL,
                                        open_file_done,
                                        g_object_ref (request));

  xdp_file_chooser_complete_open_file (object, invocation, request->id);

  return TRUE;
}
コード例 #21
0
static gboolean
handle_screenshot (XdpImplScreenshot *object,
                   GDBusMethodInvocation *invocation,
                   const char *arg_handle,
                   const char *arg_app_id,
                   const char *arg_parent_window,
                   GVariant *arg_options)
{
  g_autoptr(Request) request = NULL;
  const char *sender;
  ScreenshotDialogHandle *handle;
  g_autoptr(GError) error = NULL;
  g_autofree char *filename = NULL;
  gboolean success;
  gboolean modal;
  GtkWidget *dialog;
  GdkDisplay *display;
  GdkScreen *screen;
  ExternalWindow *external_parent = NULL;
  GtkWidget *fake_parent;

  sender = g_dbus_method_invocation_get_sender (invocation);

  request = request_new (sender, arg_app_id, arg_handle);

  org_gnome_shell_screenshot_call_screenshot_sync (shell,
                                                   FALSE,
                                                   TRUE,
                                                   "Screenshot",
                                                   &success,
                                                   &filename,
                                                   NULL, NULL);

  if (!g_variant_lookup (arg_options, "modal", "b", &modal))
    modal = TRUE;

  if (arg_parent_window)
    {
      external_parent = create_external_window_from_handle (arg_parent_window);
      if (!external_parent)
        g_warning ("Failed to associate portal window with parent window %s",
                   arg_parent_window);
    }

  if (external_parent)
    display = external_window_get_display (external_parent);
  else
    display = gdk_display_get_default ();
  screen = gdk_display_get_default_screen (display);

  fake_parent = g_object_new (GTK_TYPE_WINDOW,
                              "type", GTK_WINDOW_TOPLEVEL,
                              "screen", screen,
                              NULL);
  g_object_ref_sink (fake_parent);

  dialog = GTK_WIDGET (screenshot_dialog_new (arg_app_id, filename));
  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fake_parent));
  gtk_window_set_modal (GTK_WINDOW (dialog), modal);

  handle = g_new0 (ScreenshotDialogHandle, 1);
  handle->impl = object;
  handle->invocation = invocation;
  handle->request = g_object_ref (request);
  handle->dialog = g_object_ref (dialog);
  handle->external_parent = external_parent;
  handle->uri = g_filename_to_uri (filename, NULL, NULL);

  g_signal_connect (request, "handle-close", G_CALLBACK (handle_close), handle);

  g_signal_connect (dialog, "done", G_CALLBACK (screenshot_dialog_done), handle);

  gtk_widget_realize (dialog);

  if (external_parent)
    external_window_set_parent_of (external_parent, gtk_widget_get_window (dialog));

  gtk_widget_show (dialog);

  request_export (request, g_dbus_method_invocation_get_connection (invocation));

  return TRUE;
}
コード例 #22
0
/**
 * g_dbus_method_invocation_return_value:
 * @invocation: A #GDBusMethodInvocation.
 * @parameters: A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters.
 *
 * Finishes handling a D-Bus method call by returning @parameters.
 * If the @parameters GVariant is floating, it is consumed.
 *
 * It is an error if @parameters is not of the right format.
 *
 * This method will free @invocation, you cannot use it afterwards.
 *
 * Since: 2.26
 */
void
g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
                                       GVariant              *parameters)
{
  GDBusMessage *reply;
  GError *error;

  g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
  g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));

  if (parameters == NULL)
    parameters = g_variant_new_tuple (NULL, 0);

  /* if we have introspection data, check that the signature of @parameters is correct */
  if (invocation->method_info != NULL)
    {
      GVariantType *type;

      type = _g_dbus_compute_complete_signature (invocation->method_info->out_args);

      if (!g_variant_is_of_type (parameters, type))
        {
          gchar *type_string = g_variant_type_dup_string (type);

          g_warning (_("Type of return value is incorrect, got `%s', expected `%s'"),
                     g_variant_get_type_string (parameters), type_string);
          g_variant_type_free (type);
          g_free (type_string);
          goto out;
        }
      g_variant_type_free (type);
    }

  if (G_UNLIKELY (_g_dbus_debug_return ()))
    {
      _g_dbus_debug_print_lock ();
      g_print ("========================================================================\n"
               "GDBus-debug:Return:\n"
               " >>>> METHOD RETURN\n"
               "      in response to %s.%s()\n"
               "      on object %s\n"
               "      to name %s\n"
               "      reply-serial %d\n",
               invocation->interface_name, invocation->method_name,
               invocation->object_path,
               invocation->sender,
               g_dbus_message_get_serial (invocation->message));
      _g_dbus_debug_print_unlock ();
    }

  reply = g_dbus_message_new_method_reply (invocation->message);
  g_dbus_message_set_body (reply, parameters);
  error = NULL;
  if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error))
    {
      g_warning (_("Error sending message: %s"), error->message);
      g_error_free (error);
    }
  g_object_unref (reply);

 out:
  g_object_unref (invocation);
}
コード例 #23
0
static gboolean
handle_choose_application (XdpImplAppChooser *object,
                           GDBusMethodInvocation *invocation,
                           const char *arg_handle,
                           const char *arg_app_id,
                           const char *arg_parent_window,
                           const char **choices,
                           GVariant *arg_options)
{
  g_autoptr(Request) request = NULL;
  GtkWidget *dialog;
  AppDialogHandle *handle;
  const char *sender;
  const char *latest_chosen_id;
  const char *content_type;
  const char *location;
  gboolean modal;
  GdkDisplay *display;
  GdkScreen *screen;
  ExternalWindow *external_parent = NULL;
  GtkWidget *fake_parent;

  sender = g_dbus_method_invocation_get_sender (invocation);

  request = request_new (sender, arg_app_id, arg_handle);

  if (!g_variant_lookup (arg_options, "last_choice", "&s", &latest_chosen_id))
    latest_chosen_id = NULL;
  if (!g_variant_lookup (arg_options, "modal", "b", &modal))
    modal = TRUE;
  if (!g_variant_lookup (arg_options, "content_type", "&s", &content_type))
    content_type = NULL;
  if (!g_variant_lookup (arg_options, "filename", "&s", &location) &&
      !g_variant_lookup (arg_options, "uri", "&s", &location))
    location = NULL;

  if (arg_parent_window)
    {
      external_parent = create_external_window_from_handle (arg_parent_window);
      if (!external_parent)
        g_warning ("Failed to associate portal window with parent window %s",
                   arg_parent_window);
    }

  if (external_parent)
    display = external_window_get_display (external_parent);
  else
    display = gdk_display_get_default ();
  screen = gdk_display_get_default_screen (display);

  fake_parent = g_object_new (GTK_TYPE_WINDOW,
                              "type", GTK_WINDOW_TOPLEVEL,
                              "screen", screen,
                              NULL);
  g_object_ref_sink (fake_parent);

  dialog = GTK_WIDGET (app_chooser_dialog_new (choices, latest_chosen_id, content_type, location));
  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fake_parent));

  gtk_window_set_modal (GTK_WINDOW (dialog), modal);

  handle = g_new0 (AppDialogHandle, 1);
  handle->impl = object;
  handle->invocation = invocation;
  handle->request = g_object_ref (request);
  handle->dialog = g_object_ref (dialog);
  handle->external_parent = external_parent;

  g_hash_table_insert (handles, handle->request->id, handle);

  g_signal_connect (request, "handle-close",
                    G_CALLBACK (handle_close), handle);

  g_signal_connect (dialog, "close",
                    G_CALLBACK (handle_app_chooser_close), handle);

  gtk_widget_realize (dialog);

  if (external_parent)
    external_window_set_parent_of (external_parent, gtk_widget_get_window (dialog));

  gtk_window_present (GTK_WINDOW (dialog));

  request_export (request, g_dbus_method_invocation_get_connection (invocation));

  return TRUE;
}
コード例 #24
0
static gboolean
handle_get_user_information (XdpImplAccount *object,
                             GDBusMethodInvocation *invocation,
                             const char *arg_handle,
                             const char *arg_app_id,
                             const char *arg_parent_window,
                             GVariant *arg_options)
{
  g_autoptr(Request) request = NULL;
  const char *sender;
  AccountDialogHandle *handle;
  g_autoptr(GError) error = NULL;
  const char *user_name;
  const char *real_name;
  const char *icon_file;
  GtkWidget *dialog;
  GdkDisplay *display;
  GdkScreen *screen;
  ExternalWindow *external_parent = NULL;
  GtkWidget *fake_parent;
  const char *reason;

  sender = g_dbus_method_invocation_get_sender (invocation);

  request = request_new (sender, arg_app_id, arg_handle);

  user_name = org_freedesktop_accounts_user_get_user_name (user);
  real_name = org_freedesktop_accounts_user_get_real_name (user);
  icon_file = org_freedesktop_accounts_user_get_icon_file (user);

  if (!g_variant_lookup (arg_options, "reason", "&s", &reason))
    reason = NULL;

  if (arg_parent_window)
    {
      external_parent = create_external_window_from_handle (arg_parent_window);
      if (!external_parent)
        g_warning ("Failed to associate portal window with parent window %s",
                   arg_parent_window);
    }

  if (external_parent)
    display = external_window_get_display (external_parent);
  else
    display = gdk_display_get_default ();
  screen = gdk_display_get_default_screen (display);

  fake_parent = g_object_new (GTK_TYPE_WINDOW,
                              "type", GTK_WINDOW_TOPLEVEL,
                              "screen", screen,
                              NULL);
  g_object_ref_sink (fake_parent);

  dialog = GTK_WIDGET (account_dialog_new (arg_app_id, user_name, real_name, icon_file, reason));
  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fake_parent));
  gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);

  handle = g_new0 (AccountDialogHandle, 1);
  handle->impl = object;
  handle->invocation = invocation;
  handle->request = g_object_ref (request);
  handle->dialog = g_object_ref (dialog);
  handle->external_parent = external_parent;
  handle->user_name = g_strdup (user_name);
  handle->real_name = g_strdup (real_name);
  handle->icon_uri = g_filename_to_uri (icon_file, NULL, NULL);

  g_signal_connect (request, "handle-close", G_CALLBACK (handle_close), handle);

  g_signal_connect (dialog, "done", G_CALLBACK (account_dialog_done), handle);

  gtk_widget_realize (dialog);

  if (external_parent)
    external_window_set_parent_of (external_parent, gtk_widget_get_window (dialog));

  gtk_widget_show (dialog);

  request_export (request, g_dbus_method_invocation_get_connection (invocation));

  return TRUE;
}
コード例 #25
0
ファイル: udisksdaemonutil.c プロジェクト: jprvita/udisks
/**
 * udisks_daemon_util_get_caller_uid_sync:
 * @daemon: A #UDisksDaemon.
 * @invocation: A #GDBusMethodInvocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @out_uid: (out): Return location for resolved uid or %NULL.
 * @out_gid: (out) (allow-none): Return location for resolved gid or %NULL.
 * @out_user_name: (out) (allow-none): Return location for resolved user name or %NULL.
 * @error: Return location for error.
 *
 * Gets the UNIX user id (and possibly group id and user name) of the
 * peer represented by @invocation.
 *
 * Returns: %TRUE if the user id (and possibly group id) was obtained, %FALSE otherwise
 */
gboolean
udisks_daemon_util_get_caller_uid_sync (UDisksDaemon            *daemon,
                                        GDBusMethodInvocation   *invocation,
                                        GCancellable            *cancellable,
                                        uid_t                   *out_uid,
                                        gid_t                   *out_gid,
                                        gchar                  **out_user_name,
                                        GError                 **error)
{
  gboolean ret;
  const gchar *caller;
  GVariant *value;
  GError *local_error;
  uid_t uid;

  /* TODO: cache this on @daemon */

  ret = FALSE;

  caller = g_dbus_method_invocation_get_sender (invocation);

  local_error = NULL;
  value = g_dbus_connection_call_sync (g_dbus_method_invocation_get_connection (invocation),
                                       "org.freedesktop.DBus",  /* bus name */
                                       "/org/freedesktop/DBus", /* object path */
                                       "org.freedesktop.DBus",  /* interface */
                                       "GetConnectionUnixUser", /* method */
                                       g_variant_new ("(s)", caller),
                                       G_VARIANT_TYPE ("(u)"),
                                       G_DBUS_CALL_FLAGS_NONE,
                                       -1, /* timeout_msec */
                                       cancellable,
                                       &local_error);
  if (value == NULL)
    {
      g_set_error (error,
                   UDISKS_ERROR,
                   UDISKS_ERROR_FAILED,
                   "Error determining uid of caller %s: %s (%s, %d)",
                   caller,
                   local_error->message,
                   g_quark_to_string (local_error->domain),
                   local_error->code);
      g_error_free (local_error);
      goto out;
    }

  {
    G_STATIC_ASSERT (sizeof (uid_t) == sizeof (guint32));
  }

  g_variant_get (value, "(u)", &uid);
  if (out_uid != NULL)
    *out_uid = uid;

  if (out_gid != NULL || out_user_name != NULL)
    {
      struct passwd pwstruct;
      gchar pwbuf[8192];
      struct passwd *pw = NULL;
      int rc;

      rc = getpwuid_r (uid, &pwstruct, pwbuf, sizeof pwbuf, &pw);
      if (rc == 0 && pw == NULL)
        {
          g_set_error (error,
                       UDISKS_ERROR,
                       UDISKS_ERROR_FAILED,
                       "User with uid %d does not exist", (gint) uid);
          goto out;
        }
      else if (pw == NULL)
        {
          g_set_error (error,
                       UDISKS_ERROR,
                       UDISKS_ERROR_FAILED,
                       "Error looking up passwd struct for uid %d: %m", (gint) uid);
          goto out;
        }
      if (out_gid != NULL)
        *out_gid = pw->pw_gid;
      if (out_user_name != NULL)
        *out_user_name = g_strdup (pwstruct.pw_name);
    }

  ret = TRUE;

 out:
  return ret;
}
コード例 #26
0
ファイル: timedatex.c プロジェクト: AdamWill/timedatex
static void finish_set_rtc_local_hwclock(GDBusMethodInvocation *invocation, struct method_call_data *data) {
	emit_property_change(g_dbus_method_invocation_get_connection(invocation),
			     "LocalRTC", g_variant_new_boolean(data->set_rtc_local.local));
	return_success(invocation);
}
コード例 #27
0
static int _icd_cynara_check(GDBusMethodInvocation *invocation, const char **privileges)
{
#ifdef TZ_VER_3
	FN_CALL;
	int i = 0;
	int ret;
	pid_t pid;
	char *user = NULL;
	char *client = NULL;
	char *session = NULL;
	const char *sender = NULL;
	GDBusConnection *conn = NULL;

	RETV_IF(NULL == _cynara, IOTCON_ERROR_SYSTEM);
	RETV_IF(NULL == invocation, IOTCON_ERROR_INVALID_PARAMETER);
	RETV_IF(NULL == privileges, IOTCON_ERROR_INVALID_PARAMETER);

	conn = g_dbus_method_invocation_get_connection(invocation);
	if (NULL == conn) {
		ERR("g_dbus_method_invocation_get_connection() return NULL");
		return IOTCON_ERROR_SYSTEM;
	}

	sender = g_dbus_method_invocation_get_sender(invocation);
	if (NULL == sender) {
		ERR("g_dbus_method_invocation_get_sender() return NULL");
		return IOTCON_ERROR_SYSTEM;
	}

	ret = cynara_creds_gdbus_get_client(conn, sender, CLIENT_METHOD_SMACK, &client);
	if (CYNARA_API_SUCCESS != ret) {
		ERR("cynara_creds_dbus_get_client() Fail(%d)", ret);
		return IOTCON_ERROR_SYSTEM;
	}

	ret = cynara_creds_gdbus_get_user(conn, sender, USER_METHOD_UID, &user);
	if (CYNARA_API_SUCCESS != ret) {
		ERR("cynara_creds_dbus_get_user() Fail(%d)", ret);
		free(client);
		return IOTCON_ERROR_SYSTEM;
	}

	ret = cynara_creds_gdbus_get_pid(conn, sender, &pid);
	if (CYNARA_API_SUCCESS != ret) {
		ERR("cynara_creds_gdbus_get_pid() Fail(%d)", ret);
		free(user);
		free(client);
		return IOTCON_ERROR_SYSTEM;
	}

	session = cynara_session_from_pid(pid);
	if (NULL == session) {
		ERR("cynara_session_from_pid() return NULL");
		free(user);
		free(client);
		return IOTCON_ERROR_SYSTEM;
	}

	while (privileges[i]) {
		SECURE_DBG("privileges[%d]: %s, user: %s, client: %s", i, privileges[i], user, client);
		ret = cynara_check(_cynara, client, session, user, privileges[i]);
		if (CYNARA_API_ACCESS_DENIED == ret) {
			ERR("Denied (%s)", privileges[i]);
			free(session);
			free(user);
			free(client);
			return IOTCON_ERROR_PERMISSION_DENIED;
		} else if (CYNARA_API_ACCESS_ALLOWED != ret) {
			ERR("cynara_check(%s) Fail(%d)", privileges[i], ret);
			free(session);
			free(user);
			free(client);
			return IOTCON_ERROR_SYSTEM;
		}
		i++;
	}
	free(session);
	free(user);
	free(client);
#endif
	return IOTCON_ERROR_NONE;
}
コード例 #28
0
gboolean
mail_send_short_message (EGdbusSession *object,
		GDBusMethodInvocation *invocation, const char *account_uid,
		const char *text, const char **to,
		EMailDataSession *msession, GError **ret_error)
{
	EAccount *account;
	CamelMimeMessage *message;
	CamelService *service;
	gchar *transport_uid;
	CamelInternetAddress *recipients;
	CamelMessageInfo *info;
	GSimpleAsyncResult *simple;
	SendAsyncContext *context;
	CamelInternetAddress *from;
	GCancellable *ops;
	EMailDataOperation *mops;
	char *mops_path;
	gchar subject[MAX_SUBJECT_LENGTH + 4];
	GError *error = NULL;

	/* Check params. */

	if (account_uid == NULL || *account_uid == 0) {
		error = g_error_new (G_DBUS_ERROR,
						G_DBUS_ERROR_INVALID_ARGS,
						_("Invalid account"));
		goto on_error;
	}
	if (text == NULL || *text == 0) {
		error = g_error_new (G_DBUS_ERROR,
						G_DBUS_ERROR_INVALID_ARGS,
						_("Text is empty"));
		goto on_error;
	}
	if (to == NULL || *to == 0 || **to == 0) {
		error = g_error_new (G_DBUS_ERROR,
						G_DBUS_ERROR_INVALID_ARGS,
						_("No recipient"));
		goto on_error;
	}

	/* Get transport. */

	account = e_get_account_by_uid (account_uid);
	if (!account) {
		error = g_error_new (G_DBUS_ERROR,
						G_DBUS_ERROR_INVALID_ARGS,
						_("Invalid account %s"),
						account_uid);
		goto on_error;
	}

	transport_uid = g_strconcat (account->uid, "-transport", NULL);
	service = camel_session_ref_service (CAMEL_SESSION (session),
								transport_uid);
	if (!CAMEL_IS_TRANSPORT (service)) {
		error = g_error_new(G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
					_("Invalid account %s"), account_uid);
		g_object_unref (account);
		g_free (transport_uid);
		goto on_error;
	}

	/* Prepare message. */

	message = camel_mime_message_new ();
	strncpy (subject, text, MAX_SUBJECT_LENGTH + 1);
	if (strlen(text) > MAX_SUBJECT_LENGTH)
		strcpy (subject + MAX_SUBJECT_LENGTH, "...");
	camel_mime_message_set_subject (message, subject);
	from = camel_internet_address_new ();
	camel_internet_address_add (from, NULL, "sms");
	recipients = camel_internet_address_new ();
	while (*to) {
		camel_internet_address_add (recipients, NULL, *to);
		to++;
	}
	camel_mime_message_set_from (message, from);
	camel_mime_message_set_recipients (message, CAMEL_RECIPIENT_TYPE_TO,
								recipients);
	camel_mime_message_set_date (message, CAMEL_MESSAGE_DATE_CURRENT, 0);
	camel_mime_part_set_content_type (CAMEL_MIME_PART(message),
								"text/plain");
	camel_mime_part_set_content (CAMEL_MIME_PART(message), text,
						strlen(text), "text/plain");

	info = camel_message_info_new (NULL);
	camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0);

	/* Return the new operation */

	ops = camel_operation_new ();
	mops = e_mail_data_operation_new ((CamelOperation *) ops);

	mops_path = e_mail_data_operation_register_gdbus_object (mops,
			g_dbus_method_invocation_get_connection(invocation),
			NULL);
	egdbus_session_complete_send_short_message (object, invocation,
								mops_path);

	/* The rest of the processing happens in a thread. */

	context = g_slice_new0 (SendAsyncContext);
	context->message = message;
	context->io_priority = G_PRIORITY_DEFAULT;
	context->from = CAMEL_ADDRESS (from);
	context->recipients = CAMEL_ADDRESS (recipients);
	context->info = info;
	context->transport = service;
	context->sent_folder_uri = g_strdup (account->sent_folder_uri);
	context->cancellable = ops;
	context->ops_path = mops_path;
	context->result = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);

	/* Failure here emits a runtime warning but is non-fatal. */
	context->driver = camel_session_get_filter_driver (
				CAMEL_SESSION (session), "outgoing", &error);
	if (error != NULL) {
		g_warn_if_fail (context->driver == NULL);
		g_warning ("%s", error->message);
		g_error_free (error);
	}

	/* This gets popped in async_context_free(). */
	camel_operation_push_message (context->cancellable,
							_("Sending message"));

	simple = g_simple_async_result_new (
			G_OBJECT (session), mail_send_short_message_completed,
			context, mail_send_short_message);

	g_simple_async_result_set_op_res_gpointer (
			simple, context, (GDestroyNotify) async_context_free);

	g_simple_async_result_run_in_thread (
			simple,
			(GSimpleAsyncThreadFunc) mail_send_short_to_thread,
			context->io_priority, context->cancellable);

	g_object_unref (simple);

	return TRUE;

on_error:

	*ret_error = error;

	return FALSE;
}
コード例 #29
0
static gboolean
impl_CalFactory_get_cal (EGdbusCalFactory *object,
                         GDBusMethodInvocation *invocation,
                         const gchar * const *in_source_type,
                         EDataCalFactory *factory)
{
	EDataCal *calendar;
	EBackend *backend;
	EDataCalFactoryPrivate *priv = factory->priv;
	GDBusConnection *connection;
	ESource *source;
	gchar *uri;
	gchar *path = NULL;
	const gchar *sender;
	GList *list;
	GError *error = NULL;
	gchar *source_xml = NULL;
	guint type = 0;

	sender = g_dbus_method_invocation_get_sender (invocation);
	connection = g_dbus_method_invocation_get_connection (invocation);

	if (!e_gdbus_cal_factory_decode_get_cal (in_source_type, &source_xml, &type)) {
		error = g_error_new (
			E_DATA_CAL_ERROR, NoSuchCal, _("Invalid call"));
		g_dbus_method_invocation_return_gerror (invocation, error);
		g_error_free (error);

		return TRUE;
	}

	source = e_source_new_from_standalone_xml (source_xml);
	g_free (source_xml);

	if (!source) {
		error = g_error_new (
			E_DATA_CAL_ERROR,
			NoSuchCal,
			_("Invalid source"));
		g_dbus_method_invocation_return_gerror (invocation, error);
		g_error_free (error);

		return TRUE;
	}

	uri = e_source_get_uri (source);

	if (uri == NULL || *uri == '\0') {
		g_object_unref (source);
		g_free (uri);

		error = g_error_new (
			E_DATA_CAL_ERROR,
			NoSuchCal,
			_("Empty URI"));
		g_dbus_method_invocation_return_gerror (invocation, error);
		g_error_free (error);

		return TRUE;
	}

	backend = e_data_cal_factory_get_backend (factory, source, uri, type);

	if (backend == NULL) {
		error = g_error_new (
			E_DATA_CAL_ERROR,
			NoSuchCal,
			_("Invalid source"));
		g_dbus_method_invocation_return_gerror (invocation, error);
		g_error_free (error);

		return TRUE;
	}

	g_mutex_lock (priv->calendars_lock);

	e_dbus_server_hold (E_DBUS_SERVER (factory));

	path = construct_cal_factory_path ();
	calendar = e_data_cal_new (E_CAL_BACKEND (backend));
	g_hash_table_insert (priv->calendars, g_strdup (path), calendar);
	e_cal_backend_add_client (E_CAL_BACKEND (backend), calendar);
	e_data_cal_register_gdbus_object (calendar, connection, path, &error);
	g_object_weak_ref (
		G_OBJECT (calendar), (GWeakNotify)
		calendar_freed_cb, factory);

	/* Update the hash of open connections. */
	g_mutex_lock (priv->connections_lock);
	list = g_hash_table_lookup (priv->connections, sender);
	list = g_list_prepend (list, calendar);
	g_hash_table_insert (priv->connections, g_strdup (sender), list);
	g_mutex_unlock (priv->connections_lock);

	g_mutex_unlock (priv->calendars_lock);

	g_object_unref (source);
	g_free (uri);

	e_gdbus_cal_factory_complete_get_cal (
		object, invocation, path, error);

	if (error)
		g_error_free (error);

	g_free (path);

	return TRUE;
}