diff options
author | Damien Miller <djm@mindrot.org> | 2000-08-23 10:46:23 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2000-08-23 10:46:23 +1000 |
commit | ad833b3e65c1887674714d514eb818d862bb499a (patch) | |
tree | 16fa75fe42aede072c5d3edac562c2870d1bb0e5 /session.c | |
parent | b078567bf5de1dcf12d265d98acb4dc9eba8b325 (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.c | 120 |
1 files changed, 88 insertions, 32 deletions
@@ -8,7 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include "includes.h" | 10 | #include "includes.h" |
11 | RCSID("$OpenBSD: session.c,v 1.25 2000/08/17 20:06:34 markus Exp $"); | 11 | RCSID("$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]; | |||
117 | char *aixloginmsg; | 121 | char *aixloginmsg; |
118 | #endif /* WITH_AIXAUTHENTICATE */ | 122 | #endif /* WITH_AIXAUTHENTICATE */ |
119 | 123 | ||
124 | #ifdef HAVE_LOGIN_CAP | ||
125 | static 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) | |||
1790 | void | 1837 | void |
1791 | do_authenticated2(void) | 1838 | do_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); |