]> git.samba.org - samba.git/commitdiff
vfs: change openat propotype to match linux openat2
authorVolker Lendecke <vl@samba.org>
Fri, 3 Jun 2022 13:53:29 +0000 (15:53 +0200)
committerJeremy Allison <jra@samba.org>
Sat, 6 Aug 2022 01:43:50 +0000 (01:43 +0000)
The Linux prototype for openat2 looks like this:

       long openat2(int dirfd, const char *pathname,
                   struct open_how *how, size_t size);

where "struct open_how" is defined in "linux/openat2.h". It is
designed to be extensible with further flags.

The "size" parameter is required because there is no type checking
between userland and kernelspace, so the way for Linux to find which
version of open_how is being passed in is looking at the size:
"open_how" is expected to only every grow with additional fields,
should a change be necessary in the future.

Samba does not have this problem, we can typecheck the struct and
pointers, we expect all VFS modules to be compiled against the current
vfs.h.

For now this adds no functionality, but it will make further patches
much smaller.

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>
37 files changed:
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/vfs.h
source3/include/vfs_macros.h
source3/modules/vfs_aio_pthread.c
source3/modules/vfs_audit.c
source3/modules/vfs_cap.c
source3/modules/vfs_catia.c
source3/modules/vfs_ceph.c
source3/modules/vfs_ceph_snapshots.c
source3/modules/vfs_commit.c
source3/modules/vfs_default.c
source3/modules/vfs_error_inject.c
source3/modules/vfs_extd_audit.c
source3/modules/vfs_fruit.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_glusterfs.c
source3/modules/vfs_gpfs.c
source3/modules/vfs_media_harmony.c
source3/modules/vfs_not_implemented.c
source3/modules/vfs_prealloc.c
source3/modules/vfs_preopen.c
source3/modules/vfs_shadow_copy2.c
source3/modules/vfs_snapper.c
source3/modules/vfs_streams_depot.c
source3/modules/vfs_streams_xattr.c
source3/modules/vfs_syncops.c
source3/modules/vfs_time_audit.c
source3/modules/vfs_unityed_media.c
source3/modules/vfs_virusfilter.c
source3/modules/vfs_widelinks.c
source3/modules/vfs_xattr_tdb.c
source3/smbd/files.c
source3/smbd/open.c
source3/smbd/pysmbd.c
source3/smbd/vfs.c
source3/torture/cmd_vfs.c

index 23614b660d92f33b736f27df04ecbe47d83e471e..61c343f543448401a49b5df95d87aff818a80367 100644 (file)
@@ -197,8 +197,7 @@ static int skel_openat(struct vfs_handle_struct *handle,
                       const struct files_struct *dirfsp,
                       const struct smb_filename *smb_fname,
                       struct files_struct *fsp,
-                      int flags,
-                      mode_t mode)
+                      const struct vfs_open_how *how)
 {
        errno = ENOSYS;
        return -1;
index 9fc211c5e2ee1acec700784adb5fc7ac8658de8c..8fb8644ad09fa869e2dd56e622738b6016ccd90a 100644 (file)
@@ -206,10 +206,9 @@ static int skel_openat(struct vfs_handle_struct *handle,
                       const struct files_struct *dirfsp,
                       const struct smb_filename *smb_fname,
                       struct files_struct *fsp,
-                      int flags,
-                      mode_t mode)
+                      const struct vfs_open_how *how)
 {
-       return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
 }
 
 static NTSTATUS skel_create_file(struct vfs_handle_struct *handle,
index be4712689eb6eabeec4122265a13f36c91d7a74c..e65d857d220bb5f6c460ec94411ebffc55f7e043 100644 (file)
  * Version 47 - Replace SMB_VFS_GET_REAL_FILENAME with SMB_VFS_GET_REAL_FILENAME_AT
  * Version 47 - Re-add dirfsp to CREATE_FILE
  * Version 47 - Add fsp flag fstat_before_close
+ * Version 47 - Change SMB_VFS_OPENAT() to match the Linux openat2 prototype, add vfs_open_how
  */
 
 #define SMB_VFS_INTERFACE_VERSION 47
@@ -904,6 +905,11 @@ struct vfs_aio_state {
        uint64_t duration;
 };
 
+struct vfs_open_how {
+       int flags;
+       mode_t mode;
+};
+
 /*
     Available VFS operations. These values must be in sync with vfs_ops struct
     (struct vfs_fn_pointers and struct vfs_handle_pointers inside of struct vfs_ops).
@@ -974,8 +980,7 @@ struct vfs_fn_pointers {
                         const struct files_struct *dirfsp,
                         const struct smb_filename *smb_fname,
                         struct files_struct *fsp,
-                        int flags,
-                        mode_t mode);
+                        const struct vfs_open_how *how);
        NTSTATUS (*create_file_fn)(struct vfs_handle_struct *handle,
                                   struct smb_request *req,
                                   struct files_struct *dirfsp,
@@ -1460,8 +1465,7 @@ int smb_vfs_call_openat(struct vfs_handle_struct *handle,
                        const struct files_struct *dirfsp,
                        const struct smb_filename *smb_fname,
                        struct files_struct *fsp,
-                       int flags,
-                       mode_t mode);
+                       const struct vfs_open_how *how);
 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
                                  struct smb_request *req,
                                  struct files_struct *dirfsp,
@@ -1905,8 +1909,7 @@ int vfs_not_implemented_openat(vfs_handle_struct *handle,
                               const struct files_struct *dirfsp,
                               const struct smb_filename *smb_fname,
                               struct files_struct *fsp,
-                              int flags,
-                              mode_t mode);
+                              const struct vfs_open_how *how);
 NTSTATUS vfs_not_implemented_create_file(struct vfs_handle_struct *handle,
                                struct smb_request *req,
                                struct files_struct *dirfsp,
index 840e77cf1b05c4a66d3915e4aa44277d6c26314a..c7089b62964b1297341bd60fbc5002ba9d31c3e0 100644 (file)
        smb_vfs_call_closedir((handle)->next, (dir))
 
 /* File operations */
-#define SMB_VFS_OPENAT(conn, dirfsp, smb_fname, fsp, flags, mode) \
-       smb_vfs_call_openat((conn)->vfs_handles, (dirfsp), (smb_fname), (fsp), (flags), (mode))
-#define SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode) \
-       smb_vfs_call_openat((handle)->next, (dirfsp), (smb_fname), (fsp), (flags), (mode))
+#define SMB_VFS_OPENAT(conn, dirfsp, smb_fname, fsp, how) \
+       smb_vfs_call_openat( \
+               (conn)->vfs_handles, (dirfsp), (smb_fname), (fsp), (how))
+#define SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how) \
+       smb_vfs_call_openat( \
+               (handle)->next, (dirfsp), (smb_fname), (fsp), (how))
 
 #define SMB_VFS_CREATE_FILE(conn, req, dirfsp, smb_fname, access_mask, share_access, create_disposition, \
         create_options, file_attributes, oplock_request, lease, allocation_size, private_flags, sd, ea_list, result, pinfo, in_context_blobs, out_context_blobs) \
