s4:kdc: Implement KDC plugin hardware authentication policy
[samba.git] / source3 / modules / vfs_default.c
index dee8ff50df4fe432ad8c1aa23b0ea2289888aff0..48b5dd9e39f46b178ba734651a8cf25242839358 100644 (file)
 
 static int vfswrap_connect(vfs_handle_struct *handle, const char *service, const char *user)
 {
+       bool bval;
+
        handle->conn->have_proc_fds = sys_have_proc_fds();
+#ifdef DISABLE_PROC_FDS
+       handle->conn->have_proc_fds = false;
+#endif
+
+       /*
+        * assume the kernel will support openat2(),
+        * it will be reset on the first ENOSYS.
+        *
+        * Note that libreplace will always provide openat2(),
+        * but return -1/errno = ENOSYS...
+        *
+        * The option is only there to test the fallback code.
+        */
+       bval = lp_parm_bool(SNUM(handle->conn),
+                           "vfs_default",
+                           "VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS",
+                           true);
+       if (bval) {
+               handle->conn->open_how_resolve |=
+                       VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS;
+       }
+#ifdef DISABLE_VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS
+       handle->conn->open_how_resolve &= ~VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS;
+#endif
+
        return 0;    /* Return >= 0 for success */
 }
 
@@ -179,12 +206,12 @@ static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
                *p_ts_res = TIMESTAMP_SET_SECONDS;
 #endif
 
-               DEBUG(10,("vfswrap_fs_capabilities: timestamp "
+               DBG_DEBUG("vfswrap_fs_capabilities: timestamp "
                        "resolution of %s "
                        "available on share %s, directory %s\n",
                        *p_ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec",
                        lp_servicename(talloc_tos(), lp_sub, conn->params->service),
-                       conn->connectpath ));
+                       conn->connectpath );
        }
        TALLOC_FREE(smb_fname_cpath);
        return caps;
@@ -202,7 +229,7 @@ static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle,
        size_t i;
        uint16_t max_referral_level = r->in.req.max_referral_level;
 
