コード例 #1
0
/**
 * pk_action_lookup_get_details:
 **/
static PolkitDetails *
pk_action_lookup_get_details (PolkitBackendActionLookup *lookup, const gchar *action_id,
			      PolkitDetails *action_details, PolkitActionDescription *action_description)
{
	const gchar *str;
	const gchar *title;
	gchar **package_ids;
	gchar *text;
	guint len;
	PolkitDetails *details;

	if (!g_str_has_prefix (action_id, "org.freedesktop.packagekit."))
		return NULL;

	details = polkit_details_new ();

	/* role */
	str = polkit_details_lookup (action_details, "role");
	if (str != NULL) {
		/* TRANSLATORS: the trasaction role, e.g. update-system */
		polkit_details_insert (details, _("Role"), str);
	}

	/* only-trusted */
	str = polkit_details_lookup (action_details, "only-trusted");
	if (str != NULL) {
		/* TRANSLATORS: if the transaction is forced to install only trusted packages */
		polkit_details_insert (details, _("Only trusted"), str);
	}

	/* command line */
	str = polkit_details_lookup (action_details, "cmdline");
	if (str != NULL) {
		/* TRANSLATORS: the command line of the thing that wants the authentication */
		polkit_details_insert (details, _("Command line"), str);
	}

	/* packages */
	str = polkit_details_lookup (action_details, "package_ids");
	if (str != NULL) {
		package_ids = pk_package_ids_from_string (str);
		text = pk_action_lookup_package_ids_to_string (package_ids);
		len = g_strv_length (package_ids);

		/* TRANSLATORS: title, the names of the packages that the method is processing */
		title = ngettext ("Package", "Packages", len);
		polkit_details_insert (details, title, text);

		g_strfreev (package_ids);
		g_free (text);
	}

	return details;
}
コード例 #2
0
ファイル: invocation.c プロジェクト: mvollmer/storaged
static const gchar *
lookup_method_action_and_details (gpointer instance,
                                  InvocationClient *client,
                                  uid_t uid,
                                  const GDBusMethodInfo *method,
                                  PolkitDetails **details)
{
  GObjectClass *object_class;
  const gchar *message;

  /* Exception: The Job interface is not marked up like all our others */
  if (UDISKS_IS_JOB (instance) && g_str_equal (method->name, "Cancel"))
    {
      *details = polkit_details_new ();
      polkit_details_insert (*details, "polkit.message",
                             N_("Authentication is required to cancel a job"));

      /* This is a thread-safe call */
      if (uid != udisks_job_get_started_by_uid (instance))
        return "org.freedesktop.udisks2.cancel-job-other-user";
      else
        return "org.freedesktop.udisks2.cancel-job";
    }

  *details = NULL;

  object_class = G_OBJECT_GET_CLASS (instance);
  if (g_object_class_find_property (object_class, "polkit-details") != NULL)
    {
      ObjectGetDetails ogd = { instance, NULL };

      g_main_context_invoke (NULL, object_get_polkit_details, &details);

      g_mutex_lock (&inv.mutex);
      while (ogd.details == NULL)
        g_cond_wait (&inv.wait_cond, &inv.mutex);
      g_mutex_unlock (&inv.mutex);

      *details = ogd.details;
    }

  if (!*details || polkit_details_lookup (*details, "polkit.message"))
    {
      message = g_dbus_annotation_info_lookup (method->annotations, "polkit.message");
      if (message)
        {
          if (!*details)
            *details = polkit_details_new ();
          polkit_details_insert (*details, "polkit.message", message);
        }
    }

  return g_dbus_annotation_info_lookup (method->annotations, "polkit.action_id");
}
コード例 #3
0
/**
 * pk_action_lookup_get_icon_name:
 **/
