From: Ralph Boehme Date: Thu, 14 May 2020 19:20:22 +0000 (+0200) Subject: smbd: add fd_openat() X-Git-Tag: ldb-2.2.0~366 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eaf1c6a338a6253068fc3e671605f18c71565dbb;p=thirdparty%2Fsamba.git smbd: add fd_openat() Until we actually start passing real dirfsps to fd_openat(), fd_openat() internally calls fd_open(). Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- diff --git a/source3/smbd/open.c b/source3/smbd/open.c index cbcebe71e73..a1d5f4b0c91 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -836,6 +836,70 @@ NTSTATUS fd_open(files_struct *fsp, 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. ****************************************************************************/ diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 3a0b25f021b..eeb6fcbf3d6 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -724,6 +724,9 @@ NTSTATUS check_parent_access(struct connection_struct *conn, 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,