From 3e0e756104dc77059843bcef4a8d44981df28a18 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sun, 4 Jan 2009 10:45:34 -0800 Subject: s3: Allow renames of streams via NTRENAME and fix stream error codes on rename The test_streams_rename2 test in RAW-STREAMS verifies these changes --- source3/smbd/nttrans.c | 14 +++++++------- source3/smbd/reply.c | 25 +++++++++++++++---------- 2 files changed, 22 insertions(+), 17 deletions(-) (limited to 'source3') diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 9bfc566410..a793e614af 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; } -- cgit From 7ae992b622af62e9cfcbc9077f23eff8c2fe0d15 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sun, 4 Jan 2009 17:36:36 -0800 Subject: s3: Remove a few unnecessary checks from the streams xattr module Handling of error codes when renaming a file to a stream and a stream to a file is now done in rename_internals_fsp. The NTRENAME stream path only passes in the stream name, so the new base can now be different from the old base. --- source3/modules/vfs_streams_xattr.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'source3') 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; } -- cgit From c0b98297b4064812d9a6572d56d98ddab9181446 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sun, 4 Jan 2009 19:27:06 -0800 Subject: s3: Remove a few unnecessary checks from the streams depot module and fix to work with NTRENAME Handling of error codes when renaming a file to a stream and a stream to a file is now done in rename_internals_fsp. The NTRENAME stream path only passes in the stream name, so the new base can now be different from the old base. --- source3/modules/vfs_streams_depot.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'source3') 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; } -- cgit From 5318e73e93295cbdd2e50c4291b58a317cb09ea6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 18 Dec 2008 18:01:55 +0100 Subject: smbd: prevent access to root filesystem when connecting with empty service name This only applies to a setup with "registry shares = yes" Michael (cherry picked from commit 288fa94ac7cfdf7457b5098c33fc840bed3d5410) (cherry picked from commit e85526b184e66f86b7faa9d0a37288a09c12c19e) --- source3/smbd/service.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3') 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; } -- cgit From 34d0cb4f1707d8a16ca95c6db7ead79bae3e280c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 Jan 2009 12:58:23 +0100 Subject: Fix bug 6012: Add "get_real_filename" to full_audit Thanks to Hodur for testing! Volker --- source3/modules/vfs_full_audit.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'source3') diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 7970bf2644..3615c3978b 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. */ @@ -612,6 +619,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" }, @@ -1615,6 +1623,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) -- cgit From 6d4fd789f65ea770a33abfcba42665cf6a0efb10 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 Jan 2009 13:08:07 +0100 Subject: Add create_file to vfs_op_names --- source3/include/vfs_macros.h | 2 +- source3/modules/vfs_full_audit.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source3') 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 3615c3978b..e4bda09130 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -583,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" }, -- cgit From 3305fa27987d250fe963ae24672dbd8a5b746b7d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 Jan 2009 13:32:53 +0100 Subject: Fix a bad memleak in vfs_full_audit --- source3/modules/vfs_full_audit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index e4bda09130..666dd59574 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -721,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", @@ -728,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, @@ -736,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) -- cgit From 21b7b000fb53ac3025d0038cc551a47f9d4a743b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 Jan 2009 13:33:20 +0100 Subject: Use talloc_tos in vfs_full_audit.c:do_log --- source3/modules/vfs_full_audit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 666dd59574..1d9983a753 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -852,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); -- cgit