[SCM] Samba Shared Repository - branch v4-11-test updated

Stefan Metzmacher metze at samba.org
Tue Sep 10 22:30:02 UTC 2019


The branch, v4-11-test has been updated
       via  d887047aa0c vfs: restore stat fields in vfs_stat_fsp()
       via  b4aaa612d33 s3:vfs: streamline vfs_stat_fsp()
       via  b14dd975c75 s3: replace fsp_stat() with vfs_stat_fsp()
       via  cb09104951c s3:lib: add update_stat_ex_from_saved_stat()
       via  4930920648a vfs_catia: stat info may have been updated, make sure to return changes
       via  d47f8ca1a76 s3:smbd: ensure to update the File-ID in struct smb_filename
       via  6dfeecf345c s3:lib: round itime to NTTIME resolution in make_file_id_from_itime()
       via  cca34da443e lib: add round_timespec_to_nttime()
       via  0318b68675d s4:torture: add a file-id related test
      from  02ccbe08a53 s3:ldap: Fix join with don't exists machine account

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-11-test


- Log -----------------------------------------------------------------
commit d887047aa0c2489d1d6251ffcb9ce083e86866e1
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Sep 9 08:08:06 2019 +0200

    vfs: restore stat fields in vfs_stat_fsp()
    
    This ensures we preserve btime, itime and File-ID.
    
    As the Durable Handles code calls vfs_stat_fsp() in the DH disconnect function,
    previously the btime was lost and NOT stored in the cookie. With this change the
    cookie will store the correct btime (and iflags), which requires us to call
    dos_mode() in the reconnect function to ensure we pass
    vfs_default_durable_reconnect_check_stat().
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Tue Sep 10 20:22:21 UTC 2019 on sn-devel-184
    
    (cherry picked from commit 95655fe683d499d93f3844ed72ad332ef64adb96)
    
    Autobuild-User(v4-11-test): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(v4-11-test): Tue Sep 10 22:29:08 UTC 2019 on sn-devel-184

commit b4aaa612d33caf51b44830d75997d4ad93b7740d
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Sep 9 08:03:53 2019 +0200

    s3:vfs: streamline vfs_stat_fsp()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit e00e78cfeda99bd5374eff8fb4ba84873e4e46b7)

commit b14dd975c754be30d247591190bec5db3f305245
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Sep 9 07:57:34 2019 +0200

    s3: replace fsp_stat() with vfs_stat_fsp()
    
    Both functions do the same, they differ just in the type of the returned result.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit ab03394969f8a4c748aea7d0d8ed37f9ced6cc30)

commit cb09104951cdefba991464e486c536b06356fd25
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Aug 30 14:49:47 2019 +0200

    s3:lib: add update_stat_ex_from_saved_stat()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit ac18730f10ce96a607a3a07e1360b522ebf72f38)

commit 4930920648ad6879a72c77d79508025478dcbaa2
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Aug 30 14:48:57 2019 +0200

    vfs_catia: stat info may have been updated, make sure to return changes
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 4e49999c97f53acc7006f1dc6b6812bb0e156db5)

commit d47f8ca1a769571dae73081cda6a01812c1a256c
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Aug 30 14:48:40 2019 +0200

    s3:smbd: ensure to update the File-ID in struct smb_filename
    
    Initialize the File-ID in fsp->fsp_name->st, any subsequent metadata fetch on
    this file-handle needs this, eg QFID SMB2 Create-Context or GETINFO SMB
    requests.
    
    It would be nice if SMB_VFS_SET_DOS_ATTRIBUTE() would do this, unfortunately it
    gets a const struct smb_filename.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 3483b75fed8985bd2968bbf8c85985107115fba8)

commit 6dfeecf345c0a009fff6b233241156eff3160467
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Sep 9 11:12:08 2019 +0200

    s3:lib: round itime to NTTIME resolution in make_file_id_from_itime()
    
    The rounding is needed because when a file is created via eg an SMB2 CREATE
    request, we need to calculate the correct File-ID for the QFID Create-Context or
    for a subsequent GETINFO SMB request on the same file-handle.
    
    Any later metadata request that received the File-ID will do so by going through
    dos_mode() -> ... -> parse_dos_attribute_blob(), where the File-ID will be
    calculated from the on-disk itime which has NTTIME resolution.
    
    As long as that is the only available itime backend, I'm rounding itime inside
    make_file_id_from_itime(), not in the callers.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 84abeaa60ffced276da2b28b8add6efaa6da5ca6)

commit cca34da443ed6ee530fcf8c0def63d4b00527ffd
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Sep 3 17:50:54 2019 +0200

    lib: add round_timespec_to_nttime()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 5403bb22e6cb39baf6dc1b91558744d41e9f6f64)

commit 0318b68675d0318027ff5b6abf4a0d010839e6fd
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Aug 30 14:49:24 2019 +0200

    s4:torture: add a file-id related test
    
    Note I'm using the share vfs_fruit_xattr because I need a share with both a
    streams and a acl_* VFS object.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 2ecab3c60abf9baa16a6a5e3eba0fc4720def840)

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

Summary of changes:
 lib/util/time.c               |   9 ++
 lib/util/time.h               |   1 +
 source3/include/proto.h       |   2 +
 source3/lib/file_id.c         |   2 +
 source3/lib/system.c          |  20 ++++
 source3/modules/vfs_catia.c   |   4 +
 source3/modules/vfs_dirsort.c |  13 ++-
 source3/selftest/tests.py     |   2 +
 source3/smbd/durable.c        |   2 +
 source3/smbd/fileio.c         |  17 ----
 source3/smbd/open.c           |  17 ++++
 source3/smbd/proto.h          |   1 -
 source3/smbd/reply.c          |  23 +++--
 source3/smbd/vfs.c            |  12 +--
 source4/selftest/tests.py     |   1 +
 source4/torture/smb2/create.c | 212 ++++++++++++++++++++++++++++++++++++++++++
 source4/torture/smb2/smb2.c   |   1 +
 17 files changed, 302 insertions(+), 37 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/time.c b/lib/util/time.c
index bd067f84e8e..3a6043025f4 100644
--- a/lib/util/time.c
+++ b/lib/util/time.c
@@ -956,6 +956,15 @@ void round_timespec_to_usec(struct timespec *ts)
 	}
 }
 
+/****************************************************************************
+ Round a timespec to NTTIME resolution.
+****************************************************************************/
+
+void round_timespec_to_nttime(struct timespec *ts)
+{
+	ts->tv_nsec = (ts->tv_nsec / 100) * 100;
+}
+
 /****************************************************************************
  Put a 8 byte filetime from a struct timespec. Uses GMT.
 ****************************************************************************/