-       if (DEBUGLVL(10)) {
+       if (DEBUGLVL(DBGLVL_DEBUG)) {
                NDR_PRINT_IN_DEBUG(dfs_GetDFSReferral, r);
        }
 
@@ -237,7 +264,6 @@ static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle,
                                   pathnamep,
                                   handle->conn->sconn->remote_address,
                                   handle->conn->sconn->local_address,
-                                  !handle->conn->sconn->using_smb2,
                                   junction, &consumedcnt, &self_referral);
        if (!NT_STATUS_IS_OK(status)) {
                struct smb_filename connectpath_fname = {
@@ -256,7 +282,7 @@ static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle,
        if (!self_referral) {
                pathnamep[consumedcnt] = '\0';
 
-               if (DEBUGLVL(3)) {
+               if (DEBUGLVL(DBGLVL_INFO)) {
                        dbgtext("Path %s to alternate path(s):",
                                pathnamep);
                        for (i=0; i < junction->referral_count; i++) {
@@ -363,12 +389,12 @@ static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle,
                }
                break;
        default:
-               DEBUG(0,("Invalid dfs referral version: %d\n",
-                       max_referral_level));
+               DBG_ERR("Invalid dfs referral version: %d\n",
+                       max_referral_level);
                return NT_STATUS_INVALID_LEVEL;
        }
 
-       if (DEBUGLVL(10)) {
+       if (DEBUGLVL(DBGLVL_DEBUG)) {
                NDR_PRINT_OUT_DEBUG(dfs_GetDFSReferral, r);
        }
 
@@ -574,58 +600,17 @@ static DIR *vfswrap_fdopendir(vfs_handle_struct *handle,
        return result;
 }
 
-
 static struct dirent *vfswrap_readdir(vfs_handle_struct *handle,
                                      struct files_struct *dirfsp,
-                                     DIR *dirp,
-                                     SMB_STRUCT_STAT *sbuf)
+                                     DIR *dirp)
 {
        struct dirent *result;
-       bool fake_ctime = lp_fake_directory_create_times(SNUM(handle->conn));
-       int flags = AT_SYMLINK_NOFOLLOW;
-       SMB_STRUCT_STAT st;
-       int ret;
 
        START_PROFILE(syscall_readdir);
 
        result = readdir(dirp);
        END_PROFILE(syscall_readdir);
 
-       if (sbuf == NULL) {
-               return result;
-       }
-       if (result == NULL) {
-               return NULL;
-       }
-
-       /*
-        * Default Posix readdir() does not give us stat info.
-        * Set to invalid to indicate we didn't return this info.
-        */
-       SET_STAT_INVALID(*sbuf);
-
-       ret = sys_fstatat(dirfd(dirp),
-                     result->d_name,
-                     &st,
-                     flags,
-                     fake_ctime);
-       if (ret != 0) {
-               return result;
-       }
-
-       /*
-        * As this is an optimization, ignore it if we stat'ed a
-        * symlink for non-POSIX context. Make the caller do it again
-        * as we don't know if they wanted the link info, or its
-        * target info.
-        */
-       if (S_ISLNK(st.st_ex_mode) &&
-           !(dirfsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH))
-       {
-               return result;
-       }
-       *sbuf = st;
-
        return result;
 }
 
@@ -637,22 +622,6 @@ static NTSTATUS vfswrap_freaddir_attr(struct vfs_handle_struct *handle,
        return NT_STATUS_NOT_SUPPORTED;
 }
 
-static void vfswrap_seekdir(vfs_handle_struct *handle, DIR *dirp, long offset)
-{
-       START_PROFILE(syscall_seekdir);
-       seekdir(dirp, offset);
-       END_PROFILE(syscall_seekdir);
-}
-
-static long vfswrap_telldir(vfs_handle_struct *handle, DIR *dirp)
-{
-       long result;
-       START_PROFILE(syscall_telldir);
-       result = telldir(dirp);
-       END_PROFILE(syscall_telldir);
-       return result;
-}
-
 static void vfswrap_rewinddir(vfs_handle_struct *handle, DIR *dirp)
 {
        START_PROFILE(syscall_rewinddir);
@@ -701,7 +670,8 @@ static int vfswrap_openat(vfs_handle_struct *handle,
 
        START_PROFILE(syscall_openat);
 
-       if (how->resolve != 0) {
+       if (how->resolve & ~(VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS |
+                            VFS_OPEN_HOW_WITH_BACKUP_INTENT)) {
                errno = ENOSYS;
                result = -1;
                goto out;
@@ -714,8 +684,55 @@ static int vfswrap_openat(vfs_handle_struct *handle,
        if (fsp->fsp_flags.is_pathref) {
                flags |= O_PATH;
        }
+       if (flags & O_PATH) {
+               /*
+                * From "man 2 openat":
+                *
+                *   When O_PATH is specified in flags, flag bits other than
+                *   O_CLOEXEC, O_DIRECTORY, and O_NOFOLLOW are ignored.
+                *
+                * From "man 2 openat2":
+                *
+                *   Whereas  openat(2)  ignores  unknown  bits  in  its  flags
+                *   argument, openat2() returns an error if unknown or
+                *   conflicting flags are specified in how.flags.
+                *
+                * So we better clear ignored/invalid flags
+                * and only keep the expected ones.
+                */
+               flags &= (O_PATH|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
+       }
 #endif
 
+       if (how->resolve & VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS) {
+               struct open_how linux_how = {
+                       .flags = flags,
+                       .mode = mode,
+                       .resolve = RESOLVE_NO_SYMLINKS,
+               };
+
+               result = openat2(fsp_get_pathref_fd(dirfsp),
+                                smb_fname->base_name,
+                                &linux_how,
+                                sizeof(linux_how));
+               if (result == -1) {
+                       if (errno == ENOSYS) {
+                               /*
+                                * The kernel doesn't support
+                                * openat2(), so indicate to
+                                * the callers that
+                                * VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS
+                                * would just be a waste of time.
+                                */
+                               fsp->conn->open_how_resolve &=
+                                       ~VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS;
+                       }
+                       goto out;
+               }
+
+               goto done;
+       }
+
        if (fsp->fsp_flags.is_pathref && !have_opath) {
                become_root();
                became_root = true;
@@ -727,10 +744,22 @@ static int vfswrap_openat(vfs_handle_struct *handle,
                        mode);
 
        if (became_root) {
+               int err = errno;
                unbecome_root();
+               errno = err;
        }
 
-       fsp->fsp_flags.have_proc_fds = fsp->conn->have_proc_fds;
+done:
+       if (result >= 0) {
+               fsp->fsp_flags.have_proc_fds = fsp->conn->have_proc_fds;
+       } else {
+               /*
+                * "/proc/self/fd/-1" never exists. Indicate to upper
+                * layers that for this fsp a possible name-based
+                * fallback is the only way to go.
+                */
+               fsp->fsp_flags.have_proc_fds = false;
+       }
 
 out:
        END_PROFILE(syscall_openat);
@@ -1354,14 +1383,12 @@ static NTSTATUS vfswrap_parent_pathname(struct vfs_handle_struct *handle,
                                        struct smb_filename **parent_dir_out,
                                        struct smb_filename **atname_out)
 {
-       TALLOC_CTX *frame = talloc_stackframe();
        struct smb_filename *parent = NULL;
        struct smb_filename *name = NULL;
        char *p = NULL;
 
-       parent = cp_smb_filename_nostream(frame, smb_fname_in);
+       parent = cp_smb_filename_nostream(mem_ctx, smb_fname_in);
        if (parent == NULL) {
-               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
        }
        SET_STAT_INVALID(parent->st);
@@ -1371,7 +1398,7 @@ static NTSTATUS vfswrap_parent_pathname(struct vfs_handle_struct *handle,
                TALLOC_FREE(parent->base_name);
                parent->base_name = talloc_strdup(parent, ".");
                if (parent->base_name == NULL) {
-                       TALLOC_FREE(frame);
+                       TALLOC_FREE(parent);
                        return NT_STATUS_NO_MEMORY;
                }
                p = smb_fname_in->base_name;
@@ -1381,27 +1408,23 @@ static NTSTATUS vfswrap_parent_pathname(struct vfs_handle_struct *handle,
        }
 
        if (atname_out == NULL) {
-               *parent_dir_out = talloc_move(mem_ctx, &parent);
-               TALLOC_FREE(frame);
+               *parent_dir_out = parent;
                return NT_STATUS_OK;
        }
 
-       name = cp_smb_filename(frame, smb_fname_in);
+       name = synthetic_smb_fname(
+               parent,
+               p,
+               smb_fname_in->stream_name,
+               &smb_fname_in->st,
+               smb_fname_in->twrp,
+               smb_fname_in->flags);
        if (name == NULL) {
-               TALLOC_FREE(frame);
-               return NT_STATUS_NO_MEMORY;
-       }
-       TALLOC_FREE(name->base_name);
-
-       name->base_name = talloc_strdup(name, p);
-       if (name->base_name == NULL) {
-               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
        }
 
-       *parent_dir_out = talloc_move(mem_ctx, &parent);
-       *atname_out = talloc_move(*parent_dir_out, &name);
-       TALLOC_FREE(frame);
+       *parent_dir_out = parent;
+       *atname_out = name;
        return NT_STATUS_OK;
 }
 
@@ -1425,7 +1448,13 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
        char **out_data = (char **)_out_data;
        NTSTATUS status;
 
-       SMB_ASSERT(!fsp_is_alternate_stream(fsp));
+       /*
+        * Currently all fsctls operate on the base
+        * file if given an alternate data stream.
+        * Revisit this if we implement fsctls later
+        * that need access to the ADS handle.
+        */
+       fsp = metadata_fsp(fsp);
 
        switch (function) {
        case FSCTL_SET_SPARSE:
@@ -1449,19 +1478,19 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
        case FSCTL_CREATE_OR_GET_OBJECT_ID:
        {
                unsigned char objid[16];
-               char *return_data = NULL;
+               uint8_t *return_data = NULL;
 
                /* This should return the object-id on this file.
                 * I think I'll make this be the inode+dev. JRA.
                 */
 
-               DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on %s\n",
-                         fsp_fnum_dbg(fsp)));
+               DBG_DEBUG("FSCTL_CREATE_OR_GET_OBJECT_ID: called on %s\n",
+                         fsp_fnum_dbg(fsp));
 
                *out_len = MIN(max_out_len, 64);
 
                /* Hmmm, will this cause problems if less data asked for? */
-               return_data = talloc_array(ctx, char, 64);
+               return_data = talloc_array(ctx, uint8_t, 64);
                if (return_data == NULL) {
                        return NT_STATUS_NO_MEMORY;
                }
@@ -1469,16 +1498,17 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                /* For backwards compatibility only store the dev/inode. */
                push_file_id_16(return_data, &fsp->file_id);
                memcpy(return_data+16,create_volume_objectid(fsp->conn,objid),16);
-               push_file_id_16(return_data+32, &fsp->file_id);
+               push_file_id_16(return_data + 32, &fsp->file_id);
                memset(return_data+48, 0, 16);
-               *out_data = return_data;
+               *_out_data = return_data;
                return NT_STATUS_OK;
        }
 
        case FSCTL_GET_REPARSE_POINT:
        {
+               uint32_t tag;
                status = fsctl_get_reparse_point(
-                       fsp, ctx, out_data, max_out_len, out_len);
+                       fsp, ctx, &tag, _out_data, max_out_len, out_len);
                return status;
        }
 
@@ -1513,8 +1543,8 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                char *cur_pdata = NULL;
 
                if (max_out_len < 16) {
-                       DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
-                               max_out_len));
+                       DBG_ERR("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
+                               max_out_len);
                        return NT_STATUS_INVALID_PARAMETER;
                }
 
@@ -1524,7 +1554,7 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
 
                shadow_data = talloc_zero(ctx, struct shadow_copy_data);
                if (shadow_data == NULL) {
-                       DEBUG(0,("TALLOC_ZERO() failed!\n"));
+                       DBG_ERR("TALLOC_ZERO() failed!\n");
                        return NT_STATUS_NO_MEMORY;
                }
 
@@ -1532,7 +1562,7 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                 * Call the VFS routine to actually do the work.
                 */
                if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
-                       int log_lev = 0;
+                       int log_lev = DBGLVL_ERR;
                        if (errno == 0) {
                                /* broken module didn't set errno on error */
                                status = NT_STATUS_UNSUCCESSFUL;
@@ -1540,7 +1570,7 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                                status = map_nt_error_from_unix(errno);
                                if (NT_STATUS_EQUAL(status,
                                                    NT_STATUS_NOT_SUPPORTED)) {
-                                       log_lev = 5;
+                                       log_lev = DBGLVL_INFO;
                                }
                        }
                        DEBUG(log_lev, ("FSCTL_GET_SHADOW_COPY_DATA: "
@@ -1561,8 +1591,8 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                }
 
                if (max_out_len < *out_len) {
-                       DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
-                               max_out_len, *out_len));
+                       DBG_ERR("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
+                               max_out_len, *out_len);
                        TALLOC_FREE(shadow_data);
                        return NT_STATUS_BUFFER_TOO_SMALL;
                }
@@ -1588,8 +1618,8 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
 
                cur_pdata += 12;
 
-               DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
-                         shadow_data->num_volumes, fsp_str_dbg(fsp)));
+               DBG_DEBUG("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
+                         shadow_data->num_volumes, fsp_str_dbg(fsp));
                if (labels && shadow_data->labels) {
                        for (i=0; i<shadow_data->num_volumes; i++) {
                                size_t len = 0;
@@ -1603,7 +1633,7 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                                        return status;
                                }
                                cur_pdata += 2 * sizeof(SHADOW_COPY_LABEL);
-                               DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
+                               DEBUGADD(DBGLVL_DEBUG,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
                        }
                }
 
@@ -1626,8 +1656,8 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                uid_t uid;
                size_t sid_len;
 
-               DEBUG(10, ("FSCTL_FIND_FILES_BY_SID: called on %s\n",
-                          fsp_fnum_dbg(fsp)));
+               DBG_DEBUG("FSCTL_FIND_FILES_BY_SID: called on %s\n",
+                          fsp_fnum_dbg(fsp));
 
                if (in_len < 8) {
                        /* NT_STATUS_BUFFER_TOO_SMALL maybe? */
@@ -1643,13 +1673,13 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                if (ret == -1) {
                        return NT_STATUS_INVALID_PARAMETER;
                }
-               DEBUGADD(10, ("for SID: %s\n",
+               DEBUGADD(DBGLVL_DEBUG, ("for SID: %s\n",
                              dom_sid_str_buf(&sid, &buf)));
 
                if (!sid_to_uid(&sid, &uid)) {
-                       DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
+                       DBG_ERR("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
                                 dom_sid_str_buf(&sid, &buf),
-                                (unsigned long)sid_len));
+                                (unsigned long)sid_len);
                        uid = (-1);
                }
 
@@ -1690,14 +1720,14 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                char *out_data_tmp = NULL;
 
                if (in_len != 16) {
-                       DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
-                               in_len));
+                       DBG_ERR("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
+                               in_len);
                        return NT_STATUS_INVALID_PARAMETER;
                }
 
                if (max_out_len < 16) {
-                       DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n",
-                               max_out_len));
+                       DBG_ERR("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n",
+                               max_out_len);
                        return NT_STATUS_INVALID_PARAMETER;
                }
 
@@ -1718,7 +1748,7 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                *out_len = 16;
                out_data_tmp = talloc_array(ctx, char, *out_len);
                if (out_data_tmp == NULL) {
-                       DEBUG(10, ("unable to allocate memory for response\n"));
+                       DBG_DEBUG("unable to allocate memory for response\n");
                        return NT_STATUS_NO_MEMORY;
                }
 
@@ -1740,8 +1770,8 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
 
        case FSCTL_IS_VOLUME_DIRTY:
        {
-               DEBUG(10,("FSCTL_IS_VOLUME_DIRTY: called on %s "
-                         "(but remotely not supported)\n", fsp_fnum_dbg(fsp)));
+               DBG_DEBUG("FSCTL_IS_VOLUME_DIRTY: called on %s "
+                         "(but remotely not supported)\n", fsp_fnum_dbg(fsp));
                /*
                 * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx
                 * says we have to respond with NT_STATUS_INVALID_PARAMETER
@@ -1756,8 +1786,8 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                 */
                if (!vfswrap_logged_ioctl_message) {
                        vfswrap_logged_ioctl_message = true;
-                       DEBUG(2, ("%s (0x%x): Currently not implemented.\n",
-                       __func__, function));
+                       DBG_NOTICE("%s (0x%x): Currently not implemented.\n",
+                       __func__, function);
                }
        }
 
@@ -2665,15 +2695,10 @@ static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t m
 
        if (fsp->fsp_flags.have_proc_fds) {
                int fd = fsp_get_pathref_fd(fsp);
-               const char *p = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
+
+               result = chmod(sys_proc_fd_path(fd, &buf), mode);
 
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p != NULL) {
-                       result = chmod(p, mode);
-               } else {
-                       result = -1;
-               }
                END_PROFILE(syscall_fchmod);
                return result;
        }
@@ -2701,15 +2726,10 @@ static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t ui
 
        if (fsp->fsp_flags.have_proc_fds) {
                int fd = fsp_get_pathref_fd(fsp);
-               const char *p = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
+
+               result = chown(sys_proc_fd_path(fd, &buf), uid, gid);
 
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p != NULL) {
-                       result = chown(p, uid, gid);
-               } else {
-                       result = -1;
-               }
                END_PROFILE(syscall_fchown);
                return result;
        }
