summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/modules/onefs.h10
-rw-r--r--source3/modules/onefs_open.c376
-rw-r--r--source3/modules/onefs_streams.c137
-rw-r--r--source3/modules/vfs_onefs_shadow_copy.c20
4 files changed, 322 insertions, 221 deletions
diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h
index 3e6cd29b51..6cb8036e85 100644
--- a/source3/modules/onefs.h
+++ b/source3/modules/onefs.h
@@ -64,14 +64,12 @@ int onefs_close(vfs_handle_struct *handle, struct files_struct *fsp);
int onefs_rename(vfs_handle_struct *handle, const char *oldname,
const char *newname);
-int onefs_stat(vfs_handle_struct *handle, const char *fname,
- SMB_STRUCT_STAT *sbuf);
+int onefs_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname);
int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp,
SMB_STRUCT_STAT *sbuf);
-int onefs_lstat(vfs_handle_struct *handle, const char *path,
- SMB_STRUCT_STAT *sbuf);
+int onefs_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname);
int onefs_unlink(vfs_handle_struct *handle, const char *path);
@@ -141,6 +139,10 @@ NTSTATUS onefs_samba_sd_to_sd(uint32_t security_info_sent, SEC_DESC *psd,
NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
char **pbase, char **pstream);
+NTSTATUS onefs_stream_prep_smb_fname(TALLOC_CTX *ctx,
+ const struct smb_filename *smb_fname_in,
+ struct smb_filename **smb_fname_out);
+
int onefs_rdp_add_dir_state(connection_struct *conn, SMB_STRUCT_DIR *dirp);
/*
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c
index 8b6ae20520..5aade2c562 100644
--- a/source3/modules/onefs_open.c
+++ b/source3/modules/onefs_open.c
@@ -46,7 +46,7 @@ struct onefs_fsp_data {
static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
struct smb_request *req,
- const char *fname,
+ struct smb_filename *smb_fname,
uint32_t access_mask,
uint32_t share_access,
uint32_t create_disposition,
@@ -58,8 +58,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
struct ea_list *ea_list,
files_struct **result,
int *pinfo,
- struct onefs_fsp_data *fsp_data,
- SMB_STRUCT_STAT *psbuf);
+ struct onefs_fsp_data *fsp_data);
/****************************************************************************
Open a file.
@@ -69,9 +68,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
connection_struct *conn,
struct smb_request *req,
const char *parent_dir,
- const char *name,
- const char *path,
- SMB_STRUCT_STAT *psbuf,
+ struct smb_filename *smb_fname,
int flags,
mode_t unx_mode,
uint32 access_mask,
@@ -84,18 +81,24 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
struct security_descriptor *sd,
int *granted_oplock)
{
+ char *path = NULL;
+ struct smb_filename *smb_fname_onefs = NULL;
NTSTATUS status = NT_STATUS_OK;
int accmode = (flags & O_ACCMODE);
int local_flags = flags;
- bool file_existed = VALID_STAT(*psbuf);
+ bool file_existed = VALID_STAT(smb_fname->st);
const char *wild;
- char *base = NULL;
- char *stream = NULL;
int base_fd = -1;
fsp->fh->fd = -1;
errno = EPERM;
+ status = get_full_smb_filename(talloc_tos(), smb_fname,
+ &path);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/* Check permissions */
/*
@@ -111,7 +114,8 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
if (!CAN_WRITE(conn)) {
/* It's a read-only share - fail if we wanted to write. */
if(accmode != O_RDONLY) {
- DEBUG(3,("Permission denied opening %s\n", path));
+ DEBUG(3, ("Permission denied opening %s\n",
+ smb_fname_str_dbg(smb_fname)));
return NT_STATUS_ACCESS_DENIED;
} else if(flags & O_CREAT) {
/* We don't want to write - but we must make sure that
@@ -137,7 +141,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
DEBUG(10,("onefs_open_file: truncate requested on read-only "
- "open for file %s\n", path));
+ "open for file %s\n", smb_fname_str_dbg(smb_fname)));
local_flags = (flags & ~O_ACCMODE)|O_RDWR;
}
@@ -148,7 +152,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
* open flags. JRA.
*/
- if (file_existed && S_ISFIFO(psbuf->st_ex_mode)) {
+ if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
local_flags |= O_NONBLOCK;
}
#endif
@@ -174,7 +178,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
* then was copied via Samba.
*/
DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
- path));
+ smb_fname_str_dbg(smb_fname)));
return NT_STATUS_OBJECT_NAME_INVALID;
}
@@ -190,25 +194,30 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
flags |= O_NOFOLLOW;
}
#endif
- /* Stream handling */
- if (is_ntfs_stream_name(path)) {
- status = onefs_split_ntfs_stream_name(talloc_tos(), path,
- &base, &stream);
+ /* Setup a onefs-style smb_fname struct. */
+ status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
+ &smb_fname_onefs);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- /* It's a stream, so pass in the base_fd */
- if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && stream != NULL) {
+
+ /* If it's a stream pass in the base_fd */
+ if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
+ is_ntfs_stream_smb_fname(smb_fname_onefs)) {
SMB_ASSERT(fsp->base_fsp);
- DEBUG(10,("Opening a stream: base=%s(%d), stream=%s\n",
- base, fsp->base_fsp->fh->fd, stream));
+ DEBUG(10, ("Opening a stream: base=%s(%d), stream=%s\n",
+ smb_fname_onefs->base_name, fsp->base_fsp->fh->fd,
+ smb_fname_onefs->stream_name));
base_fd = fsp->base_fsp->fh->fd;
}
fsp->fh->fd = onefs_sys_create_file(conn,
base_fd,
- stream != NULL ? stream :
- (base != NULL ? base : path),
+ smb_fname_onefs->stream_name != NULL ?
+ smb_fname_onefs->stream_name :
+ smb_fname_onefs->base_name,
access_mask,
open_access_mask,
share_access,
@@ -220,6 +229,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
sd,
new_dos_attributes,
granted_oplock);
+ TALLOC_FREE(smb_fname_onefs);
if (fsp->fh->fd == -1) {
if (errno == EMFILE) {
@@ -237,9 +247,9 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
}
status = map_nt_error_from_unix(errno);
- DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
- "(flags=%d)\n",
- path, strerror(errno), local_flags, flags));
+ DEBUG(3, ("Error opening file %s (%s) (local_flags=%d) "
+ "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
+ strerror(errno), local_flags, flags));
return status;
}
@@ -265,13 +275,15 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
int ret;
if (fsp->fh->fd == -1) {
- ret = SMB_VFS_STAT(conn, path, psbuf);
+ ret = SMB_VFS_STAT(conn, smb_fname);
} else {
- ret = SMB_VFS_FSTAT(fsp, psbuf);
+ ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
/* If we have an fd, this stat should succeed. */
if (ret == -1) {
- DEBUG(0,("Error doing fstat on open file %s "
- "(%s)\n", path,strerror(errno) ));
+ DEBUG(0, ("Error doing fstat on open file %s "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno) ));
}
}
@@ -289,14 +301,14 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
* so catch a directory open and return an EISDIR. JRA.
*/
- if(S_ISDIR(psbuf->st_ex_mode)) {
+ if(S_ISDIR(smb_fname->st.st_ex_mode)) {
fd_close(fsp);
errno = EISDIR;
return NT_STATUS_FILE_IS_A_DIRECTORY;
}
- fsp->mode = psbuf->st_ex_mode;
- fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
+ fsp->mode = smb_fname->st.st_ex_mode;
+ fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
fsp->file_pid = req ? req->smbpid : 0;
fsp->can_lock = True;
@@ -419,7 +431,7 @@ static void schedule_defer_open(struct share_mode_lock *lck,
****************************************************************************/
NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
struct smb_request *req,
- const char *fname,
+ struct smb_filename *smb_fname,
uint32 access_mask,
uint32 share_access,
uint32 create_disposition,
@@ -429,12 +441,11 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
struct security_descriptor *sd,
files_struct *fsp,
int *pinfo,
- struct onefs_fsp_data *fsp_data,
- SMB_STRUCT_STAT *psbuf)
+ struct onefs_fsp_data *fsp_data)
{
int flags=0;
int flags2=0;
- bool file_existed = VALID_STAT(*psbuf);
+ bool file_existed = VALID_STAT(smb_fname->st);
bool def_acl = False;
bool posix_open = False;
bool new_file_created = False;
@@ -451,13 +462,19 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
NTSTATUS status;
int ret_flock;
char *parent_dir;
- const char *newname;
int granted_oplock;
uint64_t oplock_callback_id = 0;
uint32 createfile_attributes = 0;
+ char *fname = NULL;
ZERO_STRUCT(id);
+ status = get_full_smb_filename(talloc_tos(), smb_fname,
+ &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
if (conn->printer) {
/*
* Printers are handled completely differently.
@@ -469,12 +486,14 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
}
DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
- fname));
+ smb_fname_str_dbg(smb_fname)));
- return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
+ return print_fsp_open(req, conn, fname, req->vuid, fsp,
+ &smb_fname->st);
}
- if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
+ if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
+ NULL)) {
return NT_STATUS_NO_MEMORY;
}
@@ -493,9 +512,9 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
"access_mask=0x%x share_access=0x%x "
"create_disposition = 0x%x create_options=0x%x "
"unix mode=0%o oplock_request=0x%x\n",
- fname, new_dos_attributes, access_mask, share_access,
- create_disposition, create_options, unx_mode,
- oplock_request));
+ smb_fname_str_dbg(smb_fname), new_dos_attributes,
+ access_mask, share_access, create_disposition,
+ create_options, unx_mode, oplock_request));
/*
* Any non-stat-only open has the potential to contend oplocks, which
@@ -514,7 +533,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
* it off, but if a customer were to turn it on it would be
* bad.
*/
- if (req == NULL && !is_stat_open(access_mask) && !is_ntfs_stream_name(fname)) {
+ if (req == NULL && !is_stat_open(access_mask) &&
+ !is_ntfs_stream_smb_fname(smb_fname)) {
smb_panic("NULL req on a non-stat-open!");
}
@@ -563,7 +583,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
}
}
- status = check_name(conn, fname);
+ status = check_name(conn, smb_fname->base_name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -571,7 +591,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
if (!posix_open) {
new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
if (file_existed) {
- existing_dos_attributes = dos_mode(conn, fname, psbuf);
+ existing_dos_attributes = dos_mode(conn, fname,
+ &smb_fname->st);
}
}
@@ -583,13 +604,13 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
/* Ignore oplock requests if oplocks are disabled. */
if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
- IS_VETO_OPLOCK_PATH(conn, fname)) {
+ IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
/* Mask off everything except the private Samba bits. */
oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
}
/* this is for OS/2 long file names - say we don't support them */
- if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
+ if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
/* OS/2 Workplace shell fix may be main code stream in a later
* release. */
DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
@@ -632,7 +653,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
if (!file_existed) {
DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
"requested for file %s and file "
- "doesn't exist.\n", fname ));
+ "doesn't exist.\n",
+ smb_fname_str_dbg(smb_fname)));
errno = ENOENT;
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
@@ -645,7 +667,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
DEBUG(5, ("onefs_open_file_ntcreate: "
"FILE_OVERWRITE requested for file "
"%s and file doesn't exist.\n",
- fname));
+ smb_fname_str_dbg(smb_fname)));
errno = ENOENT;
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
@@ -660,8 +682,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
DEBUG(5, ("onefs_open_file_ntcreate: "
"FILE_CREATE requested for file %s "
"and file already exists.\n",
- fname));
- if (S_ISDIR(psbuf->st_ex_mode)) {
+ smb_fname_str_dbg(smb_fname)));
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
errno = EISDIR;
} else {
errno = EEXIST;
@@ -686,13 +708,15 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
((create_disposition == FILE_OVERWRITE) ||
(create_disposition == FILE_OVERWRITE_IF))) {
if (!open_match_attributes(conn, existing_dos_attributes,
- new_dos_attributes, psbuf->st_ex_mode,
+ new_dos_attributes,
+ smb_fname->st.st_ex_mode,
unx_mode, &new_unx_mode)) {
DEBUG(5, ("onefs_open_file_ntcreate: attributes "
"missmatch for file %s (%x %x) (0%o, 0%o)\n",
- fname, existing_dos_attributes,
+ smb_fname_str_dbg(smb_fname),
+ existing_dos_attributes,
new_dos_attributes,
- (unsigned int)psbuf->st_ex_mode,
+ (unsigned int)smb_fname->st.st_ex_mode,
(unsigned int)unx_mode ));
errno = EACCES;
return NT_STATUS_ACCESS_DENIED;
@@ -720,7 +744,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
"open_access_mask=%#x, access_mask=0x%x\n",
- fname, open_access_mask, access_mask));
+ smb_fname_str_dbg(smb_fname), open_access_mask,
+ access_mask));
/*
* Note that we ignore the append flag as append does not
@@ -792,14 +817,15 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
(!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
"for file %s on read only %s\n",
- fname, !CAN_WRITE(conn) ? "share" : "file" ));
+ smb_fname_str_dbg(smb_fname),
+ !CAN_WRITE(conn) ? "share" : "file" ));
errno = EACCES;
return NT_STATUS_ACCESS_DENIED;
}
DEBUG(10, ("fsp = %p\n", fsp));
- fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
+ fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
fsp->share_access = share_access;
fsp->fh->private_options = create_options;
fsp->access_mask = open_access_mask; /* We change this to the
@@ -815,8 +841,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
}
if (file_existed) {
- struct timespec old_write_time = psbuf->st_ex_mtime;
- id = vfs_file_id_from_sbuf(conn, psbuf);
+ struct timespec old_write_time = smb_fname->st.st_ex_mtime;
+ id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
lck = get_share_mode_lock(talloc_tos(), id,
conn->connectpath,
@@ -874,9 +900,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
conn,
req,
parent_dir,
- newname,
- fname,
- psbuf,
+ smb_fname,
flags|flags2,
unx_mode,
access_mask,
@@ -899,18 +923,19 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
struct deferred_open_record state;
struct timespec old_write_time;
- old_write_time = psbuf->st_ex_mtime;
+ old_write_time = smb_fname->st.st_ex_mtime;
DEBUG(3, ("Someone created file %s with an "
"oplock after we looked: Retrying\n",
- fname));
+ smb_fname_str_dbg(smb_fname)));
/*
* We hit the race that when we did the stat
* on the file it did not exist, and someone
* has created it in between the stat and the
* open_file() call. Just retry immediately.
*/
- id = vfs_file_id_from_sbuf(conn, psbuf);
+ id = vfs_file_id_from_sbuf(conn,
+ &smb_fname->st);
if (!(lck = get_share_mode_lock(talloc_tos(),
id, conn->connectpath, fname,
&old_write_time))) {
@@ -919,7 +944,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
*/
DEBUG(0, ("onefs_open_file_ntcreate: "
"Could not get share mode "
- "lock for %s\n", fname));
+ "lock for %s\n",
+ smb_fname_str_dbg(smb_fname)));
status = NT_STATUS_SHARING_VIOLATION;
goto cleanup_destroy;
}
@@ -935,7 +961,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
}
/* Waiting for an oplock */
DEBUG(5,("Async createfile because a client has an "
- "oplock on %s\n", fname));
+ "oplock on %s\n",
+ smb_fname_str_dbg(smb_fname)));
SMB_ASSERT(req);
schedule_defer_open(lck, request_time, req);
@@ -1002,8 +1029,10 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
can_access_mask = FILE_READ_DATA;
}
- if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
- !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
+ if (((can_access_mask & FILE_WRITE_DATA) &&
+ !CAN_WRITE(conn)) ||
+ !can_access_file_data(conn, smb_fname,
+ can_access_mask)) {
can_access = False;
}
@@ -1088,7 +1117,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
}
if (!file_existed) {
- struct timespec old_write_time = psbuf->st_ex_mtime;
+ struct timespec old_write_time = smb_fname->st.st_ex_mtime;
/*
* Deal with the race condition where two smbd's detect the
* file doesn't exist and do the create at the same time. One
@@ -1112,7 +1141,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
if (lck == NULL) {
DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
- "share mode lock for %s\n", fname));
+ "share mode lock for %s\n",
+ smb_fname_str_dbg(smb_fname)));
fd_close(fsp);
return NT_STATUS_SHARING_VIOLATION;
}
@@ -1153,8 +1183,9 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
SMB_ASSERT(lck != NULL);
/* Delete streams if create_disposition requires it */
- if (file_existed && clear_ads && !is_ntfs_stream_name(fname)) {
- status = delete_all_streams(conn, fname);
+ if (file_existed && clear_ads &&
+ !is_ntfs_stream_smb_fname(smb_fname)) {
+ status = delete_all_streams(conn, smb_fname->base_name);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(lck);
fd_close(fsp);
@@ -1265,8 +1296,9 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
* selected.
* May be necessary depending on acl policies.
*/
- if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
- && (psbuf->st_ex_flags & SF_HASNTFSACL))) {
+ if (!posix_open && !file_existed && !def_acl &&
+ !(VALID_STAT(smb_fname->st) &&
+ (smb_fname->st.st_ex_flags & SF_HASNTFSACL))) {
int saved_errno = errno; /* We might get ENOSYS in the next
* call.. */
@@ -1292,7 +1324,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
} else {
DEBUG(5, ("onefs_open_file_ntcreate: reset "
"attributes of file %s to 0%o\n",
- fname, (unsigned int)new_unx_mode));
+ smb_fname_str_dbg(smb_fname),
+ (unsigned int)new_unx_mode));
ret = 0; /* Don't do the fchmod below. */
}
}
@@ -1301,7 +1334,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
(SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
"attributes of file %s to 0%o\n",
- fname, (unsigned int)new_unx_mode));
+ smb_fname_str_dbg(smb_fname),
+ (unsigned int)new_unx_mode));
}
/* If this is a successful open, we must remove any deferred open
@@ -1320,7 +1354,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
****************************************************************************/
static NTSTATUS onefs_open_directory(connection_struct *conn,
struct smb_request *req,
- const char *fname,
+ struct smb_filename *smb_dname,
uint32 access_mask,
uint32 share_access,
uint32 create_disposition,
@@ -1328,8 +1362,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
uint32 file_attributes,
struct security_descriptor *sd,
files_struct **result,
- int *pinfo,
- SMB_STRUCT_STAT *psbuf)
+ int *pinfo)
{
files_struct *fsp = NULL;
struct share_mode_lock *lck = NULL;
@@ -1346,14 +1379,16 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
"access_mask = 0x%x, "
"share_access = 0x%x create_options = 0x%x, "
"create_disposition = 0x%x, file_attributes = 0x%x\n",
- fname, (unsigned int)access_mask, (unsigned int)share_access,
- (unsigned int)create_options, (unsigned int)create_disposition,
+ smb_fname_str_dbg(smb_dname), (unsigned int)access_mask,
+ (unsigned int)share_access, (unsigned int)create_options,
+ (unsigned int)create_disposition,
(unsigned int)file_attributes));
if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
(conn->fs_capabilities & FILE_NAMED_STREAMS) &&
- is_ntfs_stream_name(fname)) {
- DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
+ is_ntfs_stream_smb_fname(smb_dname)) {
+ DEBUG(2, ("onefs_open_directory: %s is a stream name!\n",
+ smb_fname_str_dbg(smb_dname)));
return NT_STATUS_NOT_A_DIRECTORY;
}
@@ -1386,7 +1421,8 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
default:
DEBUG(5, ("onefs_open_directory: invalid "
"create_disposition 0x%x for directory %s\n",
- (unsigned int)create_disposition, fname));
+ (unsigned int)create_disposition,
+ smb_fname_str_dbg(smb_dname)));
return NT_STATUS_INVALID_PARAMETER;
}
@@ -1399,7 +1435,8 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
}
/* Get parent dirname */
- if (!parent_dirname(talloc_tos(), fname, &parent_dir, &dirname)) {
+ if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
+ &dirname)) {
return NT_STATUS_NO_MEMORY;
}
@@ -1408,7 +1445,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
file_attributes = 0;
} else {
- mode = unix_mode(conn, aDIR, fname, parent_dir);
+ mode = unix_mode(conn, aDIR, smb_dname->base_name, parent_dir);
}
/*
@@ -1431,7 +1468,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
retry_open:
fsp->fh->fd = onefs_sys_create_file(conn,
-1,
- fname,
+ smb_dname->base_name,
access_mask,
access_mask,
share_access,
@@ -1445,7 +1482,8 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
NULL);
if (fsp->fh->fd == -1) {
- DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
+ DEBUG(3, ("Error opening %s. Errno=%d (%s).\n",
+ smb_fname_str_dbg(smb_dname), errno,
strerror(errno)));
SMB_ASSERT(errno != EINPROGRESS);
@@ -1467,15 +1505,16 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
file_free(req, fsp);
if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
- DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
+ DEBUG(5, ("onefs_open_directory: FILE_OPEN requested "
"for directory %s and it doesn't "
- "exist.\n", fname ));
+ "exist.\n", smb_fname_str_dbg(smb_dname)));
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
} else if ((errno == EEXIST) &&
(create_disposition == FILE_CREATE)) {
- DEBUG(5,("onefs_open_directory: FILE_CREATE "
+ DEBUG(5, ("onefs_open_directory: FILE_CREATE "
"requested for directory %s and it "
- "already exists.\n", fname ));
+ "already exists.\n",
+ smb_fname_str_dbg(smb_dname)));
return NT_STATUS_OBJECT_NAME_COLLISION;
} else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
/* Catch sharing violations. */
@@ -1488,15 +1527,18 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
if (info == FILE_WAS_CREATED) {
/* Pulled from mkdir_internal() */
- if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
+ if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
DEBUG(2, ("Could not stat directory '%s' just "
- "created: %s\n",fname, strerror(errno)));
+ "created: %s\n",
+ smb_fname_str_dbg(smb_dname),
+ strerror(errno)));
return map_nt_error_from_unix(errno);
}
- if (!S_ISDIR(psbuf->st_ex_mode)) {
+ if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
DEBUG(0, ("Directory just '%s' created is not a "
- "directory\n", fname));
+ "directory\n",
+ smb_fname_str_dbg(smb_dname)));
return NT_STATUS_ACCESS_DENIED;
}
@@ -1508,32 +1550,35 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
* parent dir.
*/
if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
- (mode & ~psbuf->st_ex_mode)) {
- SMB_VFS_CHMOD(conn, fname, (psbuf->st_ex_mode |
- (mode & ~psbuf->st_ex_mode)));
+ (mode & ~smb_dname->st.st_ex_mode)) {
+ SMB_VFS_CHMOD(conn, smb_dname->base_name,
+ (smb_dname->st.st_ex_mode |
+ (mode & ~smb_dname->st.st_ex_mode)));
}
}
/* Change the owner if required. */
if (lp_inherit_owner(SNUM(conn))) {
- change_dir_owner_to_parent(conn, parent_dir, fname,
- psbuf);
+ change_dir_owner_to_parent(conn, parent_dir,
+ smb_dname->base_name,
+ &smb_dname->st);
}
notify_fname(conn, NOTIFY_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_DIR_NAME, fname);
+ FILE_NOTIFY_CHANGE_DIR_NAME,
+ smb_dname->base_name);
}
/* Stat the fd for Samba bookkeeping. */
- if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
+ if(SMB_VFS_FSTAT(fsp, &smb_dname->st) != 0) {
fd_close(fsp);
file_free(req, fsp);
return map_nt_error_from_unix(errno);
}
/* Setup the files_struct for it. */
- fsp->mode = psbuf->st_ex_mode;
- fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
+ fsp->mode = smb_dname->st.st_ex_mode;
+ fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
fsp->file_pid = req ? req->smbpid : 0;
fsp->can_lock = False;
@@ -1553,21 +1598,21 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
fsp->is_directory = True;
fsp->posix_open = posix_open;
- string_set(&fsp->fsp_name,fname);
+ string_set(&fsp->fsp_name, smb_dname->base_name);
- mtimespec = psbuf->st_ex_mtime;
+ mtimespec = smb_dname->st.st_ex_mtime;
/*
* Still set the samba share mode lock for correct delete-on-close
* semantics and to make smbstatus more useful.
*/
lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
- conn->connectpath,
- fname, &mtimespec);
+ conn->connectpath, smb_dname->base_name,
+ &mtimespec);
if (lck == NULL) {
DEBUG(0, ("onefs_open_directory: Could not get share mode "
- "lock for %s\n", fname));
+ "lock for %s\n", smb_fname_str_dbg(smb_dname)));
fd_close(fsp);
file_free(req, fsp);
return NT_STATUS_SHARING_VIOLATION;
@@ -1618,7 +1663,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
*/
static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
struct smb_request *req,
- const char *fname,
+ struct smb_filename *smb_fname,
uint32_t access_mask,
uint32_t share_access,
uint32_t create_disposition,
@@ -1630,10 +1675,8 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
struct ea_list *ea_list,
files_struct **result,
int *pinfo,
- struct onefs_fsp_data *fsp_data,
- SMB_STRUCT_STAT *psbuf)
+ struct onefs_fsp_data *fsp_data)
{
- SMB_STRUCT_STAT sbuf;
int info = FILE_WAS_OPENED;
files_struct *base_fsp = NULL;
files_struct *fsp = NULL;
@@ -1650,7 +1693,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
(unsigned int)create_disposition,
(unsigned int)create_options,
(unsigned int)oplock_request,
- ea_list, sd, fname));
+ ea_list, sd, smb_fname_str_dbg(smb_fname)));
if (create_options & FILE_OPEN_BY_FILE_ID) {
status = NT_STATUS_NOT_SUPPORTED;
@@ -1668,15 +1711,6 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
oplock_request |= INTERNAL_OPEN_ONLY;
}
- if (psbuf != NULL) {
- sbuf = *psbuf;
- }
- else {
- if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
- SET_STAT_INVALID(sbuf);
- }
- }
-
if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
access_mask &= ~SYSTEM_SECURITY_ACCESS;
@@ -1684,12 +1718,12 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
&& (access_mask & DELETE_ACCESS)
- && !is_ntfs_stream_name(fname)) {
+ && !is_ntfs_stream_smb_fname(smb_fname)) {
/*
* We can't open a file with DELETE access if any of the
* streams is open without FILE_SHARE_DELETE
*/
- status = open_streams_for_delete(conn, fname);
+ status = open_streams_for_delete(conn, smb_fname->base_name);
if (!NT_STATUS_IS_OK(status)) {
goto fail;
@@ -1697,26 +1731,15 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
}
if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
- && is_ntfs_stream_name(fname)) {
- char *base;
+ && is_ntfs_stream_smb_fname(smb_fname)) {
uint32 base_create_disposition;
+ struct smb_filename *smb_fname_base = NULL;
if (create_options & FILE_DIRECTORY_FILE) {
status = NT_STATUS_NOT_A_DIRECTORY;
goto fail;
}
- status = onefs_split_ntfs_stream_name(talloc_tos(), fname,
- &base, NULL);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("onefs_create_file_unixpath: "
- "split_ntfs_stream_name failed: %s\n",
- nt_errstr(status)));
- goto fail;
- }
-
- SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
-
switch (create_disposition) {
case FILE_OPEN:
base_create_disposition = FILE_OPEN;
@@ -1726,10 +1749,24 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
break;
}
+ /* 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)) {
+ goto fail;
+ }
+
+ if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
+ DEBUG(10, ("Unable to stat stream: %s\n",
+ smb_fname_str_dbg(smb_fname_base)));
+ }
+
status = onefs_create_file_unixpath(
conn, /* conn */
NULL, /* req */
- base, /* fname */
+ smb_fname_base, /* fname */
SYNCHRONIZE_ACCESS, /* access_mask */
(FILE_SHARE_READ |
FILE_SHARE_WRITE |
@@ -1743,12 +1780,14 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
NULL, /* ea_list */
&base_fsp, /* result */
NULL, /* pinfo */
- NULL, /* fsp_data */
- NULL); /* psbuf */
+ NULL); /* fsp_data */
+
+ TALLOC_FREE(smb_fname_base);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("onefs_create_file_unixpath for base %s "
- "failed: %s\n", base, nt_errstr(status)));
+ "failed: %s\n", smb_fname->base_name,
+ nt_errstr(status)));
goto fail;
}
@@ -1762,7 +1801,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
DEBUG(5, ("Oplock(%d) being requested on a stream! "
"Ignoring oplock request: fname=%s\n",
oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
- fname));
+ smb_fname_str_dbg(smb_fname)));
/* Request NO_OPLOCK instead. */
oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
}
@@ -1801,7 +1840,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
status = onefs_open_directory(
conn, /* conn */
req, /* req */
- fname, /* fname */
+ smb_fname, /* fname */
access_mask, /* access_mask */
share_access, /* share_access */
create_disposition, /* create_disposition*/
@@ -1809,8 +1848,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
file_attributes, /* file_attributes */
sd, /* sd */
&fsp, /* result */
- &info, /* pinfo */
- &sbuf); /* psbuf */
+ &info); /* pinfo */
} else {
/*
@@ -1833,7 +1871,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
status = onefs_open_file_ntcreate(
conn, /* conn */
req, /* req */
- fname, /* fname */
+ smb_fname, /* fname */
access_mask, /* access_mask */
share_access, /* share_access */
create_disposition, /* create_disposition*/
@@ -1843,8 +1881,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
sd, /* sd */
fsp, /* result */
&info, /* pinfo */
- fsp_data, /* fsp_data */
- &sbuf); /* psbuf */
+ fsp_data); /* fsp_data */
if(!NT_STATUS_IS_OK(status)) {
file_free(req, fsp);
@@ -1875,7 +1912,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
status = onefs_open_directory(
conn, /* conn */
req, /* req */
- fname, /* fname */
+ smb_fname, /* fname */
access_mask, /* access_mask */
share_access, /* share_access */
create_disposition, /* create_disposition*/
@@ -1883,8 +1920,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
file_attributes, /* file_attributes */
sd, /* sd */
&fsp, /* result */
- &info, /* pinfo */
- &sbuf); /* psbuf */
+ &info); /* pinfo */
}
}
@@ -1897,13 +1933,13 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
SMB_ASSERT(fsp);
if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
- status = set_ea(conn, fsp, fname, ea_list);
+ status = set_ea(conn, fsp, smb_fname, ea_list);
if (!NT_STATUS_IS_OK(status)) {
goto fail;
}
}
- if (!fsp->is_directory && S_ISDIR(sbuf.st_ex_mode)) {
+ if (!fsp->is_directory && S_ISDIR(smb_fname->st.st_ex_mode)) {
status = NT_STATUS_ACCESS_DENIED;
goto fail;
}
@@ -1911,7 +1947,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
/* Save the requested allocation size. */
if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
if (allocation_size
- && (allocation_size > sbuf.st_ex_size)) {
+ && (allocation_size > smb_fname->st.st_ex_size)) {
fsp->initial_allocation_size = smb_roundup(
fsp->conn, allocation_size);
if (fsp->is_directory) {
@@ -1926,7 +1962,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
}
} else {
fsp->initial_allocation_size = smb_roundup(
- fsp->conn, (uint64_t)sbuf.st_ex_size);
+ fsp->conn, (uint64_t)smb_fname->st.st_ex_size);
}
}
@@ -1936,13 +1972,8 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
if (pinfo != NULL) {
*pinfo = info;
}
- if (psbuf != NULL) {
- if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
- *psbuf = sbuf;
- }
- else {
- SMB_VFS_FSTAT(fsp, psbuf);
- }
+ if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
+ SMB_VFS_FSTAT(fsp, &smb_fname->st);
}
return NT_STATUS_OK;
@@ -1997,7 +2028,6 @@ NTSTATUS onefs_create_file(vfs_handle_struct *handle,
struct onefs_fsp_data fsp_data = {};
int info = FILE_WAS_OPENED;
files_struct *fsp = NULL;
- char *fname = NULL;
NTSTATUS status;
DEBUG(10,("onefs_create_file: access_mask = 0x%x "
@@ -2024,11 +2054,6 @@ NTSTATUS onefs_create_file(vfs_handle_struct *handle,
}
}
- status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
/* All file access must go through check_name() */
status = check_name(conn, smb_fname->base_name);
if (!NT_STATUS_IS_OK(status)) {
@@ -2038,7 +2063,7 @@ NTSTATUS onefs_create_file(vfs_handle_struct *handle,
status = onefs_create_file_unixpath(
conn, /* conn */
req, /* req */
- fname, /* fname */
+ smb_fname, /* fname */
access_mask, /* access_mask */
share_access, /* share_access */
create_disposition, /* create_disposition*/
@@ -2050,8 +2075,7 @@ NTSTATUS onefs_create_file(vfs_handle_struct *handle,
ea_list, /* ea_list */
&fsp, /* result */
&info, /* pinfo */
- &fsp_data, /* fsp_data */
- &smb_fname->st); /* psbuf */
+ &fsp_data); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
goto fail;
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index 284e199fc5..a4c6146fb0 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -54,6 +54,52 @@ NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
return NT_STATUS_OK;
}
+NTSTATUS onefs_stream_prep_smb_fname(TALLOC_CTX *ctx,
+ const struct smb_filename *smb_fname_in,
+ struct smb_filename **smb_fname_out)
+{
+ char *stream_name = NULL;
+ NTSTATUS status;
+
+ /*
+ * Only attempt to strip off the trailing :$DATA if there is an actual
+ * stream there. If it is the default stream, the smb_fname_out will
+ * just have a NULL stream so the base file is opened.
+ */
+ if (smb_fname_in->stream_name &&
+ !is_ntfs_default_stream_smb_fname(smb_fname_in)) {
+ char *str_tmp = smb_fname_in->stream_name;
+
+ /* First strip off the leading ':' */
+ if (str_tmp[0] == ':') {
+ str_tmp++;
+ }
+
+ /* Create a new copy of the stream_name. */
+ stream_name = talloc_strdup(ctx, str_tmp);
+ if (stream_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* Strip off the :$DATA if one exists. */
+ str_tmp = strrchr_m(stream_name, ':');
+ if (str_tmp) {
+ str_tmp[0] = '\0';
+ }
+ }
+
+ /*
+ * If there was a stream that wasn't the default stream the leading
+ * colon and trailing :$DATA has now been stripped off. Create a new
+ * smb_filename to pass back.
+ */
+ status = create_synthetic_smb_fname(ctx, smb_fname_in->base_name,
+ stream_name, &smb_fname_in->st,
+ smb_fname_out);
+ TALLOC_FREE(stream_name);
+ return status;
+}
+
int onefs_is_stream(const char *path, char **pbase, char **pstream,
bool *is_stream)
{
@@ -312,28 +358,37 @@ static int stat_stream(struct connection_struct *conn, const char *base,
return ret;
}
-int onefs_stat(vfs_handle_struct *handle, const char *path,
- SMB_STRUCT_STAT *sbuf)
+int onefs_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
{
+ struct smb_filename *smb_fname_onefs = NULL;
+ NTSTATUS status;
int ret;
- bool is_stream;
- char *base = NULL;
- char *stream = NULL;
- ret = onefs_is_stream(path, &base, &stream, &is_stream);
- if (ret)
- return ret;
+ status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
+ &smb_fname_onefs);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
- if (!is_stream) {
- ret = onefs_sys_stat(path, sbuf);
- } else if (!stream) {
- /* If it's the ::$DATA stream just stat the base file name. */
- ret = onefs_sys_stat(base, sbuf);
+ /*
+ * If the smb_fname has no stream or is :$DATA, then just stat the
+ * base stream. Otherwise stat the stream.
+ */
+ if (!is_ntfs_stream_smb_fname(smb_fname_onefs)) {
+ ret = onefs_sys_stat(smb_fname_onefs->base_name,
+ &smb_fname->st);
} else {
- ret = stat_stream(handle->conn, base, stream, sbuf, 0);
+ ret = stat_stream(handle->conn, smb_fname_onefs->base_name,
+ smb_fname_onefs->stream_name, &smb_fname->st,
+ 0);
}
- onefs_adjust_stat_time(handle->conn, path, sbuf);
+ onefs_adjust_stat_time(handle->conn, smb_fname->base_name,
+ &smb_fname->st);
+
+ TALLOC_FREE(smb_fname_onefs);
+
return ret;
}
@@ -361,29 +416,37 @@ int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp,
return ret;
}
-int onefs_lstat(vfs_handle_struct *handle, const char *path,
- SMB_STRUCT_STAT *sbuf)
+int onefs_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
{
+ struct smb_filename *smb_fname_onefs = NULL;
+ NTSTATUS status;
int ret;
- bool is_stream;
- char *base = NULL;
- char *stream = NULL;
- ret = onefs_is_stream(path, &base, &stream, &is_stream);
- if (ret)
- return ret;
+ status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
+ &smb_fname_onefs);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
- if (!is_stream) {
- ret = onefs_sys_lstat(path, sbuf);
- } else if (!stream) {
- /* If it's the ::$DATA stream just stat the base file name. */
- ret = onefs_sys_lstat(base, sbuf);
+ /*
+ * If the smb_fname has no stream or is :$DATA, then just stat the
+ * base stream. Otherwise stat the stream.
+ */
+ if (!is_ntfs_stream_smb_fname(smb_fname_onefs)) {
+ ret = onefs_sys_lstat(smb_fname_onefs->base_name,
+ &smb_fname->st);
} else {
- ret = stat_stream(handle->conn, base, stream, sbuf,
+ ret = stat_stream(handle->conn, smb_fname_onefs->base_name,
+ smb_fname_onefs->stream_name, &smb_fname->st,
AT_SYMLINK_NOFOLLOW);
}
- onefs_adjust_stat_time(handle->conn, path, sbuf);
+ onefs_adjust_stat_time(handle->conn, smb_fname->base_name,
+ &smb_fname->st);
+
+ TALLOC_FREE(smb_fname_onefs);
+
return ret;
}
@@ -661,10 +724,22 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
}
ret = SMB_VFS_FSTAT(fsp, &sbuf);
} else {
+ struct smb_filename *smb_fname = NULL;
+
if (is_ntfs_stream_name(fname)) {
return NT_STATUS_INVALID_PARAMETER;
}
- ret = SMB_VFS_STAT(handle->conn, fname, &sbuf);
+
+ status = create_synthetic_smb_fname(talloc_tos(), fname, NULL,
+ NULL, &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ ret = SMB_VFS_STAT(handle->conn, smb_fname);
+
+ sbuf = smb_fname->st;
+
+ TALLOC_FREE(smb_fname);
}
if (ret == -1) {
diff --git a/source3/modules/vfs_onefs_shadow_copy.c b/source3/modules/vfs_onefs_shadow_copy.c
index 45860fa90d..3eca664c8a 100644
--- a/source3/modules/vfs_onefs_shadow_copy.c
+++ b/source3/modules/vfs_onefs_shadow_copy.c
@@ -278,21 +278,21 @@ onefs_shadow_copy_rename(vfs_handle_struct *handle, const char *old_name,
}
static int
-onefs_shadow_copy_stat(vfs_handle_struct *handle, const char *path,
- SMB_STRUCT_STAT *sbuf)
+onefs_shadow_copy_stat(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname)
{
- SHADOW_NEXT(STAT,
- (handle, cpath ?: path, sbuf),
- int);
+ SHADOW_NEXT_SMB_FNAME(STAT,
+ (handle, smb_fname),
+ int);
}
static int
-onefs_shadow_copy_lstat(vfs_handle_struct *handle, const char *path,
- SMB_STRUCT_STAT *sbuf)
+onefs_shadow_copy_lstat(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname)
{
- SHADOW_NEXT(LSTAT,
- (handle, cpath ?: path, sbuf),
- int);
+ SHADOW_NEXT_SMB_FNAME(LSTAT,
+ (handle, smb_fname),
+ int);
}
static int