From: Jeremy Allison Date: Wed, 1 Dec 2021 20:53:29 +0000 (-0800) Subject: s3: smbd: Change unlink_internals() to ignore has_wild parameter. X-Git-Tag: tdb-1.4.6~393 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42985702df0485208fc46117ea73622f1a9e4a26;p=thirdparty%2Fsamba.git s3: smbd: Change unlink_internals() to ignore has_wild parameter. It's always passed as false now so we can remove the (horrible) enumeration code for unlink. Signed-off-by: Jeremy Allison Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 64c386785a9..c64a5d01eda 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3284,11 +3284,9 @@ NTSTATUS unlink_internals(connection_struct *conn, { char *fname_dir = NULL; char *fname_mask = NULL; - int count=0; NTSTATUS status = NT_STATUS_OK; struct smb_filename *smb_fname_dir = NULL; TALLOC_CTX *ctx = talloc_tos(); - int ret; bool posix_pathname = (smb_fname->flags & SMB_FILENAME_POSIX_PATH); /* Split up the directory from the filename/mask. */ @@ -3319,212 +3317,37 @@ NTSTATUS unlink_internals(connection_struct *conn, } } - if (!has_wild) { - - /* - * Only one file needs to be unlinked. Append the mask back - * onto the directory. - */ - TALLOC_FREE(smb_fname->base_name); - if (ISDOT(fname_dir)) { - /* Ensure we use canonical names on open. */ - smb_fname->base_name = talloc_asprintf(smb_fname, - "%s", - fname_mask); - } else { - smb_fname->base_name = talloc_asprintf(smb_fname, - "%s/%s", - fname_dir, - fname_mask); - } - if (!smb_fname->base_name) { - status = NT_STATUS_NO_MEMORY; - goto out; - } - if (dirtype == 0) { - dirtype = FILE_ATTRIBUTE_NORMAL; - } - - status = check_name(conn, smb_fname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - - status = do_unlink(conn, req, smb_fname, dirtype); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - - count++; + /* + * Only one file needs to be unlinked. Append the mask back + * onto the directory. + */ + TALLOC_FREE(smb_fname->base_name); + if (ISDOT(fname_dir)) { + /* Ensure we use canonical names on open. */ + smb_fname->base_name = talloc_asprintf(smb_fname, + "%s", + fname_mask); } else { - struct smb_Dir *dir_hnd = NULL; - long offset = 0; - const char *dname = NULL; - char *talloced = NULL; - bool case_sensitive = - (smb_fname->flags & SMB_FILENAME_POSIX_PATH) ? - true : conn->case_sensitive; - - if ((dirtype & SAMBA_ATTRIBUTES_MASK) == FILE_ATTRIBUTE_DIRECTORY) { - status = NT_STATUS_OBJECT_NAME_INVALID; - goto out; - } - if (dirtype == 0) { - dirtype = FILE_ATTRIBUTE_NORMAL; - } - - if (strequal(fname_mask,"????????.???")) { - TALLOC_FREE(fname_mask); - fname_mask = talloc_strdup(ctx, "*"); - if (!fname_mask) { - status = NT_STATUS_NO_MEMORY; - goto out; - } - } - - smb_fname_dir = synthetic_smb_fname(talloc_tos(), - fname_dir, - NULL, - NULL, - smb_fname->twrp, - smb_fname->flags); - if (smb_fname_dir == NULL) { - status = NT_STATUS_NO_MEMORY; - goto out; - } - - status = check_name(conn, smb_fname_dir); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - - dir_hnd = OpenDir(talloc_tos(), conn, smb_fname_dir, fname_mask, - dirtype); - if (dir_hnd == NULL) { - status = map_nt_error_from_unix(errno); - goto out; - } - - /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then - the pattern matches against the long name, otherwise the short name - We don't implement this yet XXXX - */ - - status = NT_STATUS_NO_SUCH_FILE; - - while ((dname = ReadDirName(dir_hnd, &offset, - &smb_fname->st, &talloced))) { - TALLOC_CTX *frame = talloc_stackframe(); - char *p = NULL; - struct smb_filename *f = NULL; - - /* Quick check for "." and ".." */ - if (ISDOT(dname) || ISDOTDOT(dname)) { - TALLOC_FREE(frame); - TALLOC_FREE(talloced); - continue; - } - - if (IS_VETO_PATH(conn, dname)) { - TALLOC_FREE(frame); - TALLOC_FREE(talloced); - continue; - } - - if(!mask_match(dname, fname_mask, - case_sensitive)) { - TALLOC_FREE(frame); - TALLOC_FREE(talloced); - continue; - } - - if (ISDOT(fname_dir)) { - /* Ensure we use canonical names on open. */ - p = talloc_asprintf(smb_fname, "%s", dname); - } else { - p = talloc_asprintf(smb_fname, "%s/%s", - fname_dir, dname); - } - if (p == NULL) { - TALLOC_FREE(dir_hnd); - status = NT_STATUS_NO_MEMORY; - TALLOC_FREE(frame); - TALLOC_FREE(talloced); - goto out; - } - f = synthetic_smb_fname(frame, - p, - NULL, - &smb_fname->st, - smb_fname->twrp, - smb_fname->flags); - if (f == NULL) { - TALLOC_FREE(dir_hnd); - status = NT_STATUS_NO_MEMORY; - TALLOC_FREE(frame); - TALLOC_FREE(talloced); - goto out; - } - - ret = vfs_stat(conn, f); - if (ret != 0) { - status = map_nt_error_from_unix(errno); - TALLOC_FREE(dir_hnd); - TALLOC_FREE(frame); - TALLOC_FREE(talloced); - goto out; - } - - status = openat_pathref_fsp(conn->cwd_fsp, f); - if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) && - (f->flags & SMB_FILENAME_POSIX_PATH) && - S_ISLNK(f->st.st_ex_mode)) - { - status = NT_STATUS_OK; - } - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(dir_hnd); - TALLOC_FREE(frame); - TALLOC_FREE(talloced); - goto out; - } - - if (!is_visible_fsp(f->fsp)) { - TALLOC_FREE(frame); - TALLOC_FREE(talloced); - continue; - } - - status = check_name(conn, f); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(dir_hnd); - TALLOC_FREE(frame); - TALLOC_FREE(talloced); - goto out; - } - - status = do_unlink(conn, req, f, dirtype); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(dir_hnd); - TALLOC_FREE(frame); - TALLOC_FREE(talloced); - goto out; - } - - count++; - DBG_DEBUG("successful unlink [%s]\n", - smb_fname_str_dbg(f)); - - TALLOC_FREE(frame); - TALLOC_FREE(talloced); - } - TALLOC_FREE(dir_hnd); + smb_fname->base_name = talloc_asprintf(smb_fname, + "%s/%s", + fname_dir, + fname_mask); + } + if (!smb_fname->base_name) { + status = NT_STATUS_NO_MEMORY; + goto out; + } + if (dirtype == 0) { + dirtype = FILE_ATTRIBUTE_NORMAL; } - if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) { - status = map_nt_error_from_unix(errno); + status = check_name(conn, smb_fname); + if (!NT_STATUS_IS_OK(status)) { + goto out; } + status = do_unlink(conn, req, smb_fname, dirtype); + out: TALLOC_FREE(smb_fname_dir); TALLOC_FREE(fname_dir);