summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/include/vfs_macros.h2
-rw-r--r--source3/modules/vfs_full_audit.c35
-rw-r--r--source3/modules/vfs_streams_depot.c30
-rw-r--r--source3/modules/vfs_streams_xattr.c11
-rw-r--r--source3/smbd/nttrans.c14
-rw-r--r--source3/smbd/reply.c25
-rw-r--r--source3/smbd/service.c4
7 files changed, 77 insertions, 44 deletions
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index b008d86b3c..c6ccd4912a 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -340,7 +340,7 @@
#define SMB_VFS_NEXT_CHFLAGS(handle, path, flags) ((handle)->vfs_next.ops.chflags((handle)->vfs_next.handles.chflags, (path), (flags)))
#define SMB_VFS_NEXT_FILE_ID_CREATE(handle, dev, inode) ((handle)->vfs_next.ops.file_id_create((handle)->vfs_next.handles.file_id_create, (dev), (inode)))
#define SMB_VFS_NEXT_STREAMINFO(handle, fsp, fname, mem_ctx, num_streams, streams) ((handle)->vfs_next.ops.streaminfo((handle)->vfs_next.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams)))
-#define SMB_VFS_NEXT_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name) ((conn)->vfs_next.ops.get_real_filename((conn)->vfs_next.handles.get_real_filename, (path), (name), (mem_ctx), (found_name)))
+#define SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx, found_name) ((handle)->vfs_next.ops.get_real_filename((handle)->vfs_next.handles.get_real_filename, (path), (name), (mem_ctx), (found_name)))
/* NT ACL operations. */
#define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc) ((handle)->vfs_next.ops.fget_nt_acl((handle)->vfs_next.handles.fget_nt_acl, (fsp), (security_info), (ppdesc)))
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 7970bf2644..1d9983a753 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -211,6 +211,11 @@ static NTSTATUS smb_full_audit_streaminfo(vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
unsigned int *pnum_streams,
struct stream_struct **pstreams);
+static int smb_full_audit_get_real_filename(struct vfs_handle_struct *handle,
+ const char *path,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name);
static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info,
SEC_DESC **ppdesc);
@@ -444,6 +449,8 @@ static vfs_op_tuple audit_op_tuples[] = {
SMB_VFS_LAYER_LOGGER},
{SMB_VFS_OP(smb_full_audit_streaminfo), SMB_VFS_OP_STREAMINFO,
SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(smb_full_audit_get_real_filename), SMB_VFS_OP_GET_REAL_FILENAME,
+ SMB_VFS_LAYER_LOGGER},
/* NT ACL operations. */
@@ -576,6 +583,7 @@ static struct {
{ SMB_VFS_OP_RMDIR, "rmdir" },
{ SMB_VFS_OP_CLOSEDIR, "closedir" },
{ SMB_VFS_OP_OPEN, "open" },
+ { SMB_VFS_OP_CREATE_FILE, "create_file" },
{ SMB_VFS_OP_CLOSE, "close" },
{ SMB_VFS_OP_READ, "read" },
{ SMB_VFS_OP_PREAD, "pread" },
@@ -612,6 +620,7 @@ static struct {
{ SMB_VFS_OP_CHFLAGS, "chflags" },
{ SMB_VFS_OP_FILE_ID_CREATE, "file_id_create" },
{ SMB_VFS_OP_STREAMINFO, "streaminfo" },
+ { SMB_VFS_OP_GET_REAL_FILENAME, "get_real_filename" },
{ SMB_VFS_OP_FGET_NT_ACL, "fget_nt_acl" },
{ SMB_VFS_OP_GET_NT_ACL, "get_nt_acl" },
{ SMB_VFS_OP_FSET_NT_ACL, "fset_nt_acl" },
@@ -712,6 +721,7 @@ static int audit_syslog_priority(vfs_handle_struct *handle)
static char *audit_prefix(TALLOC_CTX *ctx, connection_struct *conn)
{
char *prefix = NULL;
+ char *result;
prefix = talloc_strdup(ctx,
lp_parm_const_string(SNUM(conn), "full_audit",
@@ -719,7 +729,7 @@ static char *audit_prefix(TALLOC_CTX *ctx, connection_struct *conn)
if (!prefix) {
return NULL;
}
- return talloc_sub_advanced(ctx,
+ result = talloc_sub_advanced(ctx,
lp_servicename(SNUM(conn)),
conn->server_info->unix_name,
conn->connectpath,
@@ -727,6 +737,8 @@ static char *audit_prefix(TALLOC_CTX *ctx, connection_struct *conn)
conn->server_info->sanitized_username,
pdb_get_domain(conn->server_info->sam_account),
prefix);
+ TALLOC_FREE(prefix);
+ return result;
}
static bool log_success(vfs_handle_struct *handle, vfs_op_type op)
@@ -840,14 +852,14 @@ static void do_log(vfs_op_type op, bool success, vfs_handle_struct *handle,
fstr_sprintf(err_msg, "fail (%s)", strerror(errno));
va_start(ap, format);
- op_msg = talloc_vasprintf(NULL, format, ap);
+ op_msg = talloc_vasprintf(talloc_tos(), format, ap);
va_end(ap);
if (!op_msg) {
return;
}
- audit_pre = audit_prefix(NULL, handle->conn);
+ audit_pre = audit_prefix(talloc_tos(), handle->conn);
syslog(audit_syslog_priority(handle), "%s|%s|%s|%s\n",
audit_pre ? audit_pre : "",
audit_opname(op), err_msg, op_msg);
@@ -1615,6 +1627,23 @@ static NTSTATUS smb_full_audit_streaminfo(vfs_handle_struct *handle,
return result;
}
+static int smb_full_audit_get_real_filename(struct vfs_handle_struct *handle,
+ const char *path,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ int result;
+
+ result = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx,
+ found_name);
+
+ do_log(SMB_VFS_OP_GET_REAL_FILENAME, (result == 0), handle,
+ "%s/%s->%s", path, name, (result == 0) ? "" : *found_name);
+
+ return result;
+}
+
static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info,
SEC_DESC **ppdesc)
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index 69d34940fd..54c17db1ce 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -525,6 +525,7 @@ static int streams_depot_rename(vfs_handle_struct *handle,
char *nsname = NULL;
char *ostream_fname = NULL;
char *nstream_fname = NULL;
+ char *newname_full = NULL;
DEBUG(10, ("streams_depot_rename called for %s => %s\n",
oldname, newname));
@@ -536,11 +537,6 @@ static int streams_depot_rename(vfs_handle_struct *handle,
return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
}
- if (!(old_is_stream && new_is_stream)) {
- errno = ENOSYS;
- return -1;
- }
-
frame = talloc_stackframe();
if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), oldname,
@@ -549,7 +545,7 @@ static int streams_depot_rename(vfs_handle_struct *handle,
goto done;
}
- if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), oldname,
+ if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), newname,
&nbase, &nsname))) {
errno = ENOMEM;
goto done;
@@ -561,17 +557,27 @@ static int streams_depot_rename(vfs_handle_struct *handle,
goto done;
}
- if (StrCaseCmp(obase, nbase) != 0) {
- errno = ENOSYS;
- goto done;
- }
-
ostream_fname = stream_name(handle, oldname, false);
if (ostream_fname == NULL) {
return -1;
}
- nstream_fname = stream_name(handle, newname, false);
+ /*
+ * Handle passing in a stream name without the base file. This is
+ * exercised by the NTRENAME streams rename path.
+ */
+ if (StrCaseCmp(nbase, "./") == 0) {
+ newname_full = talloc_asprintf(talloc_tos(), "%s:%s", obase,
+ nsname);
+ if (newname_full == NULL) {
+ errno = ENOMEM;
+ goto done;
+ }
+ }
+
+ nstream_fname = stream_name(handle,
+ newname_full ? newname_full : newname,
+ false);
if (nstream_fname == NULL) {
return -1;
}
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index ecfc31970d..7124c57520 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -511,11 +511,6 @@ static int streams_xattr_rename(vfs_handle_struct *handle,
return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
}
- if (!(o_is_stream && n_is_stream)) {
- errno = ENOSYS;
- goto fail;
- }
-
frame = talloc_stackframe();
if (!frame) {
goto fail;
@@ -544,12 +539,6 @@ static int streams_xattr_rename(vfs_handle_struct *handle,
goto fail;
}
- /* the new base should be empty */
- if (StrCaseCmp(obase, nbase) != 0) {
- errno = ENOSYS;
- goto fail;
- }
-
if (StrCaseCmp(ostream, nstream) == 0) {
goto done;
}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index b17aec80fa..3f33237f18 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -1310,13 +1310,6 @@ void reply_ntrename(struct smb_request *req)
return;
}
- if( is_ntfs_stream_name(oldname)) {
- /* Can't rename a stream. */
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
- END_PROFILE(SMBntrename);
- return;
- }
-
if (ms_has_wild(oldname)) {
reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
END_PROFILE(SMBntrename);
@@ -1364,6 +1357,13 @@ void reply_ntrename(struct smb_request *req)
return;
}
+ /* The new name must begin with a ':' if the old name is a stream. */
+ if (is_ntfs_stream_name(oldname) && (newname[0] != ':')) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ END_PROFILE(SMBntrename);
+ return;
+ }
+
DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
switch(rename_type) {
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 2133a30dc6..593558e399 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -5439,7 +5439,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
SMB_STRUCT_STAT sbuf, sbuf1;
NTSTATUS status = NT_STATUS_OK;
struct share_mode_lock *lck = NULL;
- bool dst_exists;
+ bool dst_exists, old_is_stream, new_is_stream;
ZERO_STRUCT(sbuf);
@@ -5508,6 +5508,18 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
return NT_STATUS_OK;
}
+ old_is_stream = is_ntfs_stream_name(fsp->fsp_name);
+ new_is_stream = is_ntfs_stream_name(newname);
+
+ /* Return the correct error code if both names aren't streams. */
+ if (!old_is_stream && new_is_stream) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+
+ if (old_is_stream && !new_is_stream) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
/*
* Have vfs_object_exist also fill sbuf1
*/
@@ -5519,18 +5531,11 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
return NT_STATUS_OBJECT_NAME_COLLISION;
}
- if(replace_if_exists && dst_exists) {
- /* Ensure both or neither are stream names. */
- if (is_ntfs_stream_name(fsp->fsp_name) !=
- is_ntfs_stream_name(newname)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
- }
-
if (dst_exists) {
struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf1);
files_struct *dst_fsp = file_find_di_first(fileid);
- if (dst_fsp) {
+ /* The file can be open when renaming a stream */
+ if (dst_fsp && !new_is_stream) {
DEBUG(3, ("rename_internals_fsp: Target file open\n"));
return NT_STATUS_ACCESS_DENIED;
}
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 0dea615fb5..e90098fed0 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -235,6 +235,10 @@ static int load_registry_service(const char *servicename)
return -1;
}
+ if ((servicename == NULL) || (*servicename == '\0')) {
+ return -1;
+ }
+
if (strequal(servicename, GLOBAL_NAME)) {
return -2;
}