open_session (const gchar *user_to_auth,
	      uid_t        target_uid)
{
  gboolean ret;
  gint rc;
  pam_handle_t *pam_h;
  char **envlist;
  struct pam_conv conversation;

  ret = FALSE;

  pam_h = NULL;

  conversation.conv        = pam_conversation_function;
  conversation.appdata_ptr = NULL;

  /* start the pam stack */
  rc = pam_start ("polkit-1",
                  user_to_auth,
                  &conversation,
                  &pam_h);
  if (rc != PAM_SUCCESS)
    {
      g_printerr ("pam_start() failed: %s\n", pam_strerror (pam_h, rc));
      goto out;
    }

  /* open a session */
  rc = pam_open_session (pam_h,
                         0); /* flags */
  if (rc != PAM_SUCCESS)
    {
      g_printerr ("pam_open_session() failed: %s\n", pam_strerror (pam_h, rc));
      goto out;
    }

  ret = TRUE;

  envlist = pam_getenvlist (pam_h);
  if (envlist != NULL)
    {
      guint n;
      for (n = 0; envlist[n]; n++)
	{
	  const char *envitem = envlist[n];
	  
	  if (g_str_has_prefix (envitem, "XDG_RUNTIME_DIR="))
	    {
	      const char *eq = strchr (envitem, '=');
	      g_assert (eq);
	      if (!xdg_runtime_dir_is_owned_by (eq + 1, target_uid))
		continue;
	    }

	  putenv (envlist[n]);
	}
      free (envlist);
    }

out:
  if (pam_h != NULL)
    pam_end (pam_h, rc);
  return ret;
}
open_session (const gchar *user_to_auth,
	      uid_t        target_uid)
{
  gboolean ret;
  gint rc;
  pam_handle_t *pam_h;
  char **envlist;
  struct pam_conv conversation;

  ret = FALSE;

  pam_h = NULL;

  conversation.conv        = pam_conversation_function;
  conversation.appdata_ptr = NULL;

   
  rc = pam_start ("polkit-1",
                  user_to_auth,
                  &conversation,
                  &pam_h);
  if (rc != PAM_SUCCESS)
    {
      g_printerr ("pam_start() failed: %s\n", pam_strerror (pam_h, rc));
      goto out;
    }

   
  rc = pam_open_session (pam_h,
                         0);  
  if (rc != PAM_SUCCESS)
    {
      g_printerr ("pam_open_session() failed: %s\n", pam_strerror (pam_h, rc));
      goto out;
    }

  ret = TRUE;

  envlist = pam_getenvlist (pam_h);
  if (envlist != NULL)
    {
      guint n;
      for (n = 0; envlist[n]; n++)
	{
	  const char *envitem = envlist[n];
	  
	  if (g_str_has_prefix (envitem, "XDG_RUNTIME_DIR="))
	    {
	      const char *eq = strchr (envitem, '=');
	      g_assert (eq);
	      if (!xdg_runtime_dir_is_owned_by (eq + 1, target_uid))
		continue;
	    }

	  putenv (envlist[n]);
	}
      free (envlist);
    }

out:
  if (pam_h != NULL)
    pam_end (pam_h, rc);
  return ret;
}