diff options
author | Renato Botelho <renato@netgate.com> | 2016-03-14 07:56:21 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2016-03-14 07:56:21 -0300 |
commit | a26e4b3de35515ec3eaf2eb76b001a6a502bf56c (patch) | |
tree | 66dd86f3e16db9b45f07c989e95501b6456cf6a5 /crypto/openssh/openbsd-compat/port-solaris.c | |
parent | 7d66bf7f17e48798ec04b7a6d99daff1820e28f8 (diff) | |
parent | a64e8d254dc9ecd38594b71dcd7d53c6084c5abc (diff) | |
download | FreeBSD-src-a26e4b3de35515ec3eaf2eb76b001a6a502bf56c.zip FreeBSD-src-a26e4b3de35515ec3eaf2eb76b001a6a502bf56c.tar.gz |
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'crypto/openssh/openbsd-compat/port-solaris.c')
-rw-r--r-- | crypto/openssh/openbsd-compat/port-solaris.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/crypto/openssh/openbsd-compat/port-solaris.c b/crypto/openssh/openbsd-compat/port-solaris.c index 25382f1..e36e412 100644 --- a/crypto/openssh/openbsd-compat/port-solaris.c +++ b/crypto/openssh/openbsd-compat/port-solaris.c @@ -227,3 +227,139 @@ solaris_set_default_project(struct passwd *pw) } } #endif /* USE_SOLARIS_PROJECTS */ + +#ifdef USE_SOLARIS_PRIVS +# ifdef HAVE_PRIV_H +# 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) +{ + priv_set_t *pset = NULL, *npset = NULL; + + /* + * Note: this variant avoids dropping DAC filesystem rights, in case + * the process calling it is running as root and should have the + * ability to read/write/chown any file on the system. + * + * We start with the basic set, then *add* the DAC rights to it while + * taking away other parts of BASIC we don't need. Then we intersect + * this with our existing PERMITTED set. In this way we keep any + * DAC rights we had before, while otherwise reducing ourselves to + * the minimum set of privileges we need to proceed. + * + * This also means we drop any other parts of "root" that we don't + * need (e.g. the ability to kill any process, create new device nodes + * etc etc). + */ + + if ((pset = priv_allocset()) == NULL) + fatal("priv_allocset: %s", strerror(errno)); + 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 || + priv_addset(npset, PRIV_FILE_DAC_SEARCH) != 0 || + priv_addset(npset, PRIV_FILE_DAC_WRITE) != 0 || + priv_addset(npset, PRIV_FILE_OWNER) != 0) + 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 || + priv_delset(npset, PRIV_PROC_SESSION) != 0) + fatal("priv_delset: %s", strerror(errno)); + + if (getppriv(PRIV_PERMITTED, pset) != 0) + fatal("getppriv: %s", strerror(errno)); + + priv_intersect(pset, npset); + + if (setppriv(PRIV_SET, PRIV_PERMITTED, npset) != 0 || + setppriv(PRIV_SET, PRIV_LIMIT, npset) != 0 || + setppriv(PRIV_SET, PRIV_INHERITABLE, npset) != 0) + fatal("setppriv: %s", strerror(errno)); + + priv_freeset(pset); + priv_freeset(npset); +} + +void +solaris_drop_privs_root_pinfo_net(void) +{ + priv_set_t *pset = NULL; + + /* Start with "basic" and drop everything we don't need. */ + 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)); + + if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 || + setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 || + setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0) + fatal("setppriv: %s", strerror(errno)); + + priv_freeset(pset); +} + +void +solaris_drop_privs_root_pinfo_net_exec(void) +{ + priv_set_t *pset = NULL; + + + /* Start with "basic" and drop everything we don't need. */ + 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) + fatal("priv_delset: %s", strerror(errno)); + + if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 || + setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 || + setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0) + fatal("setppriv: %s", strerror(errno)); + + priv_freeset(pset); +} + +#endif |