summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2019-07-11 17:02:15 +0200
committerKarolin Seeger <kseeger@samba.org>2019-08-28 09:39:46 +0200
commit8e2c37bdde18440299f7e5d4a0393e0cc465ac31 (patch)
tree7ee8c7f229395c051866659649a0505476d70246 /source3
parentc98528753fc4754c0a34a449f9cc682c8c83e318 (diff)
downloadsamba-8e2c37bdde18440299f7e5d4a0393e0cc465ac31.tar.gz
CVE-2019-10197: smbd: split change_to_user_impersonate() out of change_to_user_internal()
This makes sure we always call chdir_current_service() even when we still impersonated the user. Which is important in order to run the SMB* request within the correct working directory and only if the user has permissions to enter that directory. It makes sure we always update conn->lastused_count in chdir_current_service() for each request. Note that vfs_ChDir() (called from chdir_current_service()) maintains its own cache and avoids calling SMB_VFS_CHDIR() if possible. It means we still avoid syscalls if we get a multiple requests for the same session/tcon tuple. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
Diffstat (limited to 'source3')
-rw-r--r--source3/smbd/uid.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 9cf09c11a62..f65e3091dfd 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -311,9 +311,9 @@ static void print_impersonation_info(connection_struct *conn)
stack, but modify the current_user entries.
****************************************************************************/
-static bool change_to_user_internal(connection_struct *conn,
- const struct auth_session_info *session_info,
- uint64_t vuid)
+static bool change_to_user_impersonate(connection_struct *conn,
+ const struct auth_session_info *session_info,
+ uint64_t vuid)
{
int snum;
gid_t gid;
@@ -326,7 +326,6 @@ static bool change_to_user_internal(connection_struct *conn,
if ((current_user.conn == conn) &&
(current_user.vuid == vuid) &&
- (current_user.need_chdir == conn->tcon_done) &&
(current_user.ut.uid == session_info->unix_token->uid))
{
DBG_INFO("Skipping user change - already user\n");
@@ -431,6 +430,20 @@ static bool change_to_user_internal(connection_struct *conn,
current_user.conn = conn;
current_user.vuid = vuid;
+ return true;
+}
+
+static bool change_to_user_internal(connection_struct *conn,
+ const struct auth_session_info *session_info,
+ uint64_t vuid)
+{
+ bool ok;
+
+ ok = change_to_user_impersonate(conn, session_info, vuid);
+ if (!ok) {
+ return false;
+ }
+
current_user.need_chdir = conn->tcon_done;
current_user.done_chdir = false;