コード例 #1
0
ファイル: loghelpers.c プロジェクト: raorn/wdm
void WDMRedirectStderr(int level)
{
    int errpipe[2];
    int exitstatus;

    if (pipe(errpipe) == -1)
        WDMError("cannot create pipe. " "all stderr messages will go to stderr\n");

    childpid = fork();
    if (childpid == -1) {
        WDMError("fork failed. " "all stderr messages will go to stderr\n");
        close(errpipe[0]);
        close(errpipe[1]);
    } else if (childpid != 0) {
        /* parent, will read all messages from stderr and
         * redirect it to log */
        Signal(SIGTERM, WDMRedirectSignals);
        Signal(SIGINT, WDMRedirectSignals);
        Signal(SIGHUP, WDMRedirectSignals);
        close(errpipe[1]);
        exitstatus = WDMRedirectFileToLog(WDM_LEVEL_ERROR, childpid, errpipe[0]);
        close(errpipe[0]);
        exit(exitstatus);
    }

    /* child, will close read end of pipe and dup2
     * write end of pipe to stderr */
    close(errpipe[0]);
    RegisterCloseOnFork(errpipe[1]);
    dup2(errpipe[1], 2);
}
コード例 #2
0
ファイル: session.c プロジェクト: bbidulock/wdm
void SecureDisplay(struct display *d, Display * dpy)
{
	WDMDebug("SecureDisplay %s\n", d->name);
	(void)Signal(SIGALRM, syncTimeout);
	if (Setjmp(syncJump)) {
		WDMError("WARNING: display %s could not be secured\n", d->name);
		SessionExit(d, RESERVER_DISPLAY, FALSE);
	}
	(void)alarm((unsigned)d->grabTimeout);
	WDMDebug("Before XGrabServer %s\n", d->name);
	XGrabServer(dpy);
	if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) {
		(void)alarm(0);
		(void)Signal(SIGALRM, SIG_DFL);
		WDMError("WARNING: keyboard on display %s could not be secured\n", d->name);
		SessionExit(d, RESERVER_DISPLAY, FALSE);
	}
	WDMDebug("XGrabKeyboard succeeded %s\n", d->name);
	(void)alarm(0);
	(void)Signal(SIGALRM, SIG_DFL);
	pseudoReset(dpy);
	if (!d->grabServer) {
		XUngrabServer(dpy);
		XSync(dpy, 0);
	}
	WDMDebug("done secure %s\n", d->name);
}
コード例 #3
0
ファイル: server.c プロジェクト: bbidulock/wdm
static int StartServerOnce(struct display *d)
{
	char **f;
	char **argv;
	char arg[1024];
	int pid;

	WDMDebug("StartServer for %s\n", d->name);
	receivedUsr1 = 0;
	(void)Signal(SIGUSR1, CatchUsr1);
	argv = d->argv;
	switch (pid = fork()) {
	case 0:
		CleanUpChild();
#ifdef XDMCP
		/* The chooser socket is not closed by CleanUpChild() */
		DestroyWellKnownSockets();
#endif
		if (d->authFile) {
			sprintf(arg, "-auth %s", d->authFile);
			argv = parseArgs(argv, arg);
		}
		if (!argv) {
			WDMError("StartServer: no arguments\n");
			sleep((unsigned)d->openDelay);
			exit(UNMANAGE_DISPLAY);
		}
		for (f = argv; *f; f++)
			WDMDebug("'%s' ", *f);
		WDMDebug("\n");
		/*
		 * give the server SIGUSR1 ignored,
		 * it will notice that and send SIGUSR1
		 * when ready
		 */
		(void)Signal(SIGUSR1, SIG_IGN);
		(void)execv(argv[0], argv);
		WDMError("server %s cannot be executed\n", argv[0]);
		sleep((unsigned)d->openDelay);
		exit(REMANAGE_DISPLAY);
	case -1:
		WDMError("fork failed, sleeping\n");
		return 0;
	default:
		break;
	}
	WDMDebug("Server Started %d\n", pid);
	d->serverPid = pid;
	if (serverPause((unsigned)d->openDelay, pid))
		return FALSE;
	return TRUE;
}
コード例 #4
0
ファイル: session.c プロジェクト: bbidulock/wdm
void SessionExit(struct display *d, int status, int removeAuth)
{
#ifdef USE_PAM
	pam_handle_t *pamh = thepamh();
	if (pamh) {
		/* shutdown PAM session */
		if (pam_setcred(pamh, PAM_DELETE_CRED) != PAM_SUCCESS)
			WDMError("pam_setcred(DELETE_CRED) failed, errno=%d", errno);
		pam_close_session(pamh, 0);
		pam_end(pamh, PAM_SUCCESS);
		pamh = NULL;
	}
#endif

	/* make sure the server gets reset after the session is over */
	if (d->serverPid >= 2 && d->resetSignal)
		kill(d->serverPid, d->resetSignal);
	else
		ResetServer(d);
	if (removeAuth) {
		setgid(verify.gid);
		setuid(verify.uid);
		RemoveUserAuthorization(d, &verify);
	}
	WDMDebug("Display %s exiting with status %d\n", d->name, status);
	exit(status);
}
コード例 #5
0
ファイル: loghelpers.c プロジェクト: raorn/wdm
int WDMRedirectFileToLog(int level, pid_t pid, int fd)
{
    fd_set set;
    int status;
    struct timeval tv;
    char buf[1024];
    int n;

    WDMDebug("logger started\n");
    while (waitpid(pid, &status, WNOHANG) == 0) {
        FD_ZERO(&set);
        FD_SET(fd, &set);
        tv.tv_sec = 1;
        tv.tv_usec = 0;
        if (select(fd + 1, &set, NULL, NULL, &tv) > 0) {
            n = read(fd, buf, sizeof(buf));
            if (n == -1)
                WDMError("error reading form pipe(stderr)\n");

            WDMBufferedLogMessages(level, buf, n);
        }
    }
    WDMBufferedLogMessages(level, "\n", 1);
    WDMDebug("logger stopped\n");

    return WEXITSTATUS(status);
}
コード例 #6
0
ファイル: session.c プロジェクト: bbidulock/wdm
static void AbortClient(int pid)
{
	int sig = SIGTERM;
	volatile int i;
	int retId;

	for (i = 0; i < 4; i++) {
		if (killpg(pid, sig) == -1) {
			switch (errno) {
			case EPERM:
				WDMError("wdm can't kill client\n");
			case EINVAL:
			case ESRCH:
				return;
			}
		}
		if (!Setjmp(tenaciousClient)) {
			(void)Signal(SIGALRM, waitAbort);
			(void)alarm((unsigned)10);
			retId = wait((waitType *) 0);
			(void)alarm((unsigned)0);
			(void)Signal(SIGALRM, SIG_DFL);
			if (retId == pid)
				break;
		} else
			(void)Signal(SIGALRM, SIG_DFL);
		sig = SIGKILL;
	}
}
コード例 #7
0
ファイル: config.c プロジェクト: cz172638/wdm
WDMLoginConfig *
LoadConfiguration(char *configFile)
{
	char *filename = configFile ? configFile : DEF_WDMLOGIN_CONFIG;
	WMPropList *db;
	WDMLoginConfig *config = NULL;

	db = WMReadPropListFromFile(filename);
	if(db == NULL)
		WDMError("Cannot open config file. Using builtin defaults\n");
	if(!WDMCheckPLDictionary(db, &wdmLogin_config, &config))
		WDMError("Error parsing config file. Using builtin defaults\n");
	if(db)
		WMReleasePropList(db);
	return config;
}
コード例 #8
0
ファイル: dm.c プロジェクト: bbidulock/wdm
static void ScanServers(void)
{
	char lineBuf[10240];
	int len;
	FILE *serversFile;
	struct stat statb;
	static DisplayType acceptableTypes[] = { {Local, Permanent, FromFile},
	{Foreign, Permanent, FromFile},
	};

#define NumTypes    (sizeof (acceptableTypes) / sizeof (acceptableTypes[0]))

	if (servers[0] == '/') {
		serversFile = fopen(servers, "r");
		if (serversFile == NULL) {
			WDMError("cannot access servers file %s\n", servers);
			return;
		}
		if (ServersModTime == 0) {
			fstat(fileno(serversFile), &statb);
			ServersModTime = statb.st_mtime;
		}
		while (fgets(lineBuf, sizeof(lineBuf) - 1, serversFile)) {
			len = strlen(lineBuf);
			if (lineBuf[len - 1] == '\n')
				lineBuf[len - 1] = '\0';
			ParseDisplay(lineBuf, acceptableTypes, NumTypes);
		}
		fclose(serversFile);
	} else {
		ParseDisplay(servers, acceptableTypes, NumTypes);
	}
}
コード例 #9
0
ファイル: daemon.c プロジェクト: bbidulock/wdm
void BecomeOrphan(void)
{
	Pid_t child_id;

	/*
	 * fork so that the process goes into the background automatically. Also
	 * has a nice side effect of having the child process get inherited by
	 * init (pid 1).
	 * Separate the child into its own process group before the parent
	 * exits.  This eliminates the possibility that the child might get
	 * killed when the init script that's running wdm exits.
	 */

	child_id = fork();
	switch (child_id) {
	case 0:
		/* child */
		break;
	case -1:
		/* error */
		WDMError("daemon fork failed, errno = %d\n", errno);
		break;

	default:
		/* parent */

		exit(0);
	}
}
コード例 #10
0
ファイル: reset.c プロジェクト: cz172638/wdm
void
pseudoReset (Display *dpy)
{
	Window	root;
	int	screen;

	if (Setjmp (resetJmp)) {
		WDMError("pseudoReset timeout\n");
	} else {
		(void) Signal (SIGALRM, abortReset);
		(void) alarm (30);
		XSetErrorHandler (ignoreErrors);
		for (screen = 0; screen < ScreenCount (dpy); screen++) {
			WDMDebug("pseudoReset screen %d\n", screen);
			root = RootWindow (dpy, screen);
			killWindows (dpy, root);
		}
		WDMDebug("before XSync\n");
		XSync (dpy, False);
		(void) alarm (0);
	}
	Signal (SIGALRM, SIG_DFL);
	XSetErrorHandler ((XErrorHandler)0 );
	WDMDebug("pseudoReset done\n");
}
コード例 #11
0
ファイル: session.c プロジェクト: bbidulock/wdm
static int ErrorHandler(Display * dpy, XErrorEvent * event)
{
	WDMError("X error\n");
	if (XmuPrintDefaultErrorMessage(dpy, event, stderr) == 0)
		return 0;
	exit(UNMANAGE_DISPLAY);
 /*NOTREACHED*/}
