summaryrefslogtreecommitdiff
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 b4c0aaab7..e36b04942 100644
--- a/configure.ac
+++ b/configure.ac
@@ -896,11 +896,9 @@ mips-sony-bsd|mips-sony-newsos4)
896 else 896 else
897 AC_MSG_RESULT([no]) 897 AC_MSG_RESULT([no])
898 fi 898 fi
899 AC_CHECK_FUNC([setppriv], 899 AC_CHECK_FUNCS([setppriv])
900 [ AC_CHECK_HEADERS([priv.h], [ 900 AC_CHECK_FUNCS([priv_basicset])
901 SOLARIS_PRIVS="yes" 901 AC_CHECK_HEADERS([priv.h])
902 ])
903 ])
904 AC_ARG_WITH([solaris-contracts], 902 AC_ARG_WITH([solaris-contracts],
905 [ --with-solaris-contracts Enable Solaris process contracts (experimental)], 903 [ --with-solaris-contracts Enable Solaris process contracts (experimental)],
906 [ 904 [
@@ -925,7 +923,9 @@ mips-sony-bsd|mips-sony-newsos4)
925 [ --with-solaris-privs Enable Solaris/Illumos privileges (experimental)], 923 [ --with-solaris-privs Enable Solaris/Illumos privileges (experimental)],
926 [ 924 [
927 AC_MSG_CHECKING([for Solaris/Illumos privilege support]) 925 AC_MSG_CHECKING([for Solaris/Illumos privilege support])
928 if test "x$SOLARIS_PRIVS" = "xyes" ; then 926 if test "x$ac_cv_func_setppriv" = "xyes" -a \
927 "x$ac_cv_header_priv_h" = "xyes" ; then
928 SOLARIS_PRIVS=yes
929 AC_MSG_RESULT([found]) 929 AC_MSG_RESULT([found])
930 AC_DEFINE([NO_UID_RESTORATION_TEST], [1], 930 AC_DEFINE([NO_UID_RESTORATION_TEST], [1],
931 [Define to disable UID restoration test]) 931 [Define to disable UID restoration test])
diff --git a/openbsd-compat/port-solaris.c b/openbsd-compat/port-solaris.c
index 962cd1685..e36e412d7 100644
--- a/openbsd-compat/port-solaris.c
+++ b/openbsd-compat/port-solaris.c
@@ -233,6 +233,26 @@ solaris_set_default_project(struct passwd *pw)
233# include <priv.h> 233# include <priv.h>
234# endif 234# endif
235 235
236priv_set_t *
237solaris_basic_privset(void)
238{
239 priv_set_t *pset;
240
241#ifdef HAVE_PRIV_BASICSET
242 if ((pset = priv_allocset()) == NULL) {
243 error("priv_allocset: %s", strerror(errno));
244 return NULL;
245 }
246 priv_basicset(pset);
247#else
248 if ((pset = priv_str_to_set("basic", ",", NULL)) == NULL) {
249 error("priv_str_to_set: %s", strerror(errno));
250 return NULL;
251 }
252#endif
253 return pset;
254}
255
236void 256void
237solaris_drop_privs_pinfo_net_fork_exec(void) 257solaris_drop_privs_pinfo_net_fork_exec(void)
238{ 258{
@@ -254,11 +274,10 @@ solaris_drop_privs_pinfo_net_fork_exec(void)
254 * etc etc). 274 * etc etc).
255 */ 275 */
256 276
257 if ((pset = priv_allocset()) == NULL || 277 if ((pset = priv_allocset()) == NULL)
258 (npset = priv_allocset()) == NULL)
259 fatal("priv_allocset: %s", strerror(errno)); 278 fatal("priv_allocset: %s", strerror(errno));
260 279 if ((npset = solaris_basic_privset()) == NULL)
261 priv_basicset(npset); 280 fatal("solaris_basic_privset: %s", strerror(errno));
262 281
263 if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 || 282 if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 ||
264 priv_addset(npset, PRIV_FILE_DAC_READ) != 0 || 283 priv_addset(npset, PRIV_FILE_DAC_READ) != 0 ||
@@ -268,7 +287,9 @@ solaris_drop_privs_pinfo_net_fork_exec(void)
268 fatal("priv_addset: %s", strerror(errno)); 287 fatal("priv_addset: %s", strerror(errno));
269 288
270 if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 || 289 if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 ||
290#ifdef PRIV_NET_ACCESS
271 priv_delset(npset, PRIV_NET_ACCESS) != 0 || 291 priv_delset(npset, PRIV_NET_ACCESS) != 0 ||
292#endif
272 priv_delset(npset, PRIV_PROC_EXEC) != 0 || 293 priv_delset(npset, PRIV_PROC_EXEC) != 0 ||
273 priv_delset(npset, PRIV_PROC_FORK) != 0 || 294 priv_delset(npset, PRIV_PROC_FORK) != 0 ||
274 priv_delset(npset, PRIV_PROC_INFO) != 0 || 295 priv_delset(npset, PRIV_PROC_INFO) != 0 ||
@@ -294,14 +315,14 @@ solaris_drop_privs_root_pinfo_net(void)
294{ 315{
295 priv_set_t *pset = NULL; 316 priv_set_t *pset = NULL;
296 317
297 if ((pset = priv_allocset()) == NULL)
298 fatal("priv_allocset: %s", strerror(errno));
299
300 /* Start with "basic" and drop everything we don't need. */ 318 /* Start with "basic" and drop everything we don't need. */
301 priv_basicset(pset); 319 if ((pset = solaris_basic_privset()) == NULL)
320 fatal("solaris_basic_privset: %s", strerror(errno));
302 321
303 if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 || 322 if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
323#ifdef PRIV_NET_ACCESS
304 priv_delset(pset, PRIV_NET_ACCESS) != 0 || 324 priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
325#endif
305 priv_delset(pset, PRIV_PROC_INFO) != 0 || 326 priv_delset(pset, PRIV_PROC_INFO) != 0 ||
306 priv_delset(pset, PRIV_PROC_SESSION) != 0) 327 priv_delset(pset, PRIV_PROC_SESSION) != 0)
307 fatal("priv_delset: %s", strerror(errno)); 328 fatal("priv_delset: %s", strerror(errno));
@@ -319,14 +340,15 @@ solaris_drop_privs_root_pinfo_net_exec(void)
319{ 340{
320 priv_set_t *pset = NULL; 341 priv_set_t *pset = NULL;
321 342
322 if ((pset = priv_allocset()) == NULL)
323 fatal("priv_allocset: %s", strerror(errno));
324 343
325 /* Start with "basic" and drop everything we don't need. */ 344 /* Start with "basic" and drop everything we don't need. */
326 priv_basicset(pset); 345 if ((pset = solaris_basic_privset()) == NULL)
346 fatal("solaris_basic_privset: %s", strerror(errno));
327 347
328 if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 || 348 if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
349#ifdef PRIV_NET_ACCESS
329 priv_delset(pset, PRIV_NET_ACCESS) != 0 || 350 priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
351#endif
330 priv_delset(pset, PRIV_PROC_EXEC) != 0 || 352 priv_delset(pset, PRIV_PROC_EXEC) != 0 ||
331 priv_delset(pset, PRIV_PROC_INFO) != 0 || 353 priv_delset(pset, PRIV_PROC_INFO) != 0 ||
332 priv_delset(pset, PRIV_PROC_SESSION) != 0) 354 priv_delset(pset, PRIV_PROC_SESSION) != 0)
diff --git a/openbsd-compat/port-solaris.h b/openbsd-compat/port-solaris.h
index b077e186a..3a41ea8cd 100644
--- a/openbsd-compat/port-solaris.h
+++ b/openbsd-compat/port-solaris.h
@@ -26,8 +26,11 @@ void solaris_contract_pre_fork(void);
26void solaris_contract_post_fork_child(void); 26void solaris_contract_post_fork_child(void);
27void solaris_contract_post_fork_parent(pid_t pid); 27void solaris_contract_post_fork_parent(pid_t pid);
28void solaris_set_default_project(struct passwd *); 28void solaris_set_default_project(struct passwd *);
29# ifdef USE_SOLARIS_PRIVS
30priv_set_t *solaris_basic_privset(void);
29void solaris_drop_privs_pinfo_net_fork_exec(void); 31void solaris_drop_privs_pinfo_net_fork_exec(void);
30void solaris_drop_privs_root_pinfo_net(void); 32void solaris_drop_privs_root_pinfo_net(void);
31void solaris_drop_privs_root_pinfo_net_exec(void); 33void solaris_drop_privs_root_pinfo_net_exec(void);
34# endif /* USE_SOLARIS_PRIVS */
32 35
33#endif 36#endif
diff --git a/sandbox-solaris.c b/sandbox-solaris.c
index 98714e170..343a01022 100644
--- a/sandbox-solaris.c
+++ b/sandbox-solaris.c
@@ -48,19 +48,20 @@ ssh_sandbox_init(struct monitor *monitor)
48 struct ssh_sandbox *box = NULL; 48 struct ssh_sandbox *box = NULL;
49 49
50 box = xcalloc(1, sizeof(*box)); 50 box = xcalloc(1, sizeof(*box));
51 box->pset = priv_allocset(); 51
52 /* Start with "basic" and drop everything we don't need. */
53 box->pset = solaris_basic_privset();
52 54
53 if (box->pset == NULL) { 55 if (box->pset == NULL) {
54 free(box); 56 free(box);
55 return NULL; 57 return NULL;
56 } 58 }
57 59
58 /* Start with "basic" and drop everything we don't need. */
59 priv_basicset(box->pset);
60
61 /* Drop everything except the ability to use already-opened files */ 60 /* Drop everything except the ability to use already-opened files */
62 if (priv_delset(box->pset, PRIV_FILE_LINK_ANY) != 0 || 61 if (priv_delset(box->pset, PRIV_FILE_LINK_ANY) != 0 ||
62#ifdef PRIV_NET_ACCESS
63 priv_delset(box->pset, PRIV_NET_ACCESS) != 0 || 63 priv_delset(box->pset, PRIV_NET_ACCESS) != 0 ||
64#endif
64 priv_delset(box->pset, PRIV_PROC_EXEC) != 0 || 65 priv_delset(box->pset, PRIV_PROC_EXEC) != 0 ||
65 priv_delset(box->pset, PRIV_PROC_FORK) != 0 || 66 priv_delset(box->pset, PRIV_PROC_FORK) != 0 ||
66 priv_delset(box->pset, PRIV_PROC_INFO) != 0 || 67 priv_delset(box->pset, PRIV_PROC_INFO) != 0 ||