Fix Bug #5285. (libcap header mismatch)
authorGünther Deschner <gd@samba.org>
Wed, 28 May 2008 11:20:16 +0000 (13:20 +0200)
committerGünther Deschner <gd@samba.org>
Wed, 28 May 2008 11:22:52 +0000 (13:22 +0200)
Can someone with gpfs available test this ? The only codepath using this
function is the modules/gpfs.c module. The fix resolves at least the build
issues Samba has with recent kernel / libcap versions by using the portable
cap_get_proc()/cap_set_proc() interface (instead of using capget/capset).

Guenther
(This used to be commit 177955141247a4eb56ba0d82dc1add7f52175c40)

source3/include/smb.h
source3/lib/system.c
source3/smbd/oplock_linux.c

index e7860b7903822cd46c2504ce450865d68f8ca48c..76cc389a1085acf378b8c49f71a523b8ba4f3f53 100644 (file)
@@ -1709,7 +1709,8 @@ minimum length == 18.
 
 enum smbd_capability {
     KERNEL_OPLOCK_CAPABILITY,
-    DMAPI_ACCESS_CAPABILITY
+    DMAPI_ACCESS_CAPABILITY,
+    LEASE_CAPABILITY
 };
 
 /* if a kernel does support oplocks then a structure of the following
index fa50955ef64cedee89a0d247fd78d74736617e74..eabb6d6dc48dbca7b1dc7fb9b4ea4b5cec934b2c 100644 (file)
@@ -731,6 +731,11 @@ static bool set_process_capability(enum smbd_capability capability,
 #elif CAP_MKNOD
                        /* Linux has CAP_MKNOD for DMAPI access. */
                        cap_vals[num_cap_vals++] = CAP_MKNOD;
+#endif
+                       break;
+               case LEASE_CAPABILITY:
+#ifdef CAP_LEASE
+                       cap_vals[num_cap_vals++] = CAP_LEASE;
 #endif
                        break;
        }
index fa7cb42bc6d9ca4bcb17e617ad0a35ef01fa755e..08df228f8fd6d4c604591d400aa7235ba848e142 100644 (file)
 
 #if HAVE_KERNEL_OPLOCKS_LINUX
 
-/* these can be removed when they are in glibc headers */
-struct  cap_user_header {
-       uint32 version;
-       int pid;
-} header;
-struct cap_user_data {
-       uint32 effective;
-       uint32 permitted;
-       uint32 inheritable;
-} data;
-
-extern int capget(struct cap_user_header * hdrp,
-                 struct cap_user_data * datap);
-extern int capset(struct cap_user_header * hdrp,
-                 const struct cap_user_data * datap);
-
 static SIG_ATOMIC_T signals_received;
 #define FD_PENDING_SIZE 100
 static SIG_ATOMIC_T fd_pending_array[FD_PENDING_SIZE];
@@ -75,40 +59,12 @@ static void signal_handler(int sig, siginfo_t *info, void *unused)
        sys_select_signal(RT_SIGNAL_LEASE);
 }
 
-/****************************************************************************
- Try to gain a linux capability.
-****************************************************************************/
-
-static void set_capability(unsigned capability)
-{
-#ifndef _LINUX_CAPABILITY_VERSION
-#define _LINUX_CAPABILITY_VERSION 0x19980330
-#endif
-       header.version = _LINUX_CAPABILITY_VERSION;
-       header.pid = 0;
-
-       if (capget(&header, &data) == -1) {
-               DEBUG(3,("Unable to get kernel capabilities (%s)\n",
-                        strerror(errno)));
-               return;
-       }
-
-       if (0 == (data.effective & (1<<capability))) {
-               data.effective |= (1<<capability);
-
-               if (capset(&header, &data) == -1) {
-                       DEBUG(3,("Unable to set %d capability (%s)\n", 
-                                capability, strerror(errno)));
-               }
-       }
-}
-
 /*
  * public function to get linux lease capability. Needed by some VFS modules (eg. gpfs.c)
  */
 void linux_set_lease_capability(void)
 {
-       set_capability(CAP_LEASE);
+       set_effective_capability(LEASE_CAPABILITY);
 }
 
 /* 
@@ -136,7 +92,7 @@ int linux_setlease(int fd, int leasetype)
 
        ret = fcntl(fd, F_SETLEASE, leasetype);
        if (ret == -1 && errno == EACCES) {
-               set_capability(CAP_LEASE);
+               set_effective_capability(LEASE_CAPABILITY);
                ret = fcntl(fd, F_SETLEASE, leasetype);
        }