summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/configure.in47
-rw-r--r--source3/include/includes.h18
-rw-r--r--source3/include/smb.h4
-rw-r--r--source3/lib/smbrun.c4
-rw-r--r--source3/lib/system.c122
-rw-r--r--source3/smbd/chgpasswd.c2
-rw-r--r--source3/smbd/oplock_irix.c2
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());