static int StartServerOnce (struct display *d) { char **f; char **argv; char arg[1024]; int pid; Debug ("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) { LogError ("StartServer: no arguments\n"); sleep ((unsigned) d->openDelay); exit (UNMANAGE_DISPLAY); } for (f = argv; *f; f++) Debug ("'%s' ", *f); Debug ("\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); LogError ("server %s cannot be executed\n", argv[0]); sleep ((unsigned) d->openDelay); exit (REMANAGE_DISPLAY); case -1: LogError ("fork failed, sleeping\n"); return 0; default: break; } Debug ("Server Started %d\n", pid); d->serverPid = pid; if (serverPause ((unsigned) d->openDelay, pid)) return FALSE; return TRUE; }
void StartDisplay (struct display *d) { pid_t pid; Debug ("StartDisplay %s\n", d->name); LogInfo ("Starting X server on %s\n", d->name); LoadServerResources (d); if (d->authorize) { Debug ("SetLocalAuthorization %s, auth %s\n", d->name, d->authNames[0]); SetLocalAuthorization (d); } if (d->serverPid == -1 && !StartServer (d)) { LogError ("Server for display %s can't be started, session disabled\n", d->name); RemoveDisplay (d); return; } if (!nofork_session) pid = fork (); else pid = 0; switch (pid) { case 0: if (!nofork_session) { CleanUpChild (); (void) signal (SIGPIPE, SIG_IGN); } openlog("xenodm", LOG_PID, LOG_AUTHPRIV); LoadSessionResources (d); SetAuthorization (d); if (!WaitForServer (d)) exit (OPENFAILED_DISPLAY); SetWindowPath(d); if (pledge("stdio rpath cpath wpath fattr flock proc dns inet unix exec prot_exec getpw id", NULL) != 0) exit(OPENFAILED_DISPLAY); ManageSession (d); exit (REMANAGE_DISPLAY); case -1: break; default: Debug ("pid: %d\n", pid); d->pid = pid; d->status = running; break; } }
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); }
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; } }
static Bool StartClient ( struct verify_info *verify, struct display *d, int *pidp, char *name, char *passwd) { char **f, *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) { Debug ("StartSession %s: ", verify->argv[0]); for (f = verify->argv; *f; f++) Debug ("%s ", *f); Debug ("; "); } if (verify->userEnviron) { for (f = verify->userEnviron; *f; f++) Debug ("%s ", *f); Debug ("\n"); } #ifdef USE_PAM if (pamh) pam_open_session(pamh, 0); #endif switch (pid = fork ()) { case 0: CleanUpChild (); #ifdef XDMCP /* The chooser socket is not closed by CleanUpChild() */ DestroyWellKnownSockets(); #endif /* Do system-dependent login setup here */ #ifdef USE_PAM /* pass in environment variables set by libpam and modules it called */ if (pamh) { long i; char **pam_env = pam_getenvlist(pamh); for(i = 0; pam_env && pam_env[i]; i++) { verify->userEnviron = putEnv(pam_env[i], verify->userEnviron); } } #endif #ifndef AIXV3 #ifndef HAS_SETUSERCONTEXT if (setgid(verify->gid) < 0) { LogError("setgid %d (user \"%s\") failed, errno=%d\n", verify->gid, name, errno); return (0); } #if defined(BSD) && (BSD >= 199103) if (setlogin(name) < 0) { LogError("setlogin for \"%s\" failed, errno=%d", name, errno); return(0); } #endif #ifndef QNX4 if (initgroups(name, verify->gid) < 0) { LogError("initgroups for \"%s\" failed, errno=%d\n", name, errno); return (0); } #endif /* QNX4 doesn't support multi-groups, no initgroups() */ #ifdef USE_PAM if (thepamh()) { pam_setcred(thepamh(), PAM_ESTABLISH_CRED); } #endif if (setuid(verify->uid) < 0) { LogError("setuid %d (user \"%s\") failed, errno=%d\n", verify->uid, name, errno); return (0); } #else /* HAS_SETUSERCONTEXT */ /* * Set the user's credentials: uid, gid, groups, * environment variables, resource limits, and umask. */ pwd = getpwnam(name); if (pwd) { if (setusercontext(NULL, pwd, pwd->pw_uid, LOGIN_SETALL) < 0) { LogError("setusercontext for \"%s\" failed, errno=%d\n", name, errno); return (0); } endpwent(); } else { LogError("getpwnam for \"%s\" failed, errno=%d\n", name, errno); return (0); } #endif /* HAS_SETUSERCONTEXT */ #else /* AIXV3 */ /* * Set the user's credentials: uid, gid, groups, * audit classes, user limits, and umask. */ if (setpcred(name, NULL) == -1) { LogError("setpcred for \"%s\" failed, errno=%d\n", name, errno); return (0); } #endif /* AIXV3 */ /* * for user-based authorization schemes, * use the password to get the user's credentials. */ #ifdef SECURE_RPC /* do like "keylogin" program */ { char netname[MAXNETNAMELEN+1], secretkey[HEXKEYBYTES+1]; int nameret, keyret; int len; int key_set_ok = 0; nameret = getnetname (netname); Debug ("User netname: %s\n", netname); len = strlen (passwd); if (len > 8) bzero (passwd + 8, len - 8); keyret = getsecretkey(netname,secretkey,passwd); Debug ("getsecretkey returns %d, key length %d\n", keyret, strlen (secretkey)); /* is there a key, and do we have the right password? */ if (keyret == 1) { if (*secretkey) { keyret = key_setsecret(secretkey); Debug ("key_setsecret returns %d\n", keyret); if (keyret == -1) LogError ("failed to set NIS secret key\n"); else key_set_ok = 1; } else { /* found a key, but couldn't interpret it */ LogError ("password incorrect for NIS principal \"%s\"\n", nameret ? netname : name); } } if (!key_set_ok) { /* remove SUN-DES-1 from authorizations list */ int i, j; for (i = 0; i < d->authNum; i++) { if (d->authorizations[i]->name_length == 9 && memcmp(d->authorizations[i]->name, "SUN-DES-1", 9) == 0) { for (j = i+1; j < d->authNum; j++) d->authorizations[j-1] = d->authorizations[j]; d->authNum--; break; } } } bzero(secretkey, strlen(secretkey)); } #endif #ifdef K5AUTH /* do like "kinit" program */ { int i, j; int result; extern char *Krb5CCacheName(); result = Krb5Init(name, passwd, d); if (result == 0) { /* point session clients at the Kerberos credentials cache */ verify->userEnviron = setEnv(verify->userEnviron, "KRB5CCNAME", Krb5CCacheName(d->name)); } else { for (i = 0; i < d->authNum; i++) { if (d->authorizations[i]->name_length == 14 && memcmp(d->authorizations[i]->name, "MIT-KERBEROS-5", 14) == 0) { /* remove Kerberos from authorizations list */ for (j = i+1; j < d->authNum; j++) d->authorizations[j-1] = d->authorizations[j]; d->authNum--; break; } } } } #endif /* K5AUTH */ bzero(passwd, strlen(passwd)); SetUserAuthorization (d, verify); home = getEnv (verify->userEnviron, "HOME"); if (home) if (chdir (home) == -1) { LogError ("user \"%s\": cannot chdir to home \"%s\" (err %d), using \"/\"\n", getEnv (verify->userEnviron, "USER"), home, errno); chdir ("/"); verify->userEnviron = setEnv(verify->userEnviron, "HOME", "/"); } if (verify->argv) { Debug ("executing session %s\n", verify->argv[0]); execute (verify->argv, verify->userEnviron); LogError ("Session \"%s\" execution failed (err %d)\n", verify->argv[0], errno); } else { LogError ("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)); Debug ("StartSession, fork failed\n"); LogError ("can't start session on \"%s\", fork failed, errno=%d\n", d->name, errno); return 0; default: bzero(passwd, strlen(passwd)); Debug ("StartSession, fork succeeded %d\n", pid); *pidp = pid; return 1; } }
static Bool StartClient ( struct verify_info *verify, struct display *d, pid_t *pidp, char *name) { char **f, *home; char *failsafeArgv[2]; pid_t pid; struct passwd* pwd; if (pledge("stdio rpath wpath cpath fattr proc getpw id exec dns unix inet", NULL) != 0) exit(25); if (verify->argv) { Debug ("StartSession %s: ", verify->argv[0]); for (f = verify->argv; *f; f++) Debug ("%s ", *f); Debug ("; "); } if (verify->userEnviron) { for (f = verify->userEnviron; *f; f++) Debug ("%s ", *f); Debug ("\n"); } switch (pid = fork ()) { case 0: CleanUpChild (); /* * Set the user's credentials: uid, gid, groups, * environment variables, resource limits, and umask. */ pwd = getpwnam(name); if (pwd) { if (d->windowPath != NULL) { /* XXX not working because of pledge() */ Debug("login_fbtab %s %d\n", d->windowPath, geteuid()); login_fbtab(d->windowPath, pwd->pw_uid, pwd->pw_gid); } if (setusercontext(NULL, pwd, pwd->pw_uid, LOGIN_SETALL) < 0) { LogError ("setusercontext for \"%s\" failed: %s\n", name, _SysErrorMsg (errno)); return (0); } } else { LogError ("getpwnam for \"%s\" failed: %s\n", name, _SysErrorMsg (errno)); return (0); } if (d->windowPath) verify->userEnviron = setEnv(verify->userEnviron, "WINDOWPATH", d->windowPath); else Debug("No WINDOWPATH found\n"); SetUserAuthorization (d, verify); home = getEnv (verify->userEnviron, "HOME"); if (home) if (chdir (home) == -1) { LogError ("user \"%s\": cannot chdir to home \"%s\" (err %d), using \"/\"\n", getEnv (verify->userEnviron, "USER"), home, errno); chdir ("/"); verify->userEnviron = setEnv(verify->userEnviron, "HOME", "/"); } if (verify->argv) { LogInfo ("executing session %s\n", verify->argv[0]); execute (verify->argv, verify->userEnviron); LogError ("Session \"%s\" execution failed (err %d)\n", verify->argv[0], errno); } else { LogError ("Session has no command/arguments\n"); } failsafeArgv[0] = d->failsafeClient; failsafeArgv[1] = NULL; execute (failsafeArgv, verify->userEnviron); exit (1); case -1: Debug ("StartSession, fork failed\n"); LogError ("can't start session on \"%s\", fork failed: %s\n", d->name, _SysErrorMsg (errno)); return 0; default: Debug ("StartSession, fork succeeded %d\n", pid); *pidp = pid; return 1; } }
void StartDisplay (struct display *d) { pid_t pid; Debug ("StartDisplay %s\n", d->name); LogInfo ("Starting X server on %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) { Debug ("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)) { LogError ("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); } if (!nofork_session) pid = fork (); else pid = 0; switch (pid) { case 0: if (!nofork_session) { CleanUpChild (); (void) Signal (SIGPIPE, SIG_IGN); } #ifdef USE_SYSLOG openlog("xdm", LOG_PID, LOG_AUTHPRIV); #endif LoadSessionResources (d); SetAuthorization (d); if (!WaitForServer (d)) exit (OPENFAILED_DISPLAY); SetWindowPath(d); #ifdef XDMCP if (d->useChooser) RunChooser (d); else #endif ManageSession (d); exit (REMANAGE_DISPLAY); case -1: break; default: Debug ("pid: %d\n", pid); d->pid = pid; d->status = running; break; } }
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; } }