Advertisement
ananas

xdm greeter.c

Dec 22nd, 2012
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.95 KB | None | 0 0
  1. #include <sys/types.h>
  2. #include <pwd.h>
  3. #include <shadow.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6.  
  7. #include <security/pam_appl.h>
  8.  
  9. #ifndef _XOPEN_SOURCE
  10. # define _XOPEN_SOURCE 1
  11. #endif
  12. #include <unistd.h>
  13.  
  14. #include "greet.h"
  15.  
  16. static ConfigData *cfg = NULL;
  17.  
  18. static GtkWidget *le, *pe, *se;
  19. static gchar *uname = NULL;
  20. static gchar *sess_cmd = NULL;
  21.  
  22. /*
  23.  * Function pointers filled in by the initial call ito the library
  24.  */
  25.  
  26. int (*__xdm_PingServer) (struct display * d, Display * alternateDpy) = NULL;
  27. void (*__xdm_SessionPingFailed) (struct display * d) = NULL;
  28. void (*__xdm_Debug) (const char *fmt, ...) = NULL;
  29. void (*__xdm_RegisterCloseOnFork) (int fd) = NULL;
  30. void (*__xdm_SecureDisplay) (struct display * d, Display * dpy) = NULL;
  31. void (*__xdm_UnsecureDisplay) (struct display * d, Display * dpy) = NULL;
  32. void (*__xdm_ClearCloseOnFork) (int fd) = NULL;
  33. void (*__xdm_SetupDisplay) (struct display * d) = NULL;
  34. void (*__xdm_LogError) (const char *fmt, ...) = NULL;
  35. void (*__xdm_SessionExit) (struct display * d, int status, int removeAuth) = NULL;
  36. void (*__xdm_DeleteXloginResources) (struct display * d, Display * dpy) = NULL;
  37. int (*__xdm_source) (char **environ, char *file) = NULL;
  38. char **(*__xdm_defaultEnv) (void) = NULL;
  39. char **(*__xdm_setEnv) (char **e, char *name, char *value) = NULL;
  40. char **(*__xdm_putEnv) (const char *string, char **env) = NULL;
  41. char **(*__xdm_parseArgs) (char **argv, char *string) = NULL;
  42. void (*__xdm_printEnv) (char **e) = NULL;
  43. char **(*__xdm_systemEnv) (struct display * d, char *user, char *home) = NULL;
  44. void (*__xdm_LogOutOfMem) (const char *fmt, ...) = NULL;
  45. void (*__xdm_setgrent) (void) = NULL;
  46. struct group *(*__xdm_getgrent) (void) = NULL;
  47. void (*__xdm_endgrent) (void) = NULL;
  48. struct spwd *(*__xdm_getspnam) (const char *) = NULL;
  49. void (*__xdm_endspent) (void) = NULL;
  50. struct passwd *(*__xdm_getpwnam) (const char *) = NULL;
  51. void (*__xdm_endpwent) (void) = NULL;
  52. char *(*__xdm_crypt) (const char *, const char *) = NULL;
  53. #ifdef USE_PAM
  54. pam_handle_t **(*__xdm_thepamhp) (void) = NULL;
  55. #endif
  56.  
  57. #ifdef USE_PAM
  58. /* pam conversation handler */
  59. static int pamconv(int num_msg, const struct pam_message **msg,
  60.            struct pam_response **response, void *appdata_ptr)
  61. {
  62.   gint i, ret = PAM_SUCCESS;
  63.   const gchar *pam_msg_styles[5] = { "<invalid pam msg style>",
  64.                      "PAM_PROMPT_ECHO_OFF", "PAM_PROMPT_ECHO_ON",
  65.                      "PAM_ERROR_MSG", "PAM_TEXT_INFO" } ;
  66.   struct pam_message *m;
  67.   struct pam_response *r;
  68.  
  69.   *response = calloc (num_msg, sizeof (struct pam_response));
  70.   if (*response == NULL)
  71.     return PAM_BUF_ERR;
  72.  
  73.   m = (struct pam_message *) *msg;
  74.   r = *response;
  75.  
  76.   for (i = 0; i < num_msg; i++ , m++ , r++) {
  77.     Debug ("pam_msg: %s (%d): '%s'\n",
  78.        ((m->msg_style > 0) && (m->msg_style <= 4)) ?
  79.        pam_msg_styles[m->msg_style] : pam_msg_styles[0],
  80.        m->msg_style, m->msg);
  81.    
  82.     switch (m->msg_style)
  83.       {
  84.       case PAM_PROMPT_ECHO_ON:
  85.     r->resp = g_strdup (gtk_entry_get_text (GTK_ENTRY (le)));
  86.     break;
  87.       case PAM_PROMPT_ECHO_OFF:
  88.     r->resp = g_strdup (gtk_entry_get_text (GTK_ENTRY (pe)));
  89.     if (!r->resp[0])
  90.       ret = PAM_BUF_ERR;
  91.     break;
  92.       case PAM_TEXT_INFO:
  93.       case PAM_ERROR_MSG:
  94.     LogError ("pam_msg: %s\n", m->msg);
  95.     break;
  96.       default:
  97.     LogError ("Unknown PAM msg_style: %d\n", m->msg_style);
  98.       }
  99.   }
  100.  
  101.   return ret;
  102. }
  103. #endif
  104.  
  105. static void
  106. parse_config ()
  107. {
  108.   gchar *cfile;
  109.  
  110.   if (cfg)
  111.     return;
  112.  
  113.   cfg = g_new0 (ConfigData, 1);
  114.  
  115.   cfg->min_uid = MIN_UID;
  116.  
  117.   cfg->welcome = WELCOME;
  118.   cfg->user_lbl = USERLABEL;
  119.   cfg->pwd_lbl = PASSLABEL;
  120.   cfg->sess_lbl = SESSLABEL;
  121.  
  122.   cfg->borders = BORDERS;
  123.  
  124.   cfg->allow_root = TRUE;
  125.  
  126.   cfg->path = DEFAULT_PATH;
  127.  
  128.   cfg->reboot_cmd = REBOOT_CMD;
  129.   cfg->poweroff_cmd = POWEROFF_CMD;
  130.   cfg->suspend_cmd = SUSPEND_CMD;
  131.   cfg->hibernate_cmd = HIBERNATE_CMD;
  132.  
  133.   cfile = g_build_filename (SYSCONFDIR, "greeter.conf", NULL);
  134.   if (g_file_test (cfile, G_FILE_TEST_EXISTS))
  135.     {
  136.       GKeyFile *kf;
  137.      
  138.       kf = g_key_file_new ();
  139.       if (g_key_file_load_from_file (kf, cfile, G_KEY_FILE_NONE, NULL))
  140.     {
  141.       if (g_key_file_has_group (kf, "Interface"))
  142.         {
  143.           if (g_key_file_has_key (kf, "Interface", "MinUID", NULL))
  144.         cfg->min_uid = g_key_file_get_integer (kf, "Interface", "MinUID", NULL);
  145.           if (g_key_file_has_key (kf, "Interface", "Welcome", NULL))
  146.         cfg->welcome = g_key_file_get_locale_string (kf, "Interface", "Welcome", NULL, NULL);
  147.           cfg->background = g_key_file_get_string (kf, "Interface", "Background", NULL);
  148.           if (g_key_file_has_key (kf, "Interface", "Username", NULL))
  149.         cfg->user_lbl = g_key_file_get_locale_string (kf, "Interface", "Username", NULL, NULL);
  150.           if (g_key_file_has_key (kf, "Interface", "Password", NULL))
  151.         cfg->pwd_lbl = g_key_file_get_locale_string (kf, "Interface", "Password", NULL, NULL);
  152.           if (g_key_file_has_key (kf, "Interface", "Session", NULL))
  153.         cfg->sess_lbl = g_key_file_get_locale_string (kf, "Interface", "Session", NULL, NULL);
  154.           if (g_key_file_has_key (kf, "Interface", "Borders", NULL))
  155.         cfg->borders = g_key_file_get_integer (kf, "Interface", "Borders", NULL);
  156.           cfg->theme = g_key_file_get_string (kf, "Interface", "Theme", NULL);
  157.         }
  158.  
  159.       if (g_key_file_has_group (kf, "Login"))
  160.         {
  161.           cfg->session = g_key_file_get_string (kf, "Login", "Session", NULL);
  162.           cfg->auto_login = g_key_file_get_boolean (kf, "Login", "Autologin", NULL);
  163.           cfg->auto_user = g_key_file_get_string (kf, "Login", "Autouser", NULL);
  164.           if (g_key_file_has_key (kf, "Login", "AllowRoot", NULL))
  165.         cfg->allow_root = g_key_file_get_boolean (kf, "Login", "AllowRoot", NULL);
  166.           if (g_key_file_has_key (kf, "Login", "Path", NULL))
  167.         cfg->path = g_key_file_get_string (kf, "Login", "Path", NULL);
  168.         }
  169.  
  170.       if (g_key_file_has_group (kf, "Actions"))
  171.         {
  172.           if (g_key_file_has_key (kf, "Actions", "Reboot", NULL))
  173.         cfg->reboot_cmd = g_key_file_get_string (kf, "Actions", "Reboot", NULL);
  174.           if (g_key_file_has_key (kf, "Actions", "Poweroff", NULL))
  175.         cfg->poweroff_cmd = g_key_file_get_string (kf, "Actions", "Poweroff", NULL);
  176.           if (g_key_file_has_key (kf, "Actions", "Suspend", NULL))
  177.         cfg->suspend_cmd = g_key_file_get_string (kf, "Actions", "Suspend", NULL);
  178.           if (g_key_file_has_key (kf, "Actions", "Hibernate", NULL))
  179.         cfg->hibernate_cmd = g_key_file_get_string (kf, "Actions", "Hibernate", NULL);
  180.         }
  181.     }
  182.       g_key_file_free (kf);
  183.     }
  184.   g_free (cfile);
  185. }
  186.  
  187. static gboolean
  188. username_compl_cb (GtkEntryCompletion *w, GtkTreeModel *m, GtkTreeIter *it, gpointer d)
  189. {
  190.   gchar *name;
  191.  
  192.   gtk_tree_model_get (m, it, 0, &name, -1);
  193.   gtk_entry_set_text (GTK_ENTRY (le), name);
  194.   g_signal_emit_by_name (G_OBJECT (le), "activate");
  195.  
  196.   return TRUE;
  197. }
  198.  
  199. static void
  200. load_users ()
  201. {
  202.   GtkListStore *store;
  203.   GtkTreeIter iter;
  204.   GtkEntryCompletion *compl;
  205.   struct passwd *pwd;
  206.  
  207.   store = gtk_list_store_new (1, G_TYPE_STRING);
  208.   while ((pwd = getpwent ()) != NULL)
  209.     {
  210.       if (pwd->pw_uid >= cfg->min_uid)
  211.         {
  212.           gtk_list_store_append (store, &iter);
  213.           gtk_list_store_set (store, &iter, 0, pwd->pw_name, -1);
  214.         }
  215.     }
  216.   endpwent ();
  217.  
  218.   /* add special users */
  219.   gtk_list_store_append (store, &iter);
  220.   gtk_list_store_set (store, &iter, 0, "@poweroff", -1);
  221.   gtk_list_store_append (store, &iter);
  222.   gtk_list_store_set (store, &iter, 0, "@reboot", -1);
  223.   gtk_list_store_append (store, &iter);
  224.   gtk_list_store_set (store, &iter, 0, "@suspend", -1);
  225.   gtk_list_store_append (store, &iter);
  226.   gtk_list_store_set (store, &iter, 0, "@hibernate", -1);
  227.  
  228.   compl = gtk_entry_completion_new ();
  229.   gtk_entry_completion_set_model (compl, GTK_TREE_MODEL (store));
  230.   gtk_entry_completion_set_text_column (compl, 0);
  231.   gtk_entry_set_completion (GTK_ENTRY (le), compl);
  232.  
  233.   g_signal_connect (G_OBJECT (compl), "match-selected", G_CALLBACK (username_compl_cb), NULL);
  234.  
  235.   g_object_unref (store);
  236.   g_object_unref (compl);
  237. }
  238.  
  239. static void
  240. load_sessions ()
  241. {
  242.   GDir *dir;
  243.   const gchar *filename;
  244.   GtkListStore *ss;
  245.   gint len, s = 0, as = -1;
  246.  
  247.   dir = g_dir_open (SESSIONDIR, 0, NULL);
  248.   if (!dir)
  249.     return;
  250.  
  251.   len = strlen (cfg->session);
  252.   ss = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (se)));
  253.   while ((filename = g_dir_read_name (dir)) != NULL)
  254.     {
  255.       GKeyFile *kf;
  256.       gchar *fullname;
  257.      
  258.       if (!g_str_has_suffix (filename, ".desktop"))
  259.     continue;
  260.  
  261.       kf = g_key_file_new ();
  262.       fullname = g_build_filename (SESSIONDIR, filename, NULL);
  263.       if (g_key_file_load_from_file (kf, fullname, 0, NULL))
  264.     {
  265.       GtkTreeIter it;
  266.       GdkPixbuf *pb = NULL;
  267.       gchar *name, *icon, *cmd;
  268.  
  269.       name =  g_key_file_get_locale_string (kf, "Desktop Entry", "Name", NULL, NULL);
  270.       icon = g_key_file_get_string (kf, "Desktop Entry", "Icon", NULL);
  271.       cmd = g_key_file_get_string (kf, "Desktop Entry", "Exec", NULL);
  272.  
  273.       if (icon)
  274.         {
  275.           if (g_file_test (icon, G_FILE_TEST_EXISTS))
  276.         pb = gdk_pixbuf_new_from_file_at_size (icon, 16, 16, NULL);
  277.           else
  278.         pb = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), icon, 16, 0, NULL);
  279.         }
  280.  
  281.       gtk_list_store_append (ss, &it);
  282.       gtk_list_store_set (ss, &it, 0, pb, 1, name, 2, cmd, -1);
  283.  
  284.       if (g_ascii_strncasecmp (filename, cfg->session, len) == 0)
  285.         as = s;
  286.       s++;
  287.  
  288.       g_free (name);
  289.       g_free (icon);
  290.       g_free (cmd);
  291.     }
  292.  
  293.       g_free (fullname);
  294.       g_key_file_free (kf);
  295.     }
  296.   g_dir_close (dir);
  297.  
  298.   gtk_combo_box_set_active (GTK_COMBO_BOX (se), as);
  299. }
  300.  
  301. static void
  302. username_cb (GtkWidget *w, gpointer d)
  303. {
  304.   const gchar *name = gtk_entry_get_text (GTK_ENTRY (le));
  305.  
  306.   if (!name || !name[0])
  307.     {
  308.       gtk_widget_grab_focus (le);
  309.       return;
  310.     }
  311.  
  312.   if (name[0] == '@')
  313.     {
  314.       /* proceed special names */
  315.       if (g_ascii_strcasecmp (name + 1, "reboot") == 0)
  316.         g_spawn_command_line_async (cfg->reboot_cmd, NULL);
  317.       else if (g_ascii_strcasecmp (name + 1, "poweroff") == 0)
  318.         g_spawn_command_line_async (cfg->poweroff_cmd, NULL);
  319.       else if (g_ascii_strcasecmp (name + 1, "suspend") == 0)
  320.         g_spawn_command_line_async (cfg->suspend_cmd, NULL);
  321.       else if (g_ascii_strcasecmp (name + 1, "hibernate") == 0)
  322.         g_spawn_command_line_async (cfg->hibernate_cmd, NULL);
  323.     }
  324.  
  325.   gtk_widget_grab_focus (pe);
  326. }
  327.  
  328. static void
  329. verify_auth (GtkWidget *w, gpointer d)
  330. {
  331.   GtkTreeModel *model;
  332.   GtkTreeIter it;
  333.   const gchar *name;
  334. #ifdef USE_PAM
  335.   /* Run PAM conversation */
  336.   pam_handle_t **pamhp = thepamhp();
  337.   gint pam_error;
  338.   const gchar *pam_fname;
  339. #else
  340.   struct passwd *pw;
  341.   struct spwd *sp;
  342.   const gchar *pwd;
  343.   gchar *cpwd;
  344. #endif
  345.  
  346.   name = gtk_entry_get_text (GTK_ENTRY (le));
  347.  
  348.   if (!cfg->allow_root && g_ascii_strcasecmp (name, "root") == 0)
  349.     goto clear;
  350.  
  351.   uname = g_strdup (name);
  352.  
  353.   /* get session command */
  354.   model = gtk_combo_box_get_model (GTK_COMBO_BOX (se));
  355.   gtk_combo_box_get_active_iter (GTK_COMBO_BOX (se), &it);
  356.   gtk_tree_model_get (model, &it, 2, &sess_cmd, -1);
  357.  
  358. #ifdef USE_PAM
  359.   /* authenticate user */
  360.   pam_error = pam_authenticate (*pamhp, 0);
  361.   pam_fname = "pam_authenticate";
  362.   if (pam_error != PAM_SUCCESS)
  363.     {
  364.       LogError ("%s failure: %s\n", pam_fname, pam_strerror (*pamhp, pam_error));
  365.       goto clear;
  366.     }
  367.  
  368.   /* handle expired passwords */
  369.   pam_error = pam_acct_mgmt (*pamhp, 0);
  370.   pam_fname = "pam_acct_mgmt";
  371.   if (pam_error == PAM_NEW_AUTHTOK_REQD)
  372.     {
  373.       do
  374.     {
  375.       pam_error = pam_chauthtok (*pamhp, PAM_CHANGE_EXPIRED_AUTHTOK);
  376.     }
  377.       while ((pam_error == PAM_AUTHTOK_ERR) || (pam_error == PAM_TRY_AGAIN));
  378.       pam_fname = "pam_chauthtok";
  379.     }
  380.   if (pam_error != PAM_SUCCESS)
  381.     {
  382.       LogError ("%s failure: %s\n", pam_fname, pam_strerror (*pamhp, pam_error));
  383.       goto clear;
  384.     }
  385.  
  386.   pam_setcred (*pamhp, 0);
  387.  
  388.   gtk_main_quit ();
  389. #else /* not PAM */
  390.   /* get user */
  391.   pw = getpwnam (name);
  392.   endpwent ();
  393.   if (!pw)
  394.     goto clear;
  395.  
  396.   /* get password */
  397.   pwd = gtk_entry_get_text (GTK_ENTRY (pe));
  398.   if (!pwd || !pwd[0])
  399.     goto clear;
  400.  
  401.   cpwd = pw->pw_passwd;
  402.   if (!cpwd || !cpwd[0] || strcmp (cpwd, "x") == 0)
  403.     {
  404.       sp = getspnam (pw->pw_name);
  405.       endspent ();
  406.       if (!sp)
  407.     goto clear;
  408.       cpwd = sp->sp_pwdp;
  409.     }
  410.  
  411.   if (g_ascii_strcasecmp ((const gchar *) crypt (pwd, cpwd), cpwd) == 0)
  412.     gtk_main_quit ();
  413. #endif /* USE_PAM */
  414.  
  415.  clear:
  416.   gtk_entry_set_text (GTK_ENTRY (le), "");
  417.   gtk_entry_set_text (GTK_ENTRY (pe), "");
  418.   gtk_widget_grab_focus (le);
  419. }
  420.  
  421. static GtkWidget *
  422. create_dialog ()
  423. {
  424.   GtkWidget *w, *f, *b, *wb, *t, *l;
  425.   GtkListStore *ss;
  426.   GtkCellRenderer *r;
  427.   gchar *wlc;
  428.  
  429.   /* window */
  430.   w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  431.   gtk_window_set_position (GTK_WINDOW (w), GTK_WIN_POS_CENTER_ALWAYS);
  432.  
  433.   f = gtk_frame_new (NULL);
  434.   gtk_frame_set_shadow_type (GTK_FRAME (f), GTK_SHADOW_ETCHED_IN);
  435.   gtk_container_set_border_width (GTK_CONTAINER (f), 2);
  436.   gtk_container_add (GTK_CONTAINER (w), f);
  437.  
  438.   b = gtk_vbox_new (FALSE, 0);
  439.   gtk_container_set_border_width (GTK_CONTAINER (b), cfg->borders);
  440.   gtk_container_add (GTK_CONTAINER (f), b);
  441.  
  442.   wb = gtk_hbox_new (FALSE, 0);
  443.   gtk_box_pack_start (GTK_BOX (b), wb, TRUE, TRUE, 0);
  444.  
  445.   /* welcome */
  446.   l = gtk_image_new_from_icon_name ("dialog-password", GTK_ICON_SIZE_DIALOG);
  447.   gtk_box_pack_start (GTK_BOX (wb), l, TRUE, FALSE, 0);
  448.   l = gtk_label_new (NULL);
  449.   gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
  450.   wlc = g_strdup_printf (cfg->welcome, g_get_host_name ());
  451.   gtk_label_set_markup (GTK_LABEL (l), wlc);
  452.   g_free (wlc);
  453.   gtk_box_pack_start (GTK_BOX (wb), l, TRUE, TRUE, 0);
  454.  
  455.   /* login */
  456.   t = gtk_table_new (3, 2, FALSE);
  457.   gtk_table_set_row_spacings (GTK_TABLE (t), 10);
  458.   gtk_table_set_col_spacings (GTK_TABLE (t), 10);
  459.   gtk_container_set_border_width (GTK_CONTAINER (t), 15);
  460.   gtk_box_pack_start (GTK_BOX (b), t, TRUE, TRUE, 5);
  461.  
  462.   /* session */
  463.   l = gtk_label_new (NULL);
  464.   gtk_label_set_markup (GTK_LABEL (l), cfg->sess_lbl);
  465.   gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
  466.   gtk_table_attach (GTK_TABLE (t), l, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
  467.  
  468.   ss = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
  469.   se = gtk_combo_box_new_with_model (GTK_TREE_MODEL (ss));
  470.   g_object_unref (ss);
  471.   gtk_table_attach (GTK_TABLE (t), se, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
  472.  
  473.   r = gtk_cell_renderer_pixbuf_new ();
  474.   gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (se), r, FALSE);
  475.   gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (se), r, "pixbuf", 0, NULL);
  476.   r = gtk_cell_renderer_text_new ();
  477.   gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (se), r, TRUE);
  478.   gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (se), r, "text", 1, NULL);
  479.  
  480.   /* user */
  481.   l = gtk_label_new (NULL);
  482.   gtk_label_set_markup (GTK_LABEL (l), cfg->user_lbl);
  483.   gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
  484.   gtk_table_attach (GTK_TABLE (t), l, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
  485.   le = gtk_entry_new ();
  486.   gtk_table_attach (GTK_TABLE (t), le, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
  487.  
  488.   /* password */
  489.   l = gtk_label_new (NULL);
  490.   gtk_label_set_markup (GTK_LABEL (l), cfg->pwd_lbl);
  491.   gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
  492.   gtk_table_attach (GTK_TABLE (t), l, 0, 1, 2, 3, GTK_FILL, 0, 0, 0);
  493.   pe = gtk_entry_new ();
  494.   gtk_entry_set_visibility (GTK_ENTRY (pe), FALSE);
  495.   gtk_table_attach (GTK_TABLE (t), pe, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0);
  496.  
  497.   g_signal_connect (G_OBJECT (le), "activate", G_CALLBACK (username_cb), NULL);
  498.   g_signal_connect (G_OBJECT (pe), "activate", G_CALLBACK (verify_auth), NULL);
  499.  
  500.   load_users ();
  501.   load_sessions ();
  502.  
  503.   return w;
  504. }
  505.  
  506. greet_user_rtn
  507. GreetUser (struct display *d,
  508.        Display ** dpy,
  509.        struct verify_info *verify,
  510.        struct greet_info *greet,
  511.        struct dlfuncs *dlfuncs)
  512. {
  513.   GtkWidget *w;
  514.   GdkDisplay *gd;
  515.   struct passwd *p;
  516.   gchar **env;
  517. #ifdef USE_PAM
  518.   pam_handle_t **pamhp;
  519.   struct pam_conv pc = { pamconv, NULL };
  520. #endif
  521.  
  522.   /*
  523.    * These must be set before they are used.
  524.    */
  525.   __xdm_PingServer = dlfuncs->_PingServer;
  526.   __xdm_SessionPingFailed = dlfuncs->_SessionPingFailed;
  527.   __xdm_Debug = dlfuncs->_Debug;
  528.   __xdm_RegisterCloseOnFork = dlfuncs->_RegisterCloseOnFork;
  529.   __xdm_SecureDisplay = dlfuncs->_SecureDisplay;
  530.   __xdm_UnsecureDisplay = dlfuncs->_UnsecureDisplay;
  531.   __xdm_ClearCloseOnFork = dlfuncs->_ClearCloseOnFork;
  532.   __xdm_SetupDisplay = dlfuncs->_SetupDisplay;
  533.   __xdm_LogError = dlfuncs->_LogError;
  534.   __xdm_SessionExit = dlfuncs->_SessionExit;
  535.   __xdm_DeleteXloginResources = dlfuncs->_DeleteXloginResources;
  536.   __xdm_source = dlfuncs->_source;
  537.   __xdm_defaultEnv = dlfuncs->_defaultEnv;
  538.   __xdm_setEnv = dlfuncs->_setEnv;
  539.   __xdm_putEnv = dlfuncs->_putEnv;
  540.   __xdm_parseArgs = dlfuncs->_parseArgs;
  541.   __xdm_printEnv = dlfuncs->_printEnv;
  542.   __xdm_systemEnv = dlfuncs->_systemEnv;
  543.   __xdm_LogOutOfMem = dlfuncs->_LogOutOfMem;
  544.   __xdm_setgrent = dlfuncs->_setgrent;
  545.   __xdm_getgrent = dlfuncs->_getgrent;
  546.   __xdm_endgrent = dlfuncs->_endgrent;
  547.   __xdm_getspnam = dlfuncs->_getspnam;
  548.   __xdm_endspent = dlfuncs->_endspent;
  549.   __xdm_getpwnam = dlfuncs->_getpwnam;
  550.   __xdm_endpwent = dlfuncs->_endpwent;
  551.   __xdm_crypt = dlfuncs->_crypt;
  552. # ifdef USE_PAM
  553.   __xdm_thepamhp = dlfuncs->_thepamhp;
  554. # endif
  555.  
  556.   parse_config ();
  557.  
  558.   gtk_parse_args (0, NULL);
  559.   gd = gdk_display_open (d->name);
  560.   gdk_display_manager_set_default_display (gdk_display_manager_get (), gd);
  561.   *dpy = GDK_DISPLAY_XDISPLAY (gd);
  562.  
  563.   if (!*dpy)
  564.     {
  565.       LogError ("Cannot reopen display %s for greet window\n", d->name);
  566.       exit (3);
  567.     }
  568.  
  569.   gdk_x11_grab_server ();
  570.  
  571. #ifdef USE_PAM
  572.   pamhp = thepamhp ();
  573.  
  574.   pam_start ("xdm", NULL, &pc, pamhp);
  575.   pam_set_item (*pamhp, PAM_USER_PROMPT, ">");
  576.  
  577.   if (d->name[0] != ':')
  578.     {  
  579.       /* Displaying to remote host */
  580.       gchar *hostname = g_strdup (d->name);
  581.       gchar *colon = strrchr (hostname, ':');
  582.  
  583.       if (colon != NULL)
  584.     *colon = '\0';
  585.  
  586.       pam_set_item (*pamhp, PAM_RHOST, hostname);
  587.       g_free (hostname);
  588.     }
  589.   else         
  590.     pam_set_item (*pamhp, PAM_TTY, d->name);
  591. #endif
  592.  
  593.   if (!cfg->auto_login)
  594.     {
  595.       GdkWindow *root = gdk_get_default_root_window ();
  596.  
  597.       /* load specific theme */
  598.       if (cfg->theme)
  599.     g_object_set (gtk_settings_get_default (), "gtk-theme-name", cfg->theme, NULL);
  600.  
  601.       /* set cursor */
  602.       gdk_window_set_cursor (root, gdk_cursor_new_for_display (gd, GDK_LEFT_PTR));
  603.  
  604.       /* load background */
  605.       if (cfg->background && cfg->background[0])
  606.     {
  607.       GdkPixbuf *pb = NULL;
  608.       GError *err = NULL;
  609.       gint width, height;
  610.       gchar *filename = NULL;
  611.      
  612.       if (g_file_test (cfg->background, G_FILE_TEST_EXISTS))
  613.         filename = g_strdup (cfg->background);
  614.       else
  615.         filename = g_build_filename (WPDIR, cfg->background, NULL);
  616.  
  617.       gdk_window_get_size (GDK_WINDOW (root), &width, &height);
  618.       pb = gdk_pixbuf_new_from_file_at_scale (filename, width, height, FALSE, &err);
  619.       if (pb)
  620.         {
  621.           GdkPixmap *pm = NULL;
  622.           gdk_pixbuf_render_pixmap_and_mask (pb, &pm, NULL, 128);
  623.           gdk_window_set_back_pixmap (root, pm, FALSE);
  624.           gdk_window_clear (root);
  625.           g_object_unref (pb);
  626.         }
  627.       else
  628.         Debug ("Set background: %s", err->message);
  629.  
  630.       g_free (filename);
  631.     }
  632.  
  633.       /* create login window */
  634.       w = create_dialog ();
  635.       gtk_widget_show_all (w);
  636.  
  637.       gtk_widget_grab_default (w);
  638.       gtk_widget_grab_focus (le);
  639.  
  640.       gdk_keyboard_grab (gtk_widget_get_window (w), FALSE, GDK_CURRENT_TIME);
  641.  
  642.       gtk_main ();
  643.  
  644.       gtk_widget_destroy (w);
  645.  
  646.       gdk_keyboard_ungrab (GDK_CURRENT_TIME);
  647.       gdk_x11_ungrab_server ();
  648.  
  649.       Debug ("Greet loop finished\n");
  650.     }
  651.   else
  652.     {
  653.       uname = g_strdup (cfg->auto_user);
  654. #ifdef USE_PAM
  655.       pam_set_item (*pamhp, PAM_USER, uname);    
  656. #endif
  657.     }
  658.  
  659.   if (!uname)
  660.     return Greet_Failure;
  661.    
  662.   greet->name = uname;
  663.   p = getpwnam (greet->name);
  664.   endpwent ();
  665.  
  666.   verify->uid = p->pw_uid;
  667.   verify->gid = p->pw_gid;
  668.  
  669.   if (d->session)
  670.     verify->argv = parseArgs (NULL, d->session);
  671.   else
  672.     verify->argv = parseArgs (NULL, "Xsession");
  673.  
  674.   env = defaultEnv ();
  675.   env = setEnv (env, "DISPLAY", d->name);
  676.   env = setEnv (env, "HOME", p->pw_dir);
  677.   env = setEnv (env, "LOGNAME", p->pw_name); /* POSIX, System V */
  678.   env = setEnv (env, "USER", p->pw_name);    /* BSD */
  679.   env = setEnv (env, "PATH", cfg->path);
  680.   env = setEnv (env, "SHELL", p->pw_shell);
  681.   if (sess_cmd)
  682.     env = setEnv (env, "SESSION_COMMAND", sess_cmd);
  683.   verify->userEnviron = env;
  684.   Debug ("user environment:\n");
  685.   printEnv (verify->userEnviron);
  686.  
  687.   verify->systemEnviron = systemEnv (d, p->pw_name, p->pw_dir);
  688.   Debug ("system environment:\n");
  689.   printEnv (verify->systemEnviron);
  690.   Debug ("end of environments\n");
  691.  
  692.   g_free (cfg);
  693.   cfg = NULL;
  694.  
  695.   if (source (verify->systemEnviron, d->startup))
  696.     {
  697.       Debug ("Startup program %s exited with non-zero status\n", d->startup);
  698.       SessionExit (d, 0, FALSE);
  699.     }
  700.  
  701.   return Greet_Success;
  702. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement