[SCM] Samba Shared Repository - branch master updated

Christof Schmitt cs at samba.org
Wed Aug 14 17:48:02 UTC 2019


The branch, master has been updated
       via  ec05edcceed smbd: Make sys_disk_free static
       via  f77c6c8be6b selftest: Add test for quota query on directory with SGID
       via  bbb259e7acb vfs_fake_dfq: Add option to fake stat information
       via  72c4e33decb vfs_gpfs: Check group quota for directory when SGID is set
       via  02b7e6c79b8 quotas: Check group quota for directory when SGID is set
      from  9b7825d2d38 auth:ntlmssp: Use generate_random_buffer() for session keys

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit ec05edcceed96f4a17ce7e45c4554b0500946ce0
Author: Christof Schmitt <cs at samba.org>
Date:   Tue Aug 13 13:45:48 2019 -0700

    smbd: Make sys_disk_free static
    
    The function is only called from the same file.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Christof Schmitt <cs at samba.org>
    Autobuild-Date(master): Wed Aug 14 17:47:33 UTC 2019 on sn-devel-184

commit f77c6c8be6b19880fb46fb5524a39cea03ef7bd5
Author: Christof Schmitt <cs at samba.org>
Date:   Tue Aug 13 13:44:52 2019 -0700

    selftest: Add test for quota query on directory with SGID
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit bbb259e7acb2485232359191f9d799e4c87bcbae
Author: Christof Schmitt <cs at samba.org>
Date:   Tue Aug 13 13:37:22 2019 -0700

    vfs_fake_dfq: Add option to fake stat information
    
    Add an option to allow faking the gid and the SGID bit in the returned
    stat buffer. That will be used to verify quota queries on folders with
    SGID set.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 72c4e33decbaa19f9e7845240fdcf02029ded82c
Author: Christof Schmitt <cs at samba.org>
Date:   Wed Aug 7 10:42:26 2019 -0700

    vfs_gpfs: Check group quota for directory when SGID is set
    
    On directories with the "set group id" (SGID) bit is set, new files and
    subfolders will be created with the group of the directory, and not with
    the primary group of the user. Checking for free space in this case
    should query the group quota for the gid of the directory.
    
    This is the same change as the common smbd code, but since vfs_gpfs
    still has its own check for available space and quotas, add it here as
    well. A future goal would be to use the common free space check instead
    of duplicating code in vfs_gpfs.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 02b7e6c79b866ba0d339cad6c4fc9eb0d0be8968
Author: Christof Schmitt <cs at samba.org>
Date:   Tue Aug 13 13:40:48 2019 -0700

    quotas: Check group quota for directory when SGID is set
    
    On directories with the "set group id" (SGID) bit is set, new files and
    subfolders will be created with the group of the directory, and not with
    the primary group of the user. Checking for free space in this case
    should query the group quota for the gid of the directory.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/modules/vfs_fake_dfq.c           | 79 ++++++++++++++++++++++++++++++++
 source3/modules/vfs_gpfs.c               | 20 +++++++-
 source3/script/tests/test_dfree_quota.sh |  9 ++++
 source3/smbd/dfree.c                     |  7 ++-
 source3/smbd/proto.h                     |  2 -
 source3/smbd/quotas.c                    | 23 ++++++++--
 6 files changed, 130 insertions(+), 10 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/modules/vfs_fake_dfq.c b/source3/modules/vfs_fake_dfq.c
index 019b2e8891d..5347d7500af 100644
--- a/source3/modules/vfs_fake_dfq.c
+++ b/source3/modules/vfs_fake_dfq.c
@@ -187,11 +187,90 @@ out:
 	return rc;
 }
 
