s3: smbd: smb2-posix: WIP. Partial implementation of fsctl_get_reparse_point()
authorJeremy Allison <jra@samba.org>
Tue, 18 Sep 2018 22:11:52 +0000 (15:11 -0700)
committerJeremy Allison <jra@samba.org>
Mon, 25 Feb 2019 20:48:05 +0000 (12:48 -0800)
Signed-off-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_default.c

index d646ce4f4ba86208138bbca0b26ab422f8659909..a22121b6a0b6afc314a5a22ddf7bcb29a50ba3a1 100644 (file)
@@ -1148,16 +1148,72 @@ static NTSTATUS vfswrap_translate_name(struct vfs_handle_struct *handle,
        return NT_STATUS_NONE_MAPPED;
 }
 
+static bool validate_reparse_xattr_data(struct files_struct *fsp,
+                               const char *data,
+                               uint32_t len)
+{
+       /* TODO... Ensure if NFS blk/char data then it's
+         from a root-owned file. */
+       return true;
+}
+
 static NTSTATUS fsctl_get_reparse_point(struct files_struct *fsp,
                                        TALLOC_CTX *ctx,
                                        char **out_data,
                                        uint32_t max_out_len,
                                        uint32_t *out_len)
 {
-       /* Fail it with STATUS_NOT_A_REPARSE_POINT */
-       DEBUG(10, ("FSCTL_GET_REPARSE_POINT: called on %s. "
-               "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp)));
-       return NT_STATUS_NOT_A_REPARSE_POINT;
+       char *data = NULL;
+       uint32_t len;
+
+       if (!fsp ->is_reparsepoint) {
+               /* Fail it with STATUS_NOT_A_REPARSE_POINT */
+               DEBUG(10, ("FSCTL_GET_REPARSE_POINT: called on %s. "
+                       "Status: not a reparse point\n", fsp_fnum_dbg(fsp)));
+               return NT_STATUS_NOT_A_REPARSE_POINT;
+       }
+       /* OK, this is a reparse point handle open. */
+       if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
+               /* Fake up reparse point link return. */
+               /* TODO... */
+               /*
+               SMB_VFS_NEXT_READLINK(handle, cap_smb_fname, buf, bufsiz);
+               */
+               return NT_STATUS_NOT_A_REPARSE_POINT;
+       } else {
+               ssize_t ret = -1;
+
+               /* Only zero length files allowed. */
+               if (fsp->fsp_name->st.st_ex_size != 0) {
+                       return NT_STATUS_NOT_A_REPARSE_POINT;
+               }
+               len = MIN(max_out_len, 64*1024);
+               data = talloc_array(ctx,
+                               char,
+                               len);
+               if (data == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               /* Get the SAMBA_XATTR_REPARSE_ATTRIB attribute. */
+               ret = SMB_VFS_FGETXATTR(fsp,
+                               SAMBA_XATTR_REPARSE_ATTRIB,
+                               data,
+                               len);
+               if (ret == -1) {
+                       int saved_errno = errno;
+                       TALLOC_FREE(data);
+                       errno = saved_errno;
+                       return map_nt_error_from_unix(errno);
+               }
+       }
+       if (!validate_reparse_xattr_data(fsp, data, len)) {
+               return NT_STATUS_NOT_A_REPARSE_POINT;
+       }
+
+       *out_data = data;
+       *out_len = len;
+
+       return NT_STATUS_OK;
 }
 
 /*