open-src/xserver/xorg/sun-src/os/dtlogin.c
changeset 1088 1c99106ccbe0
parent 943 294f64612d23
equal deleted inserted replaced
1087:a8aa060182e1 1088:1c99106ccbe0
     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     }
   152     displayNumber = atoi(display); /* Assigned in dix/main.c */
   157     displayNumber = atoi(display); /* Assigned in dix/main.c */
   153 
   158 
   154     dmd->pipeFD = dtlogin_create_pipe(displayNumber, dmd);
   159     dmd->pipeFD = dtlogin_create_pipe(displayNumber, dmd);
   155 
   160 
   156     if (dmd->pipeFD == -1) {
   161     if (dmd->pipeFD == -1) {
   157 	xfree(dmd);
   162 	free(dmd);
   158 	return;
   163 	return;
   159     }
   164     }
   160 
   165 
   161     dmHandlerData = dmd;
   166     dmHandlerData = dmd;
   162 
   167 
   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 }
   296     char *p, *n;
   301     char *p, *n;
   297     int done = 0;
   302     int done = 0;
   298 
   303 
   299     if (dmd->buf == NULL) {
   304     if (dmd->buf == NULL) {
   300 	dmd->bufsize = BUFLEN;
   305 	dmd->bufsize = BUFLEN;
   301 	dmd->buf = xalloc(dmd->bufsize);
   306 	dmd->buf = malloc(dmd->bufsize);
   302 	dmd->buf[0] = '\0';
   307 	dmd->buf[0] = '\0';
   303     }
   308     }
   304 
   309 
   305     /* Read data from pipe and split into tokens, buffering the rest */
   310     /* Read data from pipe and split into tokens, buffering the rest */
   306     while (!done) {
   311     while (!done) {
   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) {