|
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 |