components/gnome/gdm/patches/0004-sdtlogin.patch
changeset 7201 bcc18175756d
child 7567 1ac26224c2cb
equal deleted inserted replaced
7200:bc003d56ef5a 7201:bcc18175756d
       
     1 From f7978982d31f67867d8200f9f3102eb423312abc Mon Sep 17 00:00:00 2001
       
     2 From: Alan Coopersmith <[email protected]>
       
     3 Date: Tue, 29 Dec 2015 12:50:16 -0800
       
     4 Subject: [PATCH 04/19] sdtlogin
       
     5 
       
     6 Adds SDTLOGIN interface, which drops the Xserver to user
       
     7 perms rather than running as root, for added security on Solaris.
       
     8 Original date:2008-05-06 owner:yippi type:feature
       
     9 
       
    10 For the original definition, see Sun ASARC case 1995/390.
       
    11 For the current implementation in the X server, see sun-src/os/dtlogin.c
       
    12 and dtlogin-userinfo.patch in open-src/xserver/xorg in the X gate.
       
    13 ---
       
    14  common/gdm-common.h         |   5 ++
       
    15  daemon/gdm-server.c         |  11 +++++
       
    16  daemon/gdm-session-worker.c | 116 ++++++++++++++++++++++++++++++++++++++++++++
       
    17  daemon/main.c               |  15 ++++++
       
    18  4 files changed, 147 insertions(+)
       
    19 
       
    20 diff --git a/common/gdm-common.h b/common/gdm-common.h
       
    21 index 19dbbbb..6ac61c0 100644
       
    22 --- a/common/gdm-common.h
       
    23 +++ b/common/gdm-common.h
       
    24 @@ -42,6 +42,11 @@ GQuark gdm_common_error_quark (void);
       
    25  typedef char * (*GdmExpandVarFunc) (const char *var,
       
    26                                      gpointer user_data);
       
    27  
       
    28 +#ifdef __sun
       
    29 +#define GDM_DT_DIR "/var/dt"
       
    30 +#define GDM_SDTLOGIN_DIR "/var/dt/sdtlogin"
       
    31 +#endif
       
    32 +
       
    33  G_BEGIN_DECLS
       
    34  
       
    35  int            gdm_wait_on_pid           (int pid);
       
    36 diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
       
    37 index 08f2354..2cec263 100644
       
    38 --- a/daemon/gdm-server.c
       
    39 +++ b/daemon/gdm-server.c
       
    40 @@ -742,6 +742,17 @@ gdm_server_spawn (GdmServer    *server,
       
    41                  goto out;
       
    42          }
       
    43  
       
    44 +#if __sun
       
    45 +        /* Remove old communication pipe, if present */
       
    46 +        char *display_num = strchr(server->priv->display_name, ':');
       
    47 +        if (display_num != NULL && display_num[1] != '\0') {
       
    48 +                char *old_pipe = g_strdup_printf ("%s/%s", GDM_SDTLOGIN_DIR,
       
    49 +                                                  display_num + 1);
       
    50 +                VE_IGNORE_EINTR (g_remove (old_pipe));
       
    51 +                g_free (old_pipe);
       
    52 +        }
       
    53 +#endif
       
    54 +
       
    55          env = get_server_environment (server);
       
    56  
       
    57          freeme = g_strjoinv (" ", argv);
       
    58 diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
       
    59 index 291caad..93c9e82 100644
       
    60 --- a/daemon/gdm-session-worker.c
       
    61 +++ b/daemon/gdm-session-worker.c
       
    62 @@ -38,6 +38,7 @@
       
    63  #include <pwd.h>
       
    64  
       
    65  #if __sun
       
    66 +#include <sys/param.h>
       
    67  #define GDM_PAM_QUAL
       
    68  #else
       
    69  #define GDM_PAM_QUAL const
       
    70 @@ -2044,6 +2045,115 @@ out:
       
    71          return fd;
       
    72  }
       
    73  
       
    74 +#ifdef __sun
       
    75 +static void
       
    76 +solaris_xserver_cred (const char *username, struct passwd *passwd_entry,
       
    77 +                      const char *x11_display_name)
       
    78 +{
       
    79 +        FILE *fp;
       
    80 +        struct stat statbuf;
       
    81 +        gid_t  groups[NGROUPS_UMAX];
       
    82 +        char *tmp, *p, pipe[MAXPATHLEN], info[MAXPATHLEN];
       
    83 +        int display_number = 0;
       
    84 +        int fd, i;
       
    85 +        int ngroups;
       
    86 +
       
    87 +        if (g_access (passwd_entry->pw_dir, F_OK) != 0) {
       
    88 +                g_debug ("solaris_xserver_cred: no HOME dir access\n");
       
    89 +                return;
       
    90 +        }
       
    91 +
       
    92 +        /*
       
    93 +         * Handshake with server. Make sure it created a pipe.
       
    94 +         * Open and write.
       
    95 +         */
       
    96 +        if ((tmp = strstr (x11_display_name, ":")) != NULL) {
       
    97 +                tmp++;
       
    98 +                display_number = g_ascii_strtod (tmp, &p);
       
    99 +
       
   100 +                if (errno != 0) {
       
   101 +                        g_debug ("solaris_xserver_cred: problem getting display number\n");
       
   102 +                        return;
       
   103 +                }
       
   104 +        }
       
   105 +
       
   106 +        if (g_stat (GDM_SDTLOGIN_DIR, &statbuf) == 0) {
       
   107 +                if (! S_ISDIR(statbuf.st_mode)) {
       
   108 +                        g_debug ("solaris_xserver_cred: %s is not a directory\n",
       
   109 +                                 GDM_SDTLOGIN_DIR);
       
   110 +                        return;
       
   111 +                }
       
   112 +        } else {
       
   113 +                g_debug ("solaris_xserver_cred: %s does not exist\n", GDM_SDTLOGIN_DIR);
       
   114 +                return;
       
   115 +        }
       
   116 +
       
   117 +        snprintf (pipe, sizeof(pipe), "%s/%d", GDM_SDTLOGIN_DIR, display_number);
       
   118 +        fd = open (pipe, O_RDWR);
       
   119 +        g_remove (pipe);
       
   120 +
       
   121 +        if (fd < 0) {
       
   122 +                g_debug ("solaris_xserver_cred: could not open %s\n", pipe);
       
   123 +                return;
       
   124 +        }
       
   125 +        if (fstat (fd, &statbuf) == 0 ) {
       
   126 +                if (! S_ISFIFO(statbuf.st_mode)) {
       
   127 +                        close (fd);
       
   128 +                        g_debug ("solaris_xserver_cred: %s is not a pipe\n", pipe);
       
   129 +                        return;
       
   130 +                }
       
   131 +        } else {
       
   132 +                close (fd);
       
   133 +                g_debug ("solaris_xserver_cred: %s does not exist\n", pipe);
       
   134 +                return;
       
   135 +        }
       
   136 +        fp = fdopen (fd, "w");
       
   137 +        if (fp == NULL) {
       
   138 +                close (fd);
       
   139 +                g_debug ("solaris_xserver_cred: could not fdopen %s\n", pipe);
       
   140 +                return;
       
   141 +        }
       
   142 +
       
   143 +        snprintf (info, sizeof(info), "GID=\"%d\"; ", passwd_entry->pw_gid);
       
   144 +        fputs (info, fp);
       
   145 +        g_debug ("solaris_xserver_cred: %s\n", info);
       
   146 +
       
   147 +        if (initgroups (username, passwd_entry->pw_gid) == -1) {
       
   148 +                ngroups = 0;
       
   149 +        } else {
       
   150 +                ngroups = getgroups (NGROUPS_UMAX, groups);
       
   151 +        }
       
   152 +
       
   153 +        for (i=0; i < ngroups; i++) {
       
   154 +                snprintf (info, sizeof(info), "G_LIST_ID=\"%u\" ", groups[i]);
       
   155 +                fputs (info, fp);
       
   156 +                g_debug ("solaris_xserver_cred: %s\n", info);
       
   157 +        }
       
   158 +
       
   159 +        if (ngroups > 0) {
       
   160 +                fputc (';', fp);
       
   161 +        }
       
   162 +
       
   163 +        snprintf (info, sizeof(info), " HOME=\"%s\" ", passwd_entry->pw_dir);
       
   164 +        fputs (info, fp);
       
   165 +        g_debug ("solaris_xserver_cred: %s\n", info);
       
   166 +
       
   167 +        snprintf (info, sizeof(info), " UID=\"%d\" EOF=\"\";", passwd_entry->pw_uid);
       
   168 +        fputs (info, fp);
       
   169 +        g_debug ("solaris_xserver_cred: %s\n", info);
       
   170 +
       
   171 +        /*
       
   172 +         * Handshake with server. Make sure it read the pipe.
       
   173 +         *
       
   174 +         * Close file descriptor.
       
   175 +         */
       
   176 +        fflush (fp);
       
   177 +        fclose (fp);
       
   178 +
       
   179 +        return;
       
   180 +}
       
   181 +#endif
       
   182 +
       
   183  static gboolean
       
   184  gdm_session_worker_start_session (GdmSessionWorker  *worker,
       
   185                                    GError           **error)
       
   186 @@ -2061,6 +2171,12 @@ gdm_session_worker_start_session (GdmSessionWorker  *worker,
       
   187                           worker->priv->arguments[0]);
       
   188          }
       
   189  
       
   190 +#ifdef __sun
       
   191 +        solaris_xserver_cred (worker->priv->username,
       
   192 +                              passwd_entry,
       
   193 +                              worker->priv->x11_display_name);
       
   194 +#endif
       
   195 +
       
   196          error_code = PAM_SUCCESS;
       
   197  
       
   198  #ifdef WITH_SYSTEMD
       
   199 diff --git a/daemon/main.c b/daemon/main.c
       
   200 index ca2dda3..50f6e94 100644
       
   201 --- a/daemon/main.c
       
   202 +++ b/daemon/main.c
       
   203 @@ -324,6 +324,21 @@ main (int    argc,
       
   204  
       
   205          block_sigusr1 ();
       
   206  
       
   207 +#ifdef __sun
       
   208 +        {
       
   209 +                struct stat statbuf;
       
   210 +                int r;
       
   211 +
       
   212 +                r = stat (GDM_DT_DIR, &statbuf);
       
   213 +                if (r < 0) {
       
   214 +                        g_mkdir (GDM_DT_DIR, 0755);
       
   215 +                }
       
   216 +
       
   217 +                g_remove (GDM_SDTLOGIN_DIR);
       
   218 +                g_mkdir (GDM_SDTLOGIN_DIR, 0700);
       
   219 +        }
       
   220 +#endif
       
   221 +
       
   222          bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
       
   223          textdomain (GETTEXT_PACKAGE);
       
   224          setlocale (LC_ALL, "");
       
   225 -- 
       
   226 2.7.4
       
   227