diff options
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/debug.c | 1 | ||||
-rw-r--r-- | source3/lib/smbrun.c | 6 | ||||
-rw-r--r-- | source3/lib/system.c | 30 |
3 files changed, 35 insertions, 2 deletions
diff --git a/source3/lib/debug.c b/source3/lib/debug.c index 29d879adbc..97a147f17d 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -166,6 +166,7 @@ static const char *default_classname_table[] = { "acls", /* DBGC_ACLS */ "locking", /* DBGC_LOCKING */ "msdfs", /* DBGC_MSDFS */ + "dmapi", /* DBGC_DMAPI */ NULL }; diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c index 521b1bf761..4400aeb443 100644 --- a/source3/lib/smbrun.c +++ b/source3/lib/smbrun.c @@ -62,9 +62,10 @@ int smbrun(const char *cmd, int *outfd) gid_t gid = current_user.ut.gid; /* - * Lose any kernel oplock capabilities we may have. + * Lose any elevated privileges. */ drop_effective_capability(KERNEL_OPLOCK_CAPABILITY); + drop_effective_capability(DMAPI_ACCESS_CAPABILITY); /* point our stdout at the file we want output to go into */ @@ -194,9 +195,10 @@ int smbrunsecret(const char *cmd, const char *secret) int ifd[2]; /* - * Lose any kernel oplock capabilities we may have. + * Lose any elevated privileges. */ drop_effective_capability(KERNEL_OPLOCK_CAPABILITY); + drop_effective_capability(DMAPI_ACCESS_CAPABILITY); /* build up an input pipe */ if(pipe(ifd)) { diff --git a/source3/lib/system.c b/source3/lib/system.c index ffb7031715..2e5f42307b 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -22,6 +22,10 @@ #include "includes.h" +#ifdef HAVE_SYS_PRCTL_H +#include <sys/prctl.h> +#endif + /* The idea is that this file will eventually have wrappers around all important system calls in samba. The aims are: @@ -661,6 +665,19 @@ static BOOL set_process_capability(enum smbd_capability capability, cap_t cap; +#if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS) + /* On Linux, make sure that any capabilities we grab are sticky + * across UID changes. We expect that this would allow us to keep both + * the effective and permitted capability sets, but as of circa 2.6.16, + * only the permitted set is kept. It is a bug (which we work around) + * that the effective set is lost, but we still require the effective + * set to be kept. + */ + if (!prctl(PR_GET_KEEPCAPS)) { + prctl(PR_SET_KEEPCAPS, 1); + } +#endif + cap = cap_get_proc(); if (cap == NULL) { DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n", @@ -675,6 +692,15 @@ static BOOL set_process_capability(enum smbd_capability capability, cap_vals[num_cap_vals++] = CAP_NETWORK_MGT; #endif break; + case DMAPI_ACCESS_CAPABILITY: +#ifdef CAP_DEVICE_MGT + /* IRIX has CAP_DEVICE_MGT for DMAPI access. */ + cap_vals[num_cap_vals++] = CAP_DEVICE_MGT; +#elif CAP_MKNOD + /* Linux has CAP_MKNOD for DMAPI access. */ + cap_vals[num_cap_vals++] = CAP_MKNOD; +#endif + break; } SMB_ASSERT(num_cap_vals <= ARRAY_SIZE(cap_vals)); @@ -686,6 +712,10 @@ static BOOL set_process_capability(enum smbd_capability capability, cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals, enable ? CAP_SET : CAP_CLEAR); + + /* We never want to pass capabilities down to our children, so make + * sure they are not inherited. + */ cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR); if (cap_set_proc(cap) == -1) { |