diff options
-rw-r--r-- | source3/configure.in | 47 | ||||
-rw-r--r-- | source3/include/includes.h | 18 | ||||
-rw-r--r-- | source3/include/smb.h | 4 | ||||
-rw-r--r-- | source3/lib/smbrun.c | 4 | ||||
-rw-r--r-- | source3/lib/system.c | 122 | ||||
-rw-r--r-- | source3/smbd/chgpasswd.c | 2 | ||||
-rw-r--r-- | source3/smbd/oplock_irix.c | 2 |
7 files changed, 111 insertions, 88 deletions
diff --git a/source3/configure.in b/source3/configure.in index d6a5bbcd5a..f61ca178ef 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -822,7 +822,8 @@ esac AC_CHECK_HEADERS(shadow.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h) AC_CHECK_HEADERS(nss.h nss_common.h nsswitch.h ns_api.h sys/security.h security/pam_appl.h) AC_CHECK_HEADERS(stropts.h poll.h) -AC_CHECK_HEADERS(sys/capability.h syscall.h sys/syscall.h) +AC_CHECK_HEADERS(syscall.h sys/syscall.h) + AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/xattr.h sys/extattr.h sys/uio.h) AC_CHECK_HEADERS(sys/ea.h sys/proplist.h) @@ -2310,22 +2311,46 @@ if test x"$samba_cv_HAVE_KERNEL_OPLOCKS_IRIX" = x"yes"; then AC_DEFINE(HAVE_KERNEL_OPLOCKS_IRIX,1,[Whether IRIX kernel oplock type definitions are available]) fi -AC_CACHE_CHECK([for irix specific capabilities],samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES,[ -AC_TRY_RUN([#include <sys/types.h> +################################################# +# Check for POSIX capability support + +AC_CHECK_HEADER(sys/capability.h, [samba_cv_HAVE_SYS_CAPABILITY_H=yes; + AC_DEFINE(HAVE_SYS_CAPABILITY_H, 1, Whether sys/capability.h is present)], + [], []) + +if test x"$samba_cv_HAVE_SYS_CAPABILITY_H" = x"yes"; then + + ac_save_LIBS=$LIBS + AC_LIBTESTFUNC(cap, cap_get_proc) + + AC_CACHE_CHECK([for POSIX capabilities], + samba_cv_HAVE_POSIX_CAPABILITIES, + [ + AC_TRY_RUN([ +#include <sys/types.h> #include <sys/capability.h> main() { cap_t cap; - if ((cap = cap_get_proc()) == NULL) + cap_value_t vals[1]; + if (!(cap = cap_get_proc())) exit(1); - cap->cap_effective |= CAP_NETWORK_MGT; - cap->cap_inheritable |= CAP_NETWORK_MGT; + vals[0] = CAP_CHOWN; + cap_set_flag(cap, CAP_INHERITABLE, 1, vals, CAP_CLEAR); cap_set_proc(cap); exit(0); -} -], -samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=yes,samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=no,samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=cross)]) -if test x"$samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES" = x"yes"; then - AC_DEFINE(HAVE_IRIX_SPECIFIC_CAPABILITIES,1,[Whether IRIX specific capabilities are available]) +}], + samba_cv_HAVE_POSIX_CAPABILITIES=yes, + samba_cv_HAVE_POSIX_CAPABILITIES=no, + samba_cv_HAVE_POSIX_CAPABILITIES=cross) + ]) + +if test x"$samba_cv_HAVE_POSIX_CAPABILITIES" = x"yes"; then + AC_DEFINE(HAVE_POSIX_CAPABILITIES, 1, + [Whether POSIX capabilities are available]) +else + LIBS=$ac_save_LIBS +fi + fi # diff --git a/source3/include/includes.h b/source3/include/includes.h index 4bd84c877a..9f6f8b2471 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -362,24 +362,6 @@ #include <execinfo.h> #endif -#ifdef HAVE_SYS_CAPABILITY_H - -#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H) -#define _I386_STATFS_H -#define _PPC_STATFS_H -#define BROKEN_REDHAT_7_STATFS_WORKAROUND -#endif - -#include <sys/capability.h> - -#ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND -#undef _I386_STATFS_H -#undef _PPC_STATFS_H -#undef BROKEN_REDHAT_7_STATFS_WORKAROUND -#endif - -#endif - #if defined(HAVE_RPC_RPC_H) /* * Check for AUTH_ERROR define conflict with rpc/rpc.h in prot.h. diff --git a/source3/include/smb.h b/source3/include/smb.h index 59948edf40..26b4b69266 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1566,7 +1566,9 @@ minimum length == 18. * Capabilities abstracted for different systems. */ -#define KERNEL_OPLOCK_CAPABILITY 0x1 +enum smbd_capability { + KERNEL_OPLOCK_CAPABILITY +}; /* if a kernel does support oplocks then a structure of the following typee is used to describe how to interact with the kernel */ diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c index 4f5525039f..521b1bf761 100644 --- a/source3/lib/smbrun.c +++ b/source3/lib/smbrun.c @@ -64,7 +64,7 @@ int smbrun(const char *cmd, int *outfd) /* * Lose any kernel oplock capabilities we may have. */ - oplock_set_capability(False, False); + drop_effective_capability(KERNEL_OPLOCK_CAPABILITY); /* point our stdout at the file we want output to go into */ @@ -196,7 +196,7 @@ int smbrunsecret(const char *cmd, const char *secret) /* * Lose any kernel oplock capabilities we may have. */ - oplock_set_capability(False, False); + drop_effective_capability(KERNEL_OPLOCK_CAPABILITY); /* build up an input pipe */ if(pipe(ifd)) { diff --git a/source3/lib/system.c b/source3/lib/system.c index f38001cb7b..ffb7031715 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -624,85 +624,99 @@ struct hostent *sys_gethostbyname(const char *name) } -#if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES) -/************************************************************************** - Try and abstract process capabilities (for systems that have them). -****************************************************************************/ -static BOOL set_process_capability( uint32 cap_flag, BOOL enable ) -{ - if(cap_flag == KERNEL_OPLOCK_CAPABILITY) { - cap_t cap = cap_get_proc(); +#if defined(HAVE_POSIX_CAPABILITIES) - if (cap == NULL) { - DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n", - strerror(errno))); - return False; - } +#ifdef HAVE_SYS_CAPABILITY_H - if(enable) - cap->cap_effective |= CAP_NETWORK_MGT; - else - cap->cap_effective &= ~CAP_NETWORK_MGT; +#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H) +#define _I386_STATFS_H +#define _PPC_STATFS_H +#define BROKEN_REDHAT_7_STATFS_WORKAROUND +#endif - if (cap_set_proc(cap) == -1) { - DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n", - strerror(errno))); - cap_free(cap); - return False; - } +#include <sys/capability.h> - cap_free(cap); +#ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND +#undef _I386_STATFS_H +#undef _PPC_STATFS_H +#undef BROKEN_REDHAT_7_STATFS_WORKAROUND +#endif - DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n")); - } - return True; -} +#endif /* HAVE_SYS_CAPABILITY_H */ /************************************************************************** - Try and abstract inherited process capabilities (for systems that have them). + Try and abstract process capabilities (for systems that have them). ****************************************************************************/ -static BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable ) +/* Set the POSIX capabilities needed for the given purpose into the effective + * capability set of the current process. Make sure they are always removed + * from the inheritable set, because there is no circumstance in which our + * children should inherit our elevated privileges. + */ +static BOOL set_process_capability(enum smbd_capability capability, + BOOL enable) { - if(cap_flag == KERNEL_OPLOCK_CAPABILITY) { - cap_t cap = cap_get_proc(); + cap_value_t cap_vals[2] = {0}; + int num_cap_vals = 0; - if (cap == NULL) { - DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n", - strerror(errno))); - return False; - } + cap_t cap; - if(enable) - cap->cap_inheritable |= CAP_NETWORK_MGT; - else - cap->cap_inheritable &= ~CAP_NETWORK_MGT; + cap = cap_get_proc(); + if (cap == NULL) { + DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n", + strerror(errno))); + return False; + } - if (cap_set_proc(cap) == -1) { - DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n", - strerror(errno))); - cap_free(cap); - return False; - } + switch (capability) { + case KERNEL_OPLOCK_CAPABILITY: +#ifdef CAP_NETWORK_MGT + /* IRIX has CAP_NETWORK_MGT for oplocks. */ + cap_vals[num_cap_vals++] = CAP_NETWORK_MGT; +#endif + break; + } + + SMB_ASSERT(num_cap_vals <= ARRAY_SIZE(cap_vals)); + if (num_cap_vals == 0) { cap_free(cap); + return True; + } + + cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals, + enable ? CAP_SET : CAP_CLEAR); + cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR); - DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n")); + if (cap_set_proc(cap) == -1) { + DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n", + strerror(errno))); + cap_free(cap); + return False; } + + cap_free(cap); return True; } -#endif + +#endif /* HAVE_POSIX_CAPABILITIES */ /**************************************************************************** Gain the oplock capability from the kernel if possible. ****************************************************************************/ -void oplock_set_capability(BOOL this_process, BOOL inherit) +void set_effective_capability(enum smbd_capability capability) { -#if HAVE_KERNEL_OPLOCKS_IRIX - set_process_capability(KERNEL_OPLOCK_CAPABILITY,this_process); - set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,inherit); -#endif +#if defined(HAVE_POSIX_CAPABILITIES) + set_process_capability(capability, True); +#endif /* HAVE_POSIX_CAPABILITIES */ +} + +void drop_effective_capability(enum smbd_capability capability) +{ +#if defined(HAVE_POSIX_CAPABILITIES) + set_process_capability(capability, False); +#endif /* HAVE_POSIX_CAPABILITIES */ } /************************************************************************** diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 224ae3d763..aef487f4a7 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -417,7 +417,7 @@ while we were waiting\n", WTERMSIG(wstat))); /* * Lose any oplock capabilities. */ - oplock_set_capability(False, False); + drop_effective_capability(KERNEL_OPLOCK_CAPABILITY); /* make sure it doesn't freeze */ alarm(20); diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c index 8f01438745..83883444a7 100644 --- a/source3/smbd/oplock_irix.c +++ b/source3/smbd/oplock_irix.c @@ -35,7 +35,7 @@ static BOOL irix_oplocks_available(void) int pfd[2]; pstring tmpname; - oplock_set_capability(True, False); + set_effective_capability(KERNEL_OPLOCK_CAPABILITY); slprintf(tmpname,sizeof(tmpname)-1, "%s/koplock.%d", lp_lockdir(), (int)sys_getpid()); |