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;
}
/*