Esempio n. 1
0
void
storage_invocation_initialize (GDBusConnection *connection,
                               StorageClientFunc client_appeared,
                               StorageClientFunc client_disappeared,
                               gpointer user_data)
{
  GObjectClass *object_class;
  GError *error = NULL;

  inv.client_appeared = client_appeared;
  inv.client_disappeared = client_disappeared;
  inv.client_user_data = user_data;

  inv.dbus_interface_skeleton_class = g_type_class_ref (G_TYPE_DBUS_INTERFACE_SKELETON);

  object_class = G_OBJECT_CLASS (inv.dbus_interface_skeleton_class);
  inv.overridden_constructor = object_class->constructor;
  object_class->constructor = hook_dbus_interface_skeleton_constructor;

  inv.clients = g_hash_table_new_full (g_str_hash, g_str_equal,
                                       NULL, invocation_client_unref);

  g_dbus_connection_add_filter (connection, on_connection_filter, NULL, NULL);

  inv.authority = polkit_authority_get_sync (NULL, &error);
  if (error != NULL)
    {
      g_warning ("Couldn't connect to polkit: %s", error->message);
      g_error_free (error);
    }
}
Esempio n. 2
0
static void
storage_daemon_constructed (GObject *object)
{
  StorageDaemon *self = STORAGE_DAEMON (object);
  GError *error;

  G_OBJECT_CLASS (storage_daemon_parent_class)->constructed (object);

  storage_invocation_initialize (self->connection,
                            on_client_appeared,
                            on_client_disappeared,
                            self);

  error = NULL;
  self->authority = polkit_authority_get_sync (NULL, &error);
  if (self->authority == NULL)
    {
      g_warning ("Error initializing polkit authority: %s (%s, %d)",
                 error->message, g_quark_to_string (error->domain), error->code);
      g_error_free (error);
    }

  /* Yes, we use the same paths as the main udisks daemon on purpose */
  self->object_manager = g_dbus_object_manager_server_new ("/org/freedesktop/UDisks2");

  /* Export the ObjectManager */
  g_dbus_object_manager_server_set_connection (self->object_manager, self->connection);

  storage_manager_new_async (on_manager_ready, self);
}
Esempio n. 3
0
static gboolean
register_mechanism (GConfDefaults *mechanism)
{
        GError *error = NULL;

        mechanism->priv->auth = polkit_authority_get_sync (NULL, NULL);

        error = NULL;
        mechanism->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
        if (mechanism->priv->system_bus_connection == NULL) {
                if (error != NULL) {
                        g_critical ("error getting system bus: %s", error->message);
                        g_error_free (error);
                }
                goto error;
        }

        dbus_g_connection_register_g_object (mechanism->priv->system_bus_connection, "/",
                                             G_OBJECT (mechanism));

        mechanism->priv->system_bus_proxy = dbus_g_proxy_new_for_name (mechanism->priv->system_bus_connection,
                                                                      DBUS_SERVICE_DBUS,
                                                                      DBUS_PATH_DBUS,
                                                                      DBUS_INTERFACE_DBUS);

        start_killtimer ();

        return TRUE;

error:
        return FALSE;
}
/*
 * This handler is run in a separate thread, so all operations can be
 * synchronous.
 */
