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

Reply via email to