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 <j...@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 <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>
    
    Autobuild-User(master): Volker Lendecke <v...@samba.org>
    Autobuild-Date(master): Thu Jul 28 16:34:54 UTC 2022 on sn-devel-184

commit a70a9c63df34467dfef57003cf9f156e9b8d7b03
Author: Jeremy Allison <j...@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 <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 12001941a4f77b1595ff4f64c7377dbc64f2dead
Author: Jeremy Allison <j...@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 <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 34056ced09962c9733e338b9d60559a297acbd9e
Author: Jeremy Allison <j...@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 <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit f599e469066cd8048498067e083747a611f16342
Author: Jeremy Allison <j...@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 <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 952f92ccb39edf18e1a2d4e3df4b1781b37c7206
Author: Jeremy Allison <j...@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 <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 48be22d8cce4c3508e145d727a378c4a6d3a4c3a
Author: Jeremy Allison <j...@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 <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit e82a37d42bb67fbf351f7d1fd82e8c200414780d
Author: Jeremy Allison <j...@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 <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 758ffebb8a8ce6b92598137f927a67961690bb69
Author: Jeremy Allison <j...@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 <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit be8ac8df178556957d3d20d309b0f79cb1df6b34
Author: Jeremy Allison <j...@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 <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 1a653fdc4422450737ab885d2531db8bed9fcf03
Author: Jeremy Allison <j...@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 <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@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

Reply via email to