mirror of
https://github.com/samba-team/samba.git
synced 2025-02-26 21:57:41 +03:00
s3 onefs: Plumb smb_filename through onefs createfile path
This commit is contained in:
parent
358ccc3282
commit
2ccd501220
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
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);
|
||||
} else {
|
||||
ret = stat_stream(handle->conn, base, stream, sbuf, 0);
|
||||
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;
|
||||
}
|
||||
|
||||
onefs_adjust_stat_time(handle->conn, path, 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, smb_fname_onefs->base_name,
|
||||
smb_fname_onefs->stream_name, &smb_fname->st,
|
||||
0);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user