diff --git a/lib/util/time.h b/lib/util/time.h
index 1988b330576..7a8f8af35d9 100644
--- a/lib/util/time.h
+++ b/lib/util/time.h
@@ -328,6 +328,7 @@ struct timespec timespec_min(const struct timespec *ts1,
 int timespec_compare(const struct timespec *ts1, const struct timespec *ts2);
 void round_timespec_to_sec(struct timespec *ts);
 void round_timespec_to_usec(struct timespec *ts);
+void round_timespec_to_nttime(struct timespec *ts);
 NTTIME unix_timespec_to_nt_time(struct timespec ts);
 
 #endif /* _SAMBA_TIME_H_ */
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 8b387f7c563..ad6f3bbf9c3 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -223,6 +223,8 @@ void update_stat_ex_mtime(struct stat_ex *dst, struct timespec write_ts);
 void update_stat_ex_itime(struct stat_ex *dst, struct timespec itime);
 void update_stat_ex_create_time(struct stat_ex *dst, struct timespec create_time);
 void update_stat_ex_file_id(struct stat_ex *dst, uint64_t file_id);
+void update_stat_ex_from_saved_stat(struct stat_ex *dst,
+				    const struct stat_ex *src);
 int sys_stat(const char *fname, SMB_STRUCT_STAT *sbuf,
 	     bool fake_dir_create_times);
 int sys_fstat(int fd, SMB_STRUCT_STAT *sbuf,
diff --git a/source3/lib/file_id.c b/source3/lib/file_id.c
index 7d4fb006afe..21f22ffbf3b 100644
--- a/source3/lib/file_id.c
+++ b/source3/lib/file_id.c
@@ -102,6 +102,8 @@ uint64_t make_file_id_from_itime(SMB_STRUCT_STAT *st)
 		return ino;
 	}
 
+	round_timespec_to_nttime(&itime);
+
 	file_id_low = itime.tv_nsec;
 	if (file_id_low == 0) {
 		/*
diff --git a/source3/lib/system.c b/source3/lib/system.c
index a67388e436a..0620439c944 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -355,6 +355,26 @@ void update_stat_ex_file_id(struct stat_ex *dst, uint64_t file_id)
 	dst->st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_FILE_ID;
 }
 
+void update_stat_ex_from_saved_stat(struct stat_ex *dst,
+				    const struct stat_ex *src)
+{
+	if (!VALID_STAT(*src)) {
+		return;
+	}
+
+	if (!(src->st_ex_iflags & ST_EX_IFLAG_CALCULATED_BTIME)) {
+		update_stat_ex_create_time(dst, src->st_ex_btime);
+	}
+
+	if (!(src->st_ex_iflags & ST_EX_IFLAG_CALCULATED_ITIME)) {
+		update_stat_ex_itime(dst, src->st_ex_itime);
+	}
+
+	if (!(src->st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)) {
+		update_stat_ex_file_id(dst, src->st_ex_file_id);
+	}
+}
+
 void init_stat_ex_from_stat (struct stat_ex *dst,
 			    const struct stat *src,
 			    bool fake_dir_create_times)
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 762491ede31..1869d21dbcf 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -2377,6 +2377,10 @@ static NTSTATUS catia_get_dos_attributes(struct vfs_handle_struct *handle,
 	status = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle,
 						 mapped_smb_fname,
 						 dosmode);
+	if (NT_STATUS_IS_OK(status)) {
+		smb_fname->st = mapped_smb_fname->st;
+	}
+
 	TALLOC_FREE(mapped_name);
 	TALLOC_FREE(mapped_smb_fname);
 
diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c
index c23f6f0152d..c6b5ea41c93 100644
--- a/source3/modules/vfs_dirsort.c
+++ b/source3/modules/vfs_dirsort.c
@@ -44,19 +44,22 @@ static bool get_sorted_dir_mtime(vfs_handle_struct *handle,
 {
 	int ret;
 	struct timespec mtime;
+	NTSTATUS status;
 
 	if (data->fsp) {
-		ret = fsp_stat(data->fsp);
+		status = vfs_stat_fsp(data->fsp);
+		if (!NT_STATUS_IS_OK(status)) {
+			return false;
+		}
 		mtime = data->fsp->fsp_name->st.st_ex_mtime;
 	} else {
 		ret = SMB_VFS_STAT(handle->conn, data->smb_fname);
+		if (ret == -1) {
+			return false;
+		}
 		mtime = data->smb_fname->st.st_ex_mtime;
 	}
 
-	if (ret == -1) {
-		return false;
-	}
-
 	*ret_mtime = mtime;
 
 	return true;
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 31cb8ca33f1..20f2eea7661 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -689,6 +689,8 @@ for t in tests:
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/delete_readonly -U$USERNAME%$PASSWORD --option=torture:delete_readonly=true')
         plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
+    elif t == "smb2.fileid":
+        plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/vfs_fruit_xattr -U$USERNAME%$PASSWORD')
     elif t == "rpc.wkssvc":
         plansmbtorture4testsuite(t, "ad_member", '//$SERVER/tmp -U$DC_USERNAME%$DC_PASSWORD')
     elif t == "rpc.srvsvc":
diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c
index 4aa5a2d619e..89c4c1e8d14 100644
--- a/source3/smbd/durable.c
+++ b/source3/smbd/durable.c
@@ -842,6 +842,8 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 	}
 
+	(void)dos_mode(fsp->conn, fsp->fsp_name);
+
 	ok = vfs_default_durable_reconnect_check_stat(&cookie.stat_info,
 						      &fsp->fsp_name->st,
 						      fsp_str_dbg(fsp));
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index a00b368f92b..067ce5a9ad4 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -1068,20 +1068,3 @@ NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_throug
 	}
 	return NT_STATUS_OK;
 }
-
-/************************************************************
- Perform a stat whether a valid fd or not.
-************************************************************/
-
-int fsp_stat(files_struct *fsp)
-{
-	if (fsp->fh->fd == -1) {
-		if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
-			return SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
-		} else {
-			return SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
-		}
-	} else {
-		return SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
-	}
-}
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 2ee4a2c4fca..a5650ac9c2d 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -3710,6 +3710,15 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
 
 	if (info == FILE_WAS_CREATED) {
 		smb_fname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME;
+
+		if (lp_store_dos_attributes(SNUM(conn)) &&
+		    smb_fname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)
+		{
+			uint64_t file_id;
+
+			file_id = make_file_id_from_itime(&smb_fname->st);
+			update_stat_ex_file_id(&smb_fname->st, file_id);
+		}
 	}
 
 	if (info != FILE_WAS_OPENED) {
@@ -3862,6 +3871,14 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
 	smb_dname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME;
 
 	if (lp_store_dos_attributes(SNUM(conn))) {
+		if (smb_dname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)
+		{
+			uint64_t file_id;
+
+			file_id = make_file_id_from_itime(&smb_dname->st);
+			update_stat_ex_file_id(&smb_dname->st, file_id);
+		}
+
 		if (!posix_open) {
 			file_set_dosmode(conn, smb_dname,
 					 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index cd1ec9a1f9e..10ffaf6e480 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -342,7 +342,6 @@ void delete_write_cache(files_struct *fsp);
 void set_filelen_write_cache(files_struct *fsp, off_t file_size);
 ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason);
 NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_through);
-int fsp_stat(files_struct *fsp);
 
 /* The following definitions come from smbd/filename.c  */
 
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index dec67a10cae..35d1ae772d5 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -3662,6 +3662,7 @@ void reply_readbraw(struct smb_request *req)
 	files_struct *fsp;
 	struct lock_struct lock;
 	off_t size = 0;
+	NTSTATUS status;
 
 	START_PROFILE(SMBreadbraw);
 
@@ -3759,7 +3760,8 @@ void reply_readbraw(struct smb_request *req)
 		return;
 	}
 
-	if (fsp_stat(fsp) == 0) {
+	status = vfs_stat_fsp(fsp);
+	if (NT_STATUS_IS_OK(status)) {
 		size = fsp->fsp_name->st.st_ex_size;
 	}
 
@@ -4090,6 +4092,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
 	ssize_t nread = -1;
 	struct lock_struct lock;
 	int saved_errno = 0;
+	NTSTATUS status;
 
 	init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
 	    (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
@@ -4114,8 +4117,9 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
 		uint8_t headerbuf[smb_size + 12 * 2 + 1 /* padding byte */];
 		DATA_BLOB header;
 
-		if(fsp_stat(fsp) == -1) {
-			reply_nterror(req, map_nt_error_from_unix(errno));
+		status = vfs_stat_fsp(fsp);
+		if (!NT_STATUS_IS_OK(status)) {
+			reply_nterror(req, status);
 			goto out;
 		}
 
@@ -5323,6 +5327,7 @@ void reply_lseek(struct smb_request *req)
 	off_t res= -1;
 	int mode,umode;
 	files_struct *fsp;
+	NTSTATUS status;
 
 	START_PROFILE(SMBlseek);
 
@@ -5367,9 +5372,9 @@ void reply_lseek(struct smb_request *req)
 			if(errno == EINVAL) {
 				off_t current_pos = startpos;
 
-				if(fsp_stat(fsp) == -1) {
-					reply_nterror(req,
-						map_nt_error_from_unix(errno));
+				status = vfs_stat_fsp(fsp);
+				if (!NT_STATUS_IS_OK(status)) {
+					reply_nterror(req, status);
 					END_PROFILE(SMBlseek);
 					return;
 				}
@@ -8739,6 +8744,7 @@ void reply_getattrE(struct smb_request *req)
 	int mode;
 	files_struct *fsp;
 	struct timespec create_ts;
+	NTSTATUS status;
 
 	START_PROFILE(SMBgetattrE);
 
@@ -8757,8 +8763,9 @@ void reply_getattrE(struct smb_request *req)
 	}
 
 	/* Do an fstat on this file */
-	if(fsp_stat(fsp)) {
-		reply_nterror(req, map_nt_error_from_unix(errno));
+	status = vfs_stat_fsp(fsp);
+	if (!NT_STATUS_IS_OK(status)) {
+		reply_nterror(req, status);
 		END_PROFILE(SMBgetattrE);
 		return;
 	}
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 51a4aeb0f22..c8437a0c6c9 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -1406,6 +1406,7 @@ int vfs_stat_smb_basename(struct connection_struct *conn,
 NTSTATUS vfs_stat_fsp(files_struct *fsp)
 {
 	int ret;
+	struct stat_ex saved_stat = fsp->fsp_name->st;
 
 	if(fsp->fh->fd == -1) {
 		if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
@@ -1413,14 +1414,13 @@ NTSTATUS vfs_stat_fsp(files_struct *fsp)
 		} else {
 			ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
 		}
-		if (ret == -1) {
-			return map_nt_error_from_unix(errno);
-		}
 	} else {
-		if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
-			return map_nt_error_from_unix(errno);
-		}
+		ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
+	}
+	if (ret == -1) {
+		return map_nt_error_from_unix(errno);
 	}
+	update_stat_ex_from_saved_stat(&fsp->fsp_name->st, &saved_stat);
 	return NT_STATUS_OK;
 }
 
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index bf3dd98cbef..3f55649f217 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -342,6 +342,7 @@ smb2_s3only = [
     "smb2.kernel-oplocks",
     "smb2.durable-v2-delay",
     "smb2.aio_delay",
+    "smb2.fileid",
 ]
 smb2 = [x for x in smbtorture4_testsuites("smb2.") if x not in smb2_s3only]
 
diff --git a/source4/torture/smb2/create.c b/source4/torture/smb2/create.c
index 9b32062ab07..beddefc4c8d 100644
--- a/source4/torture/smb2/create.c
+++ b/source4/torture/smb2/create.c
@@ -1905,6 +1905,204 @@ done:
 	return ret;
 }
 
+static bool test_fileid(struct torture_context *tctx,
+			struct smb2_tree *tree)
+{
+	TALLOC_CTX *mem_ctx = talloc_new(tctx);
+	const char *fname = DNAME "\\foo";
+	const char *sname = DNAME "\\foo:bar";
+	struct smb2_handle testdirh;
+	struct smb2_handle h1;
+	struct smb2_create create;
+	union smb_fileinfo finfo;
+	union smb_setfileinfo sinfo;
+	struct smb2_find f;
+	unsigned int count;
+	union smb_search_data *d;
+	uint64_t fileid;
+	uint64_t stream_fileid;
+	NTSTATUS status;
+	bool ret = true;
+
+	smb2_deltree(tree, DNAME);
+
+	status = torture_smb2_testdir(tree, DNAME, &testdirh);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"torture_smb2_testdir failed\n");
+
+	create = (struct smb2_create) {
+		.in.desired_access = SEC_FILE_ALL,
+		.in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
+		.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
+		.in.create_disposition = NTCREATEX_DISP_OPEN_IF,
+		.in.fname = fname,
+		.in.query_on_disk_id = true,
+	};
+
+	status = smb2_create(tree, tctx, &create);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"test file could not be created\n");
+	h1 = create.out.file.handle;
+
+	fileid = BVAL(&create.out.on_disk_id, 0);
+
+	finfo = (union smb_fileinfo) {
+		.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
+		.generic.in.file.handle = h1,
+	};
+
+	status = smb2_getinfo_file(tree, tctx, &finfo);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"torture_smb2_testdir\n");
+
+	torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid,
+				      ret, done, "bad fileid\n");
+
+	f = (struct smb2_find) {
+		.in.file.handle = testdirh,
+		.in.pattern = "foo",
+		.in.max_response_size = 0x1000,
+		.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
+	};
+
+	status = smb2_find_level(tree, tree, &f, &count, &d);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_find_level failed\n");
+
+	torture_assert_u64_equal_goto(tctx,
+				      d->id_both_directory_info.file_id,
+				      fileid,
+				      ret, done, "bad fileid\n");
+
+	smb2_util_close(tree, h1);
+
+	create = (struct smb2_create) {
+		.in.desired_access = SEC_FILE_ALL,
+		.in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
+		.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
+		.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF,
+		.in.fname = sname,
+		.in.query_on_disk_id = true,
+	};
+
+	status = smb2_create(tree, tctx, &create);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"test file could not be created\n");
+	h1 = create.out.file.handle;
+
+	stream_fileid = BVAL(&create.out.on_disk_id, 0);
+	torture_assert_u64_equal_goto(tctx, stream_fileid, fileid,
+				      ret, done, "bad fileid\n");
+
+	finfo = (union smb_fileinfo) {
+		.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
+		.generic.in.file.handle = h1,
+	};
+
+	status = smb2_getinfo_file(tree, tctx, &finfo);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_getinfo_file failed\n");
+
+	torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid,
+				      ret, done, "bad fileid\n");
+
+	f = (struct smb2_find) {
+		.in.file.handle	= testdirh,
+		.in.pattern = "foo",
+		.in.max_response_size = 0x1000,
+		.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
+		.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART,
+	};
+
+	status = smb2_find_level(tree, tree, &f, &count, &d);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_find_level failed\n");
+
+	torture_assert_u64_equal_goto(tctx,
+				      d->id_both_directory_info.file_id,
+				      fileid,
+				      ret, done, "bad fileid\n");
+
+	status = smb2_util_write(tree, h1, "foo", 0, strlen("foo"));
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_util_write failed\n");
+
+	sinfo = (union smb_setfileinfo) {
+		.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION,
+		.basic_info.in.file.handle = h1,
+	};
+	unix_to_nt_time(&sinfo.basic_info.in.write_time, time(NULL));
+
+	status = smb2_setinfo_file(tree, &sinfo);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_setinfo_file failed\n");


-- 
Samba Shared Repository



More information about the samba-cvs mailing list