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;
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,
* 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
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).
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,
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,
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,
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) \
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;
/* 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);
}
/*
}
/* 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
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) : "");
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;
dirfsp,
smb_fname,
fsp,
- flags,
- mode);
-
+ how);
if (ret == -1) {
saved_errno = errno;
}
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;
dirfsp,
smb_fname,
fsp,
- flags,
- mode);
-
+ how);
if (ret == -1) {
saved_errno = errno;
}
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;
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;
dirfsp,
smb_fname_in,
fsp,
- flags,
- mode);
+ how);
}
ret = ceph_snap_gmt_convert(handle,
dirfsp,
smb_fname,
fsp,
- flags,
- mode);
+ how);
if (ret == -1) {
saved_errno = errno;
}
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;
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 */
}
}
- 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;
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;
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);
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,
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),
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) : "");
{
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));
dirfsp,
smb_fname,
fsp,
- open_flags,
- mode);
+ &how);
if (fd != -1) {
return fd;
}
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,
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;
dirfsp,
smb_fname,
fsp,
- flags,
- mode);
+ how);
}
SMB_ASSERT(fsp_is_alternate_stream(fsp));
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);
}
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);
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));
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;
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;
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) {
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;
}
if (config->syncio) {
- flags |= O_SYNC;
+ how.flags |= O_SYNC;
}
ext = VFS_ADD_FSP_EXTENSION(handle, fsp, struct gpfs_fsp_extension,
*/
*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);
}
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;
dirfsp,
smb_fname,
fsp,
- flags,
- mode);
+ how);
goto out;
}
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:
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;
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.
*/
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;
}
* 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);
*/
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,
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;
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;
}
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;
* 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,
* 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;
}
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;
}
#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));
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;
dirfsp,
smb_fname_in,
fsp,
- flags,
- mode);
+ how);
}
smb_fname = cp_smb_filename(talloc_tos(), smb_fname_in);
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;
}
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;
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(
fspcwd,
smb_fname_stream,
fsp,
- flags,
- mode);
+ how);
done:
TALLOC_FREE(smb_fname_stream);
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;
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));
goto fail;
}
- if (!(flags & O_CREAT)) {
+ if (!(how->flags & O_CREAT)) {
errno = ENOATTR;
goto fail;
}
set_empty_xattr = true;
}
- if (flags & O_TRUNC) {
+ if (how->flags & O_TRUNC) {
set_empty_xattr = true;
}
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;
}
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,
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;
dirfsp,
smb_fname,
fsp,
- flags,
- mode);
+ how);
clock_gettime_mono(&ts2);
timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
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;
dirfsp,
smb_fname,
fsp,
- flags,
- mode);
+ how);
}
if (alloc_get_client_smb_fname(handle, talloc_tos(),
dirfsp,
client_fname,
fsp,
- flags,
- mode);
+ how);
err:
TALLOC_FREE(client_fname);
DEBUG(10, ("Leaving with smb_fname->base_name '%s'\n",
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;
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;
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);
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,
* 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,
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;
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;
}
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);
* 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
/*
* 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
dirfsp,
&rel_fname,
fsp,
- flags,
- 0);
+ &how);
if ((fd == -1) && (errno == ENOENT)) {
status = get_real_filename_at(
dirfsp,
&rel_fname,
fsp,
- flags,
- 0);
+ &how);
}
if ((fd == -1) && (errno == ENOTDIR)) {
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
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);
}
}
if (fsp_is_stream) {
+ struct vfs_open_how how = { .flags = flags, .mode = mode, };
int fd;
fd = SMB_VFS_OPENAT(
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);
}
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];
fsp->conn->cwd_fsp,
&proc_fname,
fsp,
- flags,
- mode);
+ &how);
if (new_fd == -1) {
status = map_nt_error_from_unix(errno);
fd_close(fsp);
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;
fspcwd,
smb_fname,
fsp,
- flags,
- 00644);
+ &how);
umask(saved_umask);
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,
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;
NTSTATUS status;
int fd;
- mode = 00400;
-
if (argc < 3 || argc > 5) {
printf("Usage: open <filename> <flags> <mode>\n");
printf(" flags: O = O_RDONLY\n");
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:
}
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;
}
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);
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;
return NT_STATUS_OK;
}
- mode = 00400;
fsp = talloc_zero(vfs, struct files_struct);
if (fsp == NULL) {
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));