@@ -2834,19 +2854,12 @@ static int vfswrap_fntimes(vfs_handle_struct *handle,
 
        if (fsp->fsp_flags.have_proc_fds) {
                int fd = fsp_get_pathref_fd(fsp);
-               const char *p = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
 
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p != NULL) {
-                       /*
-                        * The dirfd argument of utimensat is ignored when
-                        * pathname is an absolute path
-                        */
-                       result = utimensat(AT_FDCWD, p, times, 0);
-               } else {
-                       result = -1;
-               }
+               result = utimensat(AT_FDCWD,
+                                  sys_proc_fd_path(fd, &buf),
+                                  times,
+                                  0);
 
                goto out;
        }
@@ -2917,8 +2930,8 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
        if (ret == 0) {
                return 0;
        }
-       DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
-               "error %d. Falling back to slow manual allocation\n", errno));
+       DBG_DEBUG("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
+               "error %d. Falling back to slow manual allocation\n", errno);
 
        /* available disk space is enough or not? */
        space_avail =
@@ -3262,15 +3275,9 @@ static int vfswrap_fchflags(vfs_handle_struct *handle,
        }
 
        if (fsp->fsp_flags.have_proc_fds) {
-               const char *p = NULL;
-               char buf[PATH_MAX];
-
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return -1;
-               }
+               struct sys_proc_fd_path_buf buf;
 