static gchar *
pk_action_lookup_get_icon_name (PolkitBackendActionLookup *lookup, const gchar *action_id,
				PolkitDetails *details, PolkitActionDescription *action_description)
{
	PkRoleEnum role = PK_ROLE_ENUM_UNKNOWN;
	gboolean only_trusted = TRUE;
	const gchar *only_trusted_text;
	const gchar *role_text;
	const gchar *cmdline;
	gchar *value = NULL;

	if (!g_str_has_prefix (action_id, "org.freedesktop.packagekit."))
		goto out;

	/* get role */
	role_text = polkit_details_lookup (details, "role");
	if (role_text != NULL)
		role = pk_role_enum_from_string (role_text);

	/* get only-trusted */
	only_trusted_text = polkit_details_lookup (details, "only-trusted");
	if (only_trusted_text != NULL)
		only_trusted = g_str_equal (only_trusted_text, "true");

	/* get the command line */
	cmdline = polkit_details_lookup (details, "cmdline");
	if (role == PK_ROLE_ENUM_REPO_ENABLE &&
	    pk_action_lookup_cmdline_is_debuginfo_install (cmdline)) {
		/* TODO: need a debugging icon */
		value = g_strdup ("network-server");
		goto out;
	}

	/* only-trusted */
	if (!only_trusted) {
		value = g_strdup ("emblem-important");
		goto out;
	}
out:
	return value;
}
コード例 #4
0
static gboolean
polkit_authorization_result_get_dismissed(PolkitAuthorizationResult *result)
{
    gboolean ret;
    PolkitDetails *details;

    g_return_val_if_fail(POLKIT_IS_AUTHORIZATION_RESULT(result), FALSE);

    ret = FALSE;
    details = polkit_authorization_result_get_details(result);
    if (details != NULL && polkit_details_lookup(details, "polkit.dismissed"))
        ret = TRUE;

    return ret;
}
コード例 #5
0
static void
polkit_mate_authentication_dialog_constructed (GObject *object)
{
  PolkitMateAuthenticationDialog *dialog;
  GtkWidget *hbox;
  GtkWidget *main_vbox;
  GtkWidget *vbox;
  GtkWidget *table_alignment;
  GtkWidget *table;
  GtkWidget *details_expander;
  GtkWidget *details_vbox;
  GtkWidget *label;
  GtkWidget *image;
  GtkWidget *content_area;
  GtkWidget *action_area;
  gboolean have_user_combobox;
  gchar *s;
  guint rows;

  dialog = POLKIT_MATE_AUTHENTICATION_DIALOG (object);

  if (G_OBJECT_CLASS (polkit_mate_authentication_dialog_parent_class)->constructed != NULL)
    G_OBJECT_CLASS (polkit_mate_authentication_dialog_parent_class)->constructed (object);

  have_user_combobox = FALSE;

  dialog->priv->cancel_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
                                                            GTK_STOCK_CANCEL,
                                                            GTK_RESPONSE_CANCEL);
  dialog->priv->auth_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
                                                          _("_Authenticate"),
                                                          GTK_RESPONSE_OK);
  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);

  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
  action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));

  #if !GTK_CHECK_VERSION(3, 0, 0)
  gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
  #endif
  gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
  gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
  gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
  gtk_box_set_spacing (GTK_BOX (action_area), 6);
  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
  gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_DIALOG_AUTHENTICATION);

  hbox = gtk_hbox_new (FALSE, 12);
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
  gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0);

  image = get_image (dialog);
  gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
  gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);

  main_vbox = gtk_vbox_new (FALSE, 10);
  gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0);

  /* main message */
  label = gtk_label_new (NULL);
  s = g_strdup_printf ("<big><b>%s</b></big>", dialog->priv->message);
  gtk_label_set_markup (GTK_LABEL (label), s);
  g_free (s);
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
  gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);

  /* secondary message */
  label = gtk_label_new (NULL);
  if (g_strv_length (dialog->priv->users) > 1)
    {
          gtk_label_set_markup (GTK_LABEL (label),
                                _("An application is attempting to perform an action that requires privileges. "
                                  "Authentication as one of the users below is required to perform this action."));
    }
  else
    {
      if (strcmp (g_get_user_name (), dialog->priv->users[0]) == 0)
        {
          gtk_label_set_markup (GTK_LABEL (label),
                                _("An application is attempting to perform an action that requires privileges. "
                                  "Authentication is required to perform this action."));
        }
      else
        {
          gtk_label_set_markup (GTK_LABEL (label),
                                _("An application is attempting to perform an action that requires privileges. "
                                  "Authentication as the super user is required to perform this action."));
        }
    }
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
  gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);

  /* user combobox */
  if (g_strv_length (dialog->priv->users) > 1)
    {
      dialog->priv->user_combobox = gtk_combo_box_new ();
      gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (dialog->priv->user_combobox), FALSE, FALSE, 0);

      create_user_combobox (dialog);

      have_user_combobox = TRUE;
    }
  else
    {
      dialog->priv->selected_user = g_strdup (dialog->priv->users[0]);
    }

  /* password entry */
  vbox = gtk_vbox_new (FALSE, 0);
  gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);

  table_alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
  gtk_box_pack_start (GTK_BOX (vbox), table_alignment, FALSE, FALSE, 0);
  table = gtk_table_new (1, 2, FALSE);
  gtk_table_set_col_spacings (GTK_TABLE (table), 12);
  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
  gtk_container_add (GTK_CONTAINER (table_alignment), table);
  dialog->priv->password_entry = gtk_entry_new ();
  gtk_entry_set_visibility (GTK_ENTRY (dialog->priv->password_entry), FALSE);
  dialog->priv->prompt_label = add_row (table, 0, _("_Password:"******"activate",
                            G_CALLBACK (gtk_window_activate_default),
                            dialog);

  dialog->priv->table_alignment = table_alignment;
  /* initially never show the password entry stuff; we'll toggle it on/off so it's
   * only shown when prompting for a password */
  gtk_widget_set_no_show_all (dialog->priv->table_alignment, TRUE);

  /* A label for showing PAM_TEXT_INFO and PAM_TEXT_ERROR messages */
  label = gtk_label_new (NULL);
  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
  dialog->priv->info_label = label;

  /* Details */
  details_expander = gtk_expander_new_with_mnemonic (_("<small><b>_Details</b></small>"));
  gtk_expander_set_use_markup (GTK_EXPANDER (details_expander), TRUE);
  gtk_box_pack_start (GTK_BOX (content_area), details_expander, FALSE, FALSE, 0);

  details_vbox = gtk_vbox_new (FALSE, 10);
  gtk_container_add (GTK_CONTAINER (details_expander), details_vbox);

  table_alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
  gtk_box_pack_start (GTK_BOX (details_vbox), table_alignment, FALSE, FALSE, 0);
  table = gtk_table_new (1, 3, FALSE);
  gtk_table_set_col_spacings (GTK_TABLE (table), 12);
  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
  gtk_container_add (GTK_CONTAINER (table_alignment), table);

  /* TODO: sort keys? */
  rows = 0;
  if (dialog->priv->details != NULL)
    {
      guint n;
      gchar **keys;

      keys = polkit_details_get_keys (dialog->priv->details);
      for (n = 0; keys[n] != NULL; n++)
        {
          const gchar *key = keys[n];
          const gchar *value;

          value = polkit_details_lookup (dialog->priv->details, key);

          label = gtk_label_new (NULL);
          s = g_strdup_printf ("<small>%s</small>", value);
          gtk_label_set_markup (GTK_LABEL (label), s);
          g_free (s);
          gtk_misc_set_alignment (GTK_MISC (label), 0, 1.0);
          s = g_strdup_printf ("<small><b>%s:</b></small>", key);
          add_row (table, rows, s, label);
          g_free (s);

          rows++;
        }
      g_strfreev (keys);
    }

  /* --- */

  label = gtk_label_new (NULL);
  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
  s = g_strdup_printf ("<small><a href=\"%s\">%s</a></small>",
                       dialog->priv->action_id,
                       dialog->priv->action_id);
  gtk_label_set_markup (GTK_LABEL (label), s);
  g_free (s);
  gtk_misc_set_alignment (GTK_MISC (label), 0, 1.0);
  add_row (table, rows++, _("<small><b>Action:</b></small>"), label);
  g_signal_connect (label, "activate-link", G_CALLBACK (action_id_activated), NULL);

  s = g_strdup_printf (_("Click to edit %s"), dialog->priv->action_id);
  gtk_widget_set_tooltip_markup (label, s);
  g_free (s);

  /* --- */

  label = gtk_label_new (NULL);
  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
  s = g_strdup_printf ("<small><a href=\"%s\">%s</a></small>",
                       dialog->priv->vendor_url,
                       dialog->priv->vendor);
  gtk_label_set_markup (GTK_LABEL (label), s);
  g_free (s);
  gtk_misc_set_alignment (GTK_MISC (label), 0, 1.0);
  add_row (table, rows++, _("<small><b>Vendor:</b></small>"), label);

  s = g_strdup_printf (_("Click to open %s"), dialog->priv->vendor_url);
  gtk_widget_set_tooltip_markup (label, s);
  g_free (s);

  if (have_user_combobox)
    {
      /* ... and make the password entry and "Authenticate" button insensitive */
      gtk_widget_set_sensitive (dialog->priv->prompt_label, FALSE);
      gtk_widget_set_sensitive (dialog->priv->password_entry, FALSE);
      gtk_widget_set_sensitive (dialog->priv->auth_button, FALSE);
    }
  else
    {
    }

  gtk_widget_realize (GTK_WIDGET (dialog));

}
コード例 #6
0
static void initiate_authentication(PolkitAgentListener  *listener,
				    const gchar          *action_id,
				    const gchar          *message,
				    const gchar          *icon_name,
				    PolkitDetails        *details,
				    const gchar          *cookie,
				    GList                *identities,
				    GCancellable         *cancellable,
				    GAsyncReadyCallback   callback,
				    gpointer              user_data)
{
	GtkWidget *content;
	GtkWidget *combo_label;
	GtkWidget *grid;
	AuthDlgData *d = g_slice_new0(AuthDlgData);

	char** p;

	for(p = polkit_details_get_keys(details); *p; ++p)
		g_debug("initiate_authentication: %s: %s", *p, polkit_details_lookup(details, *p));

	d->task = g_task_new(listener, cancellable, callback, user_data);
	d->cancellable = cancellable;
	d->action_id = g_strdup(action_id);
	d->cookie = g_strdup(cookie);
	d->auth_dlg = xfce_titled_dialog_new_with_buttons(
			"Authentication required",
			NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
			"_Deny", GTK_RESPONSE_CANCEL,
			"_Allow", GTK_RESPONSE_OK,
			NULL);
	xfce_titled_dialog_set_subtitle(XFCE_TITLED_DIALOG(d->auth_dlg), message);
	gtk_window_set_icon_name(GTK_WINDOW(d->auth_dlg), "dialog-password");

	content = gtk_dialog_get_content_area(GTK_DIALOG(d->auth_dlg));

	combo_label = gtk_label_new("Identity:");
	gtk_widget_set_halign(combo_label, GTK_ALIGN_END);
	gtk_widget_show(combo_label);

	d->id_combo = gtk_combo_box_new();
	add_identities(GTK_COMBO_BOX(d->id_combo), identities);
	g_signal_connect(d->id_combo, "changed",
			 G_CALLBACK(on_id_combo_user_changed), d);
	gtk_combo_box_set_active(GTK_COMBO_BOX(d->id_combo), 0);
	gtk_widget_set_hexpand(d->id_combo, TRUE);
	gtk_widget_show(d->id_combo);

	d->entry_label = gtk_label_new(NULL);
	gtk_widget_set_halign(d->entry_label, GTK_ALIGN_END);
	gtk_widget_show(d->entry_label);

	d->entry = gtk_entry_new();
	gtk_entry_set_visibility(GTK_ENTRY(d->entry), FALSE);
	gtk_widget_set_hexpand(d->entry, TRUE);
	gtk_widget_show(d->entry);
	g_signal_connect (d->entry, "activate", G_CALLBACK(on_entry_activate), d);

	grid = grid2x2(combo_label, d->id_combo, d->entry_label, d->entry);
	gtk_box_pack_start(GTK_BOX(content), grid, TRUE, TRUE, 0);

	d->status = gtk_label_new(NULL);
	gtk_box_pack_start(GTK_BOX(content), d->status, TRUE, TRUE, 0);
	gtk_widget_show(d->status);

	g_signal_connect(cancellable, "cancelled", G_CALLBACK(on_cancelled), d);
	g_signal_connect(d->auth_dlg, "response",
			 G_CALLBACK(on_auth_dlg_response), d);

	gtk_widget_grab_focus(d->entry);
	gtk_window_present(GTK_WINDOW(d->auth_dlg));
}
コード例 #7
0
/**
 * pk_action_lookup_get_message:
 **/
