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)
- (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 d65b06984..82096c3ab 100644
--- a/session.c
+++ b/session.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#include "includes.h" 10#include "includes.h"
11RCSID("$OpenBSD: session.c,v 1.25 2000/08/17 20:06:34 markus Exp $"); 11RCSID("$OpenBSD: session.c,v 1.29 2000/08/21 16:23:31 millert Exp $");
12 12
13#include "xmalloc.h" 13#include "xmalloc.h"
14#include "ssh.h" 14#include "ssh.h"
@@ -52,6 +52,10 @@ RCSID("$OpenBSD: session.c,v 1.25 2000/08/17 20:06:34 markus Exp $");
52# define S_UNOFILE_HARD S_UNOFILE "_hard" 52# define S_UNOFILE_HARD S_UNOFILE "_hard"
53#endif 53#endif
54 54
55#ifdef HAVE_LOGIN_CAP
56#include <login_cap.h>
57#endif
58
55/* types */ 59/* types */
56 60
57#define TTYSZ 64 61#define TTYSZ 64
@@ -117,6 +121,10 @@ Session sessions[MAX_SESSIONS];
117char *aixloginmsg; 121char *aixloginmsg;
118#endif /* WITH_AIXAUTHENTICATE */ 122#endif /* WITH_AIXAUTHENTICATE */
119 123
124#ifdef HAVE_LOGIN_CAP
125static login_cap_t *lc;
126#endif
127
120/* 128/*
121 * Remove local Xauthority file. 129 * Remove local Xauthority file.
122 */ 130 */
@@ -200,6 +208,13 @@ do_authenticated(struct passwd * pw)
200 s = session_new(); 208 s = session_new();
201 s->pw = pw; 209 s->pw = pw;
202 210
211#ifdef HAVE_LOGIN_CAP
212 if ((lc = login_getclass(pw->pw_class)) == NULL) {
213 error("unable to get login class");
214 return;
215 }
216#endif
217
203 /* 218 /*
204 * We stay in this loop until the client requests to execute a shell 219 * We stay in this loop until the client requests to execute a shell
205 * or a command. 220 * or a command.
@@ -650,7 +665,11 @@ do_login(Session *s)
650 665
651 /* Done if .hushlogin exists. */ 666 /* Done if .hushlogin exists. */
652 snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir); 667 snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
668#ifdef HAVE_LOGIN_CAP
669 if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
670#else
653 if (stat(buf, &st) >= 0) 671 if (stat(buf, &st) >= 0)
672#endif
654 return; 673 return;
655 674
656#ifdef USE_PAM 675#ifdef USE_PAM
@@ -677,7 +696,12 @@ do_login(Session *s)
677 printf("Last login: %s from %s\r\n", time_string, buf); 696 printf("Last login: %s from %s\r\n", time_string, buf);
678 } 697 }
679 if (options.print_motd) { 698 if (options.print_motd) {
699#ifdef HAVE_LOGIN_CAP
700 f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
701 "/etc/motd"), "r");
702#else
680 f = fopen("/etc/motd", "r"); 703 f = fopen("/etc/motd", "r");
704#endif
681 if (f) { 705 if (f) {
682 while (fgets(buf, sizeof(buf), f)) 706 while (fgets(buf, sizeof(buf), f))
683 fputs(buf, stdout); 707 fputs(buf, stdout);
@@ -887,10 +911,10 @@ do_child(const char *command, struct passwd * pw, const char *term,
887 const char *display, const char *auth_proto, 911 const char *display, const char *auth_proto,
888 const char *auth_data, const char *ttyname) 912 const char *auth_data, const char *ttyname)
889{ 913{
890 const char *shell, *cp = NULL; 914 const char *shell, *hostname, *cp = NULL;
891 char buf[256]; 915 char buf[256];
892 char cmd[1024]; 916 char cmd[1024];
893 FILE *f; 917 FILE *f = NULL;
894 unsigned int envsize, i; 918 unsigned int envsize, i;
895 char **env; 919 char **env;
896 extern char **environ; 920 extern char **environ;
@@ -905,24 +929,26 @@ do_child(const char *command, struct passwd * pw, const char *term,
905 options.use_login = 0; 929 options.use_login = 0;
906 930
907#ifndef USE_PAM /* pam_nologin handles this */ 931#ifndef USE_PAM /* pam_nologin handles this */
908 f = fopen("/etc/nologin", "r"); 932 if (!options.use_login) {
909 if (f) { 933# ifdef HAVE_LOGIN_CAP
910 /* /etc/nologin exists. Print its contents and exit. */ 934 if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
911 while (fgets(buf, sizeof(buf), f)) 935 f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
912 fputs(buf, stderr); 936 _PATH_NOLOGIN), "r");
913 fclose(f); 937# else /* HAVE_LOGIN_CAP */
914 if (pw->pw_uid != 0) 938 if (pw->pw_uid)
939 f = fopen(_PATH_NOLOGIN, "r");
940# endif /* HAVE_LOGIN_CAP */
941 if (f) {
942 /* /etc/nologin exists. Print its contents and exit. */
943 while (fgets(buf, sizeof(buf), f))
944 fputs(buf, stderr);
945 fclose(f);
915 exit(254); 946 exit(254);
947 }
916 } 948 }
917#endif /* USE_PAM */ 949#endif /* USE_PAM */
918 950
919#ifndef HAVE_OSF_SIA 951 /* Set login name, uid, gid, and groups. */
920 /* Set login name in the kernel. */
921 if (setlogin(pw->pw_name) < 0)
922 error("setlogin failed: %s", strerror(errno));
923#endif
924
925 /* Set uid, gid, and groups. */
926 /* Login(1) does this as well, and it needs uid 0 for the "-h" 952 /* Login(1) does this as well, and it needs uid 0 for the "-h"
927 switch, so we let login(1) to this for us. */ 953 switch, so we let login(1) to this for us. */
928 if (!options.use_login) { 954 if (!options.use_login) {
@@ -943,10 +969,18 @@ do_child(const char *command, struct passwd * pw, const char *term,
943 } 969 }
944#else /* HAVE_OSF_SIA */ 970#else /* HAVE_OSF_SIA */
945 if (getuid() == 0 || geteuid() == 0) { 971 if (getuid() == 0 || geteuid() == 0) {
946#if defined(HAVE_GETUSERATTR) 972# ifdef HAVE_GETUSERATTR
947 set_limits_from_userattr(pw->pw_name); 973 set_limits_from_userattr(pw->pw_name);
948#endif /* defined(HAVE_GETUSERATTR) */ 974# endif /* HAVE_GETUSERATTR */
949 975# ifdef HAVE_LOGIN_CAP
976 if (setusercontext(lc, pw, pw->pw_uid,
977 (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
978 perror("unable to set user context");
979 exit(1);
980 }
981# else /* HAVE_LOGIN_CAP */
982 if (setlogin(pw->pw_name) < 0)
983 error("setlogin failed: %s", strerror(errno));
950 if (setgid(pw->pw_gid) < 0) { 984 if (setgid(pw->pw_gid) < 0) {
951 perror("setgid"); 985 perror("setgid");
952 exit(1); 986 exit(1);
@@ -957,38 +991,39 @@ do_child(const char *command, struct passwd * pw, const char *term,
957 exit(1); 991 exit(1);
958 } 992 }
959 endgrent(); 993 endgrent();
960 994# ifdef WITH_IRIX_ARRAY
961#ifdef WITH_IRIX_ARRAY
962 /* initialize array session */ 995 /* initialize array session */
963 if (newarraysess() != 0) 996 if (newarraysess() != 0)
964 fatal("Failed to set up new array session: %.100s", 997 fatal("Failed to set up new array session: %.100s",
965 strerror(errno)); 998 strerror(errno));
966#endif /* WITH_IRIX_ARRAY */ 999# endif /* WITH_IRIX_ARRAY */
967 1000# ifdef WITH_IRIX_PROJECT
968#ifdef WITH_IRIX_PROJECT
969 /* initialize irix project info */ 1001 /* initialize irix project info */
970 if ((projid = getdfltprojuser(pw->pw_name)) == -1) { 1002 if ((projid = getdfltprojuser(pw->pw_name)) == -1) {
971 debug("Failed to get project id, using projid 0"); 1003 debug("Failed to get project id, using projid 0");
972 projid = 0; 1004 projid = 0;
973 } 1005 }
974
975 if (setprid(projid)) 1006 if (setprid(projid))
976 fatal("Failed to initialize project %d for %s: %.100s", 1007 fatal("Failed to initialize project %d for %s: %.100s",
977 (int)projid, pw->pw_name, strerror(errno)); 1008 (int)projid, pw->pw_name, strerror(errno));
978#endif /* WITH_IRIX_PROJECT */ 1009# endif /* WITH_IRIX_PROJECT */
979
980 /* Permanently switch to the desired uid. */ 1010 /* Permanently switch to the desired uid. */
981 permanently_set_uid(pw->pw_uid); 1011 permanently_set_uid(pw->pw_uid);
1012# endif /* HAVE_LOGIN_CAP */
982 } 1013 }
1014#endif /* HAVE_OSF_SIA */
1015
983 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) 1016 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
984 fatal("Failed to set uids to %d.", (int) pw->pw_uid); 1017 fatal("Failed to set uids to %d.", (int) pw->pw_uid);
985#endif /* HAVE_OSF_SIA */
986 } 1018 }
987 /* 1019 /*
988 * Get the shell from the password data. An empty shell field is 1020 * Get the shell from the password data. An empty shell field is
989 * legal, and means /bin/sh. 1021 * legal, and means /bin/sh.
990 */ 1022 */
991 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; 1023 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
1024#ifdef HAVE_LOGIN_CAP
1025 shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
1026#endif
992 1027
993#ifdef AFS 1028#ifdef AFS
994 /* Try to get AFS tokens for the local cell. */ 1029 /* Try to get AFS tokens for the local cell. */
@@ -1012,7 +1047,12 @@ do_child(const char *command, struct passwd * pw, const char *term,
1012 child_set_env(&env, &envsize, "USER", pw->pw_name); 1047 child_set_env(&env, &envsize, "USER", pw->pw_name);
1013 child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); 1048 child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
1014 child_set_env(&env, &envsize, "HOME", pw->pw_dir); 1049 child_set_env(&env, &envsize, "HOME", pw->pw_dir);
1050#ifdef HAVE_LOGIN_CAP
1051 (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH);
1052 child_set_env(&env, &envsize, "PATH", getenv("PATH"));
1053#else
1015 child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); 1054 child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
1055#endif
1016 1056
1017 snprintf(buf, sizeof buf, "%.200s/%.50s", 1057 snprintf(buf, sizeof buf, "%.200s/%.50s",
1018 _PATH_MAILDIR, pw->pw_name); 1058 _PATH_MAILDIR, pw->pw_name);
@@ -1096,6 +1136,9 @@ do_child(const char *command, struct passwd * pw, const char *term,
1096 for (i = 0; env[i]; i++) 1136 for (i = 0; env[i]; i++)
1097 fprintf(stderr, " %.200s\n", env[i]); 1137 fprintf(stderr, " %.200s\n", env[i]);
1098 } 1138 }
1139 /* we have to stash the hostname before we close our socket. */
1140 if (options.use_login)
1141 hostname = get_remote_name_or_ip();
1099 /* 1142 /*
1100 * Close the connection descriptors; note that this is the child, and 1143 * Close the connection descriptors; note that this is the child, and
1101 * the server will still have the socket open, and it is important 1144 * 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,
1132 close(i); 1175 close(i);
1133 1176
1134 /* Change current directory to the user\'s home directory. */ 1177 /* Change current directory to the user\'s home directory. */
1135 if (chdir(pw->pw_dir) < 0) 1178 if (chdir(pw->pw_dir) < 0) {
1136 fprintf(stderr, "Could not chdir to home directory %s: %s\n", 1179 fprintf(stderr, "Could not chdir to home directory %s: %s\n",
1137 pw->pw_dir, strerror(errno)); 1180 pw->pw_dir, strerror(errno));
1181#ifdef HAVE_LOGIN_CAP
1182 if (login_getcapbool(lc, "requirehome", 0))
1183 exit(1);
1184#endif
1185 }
1138 1186
1139 /* 1187 /*
1140 * Must take new environment into use so that .ssh/rc, /etc/sshrc and 1188 * 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,
1252 } else { 1300 } else {
1253 /* Launch login(1). */ 1301 /* Launch login(1). */
1254 1302
1255 execl(LOGIN_PROGRAM, "login", 1303 execl(LOGIN_PROGRAM, "login", "-h", hostname,
1256 "-h", get_remote_name_or_ip(),
1257 "-p", "-f", "--", pw->pw_name, NULL); 1304 "-p", "-f", "--", pw->pw_name, NULL);
1258 1305
1259 /* Login couldn't be executed, die. */ 1306 /* Login couldn't be executed, die. */
@@ -1790,6 +1837,8 @@ session_proctitle(Session *s)
1790void 1837void
1791do_authenticated2(void) 1838do_authenticated2(void)
1792{ 1839{
1840 struct passwd *pw;
1841
1793 /* 1842 /*
1794 * Cancel the alarm we set to limit the time taken for 1843 * Cancel the alarm we set to limit the time taken for
1795 * authentication. 1844 * authentication.
@@ -1799,6 +1848,13 @@ do_authenticated2(void)
1799 close(startup_pipe); 1848 close(startup_pipe);
1800 startup_pipe = -1; 1849 startup_pipe = -1;
1801 } 1850 }
1851#ifdef HAVE_LOGIN_CAP
1852 pw = auth_get_user();
1853 if ((lc = login_getclass(pw->pw_class)) == NULL) {
1854 error("unable to get login class");
1855 return;
1856 }
1857#endif
1802 server_loop2(); 1858 server_loop2();
1803 if (xauthfile) 1859 if (xauthfile)
1804 xauthfile_cleanup_proc(NULL); 1860 xauthfile_cleanup_proc(NULL);