コード例 #12
0
ファイル: dm.c プロジェクト: bbidulock/wdm
static int StorePid(void)
{
	int oldpid;

	if (pidFile[0] != '\0') {
		pidFd = open(pidFile, O_RDWR);
		if (pidFd == -1 && errno == ENOENT)
			pidFd = open(pidFile, O_RDWR | O_CREAT, 0666);
		if (pidFd == -1 || !(pidFilePtr = fdopen(pidFd, "r+"))) {
			WDMError("process-id file %s cannot be opened\n", pidFile);
			return -1;
		}
		if (fscanf(pidFilePtr, "%d\n", &oldpid) != 1)
			oldpid = -1;
		fseek(pidFilePtr, 0l, 0);
		if (lockPidFile.i) {
#ifdef F_SETLK
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
			struct flock lock_data;
			lock_data.l_type = F_WRLCK;
			lock_data.l_whence = SEEK_SET;
			lock_data.l_start = lock_data.l_len = 0;
			if (fcntl(pidFd, F_SETLK, &lock_data) == -1) {
				if (errno == EAGAIN)
					return oldpid;
				else
					return -1;
			}
#else
#ifdef LOCK_EX
			if (flock(pidFd, LOCK_EX | LOCK_NB) == -1) {
				if (errno == EWOULDBLOCK)
					return oldpid;
				else
					return -1;
			}
#else
			if (lockf(pidFd, F_TLOCK, 0) == -1) {
				if (errno == EACCES)
					return oldpid;
				else
					return -1;
			}
#endif
#endif
		}
		fprintf(pidFilePtr, "%5ld\n", (long)getpid());
		(void)fflush(pidFilePtr);
		RegisterCloseOnFork(pidFd);
	}
	return 0;
}
コード例 #13
0
ファイル: server.c プロジェクト: bbidulock/wdm
int WaitForServer(struct display *d)
{
	static int i;

	for (i = 0; i < (d->openRepeat > 0 ? d->openRepeat : 1); i++) {
		(void)Signal(SIGALRM, abortOpen);
		(void)alarm((unsigned)d->openTimeout);
		if (!Setjmp(openAbort)) {
			WDMDebug("Before XOpenDisplay(%s)\n", d->name);
			errno = 0;
			(void)XSetIOErrorHandler(openErrorHandler);
			dpy = XOpenDisplay(d->name);
			(void)alarm((unsigned)0);
			(void)Signal(SIGALRM, SIG_DFL);
			(void)XSetIOErrorHandler((int (*)(Display *))0);
			WDMDebug("After XOpenDisplay(%s)\n", d->name);
			if (dpy) {
#ifdef XDMCP
				if (d->displayType.location == Foreign)
					GetRemoteAddress(d, ConnectionNumber(dpy));
#endif
				RegisterCloseOnFork(ConnectionNumber(dpy));
				(void)fcntl(ConnectionNumber(dpy), F_SETFD, 0);
				return 1;
			} else {
				WDMDebug("OpenDisplay failed %d (%s) on \"%s\"\n", errno, strerror(errno), d->name);
			}
			WDMDebug("waiting for server to start %d\n", i);
			sleep((unsigned)d->openDelay);
		} else {
			WDMDebug("hung in open, aborting\n");
			WDMError("Hung in XOpenDisplay(%s), aborting\n", d->name);
			(void)Signal(SIGALRM, SIG_DFL);
			break;
		}
	}
	WDMDebug("giving up on server\n");
	WDMError("server open failed for %s, giving up\n", d->name);
	return 0;
}
コード例 #14
0
ファイル: Greet.c プロジェクト: bbidulock/wdm
static void guaranteed_read(int fd, char *buf, size_t count)
{
	int bytes_read;

	if (count == 0) {
		return;
	}

	while ((bytes_read = read(fd, buf, count)) > 0) {
		count -= bytes_read;
		buf += bytes_read;

		if (count == 0) {
			return;
		}
	}

	WDMError("Greet: guarenteed_read error, UNMANAGE DISPLAY\n");
	WDMError("Greet: pipe read error with %s\n", wdmLogin);
	SessionExit(Save_d, RESERVER_DISPLAY, FALSE);	/* this exits */
	exit(UNMANAGE_DISPLAY);		/* should not happen */
}
コード例 #15
0
ファイル: session.c プロジェクト: bbidulock/wdm
static int runAndWait(char **args, char **environ)
{
	int pid;
	waitType result;

	switch (pid = fork()) {
	case 0:
		CleanUpChild();
		execute(args, environ);
		WDMError("can't execute \"%s\" (err %d)\n", args[0], errno);
		exit(1);
	case -1:
		WDMDebug("fork failed\n");
		WDMError("can't fork to execute \"%s\" (err %d)\n", args[0], errno);
		return 1;
	default:
		while (wait(&result) != pid)
			/* SUPPRESS 530 */
			;
		break;
	}
	return waitVal(result);
}
コード例 #16
0
ファイル: Greet.c プロジェクト: bbidulock/wdm
static int Greet(struct display *d, struct greet_info *greet)
{
	int code = 0, done = 0, extension_code = 0;

	readstring(pipe_filedes[0], name);	/* username */
	readstring(pipe_filedes[0], password);

	xsessionArg[0] = '\0';
	while (!done) {
		extension_code = readuc(pipe_filedes[0]);
		switch (extension_code) {
		case 0:				/*end of data */
			done = 1;
			break;
		case 1:				/*xsession parameter */
			readstring(pipe_filedes[0], xsessionArg);
			break;
		case 2:				/*reboot */
			readstring(pipe_filedes[0], exitArg);
			code = 2;
			break;
		case 3:				/*halt */
			readstring(pipe_filedes[0], exitArg);
			code = 3;
			break;
		case 4:				/*exit */
			readstring(pipe_filedes[0], exitArg);
			code = 4;
			break;
		default:				/*???? */
			WDMError("Bad extension code from external program: %i\n", code);
			exit(RESERVER_DISPLAY);
			break;
		}
	}
	greet->name = name;
	greet->password = password;

	if (xsessionArg[0] == '\0')
		greet->string = NULL;
	else
		greet->string = xsessionArg;

	return code;
}
コード例 #17
0
ファイル: server.c プロジェクト: bbidulock/wdm
static int serverPause(unsigned t, int serverPid)
{
	int pid;

	serverPauseRet = 0;
	if (!Setjmp(pauseAbort)) {
		(void)Signal(SIGALRM, serverPauseAbort);
		(void)Signal(SIGUSR1, serverPauseUsr1);
#ifdef SYSV
		if (receivedUsr1)
			(void)alarm((unsigned)1);
		else
			(void)alarm(t);
#else
		if (!receivedUsr1)
			(void)alarm(t);
		else
			WDMDebug("Already received USR1\n");
#endif
		for (;;) {
			if (!receivedUsr1)
				pid = wait((waitType *) 0);
			else
				pid = waitpid(-1, (int *)0, WNOHANG);
			if (pid == serverPid || (pid == -1 && errno == ECHILD)) {
				WDMDebug("Server dead\n");
				serverPauseRet = 1;
				break;
			}
			if (pid == 0) {
				WDMDebug("Server alive and kicking\n");
				break;
			}
		}
	}
	(void)alarm((unsigned)0);
	(void)Signal(SIGALRM, SIG_DFL);
	(void)Signal(SIGUSR1, CatchUsr1);
	if (serverPauseRet) {
		WDMDebug("Server died\n");
		WDMError("server unexpectedly died\n");
	}
	return serverPauseRet;
}
コード例 #18
0
ファイル: dm.c プロジェクト: bbidulock/wdm
void WaitForChild(void)
{
	int pid;
	struct display *d;
	waitType status;
	sigset_t mask, omask;

	sigemptyset(&mask);
	sigaddset(&mask, SIGCHLD);
	sigaddset(&mask, SIGHUP);
	sigprocmask(SIG_BLOCK, &mask, &omask);
	WDMDebug("signals blocked\n");
	if (!ChildReady && !Rescan)
		sigsuspend(&omask);
	ChildReady = 0;
	sigprocmask(SIG_SETMASK, &omask, (sigset_t *) NULL);
	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
	{
		WDMDebug("Manager wait returns pid: %d sig %d core %d code %d\n", pid, waitSig(status), waitCore(status), waitCode(status));
		if (autoRescan.i)
			RescanIfMod();
		/* SUPPRESS 560 */
		if ((d = FindDisplayByPid(pid))) {
			d->pid = -1;
			switch (waitVal(status)) {
			case UNMANAGE_DISPLAY:
				WDMDebug("Display exited with UNMANAGE_DISPLAY\n");
				StopDisplay(d);
				break;
			case OBEYSESS_DISPLAY:
				d->startTries = 0;
				WDMDebug("Display exited with OBEYSESS_DISPLAY\n");
				if (d->displayType.lifetime != Permanent || d->status == zombie)
					StopDisplay(d);
				else
					RestartDisplay(d, FALSE);
				break;
			default:
				WDMDebug("Display exited with unknown status %d\n", waitVal(status));
				WDMError("Unknown session exit code %d from process %d\n", waitVal(status), pid);
				StopDisplay(d);
				break;
			case OPENFAILED_DISPLAY:
				WDMDebug("Display exited with OPENFAILED_DISPLAY, try %d of %d\n", d->startTries, d->startAttempts);
				WDMError("Display %s cannot be opened\n", d->name);
				/*
				 * no display connection was ever made, tell the
				 * terminal that the open attempt failed
				 */
#ifdef XDMCP
				if (d->displayType.origin == FromXDMCP)
					SendFailed(d, "Cannot open display");
#endif
				if (d->displayType.origin == FromXDMCP || d->status == zombie || ++d->startTries >= d->startAttempts) {
					WDMError("Display %s is being disabled\n", d->name);
					StopDisplay(d);
				} else {
					RestartDisplay(d, TRUE);
				}
				break;
			case RESERVER_DISPLAY:
				d->startTries = 0;
				WDMDebug("Display exited with RESERVER_DISPLAY\n");
				if (d->displayType.origin == FromXDMCP || d->status == zombie)
					StopDisplay(d);
				else
					RestartDisplay(d, TRUE);
				{
					Time_t Time;
					time(&Time);
					WDMDebug("time %i %i\n", (int)Time, (int)d->lastCrash);
					if (d->lastCrash && ((Time - d->lastCrash) < XDM_BROKEN_INTERVAL)) {
						WDMDebug("Server crash frequency too high:" " removing display %s\n", d->name);
						WDMError("Server crash rate too high:" " removing display %s\n", d->name);
						RemoveDisplay(d);
					} else
						d->lastCrash = Time;
				}
				break;
			case waitCompose(SIGTERM, 0, 0):
				WDMDebug("Display exited on SIGTERM, try %d of %d\n", d->startTries, d->startAttempts);
				if (d->displayType.origin == FromXDMCP || d->status == zombie || ++d->startTries >= d->startAttempts) {
					WDMError("Display %s is being disabled\n", d->name);
					StopDisplay(d);
				} else
					RestartDisplay(d, TRUE);
				break;
			case REMANAGE_DISPLAY:
				d->startTries = 0;
				WDMDebug("Display exited with REMANAGE_DISPLAY\n");
				/*
				 * XDMCP will restart the session if the display
				 * requests it
				 */
				if (d->displayType.origin == FromXDMCP || d->status == zombie)
					StopDisplay(d);
				else
					RestartDisplay(d, FALSE);
				break;
			}
		}
		/* SUPPRESS 560 */
		else if ((d = FindDisplayByServerPid(pid))) {
			d->serverPid = -1;
			switch (d->status) {
			case zombie:
				WDMDebug("Zombie server reaped, removing display %s\n", d->name);
				RemoveDisplay(d);
				break;
			case phoenix:
				WDMDebug("Phoenix server arises, restarting display %s\n", d->name);
				d->status = notRunning;
				break;
			case running:
				WDMDebug("Server for display %s terminated unexpectedly, status %d %d\n", d->name, waitVal(status), status);
				WDMError("Server for display %s terminated unexpectedly: %d\n", d->name, waitVal(status));
				d->status = notRunning;
				if (d->pid != -1) {
					WDMDebug("Terminating session pid %d\n", d->pid);
					TerminateProcess(d->pid, SIGTERM);
				}
				break;
			case notRunning:
				WDMDebug("Server exited for notRunning session on display %s\n", d->name);
				break;
			}
		} else {
			WDMDebug("Unknown child termination, status %d\n", waitVal(status));
		}
	}
	StartDisplays();
}
コード例 #19
0
ファイル: dm.c プロジェクト: bbidulock/wdm
void StartDisplay(struct display *d)
{
	int pid;

	WDMDebug("StartDisplay %s\n", d->name);
	LoadServerResources(d);
	if (d->displayType.location == Local) {
		/* don't bother pinging local displays; we'll
		 * certainly notice when they exit
		 */
		d->pingInterval = 0;
		if (d->authorize) {
			WDMDebug("SetLocalAuthorization %s, auth %s\n", d->name, d->authNames[0]);
			SetLocalAuthorization(d);
			/*
			 * reset the server after writing the authorization information
			 * to make it read the file (for compatibility with old
			 * servers which read auth file only on reset instead of
			 * at first connection)
			 */
			if (d->serverPid != -1 && d->resetForAuth && d->resetSignal)
				kill(d->serverPid, d->resetSignal);
		}
		if (d->serverPid == -1 && !StartServer(d)) {
			WDMError("Server for display %s can't be started, session disabled\n", d->name);
			RemoveDisplay(d);
			return;
		}
	} else {
		/* this will only happen when using XDMCP */
		if (d->authorizations)
			SaveServerAuthorizations(d, d->authorizations, d->authNum);
	}
	pid = fork();
	switch (pid) {
	case 0:
		CleanUpChild();
		LoadSessionResources(d);
		SetAuthorization(d);
		(void)Signal(SIGPIPE, SIG_IGN);
		(void)Signal(SIGHUP, SIG_IGN);
		if (!WaitForServer(d))
			exit(OPENFAILED_DISPLAY);
#ifdef XDMCP
		if (d->useChooser)
			RunChooser(d);
		else
#endif
			ManageSession(d);
		exit(REMANAGE_DISPLAY);
	case -1:
		break;
	default:
		WDMDebug("pid: %d\n", pid);
		d->pid = pid;
		d->status = running;
		/* checking a predeclared X resource DisplayManager*wdmSequentialXServerLaunch here */
		if (wdmSequentialXServerLaunch)
			WaitForServer(d);
		break;
	}
}
コード例 #20
0
ファイル: Greet.c プロジェクト: bbidulock/wdm
static int InitGreet(struct display *d)
{
	int pid;

	WDMDebug("Greet display=%s\n", d->name);

	pipe(pipe_filedes);

	pid = fork();

	if (pid == -1) {			/* error */
		WDMError("Greet cannot fork\n");
		exit(RESERVER_DISPLAY);
	}
	if (pid == 0) {				/* child */
		char **env = NULL;
		char *argv[20];
		int argc = 1;			/* argc = 0 is for command itself */

		close(pipe_filedes[0]);
		fcntl(pipe_filedes[1], F_SETFD, 0);	/* Reset close-on-exec (just in case) */

		env = (char **)systemEnv(d, (char *)NULL, FAKEHOME);

		if (*wdmLocale)
			env = WDMSetEnv(env, "LANG", wdmLocale);

		if (*wdmCursorTheme)
			env = WDMSetEnv(env, "XCURSOR_THEME", wdmCursorTheme);

		if ((argv[0] = strrchr(wdmLogin, '/')) == NULL)
			argv[0] = wdmLogin;
		else
			argv[0]++;

		argv[argc++] = wstrconcat("-d", d->name);
		if (*wdmWm)
			argv[argc++] = wstrconcat("-w", wdmWm);
		if (*wdmLogo)
			argv[argc++] = wstrconcat("-l", wdmLogo);
		if (*wdmHelpFile)
			argv[argc++] = wstrconcat("-h", wdmHelpFile);
		if (*wdmDefaultUser)
			argv[argc++] = "-u";
		if (*wdmBg)
			argv[argc++] = wstrconcat("-b", wdmBg);
		if (*wdmLoginConfig)
			argv[argc++] = wstrconcat("-c", wdmLoginConfig);
		if (wdmAnimations)
			argv[argc++] = "-a";
		if (wdmXineramaHead) {
			argv[argc] = wmalloc(25);	/* much more than length of 64bit integer 
										   converted to string, but it still a hack */
			sprintf(argv[argc++], "-x%i", wdmXineramaHead);
		}
		argv[argc] = wmalloc(25);
		sprintf(argv[argc++], "-f%i", pipe_filedes[1]);

		argv[argc++] = NULL;
		execve(wdmLogin, argv, env);

		WDMError("Greet cannot exec %s\n", wdmLogin);
		exit(RESERVER_DISPLAY);
	}

	close(pipe_filedes[1]);
	RegisterCloseOnFork(pipe_filedes[0]);
	return pid;
}
コード例 #21
0
ファイル: Greet.c プロジェクト: bbidulock/wdm
greet_user_rtn GreetUser(struct display * d, Display ** dpy, struct verify_info * verify, struct greet_info * greet)
{
	int flag;
	int pid;
	int code;

	Save_d = d;					/* hopefully, this is OK */

	*dpy = XOpenDisplay(d->name);	/* make sure we have the display */
	/*
	 * Run the setup script - note this usually will not work when
	 * the server is grabbed, so we don't even bother trying.
	 */
	if (!d->grabServer)
		SetupDisplay(d);
	if (!*dpy) {
		WDMError("Cannot reopen display %s for greet window\n", d->name);
		exit(RESERVER_DISPLAY);
	}

	pid = InitGreet(d);			/* fork and exec the external program */

	for (;;) {
		/*
		 * Greet user, requesting name/password
		 */
		code = Greet(d, greet);
		WDMDebug("Greet greet done: %s, pwlen=%i\n", name, strlen(password));

		if (code != 0) {
			WDMDebug("Greet: exit code=%i, %s\n", code, exitArg);
			if (wdmVerify || wdmRoot) {
				flag = False;
				if (Verify(d, greet, verify))
					flag = True;
				if (wdmRoot && (strcmp(greet->name, "root") != 0))
					flag = False;
			} else
				flag = True;
			if (flag == True) {
				switch (code) {
				case 2:		/* reboot */
					CloseGreet(pid);
					WDMInfo("reboot(%s) by %s\n", exitArg, name);
					system(wdmReboot);
					SessionExit(d, UNMANAGE_DISPLAY, FALSE);
					break;
				case 3:		/* halt */
					CloseGreet(pid);
					WDMInfo("halt(%s) by %s\n", exitArg, name);
					system(wdmHalt);
					SessionExit(d, UNMANAGE_DISPLAY, FALSE);
					break;
				case 4:		/* exit */
					CloseGreet(pid);
					WDMDebug("UNMANAGE_DISPLAY\n");
					WDMInfo("%s exit(%s) by %s\n", PACKAGE_NAME, exitArg, name);
#if 0
					SessionExit(d, UNMANAGE_DISPLAY, FALSE);
#else
					WDMDebug("Killing parent process %d\n", getppid());
					kill(getppid(), SIGINT);
#endif
					break;
				}
			} else {
				kill(pid, SIGUSR1);	/* Verify failed */
			}
		} else {
			/*
			 * Verify user
			 */
			if ((!*greet->name) && *wdmDefaultUser) {
				greet->name = wdmDefaultUser;
				greet->password = wdmDefaultPasswd;
			}
			if (Verify(d, greet, verify))
				break;
			else
				kill(pid, SIGUSR1);	/* Verify failed */
		}
	}
	DeleteXloginResources(d, *dpy);
	CloseGreet(pid);
	WDMDebug("Greet loop finished\n");
	/*
	 * Run system-wide initialization file
	 */
	if (source(verify->systemEnviron, d->startup) != 0) {
		WDMDebug("Startup program %s exited with non-zero status\n", d->startup);
		SessionExit(d, OBEYSESS_DISPLAY, FALSE);
	}

	return Greet_Success;
}
コード例 #22
0
ファイル: session.c プロジェクト: bbidulock/wdm
static int IOErrorHandler(Display * dpy)
{
	WDMError("fatal IO error %d (%s)\n", errno, _SysErrorMsg(errno));
	exit(RESERVER_DISPLAY);
	 /*NOTREACHED*/ return 0;
}
コード例 #23
0
ファイル: server.c プロジェクト: bbidulock/wdm
static int openErrorHandler(Display * dpy)
{
	WDMError("IO Error in XOpenDisplay\n");
	exit(OPENFAILED_DISPLAY);
	 /*NOTREACHED*/ return (0);
}
コード例 #24
0
ファイル: session.c プロジェクト: bbidulock/wdm
static Bool StartClient(struct verify_info *verify, struct display *d, int *pidp, char *name, char *passwd
#ifdef WITH_CONSOLE_KIT
						, char *ck_session_cookie
#endif
	)
{
	char **f;
	const char *home;
	char *failsafeArgv[2];
	int pid;
#ifdef HAS_SETUSERCONTEXT
	struct passwd *pwd;
#endif
#ifdef USE_PAM
	pam_handle_t *pamh = thepamh();
#endif

	if (verify->argv) {
		WDMDebug("StartSession %s: ", verify->argv[0]);
		for (f = verify->argv; *f; f++)
			WDMDebug("%s ", *f);
		WDMDebug("; ");
	}
	if (verify->userEnviron) {
		for (f = verify->userEnviron; *f; f++)
			WDMDebug("%s ", *f);
		WDMDebug("\n");
	}

	/* Do system-dependent login setup here */

	if (setgid(verify->gid) < 0) {
		WDMError("setgid %d (user \"%s\") failed, errno=%d\n", verify->gid, name, errno);
		return (0);
	}
#if defined(BSD) && (BSD >= 199103)
	if (setlogin(name) < 0) {
		WDMError("setlogin for \"%s\" failed, errno=%d", name, errno);
		return (0);
	}
#endif
	if (initgroups(name, verify->gid) < 0) {
		WDMError("initgroups for \"%s\" failed, errno=%d\n", name, errno);
		return (0);
	}
#ifdef USE_PAM
	if (pamh) {
		if (pam_setcred(pamh, PAM_ESTABLISH_CRED) != PAM_SUCCESS) {
			WDMError("pam_setcred failed, errno=%d\n", errno);
			log_to_audit_system(0);
			pam_end(pamh, PAM_SUCCESS);
			pamh = NULL;
			return 0;
		}

		pam_open_session(pamh, 0);
		log_to_audit_system(1);

		/* pass in environment variables set by libpam and modules it called */
		{
			long i;
			char **pam_env = pam_getenvlist(pamh);
			for (i = 0; pam_env && pam_env[i]; i++) {
				verify->userEnviron = WDMPutEnv(verify->userEnviron, pam_env[i]);
			}
		}
	}
#endif
	switch (pid = fork()) {
	case 0:
		CleanUpChild();
#ifdef XDMCP
		/* The chooser socket is not closed by CleanUpChild() */
		DestroyWellKnownSockets();
#endif

		if (setuid(verify->uid) < 0) {
			WDMError("setuid %d (user \"%s\") failed, errno=%d\n", verify->uid, name, errno);
			return (0);
		}

		/*
		 * for Security Enhanced Linux,
		 * set the default security context for this user.
		 */
#ifdef WITH_SELINUX
		if (is_selinux_enabled()) {
			security_context_t scontext;
			if (get_default_context(name, NULL, &scontext))
				WDMError("Failed to get default security context" " for %s.", name);
			WDMDebug("setting security context to %s", scontext);
			if (setexeccon(scontext)) {
				freecon(scontext);
				WDMError("Failed to set exec security context %s " "for %s.", scontext, name);
			}
			freecon(scontext);
		}
#endif
		/*
		 * for user-based authorization schemes,
		 * use the password to get the user's credentials.
		 */
		bzero(passwd, strlen(passwd));
#ifdef WITH_CONSOLE_KIT
		if (ck_session_cookie != NULL) {
			verify->userEnviron = WDMSetEnv(verify->userEnviron, "XDG_SESSION_COOKIE", ck_session_cookie);
		}
#endif
		SetUserAuthorization(d, verify);
		home = WDMGetEnv(verify->userEnviron, "HOME");
		if (home)
			if (chdir(home) == -1) {
				WDMError("user \"%s\": cannot chdir to home \"%s\" (err %d), using \"/\"\n",
						 WDMGetEnv(verify->userEnviron, "USER"), home, errno);
				chdir("/");
				verify->userEnviron = WDMSetEnv(verify->userEnviron, "HOME", "/");
			}
		if (verify->argv) {
			WDMDebug("executing session %s\n", verify->argv[0]);
			execute(verify->argv, verify->userEnviron);
			WDMError("Session \"%s\" execution failed (err %d)\n", verify->argv[0], errno);
		} else {
			WDMError("Session has no command/arguments\n");
		}
		failsafeArgv[0] = d->failsafeClient;
		failsafeArgv[1] = 0;
		execute(failsafeArgv, verify->userEnviron);
		exit(1);
	case -1:
		bzero(passwd, strlen(passwd));
		WDMDebug("StartSession, fork failed\n");
		WDMError("can't start session on \"%s\", fork failed, errno=%d\n", d->name, errno);
		return 0;
	default:
		bzero(passwd, strlen(passwd));
		WDMDebug("StartSession, fork succeeded %d\n", pid);
		*pidp = pid;
		return 1;
	}
}
コード例 #25
0
ファイル: dm.c プロジェクト: bbidulock/wdm
int main(int argc, char **argv)
{
	int oldpid, oldumask;
	char cmdbuf[1024];
	int debugMode = 0;

	/* make sure at least world write access is disabled */
	if (((oldumask = umask(022)) & 002) == 002)
		(void)umask(oldumask);
#ifndef NOXDMTITLE
	Title = argv[0];
	TitleLen = (argv[argc - 1] + strlen(argv[argc - 1])) - Title;
#endif

	/*
	 * Step 1 - load configuration parameters
	 */
	InitResources(argc, argv);
	SetConfigFileTime();
	LoadDMResources();
	/*
	 * Only allow root to run in non-debug mode to avoid problems
	 */
	debugMode = (debugLevel.i > WDM_LEVEL_WARNING);
	if (!debugMode && getuid() != 0) {
		fprintf(stderr, "Only root wants to run %s\n", argv[0]);
		exit(1);
	}
	if (!debugMode && daemonMode.i) {
		BecomeOrphan();
		BecomeDaemon();
	}
	/* SUPPRESS 560 */
	if ((oldpid = StorePid())) {
		if (oldpid == -1)
			WDMError("Can't create/lock pid file %s\n", pidFile);
		else
			WDMError("Can't lock pid file %s, another wdm is running " "(pid %d)\n", pidFile, oldpid);
		exit(1);
	}
	WDMLogLevel(debugLevel.i);
	if (useSyslog.i) {
		WDMUseSysLog("wdm", WDMStringToFacility(syslogFacility));
	} else if (errorLogFile && *errorLogFile) {
		int f;
		if ((f = open(errorLogFile, O_CREAT | O_WRONLY | O_APPEND, 0600)) == -1)
			WDMError("cannot open errorLogFile %s\n", errorLogFile);
		else
			WDMLogStream(fdopen(f, "w"));
	}
	/* redirect any messages for stderr into standard logging functions. */
	WDMRedirectStderr(WDM_LEVEL_ERROR);

	/* Clean up any old Authorization files */
	sprintf(cmdbuf, "/bin/rm -f %s/authdir/authfiles/A*", authDir);
	system(cmdbuf);

#ifdef XDMCP
	init_session_id();
	CreateWellKnownSockets();
#else
	WDMDebug("wdm: not compiled for XDMCP\n");
#endif
	parent_pid = getpid();
	(void)Signal(SIGTERM, StopAll);
	(void)Signal(SIGINT, StopAll);
	/*
	 * Step 2 - Read /etc/Xservers and set up
	 *      the socket.
	 *
	 *      Keep a sub-daemon running
	 *      for each entry
	 */
	SetAccessFileTime();
#ifdef XDMCP
	ScanAccessDatabase();
#endif
	ScanServers();
	StartDisplays();
	(void)Signal(SIGHUP, RescanNotify);
	(void)Signal(SIGCHLD, ChildNotify);
	while (
#ifdef XDMCP
			  AnyWellKnownSockets() ||
#endif
			  AnyDisplaysLeft()) {
		if (Rescan) {
			RescanServers();
			Rescan = 0;
		}
		WaitForSomething();
	}
	WDMDebug("Nothing left to do, exiting\n");
	exit(0);
 /*NOTREACHED*/}
