static void StopAll(int n) { int olderrno = errno; if (parent_pid != getpid()) { /* * We are a child wdm process that was killed by the * master wdm before we were able to return from fork() * and remove this signal handler. * * See defect XWSog08655 for more information. */ WDMDebug("Child wdm caught SIGTERM before it remove that signal.\n"); (void)Signal(n, SIG_DFL); TerminateProcess(getpid(), SIGTERM); errno = olderrno; return; } WDMDebug("Shutting down entire manager\n"); #ifdef XDMCP DestroyWellKnownSockets(); #endif ForEachDisplay(StopDisplay); errno = olderrno; }
/* ARGSUSED */ static SIGVAL StopAll (int n) { int olderrno = errno; if (parent_pid != getpid()) { /* * We are a child xdm process that was killed by the * master xdm before we were able to return from fork() * and remove this signal handler. * * See defect XWSog08655 for more information. */ Debug ("Child xdm caught SIGTERM before it removed that signal.\n"); (void) Signal (n, SIG_DFL); TerminateProcess (getpid(), SIGTERM); errno = olderrno; return; } Debug ("Shutting down entire manager\n"); LogInfo ("Shutting down\n"); #ifdef XDMCP DestroyWellKnownSockets (); #endif ForEachDisplay (StopDisplay); #ifdef SIGNALS_RESET_WHEN_CAUGHT /* to avoid another one from killing us unceremoniously */ (void) Signal (SIGTERM, StopAll); (void) Signal (SIGINT, StopAll); #endif errno = olderrno; }
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; }
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, 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; } }