summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2016-02-19 09:05:39 +1100
committerDarren Tucker <dtucker@zip.com.au>2016-02-19 09:05:39 +1100
commit907091acb188b1057d50c2158f74c3ecf1c2302b (patch)
tree62f2c59f51e55a3f49c7c173527425eb1b19a876
parent292a8dee14e5e67dcd1b49ba5c7b9023e8420d59 (diff)
Make Solaris privs code build on older systems.
Not all systems with Solaris privs have priv_basicset so factor that out and provide backward compatibility code. Similarly, not all have PRIV_NET_ACCESS so wrap that in #ifdef. Based on code from alex at cooperi.net and djm@ with help from carson at taltos.org and wieland at purdue.edu.
-rw-r--r--configure.ac12
-rw-r--r--openbsd-compat/port-solaris.c44
-rw-r--r--openbsd-compat/port-solaris.h3
-rw-r--r--sandbox-solaris.c9
4 files changed, 47 insertions, 21 deletions
diff --git a/configure.ac b/configure.ac
index b4c0aaab..e36b0494 100644
--- a/configure.ac
+++ b/configure.ac
@@ -896,11 +896,9 @@ mips-sony-bsd|mips-sony-newsos4)
else
AC_MSG_RESULT([no])
fi
- AC_CHECK_FUNC([setppriv],
- [ AC_CHECK_HEADERS([priv.h], [
- SOLARIS_PRIVS="yes"
- ])
- ])
+ AC_CHECK_FUNCS([setppriv])
+ AC_CHECK_FUNCS([priv_basicset])
+ AC_CHECK_HEADERS([priv.h])
AC_ARG_WITH([solaris-contracts],
[ --with-solaris-contracts Enable Solaris process contracts (experimental)],
[
@@ -925,7 +923,9 @@ mips-sony-bsd|mips-sony-newsos4)
[ --with-solaris-privs Enable Solaris/Illumos privileges (experimental)],
[
AC_MSG_CHECKING([for Solaris/Illumos privilege support])
- if test "x$SOLARIS_PRIVS" = "xyes" ; then
+ if test "x$ac_cv_func_setppriv" = "xyes" -a \
+ "x$ac_cv_header_priv_h" = "xyes" ; then
+ SOLARIS_PRIVS=yes
AC_MSG_RESULT([found])
AC_DEFINE([NO_UID_RESTORATION_TEST], [1],
[Define to disable UID restoration test])
diff --git a/openbsd-compat/port-solaris.c b/openbsd-compat/port-solaris.c
index 962cd168..e36e412d 100644
--- a/openbsd-compat/port-solaris.c
+++ b/openbsd-compat/port-solaris.c
@@ -233,6 +233,26 @@ solaris_set_default_project(struct passwd *pw)
# include <priv.h>
# endif
+priv_set_t *
+solaris_basic_privset(void)
+{
+ priv_set_t *pset;
+
+#ifdef HAVE_PRIV_BASICSET
+ if ((pset = priv_allocset()) == NULL) {
+ error("priv_allocset: %s", strerror(errno));
+ return NULL;
+ }
+ priv_basicset(pset);
+#else
+ if ((pset = priv_str_to_set("basic", ",", NULL)) == NULL) {
+ error("priv_str_to_set: %s", strerror(errno));
+ return NULL;
+ }
+#endif
+ return pset;
+}
+
void
solaris_drop_privs_pinfo_net_fork_exec(void)
{
@@ -254,11 +274,10 @@ solaris_drop_privs_pinfo_net_fork_exec(void)
* etc etc).
*/
- if ((pset = priv_allocset()) == NULL ||
- (npset = priv_allocset()) == NULL)
+ if ((pset = priv_allocset()) == NULL)
fatal("priv_allocset: %s", strerror(errno));
-
- priv_basicset(npset);
+ if ((npset = solaris_basic_privset()) == NULL)
+ fatal("solaris_basic_privset: %s", strerror(errno));
if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 ||
priv_addset(npset, PRIV_FILE_DAC_READ) != 0 ||
@@ -268,7 +287,9 @@ solaris_drop_privs_pinfo_net_fork_exec(void)
fatal("priv_addset: %s", strerror(errno));
if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 ||
+#ifdef PRIV_NET_ACCESS
priv_delset(npset, PRIV_NET_ACCESS) != 0 ||
+#endif
priv_delset(npset, PRIV_PROC_EXEC) != 0 ||
priv_delset(npset, PRIV_PROC_FORK) != 0 ||
priv_delset(npset, PRIV_PROC_INFO) != 0 ||
@@ -294,14 +315,14 @@ solaris_drop_privs_root_pinfo_net(void)
{
priv_set_t *pset = NULL;
- if ((pset = priv_allocset()) == NULL)
- fatal("priv_allocset: %s", strerror(errno));
-
/* Start with "basic" and drop everything we don't need. */
- priv_basicset(pset);
+ if ((pset = solaris_basic_privset()) == NULL)
+ fatal("solaris_basic_privset: %s", strerror(errno));
if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
+#ifdef PRIV_NET_ACCESS
priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
+#endif
priv_delset(pset, PRIV_PROC_INFO) != 0 ||
priv_delset(pset, PRIV_PROC_SESSION) != 0)
fatal("priv_delset: %s", strerror(errno));
@@ -319,14 +340,15 @@ solaris_drop_privs_root_pinfo_net_exec(void)
{
priv_set_t *pset = NULL;
- if ((pset = priv_allocset()) == NULL)
- fatal("priv_allocset: %s", strerror(errno));
/* Start with "basic" and drop everything we don't need. */
- priv_basicset(pset);
+ if ((pset = solaris_basic_privset()) == NULL)
+ fatal("solaris_basic_privset: %s", strerror(errno));
if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
+#ifdef PRIV_NET_ACCESS
priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
+#endif
priv_delset(pset, PRIV_PROC_EXEC) != 0 ||
priv_delset(pset, PRIV_PROC_INFO) != 0 ||
priv_delset(pset, PRIV_PROC_SESSION) != 0)
diff --git a/openbsd-compat/port-solaris.h b/openbsd-compat/port-solaris.h
index b077e186..3a41ea8c 100644
--- a/openbsd-compat/port-solaris.h
+++ b/openbsd-compat/port-solaris.h
@@ -26,8 +26,11 @@ void solaris_contract_pre_fork(void);
void solaris_contract_post_fork_child(void);
void solaris_contract_post_fork_parent(pid_t pid);
void solaris_set_default_project(struct passwd *);
+# ifdef USE_SOLARIS_PRIVS
+priv_set_t *solaris_basic_privset(void);
void solaris_drop_privs_pinfo_net_fork_exec(void);
void solaris_drop_privs_root_pinfo_net(void);
void solaris_drop_privs_root_pinfo_net_exec(void);
+# endif /* USE_SOLARIS_PRIVS */
#endif
diff --git a/sandbox-solaris.c b/sandbox-solaris.c
index 98714e17..343a0102 100644
--- a/sandbox-solaris.c
+++ b/sandbox-solaris.c
@@ -48,19 +48,20 @@ ssh_sandbox_init(struct monitor *monitor)
struct ssh_sandbox *box = NULL;
box = xcalloc(1, sizeof(*box));
- box->pset = priv_allocset();
+
+ /* Start with "basic" and drop everything we don't need. */
+ box->pset = solaris_basic_privset();
if (box->pset == NULL) {
free(box);
return NULL;
}
- /* Start with "basic" and drop everything we don't need. */
- priv_basicset(box->pset);
-
/* Drop everything except the ability to use already-opened files */
if (priv_delset(box->pset, PRIV_FILE_LINK_ANY) != 0 ||
+#ifdef PRIV_NET_ACCESS
priv_delset(box->pset, PRIV_NET_ACCESS) != 0 ||
+#endif
priv_delset(box->pset, PRIV_PROC_EXEC) != 0 ||
priv_delset(box->pset, PRIV_PROC_FORK) != 0 ||
priv_delset(box->pset, PRIV_PROC_INFO) != 0 ||