s3: smbd: Fix SMB1 reply_unlink() to handle wildcards.
authorJeremy Allison <jra@samba.org>
Mon, 5 Oct 2020 18:40:41 +0000 (11:40 -0700)
committerRalph Boehme <slow@samba.org>
Thu, 8 Oct 2020 15:07:30 +0000 (15:07 +0000)
Add a 'bool have_wcard' to unlink_internals().
Move the wildcard detection out of unlink_internals() as it
was looking at the wrong thing.

This is now correctly set only from the unmangled last component
of the path sent to reply_unlink().

We now pass:

Samba3.smbtorture_s3.crypt_client.SMB1-WILD-MANGLE-UNLINK(nt4_dc_smb1)
samba3.smbtorture_s3.plain.SMB1-WILD-MANGLE-UNLINK(fileserver_smb1)

so remove the knownfail.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
selftest/knownfail.d/smb1-wild-mangle-unlink [deleted file]
source3/printing/nt_printing.c
source3/smbd/proto.h
source3/smbd/reply.c
source3/smbd/trans2.c

diff --git a/selftest/knownfail.d/smb1-wild-mangle-unlink b/selftest/knownfail.d/smb1-wild-mangle-unlink
deleted file mode 100644 (file)
index a8cdf25..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Check SMB1 wildcard demangle
-^samba3.smbtorture_s3.plain.SMB1-WILD-MANGLE-UNLINK.smbtorture\(fileserver_smb1\)
-^samba3.smbtorture_s3.crypt_client.SMB1-WILD-MANGLE-UNLINK.smbtorture\(nt4_dc_smb1\)
index fc4e552e213ef6ceac7a1fdcf0084a595e1de55d..2296b92b8b04be5c3de9d6ec0e1bb01e9fbe3b3d 100644 (file)
@@ -2037,7 +2037,7 @@ static NTSTATUS driver_unlink_internals(connection_struct *conn,
                goto err_out;
        }
 
-       status = unlink_internals(conn, NULL, 0, smb_fname);
+       status = unlink_internals(conn, NULL, 0, smb_fname, false);
 err_out:
        talloc_free(tmp_ctx);
        return status;
index a67d22a3a5d80759be22f9070e3c58c60baf8b7c..cd4b34c050bb7fa9f2342227d3a91fbaffd39a20 100644 (file)
@@ -976,7 +976,8 @@ void reply_ctemp(struct smb_request *req);
 NTSTATUS unlink_internals(connection_struct *conn,
                        struct smb_request *req,
                        uint32_t dirtype,
-                       struct smb_filename *smb_fname);
+                       struct smb_filename *smb_fname,
+                       bool has_wcard);
 void reply_unlink(struct smb_request *req);
 ssize_t fake_sendfile(struct smbXsrv_connection *xconn, files_struct *fsp,
                      off_t startpos, size_t nread);
index b4f4a5f4de09f5f39ae42d80dfaf1e975a605323..c4380f070bd3f51054a0e4ef9f6ebff23185a61f 100644 (file)
@@ -3271,14 +3271,14 @@ static NTSTATUS do_unlink(connection_struct *conn,
 NTSTATUS unlink_internals(connection_struct *conn,
                        struct smb_request *req,
                        uint32_t dirtype,
-                       struct smb_filename *smb_fname)
+                       struct smb_filename *smb_fname,
+                       bool has_wild)
 {
        char *fname_dir = NULL;
        char *fname_mask = NULL;
        int count=0;
        NTSTATUS status = NT_STATUS_OK;
        struct smb_filename *smb_fname_dir = NULL;
-       bool has_wild = false;
        TALLOC_CTX *ctx = talloc_tos();
 
        /* Split up the directory from the filename/mask. */
@@ -3288,17 +3288,6 @@ NTSTATUS unlink_internals(connection_struct *conn,
                goto out;
        }
 
-       if (req != NULL && !req->posix_pathnames) {
-               /*
-                * Check the wildcard mask *before*
-                * unmangling. As mangling is done
-                * for names that can't be returned
-                * to Windows the unmangled name may
-                * contain Windows wildcard characters.
-                */
-               has_wild = ms_has_wild(fname_mask);
-       }
-
        /*
         * We should only check the mangled cache
         * here if unix_convert failed. This means
@@ -3518,6 +3507,7 @@ void reply_unlink(struct smb_request *req)
        uint32_t ucf_flags = UCF_ALWAYS_ALLOW_WCARD_LCOMP |
                        ucf_flags_from_smb_request(req);
        TALLOC_CTX *ctx = talloc_tos();
+       bool has_wild = false;
 
        START_PROFILE(SMBunlink);
 
@@ -3550,9 +3540,22 @@ void reply_unlink(struct smb_request *req)
                goto out;
        }
 
+       if (req != NULL && !req->posix_pathnames) {
+               char *lcomp = get_original_lcomp(ctx,
+                                       conn,
+                                       name,
+                                       ucf_flags);
+               if (lcomp == NULL) {
+                       reply_nterror(req, NT_STATUS_NO_MEMORY);
+                       goto out;
+               }
+               has_wild = ms_has_wild(lcomp);
+               TALLOC_FREE(lcomp);
+       }
+
        DEBUG(3,("reply_unlink : %s\n", smb_fname_str_dbg(smb_fname)));
 
-       status = unlink_internals(conn, req, dirtype, smb_fname);
+       status = unlink_internals(conn, req, dirtype, smb_fname, has_wild);
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->xconn, req->mid)) {
                        /* We have re-scheduled this call. */
index 14c788e6c0b4b00b65a8c196789f5585e4863eb9..792c70403f0ce2597e167592976b0cf08c77697b 100644 (file)
@@ -6465,7 +6465,8 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
                        status = unlink_internals(conn,
                                                req,
                                                FILE_ATTRIBUTE_NORMAL,
-                                               smb_fname_new);
+                                               smb_fname_new,
+                                               false);
                        if (!NT_STATUS_IS_OK(status)) {
                                return status;
                        }