void log_to_audit_system(int success) { struct passwd *pw; char buf[64], *hostname = NULL, *tty = NULL, *login = NULL; int audit_fd; pam_handle_t *pamh = thepamh(); if (!pamh) { WDMDebug("pamh == NULL\n"); return; } audit_fd = audit_open(); pam_get_item(pamh, PAM_RHOST, (const void **)&hostname); pam_get_item(pamh, PAM_TTY, (const void **)&tty); pam_get_item(pamh, PAM_USER, (const void **)&login); if (login) pw = getpwnam(login); else { login = "******"; pw = NULL; } WDMDebug("audit_log_acct_message(%d, %d, %s, %s, %s, %d, %s, %s, %s, %d);\n", audit_fd, AUDIT_USER_LOGIN, NULL, "wdm", login, pw ? pw->pw_uid : -1, hostname, NULL, tty, success); audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, NULL, "wdm", login, pw ? pw->pw_uid : -1, hostname, NULL, tty, success); close(audit_fd); }
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); }
void SessionExit (struct display *d, int status, int removeAuth) { #ifdef USE_PAM pam_handle_t *pamh = thepamh(); #endif #ifdef USE_PAM if (pamh) { /* shutdown PAM session */ 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); #ifdef K5AUTH /* do like "kdestroy" program */ { krb5_error_code code; krb5_ccache ccache; code = Krb5DisplayCCache(d->name, &ccache); if (code) LogError("%s while getting Krb5 ccache to destroy\n", error_message(code)); else { code = krb5_cc_destroy(ccache); if (code) { if (code == KRB5_FCC_NOFILE) { Debug ("No Kerberos ccache file found to destroy\n"); } else LogError("%s while destroying Krb5 credentials cache\n", error_message(code)); } else Debug ("Kerberos ccache destroyed\n"); krb5_cc_close(ccache); } } #endif /* K5AUTH */ } Debug ("Display %s exiting with status %d\n", d->name, status); exit (status); }
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; } }