fixed Linux capabilities handling
authorAndrew Tridgell <tridge@samba.org>
Sun, 11 Jun 2000 06:24:54 +0000 (06:24 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sun, 11 Jun 2000 06:24:54 +0000 (06:24 +0000)
I used a trick where CAP_LEASE isn't claimed until it is needed. This
means we avoid a system call per setreuid(), and never call capset()
unless a user tries to get a oplock on a file that they don't own
(This used to be commit afa98d511f70f455d599c3a36dd25e49fe74ac09)

source3/include/includes.h
source3/smbd/oplock_linux.c

index a30a8448ad5dd35f955b58353c74930c64c96187..432fd09f0bc2becbfacc65b63a8e84cc083f130c 100644 (file)
@@ -868,18 +868,6 @@ int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
 #include <dlfcn.h>
 #endif
 
-#if HAVE_KERNEL_OPLOCKS_LINUX
-#ifndef F_SETLEASE
-#define F_SETLEASE     1024
-#endif
-#ifndef F_GETLEASE
-#define F_GETLEASE     1025
-#endif
-#ifndef CAP_LEASE
-#define CAP_LEASE 28
-#endif
-#endif
-
 extern int DEBUGLEVEL;
 
 #endif /* _INCLUDES_H */
index 73a14b3e88fe36687b38fbb0ecdb2123ea1d46ab..ae0a72d0f67a7d5eb295fd416a19058ba2f78e74 100644 (file)
@@ -31,18 +31,18 @@ static unsigned signals_received;
 static unsigned signals_processed;
 static int fd_pending; /* the fd of the current pending SIGIO */
 
-/* these can be removed when they are in libc */
-typedef struct __user_cap_header_struct {
-        uint32 version;
-        int pid;
-} *cap_user_header_t;
-typedef struct __user_cap_data_struct {
-        uint32 effective;
-        uint32 permitted;
-        uint32 inheritable;
-} *cap_user_data_t;
 
+#ifndef F_SETLEASE
+#define F_SETLEASE     1024
+#endif
+
+#ifndef F_GETLEASE
+#define F_GETLEASE     1025
+#endif
+
+#ifndef CAP_LEASE
+#define CAP_LEASE 28
+#endif
 
 /****************************************************************************
 handle a SIGIO, incrementing the signals_received and blocking SIGIO
@@ -55,19 +55,37 @@ static void sigio_handler(int signal, siginfo_t *info, void *unused)
 }
 
 /****************************************************************************
-try to gain the CAP_LEASE capability
+try to gain a linux capability
 ****************************************************************************/
-static void set_lease_capability(void)
+static void set_capability(unsigned capability)
 {
-       cap_user_header_t header;
-       cap_user_data_t data;
-       if (capget(header, data) == -1) {
-               DEBUG(3,("Unable to get kernel capabilities\n"));
+#ifndef _LINUX_CAPABILITY_VERSION
+#define _LINUX_CAPABILITY_VERSION 0x19980330
+#endif
+       /* these can be removed when they are in glibc headers */
+       struct  {
+               uint32 version;
+               int pid;
+       } header;
+       struct {
+               uint32 effective;
+               uint32 permitted;
+               uint32 inheritable;
+       } data;
+
+       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;
        }
-       data->effective |= (1<<CAP_LEASE);
-       if (capset(header, data) == -1) {
-               DEBUG(3,("Unable to set CAP_LEASE capability\n"));
+
+       data.effective |= (1<<capability);
+
+       if (capset(&header, &data) == -1) {
+               DEBUG(3,("Unable to set %d capability (%s)\n", 
+                        capability, strerror(errno)));
        }
 }
 
@@ -81,7 +99,7 @@ static int linux_setlease(int fd, int leasetype)
        int ret;
        ret = fcntl(fd, F_SETLEASE, leasetype);
        if (ret == -1 && errno == EACCES) {
-               set_lease_capability();
+               set_capability(CAP_LEASE);
                ret = fcntl(fd, F_SETLEASE, leasetype);
        }