static gboolean
on_authorize_method_check (GDBusInterfaceSkeleton *interface,
                           GDBusMethodInvocation  *invocation,
                           EmerDaemon             *daemon)
{
  const gchar *method_name =
    g_dbus_method_invocation_get_method_name (invocation);
  const AuthorizedMethod *authorized_method = lookup_authorized_method (method_name);

  if (authorized_method == NULL)
    return TRUE;

  GError *error = NULL;
  PolkitAuthority *authority =
    polkit_authority_get_sync (NULL /*GCancellable*/, &error);
  if (authority == NULL)
    {
      g_critical ("Could not get PolicyKit authority: %s.", error->message);
      g_dbus_method_invocation_return_gerror (invocation, error);
      g_error_free (error);
      return FALSE;
    }

  const gchar *sender_name = g_dbus_method_invocation_get_sender (invocation);
  PolkitSubject *subject = polkit_system_bus_name_new (sender_name);

  PolkitAuthorizationResult *result =
    polkit_authority_check_authorization_sync (authority,
                                               subject,
                                               authorized_method->method_full_name,
                                               NULL /*PolkitDetails*/,
                                               POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
                                               NULL /*GCancellable*/,
                                               &error);
  g_object_unref (authority);
  g_object_unref (subject);
  if (result == NULL)
    {
      g_critical ("Could not get PolicyKit authorization result: %s.",
                  error->message);
      g_dbus_method_invocation_return_gerror (invocation, error);
      g_error_free (error);
      return FALSE;
    }

  gboolean authorized = polkit_authorization_result_get_is_authorized (result);
  if (!authorized)
    g_dbus_method_invocation_return_error_literal (invocation,
                                                   G_DBUS_ERROR,
                                                   G_DBUS_ERROR_AUTH_FAILED,
                                                   authorized_method->error_message);

  g_object_unref (result);
  return authorized;
}
Esempio n. 5
0
static PolkitResult do_check(PolkitSubject *subject, const char *action_id)
{
    PolkitAuthority *authority;
    PolkitAuthorizationResult *auth_result;
    PolkitResult result = PolkitNo;
    GError *error = NULL;
    GCancellable * cancellable;

    cancellable = g_cancellable_new();

    /* we ignore the error for now .. */
    authority = polkit_authority_get_sync(cancellable, NULL);

    guint cancel_timeout = g_timeout_add(POLKIT_TIMEOUT * 1000,
                   (GSourceFunc) do_cancel,
                   cancellable);

    auth_result = polkit_authority_check_authorization_sync(authority,
                subject,
                action_id,
                NULL,
                POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
                cancellable,
                &error);
    g_object_unref(cancellable);
    g_object_unref(authority);
    g_source_remove(cancel_timeout);
    g_object_unref(subject);
    if (error)
    {
        g_error_free(error);
        return PolkitUnknown;
    }

    if (!auth_result)
        return PolkitUnknown;

    if (polkit_authorization_result_get_is_challenge(auth_result))
    {
        /* Can't happen (happens only with
         * POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE flag) */
        result = PolkitChallenge;
        goto out;
    }

    if (polkit_authorization_result_get_is_authorized(auth_result))
    {
        result = PolkitYes;
        goto out;
    }

out:
    g_object_unref(auth_result);
    return result;
}
static void fprint_device_init(FprintDevice *device)
{
	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(device);
	priv->id = ++last_id;

	/* Setup PolicyKit */
	priv->auth = polkit_authority_get_sync (NULL, NULL);
	priv->clients = g_hash_table_new_full (g_str_hash,
					       g_str_equal,
					       g_free,
					       NULL);
}
Esempio n. 7
0
static PolkitAuthority *
pk_authority_get (GError **error)
{
	static PolkitAuthority *authority = NULL;

	if (authority == NULL)
		authority = polkit_authority_get_sync (NULL, error);

	/* Yes, ref every time; we want to keep the object alive */
	g_warn_if_fail (authority);
	return authority ? g_object_ref (authority) : NULL;
}
int main(void)
{
    pid_t parent_pid;
    GInputStream *stdin_unix_stream;

  /* Nuke the environment to get a well-known and sanitized
   * environment to avoid attacks via e.g. the DBUS_SYSTEM_BUS_ADDRESS
   * environment variable and similar.
   */
    if (clearenv () != 0) {
        FATAL_ERROR("Error clearing environment: %s\n", g_strerror (errno));
        return 1;
    }

#if !GLIB_CHECK_VERSION(2,36,0)
    g_type_init();
#endif

    loop = g_main_loop_new(NULL, FALSE);

    authority = polkit_authority_get_sync(NULL, NULL);
    parent_pid = getppid ();
    if (parent_pid == 1) {
            FATAL_ERROR("Parent process was reaped by init(1)\n");
            return 1;
    }
    /* Do what pkexec does */
    subject = polkit_unix_process_new_for_owner(parent_pid, 0, getuid ());

    stdin_unix_stream = g_unix_input_stream_new(STDIN_FILENO, 0);
    stdin_stream = g_data_input_stream_new(stdin_unix_stream);
    g_data_input_stream_set_newline_type(stdin_stream,
                                         G_DATA_STREAM_NEWLINE_TYPE_LF);
    g_clear_object(&stdin_unix_stream);
    g_data_input_stream_read_line_async(stdin_stream, G_PRIORITY_DEFAULT, NULL,
                                        stdin_read_complete, NULL);

    g_main_loop_run(loop);

    if (polkit_cancellable)
        g_clear_object(&polkit_cancellable);
    g_object_unref(stdin_stream);
    g_object_unref(authority);
    g_object_unref(subject);
    g_main_loop_unref(loop);

    return exit_status;
}
static void
mm_auth_provider_polkit_init (MMAuthProviderPolkit *self)
{
    GError *error = NULL;

    self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
                                              MM_TYPE_AUTH_PROVIDER_POLKIT,
                                              MMAuthProviderPolkitPrivate);

    self->priv->authority = polkit_authority_get_sync (NULL, &error);
    if (!self->priv->authority) {
        /* NOTE: we failed to create the polkit authority, but we still create
         * our AuthProvider. Every request will fail, though. */
        mm_warn ("failed to create PolicyKit authority: '%s'",
                 error ? error->message : "unknown");
		g_clear_error (&error);
    }
}
Esempio n. 10
0
/**
 * on_bus_acquired:
 */