+static void dfq_fake_stat(struct vfs_handle_struct *handle,
+			  struct smb_filename *smb_fname,
+			  SMB_STRUCT_STAT *sbuf)
+{
+	int snum = SNUM(handle->conn);
+	char *full_path = NULL;
+	char *to_free = NULL;
+	char path[PATH_MAX + 1];
+	int len;
+	gid_t gid;
+
+	len = full_path_tos(handle->conn->cwd_fname->base_name,
+			    smb_fname->base_name,
+			    path, sizeof(path),
+			    &full_path, &to_free);
+	if (len == -1) {
+		DBG_ERR("Could not allocate memory in full_path_tos.\n");
+		return;
+	}
+
+	gid = dfq_load_param(snum, full_path, "stat", "sgid", 0);
+	if (gid != 0) {
+		sbuf->st_ex_gid = gid;
+		sbuf->st_ex_mode |= S_ISGID;
+	}
+
+	TALLOC_FREE(to_free);
+}
+
+static int dfq_stat(vfs_handle_struct *handle,
+		    struct smb_filename *smb_fname)
+{
+	int ret;
+
+	ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
+	if (ret == -1) {
+		return ret;
+	}
+
+	dfq_fake_stat(handle, smb_fname, &smb_fname->st);
+
+	return 0;
+}
+
+static int dfq_fstat(vfs_handle_struct *handle,
+		     files_struct *fsp,
+		     SMB_STRUCT_STAT *sbuf)
+{
+	int ret;
+
+	ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
+	if (ret == -1) {
+		return ret;
+	}
+
+	dfq_fake_stat(handle, fsp->fsp_name, sbuf);
+
+	return 0;
+}
+
+static int dfq_lstat(vfs_handle_struct *handle,
+		     struct smb_filename *smb_fname)
+{
+	int ret;
+
+	ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
+	if (ret == -1) {
+		return ret;
+	}
+
+	dfq_fake_stat(handle, smb_fname, &smb_fname->st);
+
+	return 0;
+}
+
 struct vfs_fn_pointers vfs_fake_dfq_fns = {
     /* Disk operations */
 
     .disk_free_fn = dfq_disk_free,
     .get_quota_fn = dfq_get_quota,
+
+    .stat_fn = dfq_stat,
+    .fstat_fn = dfq_fstat,
+    .lstat_fn = dfq_lstat,
 };
 
 static_decl_vfs;
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 6994aa09385..d8e9a3231bf 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -2306,8 +2306,24 @@ static uint64_t vfs_gpfs_disk_free(vfs_handle_struct *handle,
 					      bsize, dfree, dsize);
 	}
 
-	err = get_gpfs_quota(smb_fname->base_name,
-			GPFS_GRPQUOTA, utok->gid, &qi_group);
+	/*
+	 * If new files created under this folder get this folder's
+	 * GID, then available space is governed by the quota of the
+	 * folder's GID, not the primary group of the creating user.
+	 */
+	if (VALID_STAT(smb_fname->st) &&
+	    S_ISDIR(smb_fname->st.st_ex_mode) &&
+	    smb_fname->st.st_ex_mode & S_ISGID) {
+		become_root();
+		err = get_gpfs_quota(smb_fname->base_name, GPFS_GRPQUOTA,
+				     smb_fname->st.st_ex_gid, &qi_group);
+		unbecome_root();
+
+	} else {
+		err = get_gpfs_quota(smb_fname->base_name, GPFS_GRPQUOTA,
+				     utok->gid, &qi_group);
+	}
+
 	if (err) {
 		return SMB_VFS_NEXT_DISK_FREE(handle, smb_fname,
 					      bsize, dfree, dsize);
diff --git a/source3/script/tests/test_dfree_quota.sh b/source3/script/tests/test_dfree_quota.sh
index 444a6684942..cfba4a9173f 100755
--- a/source3/script/tests/test_dfree_quota.sh
+++ b/source3/script/tests/test_dfree_quota.sh
@@ -76,6 +76,9 @@ nfs:udflt:nosys = 1
 confdfqp:df:block size = 4096:disk free = 10:disk size = 80
 confdfqp:u$uid1:block size = 4096:hard limit = 40:soft limit = 40:cur blocks = 36
 confdfqp:u$uid2:block size = 4096:hard limit = 41:soft limit = 41:cur blocks = 36
+sgid:stat:sgid = 98765
+sgid:u$uid:block size = 4096:hard limit = 0:soft limit = 0:cur blocks = 80
+sgid:g98765:block size = 4096:hard limit = 50:soft limit = 50:cur blocks = 40
 ABC
 }
 
