r14600: Refactor capability interface from being IRIX-specific to using only
authorJames Peach <jpeach@samba.org>
Tue, 21 Mar 2006 02:56:49 +0000 (02:56 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:15:39 +0000 (11:15 -0500)
the POSIX interface. Note that this removes support for inherited
capabilities. This wasn't used, and probably should not be.

source/configure.in
source/include/includes.h
source/include/smb.h
source/lib/smbrun.c
source/lib/system.c
source/smbd/chgpasswd.c
source/smbd/oplock_irix.c

index d6a5bbcd5a98b764c5341bdd5b43366bd5dbe7d7..f61ca178efbc741bc7e4647f5f6961cead085714 100644 (file)
@@ -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
 
 #
index 4bd84c877aac80b2fbac011095c9336940019b63..9f6f8b2471841e1b64183f01823c57c93f361b7c 100644 (file)
 #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.
index 59948edf40f741e7893fd2fe666ab0d894804559..26b4b69266fb1bef6c7b9e85b28126b39d1f793b 100644 (file)
@@ -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 */
index 4f5525039f5ab4d538d08678015941e840bb8f84..521b1bf761e211d1aeba86af813ccd857f82f2ff 100644 (file)
@@ -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)) {
index f38001cb7bdf4704bf4d27c5300ec0c9809f59e0..ffb7031715049ec540ad472e6f337dce7e5363e3 100644 (file)
@@ -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 */
 }
 
 /**************************************************************************
index 224ae3d763e08234b1dfad5c957b2c53a22d91b4..aef487f4a7628c94ea1ffa4951737984e6e073c6 100644 (file)
@@ -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);
index 8f0143874590473988412925d079d8235f4bddbb..83883444a7b8b70b6d0fff041db1d564d638f8e8 100644 (file)
@@ -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());