index d58e990a66646e9e7b668fc1db2818f3577a36fe..b4245ee89dcee4569514ac1c00c90a50542bb800 100644 (file)
@@ -450,8 +450,7 @@ static int aio_pthread_openat_fn(vfs_handle_struct *handle,
                                 const struct files_struct *dirfsp,
                                 const struct smb_filename *smb_fname,
                                 struct files_struct *fsp,
-                                int flags,
-                                mode_t mode)
+                                const struct vfs_open_how *how)
 {
        int my_errno = 0;
        int fd = -1;
@@ -475,24 +474,24 @@ static int aio_pthread_openat_fn(vfs_handle_struct *handle,
                /* aio opens turned off. */
                return openat(fsp_get_pathref_fd(dirfsp),
                              smb_fname->base_name,
-                             flags,
-                             mode);
+                             how->flags,
+                             how->mode);
        }
 
-       if (!(flags & O_CREAT)) {
+       if (!(how->flags & O_CREAT)) {
                /* Only creates matter. */
                return openat(fsp_get_pathref_fd(dirfsp),
                              smb_fname->base_name,
-                             flags,
-                             mode);
+                             how->flags,
+                             how->mode);
        }
 
-       if (!(flags & O_EXCL)) {
+       if (!(how->flags & O_EXCL)) {
                /* Only creates with O_EXCL matter. */
                return openat(fsp_get_pathref_fd(dirfsp),
                              smb_fname->base_name,
-                             flags,
-                             mode);
+                             how->flags,
+                             how->mode);
        }
 
        /*
@@ -508,7 +507,7 @@ static int aio_pthread_openat_fn(vfs_handle_struct *handle,
        }
 
        /* Ok, it's a create exclusive call - pass it to a thread helper. */
-       return open_async(dirfsp, smb_fname, fsp, flags, mode);
+       return open_async(dirfsp, smb_fname, fsp, how->flags, how->mode);
 }
 #endif
 
index 91fbd8c19ba2a765613ee40d7e77dba1943bb845..2b01a6a8d91ff35b336d2cc528b4ecb12db306fa 100644 (file)
@@ -211,17 +211,17 @@ static int audit_openat(vfs_handle_struct *handle,
                        const struct files_struct *dirfsp,
                        const struct smb_filename *smb_fname,
                        struct files_struct *fsp,
-                       int flags,
-                       mode_t mode)
+                       const struct vfs_open_how *how)
 {
        int result;
 
-       result = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       result = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
 
        syslog(audit_syslog_priority(handle),
               "openat %s (fd %d) %s%s%s\n",
               fsp_str_dbg(fsp), result,
-              ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
+              ((how->flags & O_WRONLY) || (how->flags & O_RDWR)) ?
+              "for writing " : "",
               (result < 0) ? "failed: " : "",
               (result < 0) ? strerror(errno) : "");
 
index 43c8edb8932f62c67e54ad60122a64269ba23dc6..ac2c1b0410d85dffdeabe8c3fbf5a929a492b98b 100644 (file)
@@ -152,8 +152,7 @@ static int cap_openat(vfs_handle_struct *handle,
                      const struct files_struct *dirfsp,
                      const struct smb_filename *smb_fname_in,
                      files_struct *fsp,
-                     int flags,
-                     mode_t mode)
+                     const struct vfs_open_how *how)
 {
        char *cappath = NULL;
        struct smb_filename *smb_fname = NULL;
@@ -179,9 +178,7 @@ static int cap_openat(vfs_handle_struct *handle,
                                  dirfsp,
                                  smb_fname,
                                  fsp,
-                                 flags,
-                                 mode);
-
+                                 how);
        if (ret == -1) {
                saved_errno = errno;
        }
index f40bec3b74c98f347af364606f121d4ee8c74453..36aa43123fd4c510a0ba511ae6e9a36442115803 100644 (file)
@@ -489,8 +489,7 @@ static int catia_openat(vfs_handle_struct *handle,
                        const struct files_struct *dirfsp,
                        const struct smb_filename *smb_fname_in,
                        files_struct *fsp,
-                       int flags,
-                       mode_t mode)
+                       const struct vfs_open_how *how)
 {
        struct smb_filename *smb_fname = NULL;
        struct catia_cache *cc = NULL;
@@ -525,9 +524,7 @@ static int catia_openat(vfs_handle_struct *handle,
                                  dirfsp,
                                  smb_fname,
                                  fsp,
-                                 flags,
-                                 mode);
-
+                                 how);
        if (ret == -1) {
                saved_errno = errno;
        }
index 145829052122f91c2916b002473f83212a8d2015..59747db16c356f71dad1fe1b52dd564d888f193e 100644 (file)
@@ -400,9 +400,10 @@ static int cephwrap_openat(struct vfs_handle_struct *handle,
                           const struct files_struct *dirfsp,
                           const struct smb_filename *smb_fname,
                           files_struct *fsp,
-                          int flags,
-                          mode_t mode)
+                          const struct vfs_open_how *how)
 {
+       int flags = how->flags;
+       mode_t mode = how->mode;
        struct smb_filename *name = NULL;
        bool have_opath = false;
        bool became_root = false;
index 06ef5538450e3037f19a3fe2b06bb55a12a3b7a6..c981cebd8a21d7affbe6d17e0d0934981bfb2993 100644 (file)
@@ -939,8 +939,7 @@ static int ceph_snap_gmt_openat(vfs_handle_struct *handle,
                                const struct files_struct *dirfsp,
                                const struct smb_filename *smb_fname_in,
                                files_struct *fsp,
-                               int flags,
-                               mode_t mode)
+                               const struct vfs_open_how *how)
 {
        time_t timestamp = 0;
        struct smb_filename *smb_fname = NULL;
@@ -963,8 +962,7 @@ static int ceph_snap_gmt_openat(vfs_handle_struct *handle,
                                           dirfsp,
                                           smb_fname_in,
                                           fsp,
-                                          flags,
-                                          mode);
+                                          how);
        }
 
        ret = ceph_snap_gmt_convert(handle,
@@ -986,8 +984,7 @@ static int ceph_snap_gmt_openat(vfs_handle_struct *handle,
                                  dirfsp,
                                  smb_fname,
                                  fsp,
-                                 flags,
-                                 mode);
+                                 how);
        if (ret == -1) {
                saved_errno = errno;
        }
