version 1.27, 2000/08/20 18:30:59 |
version 1.28, 2000/08/20 18:42:40 |
|
|
#include "auth.h" |
#include "auth.h" |
#include "auth-options.h" |
#include "auth-options.h" |
|
|
|
#ifdef HAVE_LOGIN_CAP |
|
#include <login_cap.h> |
|
#endif |
|
|
/* types */ |
/* types */ |
|
|
#define TTYSZ 64 |
#define TTYSZ 64 |
|
|
#define MAX_SESSIONS 10 |
#define MAX_SESSIONS 10 |
Session sessions[MAX_SESSIONS]; |
Session sessions[MAX_SESSIONS]; |
|
|
|
#ifdef HAVE_LOGIN_CAP |
|
static login_cap_t *lc; |
|
#endif |
|
|
/* |
/* |
* Remove local Xauthority file. |
* Remove local Xauthority file. |
*/ |
*/ |
|
|
s = session_new(); |
s = session_new(); |
s->pw = pw; |
s->pw = pw; |
|
|
|
#ifdef HAVE_LOGIN_CAP |
|
if ((lc = login_getclass(pw->pw_class)) == NULL) { |
|
error("unable to get login class"); |
|
return; |
|
} |
|
#endif |
|
|
/* |
/* |
* We stay in this loop until the client requests to execute a shell |
* We stay in this loop until the client requests to execute a shell |
* or a command. |
* or a command. |
|
|
|
|
/* Done if .hushlogin exists. */ |
/* Done if .hushlogin exists. */ |
snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir); |
snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir); |
|
#ifdef HAVE_LOGIN_CAP |
|
if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0) |
|
#else |
if (stat(buf, &st) >= 0) |
if (stat(buf, &st) >= 0) |
|
#endif |
return; |
return; |
/* |
/* |
* Get the time when the user last logged in. 'buf' will be set |
* Get the time when the user last logged in. 'buf' will be set |
|
|
printf("Last login: %s from %s\r\n", time_string, buf); |
printf("Last login: %s from %s\r\n", time_string, buf); |
} |
} |
if (options.print_motd) { |
if (options.print_motd) { |
|
#ifdef HAVE_LOGIN_CAP |
|
f = fopen(login_getcapstr(lc, "welcome", "/etc/motd", |
|
"/etc/motd"), "r"); |
|
#else |
f = fopen("/etc/motd", "r"); |
f = fopen("/etc/motd", "r"); |
|
#endif |
if (f) { |
if (f) { |
while (fgets(buf, sizeof(buf), f)) |
while (fgets(buf, sizeof(buf), f)) |
fputs(buf, stdout); |
fputs(buf, stdout); |
|
|
options.use_login = 0; |
options.use_login = 0; |
|
|
if (!options.use_login) { |
if (!options.use_login) { |
|
#ifdef HAVE_LOGIN_CAP |
|
if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) |
|
f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN, |
|
_PATH_NOLOGIN), "r"); |
|
#else |
if (pw->pw_uid) |
if (pw->pw_uid) |
f = fopen(_PATH_NOLOGIN, "r"); |
f = fopen(_PATH_NOLOGIN, "r"); |
|
#endif |
if (f) { |
if (f) { |
/* /etc/nologin exists. Print its contents and exit. */ |
/* /etc/nologin exists. Print its contents and exit. */ |
while (fgets(buf, sizeof(buf), f)) |
while (fgets(buf, sizeof(buf), f)) |
|
|
exit(254); |
exit(254); |
} |
} |
} |
} |
/* Set login name in the kernel. */ |
/* Set login name, uid, gid, and groups. */ |
if (setlogin(pw->pw_name) < 0) |
|
error("setlogin failed: %s", strerror(errno)); |
|
|
|
/* Set uid, gid, and groups. */ |
|
/* Login(1) does this as well, and it needs uid 0 for the "-h" |
/* Login(1) does this as well, and it needs uid 0 for the "-h" |
switch, so we let login(1) to this for us. */ |
switch, so we let login(1) to this for us. */ |
if (!options.use_login) { |
if (!options.use_login) { |
if (getuid() == 0 || geteuid() == 0) { |
if (getuid() == 0 || geteuid() == 0) { |
|
#ifdef HAVE_LOGIN_CAP |
|
if (setusercontext(lc, pw, pw->pw_uid, |
|
(LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) { |
|
perror("unable to set user context"); |
|
exit(1); |
|
|
|
} |
|
#else |
|
if (setlogin(pw->pw_name) < 0) |
|
error("setlogin failed: %s", strerror(errno)); |
if (setgid(pw->pw_gid) < 0) { |
if (setgid(pw->pw_gid) < 0) { |
perror("setgid"); |
perror("setgid"); |
exit(1); |
exit(1); |
|
|
|
|
/* Permanently switch to the desired uid. */ |
/* Permanently switch to the desired uid. */ |
permanently_set_uid(pw->pw_uid); |
permanently_set_uid(pw->pw_uid); |
|
#endif |
} |
} |
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) |
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) |
fatal("Failed to set uids to %d.", (int) pw->pw_uid); |
fatal("Failed to set uids to %d.", (int) pw->pw_uid); |
|
|
* legal, and means /bin/sh. |
* legal, and means /bin/sh. |
*/ |
*/ |
shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; |
shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; |
|
#ifdef HAVE_LOGIN_CAP |
|
shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); |
|
#endif |
|
|
#ifdef AFS |
#ifdef AFS |
/* Try to get AFS tokens for the local cell. */ |
/* Try to get AFS tokens for the local cell. */ |
|
|
child_set_env(&env, &envsize, "USER", pw->pw_name); |
child_set_env(&env, &envsize, "USER", pw->pw_name); |
child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); |
child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); |
child_set_env(&env, &envsize, "HOME", pw->pw_dir); |
child_set_env(&env, &envsize, "HOME", pw->pw_dir); |
child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); |
#ifdef HAVE_LOGIN_CAP |
|
cp = login_getcapstr(lc, "path", _PATH_STDPATH, _PATH_STDPATH); |
|
#else |
|
cp = _PATH_STDPATH; |
|
#endif |
|
child_set_env(&env, &envsize, "PATH", cp); |
|
cp = NULL; |
|
|
snprintf(buf, sizeof buf, "%.200s/%.50s", |
snprintf(buf, sizeof buf, "%.200s/%.50s", |
_PATH_MAILDIR, pw->pw_name); |
_PATH_MAILDIR, pw->pw_name); |
|
|
close(i); |
close(i); |
|
|
/* Change current directory to the user\'s home directory. */ |
/* Change current directory to the user\'s home directory. */ |
if (chdir(pw->pw_dir) < 0) |
if (chdir(pw->pw_dir) < 0) { |
fprintf(stderr, "Could not chdir to home directory %s: %s\n", |
fprintf(stderr, "Could not chdir to home directory %s: %s\n", |
pw->pw_dir, strerror(errno)); |
pw->pw_dir, strerror(errno)); |
|
#ifdef HAVE_LOGIN_CAP |
|
if (login_getcapbool(lc, "requirehome", 0)) |
|
exit(1); |
|
#endif |
|
} |
|
|
/* |
/* |
* Must take new environment into use so that .ssh/rc, /etc/sshrc and |
* Must take new environment into use so that .ssh/rc, /etc/sshrc and |
|
|
void |
void |
do_authenticated2(void) |
do_authenticated2(void) |
{ |
{ |
|
struct passwd *pw; |
|
|
/* |
/* |
* Cancel the alarm we set to limit the time taken for |
* Cancel the alarm we set to limit the time taken for |
* authentication. |
* authentication. |
|
|
close(startup_pipe); |
close(startup_pipe); |
startup_pipe = -1; |
startup_pipe = -1; |
} |
} |
|
#ifdef HAVE_LOGIN_CAP |
|
pw = auth_get_user(); |
|
if ((lc = login_getclass(pw->pw_class)) == NULL) { |
|
error("unable to get login class"); |
|
return; |
|
} |
|
#endif |
server_loop2(); |
server_loop2(); |
if (xauthfile) |
if (xauthfile) |
xauthfile_cleanup_proc(NULL); |
xauthfile_cleanup_proc(NULL); |