static void
on_bus_acquired (GDBusConnection *connection, const gchar *name, LiHelperDaemon *helper)
{
	LiProxyObjectSkeleton *object;
	LiProxyManager *mgr_bus;
	GError *error = NULL;

	g_print ("Acquired a message bus connection\n");

	helper->authority = polkit_authority_get_sync (NULL, &error);
	g_assert_no_error (error); /* TODO: Meh... Needs smart error handling. */

	helper->obj_manager = g_dbus_object_manager_server_new ("/org/freedesktop/Limba");

	/* create the Manager object */
	object = li_proxy_object_skeleton_new ("/org/freedesktop/Limba/Manager");

	mgr_bus = li_proxy_manager_skeleton_new ();
	li_proxy_object_skeleton_set_manager (object, mgr_bus);
	g_object_unref (mgr_bus);

	g_signal_connect (mgr_bus,
			"handle-remove-software",
			G_CALLBACK (bus_manager_remove_software_cb),
			helper);

	g_signal_connect (mgr_bus,
			"handle-install-local",
			G_CALLBACK (bus_installer_install_local_cb),
			helper);

	g_signal_connect (mgr_bus,
			"handle-install",
			G_CALLBACK (bus_installer_install_cb),
			helper);

	/* export the object */
	g_dbus_object_manager_server_export (helper->obj_manager, G_DBUS_OBJECT_SKELETON (object));
	g_object_unref (object);

	g_dbus_object_manager_server_set_connection (helper->obj_manager, connection);
}
static gboolean
register_accounts_daemon (Daemon *daemon)
{
        GError *error = NULL;

        daemon->priv->authority = polkit_authority_get_sync (NULL, &error);

        if (daemon->priv->authority == NULL) {
                if (error != NULL) {
                        g_critical ("error getting polkit authority: %s", error->message);
                        g_error_free (error);
                }
                goto error;
        }

        daemon->priv->bus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
        if (daemon->priv->bus_connection == NULL) {
                if (error != NULL) {
                        g_critical ("error getting system bus: %s", error->message);
                        g_error_free (error);
                }
                goto error;
        }

        if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (daemon),
                                               daemon->priv->bus_connection,
                                               "/org/freedesktop/Accounts",
                                               &error)) {
                if (error != NULL) {
                        g_critical ("error exporting interface: %s", error->message);
                        g_error_free (error);
                }
                goto error;     
        }

        return TRUE;

 error:
        return FALSE;
}
Esempio n. 12
0
static gboolean
send_dbus_message (const char *cookie,
                   uid_t uid)
{
  PolkitAuthority *authority = NULL;
  PolkitIdentity *identity = NULL;
  GError *error = NULL;
  gboolean ret;

  ret = FALSE;

  g_type_init ();

  authority = polkit_authority_get_sync (NULL, &error);
  if (!authority)
    {
      warnx ("couldn't contact polkit authority: %s", error->message);
      goto out;
    }

  identity = polkit_unix_user_new (uid);
  if (!polkit_authority_authentication_agent_response_sync (authority, cookie,
                                                            identity, NULL, &error))
    {
      warnx ("couldn't respond to polkit daemon: %s", error->message);
      goto out;
    }

  ret = TRUE;

out:
  g_clear_error (&error);
  if (authority)
    g_object_unref (authority);
  if (identity)
    g_object_unref (identity);
  return ret;
}
Esempio n. 13
0
gpointer
cockpit_polkit_agent_register (CockpitTransport *transport,
                               GCancellable *cancellable)
{
  PolkitAgentListener *listener = NULL;
  PolkitAuthority *authority = NULL;
  PolkitSubject *subject = NULL;
  GVariant *options;
  GLogLevelFlags fatal;
  GError *error = NULL;
  gpointer handle = NULL;
  guint handler = 0;
  gchar *string;

  authority = polkit_authority_get_sync (cancellable, &error);
  if (authority == NULL)
    {
      g_message ("couldn't get polkit authority: %s", error->message);
      goto out;
    }

  subject = polkit_unix_session_new_for_process_sync (getpid (), cancellable, &error);
  if (subject == NULL)
    {
      /*
       * This can happen if there's a race between the polkit request and closing of
       * Cockpit. So it's not unheard of. We can complain, but not too loudly.
       */
      g_message ("couldn't create polkit session subject: %s", error->message);
      goto out;
    }

  listener = g_object_new (COCKPIT_TYPE_POLKIT_AGENT,
                           "transport", transport,
                           NULL);
  options = NULL;

  /*
   * HACK: Work around polkitagent warning:
   *
   * https://bugs.freedesktop.org/show_bug.cgi?id=78193
   */

  fatal = g_log_set_always_fatal (0);
  handler = g_log_set_handler (NULL, G_LOG_LEVEL_WARNING, cockpit_null_log_handler, NULL);

  handle = polkit_agent_listener_register_with_options (listener,
                                                        POLKIT_AGENT_REGISTER_FLAGS_NONE,
                                                        subject, NULL, options, cancellable, &error);

  g_log_set_always_fatal (fatal);
  g_log_remove_handler (NULL, handler);

  if (error != NULL)
    {
      if ((g_error_matches (error, POLKIT_ERROR, POLKIT_ERROR_FAILED) &&
           error->message && strstr (error->message, "already exists")) ||
          g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN))
        {
          g_debug ("couldn't register polkit agent: %s", error->message);
        }
      else
        {
          g_dbus_error_strip_remote_error (error);
          g_message ("couldn't register polkit authentication agent: %s", error->message);
        }
      goto out;
    }

  string = polkit_subject_to_string (subject);

  g_debug ("registered polkit authentication agent for subject: %s", string);
  g_free (string);

