]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Pass vfs_open_how through fd_openat
authorVolker Lendecke <vl@samba.org>
Fri, 17 Jun 2022 08:39:20 +0000 (10:39 +0200)
committerJeremy Allison <jra@samba.org>
Sat, 6 Aug 2022 01:43:50 +0000 (01:43 +0000)
Pair-programmed-with: Stefan Metzmacher <metze@samba.org>

Signed-off-by: Volker Lendecke <vl@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/lib/adouble.c
source3/smbd/durable.c
source3/smbd/files.c
source3/smbd/open.c
source3/smbd/proto.h
source3/smbd/smb2_query_directory.c

index b831464f5a96f096fc607a2b7a1eeb0e2e16538e..062c73ec75889188582e81bc09e2ef3b5fde6373 100644 (file)
@@ -2199,7 +2199,7 @@ static NTSTATUS adouble_open_rsrc_fsp(const struct files_struct *dirfsp,
        struct smb_filename *adp_smb_fname = NULL;
        struct files_struct *ad_fsp = NULL;
        NTSTATUS status;
-       int flags = in_flags;
+       struct vfs_open_how how = { .flags = in_flags, .mode = mode, };
 
        rc = adouble_path(talloc_tos(),
                          smb_base_fname,
@@ -2216,25 +2216,24 @@ static NTSTATUS adouble_open_rsrc_fsp(const struct files_struct *dirfsp,
        }
 
 #ifdef O_PATH
-       flags &= ~(O_PATH);
+       how.flags &= ~(O_PATH);
 #endif
-       if (flags & (O_CREAT | O_TRUNC | O_WRONLY)) {
+       if (how.flags & (O_CREAT | O_TRUNC | O_WRONLY)) {
                /* We always need read/write access for the metadata header too */
-               flags &= ~(O_WRONLY);
-               flags |= O_RDWR;
+               how.flags &= ~(O_WRONLY);
+               how.flags |= O_RDWR;
        }
 
        status = fd_openat(dirfsp,
                           adp_smb_fname,
                           ad_fsp,
-                          flags,
-                          mode);
+                          &how);
        if (!NT_STATUS_IS_OK(status)) {
                file_free(NULL, ad_fsp);
                return status;
        }
 
-       if (flags & (O_CREAT | O_TRUNC)) {
+       if (how.flags & (O_CREAT | O_TRUNC)) {
                ad = ad_init(talloc_tos(), ADOUBLE_RSRC);
                if (ad == NULL) {
                        file_free(NULL, ad_fsp);
index 838a5ddef055e16c3f23940aff23060ee096a89a..b21c223b2e4466e9523f8fdbda4f60c3d3c3d5bc 100644 (file)
@@ -532,7 +532,7 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
        NTSTATUS status;
        bool ok;
        int ret;
-       int flags = 0;
+       struct vfs_open_how how = { .flags = 0, };
        struct file_id file_id;
        struct smb_filename *smb_fname = NULL;
        enum ndr_err_code ndr_err;
@@ -804,14 +804,14 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
         * TODO: properly calculate open flags
         */
        if (fsp->fsp_flags.can_write && fsp->fsp_flags.can_read) {
-               flags = O_RDWR;
+               how.flags = O_RDWR;
        } else if (fsp->fsp_flags.can_write) {
-               flags = O_WRONLY;
+               how.flags = O_WRONLY;
        } else if (fsp->fsp_flags.can_read) {
-               flags = O_RDONLY;
+               how.flags = O_RDONLY;
        }
 
-       status = fd_openat(conn->cwd_fsp, fsp->fsp_name, fsp, flags, 0);
+       status = fd_openat(conn->cwd_fsp, fsp->fsp_name, fsp, &how);
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(lck);
                DEBUG(1, ("vfs_default_durable_reconnect: failed to open "
index 2f9d92382e593b9c154d46482627c0db7940848b..09ca7740c1414499c897f76f2703cfa05be87103 100644 (file)
@@ -241,9 +241,10 @@ NTSTATUS create_internal_dirfsp(connection_struct *conn,
  */
 NTSTATUS open_internal_dirfsp(connection_struct *conn,
                              const struct smb_filename *smb_dname,
-                             int open_flags,
+                             int _open_flags,
                              struct files_struct **_fsp)
 {
+       struct vfs_open_how how = { .flags = _open_flags, };
        struct files_struct *fsp = NULL;
        NTSTATUS status;
 
@@ -253,9 +254,9 @@ NTSTATUS open_internal_dirfsp(connection_struct *conn,
        }
 
 #ifdef O_DIRECTORY
-       open_flags |= O_DIRECTORY;
+       how.flags |= O_DIRECTORY;
 #endif
-       status = fd_openat(conn->cwd_fsp, fsp->fsp_name, fsp, open_flags, 0);
+       status = fd_openat(conn->cwd_fsp, fsp->fsp_name, fsp, &how);
        if (!NT_STATUS_IS_OK(status)) {
                DBG_INFO("Could not open fd for %s (%s)\n",
                         smb_fname_str_dbg(smb_dname),
@@ -289,7 +290,7 @@ NTSTATUS open_internal_dirfsp(connection_struct *conn,
  */
 NTSTATUS openat_internal_dir_from_pathref(
        struct files_struct *dirfsp,
-       int open_flags,
+       int _open_flags,
        struct files_struct **_fsp)
 {
        struct connection_struct *conn = dirfsp->conn;
@@ -301,6 +302,7 @@ NTSTATUS openat_internal_dir_from_pathref(
                .flags = smb_dname->flags,
                .twrp = smb_dname->twrp,
        };
+       struct vfs_open_how how = { .flags = _open_flags, };
        NTSTATUS status;
 
        status = create_internal_dirfsp(conn, smb_dname, &fsp);
@@ -311,9 +313,9 @@ NTSTATUS openat_internal_dir_from_pathref(
        /*
         * Pointless for opening ".", but you never know...
         */
-       open_flags |= O_NOFOLLOW;
+       how.flags |= O_NOFOLLOW;
 
-       status = fd_openat(dirfsp, &smb_dot, fsp, open_flags, 0);
+       status = fd_openat(dirfsp, &smb_dot, fsp, &how);
        if (!NT_STATUS_IS_OK(status)) {
                DBG_INFO("fd_openat(\"%s\", \".\") failed: %s\n",
                         fsp_str_dbg(dirfsp),
@@ -451,6 +453,7 @@ static NTSTATUS openat_pathref_fullname(
        struct files_struct *fsp = NULL;
        bool have_dirfsp = (dirfsp != NULL);
        bool have_basefsp = (basefsp != NULL);
+       struct vfs_open_how how = { .flags = O_RDONLY|O_NONBLOCK, };
        NTSTATUS status;
 
        DBG_DEBUG("smb_fname [%s]\n", smb_fname_str_dbg(smb_fname));
@@ -475,8 +478,7 @@ static NTSTATUS openat_pathref_fullname(
        }
        fsp_set_base_fsp(fsp, basefsp);
 
-       status = fd_openat(
-               dirfsp, smb_fname, fsp, O_RDONLY|O_NONBLOCK, 0);
+       status = fd_openat(dirfsp, smb_fname, fsp, &how);
        if (!NT_STATUS_IS_OK(status)) {
 
                smb_fname->st = fsp->fsp_name->st;
index 047a8c488c6cd7d53b62fa3fb152b225921e08e5..d39d2d619cd0766b510b1e7339ac4c91d0d38d01 100644 (file)
@@ -887,10 +887,9 @@ static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
 NTSTATUS fd_openat(const struct files_struct *dirfsp,
                   struct smb_filename *smb_fname,
                   files_struct *fsp,
-                  int _flags,
-                  mode_t _mode)
+                  const struct vfs_open_how *_how)
 {
-       struct vfs_open_how how = { .flags = _flags, .mode = _mode, };
+       struct vfs_open_how how = *_how;
        struct connection_struct *conn = fsp->conn;
        NTSTATUS status = NT_STATUS_OK;
        bool fsp_is_stream = fsp_is_alternate_stream(fsp);
@@ -1105,25 +1104,25 @@ static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
                               mode_t mode,
                               bool *file_created)
 {
+       struct vfs_open_how how = { .flags = flags, .mode = mode, };
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
        NTSTATUS retry_status;
        bool file_existed = VALID_STAT(smb_fname->st);
-       int curr_flags;
 
-       if (!(flags & O_CREAT)) {
+       if (!(how.flags & O_CREAT)) {
                /*
                 * We're not creating the file, just pass through.
                 */
-               status = fd_openat(dirfsp, smb_fname, fsp, flags, mode);
+               status = fd_openat(dirfsp, smb_fname, fsp, &how);
                *file_created = false;
                return status;
        }
 
-       if (flags & O_EXCL) {
+       if (how.flags & O_EXCL) {
                /*
                 * Fail if already exists, just pass through.
                 */
-               status = fd_openat(dirfsp, smb_fname, fsp, flags, mode);
+               status = fd_openat(dirfsp, smb_fname, fsp, &how);
 
                /*
                 * Here we've opened with O_CREAT|O_EXCL. If that went
@@ -1156,14 +1155,14 @@ static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
         */
 
        if (file_existed) {
-               curr_flags = flags & ~(O_CREAT);
+               how.flags = flags & ~(O_CREAT);
                retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
        } else {
-               curr_flags = flags | O_EXCL;
+               how.flags = flags | O_EXCL;
                retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
        }
 
-       status = fd_openat(dirfsp, smb_fname, fsp, curr_flags, mode);
+       status = fd_openat(dirfsp, smb_fname, fsp, &how);
        if (NT_STATUS_IS_OK(status)) {
                *file_created = !file_existed;
                return NT_STATUS_OK;
@@ -1177,12 +1176,12 @@ static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
                          file_existed ? "existed" : "did not exist");
 
                if (file_existed) {
-                       curr_flags = flags & ~(O_CREAT);
+                       how.flags = flags & ~(O_CREAT);
                } else {
-                       curr_flags = flags | O_EXCL;
+                       how.flags = flags | O_EXCL;
                }
 
-               status = fd_openat(dirfsp, smb_fname, fsp, curr_flags, mode);
+               status = fd_openat(dirfsp, smb_fname, fsp, &how);
        }
 
        *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
@@ -4281,6 +4280,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
        bool posix_open = false;
        bool need_re_stat = false;
        uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
+       struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
        int ret;
 
        if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
@@ -4329,7 +4329,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
         */
        fsp->fsp_flags.is_pathref = true;
 
-       status = fd_openat(conn->cwd_fsp, smb_dname, fsp, O_RDONLY | O_DIRECTORY, 0);
+       status = fd_openat(conn->cwd_fsp, smb_dname, fsp, &how);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
index daef19f13f7da7f7bfcb98e18c3f0fcaf54b9463..ceee52d79cd3d7ae1e3486328b95c3d05e21d6a0 100644 (file)
@@ -731,7 +731,7 @@ NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
 NTSTATUS fd_openat(const struct files_struct *dirfsp,
                   struct smb_filename *smb_fname,
                   files_struct *fsp,
-                  int flags, mode_t mode);
+                  const struct vfs_open_how *how);
 NTSTATUS fd_close(files_struct *fsp);
 bool is_oplock_stat_open(uint32_t access_mask);
 bool is_lease_stat_open(uint32_t access_mask);
index 3ed1c413c5bb68f30401be87b6acbcc63541b2f9..74cb049ad40bf25e7b4d46d965864a5e1441346f 100644 (file)
@@ -372,7 +372,7 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx,
        }
 
        if (in_flags & SMB2_CONTINUE_FLAG_REOPEN) {
-               int flags;
+               struct vfs_open_how how = { .flags = O_RDONLY, };
 
                status = fd_close(fsp);
                if (tevent_req_nterror(req, status)) {
@@ -384,11 +384,10 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx,
                 * descriptor. So we have to reopen it.
                 */
 
-               flags = O_RDONLY;
 #ifdef O_DIRECTORY
-               flags |= O_DIRECTORY;
+               how.flags |= O_DIRECTORY;
 #endif
-               status = fd_openat(conn->cwd_fsp, fsp->fsp_name, fsp, flags, 0);
+               status = fd_openat(conn->cwd_fsp, fsp->fsp_name, fsp, &how);
                if (tevent_req_nterror(req, status)) {
                        return tevent_req_post(req, ev);
                }