summaryrefslogtreecommitdiff
path: root/session.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-08-23 10:46:23 +1000
committerDamien Miller <djm@mindrot.org>2000-08-23 10:46:23 +1000
commitad833b3e65c1887674714d514eb818d862bb499a (patch)
tree16fa75fe42aede072c5d3edac562c2870d1bb0e5 /session.c
parentb078567bf5de1dcf12d265d98acb4dc9eba8b325 (diff)
downloadopenssh-git-ad833b3e65c1887674714d514eb818d862bb499a.tar.gz
- (djm) Pick up LOGIN_PROGRAM from environment or PATH if not set by headers
- (djm) OpenBSD CVS updates: - deraadt@cvs.openbsd.org 2000/08/18 20:07:23 [ssh.c] accept remsh as a valid name as well; roman@buildpoint.com - deraadt@cvs.openbsd.org 2000/08/18 20:17:13 [deattack.c crc32.c packet.c] rename crc32() to ssh_crc32() to avoid zlib name clash. do not move to libz crc32 function yet, because it has ugly "long"'s in it; oneill@cs.sfu.ca - deraadt@cvs.openbsd.org 2000/08/18 20:26:08 [scp.1 scp.c] -S prog support; tv@debian.org - deraadt@cvs.openbsd.org 2000/08/18 20:50:07 [scp.c] knf - deraadt@cvs.openbsd.org 2000/08/18 20:57:33 [log-client.c] shorten - markus@cvs.openbsd.org 2000/08/19 12:48:11 [channels.c channels.h clientloop.c ssh.c ssh.h] support for ~. in ssh2 - deraadt@cvs.openbsd.org 2000/08/19 15:29:40 [crc32.h] proper prototype - markus@cvs.openbsd.org 2000/08/19 15:34:44 [authfd.c authfd.h key.c key.h ssh-add.1 ssh-add.c ssh-agent.1] [ssh-agent.c ssh-keygen.c sshconnect1.c sshconnect2.c Makefile] [fingerprint.c fingerprint.h] add SSH2/DSA support to the agent and some other DSA related cleanups. (note that we cannot talk to ssh.com's ssh2 agents) - markus@cvs.openbsd.org 2000/08/19 15:55:52 [channels.c channels.h clientloop.c] more ~ support for ssh2 - markus@cvs.openbsd.org 2000/08/19 16:21:19 [clientloop.c] oops - millert@cvs.openbsd.org 2000/08/20 12:25:53 [session.c] We have to stash the result of get_remote_name_or_ip() before we close our socket or getpeername() will get EBADF and the process will exit. Only a problem for "UseLogin yes". - millert@cvs.openbsd.org 2000/08/20 12:30:59 [session.c] Only check /etc/nologin if "UseLogin no" since login(1) may have its own policy on determining who is allowed to login when /etc/nologin is present. Also use the _PATH_NOLOGIN define. - millert@cvs.openbsd.org 2000/08/20 12:42:43 [auth1.c auth2.c session.c ssh.c] Add calls to setusercontext() and login_get*(). We basically call setusercontext() in most places where previously we did a setlogin(). Add default login.conf file and put root in the "daemon" login class. - millert@cvs.openbsd.org 2000/08/21 10:23:31 [session.c] Fix incorrect PATH setting; noted by Markus.
Diffstat (limited to 'session.c')
-rw-r--r--session.c120
1 files changed, 88 insertions, 32 deletions
diff --git a/session.c b/session.c
index d65b0698..82096c3a 100644
--- a/session.c
+++ b/session.c
@@ -8,7 +8,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.25 2000/08/17 20:06:34 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.29 2000/08/21 16:23:31 millert Exp $");
#include "xmalloc.h"
#include "ssh.h"
@@ -52,6 +52,10 @@ RCSID("$OpenBSD: session.c,v 1.25 2000/08/17 20:06:34 markus Exp $");
# define S_UNOFILE_HARD S_UNOFILE "_hard"
#endif
+#ifdef HAVE_LOGIN_CAP
+#include <login_cap.h>
+#endif
+
/* types */
#define TTYSZ 64
@@ -117,6 +121,10 @@ Session sessions[MAX_SESSIONS];
char *aixloginmsg;
#endif /* WITH_AIXAUTHENTICATE */
+#ifdef HAVE_LOGIN_CAP
+static login_cap_t *lc;
+#endif
+
/*
* Remove local Xauthority file.
*/
@@ -200,6 +208,13 @@ do_authenticated(struct passwd * pw)
s = session_new();
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
* or a command.
@@ -650,7 +665,11 @@ do_login(Session *s)
/* Done if .hushlogin exists. */
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)
+#endif
return;
#ifdef USE_PAM
@@ -677,7 +696,12 @@ do_login(Session *s)
printf("Last login: %s from %s\r\n", time_string, buf);
}
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");
+#endif
if (f) {
while (fgets(buf, sizeof(buf), f))
fputs(buf, stdout);
@@ -887,10 +911,10 @@ do_child(const char *command, struct passwd * pw, const char *term,
const char *display, const char *auth_proto,
const char *auth_data, const char *ttyname)
{
- const char *shell, *cp = NULL;
+ const char *shell, *hostname, *cp = NULL;
char buf[256];
char cmd[1024];
- FILE *f;
+ FILE *f = NULL;
unsigned int envsize, i;
char **env;
extern char **environ;
@@ -905,24 +929,26 @@ do_child(const char *command, struct passwd * pw, const char *term,
options.use_login = 0;
#ifndef USE_PAM /* pam_nologin handles this */
- f = fopen("/etc/nologin", "r");
- if (f) {
- /* /etc/nologin exists. Print its contents and exit. */
- while (fgets(buf, sizeof(buf), f))
- fputs(buf, stderr);
- fclose(f);
- if (pw->pw_uid != 0)
+ 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 /* HAVE_LOGIN_CAP */
+ if (pw->pw_uid)
+ f = fopen(_PATH_NOLOGIN, "r");
+# endif /* HAVE_LOGIN_CAP */
+ if (f) {
+ /* /etc/nologin exists. Print its contents and exit. */
+ while (fgets(buf, sizeof(buf), f))
+ fputs(buf, stderr);
+ fclose(f);
exit(254);
+ }
}
#endif /* USE_PAM */
-#ifndef HAVE_OSF_SIA
- /* Set login name in the kernel. */
- if (setlogin(pw->pw_name) < 0)
- error("setlogin failed: %s", strerror(errno));
-#endif
-
- /* Set uid, gid, and groups. */
+ /* Set login name, uid, gid, and groups. */
/* Login(1) does this as well, and it needs uid 0 for the "-h"
switch, so we let login(1) to this for us. */
if (!options.use_login) {
@@ -943,10 +969,18 @@ do_child(const char *command, struct passwd * pw, const char *term,
}
#else /* HAVE_OSF_SIA */
if (getuid() == 0 || geteuid() == 0) {
-#if defined(HAVE_GETUSERATTR)
+# ifdef HAVE_GETUSERATTR
set_limits_from_userattr(pw->pw_name);
-#endif /* defined(HAVE_GETUSERATTR) */
-
+# endif /* HAVE_GETUSERATTR */
+# 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 /* HAVE_LOGIN_CAP */
+ if (setlogin(pw->pw_name) < 0)
+ error("setlogin failed: %s", strerror(errno));
if (setgid(pw->pw_gid) < 0) {
perror("setgid");
exit(1);
@@ -957,38 +991,39 @@ do_child(const char *command, struct passwd * pw, const char *term,
exit(1);
}
endgrent();
-
-#ifdef WITH_IRIX_ARRAY
+# ifdef WITH_IRIX_ARRAY
/* initialize array session */
if (newarraysess() != 0)
fatal("Failed to set up new array session: %.100s",
strerror(errno));
-#endif /* WITH_IRIX_ARRAY */
-
-#ifdef WITH_IRIX_PROJECT
+# endif /* WITH_IRIX_ARRAY */
+# ifdef WITH_IRIX_PROJECT
/* initialize irix project info */
if ((projid = getdfltprojuser(pw->pw_name)) == -1) {
debug("Failed to get project id, using projid 0");
projid = 0;
}
-
if (setprid(projid))
fatal("Failed to initialize project %d for %s: %.100s",
(int)projid, pw->pw_name, strerror(errno));
-#endif /* WITH_IRIX_PROJECT */
-
+# endif /* WITH_IRIX_PROJECT */
/* Permanently switch to the desired uid. */
permanently_set_uid(pw->pw_uid);
+# endif /* HAVE_LOGIN_CAP */
}
+#endif /* HAVE_OSF_SIA */
+
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
fatal("Failed to set uids to %d.", (int) pw->pw_uid);
-#endif /* HAVE_OSF_SIA */
}
/*
* Get the shell from the password data. An empty shell field is
* legal, and means /bin/sh.
*/
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
/* Try to get AFS tokens for the local cell. */
@@ -1012,7 +1047,12 @@ do_child(const char *command, struct passwd * pw, const char *term,
child_set_env(&env, &envsize, "USER", pw->pw_name);
child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
child_set_env(&env, &envsize, "HOME", pw->pw_dir);
+#ifdef HAVE_LOGIN_CAP
+ (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH);
+ child_set_env(&env, &envsize, "PATH", getenv("PATH"));
+#else
child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
+#endif
snprintf(buf, sizeof buf, "%.200s/%.50s",
_PATH_MAILDIR, pw->pw_name);
@@ -1096,6 +1136,9 @@ do_child(const char *command, struct passwd * pw, const char *term,
for (i = 0; env[i]; i++)
fprintf(stderr, " %.200s\n", env[i]);
}
+ /* we have to stash the hostname before we close our socket. */
+ if (options.use_login)
+ hostname = get_remote_name_or_ip();
/*
* Close the connection descriptors; note that this is the child, and
* the server will still have the socket open, and it is important
@@ -1132,9 +1175,14 @@ do_child(const char *command, struct passwd * pw, const char *term,
close(i);
/* 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",
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
@@ -1252,8 +1300,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
} else {
/* Launch login(1). */
- execl(LOGIN_PROGRAM, "login",
- "-h", get_remote_name_or_ip(),
+ execl(LOGIN_PROGRAM, "login", "-h", hostname,
"-p", "-f", "--", pw->pw_name, NULL);
/* Login couldn't be executed, die. */
@@ -1790,6 +1837,8 @@ session_proctitle(Session *s)
void
do_authenticated2(void)
{
+ struct passwd *pw;
+
/*
* Cancel the alarm we set to limit the time taken for
* authentication.
@@ -1799,6 +1848,13 @@ do_authenticated2(void)
close(startup_pipe);
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();
if (xauthfile)
xauthfile_cleanup_proc(NULL);