index 6d64896c7e044d89149a67a2efc02fb99c7b3382..c7625b0837cf1a362ef8700f1ca01e4fb4f5d439 100644 (file)
@@ -181,8 +181,7 @@ static int commit_openat(struct vfs_handle_struct *handle,
                         const struct files_struct *dirfsp,
                         const struct smb_filename *smb_fname,
                         files_struct *fsp,
-                        int flags,
-                        mode_t mode)
+                        const struct vfs_open_how *how)
 {
         off_t dthresh;
        const char *eof_mode;
@@ -190,13 +189,12 @@ static int commit_openat(struct vfs_handle_struct *handle,
         int fd;
 
         /* Don't bother with read-only files. */
-        if ((flags & O_ACCMODE) == O_RDONLY) {
+        if ((how->flags & O_ACCMODE) == O_RDONLY) {
                 return SMB_VFS_NEXT_OPENAT(handle,
                                           dirfsp,
                                           smb_fname,
                                           fsp,
-                                          flags,
-                                          mode);
+                                          how);
         }
 
         /* Read and check module configuration */
@@ -226,7 +224,7 @@ static int commit_openat(struct vfs_handle_struct *handle,
                 }
         }
 
-        fd = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       fd = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
        if (fd == -1) {
                VFS_REMOVE_FSP_EXTENSION(handle, fsp);
                return fd;
index ef68a96282eeffc3130e929fb6e074e09d2088bd..6bfda596d8aa8d5ce9cd86f7a57410438ff4f4ad 100644 (file)
@@ -691,9 +691,10 @@ static int vfswrap_openat(vfs_handle_struct *handle,
                          const struct files_struct *dirfsp,
                          const struct smb_filename *smb_fname,
                          files_struct *fsp,
-                         int flags,
-                         mode_t mode)
+                         const struct vfs_open_how *how)
 {
+       int flags = how->flags;
+       mode_t mode = how->mode;
        bool have_opath = false;
        bool became_root = false;
        int result;
index 9ead2c26727feaa18960610f7050f466d715dbf0..1a327097b307c76120a383fbaeba439055cd8ee9 100644 (file)
@@ -112,8 +112,7 @@ static int vfs_error_inject_openat(struct vfs_handle_struct *handle,
                                   const struct files_struct *dirfsp,
                                   const struct smb_filename *smb_fname,
                                   files_struct *fsp,
-                                  int flags,
-                                  mode_t mode)
+                                  const struct vfs_open_how *how)
 {
        int error = inject_unix_error("openat", handle);
        int dirfsp_flags = (O_NOFOLLOW|O_DIRECTORY);
@@ -129,13 +128,13 @@ static int vfs_error_inject_openat(struct vfs_handle_struct *handle,
 
        return_error = (error != 0);
        return_error &= !fsp->fsp_flags.is_pathref;
-       return_error &= ((flags & dirfsp_flags) != dirfsp_flags);
+       return_error &= ((how->flags & dirfsp_flags) != dirfsp_flags);
 
        if (return_error) {
                errno = error;
                return -1;
        }
-       return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
 }
 
 static int vfs_error_inject_unlinkat(struct vfs_handle_struct *handle,
index 3ac75fb890ebd82087010b6e015f99b2e62d24ed..91dce6c7dc5872c493d9de88d6dff899022db5c1 100644 (file)
@@ -227,12 +227,11 @@ static int audit_openat(vfs_handle_struct *handle,
                        const struct files_struct *dirfsp,
                        const struct smb_filename *smb_fname,
                        files_struct *fsp,
-                       int flags,
-                       mode_t mode)
+                       const struct vfs_open_how *how)
 {
        int ret;
 
-       ret = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       ret = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
 
        if (lp_syslog() > 0) {
                syslog(audit_syslog_priority(handle),
@@ -240,7 +239,7 @@ static int audit_openat(vfs_handle_struct *handle,
                       smb_fname_str_dbg(fsp->fsp_name),
                       smb_fname->base_name,
                       ret,
-                      ((flags & O_WRONLY) || (flags & O_RDWR)) ?
+                      ((how->flags & O_WRONLY) || (how->flags & O_RDWR)) ?
                       "for writing " : "",
                       (ret < 0) ? "failed: " : "",
                       (ret < 0) ? strerror(errno) : "");
index 685c15bcaa70f82506c8b1f537671b85834978d1..737f44eb03f448f6fecfeee6272d72b65777dbc9 100644 (file)
@@ -1413,7 +1413,10 @@ static int fruit_open_meta_stream(vfs_handle_struct *handle,
 {
        struct fruit_config_data *config = NULL;
        struct fio *fio = NULL;
-       int open_flags = flags & ~O_CREAT;
+       struct vfs_open_how how = {
+               .flags = flags & ~O_CREAT,
+               .mode = mode,
+       };
        int fd;
 
        DBG_DEBUG("Path [%s]\n", smb_fname_str_dbg(smb_fname));
@@ -1431,8 +1434,7 @@ static int fruit_open_meta_stream(vfs_handle_struct *handle,
                                 dirfsp,
                                 smb_fname,
                                 fsp,
-                                open_flags,
-                                mode);
+                                &how);
        if (fd != -1) {
                return fd;
        }
@@ -1701,14 +1703,17 @@ static int fruit_open_rsrc(vfs_handle_struct *handle,
        fio->config = config;
 
        switch (config->rsrc) {
-       case FRUIT_RSRC_STREAM:
+       case FRUIT_RSRC_STREAM: {
+               struct vfs_open_how how = {
+                       .flags = flags, .mode = mode,
+               };
                fd = SMB_VFS_NEXT_OPENAT(handle,
                                         dirfsp,
                                         smb_fname,
                                         fsp,
-                                        flags,
-                                        mode);
+                                        &how);
                break;
+       }
 
        case FRUIT_RSRC_ADFILE:
                fd = fruit_open_rsrc_adouble(handle, dirfsp, smb_fname,
@@ -1739,8 +1744,7 @@ static int fruit_openat(vfs_handle_struct *handle,
                        const struct files_struct *dirfsp,
                        const struct smb_filename *smb_fname,
                        files_struct *fsp,
-                       int flags,
-                       mode_t mode)
+                       const struct vfs_open_how *how)
 {
        int fd;
 
@@ -1751,8 +1755,7 @@ static int fruit_openat(vfs_handle_struct *handle,
                                           dirfsp,
                                           smb_fname,
                                           fsp,
-                                          flags,
-                                          mode);
+                                          how);
        }
 
        SMB_ASSERT(fsp_is_alternate_stream(fsp));
@@ -1762,22 +1765,21 @@ static int fruit_openat(vfs_handle_struct *handle,
                                     dirfsp,
                                     smb_fname,
                                     fsp,
-                                    flags,
-                                    mode);
+                                    how->flags,
+                                    how->mode);
        } else if (is_afpresource_stream(smb_fname->stream_name)) {
                fd = fruit_open_rsrc(handle,
                                     dirfsp,
                                     smb_fname,
                                     fsp,
-                                    flags,
-                                    mode);
+                                    how->flags,
+                                    how->mode);
        } else {
                fd = SMB_VFS_NEXT_OPENAT(handle,
                                         dirfsp,
                                         smb_fname,
                                         fsp,
-                                        flags,
-                                        mode);
+                                        how);
        }
 
        DBG_DEBUG("Path [%s] fd [%d]\n", smb_fname_str_dbg(smb_fname), fd);
@@ -2655,6 +2657,9 @@ static ssize_t fruit_pwrite_meta_stream(vfs_handle_struct *handle,
        }
 
        if (fio->fake_fd) {
+               struct vfs_open_how how = {
+                       .flags = fio->flags, .mode = fio->mode,
+               };
                int fd = fsp_get_pathref_fd(fsp);
 
                ret = vfs_fake_fd_close(fd);
@@ -2669,8 +2674,7 @@ static ssize_t fruit_pwrite_meta_stream(vfs_handle_struct *handle,
                                         NULL, /* opening a stream */
                                         fsp->fsp_name,
                                         fsp,
-                                        fio->flags,
-                                        fio->mode);
+                                        &how);
                if (fd == -1) {
                        DBG_ERR("On-demand create [%s] in write failed: %s\n",
                                fsp_str_dbg(fsp), strerror(errno));
index 6d38738ac529020dfd1c25139b9ba2165b9b6c24..25fd0cad326f8a991e5e5a23b40ed21a9f28b9aa 100644 (file)
@@ -1112,15 +1112,14 @@ static int smb_full_audit_openat(vfs_handle_struct *handle,
                                 const struct files_struct *dirfsp,
                                 const struct smb_filename *smb_fname,
                                 struct files_struct *fsp,
-                                int flags,
-                                mode_t mode)
+                                const struct vfs_open_how *how)
 {
        int result;
 
-       result = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       result = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
 
        do_log(SMB_VFS_OP_OPENAT, (result >= 0), handle, "%s|%s",
-              ((flags & O_WRONLY) || (flags & O_RDWR))?"w":"r",
+              ((how->flags & O_WRONLY) || (how->flags & O_RDWR))?"w":"r",
               fsp_str_do_log(fsp));
 
        return result;
index 23bcf83d31c659dd43db89b9f6c4b7968f85c756..081bc0c7c07a19248025d04db72bb44922dcdc39 100644 (file)
@@ -763,8 +763,7 @@ static int vfs_gluster_openat(struct vfs_handle_struct *handle,
                              const struct files_struct *dirfsp,
                              const struct smb_filename *smb_fname,
                              files_struct *fsp,
-                             int flags,
-                             mode_t mode)
+                             const struct vfs_open_how *how)
 {
        struct smb_filename *name = NULL;
        bool became_root = false;
@@ -804,13 +803,17 @@ static int vfs_gluster_openat(struct vfs_handle_struct *handle,
                became_root = true;
        }
 
-       if (flags & O_DIRECTORY) {
+       if (how->flags & O_DIRECTORY) {
                glfd = glfs_opendir(handle->data, smb_fname->base_name);
-       } else if (flags & O_CREAT) {
-               glfd = glfs_creat(handle->data, smb_fname->base_name, flags,
-                                 mode);
+       } else if (how->flags & O_CREAT) {
+               glfd = glfs_creat(handle->data,
+                                 smb_fname->base_name,
+                                 how->flags,
+                                 how->mode);
        } else {
-               glfd = glfs_open(handle->data, smb_fname->base_name, flags);
+               glfd = glfs_open(handle->data,
+                                smb_fname->base_name,
+                                how->flags);
        }
 
        if (became_root) {
index db167d002260ab699ba7832c9191668aa5d51b06..bb15ba630b99b5cfd25d11dd394356190088b76e 100644 (file)
@@ -2331,9 +2331,9 @@ static int vfs_gpfs_openat(struct vfs_handle_struct *handle,
                           const struct files_struct *dirfsp,
                           const struct smb_filename *smb_fname,
                           files_struct *fsp,
-                          int flags,
-                          mode_t mode)
+                          const struct vfs_open_how *_how)
 {
+       struct vfs_open_how how = *_how;
        struct gpfs_config_data *config = NULL;
        struct gpfs_fsp_extension *ext = NULL;
        int ret;
@@ -2353,7 +2353,7 @@ static int vfs_gpfs_openat(struct vfs_handle_struct *handle,
        }
 
        if (config->syncio) {
-               flags |= O_SYNC;
+               how.flags |= O_SYNC;
        }
 
        ext = VFS_ADD_FSP_EXTENSION(handle, fsp, struct gpfs_fsp_extension,
@@ -2368,7 +2368,7 @@ static int vfs_gpfs_openat(struct vfs_handle_struct *handle,
         */
        *ext = (struct gpfs_fsp_extension) { .offline = true };
 
-       ret = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       ret = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, &how);
        if (ret == -1) {
                VFS_REMOVE_FSP_EXTENSION(handle, fsp);
        }
index 38340daa3af46604885a7868b04142d16e516139..2ef9b89d1ebb5e62c26a4afc7b7534c8abb37e65 100644 (file)
@@ -1061,8 +1061,7 @@ static int mh_openat(struct vfs_handle_struct *handle,
                     const struct files_struct *dirfsp,
                     const struct smb_filename *smb_fname,
                     files_struct *fsp,
-                    int flags,
-                    mode_t mode)
+                    const struct vfs_open_how *how)
 {
        int ret;
        struct smb_filename *clientFname;
@@ -1076,8 +1075,7 @@ static int mh_openat(struct vfs_handle_struct *handle,
                                          dirfsp,
                                          smb_fname,
                                          fsp,
-                                         flags,
-                                         mode);
+                                         how);
                goto out;
        }
 
@@ -1101,7 +1099,7 @@ static int mh_openat(struct vfs_handle_struct *handle,
                              ctime(&(smb_fname->st.st_ex_mtime.tv_sec)),
                              ctime(&(fsp->fsp_name->st.st_ex_mtime.tv_sec))));
 
-       ret = SMB_VFS_NEXT_OPENAT(handle, dirfsp, clientFname, fsp, flags, mode);
+       ret = SMB_VFS_NEXT_OPENAT(handle, dirfsp, clientFname, fsp, how);
 err:
        TALLOC_FREE(clientFname);
 out:
index 3bfd86a96139ddd960052e44663f0854b3fa2e34..3c017c68bb8d7acdc6baec8cc07b44b089500acb 100644 (file)
@@ -216,8 +216,7 @@ int vfs_not_implemented_openat(vfs_handle_struct *handle,
                               const struct files_struct *dirfsp,
                               const struct smb_filename *smb_fname,
                               struct files_struct *fsp,
-                              int flags,
-                              mode_t mode)
+                              const struct vfs_open_how *how)
 {
        errno = ENOSYS;
        return -1;
index 467f619b8df0c3f007adfe343a03203d1567284b..51e9ad0d8fb41cdc2df9858f0e0d6892a13c7fd3 100644 (file)
@@ -110,15 +110,14 @@ static int prealloc_openat(struct vfs_handle_struct* handle,
                           const struct files_struct *dirfsp,
                           const struct smb_filename *smb_fname,
                           files_struct *fsp,
-                          int flags,
-                          mode_t mode)
+                          const struct vfs_open_how *how)
 {
        int fd;
        off_t size = 0;
        const char * dot;
        char fext[10];
 
-       if (!(flags & (O_CREAT|O_TRUNC))) {
+       if (!(how->flags & (O_CREAT|O_TRUNC))) {
                /* Caller is not intending to rewrite the file. Let's not mess
                 * with the allocation in this case.
                 */
@@ -155,7 +154,7 @@ static int prealloc_openat(struct vfs_handle_struct* handle,
                goto normal_open;
        }
 
-       fd = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       fd = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
        if (fd < 0) {
                return fd;
        }
@@ -164,7 +163,7 @@ static int prealloc_openat(struct vfs_handle_struct* handle,
         * Samba won't ever pass down O_TRUNC, which is why we have to handle
         * truncate calls specially.
         */
-       if ((flags & O_CREAT) || (flags & O_TRUNC)) {
+       if ((how->flags & O_CREAT) || (how->flags & O_TRUNC)) {
                off_t * psize;
 
                psize = VFS_ADD_FSP_EXTENSION(handle, fsp, off_t, NULL);
@@ -191,7 +190,7 @@ normal_open:
         */
        DEBUG(module_debug, ("%s: skipping preallocation for %s\n",
                MODULE, smb_fname_str_dbg(smb_fname)));
-       return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
 }
 
 static int prealloc_ftruncate(vfs_handle_struct * handle,
index 8d85dda92ecdedcea7a137f4571c23d10ea6ef8a..3b7fae5940b8dd32da48e8dc0d896946db262857 100644 (file)
@@ -531,8 +531,7 @@ static int preopen_openat(struct vfs_handle_struct *handle,
                          const struct files_struct *dirfsp,
                          const struct smb_filename *smb_fname,
                          struct files_struct *fsp,
-                         int flags,
-                         mode_t mode)
+                         const struct vfs_open_how *how)
 {
        const char *dirname = dirfsp->fsp_name->base_name;
        struct preopen_state *state;
@@ -557,16 +556,15 @@ static int preopen_openat(struct vfs_handle_struct *handle,
                                           dirfsp,
                                           smb_fname,
                                           fsp,
-                                          flags,
-                                          mode);
+                                          how);
        }
 
-       res = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       res = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
        if (res == -1) {
                return -1;
        }
 
-       if ((flags & O_ACCMODE) != O_RDONLY) {
+       if ((how->flags & O_ACCMODE) != O_RDONLY) {
                return res;
        }
 
index e8aa224648ca470d046ac4afbf6e3c085e0bc0d8..0e849d7cc418622e2b7a9d0d33299199e23a484f 100644 (file)
@@ -1542,9 +1542,9 @@ static int shadow_copy2_openat(vfs_handle_struct *handle,
                               const struct files_struct *dirfsp,
                               const struct smb_filename *smb_fname_in,
                               struct files_struct *fsp,
-                              int flags,
-                              mode_t mode)
+                              const struct vfs_open_how *_how)
 {
+       struct vfs_open_how how = *_how;
        struct smb_filename *smb_fname = NULL;
        time_t timestamp = 0;
        char *stripped = NULL;
@@ -1578,14 +1578,13 @@ static int shadow_copy2_openat(vfs_handle_struct *handle,
                         * EINVAL which we carefully map to EROFS. In sum, this
                         * matches Windows behaviour.
                         */
-                       flags &= ~(O_WRONLY | O_RDWR | O_CREAT);
+                       how.flags &= ~(O_WRONLY | O_RDWR | O_CREAT);
                }
                return SMB_VFS_NEXT_OPENAT(handle,
                                           dirfsp,
                                           smb_fname_in,
                                           fsp,
-                                          flags,
-                                          mode);
+                                          &how);
        }
 
        smb_fname->base_name = shadow_copy2_convert(smb_fname,
@@ -1607,14 +1606,13 @@ static int shadow_copy2_openat(vfs_handle_struct *handle,
         * pwrite() syscall with EINVAL which we carefully map to EROFS. In sum,
         * this matches Windows behaviour.
         */
-       flags &= ~(O_WRONLY | O_RDWR | O_CREAT);
+       how.flags &= ~(O_WRONLY | O_RDWR | O_CREAT);
 
        ret = SMB_VFS_NEXT_OPENAT(handle,
                                  dirfsp,
                                  smb_fname,
                                  fsp,
-                                 flags,
-                                 mode);
+                                 &how);
        if (ret == -1) {
                saved_errno = errno;
        }
@@ -2156,7 +2154,9 @@ static int shadow_copy2_get_shadow_copy_data(
        struct shadow_copy2_private *priv = NULL;
        struct shadow_copy2_snapentry *tmpentry = NULL;
        bool get_snaplist = false;
-       int open_flags = O_RDONLY;
+       struct vfs_open_how how = {
+               .flags = O_RDONLY, .mode = 0,
+       };
        int fd;
        int ret = -1;
        NTSTATUS status;
@@ -2198,15 +2198,14 @@ static int shadow_copy2_get_shadow_copy_data(
        }
 
 #ifdef O_DIRECTORY
-       open_flags |= O_DIRECTORY;
+       how.flags |= O_DIRECTORY;
 #endif
 
        fd = SMB_VFS_NEXT_OPENAT(handle,
                                 fspcwd,
                                 snapdir_smb_fname,
                                 dirfsp,
-                                open_flags,
-                                0);
+                                &how);
        if (fd == -1) {
                DBG_WARNING("SMB_VFS_NEXT_OPEN failed for '%s'"
                            " - %s\n", snapdir, strerror(errno));
index 15707ac03041120896befe7c52c5382d8c6a6cea..6c9a14a725f64b5b1e82b733b2c411dac49125c0 100644 (file)
@@ -2078,8 +2078,7 @@ static int snapper_gmt_openat(struct vfs_handle_struct *handle,
                              const struct files_struct *dirfsp,
                              const struct smb_filename *smb_fname_in,
                              struct files_struct *fsp,
-                             int flags,
-                             mode_t mode)
+                             const struct vfs_open_how *how)
 {
        struct smb_filename *smb_fname = NULL;
        time_t timestamp;
@@ -2097,8 +2096,7 @@ static int snapper_gmt_openat(struct vfs_handle_struct *handle,
                                           dirfsp,
                                           smb_fname_in,
                                           fsp,
-                                          flags,
-                                          mode);
+                                          how);
        }
 
        smb_fname = cp_smb_filename(talloc_tos(), smb_fname_in);
@@ -2117,7 +2115,7 @@ static int snapper_gmt_openat(struct vfs_handle_struct *handle,
                return -1;
        }
 
-       ret = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       ret = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
        if (ret == -1) {
                saved_errno = errno;
        }
index 6722d712bff5af436817894727a2673980b518ba..47e3b3605e6308c48ba32ca20ba9ef79870bb14b 100644 (file)
@@ -665,8 +665,7 @@ static int streams_depot_openat(struct vfs_handle_struct *handle,
                                const struct files_struct *dirfsp,
                                const struct smb_filename *smb_fname,
                                struct files_struct *fsp,
-                               int flags,
-                               mode_t mode)
+                               const struct vfs_open_how *how)
 {
        struct smb_filename *smb_fname_stream = NULL;
        struct files_struct *fspcwd = NULL;
@@ -679,15 +678,14 @@ static int streams_depot_openat(struct vfs_handle_struct *handle,
                                           dirfsp,
                                           smb_fname,
                                           fsp,
-                                          flags,
-                                          mode);
+                                          how);
        }
 
        SMB_ASSERT(fsp_is_alternate_stream(fsp));
        SMB_ASSERT(dirfsp == NULL);
        SMB_ASSERT(VALID_STAT(fsp->base_fsp->fsp_name->st));
 
-       create_it = (mode & O_CREAT);
+       create_it = (how->mode & O_CREAT);
 
        /* Determine the stream name, and then open it. */
        status = stream_smb_fname(
@@ -741,8 +739,7 @@ static int streams_depot_openat(struct vfs_handle_struct *handle,
                                  fspcwd,
                                  smb_fname_stream,
                                  fsp,
-                                 flags,
-                                 mode);
+                                 how);
 
  done:
        TALLOC_FREE(smb_fname_stream);
index dd6892614495694b44116526063997e3d29d1609..ed03aa3b4549f64c2622b8b17ebf95dfca961052 100644 (file)
@@ -315,8 +315,7 @@ static int streams_xattr_openat(struct vfs_handle_struct *handle,
                                const struct files_struct *dirfsp,
                                const struct smb_filename *smb_fname,
                                files_struct *fsp,
-                               int flags,
-                               mode_t mode)
+                               const struct vfs_open_how *how)
 {
        NTSTATUS status;
        struct streams_xattr_config *config = NULL;
@@ -332,15 +331,14 @@ static int streams_xattr_openat(struct vfs_handle_struct *handle,
 
        DBG_DEBUG("called for %s with flags 0x%x\n",
                  smb_fname_str_dbg(smb_fname),
-                 flags);
+                 how->flags);
 
        if (!is_named_stream(smb_fname)) {
                return SMB_VFS_NEXT_OPENAT(handle,
                                           dirfsp,
                                           smb_fname,
                                           fsp,
-                                          flags,
-                                          mode);
+                                          how);
        }
 
        SMB_ASSERT(fsp_is_alternate_stream(fsp));
@@ -373,7 +371,7 @@ static int streams_xattr_openat(struct vfs_handle_struct *handle,
                        goto fail;
                }
 
-               if (!(flags & O_CREAT)) {
+               if (!(how->flags & O_CREAT)) {
                        errno = ENOATTR;
                        goto fail;
                }
@@ -381,7 +379,7 @@ static int streams_xattr_openat(struct vfs_handle_struct *handle,
                set_empty_xattr = true;
        }
 
-       if (flags & O_TRUNC) {
+       if (how->flags & O_TRUNC) {
                set_empty_xattr = true;
        }
 
@@ -401,7 +399,7 @@ static int streams_xattr_openat(struct vfs_handle_struct *handle,
                ret = SMB_VFS_FSETXATTR(fsp->base_fsp,
                                       xattr_name,
                                       &null, sizeof(null),
-                                      flags & O_EXCL ? XATTR_CREATE : 0);
+                                      how->flags & O_EXCL ? XATTR_CREATE : 0);
                if (ret != 0) {
                        goto fail;
                }
index 14c860127b3280e363dd5b3e09ded6ca09261d55..94dcd7b846eda3fb665010ea8855e528c3339fcb 100644 (file)
@@ -292,11 +292,10 @@ static int syncops_openat(struct vfs_handle_struct *handle,
                          const struct files_struct *dirfsp,
                          const struct smb_filename *smb_fname,
                          struct files_struct *fsp,
-                         int flags,
-                         mode_t mode)
+                         const struct vfs_open_how *how)
 {
-       SYNCOPS_NEXT_SMB_FNAME(OPENAT, (flags & O_CREAT ? smb_fname : NULL),
-                              (handle, dirfsp, smb_fname, fsp, flags, mode));
+       SYNCOPS_NEXT_SMB_FNAME(OPENAT, (how->flags & O_CREAT ? smb_fname : NULL),
+                              (handle, dirfsp, smb_fname, fsp, how));
 }
 
 static int syncops_unlinkat(vfs_handle_struct *handle,
index 481a9b0829f748cad6f5c057c40bdf8430b5d315..e7633285607f0e72858edf94581f6637f21308eb 100644 (file)
@@ -621,8 +621,7 @@ static int smb_time_audit_openat(vfs_handle_struct *handle,
                                 const struct files_struct *dirfsp,
                                 const struct smb_filename *smb_fname,
                                 struct files_struct *fsp,
-                                int flags,
-                                mode_t mode)
+                                const struct vfs_open_how *how)
 {
        int result;
        struct timespec ts1,ts2;
@@ -633,8 +632,7 @@ static int smb_time_audit_openat(vfs_handle_struct *handle,
                                     dirfsp,
                                     smb_fname,
                                     fsp,
-                                    flags,
-                                    mode);
+                                    how);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
index 30200da9ae49164358d21a7561bf738b190d80cd..3c1a263c25a8bf835f40b85d31b915994d320675 100644 (file)
@@ -798,8 +798,7 @@ static int um_openat(struct vfs_handle_struct *handle,
                     const struct files_struct *dirfsp,
                     const struct smb_filename *smb_fname,
                     struct files_struct *fsp,
-                    int flags,
-                    mode_t mode)
+                    const struct vfs_open_how *how)
 {
        struct smb_filename *client_fname = NULL;
        int ret;
@@ -812,8 +811,7 @@ static int um_openat(struct vfs_handle_struct *handle,
                                           dirfsp,
                                           smb_fname,
                                           fsp,
-                                          flags,
-                                          mode);
+                                          how);
        }
 
        if (alloc_get_client_smb_fname(handle, talloc_tos(),
@@ -840,8 +838,7 @@ static int um_openat(struct vfs_handle_struct *handle,
                                  dirfsp,
                                  client_fname,
                                  fsp,
-                                 flags,
-                                 mode);
+                                 how);
 err:
        TALLOC_FREE(client_fname);
        DEBUG(10, ("Leaving with smb_fname->base_name '%s'\n",
index cbb93161a8a1f6accd885ba57360d32af0f5d016..124b4091c1b8e200bf58cb76660fbca2e0b5cf44 100644 (file)
@@ -1237,8 +1237,7 @@ static int virusfilter_vfs_openat(struct vfs_handle_struct *handle,
                                  const struct files_struct *dirfsp,
                                  const struct smb_filename *smb_fname_in,
                                  struct files_struct *fsp,
-                                 int flags,
-                                 mode_t mode)
+                                 const struct vfs_open_how *how)
 {
        TALLOC_CTX *mem_ctx = talloc_tos();
        struct virusfilter_config *config = NULL;
@@ -1291,7 +1290,7 @@ static int virusfilter_vfs_openat(struct vfs_handle_struct *handle,
                goto virusfilter_vfs_open_next;
        }
 
-       if (flags & O_TRUNC) {
+       if (how->flags & O_TRUNC) {
                DBG_INFO("Not scanned: Open flags have O_TRUNC: %s/%s\n",
                         cwd_fname, fname);
                goto virusfilter_vfs_open_next;
@@ -1402,7 +1401,7 @@ static int virusfilter_vfs_openat(struct vfs_handle_struct *handle,
        TALLOC_FREE(smb_fname);
 
 virusfilter_vfs_open_next:
-       return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname_in, fsp, flags, mode);
+       return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname_in, fsp, how);
 
 virusfilter_vfs_open_fail:
        TALLOC_FREE(smb_fname);
index 1cbb0bf0ad03b98bfcc988ad480d0652bd8457a0..2a35ea5eb689a3c544d139e18f171de2b9d5fc3f 100644 (file)
@@ -342,9 +342,9 @@ static int widelinks_openat(vfs_handle_struct *handle,
                            const struct files_struct *dirfsp,
                            const struct smb_filename *smb_fname,
                            files_struct *fsp,
-                           int flags,
-                           mode_t mode)
+                           const struct vfs_open_how *_how)
 {
+       struct vfs_open_how how = *_how;
        struct widelinks_config *config = NULL;
 
        SMB_VFS_HANDLE_GET_DATA(handle,
@@ -360,15 +360,14 @@ static int widelinks_openat(vfs_handle_struct *handle,
                 * Module active, openat after chdir (see note 1b above) and not
                 * a POSIX open (POSIX sees symlinks), so remove O_NOFOLLOW.
                 */
-               flags = (flags & ~O_NOFOLLOW);
+               how.flags = (how.flags & ~O_NOFOLLOW);
        }
 
        return SMB_VFS_NEXT_OPENAT(handle,
                                   dirfsp,
                                   smb_fname,
                                   fsp,
-                                  flags,
-                                  mode);
+                                  &how);
 }
 
 static struct dirent *widelinks_readdir(vfs_handle_struct *handle,
index 42c570b54b3e9f3542fc61d3f031b82415ab8ccd..07b95899d80d0e162231c06c270d91c8e49a8580 100644 (file)
@@ -365,8 +365,7 @@ static int xattr_tdb_openat(struct vfs_handle_struct *handle,
                            const struct files_struct *dirfsp,
                            const struct smb_filename *smb_fname,
                            struct files_struct *fsp,
-                           int flags,
-                           mode_t mode)
+                           const struct vfs_open_how *how)
 {
        struct db_context *db = NULL;
        TALLOC_CTX *frame = NULL;
@@ -378,14 +377,12 @@ static int xattr_tdb_openat(struct vfs_handle_struct *handle,
                                 dirfsp,
                                 smb_fname,
                                 fsp,
-                                flags,
-                                mode);
-
+                                how);
        if (fd == -1) {
                return -1;
        }
 
-       if ((flags & (O_CREAT|O_EXCL)) != (O_CREAT|O_EXCL)) {
+       if ((how->flags & (O_CREAT|O_EXCL)) != (O_CREAT|O_EXCL)) {
                return fd;
        }
 
index 62ca9fc1c8fb6b4910ce18592e6a9b236b039974..2f9d92382e593b9c154d46482627c0db7940848b 100644 (file)
@@ -746,9 +746,12 @@ NTSTATUS openat_pathref_dirfsp_nosymlink(
        struct smb_filename *result = NULL;
        struct files_struct *fsp = NULL;
        char *path = NULL, *next = NULL;
-       int flags = O_NOFOLLOW|O_DIRECTORY;
        int fd;
        NTSTATUS status;
+       struct vfs_open_how how = {
+               .flags = O_NOFOLLOW|O_DIRECTORY,
+               .mode = 0,
+       };
 
        DBG_DEBUG("path_in=%s\n", path_in);
 
@@ -765,7 +768,7 @@ NTSTATUS openat_pathref_dirfsp_nosymlink(
         * fsp->fsp_flags.is_pathref will make us become_root() in the
         * non-O_PATH case, which would cause a security problem.
         */
-       flags |= O_PATH;
+       how.flags |= O_PATH;
 #else
 #ifdef O_SEARCH
        /*
@@ -776,7 +779,7 @@ NTSTATUS openat_pathref_dirfsp_nosymlink(
         * function, without either we will incorrectly require also
         * the "r" bit when traversing the directory hierarchy.
         */
-       flags |= O_SEARCH;
+       how.flags |= O_SEARCH;
 #endif
 #endif
 
@@ -807,8 +810,7 @@ next:
                dirfsp,
                &rel_fname,
                fsp,
-               flags,
-               0);
+               &how);
 
        if ((fd == -1) && (errno == ENOENT)) {
                status = get_real_filename_at(
@@ -828,8 +830,7 @@ next:
                        dirfsp,
                        &rel_fname,
                        fsp,
-                       flags,
-                       0);
+                       &how);
        }
 
        if ((fd == -1) && (errno == ENOTDIR)) {
index 30628cc4fd0eff1f86b59bcf93e1d66d4eb28899..a31127774bb56a3de8c6002ca876dc1be8462ac6 100644 (file)
@@ -686,6 +686,7 @@ static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
        struct smb_filename *parent_dir_fname = NULL;
        bool have_opath = false;
        bool is_share_root = false;
+       struct vfs_open_how how = { .flags = flags, .mode = mode };
        int ret;
 
 #ifdef O_PATH
@@ -763,14 +764,13 @@ static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
                SMB_ASSERT(slash == NULL);
        }
 
-       flags |= O_NOFOLLOW;
+       how.flags |= O_NOFOLLOW;
 
        fd = SMB_VFS_OPENAT(conn,
                            dirfsp,
                            smb_fname_rel,
                            fsp,
-                           flags,
-                           mode);
+                           &how);
        if (fd == -1) {
                status = link_errno_convert(errno);
        }
@@ -912,6 +912,7 @@ NTSTATUS fd_openat(const struct files_struct *dirfsp,
        }
 
        if (fsp_is_stream) {
+               struct vfs_open_how how = { .flags = flags, .mode = mode, };
                int fd;
 
                fd = SMB_VFS_OPENAT(
@@ -919,8 +920,7 @@ NTSTATUS fd_openat(const struct files_struct *dirfsp,
                        NULL,   /* stream open is relative to fsp->base_fsp */
                        smb_fname,
                        fsp,
-                       flags,
-                       mode);
+                       &how);
                if (fd == -1) {
                        status = map_nt_error_from_unix(errno);
                }
@@ -1193,6 +1193,7 @@ static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
                                   int flags,
                                   mode_t mode)
 {
+       struct vfs_open_how how = { .flags = flags, .mode = mode };
        struct smb_filename proc_fname;
        const char *p = NULL;
        char buf[PATH_MAX];
@@ -1233,8 +1234,7 @@ static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
                                fsp->conn->cwd_fsp,
                                &proc_fname,
                                fsp,
-                               flags,
-                               mode);
+                               &how);
        if (new_fd == -1) {
                status = map_nt_error_from_unix(errno);
                fd_close(fsp);
index 5d7302c20279af60f13af141e1c73d8b061b245b..ed079b5e938fec0cc57d1a4e3286217809477aa3 100644 (file)
@@ -168,6 +168,7 @@ static NTSTATUS init_files_struct(TALLOC_CTX *mem_ctx,
                                  int flags,
                                  struct files_struct **_fsp)
 {
+       struct vfs_open_how how = { .flags = flags, .mode = 0644 };
        struct smb_filename *smb_fname = NULL;
        int fd;
        mode_t saved_umask;
@@ -209,8 +210,7 @@ static NTSTATUS init_files_struct(TALLOC_CTX *mem_ctx,
                            fspcwd,
                            smb_fname,
                            fsp,
-                           flags,
-                           00644);
+                           &how);
 
        umask(saved_umask);
 
index 334814559112826ac7a5389c138c16193c4ce0c3..09be625ab5f3141e8e6c34719c6000db03a03e62 100644 (file)
@@ -1675,16 +1675,14 @@ int smb_vfs_call_openat(struct vfs_handle_struct *handle,
                        const struct files_struct *dirfsp,
                        const struct smb_filename *smb_fname,
                        struct files_struct *fsp,
-                       int flags,
-                       mode_t mode)
+                       const struct vfs_open_how *how)
 {
        VFS_FIND(openat);
        return handle->fns->openat_fn(handle,
                                      dirfsp,
                                      smb_fname,
                                      fsp,
-                                     flags,
-                                     mode);
+                                     how);
 }
 
 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
index e068fb2f2b17faa4bdc178ff88187baa4e91632e..896197fbd5cb3f0ad93a8cf0b75a0ad66b1dec44 100644 (file)
@@ -298,8 +298,7 @@ static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
 
 static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
-       int flags;
-       mode_t mode;
+       struct vfs_open_how how = { .mode = 0400, };
        const char *flagstr;
        files_struct *fsp;
        struct files_struct *fspcwd = NULL;
@@ -307,8 +306,6 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
        NTSTATUS status;
        int fd;
 
-       mode = 00400;
-
        if (argc < 3 || argc > 5) {
                printf("Usage: open <filename> <flags> <mode>\n");
                printf("  flags: O = O_RDONLY\n");
@@ -330,42 +327,41 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
                printf("        mode defaults to 00400\n");
                return NT_STATUS_OK;
        }
-       flags = 0;
        flagstr = argv[2];
        while (*flagstr) {
                switch (*flagstr) {
                case 'O':
-                       flags |= O_RDONLY;
+                       how.flags |= O_RDONLY;
                        break;
                case 'R':
-                       flags |= O_RDWR;
+                       how.flags |= O_RDWR;
                        break;
                case 'W':
-                       flags |= O_WRONLY;
+                       how.flags |= O_WRONLY;
                        break;
                case 'C':
-                       flags |= O_CREAT;
+                       how.flags |= O_CREAT;
                        break;
                case 'E':
-                       flags |= O_EXCL;
+                       how.flags |= O_EXCL;
                        break;
                case 'T':
-                       flags |= O_TRUNC;
+                       how.flags |= O_TRUNC;
                        break;
                case 'A':
-                       flags |= O_APPEND;
+                       how.flags |= O_APPEND;
                        break;
                case 'N':
-                       flags |= O_NONBLOCK;
+                       how.flags |= O_NONBLOCK;
                        break;
 #ifdef O_SYNC
                case 'S':
-                       flags |= O_SYNC;
+                       how.flags |= O_SYNC;
                        break;
 #endif
 #ifdef O_NOFOLLOW
                case 'F':
-                       flags |= O_NOFOLLOW;
+                       how.flags |= O_NOFOLLOW;
                        break;
 #endif
                default:
@@ -374,8 +370,8 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
                }
                flagstr++;
        }
-       if ((flags & O_CREAT) && argc == 4) {
-               if (sscanf(argv[3], "%ho", (unsigned short *)&mode) == 0) {
+       if ((how.flags & O_CREAT) && argc == 4) {
+               if (sscanf(argv[3], "%ho", (unsigned short *)&how.mode) == 0) {
                        printf("open: error=-1 (invalid mode!)\n");
                        return NT_STATUS_UNSUCCESSFUL;
                }
@@ -427,8 +423,7 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
                            fspcwd,
                            smb_fname,
                            fsp,
-                           flags,
-                           mode);
+                           &how);
        if (fd == -1) {
                printf("open: error=%d (%s)\n", errno, strerror(errno));
                status = map_nt_error_from_unix(errno);
@@ -1733,8 +1728,7 @@ static NTSTATUS cmd_fset_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
 
 static NTSTATUS cmd_set_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
-       int flags;
-       mode_t mode;
+       struct vfs_open_how how = { .mode = 0400, };
        files_struct *fsp;
        struct files_struct *fspcwd = NULL;
        struct smb_filename *smb_fname = NULL;
@@ -1747,7 +1741,6 @@ static NTSTATUS cmd_set_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int a
                return NT_STATUS_OK;
        }
 
-       mode = 00400;
 
        fsp = talloc_zero(vfs, struct files_struct);
        if (fsp == NULL) {
@@ -1770,31 +1763,29 @@ static NTSTATUS cmd_set_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int a
 
        fsp->fsp_name = smb_fname;
 
-#ifdef O_DIRECTORY
-       flags = O_RDONLY|O_DIRECTORY;
-#else
-       /* POSIX allows us to open a directory with O_RDONLY. */
-       flags = O_RDONLY;
-#endif
-
        status = vfs_at_fspcwd(fsp, vfs->conn, &fspcwd);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       how.flags = O_RDWR;
        fd = SMB_VFS_OPENAT(vfs->conn,
                            fspcwd,
                            smb_fname,
                            fsp,
-                           O_RDWR,
-                           mode);
+                           &how);
        if (fd == -1 && errno == EISDIR) {
+#ifdef O_DIRECTORY
+               how.flags = O_RDONLY|O_DIRECTORY;
+#else
+       /* POSIX allows us to open a directory with O_RDONLY. */
+               how.flags = O_RDONLY;
+#endif
                fd = SMB_VFS_OPENAT(vfs->conn,
                                    fspcwd,
                                    smb_fname,
                                    fsp,
-                                   flags,
-                                   mode);
+                                   &how);
        }
        if (fd == -1) {
                printf("open: error=%d (%s)\n", errno, strerror(errno));