-               return chflags(p, flags);
+               return chflags(sys_proc_fd_path(fd, &buf), flags);
        }
 
        /*
@@ -3385,6 +3392,7 @@ static NTSTATUS vfswrap_get_real_filename_at(
 }
 
 static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
+                                  const struct files_struct *dirfsp,
                                   const struct smb_filename *smb_fname)
 {
        return handle->conn->connectpath;
@@ -3508,15 +3516,9 @@ static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle,
        }
 
        if (fsp->fsp_flags.have_proc_fds) {
-               const char *p = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
 
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return -1;
-               }
-
-               return getxattr(p, name, value, size);
+               return getxattr(sys_proc_fd_path(fd, &buf), name, value, size);
        }
 
        /*
@@ -3626,7 +3628,7 @@ static struct tevent_req *vfswrap_getxattrat_send(
 
        /*
         * Now allocate all parameters from a memory context that won't go away
-        * no matter what. These paremeters will get used in threads and we
+        * no matter what. These parameters will get used in threads and we
         * can't reliably cancel threads, so all buffers passed to the threads
         * must not be freed before all referencing threads terminate.
         */
@@ -3834,15 +3836,9 @@ static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files
        }
 
        if (fsp->fsp_flags.have_proc_fds) {
-               const char *p = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
 
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return -1;
-               }
-
-               return listxattr(p, list, size);
+               return listxattr(sys_proc_fd_path(fd, &buf), list, size);
        }
 
        /*
@@ -3862,15 +3858,9 @@ static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_s
        }
 
        if (fsp->fsp_flags.have_proc_fds) {
-               const char *p = NULL;
-               char buf[PATH_MAX];
-
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return -1;
-               }
+               struct sys_proc_fd_path_buf buf;
 
-               return removexattr(p, name);
+               return removexattr(sys_proc_fd_path(fd, &buf), name);
        }
 
        /*
@@ -3890,15 +3880,13 @@ static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_stru
        }
 
        if (fsp->fsp_flags.have_proc_fds) {
-               const char *p = NULL;
-               char buf[PATH_MAX];
-
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return -1;
-               }
+               struct sys_proc_fd_path_buf buf;
 
-               return setxattr(p, name, value, size, flags);
+               return setxattr(sys_proc_fd_path(fd, &buf),
+                               name,
+                               value,
+                               size,
+                               flags);
        }
 
        /*
@@ -3997,8 +3985,6 @@ static struct vfs_fn_pointers vfs_default_fns = {
        .fdopendir_fn = vfswrap_fdopendir,
        .readdir_fn = vfswrap_readdir,
        .freaddir_attr_fn = vfswrap_freaddir_attr,
-       .seekdir_fn = vfswrap_seekdir,
-       .telldir_fn = vfswrap_telldir,
        .rewind_dir_fn = vfswrap_rewinddir,
        .mkdirat_fn = vfswrap_mkdirat,
        .closedir_fn = vfswrap_closedir,