コード例 #26
0
ファイル: session.c プロジェクト: bbidulock/wdm
void ManageSession(struct display *d)
{
	static int pid = 0;
	Display *dpy;
	greet_user_rtn greet_stat;
#ifdef WITH_CONSOLE_KIT
	char *ck_session_cookie = NULL;
#endif

	WDMDebug("ManageSession %s\n", d->name);
	(void)XSetIOErrorHandler(IOErrorHandler);
	(void)XSetErrorHandler(ErrorHandler);
#ifndef HAS_SETPROCTITLE
	SetTitle(d->name, (char *)0);
#else
	setproctitle("%s", d->name);
#endif
	/*
	 * Load system default Resources
	 */
	LoadXloginResources(d);

	verify.version = 1;
	greet.version = 1;
	greet_stat = GreetUser(d, &dpy, &verify, &greet);

	if (greet_stat == Greet_Success) {
		clientPid = 0;
		if (!Setjmp(abortSession)) {
			(void)Signal(SIGTERM, catchTerm);
			/*
			 * Start the clients, changing uid/groups
			 *     setting up environment and running the session
			 */
#ifdef WITH_CONSOLE_KIT
			ck_session_cookie = open_ck_session(getpwnam(greet.name), d);
#endif
			if (StartClient(&verify, d, &clientPid, greet.name, greet.password
#ifdef WITH_CONSOLE_KIT
							, ck_session_cookie
#endif
				)) {
				WDMDebug("Client Started\n");

				/*
				 * Wait for session to end,
				 */
				for (;;) {
					if (d->pingInterval) {
						if (!Setjmp(pingTime)) {
							(void)Signal(SIGALRM, catchAlrm);
							(void)alarm(d->pingInterval * 60);
							pid = wait((waitType *) 0);
							(void)alarm(0);
						} else {
							(void)alarm(0);
							if (!PingServer(d, (Display *) NULL))
								SessionPingFailed(d);
						}
					} else {
						pid = wait((waitType *) 0);
					}
					if (pid == clientPid)
						break;
				}
			} else {
				WDMError("session start failed\n");
			}
		} else {
			/*
			 * when terminating the session, nuke
			 * the child and then run the reset script
			 */
			AbortClient(clientPid);
		}
	}
#ifdef WITH_CONSOLE_KIT
	if (ck_session_cookie != NULL) {
		close_ck_session(ck_session_cookie);
		free(ck_session_cookie);
	}
#endif

	/*
	 * run system-wide reset file
	 */
	WDMDebug("Source reset program %s\n", d->reset);
	source(verify.systemEnviron, d->reset);
	SessionExit(d, OBEYSESS_DISPLAY, TRUE);
}