forked from rpms/openssh
22a08c3da4
The previous required to have for all SELInux user contexts with setexec capability. Otherwise user would not be able to change password if it is expired. This patch sets correct context and cleans up the exec context. When doing chroot, copy_selinux_context is called twice
139 lines
3.8 KiB
Diff
139 lines
3.8 KiB
Diff
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
|
|
index c18524e..d04f4ed 100644
|
|
--- a/openbsd-compat/port-linux-sshd.c
|
|
+++ b/openbsd-compat/port-linux-sshd.c
|
|
@@ -409,6 +409,28 @@ sshd_selinux_setup_exec_context(char *pwname)
|
|
debug3("%s: done", __func__);
|
|
}
|
|
|
|
+void
|
|
+sshd_selinux_copy_context(void)
|
|
+{
|
|
+ security_context_t *ctx;
|
|
+
|
|
+ if (!ssh_selinux_enabled())
|
|
+ return;
|
|
+
|
|
+ if (getexeccon((security_context_t *)&ctx) != 0) {
|
|
+ logit("%s: getcon failed with %s", __func__, strerror (errno));
|
|
+ return;
|
|
+ }
|
|
+ if (ctx != NULL) {
|
|
+ /* unset exec context before we will lose this capabililty */
|
|
+ if (setexeccon(NULL) != 0)
|
|
+ fatal("%s: setexeccon failed with %s", __func__, strerror (errno));
|
|
+ if (setcon(ctx) != 0)
|
|
+ fatal("%s: setcon failed with %s", __func__, strerror (errno));
|
|
+ freecon(ctx);
|
|
+ }
|
|
+}
|
|
+
|
|
#endif
|
|
#endif
|
|
|
|
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
|
|
index 8ef6cc4..b18893c 100644
|
|
--- a/openbsd-compat/port-linux.h
|
|
+++ b/openbsd-compat/port-linux.h
|
|
@@ -25,6 +25,7 @@ void ssh_selinux_setup_pty(char *, const char *);
|
|
void ssh_selinux_change_context(const char *);
|
|
void ssh_selinux_setfscreatecon(const char *);
|
|
|
|
+void sshd_selinux_copy_context(void);
|
|
void sshd_selinux_setup_exec_context(char *);
|
|
#endif
|
|
|
|
diff --git a/session.c b/session.c
|
|
index 2bcf818..b5dc144 100644
|
|
--- a/session.c
|
|
+++ b/session.c
|
|
@@ -1532,7 +1532,7 @@ void
|
|
do_setusercontext(struct passwd *pw)
|
|
{
|
|
char *chroot_path, *tmp;
|
|
-#ifdef USE_LIBIAF
|
|
+#if defined(USE_LIBIAF) || defined(WITH_SELINUX)
|
|
int doing_chroot = 0;
|
|
#endif
|
|
|
|
@@ -1538,6 +1538,9 @@ do_setusercontext(struct passwd *pw)
|
|
pw->pw_uid);
|
|
chroot_path = percent_expand(tmp, "h", pw->pw_dir,
|
|
"u", pw->pw_name, (char *)NULL);
|
|
+#ifdef WITH_SELINUX
|
|
+ sshd_selinux_copy_context();
|
|
+#endif
|
|
safely_chroot(chroot_path, pw->pw_uid);
|
|
free(tmp);
|
|
free(chroot_path);
|
|
@@ -1557,7 +1557,7 @@ do_setusercontext(struct passwd *pw)
|
|
/* Make sure we don't attempt to chroot again */
|
|
free(options.chroot_directory);
|
|
options.chroot_directory = NULL;
|
|
-#ifdef USE_LIBIAF
|
|
+#if defined(USE_LIBIAF) || defined(WITH_SELINUX)
|
|
doing_chroot = 1;
|
|
#endif
|
|
}
|
|
@@ -1565,6 +1568,11 @@ do_setusercontext(struct passwd *pw)
|
|
/* Permanently switch to the desired uid. */
|
|
permanently_set_uid(pw);
|
|
#endif
|
|
+
|
|
+#ifdef WITH_SELINUX
|
|
+ if (doing_chroot == 0)
|
|
+ sshd_selinux_copy_context();
|
|
+#endif
|
|
} else if (options.chroot_directory != NULL &&
|
|
strcasecmp(options.chroot_directory, "none") != 0) {
|
|
fatal("server lacks privileges to chroot to ChrootDirectory");
|
|
@@ -1588,9 +1588,6 @@ do_pwchange(Session *s)
|
|
if (s->ttyfd != -1) {
|
|
fprintf(stderr,
|
|
"You must change your password now and login again!\n");
|
|
-#ifdef WITH_SELINUX
|
|
- setexeccon(NULL);
|
|
-#endif
|
|
#ifdef PASSWD_NEEDS_USERNAME
|
|
execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
|
|
(char *)NULL);
|
|
@@ -1826,9 +1835,6 @@ do_child(Session *s, const char *command)
|
|
argv[i] = NULL;
|
|
optind = optreset = 1;
|
|
__progname = argv[0];
|
|
-#ifdef WITH_SELINUX
|
|
- ssh_selinux_change_context("sftpd_t");
|
|
-#endif
|
|
exit(sftp_server_main(i, argv, s->pw));
|
|
}
|
|
|
|
diff --git a/sshd.c b/sshd.c
|
|
index 07f9926..a97f8b7 100644
|
|
--- a/sshd.c
|
|
+++ b/sshd.c
|
|
@@ -632,6 +632,10 @@ privsep_preauth_child(void)
|
|
/* Demote the private keys to public keys. */
|
|
demote_sensitive_data();
|
|
|
|
+#ifdef WITH_SELINUX
|
|
+ ssh_selinux_change_context("sshd_net_t");
|
|
+#endif
|
|
+
|
|
/* Change our root directory */
|
|
if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
|
|
fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
|
|
@@ -768,6 +772,13 @@ privsep_postauth(Authctxt *authctxt)
|
|
do_setusercontext(authctxt->pw);
|
|
|
|
skip:
|
|
+#ifdef WITH_SELINUX
|
|
+ /* switch SELinux content for root too */
|
|
+ if (authctxt->pw->pw_uid == 0) {
|
|
+ sshd_selinux_copy_context();
|
|
+ }
|
|
+#endif
|
|
+
|
|
/* It is safe now to apply the key state */
|
|
monitor_apply_keystate(pmonitor);
|
|
|