From: Volker Lendecke Date: Mon, 6 May 2024 14:59:44 +0000 (+0200) Subject: smbd: Implement FSCTL_DELETE_REPARSE_POINT X-Git-Tag: tdb-1.4.11~860 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5edd1e7c3ee8aa0e873b98285ddf2344cf96932c;p=thirdparty%2Fsamba.git smbd: Implement FSCTL_DELETE_REPARSE_POINT Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Mon May 6 21:55:03 UTC 2024 on atb-devel-224 --- diff --git a/selftest/knownfail.d/reparse b/selftest/knownfail.d/reparse index f0a8c9f3cab..11d094aa5c6 100644 --- a/selftest/knownfail.d/reparse +++ b/selftest/knownfail.d/reparse @@ -1,3 +1,2 @@ ^samba.tests.reparsepoints.samba.tests.reparsepoints.ReparsePoints.test_create_reparse_directory ^samba.tests.reparsepoints.samba.tests.reparsepoints.ReparsePoints.test_create_reparse_nonempty_directory -^samba.tests.reparsepoints.samba.tests.reparsepoints.ReparsePoints.test_delete_reparse_point diff --git a/source3/modules/util_reparse.c b/source3/modules/util_reparse.c index 77bae00693c..6f47367a4b8 100644 --- a/source3/modules/util_reparse.c +++ b/source3/modules/util_reparse.c @@ -213,6 +213,71 @@ NTSTATUS fsctl_del_reparse_point(struct files_struct *fsp, const uint8_t *in_data, uint32_t in_len) { - DBG_DEBUG("Called on %s\n", fsp_str_dbg(fsp)); - return NT_STATUS_NOT_A_REPARSE_POINT; + uint32_t existing_tag; + uint8_t *existing_data = NULL; + uint32_t existing_len; + uint32_t reparse_tag; + const uint8_t *reparse_data = NULL; + size_t reparse_data_length; + NTSTATUS status; + uint32_t dos_mode; + int ret; + + status = fsctl_get_reparse_point(fsp, + talloc_tos(), + &existing_tag, + &existing_data, + UINT32_MAX, + &existing_len); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + TALLOC_FREE(existing_data); + + status = reparse_buffer_check(in_data, + in_len, + &reparse_tag, + &reparse_data, + &reparse_data_length); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (reparse_data_length != 0) { + return NT_STATUS_IO_REPARSE_DATA_INVALID; + } + + if (existing_tag != reparse_tag) { + DBG_DEBUG("Expect correct tag %" PRIX32 ", got tag %" PRIX32 + "\n", + existing_tag, + reparse_tag); + return NT_STATUS_IO_REPARSE_TAG_MISMATCH; + } + + ret = SMB_VFS_FREMOVEXATTR(fsp, SAMBA_XATTR_REPARSE_ATTRIB); + if (ret == -1) { + status = map_nt_error_from_unix(errno); + DBG_DEBUG("removexattr fail on %s - %s\n", + fsp_str_dbg(fsp), + strerror(errno)); + return status; + } + + /* + * Files with reparse points don't have the ATTR_NORMAL bit + * set + */ + dos_mode = fdos_mode(fsp); + dos_mode &= ~FILE_ATTRIBUTE_REPARSE_POINT; + + status = SMB_VFS_FSET_DOS_ATTRIBUTES(fsp->conn, fsp, dos_mode); + + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("set reparse attr fail on %s - %s\n", + fsp_str_dbg(fsp), + nt_errstr(status)); + return status; + } + + return NT_STATUS_OK; }