[SCM] Samba Shared Repository - branch master updated

Ralph Böhme slow at samba.org
Tue Sep 10 20:23:02 UTC 2019


The branch, master has been updated
       via  95655fe683d vfs: restore stat fields in vfs_stat_fsp()
       via  e00e78cfeda s3:vfs: streamline vfs_stat_fsp()
       via  ab03394969f s3: replace fsp_stat() with vfs_stat_fsp()
       via  ac18730f10c s3:lib: add update_stat_ex_from_saved_stat()
       via  4e49999c97f vfs_catia: stat info may have been updated, make sure to return changes
       via  3483b75fed8 s3:smbd: ensure to update the File-ID in struct smb_filename
       via  84abeaa60ff s3:lib: round itime to NTTIME resolution in make_file_id_from_itime()
       via  5403bb22e6c lib: add round_timespec_to_nttime()
       via  2ecab3c60ab s4:torture: add a file-id related test
      from  849e3842cd9 s4:torture/smb2: try to fix a RESOURCE_LEAK in smb2.samba3misc.localposixlock1

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


- Log -----------------------------------------------------------------
commit 95655fe683d499d93f3844ed72ad332ef64adb96
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

commit e00e78cfeda99bd5374eff8fb4ba84873e4e46b7
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>

commit ab03394969f8a4c748aea7d0d8ed37f9ced6cc30
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>

commit ac18730f10ce96a607a3a07e1360b522ebf72f38
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>

commit 4e49999c97f53acc7006f1dc6b6812bb0e156db5
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>

commit 3483b75fed8985bd2968bbf8c85985107115fba8
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>

commit 84abeaa60ffced276da2b28b8add6efaa6da5ca6
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>

commit 5403bb22e6cb39baf6dc1b91558744d41e9f6f64
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>

commit 2ecab3c60abf9baa16a6a5e3eba0fc4720def840
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>

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

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 17ea54fc4fe..7bf921f3476 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 251c02bb1ee..def8281fc43 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 96c84e14d40..caeb25a97dd 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -2384,6 +2384,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 4e6b23f4c98..dfae2c57a1d 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -717,6 +717,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 db02c229edd..a42c201b81b 100644
--- a/source3/smbd/durable.c
+++ b/source3/smbd/durable.c
@@ -841,6 +841,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 088e8cc1716..7797df03e4b 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -3667,6 +3667,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) {
@@ -3819,6 +3828,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 99458e50df9..7efbb80d3e3 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -334,7 +334,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 4446d927aeb..dcd46dd574c 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -3764,6 +3764,7 @@ void reply_readbraw(struct smb_request *req)
 	files_struct *fsp;
 	struct lock_struct lock;
 	off_t size = 0;
+	NTSTATUS status;
 
 	START_PROFILE(SMBreadbraw);
 
@@ -3861,7 +3862,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;
 	}
 
@@ -4192,6 +4194,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,
@@ -4216,8 +4219,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;
 		}
 
@@ -5425,6 +5429,7 @@ void reply_lseek(struct smb_request *req)
 	off_t res= -1;
 	int mode,umode;
 	files_struct *fsp;
+	NTSTATUS status;
 
 	START_PROFILE(SMBlseek);
 
@@ -5469,9 +5474,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;
 				}
@@ -8856,6 +8861,7 @@ void reply_getattrE(struct smb_request *req)
 	int mode;
 	files_struct *fsp;
 	struct timespec create_ts;
+	NTSTATUS status;
 
 	START_PROFILE(SMBgetattrE);
 
@@ -8874,8 +8880,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 c50ee55469d..a131b3303d5 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -1413,6 +1413,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) {
@@ -1420,14 +1421,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 6d0efcc42b8..6b2f8b3e4b5 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -345,6 +345,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 e6181c240cc..3fd99de0a3a 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