[PATCHESv2] Add vfs_admin vfs module
Uri Simchoni
uri at samba.org
Sun Oct 4 18:39:50 UTC 2015
This time with correct patch set. Sorry for the mess..
Uri.
On 10/04/2015 09:28 PM, Uri Simchoni wrote:
> Oops... something got messed up with this patch, resending shortly.
>
> On 10/04/2015 09:22 PM, Uri Simchoni wrote:
>> Hi,
>>
>> This patch set adds vfs_admin, a simple vfs module that fixes file
>> ownership for admin users.
>> When a user is defined as an admin user, smbd runs as root, and files
>> created by this user are
>> owned by root. This patch fixes that by adding a vfs module to change
>> the ownership of created objects.
>>
>> One thing worth noting is that for file creation I chose to override
>> the NT-layer create_file function rather than the POSIX layer open,
>> which would be more natural since this is a POSIX issue, created when
>> running POSIX open() system call or something with similar semantics.
>>
>> The reason for that is that when open returns, the fsp is still not
>> initialized with the just-created file descriptor, and so I cannot
>> use SMB_VFS_FCHOWN from within the open handler, and have to resort
>> to fchown() (supporting only kernel file systems) or SMB_VFS_CHOWN
>> (racy), or hack the fsp (...). The downside of it is having to deal
>> with things that don't necessarily translate to POSIX file creation
>> (streams, mkdir) and I hope I got that right. I have an alternative
>> implementation that overrides the POSIX open instead, with
>> above-mentioned limitations.
>>
>> Review appreciated.
>>
>> Thanks,
>> Uri
>
>
-------------- next part --------------
From 3973b00e592b84540a413c61c4306d739c93f25f Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Thu, 1 Oct 2015 22:53:32 +0300
Subject: [PATCH 1/2] VFS: add vfs_admin
vfs_admin is a VFS module that fixes file owner if the user is
an admin user. For admin users (users matching the per-share
"admin users" conf item), smbd runs as root, and files
created by those users are owned by root instead of by the
user.
Signed-off-by: Uri Simchoni <uri at samba.org>
---
source3/modules/vfs_admin.c | 194 ++++++++++++++++++++++++++++++++++++++++++
source3/modules/wscript_build | 8 ++
source3/wscript | 2 +-
3 files changed, 203 insertions(+), 1 deletion(-)
create mode 100644 source3/modules/vfs_admin.c
diff --git a/source3/modules/vfs_admin.c b/source3/modules/vfs_admin.c
new file mode 100644
index 0000000..ea8ad17
--- /dev/null
+++ b/source3/modules/vfs_admin.c
@@ -0,0 +1,194 @@
+/*
+ * admin VFS module. Fixes file ownership for files created by
+ * an admin user in the share.
+ *
+ * Copyright (C) Uri Simchoni, 2015
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "../source3/include/includes.h"
+#include "smbd/smbd.h"
+#include "smbd/globals.h"
+#include "auth.h"
+
+struct admin_data {
+ uid_t orig_uid;
+};
+
+static bool is_admin(vfs_handle_struct *handle)
+{
+ return handle->conn->session_info->unix_token->uid == sec_initial_uid();
+}
+
+static void chown_object(vfs_handle_struct *handle, const char *path)
+{
+ int rc;
+ struct admin_data *ctx;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, ctx, struct admin_data, return );
+
+ rc = SMB_VFS_LCHOWN(handle->conn, path, ctx->orig_uid, -1);
+ DBG_DEBUG("Chowning '%s' to %u .. %s\n", path, ctx->orig_uid,
+ rc == 0 ? "OK" : strerror(errno));
+}
+
+static int admin_connect(vfs_handle_struct *handle, const char *service,
+ const char *user)
+{
+ int rc;
+ struct admin_data *ctx;
+ struct user_struct *vuser;
+
+ rc = SMB_VFS_NEXT_CONNECT(handle, service, user);
+ if (rc < 0) {
+ return rc;
+ }
+
+ ctx = talloc_zero(handle->conn, struct admin_data);
+ if (!ctx) {
+ DBG_ERR("talloc_zero() failed\n");
+ errno = ENOMEM;
+ return -1;
+ }
+
+ vuser = get_valid_user_struct(handle->conn->sconn, handle->conn->vuid);
+ if (vuser == NULL) {
+ DBG_ERR("No user found for vuid %llu\n",
+ (unsigned long long)handle->conn->vuid);
+ errno = EIO;
+ return -1;
+ }
+
+ ctx->orig_uid = vuser->session_info->unix_token->uid;
+
+ SMB_VFS_HANDLE_SET_DATA(handle, ctx, NULL, struct admin_data,
+ return -1);
+ return 0;
+}
+
+static int admin_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
+{
+ int rc = SMB_VFS_NEXT_MKDIR(handle, path, mode);
+ if (is_admin(handle) && rc == 0) {
+ chown_object(handle, path);
+ }
+ return rc;
+}
+
+static NTSTATUS
+admin_create_file(struct vfs_handle_struct *handle, struct smb_request *req,
+ uint16_t root_dir_fid, struct smb_filename *smb_fname,
+ uint32_t access_mask, uint32_t share_access,
+ uint32_t create_disposition, uint32_t create_options,
+ uint32_t file_attributes, uint32_t oplock_request,
+ struct smb2_lease *lease, uint64_t allocation_size,
+ uint32_t private_flags, struct security_descriptor *sd,
+ struct ea_list *ea_list, files_struct **result, int *pinfo,
+ const struct smb2_create_blobs *in_context_blobs,
+ struct smb2_create_blobs *out_context_blobs)
+{
+ NTSTATUS status;
+ int info, rc;
+ struct admin_data *ctx;
+
+ status = SMB_VFS_NEXT_CREATE_FILE(
+ handle, req, root_dir_fid, smb_fname, access_mask, share_access,
+ create_disposition, create_options, file_attributes, oplock_request,
+ lease, allocation_size, private_flags, sd, ea_list, result, &info,
+ in_context_blobs, out_context_blobs);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (pinfo) {
+ *pinfo = info;
+ }
+
+ DBG_DEBUG("checking whether to fix owner of %s\n",
+ smb_fname_str_dbg(smb_fname));
+
+ if (!is_admin(handle)) {
+ DBG_DEBUG("not admin\n");
+ return status;
+ }
+
+ if (info != FILE_WAS_CREATED) {
+ DBG_DEBUG("not new - keep old owner\n");
+ return status;
+ }
+
+ if ((*result)->is_directory) {
+ DBG_DEBUG("directory - handled by mkdir\n");
+ return status;
+ }
+
+ if ((*result)->fh->fd == -1) {
+ DBG_DEBUG("no FD (a stream?)\n");
+ return status;
+ }
+
+ SMB_VFS_HANDLE_GET_DATA(handle, ctx, struct admin_data, return status);
+
+ rc = SMB_VFS_FCHOWN(*result, ctx->orig_uid, -1);
+ DBG_DEBUG("Chowning '%s' to %u .. %s\n", smb_fname_str_dbg(smb_fname),
+ ctx->orig_uid, rc == 0 ? "OK" : strerror(errno));
+
+ return status;
+}
+
+static int admin_symlink(vfs_handle_struct *handle, const char *oldpath,
+ const char *newpath)
+{
+ int rc = SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+ if (is_admin(handle) && rc == 0) {
+ chown_object(handle, newpath);
+ }
+ return rc;
+}
+
+static int admin_mknod(vfs_handle_struct *handle, const char *path, mode_t mode,
+ SMB_DEV_T dev)
+{
+ int rc = SMB_VFS_NEXT_MKNOD(handle, path, mode, dev);
+ if (is_admin(handle) && rc == 0) {
+ chown_object(handle, path);
+ }
+ return rc;
+}
+
+/* VFS operations structure */
+
+struct vfs_fn_pointers admin_fns = {
+ /* Disk operations */
+
+ .connect_fn = admin_connect,
+
+ /* Directory operations */
+
+ .mkdir_fn = admin_mkdir,
+
+ /* File operations */
+
+ /* .open_fn = admin_open, */
+ .create_file_fn = admin_create_file,
+ .symlink_fn = admin_symlink,
+ .mknod_fn = admin_mknod,
+};
+
+static_decl_vfs;
+NTSTATUS vfs_admin_init(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "admin", &admin_fns);
+}
diff --git a/source3/modules/wscript_build b/source3/modules/wscript_build
index fef412a..ccd9181 100644
--- a/source3/modules/wscript_build
+++ b/source3/modules/wscript_build
@@ -499,3 +499,11 @@ bld.SAMBA3_MODULE('vfs_vxfs',
init_function='',
internal_module=bld.SAMBA3_IS_STATIC_MODULE('vfs_vxfs'),
enabled=bld.SAMBA3_IS_ENABLED_MODULE('vfs_vxfs'))
+
+bld.SAMBA3_MODULE('vfs_admin',
+ subsystem='vfs',
+ source='vfs_admin.c',
+ deps='samba-util',
+ init_function='',
+ internal_module=bld.SAMBA3_IS_STATIC_MODULE('vfs_admin'),
+ enabled=bld.SAMBA3_IS_ENABLED_MODULE('vfs_admin'))
diff --git a/source3/wscript b/source3/wscript
index 9ff9c20..64c0b04 100644
--- a/source3/wscript
+++ b/source3/wscript
@@ -1610,7 +1610,7 @@ main() {
vfs_smb_traffic_analyzer vfs_preopen vfs_catia
vfs_media_harmony vfs_unityed_media vfs_fruit vfs_shell_snap
vfs_commit vfs_worm vfs_crossrename vfs_linux_xfs_sgid
- vfs_time_audit
+ vfs_time_audit vfs_admin
'''))
default_shared_modules.extend(TO_LIST('auth_script idmap_tdb2 idmap_script'))
# these have broken dependencies
--
1.9.1
From 4d7480c87658e371d09d3e9e6bd0cdb0e1f57262 Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Sun, 4 Oct 2015 21:32:24 +0300
Subject: [PATCH 2/2] vfs_admin: add documentation
Signed-off-by: Uri Simchoni <uri at samba.org>
---
docs-xml/manpages/vfs_admin.8.xml | 84 +++++++++++++++++++++++++++++++++++++++
docs-xml/wscript_build | 1 +
2 files changed, 85 insertions(+)
create mode 100644 docs-xml/manpages/vfs_admin.8.xml
diff --git a/docs-xml/manpages/vfs_admin.8.xml b/docs-xml/manpages/vfs_admin.8.xml
new file mode 100644
index 0000000..8a50fc4
--- /dev/null
+++ b/docs-xml/manpages/vfs_admin.8.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
+<refentry id="vfs_admin.8">
+
+<refmeta>
+ <refentrytitle>vfs_admin</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="source">Samba</refmiscinfo>
+ <refmiscinfo class="manual">System Administration tools</refmiscinfo>
+ <refmiscinfo class="version">4.3</refmiscinfo>
+</refmeta>
+
+
+<refnamediv>
+ <refname>vfs_admin</refname>
+ <refpurpose>Fix file and directory ownership for admin users</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>vfs objects = admin</command>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This VFS module is part of the
+ <citerefentry><refentrytitle>samba</refentrytitle>
+ <manvolnum>7</manvolnum></citerefentry> suite.</para>
+
+ <para>This VFS module fixes file ownership for admin users.
+ </para>
+
+ <para><citerefentry><refentrytitle>smbd</refentrytitle>
+ <manvolnum>8</manvolnum></citerefentry> supports the concept of
+ "admin users" - users who are
+ granted administrative privileges on the share.
+ When serving an admin user, smbd runs as root rather than the as
+ the user. A consequence is that files created by this user
+ are owned by "root". vfs_admin module fixes this issue by changing
+ owner of the created object (be it a file, a directory, or a special
+ UNIX file) to the UID of the admin user.
+ </para>
+
+ <para>This module is stackable, and uses the VFS to do the actual
+ changing of ownership (i.e. it supports both user-space and kernel
+ file systems). By its purpose and nature it does assume the
+ underlying file system has POSIX semantics.</para>
+
+</refsect1>
+
+
+<refsect1>
+ <title>EXAMPLES</title>
+
+ <para>Use vfs_admin to fix file ownership in a share:</para>
+
+<programlisting>
+ <smbconfsection name="[share]"/>
+ <smbconfoption name="admin users">"SAMDOM\domain admins"</smbconfoption>
+ <smbconfoption name="vfs objects">admin</smbconfoption>
+</programlisting>
+
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 4.4.0 of the Samba suite.
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+</refsect1>
+
+</refentry>
diff --git a/docs-xml/wscript_build b/docs-xml/wscript_build
index 568eba1..1ebd700 100644
--- a/docs-xml/wscript_build
+++ b/docs-xml/wscript_build
@@ -86,6 +86,7 @@ manpages='''
manpages/vfs_unityed_media.8
manpages/vfs_worm.8
manpages/vfs_xattr_tdb.8
+ manpages/vfs_admin.8
manpages/vfstest.1
manpages/wbinfo.1
manpages/winbindd.8
--
1.9.1
More information about the samba-technical
mailing list