out:
  if (subject)
    g_object_unref (subject);
  if (authority)
    g_object_unref (authority);
  if (listener)
    g_object_unref (listener);
  g_clear_error (&error);
  return handle;
}
Esempio n. 14
0
int
main (int argc, char *argv[])
{
  pid_t parent_pid;
  const gchar *action_id;
  GMainLoop *loop;
  PolkitSubject *subject;
  PolkitAuthority *authority;
  GCancellable *cancellable;

  g_type_init ();

  if (argc != 2)
    {
      g_printerr ("usage: %s <action_id>\n", argv[0]);
      return 1;
    }
  action_id = argv[1];

  loop = g_main_loop_new (NULL, FALSE);

  authority = polkit_authority_get_sync (NULL, NULL);

  /* Typically mechanisms will use a PolkitSystemBusName since most
   * clients communicate with the mechanism via D-Bus. However for
   * this simple example we use the process id of the calling process.
   *
   * Note that if the parent was reaped we have to be careful not to
   * check if init(1) is authorized (it always is).
   */
  parent_pid = getppid ();
  if (parent_pid == 1)
    {
      g_printerr ("Parent process was reaped by init(1)\n");
      return 1;
    }
  subject = polkit_unix_process_new (parent_pid);

  cancellable = g_cancellable_new ();

  g_print ("Will cancel authorization check in 10 seconds\n");

  /* Set up a 10 second timer to cancel the check */
  g_timeout_add (10 * 1000,
                 (GSourceFunc) do_cancel,
                 cancellable);

  polkit_authority_check_authorization (authority,
                                        subject,
                                        action_id,
                                        NULL, /* PolkitDetails */
                                        POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
                                        cancellable,
                                        (GAsyncReadyCallback) check_authorization_cb,
                                        loop);

  g_main_loop_run (loop);

  g_object_unref (authority);
  g_object_unref (subject);
  g_object_unref (cancellable);
  g_main_loop_unref (loop);

  return 0;
}
int
main (int argc, char **argv)
{
  gint ret;
  GMainLoop *loop;
  PolkitAgentListener *listener;
  GError *error;

  g_type_init ();
  gtk_init (&argc, &argv);

  loop = NULL;
  authority = NULL;
  listener = NULL;
  session = NULL;
  ret = 1;

  bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR);
