return status;
}
+NTSTATUS fd_openat(files_struct *fsp,
+ int flags,
+ mode_t mode)
+{
+ NTSTATUS status = NT_STATUS_OK;
+ int saved_errno = 0;
+
+ if (fsp->dirfsp == fsp->conn->cwd_fsp) {
+ return fd_open(fsp, flags, mode);
+ }
+
+ /*
+ * Never follow symlinks at this point, filename_convert() should have
+ * resolved any symlink.
+ */
+
+ flags |= O_NOFOLLOW;
+
+ /*
+ * Only follow symlinks within a share
+ * definition.
+ */
+ fsp->fh->fd = SMB_VFS_OPENAT(fsp->conn,
+ fsp->dirfsp,
+ fsp->fsp_name,
+ fsp,
+ flags,
+ mode);
+ if (fsp->fh->fd == -1) {
+ saved_errno = errno;
+ }
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
+
+ if (fsp->fh->fd == -1) {
+ int posix_errno = link_errno_convert(errno);
+
+ status = map_nt_error_from_unix(posix_errno);
+
+ if (errno == EMFILE) {
+ static time_t last_warned = 0L;
+
+ if (time((time_t *) NULL) > last_warned) {
+ DEBUG(0,("Too many open files, unable "
+ "to open more! smbd's max "
+ "open files = %d\n",
+ lp_max_open_files()));
+ last_warned = time((time_t *) NULL);
+ }
+ }
+
+ DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
+ fsp_str_dbg(fsp), flags, (int)mode,
+ fsp->fh->fd, strerror(errno));
+ return status;
+ }
+
+ DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
+ fsp_str_dbg(fsp), flags, (int)mode, fsp->fh->fd);
+
+ return status;
+}
+
/****************************************************************************
Close the file associated with a fsp.
****************************************************************************/
uint32_t access_mask);
NTSTATUS fd_open(files_struct *fsp,
int flags, mode_t mode);
+NTSTATUS fd_openat(files_struct *fsp,
+ int flags,
+ mode_t mode);
NTSTATUS fd_close(files_struct *fsp);
void change_file_owner_to_parent(connection_struct *conn,
struct smb_filename *inherit_from_dir,