Lines 48-54
uid_gid_string (uid_t uid,
Link Here
|
48 |
return buf; |
48 |
return buf; |
49 |
} |
49 |
} |
50 |
|
50 |
|
51 |
static int |
51 |
static gboolean |
52 |
set_ids_by_number (uid_t uid, |
52 |
set_ids_by_number (uid_t uid, |
53 |
gid_t gid, |
53 |
gid_t gid, |
54 |
char **message_ret) |
54 |
char **message_ret) |
Lines 96-102
set_ids_by_number (uid_t uid,
Link Here
|
96 |
|
96 |
|
97 |
g_free (reason); |
97 |
g_free (reason); |
98 |
|
98 |
|
99 |
return 0; |
99 |
return TRUE; |
100 |
} else { |
100 |
} else { |
101 |
char *reason = NULL; |
101 |
char *reason = NULL; |
102 |
|
102 |
|
Lines 141-149
set_ids_by_number (uid_t uid,
Link Here
|
141 |
g_free (reason); |
141 |
g_free (reason); |
142 |
reason = NULL; |
142 |
reason = NULL; |
143 |
} |
143 |
} |
144 |
|
144 |
return FALSE; |
145 |
return -1; |
|
|
146 |
} |
145 |
} |
|
|
146 |
return FALSE; |
147 |
} |
147 |
} |
148 |
|
148 |
|
149 |
|
149 |
|
Lines 165-176
hack_uid (char **nolock_reason,
Link Here
|
165 |
char **orig_uid, |
165 |
char **orig_uid, |
166 |
char **uid_message) |
166 |
char **uid_message) |
167 |
{ |
167 |
{ |
168 |
if (nolock_reason) |
168 |
char *reason; |
|
|
169 |
gboolean ret; |
170 |
|
171 |
ret = TRUE; |
172 |
reason = NULL; |
173 |
|
174 |
if (nolock_reason != NULL) { |
169 |
*nolock_reason = NULL; |
175 |
*nolock_reason = NULL; |
170 |
if (orig_uid) |
176 |
} |
|
|
177 |
if (orig_uid != NULL) { |
171 |
*orig_uid = NULL; |
178 |
*orig_uid = NULL; |
172 |
if (uid_message) |
179 |
} |
|
|
180 |
if (uid_message != NULL) { |
173 |
*uid_message = NULL; |
181 |
*uid_message = NULL; |
|
|
182 |
} |
174 |
|
183 |
|
175 |
/* Discard privileges, and set the effective user/group ids to the |
184 |
/* Discard privileges, and set the effective user/group ids to the |
176 |
real user/group ids. That is, give up our "chmod +s" rights. |
185 |
real user/group ids. That is, give up our "chmod +s" rights. |
Lines 181-192
hack_uid (char **nolock_reason,
Link Here
|
181 |
uid_t uid = getuid (); |
190 |
uid_t uid = getuid (); |
182 |
gid_t gid = getgid (); |
191 |
gid_t gid = getgid (); |
183 |
|
192 |
|
184 |
if (orig_uid) |
193 |
if (orig_uid != NULL) { |
185 |
*orig_uid = uid_gid_string (euid, egid); |
194 |
*orig_uid = uid_gid_string (euid, egid); |
|
|
195 |
} |
196 |
|
197 |
if (uid != euid || gid != egid) { |
198 |
if (! set_ids_by_number (uid, gid, uid_message)) { |
199 |
reason = g_strdup ("unable to discard privileges."); |
186 |
|
200 |
|
187 |
if (uid != euid || gid != egid) |
201 |
ret = FALSE; |
188 |
if (set_ids_by_number (uid, gid, uid_message) != 0) |
202 |
goto out; |
189 |
return FALSE; |
203 |
} |
|
|
204 |
} |
190 |
} |
205 |
} |
191 |
|
206 |
|
192 |
|
207 |
|
Lines 200-280
hack_uid (char **nolock_reason,
Link Here
|
200 |
and "USING XDM". |
215 |
and "USING XDM". |
201 |
*/ |
216 |
*/ |
202 |
if (getuid () == (uid_t) 0) { |
217 |
if (getuid () == (uid_t) 0) { |
203 |
if (nolock_reason) |
218 |
reason = g_strdup ("running as root"); |
204 |
*nolock_reason = g_strdup ("running as root"); |
219 |
ret = FALSE; |
205 |
return FALSE; |
220 |
goto out; |
206 |
} |
221 |
} |
207 |
|
222 |
|
208 |
/* If we're running as root, switch to a safer user. This is above and |
223 |
out: |
209 |
beyond the fact that we've disabling locking, above -- the theory is |
224 |
if (nolock_reason != NULL) { |
210 |
that running graphics demos as root is just always a stupid thing |
225 |
*nolock_reason = g_strdup (reason); |
211 |
to do, since they have probably never been security reviewed and are |
|
|
212 |
more likely to be buggy than just about any other kind of program. |
213 |
(And that assumes non-malicious code. There are also attacks here.) |
214 |
|
215 |
*** WARNING: DO NOT DISABLE THIS CODE! |
216 |
If you do so, you will open a security hole. See the sections |
217 |
of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", |
218 |
and "USING XDM". |
219 |
*/ |
220 |
if (getuid () == (uid_t) 0) { |
221 |
struct passwd *p; |
222 |
|
223 |
p = getpwnam ("nobody"); |
224 |
if (! p) p = getpwnam ("noaccess"); |
225 |
if (! p) p = getpwnam ("daemon"); |
226 |
if (! p) { |
227 |
g_warning ("running as root, and couldn't find a safer uid."); |
228 |
return FALSE; |
229 |
} |
230 |
|
231 |
if (set_ids_by_number (p->pw_uid, p->pw_gid, uid_message) != 0) |
232 |
return FALSE; |
233 |
} |
234 |
|
235 |
|
236 |
/* If there's anything even remotely funny looking about the passwd struct, |
237 |
or if we're running as some other user from the list below (a |
238 |
non-comprehensive selection of users known to be privileged in some way, |
239 |
and not normal end-users) then disable locking. If it was possible, |
240 |
switching to "nobody" would be the thing to do, but only root itself has |
241 |
the privs to do that. |
242 |
|
243 |
*** WARNING: DO NOT DISABLE THIS CODE! |
244 |
If you do so, you will open a security hole. See the sections |
245 |
of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", |
246 |
and "USING XDM". |
247 |
*/ |
248 |
{ |
249 |
uid_t uid = getuid (); /* get it again */ |
250 |
struct passwd *p = getpwuid (uid); /* get it again */ |
251 |
|
252 |
if (!p || |
253 |
uid == (uid_t) 0 || |
254 |
uid == (uid_t) -1 || |
255 |
uid == (uid_t) -2 || |
256 |
p->pw_uid == (uid_t) 0 || |
257 |
p->pw_uid == (uid_t) -1 || |
258 |
p->pw_uid == (uid_t) -2 || |
259 |
!p->pw_name || |
260 |
!*p->pw_name || |
261 |
!strcmp (p->pw_name, "root") || |
262 |
!strcmp (p->pw_name, "nobody") || |
263 |
!strcmp (p->pw_name, "noaccess") || |
264 |
!strcmp (p->pw_name, "operator") || |
265 |
!strcmp (p->pw_name, "daemon") || |
266 |
!strcmp (p->pw_name, "bin") || |
267 |
!strcmp (p->pw_name, "adm") || |
268 |
!strcmp (p->pw_name, "sys") || |
269 |
!strcmp (p->pw_name, "games")) { |
270 |
if (nolock_reason) |
271 |
*nolock_reason = g_strdup_printf ("running as %s", |
272 |
(p && p->pw_name |
273 |
&& *p->pw_name |
274 |
? p->pw_name : "<unknown>")); |
275 |
return FALSE; |
276 |
} |
277 |
} |
226 |
} |
|
|
227 |
g_free (reason); |
278 |
|
228 |
|
279 |
return TRUE; |
229 |
return ret; |
280 |
} |
230 |
} |