]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Allow symlinks to be read via GET_REPARSE_POINT
authorVolker Lendecke <vl@samba.org>
Wed, 21 Dec 2022 15:42:12 +0000 (16:42 +0100)
committerRalph Boehme <slow@samba.org>
Fri, 22 Nov 2024 09:50:37 +0000 (09:50 +0000)
... to be used soon

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/modules/util_reparse.c

index 2694410be4fa3a7ff2bd202b41ee0c6280c58631..60373d7fd4e68c4e41d693e490f7c71ed30e6b93 100644 (file)
@@ -154,6 +154,45 @@ static NTSTATUS fsctl_get_reparse_point_dev(struct files_struct *fsp,
                fsp, &reparse_data, ctx, _out_data, max_out_len, _out_len);
 }
 
+static NTSTATUS fsctl_get_reparse_point_lnk(struct files_struct *fsp,
+                                           TALLOC_CTX *mem_ctx,
+                                           uint8_t **_out_data,
+                                           uint32_t max_out_len,
+                                           uint32_t *_out_len)
+{
+       struct reparse_data_buffer *reparse = NULL;
+       struct smb_filename *parent_fname = NULL;
+       struct smb_filename *base_name = NULL;
+       NTSTATUS status;
+
+       status = parent_pathref(talloc_tos(),
+                               fsp->conn->cwd_fsp,
+                               fsp->fsp_name,
+                               &parent_fname,
+                               &base_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_DEBUG("parent_pathref(%s) failed: %s\n",
+                         fsp_str_dbg(fsp),
+                         nt_errstr(status));
+               return status;
+       }
+
+       status = read_symlink_reparse(talloc_tos(),
+                                     parent_fname->fsp,
+                                     base_name,
+                                     &reparse);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_DEBUG("read_symlink_reparse failed: %s\n",
+                         nt_errstr(status));
+               return status;
+       }
+
+       status = fsctl_get_reparse_point_int(
+               fsp, reparse, mem_ctx, _out_data, max_out_len, _out_len);
+       TALLOC_FREE(reparse);
+       return status;
+}
+
 NTSTATUS fsctl_get_reparse_point(struct files_struct *fsp,
                                 TALLOC_CTX *mem_ctx,
                                 uint32_t *_reparse_tag,
@@ -212,6 +251,11 @@ NTSTATUS fsctl_get_reparse_point(struct files_struct *fsp,
                        max_out_len,
                        &out_len);
                break;
+       case S_IFLNK:
+               DBG_DEBUG("%s is a symlink\n", fsp_str_dbg(fsp));
+               status = fsctl_get_reparse_point_lnk(
+                       fsp, mem_ctx, &out_data, max_out_len, &out_len);
+               break;
        default:
                break;
        }