s3:utils: let smbstatus report anonymous signing/encryption explicitly
[samba.git] / source3 / modules / vfs_media_harmony.c
index d6a93f8445f4a76fa001e2dcf67a89a8ecaa8e07..a027254c6b384d986af5e638d3f37062987108fa 100644 (file)
@@ -632,36 +632,35 @@ out:
  * Failure: set errno, return -1
  */
 static int mh_statvfs(struct vfs_handle_struct *handle,
-               const char *path,
+               const struct smb_filename *smb_fname,
                struct vfs_statvfs_struct *statbuf)
 {
        int status;
-       char *clientPath;
-       TALLOC_CTX *ctx;
+       struct smb_filename *clientFname = NULL;
 
-       DEBUG(MH_INFO_DEBUG, ("Entering with path '%s'\n", path));
+       DEBUG(MH_INFO_DEBUG, ("Entering with path '%s'\n",
+                       smb_fname->base_name));
 
-       if (!is_in_media_files(path))
+       if (!is_in_media_files(smb_fname->base_name))
        {
-               status = SMB_VFS_NEXT_STATVFS(handle, path, statbuf);
+               status = SMB_VFS_NEXT_STATVFS(handle, smb_fname, statbuf);
                goto out;
        }
 
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if ((status = alloc_get_client_path(handle, ctx,
-                               path,
-                               &clientPath)))
-       {
+       status = alloc_get_client_smb_fname(handle,
+                               talloc_tos(),
+                               smb_fname,
+                               &clientFname);
+       if (status != 0) {
                goto err;
        }
 
-       status = SMB_VFS_NEXT_STATVFS(handle, clientPath, statbuf);
+       status = SMB_VFS_NEXT_STATVFS(handle, clientFname, statbuf);
 err:
-       TALLOC_FREE(clientPath);
+       TALLOC_FREE(clientFname);
 out:
-       DEBUG(MH_INFO_DEBUG, ("Leaving with path '%s'\n", path));
+       DEBUG(MH_INFO_DEBUG, ("Leaving with path '%s'\n",
+                       smb_fname->base_name));
        return status;
 }
 
@@ -756,62 +755,6 @@ err:
        return status;
 }
 