@@ -227,6 +230,12 @@ test_smbclient_dfree "Test quota->dfree inode hard limit" dfq "subdir1" "ihlimit
 test_smbclient_dfree "Test quota->dfree err try group" dfq "subdir1" "trygrp1 subdir1" "240 1024. 20" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
 test_smbclient_dfree "Test quota->dfree no-quota try group" dfq "subdir1" "trygrp2 subdir1" "240 1024. 16" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
 
+# sgid on directory
+test_smbclient_dfree "Test quota on sgid directory" dfq "subdir1" \
+		     "sgid subdir1" "200 1024. 40" -U$USERNAME%$PASSWORD \
+		     --option=clientmaxprotocol=SMB3 \
+	|| failed=`expr $failed + 1`
+
 #block size different in quota and df systems
 test_smbclient_dfree "Test quota->dfree different block size" dfq "subdir1" "blksize subdir1" "307200 1024. 307200" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
 
diff --git a/source3/smbd/dfree.c b/source3/smbd/dfree.c
index 5c6c0fb00ae..31900c847f1 100644
--- a/source3/smbd/dfree.c
+++ b/source3/smbd/dfree.c
@@ -51,8 +51,11 @@ static void disk_norm(uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
  Return number of 1K blocks available on a path and total number.
 ****************************************************************************/
 
-uint64_t sys_disk_free(connection_struct *conn, struct smb_filename *fname,
-		       uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
+static uint64_t sys_disk_free(connection_struct *conn,
+			      struct smb_filename *fname,
+			      uint64_t *bsize,
+			      uint64_t *dfree,
+			      uint64_t *dsize)
 {
 	uint64_t dfree_retval;
 	uint64_t dfree_q = 0;
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 5947d9ab6f2..ce49deafed3 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -171,8 +171,6 @@ bool connections_snum_used(struct smbd_server_connection *unused, int snum);
 
 /* The following definitions come from smbd/dfree.c  */
 
-uint64_t sys_disk_free(connection_struct *conn, struct smb_filename *fname,
-		       uint64_t *bsize, uint64_t *dfree, uint64_t *dsize);
 uint64_t get_dfree_info(connection_struct *conn, struct smb_filename *fname,
 			uint64_t *bsize, uint64_t *dfree, uint64_t *dsize);
 void flush_dfree_cache(void);
diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c
index c9472682f8f..604631f81d6 100644
--- a/source3/smbd/quotas.c
+++ b/source3/smbd/quotas.c
@@ -447,11 +447,26 @@ try_group_quota:
 		return false;
 	}
 
-	id.gid = getegid();
-
 	ZERO_STRUCT(D);
-	r = SMB_VFS_GET_QUOTA(conn, fname, SMB_GROUP_QUOTA_TYPE, id,
-			      &D);
+
+	/*
+	 * If new files created under this folder get this folder's
+	 * GID, then available space is governed by the quota of the
+	 * folder's GID, not the primary group of the creating user.
+	 */
+	if (VALID_STAT(fname->st) &&
+	    S_ISDIR(fname->st.st_ex_mode) &&
+	    fname->st.st_ex_mode & S_ISGID) {
+		id.gid = fname->st.st_ex_gid;
+		become_root();
+		r = SMB_VFS_GET_QUOTA(conn, fname, SMB_GROUP_QUOTA_TYPE, id,
+				      &D);
+		unbecome_root();
+	} else {
+		id.gid = getegid();
+		r = SMB_VFS_GET_QUOTA(conn, fname, SMB_GROUP_QUOTA_TYPE, id,
+				      &D);
+	}
 
 	if (r == -1) {
 		return False;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list