#if HAVE_BIND_TEXTDOMAIN_CODESET
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif
  textdomain (GETTEXT_PACKAGE);

  loop = g_main_loop_new (NULL, FALSE);

  error = NULL;
  authority = polkit_authority_get_sync (NULL /* GCancellable* */, &error);
  if (authority == NULL)
    {
      g_warning ("Error getting authority: %s", error->message);
      g_error_free (error);
      goto out;
    }
  g_signal_connect (authority,
                    "changed",
                    G_CALLBACK (on_authority_changed),
                    NULL);

  listener = polkit_mate_listener_new ();

  error = NULL;
  session = polkit_unix_session_new_for_process_sync (getpid (), NULL, &error);
  if (error != NULL)
    {
      g_warning ("Unable to determine the session we are in: %s", error->message);
      g_error_free (error);
      goto out;
    }

  error = NULL;
  if (!polkit_agent_register_listener (listener,
                                       session,
                                       "/org/mate/PolicyKit1/AuthenticationAgent",
                                       &error))
    {
      g_printerr ("Cannot register authentication agent: %s\n", error->message);
      g_error_free (error);
      goto out;
    }

  update_temporary_authorization_icon (authority);

  g_main_loop_run (loop);

  ret = 0;

 out:
  if (authority != NULL)
    g_object_unref (authority);
  if (session != NULL)
    g_object_unref (session);
  if (listener != NULL)
    g_object_unref (listener);
  if (loop != NULL)
    g_main_loop_unref (loop);

  return ret;
}
Esempio n. 16
0
/**
 * cd_main_sender_authenticated:
 **/