static gchar *
pk_action_lookup_get_message (PolkitBackendActionLookup *lookup, const gchar *action_id,
			      PolkitDetails *details, PolkitActionDescription *action_description)
{
	PkRoleEnum role = PK_ROLE_ENUM_UNKNOWN;
	gboolean only_trusted = TRUE;
	const gchar *cmdline;
	const gchar *role_text;
	const gchar *only_trusted_text;
	const gchar *str;
	const gchar *text;
	gchar *message = NULL;
	gchar **package_ids = NULL;
	GString *string;
	guint len = 1;

	if (!g_str_has_prefix (action_id, "org.freedesktop.packagekit."))
		goto out;

	/* get role */
	role_text = polkit_details_lookup (details, "role");
	if (role_text != NULL)
		role = pk_role_enum_from_string (role_text);

	/* get only-trusted */
	only_trusted_text = polkit_details_lookup (details, "only-trusted");
	if (only_trusted_text != NULL)
		only_trusted = g_str_equal (only_trusted_text, "true");

	/* get the command line */
	cmdline = polkit_details_lookup (details, "cmdline");
	if (role == PK_ROLE_ENUM_REPO_ENABLE &&
	    pk_action_lookup_cmdline_is_debuginfo_install (cmdline)) {
		message = g_strdup (N_("To install debugging packages, extra sources need to be enabled"));
		goto out;
	}

	/* use the message shipped in the policy file */
	if (only_trusted)
		goto out;

	/* find out the number of packages so we pluralize corectly */
	str = polkit_details_lookup (details, "package_ids");
	if (str != NULL) {
		package_ids = pk_package_ids_from_string (str);
		len = g_strv_length (package_ids);
		g_strfreev (package_ids);
	}

	/* UpdatePackages */
	if (role == PK_ROLE_ENUM_UPDATE_PACKAGES) {
		string = g_string_new ("");

		/* TRANSLATORS: is not GPG signed */
		g_string_append (string, g_dgettext (GETTEXT_PACKAGE, N_("The software is not from a trusted source.")));
		g_string_append (string, "\n");

		/* TRANSLATORS: user has to trust provider -- I know, this sucks */
		text = g_dngettext (GETTEXT_PACKAGE,
				    N_("Do not update this package unless you are sure it is safe to do so."),
				    N_("Do not update these packages unless you are sure it is safe to do so."),
				    len);
		g_string_append (string, text);

		message = g_string_free (string, FALSE);
		goto out;
	}

	/* InstallPackages */
	if (role == PK_ROLE_ENUM_INSTALL_PACKAGES) {
		string = g_string_new ("");

		/* TRANSLATORS: is not GPG signed */
		g_string_append (string, g_dgettext (GETTEXT_PACKAGE, N_("The software is not from a trusted source.")));
		g_string_append (string, "\n");

		/* TRANSLATORS: user has to trust provider -- I know, this sucks */
		text = g_dngettext (GETTEXT_PACKAGE,
				    N_("Do not install this package unless you are sure it is safe to do so."),
				    N_("Do not install these packages unless you are sure it is safe to do so."),
				    len);
		g_string_append (string, text);

		message = g_string_free (string, FALSE);
		goto out;
	}
out:
	return message;
}
コード例 #8
0
static void initiate_authentication(PolkitAgentListener  *listener,
                                    const gchar          *action_id,
                                    const gchar          *message,
                                    const gchar          *icon_name,
                                    PolkitDetails        *details,
                                    const gchar          *cookie,
                                    GList                *identities,
                                    GCancellable         *cancellable,
                                    GAsyncReadyCallback   callback,
                                    gpointer              user_data)
{
    GtkBuilder* b = gtk_builder_new();
    GtkWidget *icon, *msg, *detail, *id_hbox;
    GList* l;
    DlgData* data = g_slice_new0(DlgData);
    DEBUG("init_authentication");
    DEBUG("action_id = %s", action_id);
#ifdef G_ENABLE_DEBUG
    char** p;
    for(p = polkit_details_get_keys(details);*p;++p)
        DEBUG("%s: %s", *p, polkit_details_lookup(details, *p));
#endif
    data->listener = (LXPolkitListener*)listener;
    data->result = g_simple_async_result_new(listener, callback, user_data, initiate_authentication);

    data->action_id = g_strdup(action_id);
    data->cancellable = (GCancellable*)g_object_ref(cancellable);
    data->callback = callback;
    data->user_data = user_data;
    data->cookie = g_strdup(cookie);

    /* create the dialog, load from GtkBuilder ui definition file. */
    gtk_builder_add_from_file(b, PACKAGE_UI_DIR "/lxpolkit.ui", NULL);
    data->dlg = (GtkWidget*)gtk_builder_get_object(b, "dlg");
    icon = (GtkWidget*)gtk_builder_get_object(b, "icon");
    msg = (GtkWidget*)gtk_builder_get_object(b, "msg");
    detail = (GtkWidget*)gtk_builder_get_object(b, "detail");
    id_hbox = (GtkWidget*)gtk_builder_get_object(b, "id_hbox");
    data->id = (GtkWidget*)gtk_builder_get_object(b, "id");
    data->request = (GtkWidget*)gtk_builder_get_object(b, "request");
    data->request_label = (GtkWidget*)gtk_builder_get_object(b, "request_label");
    g_object_unref(b);

    g_signal_connect(data->dlg, "response", G_CALLBACK(on_dlg_response), data);
    g_signal_connect(cancellable, "cancelled", G_CALLBACK(on_cancelled), data);

    gtk_dialog_set_alternative_button_order(GTK_DIALOG(data->dlg), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL);
    gtk_dialog_set_default_response(GTK_DIALOG(data->dlg), GTK_RESPONSE_OK);
    gtk_window_set_icon_name(GTK_WINDOW(data->dlg), GTK_STOCK_DIALOG_AUTHENTICATION);

    /* set dialog icon */
    if(icon_name && *icon_name)
        gtk_image_set_from_icon_name(GTK_IMAGE(icon), icon_name, GTK_ICON_SIZE_DIALOG);
    else
        gtk_image_set_from_stock(GTK_IMAGE(icon), GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG);

    /* set message prompt */
    gtk_label_set_text(GTK_LABEL(msg), message);

    /* create combo box for user selection */
    if( identities )
    {
        GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_OBJECT);
        g_signal_connect(data->id, "changed", G_CALLBACK(on_user_changed), data);
        for(l = identities; l; l=l->next)
        {
            PolkitIdentity* id = (PolkitIdentity*)l->data;
            char* name;
            if(POLKIT_IS_UNIX_USER(id))
            {
                struct passwd* pwd = getpwuid(polkit_unix_user_get_uid(POLKIT_UNIX_USER(id)));
                gtk_list_store_insert_with_values(store, NULL, -1, 0, pwd->pw_name, 1, id, -1);
            }
            else if(POLKIT_IS_UNIX_GROUP(id))
            {
                struct group* grp = getgrgid(polkit_unix_group_get_gid(POLKIT_UNIX_GROUP(id)));
                char* str = g_strdup_printf(_("Group: %s"), grp->gr_name);
                gtk_list_store_insert_with_values(store, NULL, -1, 0, str, 1, id, -1);
                g_free(str);
            }
            else
            {
                /* FIXME: what's this? */
                char* str = polkit_identity_to_string(id);
                gtk_list_store_insert_with_values(store, NULL, -1, 0, str, 1, id, -1);
                g_free(str);
            }
        }
        gtk_combo_box_set_model(data->id, GTK_TREE_MODEL(store));
        g_object_unref(store);
        /* select the fist user in the list */
        gtk_combo_box_set_active(data->id, 0);
    }
    else
    {
        DEBUG("no identities list, is this an error?");
        gtk_widget_hide(id_hbox);
        g_simple_async_result_complete_in_idle(data->result);
        dlg_data_free(data);
        return;
    }
    gtk_window_present(GTK_WINDOW(data->dlg));
}