1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-23 09:57:40 +03:00

fixed Linux capabilities handling

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)
This commit is contained in:
Andrew Tridgell 2000-06-11 06:24:54 +00:00
parent 8843a6379d
commit 0fb1dbe7fa
2 changed files with 39 additions and 33 deletions

View 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 */

View 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);
}