Add fdopendir to the VFS. We will use this to reuse a directory fd already open by...
[sfrench/samba-autobuild/.git] / source3 / smbd / vfs.c
index 802639f2fb352bcddf573798311b6f3a3d046e5a..40aaf6bb742d55215001691310b9b902e39cea82 100644 (file)
@@ -1105,7 +1105,7 @@ NTSTATUS vfs_stat_fsp(files_struct *fsp)
 {
        int ret;
 
-       if(fsp->is_directory || fsp->fh->fd == -1) {
+       if(fsp->fh->fd == -1) {
                if (fsp->posix_open) {
                        ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
                } else {
@@ -1200,6 +1200,15 @@ SMB_STRUCT_DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
        return handle->fns->opendir(handle, fname, mask, attributes);
 }
 
+SMB_STRUCT_DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
+                                       struct files_struct *fsp,
+                                       const char *mask,
+                                       uint32 attributes)
+{
+       VFS_FIND(fdopendir);
+       return handle->fns->fdopendir(handle, fsp, mask, attributes);
+}
+
 SMB_STRUCT_DIRENT *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
                                              SMB_STRUCT_DIR *dirp,
                                              SMB_STRUCT_STAT *sbuf)
@@ -1439,6 +1448,36 @@ int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
        return handle->fns->lchown(handle, path, uid, gid);
 }
 
+NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
+{
+       int ret;
+
+       if (fsp->fh->fd != -1) {
+               /* Try fchown. */
+               ret = SMB_VFS_FCHOWN(fsp, uid, gid);
+               if (ret == 0) {
+                       return NT_STATUS_OK;
+               }
+               if (ret == -1 && errno != ENOSYS) {
+                       return map_nt_error_from_unix(errno);
+               }
+       }
+
+       if (fsp->posix_open) {
+               ret = SMB_VFS_LCHOWN(fsp->conn,
+                       fsp->fsp_name->base_name,
+                       uid, gid);
+       } else {
+               ret = SMB_VFS_CHOWN(fsp->conn,
+                       fsp->fsp_name->base_name,
+                       uid, gid);
+       }
+       if (ret == 0) {
+               return NT_STATUS_OK;
+       }
+       return map_nt_error_from_unix(errno);
+}
+
 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
 {
        VFS_FIND(chdir);