From: Volker Lendecke Date: Fri, 3 Jun 2022 13:53:29 +0000 (+0200) Subject: vfs: change openat propotype to match linux openat2 X-Git-Tag: samba-4.17.0rc1~57 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5fc016f26852a1cc1d7809919ff00cc0404e23e3;p=thirdparty%2Fsamba.git vfs: change openat propotype to match linux openat2 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 Signed-off-by: Volker Lendecke Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 23614b660d9..61c343f5434 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -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; diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 9fc211c5e2e..8fb8644ad09 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -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, diff --git a/source3/include/vfs.h b/source3/include/vfs.h index be4712689eb..e65d857d220 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -373,6 +373,7 @@ * 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, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 840e77cf1b0..c7089b62964 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -142,10 +142,12 @@ 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) \ diff --git a/source3/modules/vfs_aio_pthread.c b/source3/modules/vfs_aio_pthread.c index d58e990a666..b4245ee89dc 100644 --- a/source3/modules/vfs_aio_pthread.c +++ b/source3/modules/vfs_aio_pthread.c @@ -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 diff --git a/source3/modules/vfs_audit.c b/source3/modules/vfs_audit.c index 91fbd8c19ba..2b01a6a8d91 100644 --- a/source3/modules/vfs_audit.c +++ b/source3/modules/vfs_audit.c @@ -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) : ""); diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index 43c8edb8932..ac2c1b0410d 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -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; } diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index f40bec3b74c..36aa43123fd 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -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; } diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c index 14582905212..59747db16c3 100644 --- a/source3/modules/vfs_ceph.c +++ b/source3/modules/vfs_ceph.c @@ -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; diff --git a/source3/modules/vfs_ceph_snapshots.c b/source3/modules/vfs_ceph_snapshots.c index 06ef5538450..c981cebd8a2 100644 --- a/source3/modules/vfs_ceph_snapshots.c +++ b/source3/modules/vfs_ceph_snapshots.c @@ -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; } diff --git a/source3/modules/vfs_commit.c b/source3/modules/vfs_commit.c index 6d64896c7e0..c7625b0837c 100644 --- a/source3/modules/vfs_commit.c +++ b/source3/modules/vfs_commit.c @@ -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; diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index ef68a96282e..6bfda596d8a 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -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; diff --git a/source3/modules/vfs_error_inject.c b/source3/modules/vfs_error_inject.c index 9ead2c26727..1a327097b30 100644 --- a/source3/modules/vfs_error_inject.c +++ b/source3/modules/vfs_error_inject.c @@ -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, diff --git a/source3/modules/vfs_extd_audit.c b/source3/modules/vfs_extd_audit.c index 3ac75fb890e..91dce6c7dc5 100644 --- a/source3/modules/vfs_extd_audit.c +++ b/source3/modules/vfs_extd_audit.c @@ -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) : ""); diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c index 685c15bcaa7..737f44eb03f 100644 --- a/source3/modules/vfs_fruit.c +++ b/source3/modules/vfs_fruit.c @@ -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)); diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 6d38738ac52..25fd0cad326 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -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; diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c index 23bcf83d31c..081bc0c7c07 100644 --- a/source3/modules/vfs_glusterfs.c +++ b/source3/modules/vfs_glusterfs.c @@ -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) { diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index db167d00226..bb15ba630b9 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -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); } diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c index 38340daa3af..2ef9b89d1eb 100644 --- a/source3/modules/vfs_media_harmony.c +++ b/source3/modules/vfs_media_harmony.c @@ -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: diff --git a/source3/modules/vfs_not_implemented.c b/source3/modules/vfs_not_implemented.c index 3bfd86a9613..3c017c68bb8 100644 --- a/source3/modules/vfs_not_implemented.c +++ b/source3/modules/vfs_not_implemented.c @@ -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; diff --git a/source3/modules/vfs_prealloc.c b/source3/modules/vfs_prealloc.c index 467f619b8df..51e9ad0d8fb 100644 --- a/source3/modules/vfs_prealloc.c +++ b/source3/modules/vfs_prealloc.c @@ -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, diff --git a/source3/modules/vfs_preopen.c b/source3/modules/vfs_preopen.c index 8d85dda92ec..3b7fae5940b 100644 --- a/source3/modules/vfs_preopen.c +++ b/source3/modules/vfs_preopen.c @@ -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; } diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index e8aa224648c..0e849d7cc41 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -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)); diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c index 15707ac0304..6c9a14a725f 100644 --- a/source3/modules/vfs_snapper.c +++ b/source3/modules/vfs_snapper.c @@ -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; } diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index 6722d712bff..47e3b3605e6 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -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); diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index dd689261449..ed03aa3b454 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -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; } diff --git a/source3/modules/vfs_syncops.c b/source3/modules/vfs_syncops.c index 14c860127b3..94dcd7b846e 100644 --- a/source3/modules/vfs_syncops.c +++ b/source3/modules/vfs_syncops.c @@ -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, diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index 481a9b0829f..e7633285607 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -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; diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c index 30200da9ae4..3c1a263c25a 100644 --- a/source3/modules/vfs_unityed_media.c +++ b/source3/modules/vfs_unityed_media.c @@ -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", diff --git a/source3/modules/vfs_virusfilter.c b/source3/modules/vfs_virusfilter.c index cbb93161a8a..124b4091c1b 100644 --- a/source3/modules/vfs_virusfilter.c +++ b/source3/modules/vfs_virusfilter.c @@ -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); diff --git a/source3/modules/vfs_widelinks.c b/source3/modules/vfs_widelinks.c index 1cbb0bf0ad0..2a35ea5eb68 100644 --- a/source3/modules/vfs_widelinks.c +++ b/source3/modules/vfs_widelinks.c @@ -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, diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index 42c570b54b3..07b95899d80 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -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; } diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 62ca9fc1c8f..2f9d92382e5 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -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)) { diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 30628cc4fd0..a31127774bb 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -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); diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c index 5d7302c2027..ed079b5e938 100644 --- a/source3/smbd/pysmbd.c +++ b/source3/smbd/pysmbd.c @@ -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); diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 33481455911..09be625ab5f 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -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, diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index e068fb2f2b1..896197fbd5c 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -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 \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));