gboolean
cd_main_sender_authenticated (GDBusConnection *connection,
			      const gchar *sender,
			      const gchar *action_id,
			      GError **error)
{
	gboolean ret = FALSE;
	GError *error_local = NULL;
	guint uid;
#ifdef USE_POLKIT
	PolkitAuthorizationResult *result = NULL;
	PolkitSubject *subject = NULL;
	PolkitAuthority *authority = NULL;
#endif

	/* uid 0 is allowed to do all actions */
	uid = cd_main_get_sender_uid (connection, sender, &error_local);
	if (uid == G_MAXUINT) {
		g_set_error (error,
			     CD_CLIENT_ERROR,
			     CD_CLIENT_ERROR_FAILED_TO_AUTHENTICATE,
			     "could not get uid to authenticate %s: %s",
			     action_id,
			     error_local->message);
		g_error_free (error_local);
		goto out;
	}

	/* the root user can always do all actions */
	if (uid == 0) {
		g_debug ("CdCommon: not checking %s for %s as uid 0",
			 action_id, sender);
		ret = TRUE;
		goto out;
	}

	/* a client running as the daemon user may also do all actions */
	if (uid == getuid ()) {
		g_debug ("CdCommon: not checking %s for %s as running as daemon user",
			 action_id, sender);
		ret = TRUE;
		goto out;
	}

#ifdef USE_POLKIT
	/* get authority */
	authority = polkit_authority_get_sync (NULL, &error_local);
	if (authority == NULL) {
		g_set_error (error,
			     CD_CLIENT_ERROR,
			     CD_CLIENT_ERROR_FAILED_TO_AUTHENTICATE,
			     "failed to get polkit authorit: %s",
			     error_local->message);
		g_error_free (error_local);
		goto out;
	}

	/* do authorization async */
	subject = polkit_system_bus_name_new (sender);
	result = polkit_authority_check_authorization_sync (authority, subject,
			action_id,
			NULL,
			POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
			NULL,
			&error_local);
	if (result == NULL) {
		g_set_error (error,
			     CD_CLIENT_ERROR,
			     CD_CLIENT_ERROR_FAILED_TO_AUTHENTICATE,
			     "could not check %s for auth: %s",
			     action_id,
			     error_local->message);
		g_error_free (error_local);
		goto out;
	}

	/* did not auth */
	if (!polkit_authorization_result_get_is_authorized (result)) {
		g_set_error (error,
			     CD_CLIENT_ERROR,
			     CD_CLIENT_ERROR_FAILED_TO_AUTHENTICATE,
			     "failed to obtain %s auth",
			     action_id);
		goto out;
	}
#else
	g_warning ("CdCommon: not checking %s for %s as no PolicyKit support",
		   action_id, sender);
#endif

	/* success */
	ret = TRUE;
out:
#ifdef USE_POLKIT
	if (authority != NULL)
		g_object_unref (authority);
	if (result != NULL)
		g_object_unref (result);
	if (subject != NULL)
		g_object_unref (subject);
#endif
	return ret;
}
Esempio n. 17
0
int
main (int    argc,
      char **argv)
{
  gchar exe_path[PATH_MAX+1];
  ssize_t exe_path_len;
  gboolean replace;
  gboolean verbose;
  gboolean show_version;
  GBusNameOwnerFlags flags;
  GOptionContext *context;
  g_autoptr(GError) error = NULL;
  const GOptionEntry options[] = {
    { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace,  "Replace old daemon.", NULL },
    { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,  "Enable debug output.", NULL },
    { "session", 0, 0, G_OPTION_ARG_NONE, &on_session_bus,  "Run in session, not system scope (for tests).", NULL },
    { "no-idle-exit", 0, 0, G_OPTION_ARG_NONE, &no_idle_exit,  "Don't exit when idle.", NULL },
    { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, "Show program version.", NULL},
    { NULL }
  };

  setlocale (LC_ALL, "");

  g_setenv ("GIO_USE_VFS", "local", TRUE);

  g_set_prgname (argv[0]);

  g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, message_handler, NULL);

  context = g_option_context_new ("");

  g_option_context_set_summary (context, "Flatpak system helper");
  g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);

  replace = FALSE;
  verbose = FALSE;
  show_version = FALSE;

  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      g_printerr ("%s: %s", g_get_application_name(), error->message);
      g_printerr ("\n");
      g_printerr ("Try \"%s --help\" for more information.",
                  g_get_prgname ());
      g_printerr ("\n");
      g_option_context_free (context);
      return 1;
    }

  if (show_version)
    {
      g_print (PACKAGE_STRING "\n");
      return 0;
    }

  if (verbose)
    g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, message_handler, NULL);

  authority = polkit_authority_get_sync (NULL, &error);
  if (authority == NULL)
    {
      g_printerr ("Can't get polkit authority: %s\n", error->message);
      return 1;
    }

  exe_path_len = readlink ("/proc/self/exe", exe_path, sizeof (exe_path) - 1);
  if (exe_path_len > 0)
    {
      exe_path[exe_path_len] = 0;
      GFileMonitor *monitor;
      g_autoptr(GFile) exe = NULL;
      g_autoptr(GError) local_error = NULL;

      exe = g_file_new_for_path (exe_path);
      monitor =  g_file_monitor_file (exe,
                                      G_FILE_MONITOR_NONE,
                                      NULL,
                                      &local_error);
      if (monitor == NULL)
        g_warning ("Failed to set watch on %s: %s", exe_path, error->message);
      else
        g_signal_connect (monitor, "changed",
                          G_CALLBACK (binary_file_changed_cb), NULL);
    }

  flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
  if (replace)
    flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;

  name_owner_id = g_bus_own_name (on_session_bus ? G_BUS_TYPE_SESSION  : G_BUS_TYPE_SYSTEM,
                                  "org.freedesktop.Flatpak.SystemHelper",
                                  flags,
                                  on_bus_acquired,
                                  on_name_acquired,
                                  on_name_lost,
                                  NULL,
                                  NULL);

  /* Ensure we don't idle exit */
  schedule_idle_callback ();

  main_loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (main_loop);

  return 0;
}