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); }
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; }
/*ARGSUSED*/ static int ignoreErrors (Display *dpy, XErrorEvent *event) { WDMDebug("ignoring error\n"); return 0; }
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; }
static void serverPauseUsr1(int n) { WDMDebug("display manager paused til SIGUSR1\n"); ++receivedUsr1; Longjmp(pauseAbort, 1); }