The branch, master has been updated
via a168389def8 lib: Remove [set|drop]_effective_capability and enum
smbd_capability
via 15ce51212bf lib: Replace calls to [set|drop]_effective_capability
via f7f3a6483af lib: Add capability-specific functions
via 2052e755ad3 lib: Remove LEASE_CAPABILITY
via d23997f55c3 lib: Remove KERNEL_OPLOCK_CAPABILITY
via 446853b8d01 lib: Remove explicitly dropping capabilities before exec
from d46d382fbc1 vfs_ceph_new: Improve log entries in
vfs_cephfs_load_lib()
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit a168389def8bf1931de525f9382e89cee749bd71
Author: Volker Lendecke <[email protected]>
Date: Fri Jan 9 10:26:29 2026 +0100
lib: Remove [set|drop]_effective_capability and enum smbd_capability
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Stefan Metzmacher <[email protected]>
Autobuild-User(master): Volker Lendecke <[email protected]>
Autobuild-Date(master): Mon Jan 12 10:39:38 UTC 2026 on atb-devel-224
commit 15ce51212bf237f81685f78002efd5df3b60e5e1
Author: Volker Lendecke <[email protected]>
Date: Fri Jan 9 10:24:32 2026 +0100
lib: Replace calls to [set|drop]_effective_capability
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Stefan Metzmacher <[email protected]>
commit f7f3a6483afbe57543d25b8c09eecdd7efd00f82
Author: Volker Lendecke <[email protected]>
Date: Fri Jan 9 10:15:25 2026 +0100
lib: Add capability-specific functions
This makes the one-attempt logic for dac_override simpler to
understand.
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Stefan Metzmacher <[email protected]>
commit 2052e755ad34ca9b4698c60c1b82f8e12408aa0a
Author: Volker Lendecke <[email protected]>
Date: Thu Jan 8 14:53:39 2026 +0100
lib: Remove LEASE_CAPABILITY
This was only used via vfs_gpfs, and that removed its use in 2020.
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Stefan Metzmacher <[email protected]>
commit d23997f55c343518ae4df98eb82faa5c4741df3d
Author: Volker Lendecke <[email protected]>
Date: Thu Jan 8 14:48:32 2026 +0100
lib: Remove KERNEL_OPLOCK_CAPABILITY
This was only used in the IRIX oplock code, which was removed in 2018.
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Stefan Metzmacher <[email protected]>
commit 446853b8d01ff63baf851a9864ae3f8af9ba1305
Author: Volker Lendecke <[email protected]>
Date: Fri Jan 9 12:01:13 2026 +0100
lib: Remove explicitly dropping capabilities before exec
These calls are not necessary: When setting capabilities, we always
remove them from the inheritable set, so they will inevitably be
removed at exec-time. Also, these groups of calls were never updated
for DAC_OVERRIDE, which would have posed a pretty severe problem.
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Stefan Metzmacher <[email protected]>
-----------------------------------------------------------------------
Summary of changes:
source3/include/proto.h | 4 +-
source3/include/smb.h | 11 --
source3/lib/smbrun.c | 12 --
source3/lib/system.c | 183 ++++++++++-----------------
source3/modules/nfs4_acls.c | 8 +-
source3/modules/vfs_gpfs.c | 12 +-
source3/rpc_server/samr/srv_samr_chgpasswd.c | 6 -
source3/smbd/dmapi.c | 4 +-
8 files changed, 84 insertions(+), 156 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 279fcee0c48..e13584c4d6c 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -193,8 +193,8 @@ DIR *sys_fdopendir(int fd);
int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev);
int sys_mknodat(int dirfd, const char *path, mode_t mode, SMB_DEV_T dev);
char *sys_getwd(void);
-void set_effective_capability(enum smbd_capability capability);
-void drop_effective_capability(enum smbd_capability capability);
+void set_dmapi_capability(bool enable);
+void set_dac_override_capability(bool enable);
long sys_random(void);
void sys_srandom(unsigned int seed);
int getgroups_max(void);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 88065e0e8eb..50e265f28b0 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -470,17 +470,6 @@ Offset Data length.
#define OPLOCKLEVEL_NONE 0
#define OPLOCKLEVEL_II 1
-/*
- * Capabilities abstracted for different systems.
- */
-
-enum smbd_capability {
- KERNEL_OPLOCK_CAPABILITY,
- DMAPI_ACCESS_CAPABILITY,
- LEASE_CAPABILITY,
- DAC_OVERRIDE_CAPABILITY
-};
-
struct kernel_oplocks_ops;
struct kernel_oplocks {
const struct kernel_oplocks_ops *ops;
diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c
index f9c6f8761c6..603ceb0acb5 100644
--- a/source3/lib/smbrun.c
+++ b/source3/lib/smbrun.c
@@ -76,12 +76,6 @@ static int smbrun_internal(const char *cmd, int *outfd, bool
sanitize,
gid_t gid = current_user.ut.gid;
void (*saved_handler)(int);
- /*
- * Lose any elevated privileges.
- */
- drop_effective_capability(KERNEL_OPLOCK_CAPABILITY);
- drop_effective_capability(DMAPI_ACCESS_CAPABILITY);
-
/* point our stdout at the file we want output to go into */
if (outfd && ((*outfd = setup_out_fd()) == -1)) {
@@ -242,12 +236,6 @@ int smbrunsecret(const char *cmd, const char *secret)
int ifd[2];
void (*saved_handler)(int);
- /*
- * Lose any elevated privileges.
- */
- drop_effective_capability(KERNEL_OPLOCK_CAPABILITY);
- drop_effective_capability(DMAPI_ACCESS_CAPABILITY);
-
/* build up an input pipe */
if(pipe(ifd)) {
return -1;
diff --git a/source3/lib/system.c b/source3/lib/system.c
index 706e080880e..e3dc53361ba 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -563,148 +563,105 @@ char *sys_getwd(void)
#if defined(HAVE_POSIX_CAPABILITIES)
-/**************************************************************************
- Try and abstract process capabilities (for systems that have them).
-****************************************************************************/
-
-/* 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)
+static bool set_one_cap(cap_value_t val, bool enable)
{
- /* "5" is the number of "num_cap_vals++" below */
- cap_value_t cap_vals[5] = {0};
- size_t num_cap_vals = 0;
-
cap_t cap;
-
-#if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
- /* On Linux, make sure that any capabilities we grab are sticky
- * across UID changes. We expect that this would allow us to keep both
- * the effective and permitted capability sets, but as of circa 2.6.16,
- * only the permitted set is kept. It is a bug (which we work around)
- * that the effective set is lost, but we still require the effective
- * set to be kept.
- */
- if (!prctl(PR_GET_KEEPCAPS)) {
- prctl(PR_SET_KEEPCAPS, 1);
- }
-#endif
+ cap_flag_value_t flag = enable ? CAP_SET : CAP_CLEAR;
+ int ret;
cap = cap_get_proc();
if (cap == NULL) {
- DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
- strerror(errno)));
- return False;
+ DBG_ERR("cap_get_proc failed: %s\n", strerror(errno));
+ return false;
}
- switch (capability) {
- /*
- * WARNING: If you add any #ifdef for a fresh
- * capability, bump up the array size in the
- * declaration of cap_vals[] above just to be
- * trivially safe to never overwrite cap_vals[].
- */
- 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;
- case DMAPI_ACCESS_CAPABILITY:
-#ifdef CAP_DEVICE_MGT
- /* IRIX has CAP_DEVICE_MGT for DMAPI access. */
- cap_vals[num_cap_vals++] = CAP_DEVICE_MGT;
-#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;
- case DAC_OVERRIDE_CAPABILITY:
-#ifdef CAP_DAC_OVERRIDE
- cap_vals[num_cap_vals++] = CAP_DAC_OVERRIDE;
-#endif
- }
-
- 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);
+ ret = cap_set_flag(cap, CAP_EFFECTIVE, 1, &val, flag);
+ SMB_ASSERT(ret == 0);
- /* We never want to pass capabilities down to our children, so make
- * sure they are not inherited.
+ /*
+ * We never want to pass capabilities down to our children, so
+ * make sure they are not inherited.
*/
- cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR);
+ ret = cap_set_flag(cap, CAP_INHERITABLE, 1, &val, CAP_CLEAR);
+ SMB_ASSERT(ret == 0);
+
+ ret = cap_set_proc(cap);
+ if (ret == -1) {
+ int err = errno;
- if (cap_set_proc(cap) == -1) {
- DBG_ERR("%s capability %d: cap_set_proc failed: %s\n",
+ DBG_ERR("%s capability %jd: cap_set_proc failed: %s\n",
enable ? "adding" : "dropping",
- capability, strerror(errno));
+ (intmax_t)val,
+ strerror(errno));
+
cap_free(cap);
- return False;
+ errno = err;
+ return false;
}
- DBG_INFO("%s capability %d\n",
- enable ? "added" : "dropped", capability);
+
+ DBG_INFO("%s capability %jd\n",
+ enable ? "added" : "dropped",
+ (intmax_t)val);
cap_free(cap);
- return True;
+ return true;
}
-#endif /* HAVE_POSIX_CAPABILITIES */
+#else /* HAVE_POSIX_CAPABILITIES */
-/****************************************************************************
- Gain the oplock capability from the kernel if possible.
-****************************************************************************/
+static bool set_one_cap(cap_value_t val, bool enable)
+{
+ return false;
+}
-#if defined(HAVE_POSIX_CAPABILITIES) && defined(CAP_DAC_OVERRIDE)
-static bool have_cap_dac_override = true;
-#else
-static bool have_cap_dac_override = false;
+#endif /* HAVE_POSIX_CAPABILITIES */
+
+void set_dmapi_capability(bool enable)
+{
+#ifdef CAP_MKNOD
+ /*
+ * Ignore result, we'll get EACCES/EPERM later
+ */
+ (void)set_one_cap(CAP_MKNOD, enable);
#endif
+ return;
+}
-void set_effective_capability(enum smbd_capability capability)
+void set_dac_override_capability(bool enable)
{
- bool ret = false;
+#ifndef CAP_DAC_OVERRIDE
- if (capability != DAC_OVERRIDE_CAPABILITY || have_cap_dac_override) {
-#if defined(HAVE_POSIX_CAPABILITIES)
- ret = set_process_capability(capability, True);
-#endif /* HAVE_POSIX_CAPABILITIES */
- }
+/*
+ * Use [un]become_root()
+ */
+#define have_cap_dac_override false
+#else
/*
- * Fallback to become_root() if CAP_DAC_OVERRIDE is not
- * available.
+ * Only try this once
*/
- if (capability == DAC_OVERRIDE_CAPABILITY) {
- if (!ret) {
- have_cap_dac_override = false;
- }
- if (!have_cap_dac_override) {
- become_root();
+ static bool have_cap_dac_override = true;
+ if (have_cap_dac_override) {
+ have_cap_dac_override = set_one_cap(CAP_DAC_OVERRIDE, enable);
+
+ if (!enable) {
+ /*
+ * Dropping caps again must always work.
+ */
+ SMB_ASSERT(have_cap_dac_override);
}
}
-}
+#endif
-void drop_effective_capability(enum smbd_capability capability)
-{
- if (capability != DAC_OVERRIDE_CAPABILITY || have_cap_dac_override) {
-#if defined(HAVE_POSIX_CAPABILITIES)
- set_process_capability(capability, False);
-#endif /* HAVE_POSIX_CAPABILITIES */
- } else {
- unbecome_root();
+ if (!have_cap_dac_override) {
+ /*
+ * Fallback if CAP_DAC_OVERRIDE is not available
+ */
+ if (enable) {
+ become_root();
+ } else {
+ unbecome_root();
+ }
}
}
diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c
index 8f99911df40..841be979f07 100644
--- a/source3/modules/nfs4_acls.c
+++ b/source3/modules/nfs4_acls.c
@@ -124,13 +124,13 @@ static int fstatat_with_cap_dac_override(int fd,
{
int ret;
- set_effective_capability(DAC_OVERRIDE_CAPABILITY);
+ set_dac_override_capability(true);
ret = sys_fstatat(fd,
pathname,
sbuf,
flags,
fake_dir_create_times);
- drop_effective_capability(DAC_OVERRIDE_CAPABILITY);
+ set_dac_override_capability(false);
return ret;
}
@@ -197,9 +197,9 @@ static int fstat_with_cap_dac_override(int fd,
SMB_STRUCT_STAT *sbuf,
{
int ret;
- set_effective_capability(DAC_OVERRIDE_CAPABILITY);
+ set_dac_override_capability(true);
ret = sys_fstat(fd, sbuf, fake_dir_create_times);
- drop_effective_capability(DAC_OVERRIDE_CAPABILITY);
+ set_dac_override_capability(false);
return ret;
}
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 3317d520e23..edd01ddabc4 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -422,12 +422,12 @@ static int gpfs_getacl_with_capability(struct
files_struct *fsp,
{
int ret, saved_errno;
- set_effective_capability(DAC_OVERRIDE_CAPABILITY);
+ set_dac_override_capability(true);
ret = gpfswrap_fgetacl(fsp_get_pathref_fd(fsp), flags, buf);
saved_errno = errno;
- drop_effective_capability(DAC_OVERRIDE_CAPABILITY);
+ set_dac_override_capability(false);
errno = saved_errno;
return ret;
@@ -1458,7 +1458,7 @@ static int vfs_gpfs_get_winattrs_helper(
* open a file implies FILE_LIST_DIRECTORY.
*/
- set_effective_capability(DAC_OVERRIDE_CAPABILITY);
+ set_dac_override_capability(true);
ret = gpfswrap_get_winattrs(
fsp_get_pathref_fd(fd),
@@ -1466,7 +1466,7 @@ static int vfs_gpfs_get_winattrs_helper(
saved_errno = errno;
- drop_effective_capability(DAC_OVERRIDE_CAPABILITY);
+ set_dac_override_capability(false);
errno = saved_errno;
}
@@ -1768,14 +1768,14 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct
vfs_handle_struct *handle,
* open a file implies FILE_LIST_DIRECTORY.
*/
- set_effective_capability(DAC_OVERRIDE_CAPABILITY);
+ set_dac_override_capability(true);
ret = gpfswrap_get_winattrs(fsp_get_pathref_fd(fsp), &attrs);
if (ret == -1) {
saved_errno = errno;
}
- drop_effective_capability(DAC_OVERRIDE_CAPABILITY);
+ set_dac_override_capability(false);
if (saved_errno != 0) {
errno = saved_errno;
diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c
b/source3/rpc_server/samr/srv_samr_chgpasswd.c
index 000f6c2b87d..41fe5bcc71e 100644
--- a/source3/rpc_server/samr/srv_samr_chgpasswd.c
+++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c
@@ -484,12 +484,6 @@ while we were waiting\n", WTERMSIG(wstat)));
} else {
/* CHILD */
- /*
- * Lose any elevated privileges.
- */
- drop_effective_capability(KERNEL_OPLOCK_CAPABILITY);
- drop_effective_capability(DMAPI_ACCESS_CAPABILITY);
-
/* make sure it doesn't freeze */
alarm(20);
diff --git a/source3/smbd/dmapi.c b/source3/smbd/dmapi.c
index 1943fe9f20b..08e8c691feb 100644
--- a/source3/smbd/dmapi.c
+++ b/source3/smbd/dmapi.c
@@ -147,7 +147,7 @@ static int dmapi_init_session(struct smbd_dmapi_context
*ctx)
}
if (ctx->session != DM_NO_SESSION) {
- set_effective_capability(DMAPI_ACCESS_CAPABILITY);
+ set_dmapi_capability(true);
}
/*
@@ -308,7 +308,7 @@ uint32_t dmapi_file_flags(const char * const path)
* can re-acquire them if necessary.
*/
- set_effective_capability(DMAPI_ACCESS_CAPABILITY);
+ set_dmapi_capability(true);
err = dm_path_to_handle(discard_const_p(char, path),
&dm_handle, &dm_handle_len);
--
Samba Shared Repository