-/* Success: return a mh_dirinfo_struct cast as a DIR
- * Failure: set errno, return NULL
- */
-static DIR *mh_opendir(vfs_handle_struct *handle,
-               const struct smb_filename *smb_fname,
-               const char *mask,
-               uint32_t attr)
-{
-       struct mh_dirinfo_struct *dirInfo;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering with fname '%s'\n",
-               smb_fname->base_name));
-
-       if (alloc_set_client_dirinfo(handle, smb_fname->base_name, &dirInfo))
-       {
-               goto err;
-       }
-
-       if (!dirInfo->isInMediaFiles)
-       {
-               dirInfo->dirstream = SMB_VFS_NEXT_OPENDIR(handle,
-                       smb_fname, mask, attr);
-       } else {
-               struct smb_filename *smb_fname_clientpath =
-                               synthetic_smb_fname(talloc_tos(),
-                                       dirInfo->clientPath,
-                                       NULL,
-                                       NULL,
-                                       smb_fname->flags);
-               if (smb_fname_clientpath == NULL) {
-                       goto err;
-               }
-
-               dirInfo->dirstream = SMB_VFS_NEXT_OPENDIR(handle,
-                       smb_fname_clientpath, mask, attr);
-               TALLOC_FREE(smb_fname_clientpath);
-       }
-
-       if (dirInfo->dirstream == NULL) {
-               goto err;
-       }
-
-       /* Success is freed in closedir. */
-       DEBUG(MH_INFO_DEBUG, ("Leaving with dirInfo->dirpath '%s', "
-                               "dirInfo->clientPath '%s'\n",
-                               dirInfo->dirpath,
-                               dirInfo->clientPath));
-       return (DIR*)dirInfo;
-err:
-       /* Failure is freed here. */
-       DEBUG(MH_ERR_DEBUG, ("Failing with fname '%s'\n",
-               smb_fname->base_name));
-       TALLOC_FREE(dirInfo);
-       return NULL;
-}
-
 static DIR *mh_fdopendir(vfs_handle_struct *handle,
                files_struct *fsp,
                const char *mask,
@@ -874,9 +817,8 @@ err:
  * End of data: return NULL
  * Failure: set errno, return NULL
  */
-static struct dirent *mh_readdir(vfs_handle_struct *handle,
-               DIR *dirp,
-               SMB_STRUCT_STAT *sbuf)
+static struct dirent *
+mh_readdir(vfs_handle_struct *handle, struct files_struct *dirfsp, DIR *dirp)
 {
        mh_dirinfo_struct* dirInfo = (mh_dirinfo_struct*)dirp;
        struct dirent *d = NULL;
@@ -899,7 +841,7 @@ static struct dirent *mh_readdir(vfs_handle_struct *handle,
 
        if (! dirInfo->isInMediaFiles)
        {
-               d = SMB_VFS_NEXT_READDIR(handle, dirInfo->dirstream, sbuf);
+               d = SMB_VFS_NEXT_READDIR(handle, dirfsp, dirInfo->dirstream);
                goto out;
        }
 
@@ -909,7 +851,7 @@ static struct dirent *mh_readdir(vfs_handle_struct *handle,
                bool isAppleDouble;
 
                skip = False;
-               d = SMB_VFS_NEXT_READDIR(handle, dirInfo->dirstream, sbuf);
+               d = SMB_VFS_NEXT_READDIR(handle, dirfsp, dirInfo->dirstream);
 
                if (d == NULL)
                {
@@ -1004,31 +946,6 @@ out:
        return d;
 }
 
-/*
- * Success: no success result defined.
- * Failure: no failure result defined.
- */
-static void mh_seekdir(vfs_handle_struct *handle,
-               DIR *dirp,
-               long offset)
-{
-       DEBUG(MH_INFO_DEBUG, ("Entering and leaving mh_seekdir\n"));
-       SMB_VFS_NEXT_SEEKDIR(handle,
-                       ((mh_dirinfo_struct*)dirp)->dirstream, offset);
-}
-
-/*
- * Success: return long
- * Failure: no failure result defined.
- */
-static long mh_telldir(vfs_handle_struct *handle,
-               DIR *dirp)
-{
-       DEBUG(MH_INFO_DEBUG, ("Entering and leaving mh_telldir\n"));
-       return SMB_VFS_NEXT_TELLDIR(handle,
-                       ((mh_dirinfo_struct*)dirp)->dirstream);
-}
-
 /*
  * Success: no success result defined.
  * Failure: no failure result defined.
@@ -1045,67 +962,47 @@ static void mh_rewinddir(vfs_handle_struct *handle,
  * Success: return 0
  * Failure: set errno, return -1
  */
-static int mh_mkdir(vfs_handle_struct *handle,
+static int mh_mkdirat(vfs_handle_struct *handle,
+               struct files_struct *dirfsp,
                const struct smb_filename *smb_fname,
                mode_t mode)
 {
        int status;
        struct smb_filename *clientFname = NULL;
        const char *path = smb_fname->base_name;
+       struct smb_filename *full_fname = NULL;
 
        DEBUG(MH_INFO_DEBUG, ("Entering with path '%s'\n", path));
 
-       if (!is_in_media_files(path))
-       {
-               status = SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode);
-               goto out;
-       }
-
-       status = alloc_get_client_smb_fname(handle,
-                               talloc_tos(),
+       if (!is_in_media_files(path)) {
+               status = SMB_VFS_NEXT_MKDIRAT(handle,
+                               dirfsp,
                                smb_fname,
-                               &clientFname);
-       if (status != 0) {
-               goto err;
+                               mode);
+               goto out;
        }
 
-       status = SMB_VFS_NEXT_MKDIR(handle, clientFname, mode);
-err:
-       TALLOC_FREE(clientFname);
-out:
-       DEBUG(MH_INFO_DEBUG, ("Leaving with path '%s'\n", path));
-       return status;
-}
-
-/*
- * Success: return 0
- * Failure: set errno, return -1
- */
-static int mh_rmdir(vfs_handle_struct *handle,
-               const struct smb_filename *smb_fname)
-{
-       int status;
-       struct smb_filename *clientFname = NULL;
-       const char *path = smb_fname->base_name;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering with path '%s'\n", path));
-
-       if (!is_in_media_files(path))
-       {
-               status = SMB_VFS_NEXT_RMDIR(handle, smb_fname);
-               goto out;
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dirfsp,
+                                                 smb_fname);
+       if (full_fname == NULL) {
+               return -1;
        }
 
        status = alloc_get_client_smb_fname(handle,
                                talloc_tos(),
-                               smb_fname,
+                               full_fname,
                                &clientFname);
        if (status != 0) {
                goto err;
        }
 
-       status = SMB_VFS_NEXT_RMDIR(handle, clientFname);
+       status = SMB_VFS_NEXT_MKDIRAT(handle,
+                       handle->conn->cwd_fsp,
+                       clientFname,
+                       mode);
 err:
+       TALLOC_FREE(full_fname);
        TALLOC_FREE(clientFname);
 out:
        DEBUG(MH_INFO_DEBUG, ("Leaving with path '%s'\n", path));
@@ -1129,66 +1026,53 @@ static int mh_closedir(vfs_handle_struct *handle,
        return SMB_VFS_NEXT_CLOSEDIR(handle, realdirp);
 }
 
-/*
- * Success: no success result defined.
- * Failure: no failure result defined.
- */
-static void mh_init_search_op(vfs_handle_struct *handle,
-               DIR *dirp)
-{
-       DEBUG(MH_INFO_DEBUG, ("Entering and leaving mh_init_search_op\n"));
-       SMB_VFS_NEXT_INIT_SEARCH_OP(handle,
-                       ((mh_dirinfo_struct*)dirp)->dirstream);
-}
-
 /*
  * Success: return non-negative file descriptor
  * Failure: set errno, return -1
  */
-static int mh_open(vfs_handle_struct *handle,
-               struct smb_filename *smb_fname,
-               files_struct *fsp,
-               int flags,
-               mode_t mode)
+static int mh_openat(struct vfs_handle_struct *handle,
+                    const struct files_struct *dirfsp,
+                    const struct smb_filename *smb_fname,
+                    files_struct *fsp,
+                    const struct vfs_open_how *how)
 {
        int ret;
        struct smb_filename *clientFname;
        TALLOC_CTX *ctx;
 
-
        DEBUG(MH_INFO_DEBUG, ("Entering with smb_fname->base_name '%s'\n",
                              smb_fname->base_name));
 
-       if (!is_in_media_files(smb_fname->base_name))
-       {
-               ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags,
-                               mode);
+       if (!is_in_media_files(smb_fname->base_name)) {
+               ret = SMB_VFS_NEXT_OPENAT(handle,
+                                         dirfsp,
+                                         smb_fname,
+                                         fsp,
+                                         how);
                goto out;
        }
 
        clientFname = NULL;
        ctx = talloc_tos();
 
-       if(alloc_get_client_smb_fname(handle, ctx,
-                               smb_fname,
-                               &clientFname))
-       {
+       if (alloc_get_client_smb_fname(handle, ctx, smb_fname, &clientFname)) {
                ret = -1;
                goto err;
        }
 
-       // What about fsp->fsp_name?
-       // We also have to get correct stat info into fsp and smb_fname
-       // for DB files, don't we?
+       /*
+        * What about fsp->fsp_name? We also have to get correct stat info into
+        * fsp and smb_fname for DB files, don't we?
+        */
 
        DEBUG(MH_INFO_DEBUG, ("Leaving with smb_fname->base_name '%s' "
-                       "smb_fname->st.st_ex_mtime %s"
-                       "               fsp->fsp_name->st.st_ex_mtime %s",
-                       smb_fname->base_name,
-                       ctime(&(smb_fname->st.st_ex_mtime.tv_sec)),
-                       ctime(&(fsp->fsp_name->st.st_ex_mtime.tv_sec))));
+                             "smb_fname->st.st_ex_mtime %s"
+                             " fsp->fsp_name->st.st_ex_mtime %s",
+                             smb_fname->base_name,
+                             ctime(&(smb_fname->st.st_ex_mtime.tv_sec)),
+                             ctime(&(fsp->fsp_name->st.st_ex_mtime.tv_sec))));
 
-       ret = SMB_VFS_NEXT_OPEN(handle, clientFname, fsp, flags, mode);
+       ret = SMB_VFS_NEXT_OPENAT(handle, dirfsp, clientFname, fsp, how);
 err:
        TALLOC_FREE(clientFname);
 out:
@@ -1203,7 +1087,7 @@ out:
  */
 static NTSTATUS mh_create_file(vfs_handle_struct *handle,
                struct smb_request *req,
-               uint16_t root_dir_fid,
+               struct files_struct *dirfsp,
                struct smb_filename *smb_fname,
                uint32_t access_mask,
                uint32_t share_access,
@@ -1211,7 +1095,7 @@ static NTSTATUS mh_create_file(vfs_handle_struct *handle,
                uint32_t create_options,
                uint32_t file_attributes,
                uint32_t oplock_request,
-               struct smb2_lease *lease,
+               const struct smb2_lease *lease,
                uint64_t allocation_size,
                uint32_t private_flags,
                struct security_descriptor *sd,
@@ -1233,7 +1117,7 @@ static NTSTATUS mh_create_file(vfs_handle_struct *handle,
                status = SMB_VFS_NEXT_CREATE_FILE(
                        handle,
                        req,
-                       root_dir_fid,
+                       dirfsp,
                        smb_fname,
                        access_mask,
                        share_access,
@@ -1272,7 +1156,7 @@ static NTSTATUS mh_create_file(vfs_handle_struct *handle,
        status = SMB_VFS_NEXT_CREATE_FILE(
                handle,
                req,
-               root_dir_fid,
+               dirfsp,
                clientFname,
                access_mask,
                share_access,
@@ -1307,15 +1191,17 @@ out:
  * Success: return 0
  * Failure: set errno, return -1
  */
-static int mh_rename(vfs_handle_struct *handle,
+static int mh_renameat(vfs_handle_struct *handle,
+               files_struct *srcfsp,
                const struct smb_filename *smb_fname_src,
+               files_struct *dstfsp,
                const struct smb_filename *smb_fname_dst)
 {
-       int status;
-       struct smb_filename *srcClientFname;
-       struct smb_filename *dstClientFname;
-       TALLOC_CTX *ctx;
-
+       int status = -1;
+       struct smb_filename *full_fname_src = NULL;
+       struct smb_filename *full_fname_dst = NULL;
+       struct smb_filename *srcClientFname = NULL;
+       struct smb_filename *dstClientFname = NULL;
 
        DEBUG(MH_INFO_DEBUG, ("Entering with "
                              "smb_fname_src->base_name '%s', "
@@ -1327,32 +1213,53 @@ static int mh_rename(vfs_handle_struct *handle,
                                &&
                        !is_in_media_files(smb_fname_dst->base_name))
        {
-               status = SMB_VFS_NEXT_RENAME(handle, smb_fname_src,
+               status = SMB_VFS_NEXT_RENAMEAT(handle,
+                               srcfsp,
+                               smb_fname_src,
+                               dstfsp,
                                smb_fname_dst);
                goto out;
        }
 
-       srcClientFname = NULL;
-       dstClientFname = NULL;
-       ctx = talloc_tos();
+       full_fname_src = full_path_from_dirfsp_atname(talloc_tos(),
+                                                     srcfsp,
+                                                     smb_fname_src);
+       if (full_fname_src == NULL) {
+               errno = ENOMEM;
+               goto out;
+        }
+       full_fname_dst = full_path_from_dirfsp_atname(talloc_tos(),
+                                                     dstfsp,
+                                                     smb_fname_dst);
+       if (full_fname_dst == NULL) {
+               errno = ENOMEM;
+               goto out;
+        }
 
-       if ((status = alloc_get_client_smb_fname(handle, ctx,
-                               smb_fname_src,
+       if ((status = alloc_get_client_smb_fname(handle,
+                               talloc_tos(),
+                               full_fname_src,
                                &srcClientFname)))
        {
                goto err;
        }
 
-       if ((status = alloc_get_client_smb_fname(handle, ctx,
-                               smb_fname_dst,
+       if ((status = alloc_get_client_smb_fname(handle,
+                               talloc_tos(),
+                               full_fname_dst,
                                &dstClientFname)))
        {
                goto err;
        }
 
-       status = SMB_VFS_NEXT_RENAME(handle, srcClientFname,
+       status = SMB_VFS_NEXT_RENAMEAT(handle,
+                               srcfsp->conn->cwd_fsp,
+                               srcClientFname,
+                               dstfsp->conn->cwd_fsp,
                                dstClientFname);
 err:
+       TALLOC_FREE(full_fname_src);
+       TALLOC_FREE(full_fname_dst);
        TALLOC_FREE(dstClientFname);
        TALLOC_FREE(srcClientFname);
 out:
@@ -1512,32 +1419,47 @@ out:
  * Success: return 0
  * Failure: set errno, return -1
  */
-static int mh_unlink(vfs_handle_struct *handle,
-               const struct smb_filename *smb_fname)
+static int mh_unlinkat(vfs_handle_struct *handle,
+               struct files_struct *dirfsp,
+               const struct smb_filename *smb_fname,
+               int flags)
 {
        int status;
+       struct smb_filename *full_fname = NULL;
        struct smb_filename *clientFname;
        TALLOC_CTX *ctx;
 
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_unlink\n"));
-       if (!is_in_media_files(smb_fname->base_name))
-       {
-               status = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
+       DEBUG(MH_INFO_DEBUG, ("Entering mh_unlinkat\n"));
+       if (!is_in_media_files(smb_fname->base_name)) {
+               status = SMB_VFS_NEXT_UNLINKAT(handle,
+                               dirfsp,
+                               smb_fname,
+                               flags);
                goto out;
        }
 
        clientFname = NULL;
        ctx = talloc_tos();
 
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dirfsp,
+                                                 smb_fname);
+       if (full_fname == NULL) {
+               return -1;
+       }
+
        if ((status = alloc_get_client_smb_fname(handle, ctx,
-                               smb_fname,
-                               &clientFname)))
-       {
+                               full_fname,
+                               &clientFname))) {
                goto err;
        }
 
-       status = SMB_VFS_NEXT_UNLINK(handle, clientFname);
+       status = SMB_VFS_NEXT_UNLINKAT(handle,
+                               dirfsp->conn->cwd_fsp,
+                               clientFname,
+                               flags);
 err:
+       TALLOC_FREE(full_fname);
        TALLOC_FREE(clientFname);
 out:
        return status;
@@ -1547,17 +1469,18 @@ out:
  * Success: return 0
  * Failure: set errno, return -1
  */
-static int mh_chmod(vfs_handle_struct *handle,
+static int mh_lchown(vfs_handle_struct *handle,
                const struct smb_filename *smb_fname,
-               mode_t mode)
+               uid_t uid,
+               gid_t gid)
 {
        int status;
        struct smb_filename *clientFname = NULL;
 
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_chmod\n"));
+       DEBUG(MH_INFO_DEBUG, ("Entering mh_lchown\n"));
        if (!is_in_media_files(smb_fname->base_name))
        {
-               status = SMB_VFS_NEXT_CHMOD(handle, smb_fname, mode);
+               status = SMB_VFS_NEXT_LCHOWN(handle, smb_fname, uid, gid);
                goto out;
        }
 
@@ -1569,7 +1492,7 @@ static int mh_chmod(vfs_handle_struct *handle,
                goto err;
        }
 
-       status = SMB_VFS_NEXT_CHMOD(handle, clientFname, mode);
+       status = SMB_VFS_NEXT_LCHOWN(handle, clientFname, uid, gid);
 err:
        TALLOC_FREE(clientFname);
 out:
@@ -1580,18 +1503,15 @@ out:
  * Success: return 0
  * Failure: set errno, return -1
  */
-static int mh_chown(vfs_handle_struct *handle,
-               const struct smb_filename *smb_fname,
-               uid_t uid,
-               gid_t gid)
+static int mh_chdir(vfs_handle_struct *handle,
+               const struct smb_filename *smb_fname)
 {
        int status;
        struct smb_filename *clientFname = NULL;
 
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_chown\n"));
-       if (!is_in_media_files(smb_fname->base_name))
-       {
-               status = SMB_VFS_NEXT_CHOWN(handle, smb_fname, uid, gid);
+       DEBUG(MH_INFO_DEBUG, ("Entering mh_chdir\n"));
+       if (!is_in_media_files(smb_fname->base_name)) {
+               status = SMB_VFS_NEXT_CHDIR(handle, smb_fname);
                goto out;
        }
 
@@ -1603,7 +1523,7 @@ static int mh_chown(vfs_handle_struct *handle,
                goto err;
        }
 
-       status = SMB_VFS_NEXT_CHOWN(handle, clientFname, uid, gid);
+       status = SMB_VFS_NEXT_CHDIR(handle, clientFname);
 err:
        TALLOC_FREE(clientFname);
 out:
@@ -1614,68 +1534,107 @@ out:
  * Success: return 0
  * Failure: set errno, return -1
  */
-static int mh_lchown(vfs_handle_struct *handle,
-               const struct smb_filename *smb_fname,
-               uid_t uid,
-               gid_t gid)
+
+static int mh_symlinkat(vfs_handle_struct *handle,
+               const struct smb_filename *link_contents,
+               struct files_struct *dirfsp,
+               const struct smb_filename *new_smb_fname)
 {
-       int status;
-       struct smb_filename *clientFname = NULL;
+       int status = -1;
+       struct smb_filename *full_fname = NULL;
+       struct smb_filename *new_link_target = NULL;
+       struct smb_filename *newclientFname = NULL;
 
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_lchown\n"));
-       if (!is_in_media_files(smb_fname->base_name))
-       {
-               status = SMB_VFS_NEXT_LCHOWN(handle, smb_fname, uid, gid);
+       DEBUG(MH_INFO_DEBUG, ("Entering mh_symlinkat\n"));
+
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               dirfsp,
+                                               new_smb_fname);
+       if (full_fname == NULL) {
+               status = -1;
+               goto err;
+       }
+
+       if (!is_in_media_files(link_contents->base_name) &&
+                       !is_in_media_files(full_fname->base_name)) {
+               status = SMB_VFS_NEXT_SYMLINKAT(handle,
+                               link_contents,
+                               dirfsp,
+                               new_smb_fname);
                goto out;
        }
 
-       status = alloc_get_client_smb_fname(handle,
-                               talloc_tos(),
-                               smb_fname,
-                               &clientFname);
-       if (status != 0) {
+       if ((status = alloc_get_client_smb_fname(handle, talloc_tos(),
+                               link_contents,
+                               &new_link_target))) {
+               goto err;
+       }
+       if ((status = alloc_get_client_smb_fname(handle, talloc_tos(),
+                               full_fname,
+                               &newclientFname))) {
                goto err;
        }
 
-       status = SMB_VFS_NEXT_LCHOWN(handle, clientFname, uid, gid);
+       status = SMB_VFS_NEXT_SYMLINKAT(handle,
+                               new_link_target,
+                               handle->conn->cwd_fsp,
+                               newclientFname);
 err:
-       TALLOC_FREE(clientFname);
+       TALLOC_FREE(new_link_target);
+       TALLOC_FREE(newclientFname);
 out:
+       TALLOC_FREE(full_fname);
        return status;
 }
 
 /*
- * Success: return 0
+ * Success: return byte count
  * Failure: set errno, return -1
  */
-static int mh_chdir(vfs_handle_struct *handle,
-               const char *path)
+static int mh_readlinkat(vfs_handle_struct *handle,
+               const struct files_struct *dirfsp,
+               const struct smb_filename *smb_fname,
+               char *buf,
+               size_t bufsiz)
 {
        int status;
-       char *clientPath;
-       TALLOC_CTX *ctx;
+       struct smb_filename *full_fname = NULL;
+       struct smb_filename *clientFname = NULL;
 
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_chdir\n"));
-       if (!is_in_media_files(path))
-       {
-               status = SMB_VFS_NEXT_CHDIR(handle, path);
-               goto out;
+       DEBUG(MH_INFO_DEBUG, ("Entering mh_readlinkat\n"));
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               dirfsp,
+                                               smb_fname);
+       if (full_fname == NULL) {
+               status = -1;
+               goto err;
        }
 
-       clientPath = NULL;
-       ctx = talloc_tos();
+       if (!is_in_media_files(full_fname->base_name)) {
+               status = SMB_VFS_NEXT_READLINKAT(handle,
+                               dirfsp,
+                               smb_fname,
+                               buf,
+                               bufsiz);
+               goto out;
+       }
 
-       if ((status = alloc_get_client_path(handle, ctx,
-                               path,
-                               &clientPath)))
-       {
+       if ((status = alloc_get_client_smb_fname(handle, talloc_tos(),
+                               full_fname,
+                               &clientFname))) {
                goto err;
        }
 
-       status = SMB_VFS_NEXT_CHDIR(handle, clientPath);
+       status = SMB_VFS_NEXT_READLINKAT(handle,
+                               handle->conn->cwd_fsp,
+                               clientFname,
+                               buf,
+                               bufsiz);
+
 err:
-       TALLOC_FREE(clientPath);
+       TALLOC_FREE(clientFname);
 out:
+       TALLOC_FREE(full_fname);
        return status;
 }
 
@@ -1683,35 +1642,74 @@ out:
  * Success: return 0
  * Failure: set errno, return -1
  */
-static int mh_ntimes(vfs_handle_struct *handle,
-               const struct smb_filename *smb_fname,
-               struct smb_file_time *ft)
+static int mh_linkat(vfs_handle_struct *handle,
+               files_struct *srcfsp,
+               const struct smb_filename *old_smb_fname,
+               files_struct *dstfsp,
+               const struct smb_filename *new_smb_fname,
+               int flags)
 {
        int status;
-       struct smb_filename *clientFname;
-       TALLOC_CTX *ctx;
+       struct smb_filename *old_full_fname = NULL;
+       struct smb_filename *oldclientFname = NULL;
+       struct smb_filename *new_full_fname = NULL;
+       struct smb_filename *newclientFname = NULL;
 
+       DEBUG(MH_INFO_DEBUG, ("Entering mh_linkat\n"));
 
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_ntimes\n"));
-       if (!is_in_media_files(smb_fname->base_name))
-       {
-               status = SMB_VFS_NEXT_NTIMES(handle, smb_fname, ft);
-               goto out;
+       old_full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               srcfsp,
+                                               old_smb_fname);
+       if (old_full_fname == NULL) {
+               status = -1;
+               goto err;
        }
 
-       clientFname = NULL;
-       ctx = talloc_tos();
+       new_full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               dstfsp,
+                                               new_smb_fname);
+       if (new_full_fname == NULL) {
+               status = -1;
+               goto err;
+       }
 
-       if ((status = alloc_get_client_smb_fname(handle, ctx,
-                               smb_fname,
-                               &clientFname)))
-       {
+       if (!is_in_media_files(old_full_fname->base_name) &&
+                       !is_in_media_files(new_full_fname->base_name)) {
+               TALLOC_FREE(old_full_fname);
+               TALLOC_FREE(new_full_fname);
+
+               status = SMB_VFS_NEXT_LINKAT(handle,
+                               srcfsp,
+                               old_smb_fname,
+                               dstfsp,
+                               new_smb_fname,
+                               flags);
+               goto out;
+       }
+
+       if ((status = alloc_get_client_smb_fname(handle, talloc_tos(),
+                               old_full_fname,
+                               &oldclientFname))) {
+               goto err;
+       }
+       if ((status = alloc_get_client_smb_fname(handle, talloc_tos(),
+                               new_full_fname,
+                               &newclientFname))) {
                goto err;
        }
 
-       status = SMB_VFS_NEXT_NTIMES(handle, clientFname, ft);
+       status = SMB_VFS_NEXT_LINKAT(handle,
+                               handle->conn->cwd_fsp,
+                               oldclientFname,
+                               handle->conn->cwd_fsp,
+                               newclientFname,
+                               flags);
+
 err:
-       TALLOC_FREE(clientFname);
+       TALLOC_FREE(old_full_fname);
+       TALLOC_FREE(new_full_fname);
+       TALLOC_FREE(newclientFname);
+       TALLOC_FREE(oldclientFname);
 out:
        return status;
 }
@@ -1720,168 +1718,54 @@ out:
  * Success: return 0
  * Failure: set errno, return -1
  */
-static int mh_symlink(vfs_handle_struct *handle,
-               const char *oldpath,
-               const char *newpath)
+static int mh_mknodat(vfs_handle_struct *handle,
+               files_struct *dirfsp,
+               const struct smb_filename *smb_fname,
+               mode_t mode,
+               SMB_DEV_T dev)
 {
        int status;
-       char *oldClientPath;
-       char *newClientPath;
+       struct smb_filename *full_fname = NULL;
+       struct smb_filename *clientFname = NULL;
        TALLOC_CTX *ctx;
 
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_symlink\n"));
-       if (!is_in_media_files(oldpath) && !is_in_media_files(newpath))
-       {
-               status = SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+       DEBUG(MH_INFO_DEBUG, ("Entering mh_mknodat\n"));
+
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               dirfsp,
+                                               smb_fname);
+       if (full_fname == NULL) {
+               status = -1;
+               goto err;
+       }
+
+       if (!is_in_media_files(full_fname->base_name)) {
+               status = SMB_VFS_NEXT_MKNODAT(handle,
+                               dirfsp,
+                               smb_fname,
+                               mode,
+                               dev);
                goto out;
        }
 
-       oldClientPath = NULL;
-       newClientPath = NULL;
        ctx = talloc_tos();
 
-       if ((status = alloc_get_client_path(handle, ctx,
-                               oldpath,
-                               &oldClientPath)))
-       {
-               goto err;
-       }
-
-       if ((status = alloc_get_client_path(handle, ctx,
-                               newpath,
-                               &newClientPath)))
-       {
+       if ((status = alloc_get_client_smb_fname(handle, ctx,
+                               full_fname,
+                               &clientFname))) {
                goto err;
        }
 
-       status = SMB_VFS_NEXT_SYMLINK(handle,
-                       oldClientPath,
-                       newClientPath);
+       status = SMB_VFS_NEXT_MKNODAT(handle,
+                       handle->conn->cwd_fsp,
+                       clientFname,
+                       mode,
+                       dev);
 
 err:
-       TALLOC_FREE(newClientPath);
-       TALLOC_FREE(oldClientPath);
-out:
-       return status;
-}
-
-/*
- * Success: return byte count
- * Failure: set errno, return -1
- */
-static int mh_readlink(vfs_handle_struct *handle,
-               const char *path,
-               char *buf,
-               size_t bufsiz)
-{
-       int status;
-       char *clientPath;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_readlink\n"));
-       if (!is_in_media_files(path))
-       {
-               status = SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz);
-               goto out;
-       }
-
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if ((status = alloc_get_client_path(handle, ctx,
-                               path,
-                               &clientPath)))
-       {
-               goto err;
-       }
-
-       status = SMB_VFS_NEXT_READLINK(handle, clientPath, buf, bufsiz);
-err:
-       TALLOC_FREE(clientPath);
-out:
-       return status;
-}
-
-/*
- * Success: return 0
- * Failure: set errno, return -1
- */
-static int mh_link(vfs_handle_struct *handle,
-               const char *oldpath,
-               const char *newpath)
-{
-       int status;
-       char *oldClientPath;
-       char *newClientPath;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_link\n"));
-       if (!is_in_media_files(oldpath) && !is_in_media_files(newpath))
-       {
-               status = SMB_VFS_NEXT_LINK(handle, oldpath, newpath);
-               goto out;
-       }
-
-       oldClientPath = NULL;
-       newClientPath = NULL;
-       ctx = talloc_tos();
-
-       if ((status = alloc_get_client_path(handle, ctx,
-                               oldpath,
-                               &oldClientPath)))
-       {
-               goto err;
-       }
-
-       if ((status = alloc_get_client_path(handle, ctx,
-                               newpath,
-                               &newClientPath)))
-       {
-               goto err;
-       }
-
-       status = SMB_VFS_NEXT_LINK(handle, oldClientPath, newClientPath);
-err:
-       TALLOC_FREE(newClientPath);
-       TALLOC_FREE(oldClientPath);
-out:
-       return status;
-}
-
-/*
- * Success: return 0
- * Failure: set errno, return -1
- */
-static int mh_mknod(vfs_handle_struct *handle,
-               const char *pathname,
-               mode_t mode,
-               SMB_DEV_T dev)
-{
-       int status;
-       char *clientPath;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_mknod\n"));
-       if (!is_in_media_files(pathname))
-       {
-               status = SMB_VFS_NEXT_MKNOD(handle, pathname, mode, dev);
-               goto out;
-       }
-
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if ((status = alloc_get_client_path(handle, ctx,
-                               pathname,
-                               &clientPath)))
-       {
-               goto err;
-       }
-
-       status = SMB_VFS_NEXT_MKNOD(handle, clientPath, mode, dev);
-err:
-       TALLOC_FREE(clientPath);
+       TALLOC_FREE(clientFname);
 out:
+       TALLOC_FREE(full_fname);
        return status;
 }
 
@@ -1889,484 +1773,39 @@ out:
  * Success: return path pointer
  * Failure: set errno, return NULL pointer
  */
-static char *mh_realpath(vfs_handle_struct *handle,
-               const char *path)
+static struct smb_filename *mh_realpath(vfs_handle_struct *handle,
+                               TALLOC_CTX *ctx,
+                               const struct smb_filename *smb_fname)
 {
-       char *buf;
-       char *clientPath;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_realpath\n"));
-       if (!is_in_media_files(path))
-       {
-               buf = SMB_VFS_NEXT_REALPATH(handle, path);
-               goto out;
-       }
-
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if (alloc_get_client_path(handle, ctx,
-                               path,
-                               &clientPath))
-       {
-               buf = NULL;
-               goto err;
-       }
-
-       buf = SMB_VFS_NEXT_REALPATH(handle, clientPath);
-err:
-       TALLOC_FREE(clientPath);
-out:
-       return buf;
-}
-
-/*
- * Success: return 0
- * Failure: set errno, return -1
- */
-static int mh_chflags(vfs_handle_struct *handle,
-               const char *path,
-               unsigned int flags)
-{
-       int status;
-       char *clientPath;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_chflags\n"));
-       if (!is_in_media_files(path))
-       {
-               status = SMB_VFS_NEXT_CHFLAGS(handle, path, flags);
-               goto out;
-       }
-
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if ((status = alloc_get_client_path(handle, ctx,
-                               path,
-                               &clientPath)))
-       {
-               goto err;
-       }
-
-       status = SMB_VFS_NEXT_CHFLAGS(handle, clientPath, flags);
-err:
-       TALLOC_FREE(clientPath);
-out:
-       return status;
-}
-
-/*
- * Success: return NT_STATUS_OK
- * Failure: return NT status error
- */
-static NTSTATUS mh_streaminfo(struct vfs_handle_struct *handle,
-               struct files_struct *fsp,
-               const struct smb_filename *smb_fname,
-               TALLOC_CTX *ctx,
-               unsigned int *num_streams,
-               struct stream_struct **streams)
-{
-       NTSTATUS status;
-       int ret;
+       struct smb_filename *result_fname = NULL;
        struct smb_filename *clientFname = NULL;
 
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_streaminfo\n"));
+       DEBUG(MH_INFO_DEBUG, ("Entering mh_realpath\n"));
        if (!is_in_media_files(smb_fname->base_name)) {
-               status = SMB_VFS_NEXT_STREAMINFO(handle,
-                               fsp,
-                               smb_fname,
-                               ctx,
-                               num_streams,
-                               streams);
-               goto out;
+               return SMB_VFS_NEXT_REALPATH(handle, ctx, smb_fname);
        }
 
-       ret = alloc_get_client_smb_fname(handle,
-                               talloc_tos(),
+       if (alloc_get_client_smb_fname(handle, ctx,
                                smb_fname,
-                               &clientFname);
-       if (ret != 0) {
-               status = NT_STATUS_NO_MEMORY;
+                               &clientFname) != 0) {
                goto err;
        }
 
-       /* This only works on files, so we don't have to worry about
-        * our fake directory stat'ing here.
-        */
-       status = SMB_VFS_NEXT_STREAMINFO(handle, fsp, clientFname,
-                               ctx, num_streams, streams);
+       result_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, clientFname);
 err:
        TALLOC_FREE(clientFname);
-out:
-       return status;
+       return result_fname;
 }
 
 /* Ignoring get_real_filename function because the default
  * doesn't do anything.
  */
 
-/*
- * Success: return NT_STATUS_OK
- * Failure: return NT status error
- * In this case, "name" is a path.
- */
-static NTSTATUS mh_get_nt_acl(vfs_handle_struct *handle,
-                             const struct smb_filename *smb_fname,
-                             uint32_t security_info,
-                             TALLOC_CTX *mem_ctx,
-                             struct security_descriptor **ppdesc)
-{
-       NTSTATUS status;
-       char *clientPath;
-       struct smb_filename *client_smb_fname = NULL;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_get_nt_acl\n"));
-       if (!is_in_media_files(smb_fname->base_name))
-       {
-               status = SMB_VFS_NEXT_GET_NT_ACL(handle, smb_fname,
-                                                security_info,
-                                                mem_ctx, ppdesc);
-               goto out;
-       }
-
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if (alloc_get_client_path(handle, ctx,
-                               smb_fname->base_name,
-                               &clientPath))
-       {
-               status = map_nt_error_from_unix(errno);
-               goto err;
-       }
-
-       client_smb_fname = synthetic_smb_fname(talloc_tos(),
-                                       clientPath,
-                                       NULL,
-                                       NULL,
-                                       smb_fname->flags);
-       if (client_smb_fname == NULL) {
-               TALLOC_FREE(clientPath);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       status = SMB_VFS_NEXT_GET_NT_ACL(handle, client_smb_fname,
-                                        security_info,
-                                        mem_ctx, ppdesc);
-err:
-       TALLOC_FREE(clientPath);
-       TALLOC_FREE(client_smb_fname);
-out:
-       return status;
-}
-
-/*
- * Success: return 0
- * Failure: set errno, return -1
- */
-static int mh_chmod_acl(vfs_handle_struct *handle,
-               const struct smb_filename *smb_fname,
-               mode_t mode)
-{
-       int status;
-       struct smb_filename *clientFname = NULL;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_chmod_acl\n"));
-       if (!is_in_media_files(smb_fname->base_name))
-       {
-               status = SMB_VFS_NEXT_CHMOD_ACL(handle, smb_fname, mode);
-               goto out;
-       }
-
-       status = alloc_get_client_smb_fname(handle,
-                               talloc_tos(),
-                               smb_fname,
-                               &clientFname);
-       if (status != 0) {
-               goto err;
-       }
-
-       status = SMB_VFS_NEXT_CHMOD_ACL(handle, clientFname, mode);
-err:
-       TALLOC_FREE(clientFname);
-out:
-       return status;
-}
-
-/*
- * Success: return acl pointer
- * Failure: set errno, return NULL
- */
-static SMB_ACL_T mh_sys_acl_get_file(vfs_handle_struct *handle,
-                                    const char *path_p,
-                                    SMB_ACL_TYPE_T type,
-                                    TALLOC_CTX *mem_ctx)
-{
-       SMB_ACL_T ret;
-       char *clientPath;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_sys_acl_get_file\n"));
-       if (!is_in_media_files(path_p))
-       {
-               ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type, mem_ctx);
-               goto out;
-       }
-
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if (alloc_get_client_path(handle, ctx,
-                               path_p,
-                               &clientPath))
-       {
-               ret = NULL;
-               goto err;
-       }
-
-       ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, clientPath, type, mem_ctx);
-err:
-       TALLOC_FREE(clientPath);
-out:
-       return ret;
-}
-
 /*
  * Success: return 0
  * Failure: set errno, return -1
- * In this case, "name" is a path.
- */
-static int mh_sys_acl_set_file(vfs_handle_struct *handle,
-               const char *name,
-               SMB_ACL_TYPE_T acltype,
-               SMB_ACL_T theacl)
-{
-       int status;
-       char *clientPath;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_sys_acl_set_file\n"));
-       if (!is_in_media_files(name))
-       {
-               status = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name,
-                               acltype, theacl);
-               goto out;
-       }
-
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if ((status = alloc_get_client_path(handle, ctx,
-                               name,
-                               &clientPath)))
-       {
-               goto err;
-       }
-
-       status = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, clientPath,
-                       acltype, theacl);
-err:
-       TALLOC_FREE(clientPath);
-out:
-       return status;
-}
-
-/*
- * Success: return 0
- * Failure: set errno, return -1
- */
-static int mh_sys_acl_delete_def_file(vfs_handle_struct *handle,
-               const char *path)
-{
-       int status;
-       char *clientPath;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_sys_acl_delete_def_file\n"));
-       if (!is_in_media_files(path))
-       {
-               status = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle,
-                               path);
-               goto out;
-       }
-
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if ((status = alloc_get_client_path(handle, ctx,
-                               path,
-                               &clientPath)))
-       {
-               goto err;
-       }
-
-       status = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, clientPath);
-err:
-       TALLOC_FREE(clientPath);
-out:
-       return status;
-}
-
-/*
- * Success: return positive number
- * Failure: set errno, return -1
  * In this case, "name" is an attr name.
  */
-static ssize_t mh_getxattr(struct vfs_handle_struct *handle,
-               const char *path,
-               const char *name,
-               void *value,
-               size_t size)
-{
-       ssize_t ret;
-       char *clientPath;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_getxattr\n"));
-       if (!is_in_media_files(path))
-       {
-               ret = SMB_VFS_NEXT_GETXATTR(handle, path, name, value,
-                               size);
-               goto out;
-       }
-
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if (alloc_get_client_path(handle, ctx,
-                               path,
-                               &clientPath))
-       {
-               ret = -1;
-               goto err;
-       }
-
-       ret = SMB_VFS_NEXT_GETXATTR(handle, clientPath, name, value, size);
-err:
-       TALLOC_FREE(clientPath);
-out:
-       return ret;
-}
-
-/*
- * Success: return positive number
- * Failure: set errno, return -1
- */
-static ssize_t mh_listxattr(struct vfs_handle_struct *handle,
-               const char *path,
-               char *list,
-               size_t size)
-{
-       ssize_t ret;
-       char *clientPath;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_listxattr\n"));
-       if (!is_in_media_files(path))
-       {
-               ret = SMB_VFS_NEXT_LISTXATTR(handle, path, list, size);
-               goto out;
-       }
-
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if (alloc_get_client_path(handle, ctx,
-                               path,
-                               &clientPath))
-       {
-               ret = -1;
-               goto err;
-       }
-
-       ret = SMB_VFS_NEXT_LISTXATTR(handle, clientPath, list, size);
-err:
-       TALLOC_FREE(clientPath);
-out:
-       return ret;
-}
-
-/*
- * Success: return 0
- * Failure: set errno, return -1
- * In this case, "name" is an attr name.
- */
-static int mh_removexattr(struct vfs_handle_struct *handle,
-               const char *path,
-               const char *name)
-{
-       int status;
-       char *clientPath;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_removexattr\n"));
-       if (!is_in_media_files(path))
-       {
-               status = SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
-               goto out;
-       }
-
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if ((status = alloc_get_client_path(handle, ctx,
-                               path,
-                               &clientPath)))
-       {
-               goto err;
-       }
-
-       status = SMB_VFS_NEXT_REMOVEXATTR(handle, clientPath, name);
-err:
-       TALLOC_FREE(clientPath);
-out:
-       return status;
-}
-
-/*
- * Success: return 0
- * Failure: set errno, return -1
- * In this case, "name" is an attr name.
- */
-static int mh_setxattr(struct vfs_handle_struct *handle,
-               const char *path,
-               const char *name,
-               const void *value,
-               size_t size,
-               int flags)
-{
-       int status;
-       char *clientPath;
-       TALLOC_CTX *ctx;
-
-       DEBUG(MH_INFO_DEBUG, ("Entering mh_setxattr\n"));
-       if (!is_in_media_files(path))
-       {
-               status = SMB_VFS_NEXT_SETXATTR(handle, path, name, value,
-                               size, flags);
-               goto out;
-       }
-
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if ((status = alloc_get_client_path(handle, ctx,
-                               path,
-                               &clientPath)))
-       {
-               goto err;
-       }
-
-       status = SMB_VFS_NEXT_SETXATTR(handle, clientPath, name, value,
-                       size, flags);
-err:
-       TALLOC_FREE(clientPath);
-out:
-       return status;
-}
 
 /* VFS operations structure */
 
@@ -2377,62 +1816,38 @@ static struct vfs_fn_pointers vfs_mh_fns = {
 
        /* Directory operations */
 
-       .opendir_fn = mh_opendir,
        .fdopendir_fn = mh_fdopendir,
        .readdir_fn = mh_readdir,
-       .seekdir_fn = mh_seekdir,
-       .telldir_fn = mh_telldir,
        .rewind_dir_fn = mh_rewinddir,
-       .mkdir_fn = mh_mkdir,
-       .rmdir_fn = mh_rmdir,
+       .mkdirat_fn = mh_mkdirat,
        .closedir_fn = mh_closedir,
-       .init_search_op_fn = mh_init_search_op,
 
        /* File operations */
 
-       .open_fn = mh_open,
+       .openat_fn = mh_openat,
        .create_file_fn = mh_create_file,
-       .rename_fn = mh_rename,
+       .renameat_fn = mh_renameat,
        .stat_fn = mh_stat,
        .lstat_fn = mh_lstat,
        .fstat_fn = mh_fstat,
-       .unlink_fn = mh_unlink,
-       .chmod_fn = mh_chmod,
-       .chown_fn = mh_chown,
+       .unlinkat_fn = mh_unlinkat,
        .lchown_fn = mh_lchown,
        .chdir_fn = mh_chdir,
-       .ntimes_fn = mh_ntimes,
-       .symlink_fn = mh_symlink,
-       .readlink_fn = mh_readlink,
-       .link_fn = mh_link,
-       .mknod_fn = mh_mknod,
+       .symlinkat_fn = mh_symlinkat,
+       .readlinkat_fn = mh_readlinkat,
+       .linkat_fn = mh_linkat,
+       .mknodat_fn = mh_mknodat,
        .realpath_fn = mh_realpath,
-       .chflags_fn = mh_chflags,
-       .streaminfo_fn = mh_streaminfo,
-
-       /* NT ACL operations. */
-
-       .get_nt_acl_fn = mh_get_nt_acl,
-
-       /* POSIX ACL operations. */
-
-       .chmod_acl_fn = mh_chmod_acl,
-
-       .sys_acl_get_file_fn = mh_sys_acl_get_file,
-       .sys_acl_set_file_fn = mh_sys_acl_set_file,
-       .sys_acl_delete_def_file_fn = mh_sys_acl_delete_def_file,
 
        /* EA operations. */
-       .getxattr_fn = mh_getxattr,
-       .listxattr_fn = mh_listxattr,
-       .removexattr_fn = mh_removexattr,
-       .setxattr_fn = mh_setxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
 
        /* aio operations */
 };
 
-NTSTATUS vfs_media_harmony_init(void);
-NTSTATUS vfs_media_harmony_init(void)
+static_decl_vfs;
+NTSTATUS vfs_media_harmony_init(TALLOC_CTX *ctx)
 {
        NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
                                "media_harmony", &vfs_mh_fns);