summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorTim Prouty <tprouty@samba.org>2009-06-16 12:01:13 -0700
committerTim Prouty <tprouty@samba.org>2009-06-17 20:11:53 -0700
commit4e3656b8d1d0bf8c0c4ade01332e7384ea890810 (patch)
treeefcb240c8b0dbdd791e01dfe62a50f4cfdca47e5 /source3
parent5cfac1a1bd59712d7a771d3631e869c5d078a0f3 (diff)
downloadsamba-4e3656b8d1d0bf8c0c4ade01332e7384ea890810.tar.gz
samba-4e3656b8d1d0bf8c0c4ade01332e7384ea890810.tar.bz2
samba-4e3656b8d1d0bf8c0c4ade01332e7384ea890810.zip
s3: Change SMB_VFS_OPEN to take an smb_filename struct
This was a little messy because of all of the vfs modules I had to touch. Most of them were pretty straight forward, but the streams modules required a little attention to handle smb_filename. Since the use of smb_filename enables the vfs modules to access the raw, over-the-wire stream, a little bit of the handling that was being done by split_ntfs_stream_name has now been shifted into the individual stream modules. It may be a little more code, but overall it gives more flexibility to the streams modules, while also allowing correct stream handling.
Diffstat (limited to 'source3')
-rw-r--r--source3/include/proto.h1
-rw-r--r--source3/include/vfs.h7
-rw-r--r--source3/modules/vfs_acl_tdb.c20
-rw-r--r--source3/modules/vfs_acl_xattr.c20
-rw-r--r--source3/modules/vfs_audit.c10
-rw-r--r--source3/modules/vfs_cap.c22
-rw-r--r--source3/modules/vfs_catia.c18
-rw-r--r--source3/modules/vfs_commit.c6
-rw-r--r--source3/modules/vfs_default.c22
-rw-r--r--source3/modules/vfs_extd_audit.c12
-rw-r--r--source3/modules/vfs_full_audit.c9
-rw-r--r--source3/modules/vfs_onefs.c5
-rw-r--r--source3/modules/vfs_onefs_shadow_copy.c11
-rw-r--r--source3/modules/vfs_prealloc.c13
-rw-r--r--source3/modules/vfs_preopen.c17
-rw-r--r--source3/modules/vfs_shadow_copy2.c31
-rw-r--r--source3/modules/vfs_streams_depot.c111
-rw-r--r--source3/modules/vfs_streams_xattr.c117
-rw-r--r--source3/modules/vfs_syncops.c25
-rw-r--r--source3/smbd/filename.c5
-rw-r--r--source3/smbd/nttrans.c16
-rw-r--r--source3/smbd/open.c8
-rw-r--r--source3/torture/cmd_vfs.c13
23 files changed, 392 insertions, 127 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 8435b790a8..4ae141e89d 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6583,6 +6583,7 @@ void send_nt_replies(connection_struct *conn,
char *pdata, int datasize);
bool is_ntfs_stream_name(const char *fname);
bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname);
+bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname);
void reply_ntcreate_and_X(struct smb_request *req);
void reply_ntcancel(struct smb_request *req);
void reply_ntrename(struct smb_request *req);
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index e0e022877a..53a4798d37 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -117,7 +117,8 @@
/* Leave at 25 - not yet released. Add init_search_op call. - sdann */
/* Leave at 25 - not yet released. Add locking calls. -- zkirsch. */
/* Leave at 25 - not yet released. Add strict locking calls. -- drichards. */
-/* Changed to version 26 - Plumb struct smb_filename to SMB_VFS_CREATE_FILE. */
+/* Changed to version 26 - Plumb struct smb_filename to SMB_VFS_CREATE_FILE,
+ SMB_VFS_OPEN. */
#define SMB_VFS_INTERFACE_VERSION 26
@@ -330,7 +331,9 @@ struct vfs_ops {
/* File operations */
- int (*open)(struct vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode);
+ int (*open)(struct vfs_handle_struct *handle,
+ struct smb_filename *smb_fname, files_struct *fsp,
+ int flags, mode_t mode);
NTSTATUS (*create_file)(struct vfs_handle_struct *handle,
struct smb_request *req,
uint16_t root_dir_fid,
diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
index 463250a9ed..e0a5b14c67 100644
--- a/source3/modules/vfs_acl_tdb.c
+++ b/source3/modules/vfs_acl_tdb.c
@@ -549,7 +549,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
*********************************************************************/
static int open_acl_tdb(vfs_handle_struct *handle,
- const char *fname,
+ struct smb_filename *smb_fname,
files_struct *fsp,
int flags,
mode_t mode)
@@ -557,7 +557,17 @@ static int open_acl_tdb(vfs_handle_struct *handle,
uint32_t access_granted = 0;
struct security_descriptor *pdesc = NULL;
bool file_existed = true;
- NTSTATUS status = get_nt_acl_tdb_internal(handle,
+ char *fname = NULL;
+ NTSTATUS status;
+
+ status = get_full_smb_filename(talloc_tos(), smb_fname,
+ &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
+ status = get_nt_acl_tdb_internal(handle,
NULL,
fname,
(OWNER_SECURITY_INFORMATION |
@@ -573,7 +583,7 @@ static int open_acl_tdb(vfs_handle_struct *handle,
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10,("open_acl_tdb: file %s open "
"refused with error %s\n",
- fname,
+ smb_fname_str_dbg(smb_fname),
nt_errstr(status) ));
errno = map_errno_from_nt_status(status);
return -1;
@@ -584,10 +594,10 @@ static int open_acl_tdb(vfs_handle_struct *handle,
DEBUG(10,("open_acl_tdb: get_nt_acl_attr_internal for "
"file %s returned %s\n",
- fname,
+ smb_fname_str_dbg(smb_fname),
nt_errstr(status) ));
- fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
if (!file_existed && fsp->fh->fd != -1) {
/* File was created. Inherit from parent directory. */
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index 05156f8456..efcc87740a 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -417,7 +417,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
*********************************************************************/
static int open_acl_xattr(vfs_handle_struct *handle,
- const char *fname,
+ struct smb_filename *smb_fname,
files_struct *fsp,
int flags,
mode_t mode)
@@ -425,7 +425,17 @@ static int open_acl_xattr(vfs_handle_struct *handle,
uint32_t access_granted = 0;
struct security_descriptor *pdesc = NULL;
bool file_existed = true;
- NTSTATUS status = get_nt_acl_xattr_internal(handle,
+ char *fname = NULL;
+ NTSTATUS status;
+
+ status = get_full_smb_filename(talloc_tos(), smb_fname,
+ &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
+ status = get_nt_acl_xattr_internal(handle,
NULL,
fname,
(OWNER_SECURITY_INFORMATION |
@@ -441,7 +451,7 @@ static int open_acl_xattr(vfs_handle_struct *handle,
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10,("open_acl_xattr: file %s open "
"refused with error %s\n",
- fname,
+ smb_fname_str_dbg(smb_fname),
nt_errstr(status) ));
errno = map_errno_from_nt_status(status);
return -1;
@@ -452,10 +462,10 @@ static int open_acl_xattr(vfs_handle_struct *handle,
DEBUG(10,("open_acl_xattr: get_nt_acl_attr_internal for "
"file %s returned %s\n",
- fname,
+ smb_fname_str_dbg(smb_fname),
nt_errstr(status) ));
- fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
if (!file_existed && fsp->fh->fd != -1) {
/* File was created. Inherit from parent directory. */
diff --git a/source3/modules/vfs_audit.c b/source3/modules/vfs_audit.c
index 4000580c42..2897cefb96 100644
--- a/source3/modules/vfs_audit.c
+++ b/source3/modules/vfs_audit.c
@@ -33,7 +33,7 @@ static void audit_disconnect(vfs_handle_struct *handle);
static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr);
static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode);
static int audit_rmdir(vfs_handle_struct *handle, const char *path);
-static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode);
+static int audit_open(vfs_handle_struct *handle, struct smb_filename *smb_fname, files_struct *fsp, int flags, mode_t mode);
static int audit_close(vfs_handle_struct *handle, files_struct *fsp);
static int audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname);
static int audit_unlink(vfs_handle_struct *handle, const char *path);
@@ -187,14 +187,16 @@ static int audit_rmdir(vfs_handle_struct *handle, const char *path)
return result;
}
-static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode)
+static int audit_open(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname, files_struct *fsp,
+ int flags, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ result = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n",
- fname, result,
+ smb_fname_str_dbg(smb_fname), result,
((flags & O_WRONLY) || (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 e26d29d667..4525fa1da3 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -106,16 +106,30 @@ static int cap_rmdir(vfs_handle_struct *handle, const char *path)
return SMB_VFS_NEXT_RMDIR(handle, cappath);
}
-static int cap_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode)
+static int cap_open(vfs_handle_struct *handle, struct smb_filename *smb_fname,
+ files_struct *fsp, int flags, mode_t mode)
{
- char *cappath = capencode(talloc_tos(), fname);
+ char *cappath;
+ char *tmp_base_name = NULL;
+ int ret;
+
+ cappath = capencode(talloc_tos(), smb_fname->base_name);
if (!cappath) {
errno = ENOMEM;
return -1;
}
- DEBUG(3,("cap: cap_open for %s\n", fname));
- return SMB_VFS_NEXT_OPEN(handle, cappath, fsp, flags, mode);
+
+ tmp_base_name = smb_fname->base_name;
+ smb_fname->base_name = cappath;
+
+ DEBUG(3,("cap: cap_open for %s\n", smb_fname_str_dbg(smb_fname)));
+ ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+
+ smb_fname->base_name = tmp_base_name;
+ TALLOC_FREE(cappath);
+
+ return ret;
}
static int cap_rename(vfs_handle_struct *handle, const char *oldname, const char *newname)
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 2870254bfb..8d1c87a9fc 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -133,18 +133,30 @@ static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle,
}
static int catia_open(vfs_handle_struct *handle,
- const char *fname,
+ struct smb_filename *smb_fname,
files_struct *fsp,
int flags,
mode_t mode)
{
- char *name = to_unix(talloc_tos(), fname);
+ char *name;
+ char *tmp_base_name;
+ int ret;
+ name = to_unix(talloc_tos(), smb_fname->base_name);
if (!name) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_OPEN(handle, name, fsp, flags, mode);
+
+ tmp_base_name = smb_fname->base_name;
+ smb_fname->base_name = name;
+
+ ret = SMB_VFS_NEXT_OPEN(handle, name, fsp, flags, mode);
+
+ smb_fname->base_name = tmp_base_name;
+ TALLOC_FREE(name);
+
+ return ret;
}
static int catia_rename(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_commit.c b/source3/modules/vfs_commit.c
index c22e8161d7..6c363229d3 100644
--- a/source3/modules/vfs_commit.c
+++ b/source3/modules/vfs_commit.c
@@ -167,7 +167,7 @@ static int commit_connect(
static int commit_open(
vfs_handle_struct * handle,
- const char * fname,
+ struct smb_filename *smb_fname,
files_struct * fsp,
int flags,
mode_t mode)
@@ -179,7 +179,7 @@ static int commit_open(
/* Don't bother with read-only files. */
if ((flags & O_ACCMODE) == O_RDONLY) {
- return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
}
/* Read and check module configuration */
@@ -208,7 +208,7 @@ static int commit_open(
}
}
- fd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
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 28adce5768..0e7ba05632 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -214,13 +214,31 @@ static void vfswrap_init_search_op(vfs_handle_struct *handle,
/* File operations */
-static int vfswrap_open(vfs_handle_struct *handle, const char *fname,
- files_struct *fsp, int flags, mode_t mode)
+static int vfswrap_open(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ files_struct *fsp, int flags, mode_t mode)
{
int result;
+ NTSTATUS status;
+ char *fname = NULL;
START_PROFILE(syscall_open);
+
+ /*
+ * XXX: Should an error be returned if there is a stream rather than
+ * trying to open a filename with a ':'?
+ */
+ status = get_full_smb_filename(talloc_tos(), smb_fname,
+ &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
result = sys_open(fname, flags, mode);
+
+ TALLOC_FREE(fname);
+
END_PROFILE(syscall_open);
return result;
}
diff --git a/source3/modules/vfs_extd_audit.c b/source3/modules/vfs_extd_audit.c
index b59a780f52..763f1545d7 100644
--- a/source3/modules/vfs_extd_audit.c
+++ b/source3/modules/vfs_extd_audit.c
@@ -36,7 +36,7 @@ static void audit_disconnect(vfs_handle_struct *handle);
static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr);
static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode);
static int audit_rmdir(vfs_handle_struct *handle, const char *path);
-static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode);
+static int audit_open(vfs_handle_struct *handle, struct smb_filename *smb_fname, files_struct *fsp, int flags, mode_t mode);
static int audit_close(vfs_handle_struct *handle, files_struct *fsp);
static int audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname);
static int audit_unlink(vfs_handle_struct *handle, const char *path);
@@ -216,21 +216,23 @@ static int audit_rmdir(vfs_handle_struct *handle, const char *path)
return result;
}
-static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode)
+static int audit_open(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname, files_struct *fsp,
+ int flags, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ result = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
if (lp_syslog() > 0) {
syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n",
- fname, result,
+ smb_fname_str_dbg(smb_fname), result,
((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
}
DEBUG(2, ("vfs_extd_audit: open %s %s %s\n",
- fname,
+ smb_fname_str_dbg(smb_fname),
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : ""));
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index e2d08b440f..5558b2f9b5 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -111,7 +111,7 @@ static int smb_full_audit_closedir(vfs_handle_struct *handle,
static void smb_full_audit_init_search_op(vfs_handle_struct *handle,
SMB_STRUCT_DIR *dirp);
static int smb_full_audit_open(vfs_handle_struct *handle,
- const char *fname, files_struct *fsp, int flags, mode_t mode);
+ struct smb_filename *smb_fnmae, files_struct *fsp, int flags, mode_t mode);
static NTSTATUS smb_full_audit_create_file(vfs_handle_struct *handle,
struct smb_request *req,
uint16_t root_dir_fid,
@@ -1179,15 +1179,16 @@ static void smb_full_audit_init_search_op(vfs_handle_struct *handle,
}
static int smb_full_audit_open(vfs_handle_struct *handle,
- const char *fname, files_struct *fsp, int flags, mode_t mode)
+ struct smb_filename *smb_fname,
+ files_struct *fsp, int flags, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ result = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
do_log(SMB_VFS_OP_OPEN, (result >= 0), handle, "%s|%s",
((flags & O_WRONLY) || (flags & O_RDWR))?"w":"r",
- fname);
+ smb_fname_str_dbg(smb_fname));
return result;
}
diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c
index 7414f16cf9..c143fcf54b 100644
--- a/source3/modules/vfs_onefs.c
+++ b/source3/modules/vfs_onefs.c
@@ -47,12 +47,13 @@ static int onefs_mkdir(vfs_handle_struct *handle, const char *path,
return SMB_VFS_NEXT_MKDIR(handle, path, mode);
}
-static int onefs_open(vfs_handle_struct *handle, const char *fname,
+static int onefs_open(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
files_struct *fsp, int flags, mode_t mode)
{
/* SMB_VFS_OPEN should never be called in vfs_onefs */
SMB_ASSERT(false);
- return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
}
static ssize_t onefs_sendfile(vfs_handle_struct *handle, int tofd,
diff --git a/source3/modules/vfs_onefs_shadow_copy.c b/source3/modules/vfs_onefs_shadow_copy.c
index 3d4ffc9084..45860fa90d 100644
--- a/source3/modules/vfs_onefs_shadow_copy.c
+++ b/source3/modules/vfs_onefs_shadow_copy.c
@@ -214,12 +214,13 @@ onefs_shadow_copy_rmdir(vfs_handle_struct *handle, const char *path)
}
static int
-onefs_shadow_copy_open(vfs_handle_struct *handle, const char *path,
- files_struct *fsp, int flags, mode_t mode)
+onefs_shadow_copy_open(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname, files_struct *fsp,
+ int flags, mode_t mode)
{
- SHADOW_NEXT(OPEN,
- (handle, cpath ?: path, fsp, flags, mode),
- int);
+ SHADOW_NEXT_SMB_FNAME(OPEN,
+ (handle, smb_fname, fsp, flags, mode),
+ int);
}
static NTSTATUS
diff --git a/source3/modules/vfs_prealloc.c b/source3/modules/vfs_prealloc.c
index 299f6548a1..2f65e94ea7 100644
--- a/source3/modules/vfs_prealloc.c
+++ b/source3/modules/vfs_prealloc.c
@@ -108,7 +108,7 @@ static int prealloc_connect(
}
static int prealloc_open(vfs_handle_struct* handle,
- const char * fname,
+ struct smb_filename *smb_fname,
files_struct * fsp,
int flags,
mode_t mode)
@@ -127,7 +127,7 @@ static int prealloc_open(vfs_handle_struct* handle,
}
*fext = '\0';
- dot = strrchr(fname, '.');
+ dot = strrchr(smb_fname->base_name, '.');
if (dot && *++dot) {
if (strlen(dot) < sizeof(fext)) {
strncpy(fext, dot, sizeof(fext));
@@ -152,7 +152,7 @@ static int prealloc_open(vfs_handle_struct* handle,
goto normal_open;
}
- fd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
if (fd < 0) {
return fd;
}
@@ -171,7 +171,8 @@ static int prealloc_open(vfs_handle_struct* handle,
DEBUG(module_debug,
("%s: preallocating %s (fd=%d) to %lld bytes\n",
- MODULE, fname, fd, (long long)size));
+ MODULE, smb_fname_str_dbg(smb_fname), fd,
+ (long long)size));
*psize = size;
if (preallocate_space(fd, *psize) < 0) {
@@ -186,8 +187,8 @@ normal_open:
* preallocation.
*/
DEBUG(module_debug, ("%s: skipping preallocation for %s\n",
- MODULE, fname));
- return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ MODULE, smb_fname_str_dbg(smb_fname)));
+ return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
}
static int prealloc_ftruncate(vfs_handle_struct * handle,
diff --git a/source3/modules/vfs_preopen.c b/source3/modules/vfs_preopen.c
index 25b9e7f3e4..dcc1ae18c1 100644
--- a/source3/modules/vfs_preopen.c
+++ b/source3/modules/vfs_preopen.c
@@ -371,21 +371,22 @@ static bool preopen_parse_fname(const char *fname, unsigned long *pnum,
return true;
}
-static int preopen_open(vfs_handle_struct *handle, const char *fname,
- files_struct *fsp, int flags, mode_t mode)
+static int preopen_open(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname, files_struct *fsp,
+ int flags, mode_t mode)
{
struct preopen_state *state;
int res;
unsigned long num;
- DEBUG(10, ("preopen_open called on %s\n", fname));
+ DEBUG(10, ("preopen_open called on %s\n", smb_fname_str_dbg(smb_fname)));
state = preopen_state_get(handle);
if (state == NULL) {
- return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
}
- res = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ res = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
if (res == -1) {
return -1;
}
@@ -394,15 +395,15 @@ static int preopen_open(vfs_handle_struct *handle, const char *fname,
return res;
}
- if (!is_in_path(fname, state->preopen_names, true)) {
+ if (!is_in_path(smb_fname->base_name, state->preopen_names, true)) {
DEBUG(10, ("%s does not match the preopen:names list\n",
- fname));
+ smb_fname_str_dbg(smb_fname)));
return res;
}
TALLOC_FREE(state->template_fname);
state->template_fname = talloc_asprintf(
- state, "%s/%s", fsp->conn->connectpath, fname);
+ state, "%s/%s", fsp->conn->connectpath, smb_fname->base_name);
if (state->template_fname == NULL) {
return res;
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 030d3e2b01..7b5b85d4be 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -115,6 +115,28 @@ static inline bool shadow_copy2_match_name(const char *name)
} \
} while (0)
+#define _SHADOW2_NEXT_SMB_FNAME(op, args, rtype, eret, extra) do { \
+ if (shadow_copy2_match_name(smb_fname->base_name)) { \
+ char *name2; \
+ char *smb_base_name_tmp = NULL; \
+ rtype ret; \
+ name2 = convert_shadow2_name(handle, smb_fname->base_name); \
+ if (name2 == NULL) { \
+ errno = EINVAL; \
+ return eret; \
+ } \
+ smb_base_name_tmp = smb_fname->base_name; \
+ smb_fname->base_name = name2; \
+ ret = SMB_VFS_NEXT_ ## op args; \
+ smb_fname->base_name = smb_base_name_tmp; \
+ talloc_free(name2); \
+ if (ret != eret) extra; \
+ return ret; \
+ } else { \
+ return SMB_VFS_NEXT_ ## op args; \
+ } \
+} while (0)
+
/*
convert a name to the shadow directory: NTSTATUS-specific handling
*/
@@ -143,6 +165,8 @@ static inline bool shadow_copy2_match_name(const char *name)
#define SHADOW2_NEXT(op, args, rtype, eret) _SHADOW2_NEXT(op, args, rtype, eret, )
+#define SHADOW2_NEXT_SMB_FNAME(op, args, rtype, eret) _SHADOW2_NEXT_SMB_FNAME(op, args, rtype, eret, )
+
#define SHADOW2_NEXT2(op, args) do { \
if (shadow_copy2_match_name(oldname) || shadow_copy2_match_name(newname)) { \
errno = EROFS; \
@@ -337,9 +361,12 @@ static int shadow_copy2_link(vfs_handle_struct *handle,
}
static int shadow_copy2_open(vfs_handle_struct *handle,
- const char *fname, files_struct *fsp, int flags, mode_t mode)
+ struct smb_filename *smb_fname, files_struct *fsp,
+ int flags, mode_t mode)
{
- SHADOW2_NEXT(OPEN, (handle, name, fsp, flags, mode), int, -1);
+ SHADOW2_NEXT_SMB_FNAME(OPEN,
+ (handle, smb_fname, fsp, flags, mode),
+ int, -1);
}
static SMB_STRUCT_DIR *shadow_copy2_opendir(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index 72affe402a..7d37af0181 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -267,6 +267,69 @@ static char *stream_dir(vfs_handle_struct *handle, const char *base_path,
TALLOC_FREE(result);
return NULL;
}
+/**
+ * Given a stream name, populate smb_fname_out with the actual location of the
+ * stream.
+ */
+static NTSTATUS stream_smb_fname(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ struct smb_filename **smb_fname_out,
+ bool create_dir)
+{
+ char *dirname, *stream_fname;
+ const char *stype;
+ NTSTATUS status;
+
+ *smb_fname_out = NULL;
+
+ dirname = stream_dir(handle, smb_fname->base_name, NULL, create_dir);
+
+ if (dirname == NULL) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ stype = strchr_m(smb_fname->stream_name + 1, ':');
+
+ stream_fname = talloc_asprintf(talloc_tos(), "%s/%s", dirname,
+ smb_fname->stream_name);
+
+ if (stream_fname == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (stype == NULL) {
+ /* Append an explicit stream type if one wasn't specified. */
+ stream_fname = talloc_asprintf(talloc_tos(), "%s:$DATA",
+ stream_fname);
+ if (stream_fname == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+ } else {
+ /* Normalize the stream type to upercase. */
+ strupper_m(strrchr_m(stream_fname, ':') + 1);
+ }
+
+ DEBUG(10, ("stream filename = %s\n", stream_fname));
+
+ /* Create an smb_filename with stream_name == NULL. */
+ status = create_synthetic_smb_fname(talloc_tos(),
+ stream_fname,
+ NULL, NULL,
+ smb_fname_out);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ return NT_STATUS_OK;
+
+ fail:
+ DEBUG(5, ("stream_name failed: %s\n", strerror(errno)));
+ TALLOC_FREE(*smb_fname_out);
+ return status;
+}
static char *stream_name(vfs_handle_struct *handle, const char *fname,
bool create_dir)
@@ -422,50 +485,52 @@ static int streams_depot_lstat(vfs_handle_struct *handle, const char *fname,
return ret;
}
-static int streams_depot_open(vfs_handle_struct *handle, const char *fname,
+static int streams_depot_open(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
files_struct *fsp, int flags, mode_t mode)
{
- TALLOC_CTX *frame;
- char *base = NULL;
- char *sname = NULL;
+ struct smb_filename *smb_fname_stream = NULL;
SMB_STRUCT_STAT base_sbuf;
- char *stream_fname;
+ NTSTATUS status;
int ret = -1;
- if (!is_ntfs_stream_name(fname)) {
- return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ if (!is_ntfs_stream_smb_fname(smb_fname)) {
+ ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+ return ret;
}
- frame = talloc_stackframe();
+ /* If the default stream is requested, just open the base file. */
+ if (is_ntfs_default_stream_smb_fname(smb_fname)) {
+ char *tmp_stream_name;
- if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), fname,
- &base, &sname))) {
- errno = ENOMEM;
- goto done;
- }
+ tmp_stream_name = smb_fname->stream_name;
+ smb_fname->stream_name = NULL;
- if (!sname) {
- ret = SMB_VFS_NEXT_OPEN(handle, base, fsp, flags, mode);
- goto done;
+ ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+
+ smb_fname->stream_name = tmp_stream_name;
+
+ return ret;
}
- ret = SMB_VFS_NEXT_STAT(handle, base, &base_sbuf);
+ /* Ensure the base file still exists. */
+ ret = SMB_VFS_NEXT_STAT(handle, smb_fname->base_name, &base_sbuf);
if (ret == -1) {
goto done;
}
- TALLOC_FREE(base);
-
- stream_fname = stream_name(handle, fname, true);
- if (stream_fname == NULL) {
+ status = stream_smb_fname(handle, smb_fname, &smb_fname_stream, true);
+ if (!NT_STATUS_IS_OK(status)) {
+ ret = -1;
+ errno = map_errno_from_nt_status(status);
goto done;
}
- ret = SMB_VFS_NEXT_OPEN(handle, stream_fname, fsp, flags, mode);
+ ret = SMB_VFS_NEXT_OPEN(handle, smb_fname_stream, fsp, flags, mode);
done:
- TALLOC_FREE(frame);
+ TALLOC_FREE(smb_fname_stream);
return ret;
}
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index ebc51e79e3..715e1a7baf 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -88,6 +88,43 @@ static ssize_t get_xattr_size(connection_struct *conn,
return result;
}
+/**
+ * Given a stream name, populate xattr_name with the xattr name to use for
+ * accessing the stream.
+ */
+static NTSTATUS streams_xattr_get_name(TALLOC_CTX *ctx,
+ const char *stream_name,
+ char **xattr_name)
+{
+ char *stype;
+
+ stype = strchr_m(stream_name + 1, ':');
+
+ *xattr_name = talloc_asprintf(ctx, "%s%s",
+ SAMBA_XATTR_DOSSTREAM_PREFIX,
+ stream_name + 1);
+ if (*xattr_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (stype == NULL) {
+ /* Append an explicit stream type if one wasn't specified. */
+ *xattr_name = talloc_asprintf(ctx, "%s:$DATA",
+ *xattr_name);
+ if (*xattr_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ } else {
+ /* Normalize the stream type to upercase. */
+ strupper_m(strrchr_m(*xattr_name, ':') + 1);
+ }
+
+ DEBUG(10, ("xattr_name: %s, stream_name: %s\n", *xattr_name,
+ stream_name));
+
+ return NT_STATUS_OK;
+}
+
static bool streams_xattr_recheck(struct stream_io *sio)
{
NTSTATUS status;
@@ -277,43 +314,54 @@ static int streams_xattr_lstat(vfs_handle_struct *handle, const char *fname,
return result;
}
-static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
+static int streams_xattr_open(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
files_struct *fsp, int flags, mode_t mode)
{
- TALLOC_CTX *frame;
NTSTATUS status;
+ struct smb_filename *smb_fname_base = NULL;
struct stream_io *sio;
- char *base, *sname;
struct ea_struct ea;
- char *xattr_name;
+ char *xattr_name = NULL;
int baseflags;
int hostfd = -1;
- DEBUG(10, ("streams_xattr_open called for %s\n", fname));
+ DEBUG(10, ("streams_xattr_open called for %s\n",
+ smb_fname_str_dbg(smb_fname)));
- if (!is_ntfs_stream_name(fname)) {
- return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ if (!is_ntfs_stream_smb_fname(smb_fname)) {
+ return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
}
- frame = talloc_stackframe();
+ /* If the default stream is requested, just open the base file. */
+ if (is_ntfs_default_stream_smb_fname(smb_fname)) {
+ char *tmp_stream_name;
+ int ret;
- status = split_ntfs_stream_name(talloc_tos(), fname,
- &base, &sname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = EINVAL;
- goto fail;
+ tmp_stream_name = smb_fname->stream_name;
+ smb_fname->stream_name = NULL;
+
+ ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+
+ smb_fname->stream_name = tmp_stream_name;
+
+ return ret;
}
- if (sname == NULL) {
- hostfd = SMB_VFS_NEXT_OPEN(handle, base, fsp, flags, mode);
- talloc_free(frame);
- return hostfd;
+ status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name,
+ &xattr_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ goto fail;
}
- xattr_name = talloc_asprintf(talloc_tos(), "%s%s",
- SAMBA_XATTR_DOSSTREAM_PREFIX, sname);
- if (xattr_name == NULL) {
- errno = ENOMEM;
+ /* Create an smb_filename with stream_name == NULL. */
+ status = create_synthetic_smb_fname(talloc_tos(),
+ smb_fname->base_name,
+ NULL, NULL,
+ &smb_fname_base);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
goto fail;
}
@@ -326,7 +374,10 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
baseflags &= ~O_EXCL;
baseflags &= ~O_CREAT;
- hostfd = SMB_VFS_OPEN(handle->conn, base, fsp, baseflags, mode);
+ hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp,
+ baseflags, mode);
+
+ TALLOC_FREE(smb_fname_base);
/* It is legit to open a stream on a directory, but the base
* fd has to be read-only.
@@ -334,7 +385,7 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
if ((hostfd == -1) && (errno == EISDIR)) {
baseflags &= ~O_ACCMODE;
baseflags |= O_RDONLY;
- hostfd = SMB_VFS_OPEN(handle->conn, fname, fsp, baseflags,
+ hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, fsp, baseflags,
mode);
}
@@ -342,8 +393,8 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
goto fail;
}
- status = get_ea_value(talloc_tos(), handle->conn, NULL, base,
- xattr_name, &ea);
+ status = get_ea_value(talloc_tos(), handle->conn, NULL,
+ smb_fname->base_name, xattr_name, &ea);
DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status)));
@@ -355,7 +406,7 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
* file for us.
*/
DEBUG(10, ("streams_xattr_open: base file %s not around, "
- "returning ENOENT\n", base));
+ "returning ENOENT\n", smb_fname->base_name));
errno = ENOENT;
goto fail;
}
@@ -372,7 +423,7 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
char null = '\0';
DEBUG(10, ("creating attribute %s on file %s\n",
- xattr_name, base));
+ xattr_name, smb_fname->base_name));
if (fsp->base_fsp->fh->fd != -1) {
if (SMB_VFS_FSETXATTR(
@@ -383,8 +434,8 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
}
} else {
if (SMB_VFS_SETXATTR(
- handle->conn, base, xattr_name,
- &null, sizeof(null),
+ handle->conn, smb_fname->base_name,
+ xattr_name, &null, sizeof(null),
flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
goto fail;
}
@@ -403,8 +454,8 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
}
} else {
if (SMB_VFS_SETXATTR(
- handle->conn, base, xattr_name,
- &null, sizeof(null),
+ handle->conn, smb_fname->base_name,
+ xattr_name, &null, sizeof(null),
flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
goto fail;
}
@@ -422,7 +473,7 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
xattr_name);
sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
- base);
+ smb_fname->base_name);
sio->fsp_name_ptr = fsp->fsp_name;
sio->handle = handle;
sio->fsp = fsp;
@@ -432,7 +483,6 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
goto fail;
}
- TALLOC_FREE(frame);
return hostfd;
fail:
@@ -444,7 +494,6 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
SMB_VFS_CLOSE(fsp);
}
- TALLOC_FREE(frame);
return -1;
}
diff --git a/source3/modules/vfs_syncops.c b/source3/modules/vfs_syncops.c
index d3f7868400..562195cbda 100644
--- a/source3/modules/vfs_syncops.c
+++ b/source3/modules/vfs_syncops.c
@@ -104,6 +104,19 @@ static void syncops_name(const char *name)
}
}
+/*
+ sync two meta data changes for 1 names
+ */
+static void syncops_smb_fname(struct smb_filename *smb_fname)
+{
+ char *parent;
+ parent = parent_dir(NULL, smb_fname->base_name);
+ if (parent) {
+ syncops_sync_directory(parent);
+ talloc_free(parent);
+ }
+}
+
/*
rename needs special handling, as we may need to fsync two directories
@@ -125,6 +138,12 @@ static int syncops_rename(vfs_handle_struct *handle,
return ret; \
} while (0)
+#define SYNCOPS_NEXT_SMB_FNAME(op, fname, args) do { \
+ int ret = SMB_VFS_NEXT_ ## op args; \
+ if (ret == 0 && fname) syncops_smb_fname(fname); \
+ return ret; \
+} while (0)
+
static int syncops_symlink(vfs_handle_struct *handle,
const char *oldname, const char *newname)
{
@@ -138,9 +157,11 @@ static int syncops_link(vfs_handle_struct *handle,
}
static int syncops_open(vfs_handle_struct *handle,
- const char *fname, files_struct *fsp, int flags, mode_t mode)
+ struct smb_filename *smb_fname, files_struct *fsp,
+ int flags, mode_t mode)
{
- SYNCOPS_NEXT(OPEN, (flags&O_CREAT?fname:NULL), (handle, fname, fsp, flags, mode));
+ SYNCOPS_NEXT_SMB_FNAME(OPEN, (flags&O_CREAT?smb_fname:NULL),
+ (handle, smb_fname, fsp, flags, mode));
}
static int syncops_unlink(vfs_handle_struct *handle, const char *fname)
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 0f69ce4820..456caf590b 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -115,8 +115,6 @@ NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
{
struct smb_filename smb_fname_loc;
- SMB_ASSERT(psbuf);
-
ZERO_STRUCT(smb_fname_loc);
/* Setup the base_name/stream_name. */
@@ -124,7 +122,8 @@ NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name);
/* Copy the psbuf if one was given. */
- smb_fname_loc.st = *psbuf;
+ if (psbuf)
+ smb_fname_loc.st = *psbuf;
/* Let copy_smb_filename() do the heavy lifting. */
return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out);
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index d2a052dd55..c4d0374e99 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -318,6 +318,22 @@ bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname)
}
/****************************************************************************
+ Returns true if the filename's stream == "::$DATA"
+ ***************************************************************************/
+bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname)
+{
+ if (lp_posix_pathnames()) {
+ return false;
+ }
+
+ if (!smb_fname->stream_name) {
+ return false;
+ }
+
+ return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0;
+}
+
+/****************************************************************************
Reply to an NT create and X call on a pipe
****************************************************************************/
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 7b2fc19a6c..5d82738f6a 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -119,7 +119,7 @@ static NTSTATUS check_open_rights(struct connection_struct *conn,
****************************************************************************/
static NTSTATUS fd_open(struct connection_struct *conn,
- const char *fname,
+ struct smb_filename *smb_fname,
files_struct *fsp,
int flags,
mode_t mode)
@@ -137,7 +137,7 @@ static NTSTATUS fd_open(struct connection_struct *conn,
}
#endif
- fsp->fh->fd = SMB_VFS_OPEN(conn,fname,fsp,flags,mode);
+ fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
if (fsp->fh->fd == -1) {
status = map_nt_error_from_unix(errno);
if (errno == EMFILE) {
@@ -155,7 +155,7 @@ static NTSTATUS fd_open(struct connection_struct *conn,
}
DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
- fname, flags, (int)mode, fsp->fh->fd,
+ smb_fname_str_dbg(smb_fname), flags, (int)mode, fsp->fh->fd,
(fsp->fh->fd == -1) ? strerror(errno) : "" ));
return status;
@@ -422,7 +422,7 @@ static NTSTATUS open_file(files_struct *fsp,
}
/* Actually do the open */
- status = fd_open(conn, path, fsp, local_flags, unx_mode);
+ status = fd_open(conn, smb_fname, fsp, local_flags, unx_mode);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
"(flags=%d)\n", smb_fname_str_dbg(smb_fname),
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 1664f9a94d..f1f4aed77c 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -236,6 +236,8 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
mode_t mode;
const char *flagstr;
files_struct *fsp;
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
mode = 00400;
@@ -328,7 +330,16 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
}
fsp->conn = vfs->conn;
- fsp->fh->fd = SMB_VFS_OPEN(vfs->conn, argv[1], fsp, flags, mode);
+ status = create_synthetic_smb_fname_split(mem_ctx, argv[1], NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ SAFE_FREE(fsp->fsp_name);
+ SAFE_FREE(fsp);
+ return status;
+ }
+
+ fsp->fh->fd = SMB_VFS_OPEN(vfs->conn, smb_fname, fsp, flags, mode);
+ TALLOC_FREE(smb_fname);
if (fsp->fh->fd == -1) {
printf("open: error=%d (%s)\n", errno, strerror(errno));
SAFE_FREE(fsp->fh);