1 /* Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. |
1 /* |
|
2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. |
2 * |
3 * |
3 * Permission is hereby granted, free of charge, to any person obtaining a |
4 * Permission is hereby granted, free of charge, to any person obtaining a |
4 * copy of this software and associated documentation files (the "Software"), |
5 * copy of this software and associated documentation files (the "Software"), |
5 * to deal in the Software without restriction, including without limitation |
6 * to deal in the Software without restriction, including without limitation |
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
37 * When shutting down, the Xserver restores it's original uid/gid as |
38 * When shutting down, the Xserver restores it's original uid/gid as |
38 * needed by the cleanup/teardown actions in several drivers. |
39 * needed by the cleanup/teardown actions in several drivers. |
39 * |
40 * |
40 * For the original definition, see Sun ASARC case 1995/390 |
41 * For the original definition, see Sun ASARC case 1995/390 |
41 */ |
42 */ |
|
43 |
|
44 #ifdef HAVE_DIX_CONFIG_H |
|
45 #include <dix-config.h> |
|
46 #endif |
42 |
47 |
43 #include <X11/Xos.h> |
48 #include <X11/Xos.h> |
44 #include <sys/param.h> |
49 #include <sys/param.h> |
45 #include <sys/socket.h> |
50 #include <sys/socket.h> |
46 #include <netinet/in.h> |
51 #include <netinet/in.h> |
97 |
102 |
98 /* Data stored in screen privates */ |
103 /* Data stored in screen privates */ |
99 struct dmScreenPriv { |
104 struct dmScreenPriv { |
100 CloseScreenProcPtr CloseScreen; |
105 CloseScreenProcPtr CloseScreen; |
101 }; |
106 }; |
102 static int dmScreenKeyIndex; |
107 static DevPrivateKeyRec dmScreenKeyRec; |
103 static DevPrivateKey dmScreenKey = &dmScreenKeyIndex; |
108 #define dmScreenKey (&dmScreenKeyRec) |
104 static struct dmdata *dmHandlerData; |
109 static struct dmdata *dmHandlerData; |
105 static struct dmuser originalUser; /* user to switch back to in CloseDown */ |
110 static struct dmuser originalUser; /* user to switch back to in CloseDown */ |
106 |
111 |
107 static Bool DtloginCloseScreen(int i, ScreenPtr pScreen); |
112 static Bool DtloginCloseScreen(int i, ScreenPtr pScreen); |
108 static void DtloginBlockHandler(pointer, struct timeval **, pointer); |
113 static void DtloginBlockHandler(pointer, struct timeval **, pointer); |
136 originalUser.homedir = getcwd(NULL, 0); |
141 originalUser.homedir = getcwd(NULL, 0); |
137 originalUser.projid = getprojid(); |
142 originalUser.projid = getprojid(); |
138 |
143 |
139 if (getuid() != 0) return; |
144 if (getuid() != 0) return; |
140 |
145 |
141 dmd = Xcalloc(sizeof(struct dmdata)); |
146 dmd = calloc(1, sizeof(struct dmdata)); |
142 if (dmd == NULL) { |
147 if (dmd == NULL) { |
143 DtloginError("Failed to allocate %d bytes for display manager pipe", |
148 DtloginError("Failed to allocate %d bytes for display manager pipe", |
144 sizeof(struct dmdata)); |
149 sizeof(struct dmdata)); |
145 return; |
150 return; |
146 } |
151 } |
195 /* Unwrap CloseScreen and call down to further levels */ |
200 /* Unwrap CloseScreen and call down to further levels */ |
196 pScreenPriv = (struct dmScreenPriv *) |
201 pScreenPriv = (struct dmScreenPriv *) |
197 dixLookupPrivate(&pScreen->devPrivates, dmScreenKey); |
202 dixLookupPrivate(&pScreen->devPrivates, dmScreenKey); |
198 |
203 |
199 pScreen->CloseScreen = pScreenPriv->CloseScreen; |
204 pScreen->CloseScreen = pScreenPriv->CloseScreen; |
200 xfree ((pointer) pScreenPriv); |
205 free (pScreenPriv); |
201 |
206 |
202 return (*pScreen->CloseScreen) (i, pScreen); |
207 return (*pScreen->CloseScreen) (i, pScreen); |
203 } |
208 } |
204 |
209 |
205 static void |
210 static void |
277 RemoveBlockAndWakeupHandlers (DtloginBlockHandler, |
282 RemoveBlockAndWakeupHandlers (DtloginBlockHandler, |
278 DtloginWakeupHandler, dmd); |
283 DtloginWakeupHandler, dmd); |
279 |
284 |
280 close(dmd->pipeFD); |
285 close(dmd->pipeFD); |
281 remove(dmd->pipename); |
286 remove(dmd->pipename); |
282 xfree(dmd->pipename); |
287 free(dmd->pipename); |
283 xfree(dmd->buf); |
288 free(dmd->buf); |
284 xfree(dmd->user.homedir); |
289 free(dmd->user.homedir); |
285 xfree(dmd); |
290 free(dmd); |
286 |
291 |
287 if (dmHandlerData == dmd) { |
292 if (dmHandlerData == dmd) { |
288 dmHandlerData = NULL; |
293 dmHandlerData = NULL; |
289 } |
294 } |
290 } |
295 } |
310 * Realloc only if buf has filled up and we don't have a record |
315 * Realloc only if buf has filled up and we don't have a record |
311 * delimiter yet. Keep track of alloced size. |
316 * delimiter yet. Keep track of alloced size. |
312 */ |
317 */ |
313 if (bufLen > (dmd->bufsize/2)) { |
318 if (bufLen > (dmd->bufsize/2)) { |
314 dmd->bufsize += BUFLEN; |
319 dmd->bufsize += BUFLEN; |
315 dmd->buf = xrealloc(dmd->buf, dmd->bufsize); |
320 dmd->buf = realloc(dmd->buf, dmd->bufsize); |
316 } |
321 } |
317 |
322 |
318 nbRead = read(dmd->pipeFD, dmd->buf + bufLen, |
323 nbRead = read(dmd->pipeFD, dmd->buf + bufLen, |
319 dmd->bufsize - bufLen - 1); |
324 dmd->bufsize - bufLen - 1); |
320 |
325 |
423 dmd->user.homedir = xstrdup(v); |
428 dmd->user.homedir = xstrdup(v); |
424 } |
429 } |
425 else if ( (strcmp(k, "UID") == 0) || (strcmp(k, "GID") == 0) |
430 else if ( (strcmp(k, "UID") == 0) || (strcmp(k, "GID") == 0) |
426 || (strcmp(k, "G_LIST_ID") == 0) ) { |
431 || (strcmp(k, "G_LIST_ID") == 0) ) { |
427 /* Value is numeric, convert to int */ |
432 /* Value is numeric, convert to int */ |
428 int val; |
433 long val; |
429 |
434 |
430 errno = 0; |
435 errno = 0; |
431 val = strtol(v, NULL, 10); |
436 val = strtol(v, NULL, 10); |
432 |
437 |
433 if ((val == 0) && (strcmp(v, "0") != 0)) { |
438 if ((val == 0) && (strcmp(v, "0") != 0)) { |
442 DtloginInfo("Out of range number \"%s\"\n", v); |
447 DtloginInfo("Out of range number \"%s\"\n", v); |
443 continue; |
448 continue; |
444 } |
449 } |
445 |
450 |
446 if (strcmp(k, "UID") == 0) { |
451 if (strcmp(k, "UID") == 0) { |
447 dmd->user.uid = val; |
452 dmd->user.uid = (uid_t) val; |
448 } |
453 } |
449 else if (strcmp(k, "GID") == 0) { |
454 else if (strcmp(k, "GID") == 0) { |
450 dmd->user.gid = val; |
455 dmd->user.gid = (gid_t) val; |
451 } |
456 } |
452 else if (strcmp(k, "G_LIST_ID") == 0) { |
457 else if (strcmp(k, "G_LIST_ID") == 0) { |
453 if (dmd->user.groupid_cnt < NGROUPS_UMAX) { |
458 if (dmd->user.groupid_cnt < NGROUPS_UMAX) { |
454 dmd->user.groupids[dmd->user.groupid_cnt++] = val; |
459 dmd->user.groupids[dmd->user.groupid_cnt++] = (gid_t) val; |
455 } |
460 } |
456 } |
461 } |
457 } |
462 } |
458 else { |
463 else { |
459 DtloginInfo("Unrecognized key \"%s\"\n", k); |
464 DtloginInfo("Unrecognized key \"%s\"\n", k); |
546 |
551 |
547 /* Wrap closeScreen to allow resetting uid on closedown */ |
552 /* Wrap closeScreen to allow resetting uid on closedown */ |
548 if ((user->uid != 0) && (user != &originalUser)) { |
553 if ((user->uid != 0) && (user != &originalUser)) { |
549 int i; |
554 int i; |
550 |
555 |
551 for (i = 0; i < screenInfo.numScreens; i++) |
556 if (dixRegisterPrivateKey(dmScreenKey, PRIVATE_SCREEN, 0)) { |
552 { |
557 for (i = 0; i < screenInfo.numScreens; i++) |
553 ScreenPtr pScreen = screenInfo.screens[i]; |
558 { |
554 struct dmScreenPriv *pScreenPriv; |
559 ScreenPtr pScreen = screenInfo.screens[i]; |
555 |
560 struct dmScreenPriv *pScreenPriv |
556 pScreenPriv = (struct dmScreenPriv *) |
561 = calloc(1, sizeof(struct dmScreenPriv)); |
557 Xcalloc(sizeof(struct dmScreenPriv)); |
562 |
558 dixSetPrivate(&pScreen->devPrivates, dmScreenKey, pScreenPriv); |
563 dixSetPrivate(&pScreen->devPrivates, dmScreenKey, |
559 |
564 pScreenPriv); |
560 if (pScreenPriv != NULL) { |
565 |
561 pScreenPriv->CloseScreen = pScreen->CloseScreen; |
566 if (pScreenPriv != NULL) { |
562 pScreen->CloseScreen = DtloginCloseScreen; |
567 pScreenPriv->CloseScreen = pScreen->CloseScreen; |
|
568 pScreen->CloseScreen = DtloginCloseScreen; |
|
569 } else { |
|
570 DtloginError("Failed to allocate %d bytes" |
|
571 " for uid reset info", |
|
572 sizeof(struct dmScreenPriv)); |
|
573 } |
563 } |
574 } |
|
575 } else { |
|
576 DtloginError("Failed to register screen private %s", |
|
577 "for uid reset info"); |
564 } |
578 } |
565 } |
579 } |
566 } |
580 } |
567 |
581 |
568 if (user->homedir != NULL) { |
582 if (user->homedir != NULL) { |