[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Thu Jul 28 16:35:02 UTC 2022


The branch, master has been updated
       via  332338173ec s3: smbd: Convert reply_checkpath() to use filename_convert_dirfsp().
       via  a70a9c63df3 s3: smbd: Convert call_trans2mkdir() to use filename_convert_dirfsp().
       via  12001941a4f s3: smbd: Convert call_trans2open() to use filename_convert_dirfsp().
       via  34056ced099 s3: smbd: Convert reply_rmdir() to use filename_convert_dirfsp().
       via  f599e469066 s3: smbd: Convert reply_ctemp() to use filename_convert_dirfsp().
       via  952f92ccb39 s3: smbd: Convert reply_mknew() to use filename_convert_dirfsp().
       via  48be22d8cce s3: smbd: Convert reply_open_and_X() to use filename_convert_dirfsp().
       via  e82a37d42bb s3: smbd: Convert reply_open() to use filename_convert_dirfsp().
       via  758ffebb8a8 s3: smbd: Fix the error processing in filename_convert_dirfsp_nosymlink() to match unix_convert() 100%
       via  be8ac8df178 s3: smbd: In filename_split_lcomp() ensure we never return a streamname if posix is set.
       via  1a653fdc442 s3: smbd: Ensure we set fsp->file_id in openat_pathref_dirfsp_nosymlink().
      from  3469895aca6 s3:winbind: Implement dcerpc_samr_chgpasswd_user4 for PamAuthChangePassword

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


- Log -----------------------------------------------------------------
commit 332338173ec9df9628e29eef2eccff2226c01e9d
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Jul 27 16:21:52 2022 -0700

    s3: smbd: Convert reply_checkpath() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    This is the acid test of filename_convert_dirfsp() pathname error
    handling.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Thu Jul 28 16:34:54 UTC 2022 on sn-devel-184

commit a70a9c63df34467dfef57003cf9f156e9b8d7b03
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Jul 27 12:39:11 2022 -0700

    s3: smbd: Convert call_trans2mkdir() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 12001941a4f77b1595ff4f64c7377dbc64f2dead
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Jul 27 12:36:23 2022 -0700

    s3: smbd: Convert call_trans2open() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 34056ced09962c9733e338b9d60559a297acbd9e
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Jul 27 12:29:18 2022 -0700

    s3: smbd: Convert reply_rmdir() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit f599e469066cd8048498067e083747a611f16342
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Jul 27 12:23:42 2022 -0700

    s3: smbd: Convert reply_ctemp() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 952f92ccb39edf18e1a2d4e3df4b1781b37c7206
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Jul 27 12:09:48 2022 -0700

    s3: smbd: Convert reply_mknew() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 48be22d8cce4c3508e145d727a378c4a6d3a4c3a
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Jul 27 12:00:32 2022 -0700

    s3: smbd: Convert reply_open_and_X() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit e82a37d42bb67fbf351f7d1fd82e8c200414780d
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Jul 27 12:05:17 2022 -0700

    s3: smbd: Convert reply_open() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 758ffebb8a8ce6b92598137f927a67961690bb69
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Jul 27 15:28:13 2022 -0700

    s3: smbd: Fix the error processing in filename_convert_dirfsp_nosymlink() to match unix_convert() 100%
    
    We need this in order to pass:
    
    samba3.raw.samba3badpath
    raw.chkpath
    samba3.base.chkpath
    
    Now we can convert all the SMB1 reply_openXXX functions,
    and reply_checkpath().
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit be8ac8df178556957d3d20d309b0f79cb1df6b34
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Jul 27 16:52:40 2022 -0700

    s3: smbd: In filename_split_lcomp() ensure we never return a streamname if posix is set.
    
    POSIX has no streams, even on the root of a directory.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 1a653fdc4422450737ab885d2531db8bed9fcf03
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Jul 27 14:36:33 2022 -0700

    s3: smbd: Ensure we set fsp->file_id in openat_pathref_dirfsp_nosymlink().
    
    This is a subtle one. The dirfsp returned by openat_pathref_dirfsp_nosymlink()
    can be used inside open.c and passed to check_parent_access_fsp() to
    check if a delete_on_close flag has been set on an existing "real"
    open fsp. So the file_id must be correctly set in order for this
    to work. Without it, samba3.base.delete fails in deltest20 when
    we convert reply_open_and_X() to use filename_convert_dirfsp().
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

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

Summary of changes:
 source3/smbd/filename.c    |  49 +++++++++++++++---
 source3/smbd/files.c       |   6 +++
 source3/smbd/smb1_reply.c  | 120 ++++++++++++++++++++++++++++++---------------
 source3/smbd/smb1_trans2.c |  41 ++++++++++------
 4 files changed, 154 insertions(+), 62 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 0f9921b62fa..3f0c395fd8f 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -2410,7 +2410,7 @@ static bool filename_split_lcomp(
 		return false;
 	}
 
-	if (name_in[0] == ':') {
+	if (!posix && (name_in[0] == ':')) {
 		/*
 		 * Special case for stream on root directory
 		 */
@@ -2749,6 +2749,19 @@ static NTSTATUS filename_convert_dirfsp_nosymlink(
 		return NT_STATUS_OK;
 	}
 
+	/*
+	 * Catch an invalid path of "." before we
+	 * call filename_split_lcomp(). We need to
+	 * do this as filename_split_lcomp() will
+	 * use "." for the missing relative component
+	 * when an empty name_in path is sent by
+	 * the client.
+	 */
+	if (ISDOT(name_in)) {
+		status = NT_STATUS_OBJECT_NAME_INVALID;
+		goto fail;
+	}
+
 	ok = filename_split_lcomp(
 		talloc_tos(),
 		name_in,
@@ -2761,11 +2774,6 @@ static NTSTATUS filename_convert_dirfsp_nosymlink(
 		goto fail;
 	}
 
-	if (fname_rel[0] == '\0') {
-		status = NT_STATUS_OBJECT_NAME_INVALID;
-		goto fail;
-	}
-
 	if (!posix) {
 		bool name_has_wild = ms_has_wild(dirname);
 		name_has_wild |= ms_has_wild(fname_rel);
@@ -2828,13 +2836,39 @@ static NTSTATUS filename_convert_dirfsp_nosymlink(
 
 		goto fail;
 	}
-	TALLOC_FREE(dirname);
 
 	if (!VALID_STAT_OF_DIR(smb_dirname->st)) {
 		status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
 		goto fail;
 	}
 
+	/*
+	 * Only look at bad last component values
+	 * once we know we have a valid directory. That
+	 * way we won't confuse error messages from
+	 * opening the directory path with error
+	 * messages from a bad last component.
+	 */
+
+	/* Relative filename can't be empty */
+	if (fname_rel[0] == '\0') {
+		status = NT_STATUS_OBJECT_NAME_INVALID;
+		goto fail;
+	}
+
+	/* Relative filename can't be ".." */
+	if (ISDOTDOT(fname_rel)) {
+		status = NT_STATUS_OBJECT_NAME_INVALID;
+		goto fail;
+	}
+	/* Relative name can only be dot if directory is empty. */
+	if (ISDOT(fname_rel) && dirname[0] != '\0') {
+		status = NT_STATUS_OBJECT_NAME_INVALID;
+		goto fail;
+	}
+
+	TALLOC_FREE(dirname);
+
 	smb_fname_rel = synthetic_smb_fname(
 		mem_ctx,
 		fname_rel,
@@ -2999,6 +3033,7 @@ done:
 	return NT_STATUS_OK;
 
 fail:
+	TALLOC_FREE(dirname);
 	TALLOC_FREE(smb_dirname);
 	TALLOC_FREE(smb_fname_rel);
 	return status;
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 9a81a16b3ec..afde81d3070 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -937,6 +937,12 @@ next:
 			  nt_errstr(status));
 		goto fail;
 	}
+	/*
+	 * We must correctly set fsp->file_id as code inside
+	 * open.c will use this to check if delete_on_close
+	 * has been set on the dirfsp.
+	 */
+	fsp->file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
 
 	result = cp_smb_filename(mem_ctx, fsp->fsp_name);
 	if (result == NULL) {
diff --git a/source3/smbd/smb1_reply.c b/source3/smbd/smb1_reply.c
index 6dfc636c9d8..de38817ea76 100644
--- a/source3/smbd/smb1_reply.c
+++ b/source3/smbd/smb1_reply.c
@@ -561,7 +561,9 @@ void reply_checkpath(struct smb_request *req)
 	struct smb_filename *smb_fname = NULL;
 	char *name = NULL;
 	NTSTATUS status;
+	struct files_struct *dirfsp = NULL;
 	uint32_t ucf_flags = ucf_flags_from_smb_request(req);
+	NTTIME twrp = 0;
 	TALLOC_CTX *ctx = talloc_tos();
 
 	START_PROFILE(SMBcheckpath);
@@ -578,13 +580,16 @@ void reply_checkpath(struct smb_request *req)
 
 	DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->vwv+0, 0)));
 
-	status = filename_convert(ctx,
-				conn,
-				name,
-				ucf_flags,
-				0,
-				&smb_fname);
-
+	if (ucf_flags & UCF_GMT_PATHNAME) {
+		extract_snapshot_token(name, &twrp);
+	}
+	status = filename_convert_dirfsp(ctx,
+					 conn,
+					 name,
+					 ucf_flags,
+					 twrp,
+					 &dirfsp,
+					 &smb_fname);
 	if (!NT_STATUS_IS_OK(status)) {
 		if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
 			reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -1407,6 +1412,7 @@ void reply_open(struct smb_request *req)
 	off_t size = 0;
 	time_t mtime=0;
 	int info;
+	struct files_struct *dirfsp = NULL;
 	files_struct *fsp;
 	int oplock_request;
 	int deny_mode;
@@ -1418,6 +1424,7 @@ void reply_open(struct smb_request *req)
 	uint32_t private_flags = 0;
 	NTSTATUS status;
 	uint32_t ucf_flags;
+	NTTIME twrp = 0;
 	TALLOC_CTX *ctx = talloc_tos();
 
 	START_PROFILE(SMBopen);
@@ -1448,12 +1455,16 @@ void reply_open(struct smb_request *req)
 
 	ucf_flags = filename_create_ucf_flags(req, create_disposition);
 
-	status = filename_convert(ctx,
-				conn,
-				fname,
-				ucf_flags,
-				0,
-				&smb_fname);
+	if (ucf_flags & UCF_GMT_PATHNAME) {
+		extract_snapshot_token(fname, &twrp);
+	}
+	status = filename_convert_dirfsp(ctx,
+					 conn,
+					 fname,
+					 ucf_flags,
+					 twrp,
+					 &dirfsp,
+					 &smb_fname);
 	if (!NT_STATUS_IS_OK(status)) {
 		if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
 			reply_botherror(req,
@@ -1468,7 +1479,7 @@ void reply_open(struct smb_request *req)
 	status = SMB_VFS_CREATE_FILE(
 		conn,					/* conn */
 		req,					/* req */
-		NULL,					/* dirfsp */
+		dirfsp,					/* dirfsp */
 		smb_fname,				/* fname */
 		access_mask,				/* access_mask */
 		share_mode,				/* share_access */
@@ -1580,6 +1591,7 @@ void reply_open_and_X(struct smb_request *req)
 	uint32_t fattr=0;
 	int mtime=0;
 	int smb_action = 0;
+	struct files_struct *dirfsp = NULL;
 	files_struct *fsp;
 	NTSTATUS status;
 	uint64_t allocation_size;
@@ -1590,6 +1602,7 @@ void reply_open_and_X(struct smb_request *req)
 	uint32_t create_options = 0;
 	uint32_t private_flags = 0;
 	uint32_t ucf_flags;
+	NTTIME twrp = 0;
 	TALLOC_CTX *ctx = talloc_tos();
 
 	START_PROFILE(SMBopenX);
@@ -1638,12 +1651,17 @@ void reply_open_and_X(struct smb_request *req)
 
 	ucf_flags = filename_create_ucf_flags(req, create_disposition);
 
-	status = filename_convert(ctx,
-				conn,
-				fname,
-				ucf_flags,
-				0,
-				&smb_fname);
+	if (ucf_flags & UCF_GMT_PATHNAME) {
+		extract_snapshot_token(fname, &twrp);
+	}
+
+	status = filename_convert_dirfsp(ctx,
+					 conn,
+					 fname,
+					 ucf_flags,
+					 twrp,
+					 &dirfsp,
+					 &smb_fname);
 	if (!NT_STATUS_IS_OK(status)) {
 		if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
 			reply_botherror(req,
@@ -1658,7 +1676,7 @@ void reply_open_and_X(struct smb_request *req)
 	status = SMB_VFS_CREATE_FILE(
 		conn,					/* conn */
 		req,					/* req */
-		NULL,					/* dirfsp */
+		dirfsp,					/* dirfsp */
 		smb_fname,				/* fname */
 		access_mask,				/* access_mask */
 		share_mode,				/* share_access */
@@ -2023,6 +2041,7 @@ void reply_mknew(struct smb_request *req)
 	char *fname = NULL;
 	uint32_t fattr = 0;
 	struct smb_file_time ft;
+	struct files_struct *dirfsp = NULL;
 	files_struct *fsp;
 	int oplock_request = 0;
 	NTSTATUS status;
@@ -2031,6 +2050,7 @@ void reply_mknew(struct smb_request *req)
 	uint32_t create_disposition;
 	uint32_t create_options = 0;
 	uint32_t ucf_flags;
+	NTTIME twrp = 0;
 	TALLOC_CTX *ctx = talloc_tos();
 
 	START_PROFILE(SMBcreate);
@@ -2063,12 +2083,17 @@ void reply_mknew(struct smb_request *req)
 	}
 
 	ucf_flags = filename_create_ucf_flags(req, create_disposition);
-	status = filename_convert(ctx,
-				conn,
-				fname,
-				ucf_flags,
-				0,
-				&smb_fname);
+	if (ucf_flags & UCF_GMT_PATHNAME) {
+		extract_snapshot_token(fname, &twrp);
+	}
+
+	status = filename_convert_dirfsp(ctx,
+					 conn,
+					 fname,
+					 ucf_flags,
+					 twrp,
+					 &dirfsp,
+					 &smb_fname);
 	if (!NT_STATUS_IS_OK(status)) {
 		if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
 			reply_botherror(req,
@@ -2089,7 +2114,7 @@ void reply_mknew(struct smb_request *req)
 	status = SMB_VFS_CREATE_FILE(
 		conn,					/* conn */
 		req,					/* req */
-		NULL,					/* dirfsp */
+		dirfsp,					/* dirfsp */
 		smb_fname,				/* fname */
 		access_mask,				/* access_mask */
 		share_mode,				/* share_access */
@@ -2163,12 +2188,14 @@ void reply_ctemp(struct smb_request *req)
 	char *wire_name = NULL;
 	char *fname = NULL;
 	uint32_t fattr;
+	struct files_struct *dirfsp = NULL;
 	files_struct *fsp;
 	int oplock_request;
 	char *s;
 	NTSTATUS status;
 	int i;
 	uint32_t ucf_flags;
+	NTTIME twrp = 0;
 	TALLOC_CTX *ctx = talloc_tos();
 
 	START_PROFILE(SMBctemp);
@@ -2206,11 +2233,16 @@ void reply_ctemp(struct smb_request *req)
 		}
 
 		ucf_flags = filename_create_ucf_flags(req, FILE_CREATE);
-		status = filename_convert(ctx, conn,
-				fname,
-				ucf_flags,
-				0,
-				&smb_fname);
+		if (ucf_flags & UCF_GMT_PATHNAME) {
+			extract_snapshot_token(fname, &twrp);
+		}
+		status = filename_convert_dirfsp(ctx,
+						 conn,
+						 fname,
+						 ucf_flags,
+						 twrp,
+						 &dirfsp,
+						 &smb_fname);
 		if (!NT_STATUS_IS_OK(status)) {
 			if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
 				reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -2225,7 +2257,7 @@ void reply_ctemp(struct smb_request *req)
 		status = SMB_VFS_CREATE_FILE(
 			conn,					/* conn */
 			req,					/* req */
-			NULL,					/* dirfsp */
+			dirfsp,					/* dirfsp */
 			smb_fname,				/* fname */
 			FILE_GENERIC_READ | FILE_GENERIC_WRITE, /* access_mask */
 			FILE_SHARE_READ | FILE_SHARE_WRITE,	/* share_access */
@@ -2244,6 +2276,7 @@ void reply_ctemp(struct smb_request *req)
 
 		if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
 			TALLOC_FREE(fname);
+			TALLOC_FREE(dirfsp);
 			TALLOC_FREE(smb_fname);
 			continue;
 		}
@@ -5834,8 +5867,10 @@ void reply_rmdir(struct smb_request *req)
 	char *directory = NULL;
 	NTSTATUS status;
 	TALLOC_CTX *ctx = talloc_tos();
+	struct files_struct *dirfsp = NULL;
 	files_struct *fsp = NULL;
 	int info = 0;
+	NTTIME twrp = 0;
 	uint32_t ucf_flags = ucf_flags_from_smb_request(req);
 
 	START_PROFILE(SMBrmdir);
@@ -5847,11 +5882,16 @@ void reply_rmdir(struct smb_request *req)
 		goto out;
 	}
 
-	status = filename_convert(ctx, conn,
-				 directory,
-				 ucf_flags,
-				 0,
-				 &smb_dname);
+	if (ucf_flags & UCF_GMT_PATHNAME) {
+		extract_snapshot_token(directory, &twrp);
+	}
+	status = filename_convert_dirfsp(ctx,
+					 conn,
+					 directory,
+					 ucf_flags,
+					 twrp,
+					 &dirfsp,
+					 &smb_dname);
 	if (!NT_STATUS_IS_OK(status)) {
 		if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
 			reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -5865,7 +5905,7 @@ void reply_rmdir(struct smb_request *req)
 	status = SMB_VFS_CREATE_FILE(
 		conn,                                   /* conn */
 		req,                                    /* req */
-		NULL,					/* dirfsp */
+		dirfsp,					/* dirfsp */
 		smb_dname,                              /* fname */
 		DELETE_ACCESS,                          /* access_mask */
 		(FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
diff --git a/source3/smbd/smb1_trans2.c b/source3/smbd/smb1_trans2.c
index 8c3bafa3a00..537b4dc6ff2 100644
--- a/source3/smbd/smb1_trans2.c
+++ b/source3/smbd/smb1_trans2.c
@@ -512,6 +512,7 @@ static void call_trans2open(connection_struct *conn,
 	int fattr=0,mtime=0;
 	SMB_INO_T inode = 0;
 	int smb_action = 0;
+	struct files_struct *dirfsp = NULL;
 	files_struct *fsp;
 	struct ea_list *ea_list = NULL;
 	uint16_t flags = 0;
@@ -521,6 +522,7 @@ static void call_trans2open(connection_struct *conn,
 	uint32_t create_disposition;
 	uint32_t create_options = 0;
 	uint32_t private_flags = 0;
+	NTTIME twrp = 0;
 	uint32_t ucf_flags = ucf_flags_from_smb_request(req);
 	TALLOC_CTX *ctx = talloc_tos();
 
@@ -583,12 +585,16 @@ static void call_trans2open(connection_struct *conn,
 		fname, (unsigned int)deny_mode, (unsigned int)open_attr,
 		(unsigned int)open_ofun, open_size));
 
-	status = filename_convert(ctx,
-				conn,
-				fname,
-				ucf_flags,
-				0,
-				&smb_fname);
+	if (ucf_flags & UCF_GMT_PATHNAME) {
+		extract_snapshot_token(fname, &twrp);
+	}
+	status = filename_convert_dirfsp(ctx,
+					 conn,
+					 fname,
+					 ucf_flags,
+					 twrp,
+					 &dirfsp,
+					 &smb_fname);
 	if (!NT_STATUS_IS_OK(status)) {
 		if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
 			reply_botherror(req,
@@ -660,7 +666,7 @@ static void call_trans2open(connection_struct *conn,
 	status = SMB_VFS_CREATE_FILE(
 		conn,					/* conn */
 		req,					/* req */
-		NULL,					/* dirfsp */
+		dirfsp,					/* dirfsp */
 		smb_fname,				/* fname */
 		access_mask,				/* access_mask */
 		share_mode,				/* share_access */
@@ -2617,6 +2623,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
 			     char **ppdata, int total_data,
 			     unsigned int max_data_bytes)
 {
+	struct files_struct *dirfsp = NULL;
 	struct files_struct *fsp = NULL;
 	struct smb_filename *smb_dname = NULL;
 	char *params = *pparams;
@@ -2625,6 +2632,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
 	NTSTATUS status = NT_STATUS_OK;
 	struct ea_list *ea_list = NULL;
 	uint32_t ucf_flags = ucf_flags_from_smb_request(req);
+	NTTIME twrp = 0;
 	TALLOC_CTX *ctx = talloc_tos();
 
 	if (!CAN_WRITE(conn)) {
@@ -2663,13 +2671,16 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
 
 	DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
 
-	status = filename_convert(ctx,
-				conn,
-				directory,
-				ucf_flags,
-				0,
-				&smb_dname);
-
+	if (ucf_flags & UCF_GMT_PATHNAME) {
+		extract_snapshot_token(directory, &twrp);
+	}
+	status = filename_convert_dirfsp(ctx,
+					 conn,
+					 directory,
+					 ucf_flags,
+					 twrp,
+					 &dirfsp,
+					 &smb_dname);
 	if (!NT_STATUS_IS_OK(status)) {
 		if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
 			reply_botherror(req,
@@ -2721,7 +2732,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
 	status = SMB_VFS_CREATE_FILE(
 		conn,					/* conn */
 		req,					/* req */
-		NULL,					/* dirfsp */
+		dirfsp,					/* dirfsp */
 		smb_dname,				/* fname */
 		MAXIMUM_ALLOWED_ACCESS,			/* access_mask */
 		FILE_SHARE_NONE,			/* share_access */


-- 
Samba Shared Repository



More information about the samba-cvs mailing list