From: Jeremy Allison Date: Mon, 5 Oct 2020 18:40:41 +0000 (-0700) Subject: s3: smbd: Fix SMB1 reply_unlink() to handle wildcards. X-Git-Tag: talloc-2.3.2~292 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=90bce2c0920d0f2dc2e3aebef0f563eda99fdaac;p=thirdparty%2Fsamba.git s3: smbd: Fix SMB1 reply_unlink() to handle wildcards. 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 Reviewed-by: Ralph Boehme --- diff --git a/selftest/knownfail.d/smb1-wild-mangle-unlink b/selftest/knownfail.d/smb1-wild-mangle-unlink deleted file mode 100644 index a8cdf25a070..00000000000 --- a/selftest/knownfail.d/smb1-wild-mangle-unlink +++ /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\) diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index fc4e552e213..2296b92b8b0 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -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; diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index a67d22a3a5d..cd4b34c050b 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -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); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index b4f4a5f4de0..c4380f070bd 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -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. */ diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 14c788e6c0b..792c70403f0 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -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; }