impersonation patchset part2 (Re: FLAG_CASELESS_PATHNAMES/SMBFLG_CASELESS in set_current_service())

Stefan Metzmacher metze at samba.org
Sun Jun 17 20:58:18 UTC 2018


And here's the patchset...

metze

Am 17.06.2018 um 22:53 schrieb Stefan Metzmacher via samba-technical:
> Am 15.06.2018 um 01:08 schrieb Jeremy Allison via samba-technical:
>> On Thu, Jun 14, 2018 at 08:01:13PM +0200, Stefan Metzmacher wrote:
>>>>>>> Windows servers ignore FLAG_CASELESS_PATHNAMES completely,
>>>>>>> but we do some magic just for smbclient and cifs.ko.
>>>>>>> Only [lib]smbclient supports changing the flag on a per request basis,
>>>>>>> but is it really used in practice?
>>>>>>
>>>>>> No.
>>>>>
>>>>> So we can really remove smbc_setOptionCaseSensitive() ?
>>>>> And the "case_sensitive" smbclient command?
>>>>
>>>> Yes, I think we can.
>>>
>>> And don't worry about the ABI change?
>>
>> What are our options here ? smbc_setOptionCaseSensitive()
>> will become a no-op, so we either leave it and document
>> it's not useful, or remove it and uprev the library major
>> number I think.
>>
>>>>>> POSIX opens (SMB1 global switch or SMB3 POSIX create context)
>>>>>> always mean case sensitive.
>>>>>
>>>>> Good.
>>>>>
>>>>>>> Can this all be done by FILE_FLAG_POSIX_SEMANTICS/ATTR_POSIX_SEMANTICS?
>>>>>>> Where we also have req->posix_pathnames and UCF_POSIX_PATHNAMES?
>>>>>>
>>>>>> Yeah, I think so - see above.
>>>>>>
>>>>>>> Any ideas how to move forward here?
>>>>>>
>>>>>> Does my plan work ? The only issues I can see are when we're
>>>>>> running on a Linux system that actually *has* a case-insensitive
>>>>>> filesystem underneath (XFS or ZFS mounted in case-insensitive mode).
>>>>>
>>>>> Then the filesystem should not announce FILE_CASE_SENSITIVE_SEARCH.
>>>>
>>>> Yes, that makes sense. The client can then know that
>>>> even if it asks for POSIX extensions it will not get
>>>> case-sensitive pathnames.
>>>
>>> Should we keep the "case sensitive" option to control this?
>>> Or should we better remove it completely.
>>
>> I think we keep it. That way, even on a case-sensitive filesystem
>> we can set "case sensitive = yes/default case = upper" to
>> preserve the large directory optimization.
>>
>>> And autodetect FILE_CASE_SENSITIVE_SEARCH from the local filesystem
>>> or add a new separate option for it?
>>
>> What option name are you thinking of here ?
>>
>>> I found it, during make_connection_snum() we don't have
>>> conn->origpath setup while calling change_to_user(),
>>> so I use a conn->tcon_done = true at the end of make_connection_snum()
>>> and only try chdir_current_service() from chane_to_user().
>>>
>>> The patches didn't pass autobuild, but I haven't checked yet if
>>> it was just a flakey test again.
>>
>> Wow, another really interesting patchset. You're on a roll here :-).
> 
> Ok, this one is reviewed by Ralph and passed autobuild a few times.
> The most important changes are:
> [PATCH 12/52] smbd: make it possible to call vfs_ChDir(conn,
> conn->cwd_fname);
> [PATCH 13/52] smbd: let create_conn_struct_as_root() fill in
>  conn->origpath
> [PATCH 19/52] smbd: call chdir_current_service() in
>  change_to_user_internal() and pop_conn_ctx()
> 
> +       /*
> +        * Check if the current context did a chdir_current_service()
> +        * and restore the cwd_fname of the previous context
> +        * if needed.
> +        */
> +       if (current_user.done_chdir && ctx_p->need_chdir) {
> +               int ret;
> +
> +               ret = vfs_ChDir(ctx_p->conn, ctx_p->conn->cwd_fname);
> +               if (ret != 0) {
> +                       DBG_ERR("vfs_ChDir() failed!\n");
> +                       smb_panic("vfs_ChDir() failed!\n");
> +               }
> +       }
> 
> I'll push that tomorrow.
> 
> metze
> 

-------------- next part --------------
From ef2c0d1b42efa8e99d9b73959ee86f004997f25c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 13:40:12 +0200
Subject: [PATCH 01/52] s3:lib: add caching to set_current_user_info()

Currently we do that in the caller, but we use global
cache anyway, so we can simplify the callers.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/lib/substitute.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c
index 9fdc5ca1edc7..ea227c5ab68d 100644
--- a/source3/lib/substitute.c
+++ b/source3/lib/substitute.c
@@ -247,6 +247,17 @@ static const char *get_smb_user_name(void)
 void set_current_user_info(const char *smb_name, const char *unix_name,
 			   const char *domain)
 {
+	static const void *last_smb_name;
+	static const void *last_unix_name;
+	static const void *last_domain;
+
+	if (likely(last_smb_name == smb_name &&
+	    last_unix_name == unix_name &&
+	    last_domain == domain))
+	{
+		return;
+	}
+
 	fstrcpy(current_user_info.smb_name, smb_name);
 	fstrcpy(current_user_info.unix_name, unix_name);
 	fstrcpy(current_user_info.domain, domain);
@@ -255,6 +266,10 @@ void set_current_user_info(const char *smb_name, const char *unix_name,
 	 * has already been sanitised in register_existing_vuid. */
 
 	sub_set_smb_name(current_user_info.smb_name);
+
+	last_smb_name = smb_name;
+	last_unix_name = unix_name;
+	last_domain = domain;
 }
 
 /*******************************************************************
-- 
2.17.1


From e4da94e3aa67872ae98e085c78e66c85af61960b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 13:58:04 +0200
Subject: [PATCH 02/52] smbd: remove xconn->client->last_session_id based
 set_current_user_info() caching

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/librpc/idl/smbXsrv.idl | 1 -
 source3/smbd/process.c         | 8 ++------
 source3/smbd/smb2_server.c     | 9 +++------
 3 files changed, 5 insertions(+), 13 deletions(-)

diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index d3f8d30d1e30..26758113af47 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -123,7 +123,6 @@ interface smbXsrv
 		 * this session_table is used for SMB1 and SMB2,
 		 */
 		[ignore] struct smbXsrv_session_table	*session_table;
-		[ignore] hyper				last_session_id;
 		/*
 		 * this tcon_table is only used for SMB1.
 		 */
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 1c54ca491462..29249ea9a759 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1571,13 +1571,9 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 		}
 	}
 
-	if (session_tag != xconn->client->last_session_id) {
-		struct user_struct *vuser = NULL;
+	if (session != NULL) {
+		struct user_struct *vuser = session->compat;
 
-		xconn->client->last_session_id = session_tag;
-		if (session) {
-			vuser = session->compat;
-		}
 		if (vuser) {
 			set_current_user_info(
 				vuser->session_info->unix_info->sanitized_username,
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 177e5ffc2f2f..a82161879c13 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -1964,12 +1964,9 @@ static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
 		return NT_STATUS_INVALID_HANDLE;
 	}
 
-	if (in_session_id != req->xconn->client->last_session_id) {
-		req->xconn->client->last_session_id = in_session_id;
-		set_current_user_info(session_info->unix_info->sanitized_username,
-				      session_info->unix_info->unix_name,
-				      session_info->info->domain_name);
-	}
+	set_current_user_info(session_info->unix_info->sanitized_username,
+			      session_info->unix_info->unix_name,
+			      session_info->info->domain_name);
 
 	return NT_STATUS_OK;
 }
-- 
2.17.1


From c1391aca409cd83c18eb1a074a4bac925938308b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 13 Jun 2018 11:03:01 +0200
Subject: [PATCH 03/52] smbd: split out set_current_case_sensitive() and
 chdir_current_service() functions

We'll soon use them independend from set_current_service().

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/proto.h   |  2 ++
 source3/smbd/service.c | 79 ++++++++++++++++++++++++++++--------------
 2 files changed, 55 insertions(+), 26 deletions(-)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 2851d6d5f7df..a6b8a05cb4c6 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1061,6 +1061,8 @@ void smbd_exit_server_cleanly(const char *const reason) _NORETURN_;
 
 bool set_conn_connectpath(connection_struct *conn, const char *connectpath);
 NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum);
+void set_current_case_sensitive(connection_struct *conn, uint16_t flags);
+bool chdir_current_service(connection_struct *conn);
 bool set_current_service(connection_struct *conn, uint16_t flags, bool do_chdir);
 void load_registry_shares(void);
 int add_home_service(const char *service, const char *username, const char *homedir);
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 75a47dee0caa..35b1a4617e85 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -90,40 +90,17 @@ bool set_conn_connectpath(connection_struct *conn, const char *connectpath)
  Load parameters specific to a connection/service.
 ****************************************************************************/
 
-bool set_current_service(connection_struct *conn, uint16_t flags, bool do_chdir)
+void set_current_case_sensitive(connection_struct *conn, uint16_t flags)
 {
 	int snum;
 	enum remote_arch_types ra_type;
 
-	if (!conn)  {
-		last_conn = NULL;
-		return(False);
-	}
-
-	conn->lastused_count++;
+	SMB_ASSERT(conn != NULL);
 
 	snum = SNUM(conn);
 
-	{
-		struct smb_filename connectpath_fname = {
-			.base_name = conn->connectpath
-		};
-		struct smb_filename origpath_fname = {
-			.base_name = conn->origpath
-		};
-
-		if (do_chdir &&
-		    vfs_ChDir(conn, &connectpath_fname) != 0 &&
-		    vfs_ChDir(conn, &origpath_fname) != 0) {
-			DEBUG(((errno!=EACCES)?0:3),
-				("chdir (%s) failed, reason: %s\n",
-				conn->connectpath, strerror(errno)));
-			return(False);
-		}
-	}
-
 	if ((conn == last_conn) && (last_flags == flags)) {
-		return(True);
+		return;
 	}
 
 	last_conn = conn;
@@ -157,6 +134,56 @@ bool set_current_service(connection_struct *conn, uint16_t flags, bool do_chdir)
 		conn->case_sensitive = false;
 		break;
 	}
+	return;
+}
+
+bool chdir_current_service(connection_struct *conn)
+{
+	const struct smb_filename connectpath_fname = {
+		.base_name = conn->connectpath,
+	};
+	const struct smb_filename origpath_fname = {
+		.base_name = conn->origpath,
+	};
+	int ret;
+
+	conn->lastused_count++;
+
+	ret = vfs_ChDir(conn, &connectpath_fname);
+	if (ret != 0) {
+		DEBUG(((errno!=EACCES)?0:3),
+		      ("chdir (%s) failed, reason: %s\n",
+		       conn->connectpath, strerror(errno)));
+		return false;
+	}
+
+	ret = vfs_ChDir(conn, &origpath_fname);
+	if (ret != 0) {
+		DEBUG(((errno!=EACCES)?0:3),
+			("chdir (%s) failed, reason: %s\n",
+			conn->origpath, strerror(errno)));
+		return false;
+	}
+
+	return true;
+}
+
+bool set_current_service(connection_struct *conn, uint16_t flags, bool do_chdir)
+{
+	bool ok;
+
+	if (conn == NULL)  {
+		return false;
+	}
+
+	if (do_chdir) {
+		ok = chdir_current_service(conn);
+		if (!ok) {
+			return false;
+		}
+	}
+
+	set_current_case_sensitive(conn, flags);
 	return true;
 }
 
-- 
2.17.1


From 20192f116b36eae583836849e67ddba2791eaefe Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 13 Jun 2018 11:23:42 +0200
Subject: [PATCH 04/52] smbd: call set_current_case_sensitive() before
 chdir_current_service()

I guess we better setup conn->case_sensitive before doing the
vfs_ChDir() calls, so we have a consistent result everytime.
Otherwise vfs_Chdir() would get conn->case_sensitive from
last request.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/service.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 35b1a4617e85..484461dfee93 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -176,6 +176,8 @@ bool set_current_service(connection_struct *conn, uint16_t flags, bool do_chdir)
 		return false;
 	}
 
+	set_current_case_sensitive(conn, flags);
+
 	if (do_chdir) {
 		ok = chdir_current_service(conn);
 		if (!ok) {
@@ -183,7 +185,6 @@ bool set_current_service(connection_struct *conn, uint16_t flags, bool do_chdir)
 		}
 	}
 
-	set_current_case_sensitive(conn, flags);
 	return true;
 }
 
-- 
2.17.1


From d70d0d6ad02e75a0b93a6d05bf2114da479da4f8 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 3 May 2018 15:04:30 +0200
Subject: [PATCH 05/52] smbd: let check_user_ok() construct ent->session_info
 in one coherent block

We should finish manipulating ent->session_info before filling
conn->session_info. And conn->session_info should be not be changed.

Use git show -U15.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/uid.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index b24ae3cc3b07..0af47831a4de 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -240,6 +240,14 @@ static bool check_user_ok(connection_struct *conn,
 		return false;
 	}
 
+	if (admin_user) {
+		DEBUG(2,("check_user_ok: user %s is an admin user. "
+			"Setting uid as %d\n",
+			ent->session_info->unix_info->unix_name,
+			sec_initial_uid() ));
+		ent->session_info->unix_token->uid = sec_initial_uid();
+	}
+
 	/*
 	 * It's actually OK to call check_user_ok() with
 	 * vuid == UID_FIELD_INVALID as called from change_to_user_by_session().
@@ -265,14 +273,6 @@ static bool check_user_ok(connection_struct *conn,
 	conn->read_only = readonly_share;
 	conn->share_access = share_access;
 
-	if (admin_user) {
-		DEBUG(2,("check_user_ok: user %s is an admin user. "
-			"Setting uid as %d\n",
-			conn->session_info->unix_info->unix_name,
-			sec_initial_uid() ));
-		conn->session_info->unix_token->uid = sec_initial_uid();
-	}
-
 	return(True);
 }
 
-- 
2.17.1


From 6924d024971fd3f78bac4f0f92149e63efe5edd2 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 12 Jun 2018 15:39:51 +0200
Subject: [PATCH 06/52] smbd: simplify the logic in change_to_user()

We can return early if (vuser == NULL).

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/uid.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 0af47831a4de..e100c45a6069 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -378,15 +378,6 @@ bool change_to_user(connection_struct *conn, uint64_t vuid)
 	}
 
 	vuser = get_valid_user_struct(conn->sconn, vuid);
-
-	if ((current_user.conn == conn) &&
-		   (vuser != NULL) && (current_user.vuid == vuid) &&
-		   (current_user.ut.uid == vuser->session_info->unix_token->uid)) {
-		DEBUG(4,("Skipping user change - already "
-			 "user\n"));
-		return(True);
-	}
-
 	if (vuser == NULL) {
 		/* Invalid vuid sent */
 		DEBUG(2,("Invalid vuid %llu used on share %s.\n",
@@ -395,6 +386,14 @@ bool change_to_user(connection_struct *conn, uint64_t vuid)
 		return false;
 	}
 
+	if ((current_user.conn == conn) &&
+	    (current_user.vuid == vuid) &&
+	    (current_user.ut.uid == vuser->session_info->unix_token->uid))
+	{
+		DBG_INFO("Skipping user change - already user\n");
+		return true;
+	}
+
 	return change_to_user_internal(conn, vuser->session_info, vuid);
 }
 
-- 
2.17.1


From f575c7fcb97b5926938d15b55615580e8e296bf1 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 12 Jun 2018 15:39:51 +0200
Subject: [PATCH 07/52] smbd: move current_user caching to
 change_to_user_internal()

Note that (current_user.vuid == vuid) also works with
UID_FIELD_INVALID.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/uid.c | 23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index e100c45a6069..af8a60d99eed 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -293,6 +293,14 @@ static bool change_to_user_internal(connection_struct *conn,
 	gid_t *group_list = NULL;
 	bool ok;
 
+	if ((current_user.conn == conn) &&
+	    (current_user.vuid == vuid) &&
+	    (current_user.ut.uid == session_info->unix_token->uid))
+	{
+		DBG_INFO("Skipping user change - already user\n");
+		return true;
+	}
+
 	snum = SNUM(conn);
 
 	ok = check_user_ok(conn, vuid, session_info, snum);
@@ -386,14 +394,6 @@ bool change_to_user(connection_struct *conn, uint64_t vuid)
 		return false;
 	}
 
-	if ((current_user.conn == conn) &&
-	    (current_user.vuid == vuid) &&
-	    (current_user.ut.uid == vuser->session_info->unix_token->uid))
-	{
-		DBG_INFO("Skipping user change - already user\n");
-		return true;
-	}
-
 	return change_to_user_internal(conn, vuser->session_info, vuid);
 }
 
@@ -403,13 +403,6 @@ static bool change_to_user_by_session(connection_struct *conn,
 	SMB_ASSERT(conn != NULL);
 	SMB_ASSERT(session_info != NULL);
 
-	if ((current_user.conn == conn) &&
-	    (current_user.ut.uid == session_info->unix_token->uid)) {
-		DEBUG(7, ("Skipping user change - already user\n"));
-
-		return true;
-	}
-
 	return change_to_user_internal(conn, session_info, UID_FIELD_INVALID);
 }
 
-- 
2.17.1


From eafe8a30534fc9bdf5ae8d8856d4b7b849921616 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 14:22:43 +0200
Subject: [PATCH 08/52] smbd: call set_current_user_info() in
 change_to_user_internal() and pop_conn_ctx()

change_to_user() should be the one and only function for the whole
impersonation processing. So we also need to stack the
set_current_user_info() information for become_user/unbecome_user.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/globals.h | 1 +
 source3/smbd/uid.c     | 9 +++++++++
 2 files changed, 10 insertions(+)

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 69db07a490ba..384599be1df2 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -89,6 +89,7 @@ extern uint16_t fnf_handle;
 struct conn_ctx {
 	connection_struct *conn;
 	uint64_t vuid;
+	userdom_struct user_info;
 };
 /* A stack of current_user connection contexts. */
 extern struct conn_ctx conn_ctx_stack[MAX_SEC_CTX_DEPTH];
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index af8a60d99eed..913d4f3aa0a1 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -301,6 +301,10 @@ static bool change_to_user_internal(connection_struct *conn,
 		return true;
 	}
 
+	set_current_user_info(session_info->unix_info->sanitized_username,
+			      session_info->unix_info->unix_name,
+			      session_info->info->domain_name);
+
 	snum = SNUM(conn);
 
 	ok = check_user_ok(conn, vuid, session_info, snum);
@@ -467,6 +471,7 @@ bool smbd_unbecome_authenticated_pipe_user(void)
 static void push_conn_ctx(void)
 {
 	struct conn_ctx *ctx_p;
+	extern userdom_struct current_user_info;
 
 	/* Check we don't overflow our stack */
 
@@ -480,6 +485,7 @@ static void push_conn_ctx(void)
 
 	ctx_p->conn = current_user.conn;
 	ctx_p->vuid = current_user.vuid;
+	ctx_p->user_info = current_user_info;
 
 	DEBUG(4, ("push_conn_ctx(%llu) : conn_ctx_stack_ndx = %d\n",
 		(unsigned long long)ctx_p->vuid, conn_ctx_stack_ndx));
@@ -501,6 +507,9 @@ static void pop_conn_ctx(void)
 	conn_ctx_stack_ndx--;
 	ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
 
+	set_current_user_info(ctx_p->user_info.smb_name,
+			      ctx_p->user_info.unix_name,
+			      ctx_p->user_info.domain);
 	current_user.conn = ctx_p->conn;
 	current_user.vuid = ctx_p->vuid;
 
-- 
2.17.1


From 6f16b970f29faffa433f3021a7a1330c946c2d89 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 14 Jun 2018 07:26:14 +0200
Subject: [PATCH 09/52] smbd: make it explicit that make_connection_snum()
 returns NT_STATUS_OK on success

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/service.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 484461dfee93..d0932c0e9717 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -879,7 +879,7 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
 		dbgtext( "(pid %d)\n", (int)getpid() );
 	}
 
-	return status;
+	return NT_STATUS_OK;
 
   err_root_exit:
 
-- 
2.17.1


From bcbdc6ee5bf9622e5876dcc267f2e8dcbddd229d Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 14 Jun 2018 07:27:43 +0200
Subject: [PATCH 10/52] smbd: remember that the tcon completely setup
 connection_struct

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/include/vfs.h  | 1 +
 source3/smbd/msdfs.c   | 1 +
 source3/smbd/service.c | 1 +
 3 files changed, 3 insertions(+)

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 81fb6c1f1453..54ab1604b799 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -436,6 +436,7 @@ typedef struct connection_struct {
 	char *connectpath;
 	char *origpath;
 	struct smb_filename *cwd_fname; /* Working directory. */
+	bool tcon_done;
 
 	struct vfs_handle_struct *vfs_handles;		/* for the new plugins */
 
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 1a6454b5c2be..a143e6d23cac 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -358,6 +358,7 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 	}
 
 	conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
+	conn->tcon_done = true;
 	*pconn = talloc_move(ctx, &conn);
 
 	return NT_STATUS_OK;
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index d0932c0e9717..612c88357ef7 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -879,6 +879,7 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
 		dbgtext( "(pid %d)\n", (int)getpid() );
 	}
 
+	conn->tcon_done = true;
 	return NT_STATUS_OK;
 
   err_root_exit:
-- 
2.17.1


From cffceb7ab98cbb24a3029f1dbc85df93b6072e02 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 14 Jun 2018 11:15:10 +0200
Subject: [PATCH 11/52] smbd: call set_current_case_sensitive() before
 change_to_user() in switch_message()

change_to_user() will soon call chdir_current_service() and we should
make sure conn->case_sensitive is prepared before calling vfs_ChDir().

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/process.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 29249ea9a759..7babf4d5699f 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1599,6 +1599,8 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 			return NULL;
 		}
 
+		set_current_case_sensitive(conn, SVAL(req->inbuf,smb_flg));
+
 		if (!change_to_user(conn,session_tag)) {
 			DEBUG(0, ("Error: Could not change to user. Removing "
 				"deferred open, mid=%llu.\n",
-- 
2.17.1


From 0f714d05c4c386f43956dc0f24e5e30d7eb0ef76 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 15 Jun 2018 11:49:57 +0200
Subject: [PATCH 12/52] smbd: make it possible to call vfs_ChDir(conn,
 conn->cwd_fname);

We should only TALLOC_FREE(old_cwd) at the successful end.
This also avoids calling cp_smb_filename() on the old value.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/vfs.c | 27 ++++++---------------------
 1 file changed, 6 insertions(+), 21 deletions(-)

diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index c3f39f324744..ebe5ca5b8698 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -787,7 +787,7 @@ int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
 {
 	int ret;
 	int saved_errno = 0;
-	struct smb_filename *saved_cwd = NULL;
+	struct smb_filename *old_cwd = conn->cwd_fname;
 
 	if (!LastDir) {
 		LastDir = SMB_STRDUP("");
@@ -802,24 +802,10 @@ int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
 		return 0;
 	}
 
-	if (conn->cwd_fname != NULL) {
-		/*
-		 * Save off where we are in case we need to return
-		 * on vfs_GetWd() failure after successful SMB_VFS_CHDIR().
-		 */
-		saved_cwd = cp_smb_filename(conn, conn->cwd_fname);
-		if (saved_cwd == NULL) {
-			return -1;
-		}
-	}
-
 	DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
 
 	ret = SMB_VFS_CHDIR(conn, smb_fname);
 	if (ret != 0) {
-		saved_errno = errno;
-		TALLOC_FREE(saved_cwd);
-		errno = saved_errno;
 		return -1;
 	}
 
@@ -830,7 +816,6 @@ int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
 	 */
 
 	/* conn cache. */
-	TALLOC_FREE(conn->cwd_fname);
 	conn->cwd_fname = vfs_GetWd(conn, conn);
 	if (conn->cwd_fname == NULL) {
 		/*
@@ -841,7 +826,7 @@ int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
 		 */
 		saved_errno = errno;
 
-		if (saved_cwd == NULL) {
+		if (old_cwd == NULL) {
 			/*
 			 * Failed on the very first chdir()+getwd()
 			 * for this connection. We can't
@@ -851,16 +836,16 @@ int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
 			/* NOTREACHED */
 			return -1;
 		}
+		/* Restore original conn->cwd_fname. */
+		conn->cwd_fname = old_cwd;
 
 		/* Return to the previous $cwd. */
-		ret = SMB_VFS_CHDIR(conn, saved_cwd);
+		ret = SMB_VFS_CHDIR(conn, conn->cwd_fname);
 		if (ret != 0) {
 			smb_panic("conn->cwd getwd failed\n");
 			/* NOTREACHED */
 			return -1;
 		}
-		/* Restore original conn->cwd_fname. */
-		conn->cwd_fname = saved_cwd;
 		errno = saved_errno;
 		/* And fail the chdir(). */
 		return -1;
@@ -873,7 +858,7 @@ int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
 
 	DEBUG(4,("vfs_ChDir got %s\n", conn->cwd_fname->base_name));
 
-	TALLOC_FREE(saved_cwd);
+	TALLOC_FREE(old_cwd);
 	if (saved_errno != 0) {
 		errno = saved_errno;
 	}
-- 
2.17.1


From 1e29148219a1bd8ff5a2a536a1c1ee86701d3abf Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 15 Jun 2018 18:40:11 +0200
Subject: [PATCH 13/52] smbd: let create_conn_struct_as_root() fill in
 conn->origpath

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/msdfs.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index a143e6d23cac..59ef628322a3 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -357,6 +357,13 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		return NT_STATUS_UNSUCCESSFUL;
 	}
 
+	talloc_free(conn->origpath);
+	conn->origpath = talloc_strdup(conn, conn->connectpath);
+	if (conn->origpath == NULL) {
+		conn_free(conn);
+		return NT_STATUS_NO_MEMORY;
+	}
+
 	conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
 	conn->tcon_done = true;
 	*pconn = talloc_move(ctx, &conn);
-- 
2.17.1


From d246b78042b182fe3eac3fa86eab22b2b9ae6510 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 14 Jun 2018 08:21:21 +0200
Subject: [PATCH 14/52] smbd: use conn->lastused_count++ directly in
 process_blocking_lock_queue()

This avoids using set_current_service(), which will be removed shortly.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/blocking.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 1e3a596d11fb..6cbf5c03e932 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -842,13 +842,10 @@ void process_blocking_lock_queue(struct smbd_server_connection *sconn)
 
 		DEBUG(10, ("Processing BLR = %p\n", blr));
 
-		/* We use set_current_service so connections with
-		 * pending locks are not marked as idle.
+		/*
+		 * Connections with pending locks are not marked as idle.
 		 */
-
-		set_current_service(blr->fsp->conn,
-				SVAL(blr->req->inbuf,smb_flg),
-				false);
+		blr->fsp->conn->lastused_count++;
 
 		/*
 		 * Remove the pending lock we're waiting on.
-- 
2.17.1


From e906a61d80c0e4d8f7866ac88e8acbf4139ee7eb Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 14 Jun 2018 08:23:56 +0200
Subject: [PATCH 15/52] smbd: remove useless set_current_service(NULL,0,True)
 from reload_services()

All this does is 'return false' as conn is NULL...

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/server_reload.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/source3/smbd/server_reload.c b/source3/smbd/server_reload.c
index 3715a51c1529..0f0621e3e813 100644
--- a/source3/smbd/server_reload.c
+++ b/source3/smbd/server_reload.c
@@ -161,8 +161,5 @@ bool reload_services(struct smbd_server_connection *sconn,
 	reset_stat_cache();
 	flush_dfree_cache();
 
-	/* this forces service parameters to be flushed */
-	set_current_service(NULL,0,True);
-
 	return(ret);
 }
-- 
2.17.1


From 47435ddc71ad170bdeb29aef20dacdbfd8dca734 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 14 Jun 2018 08:27:50 +0200
Subject: [PATCH 16/52] smbd: call chdir_current_service() directly in
 smbXsrv_tcon_disconnect()

There's no need to worry about conn->case_sensitive here.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/smbXsrv_tcon.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/source3/smbd/smbXsrv_tcon.c b/source3/smbd/smbXsrv_tcon.c
index 2804311d93c6..5ad557e1f5e6 100644
--- a/source3/smbd/smbXsrv_tcon.c
+++ b/source3/smbd/smbXsrv_tcon.c
@@ -969,11 +969,11 @@ NTSTATUS smbXsrv_tcon_disconnect(struct smbXsrv_tcon *tcon, uint64_t vuid)
 	if (tcon->compat) {
 		bool ok;
 
-		ok = set_current_service(tcon->compat, 0, true);
+		ok = chdir_current_service(tcon->compat);
 		if (!ok) {
 			status = NT_STATUS_INTERNAL_ERROR;
 			DEBUG(0, ("smbXsrv_tcon_disconnect(0x%08x, '%s'): "
-				  "set_current_service() failed: %s\n",
+				  "chdir_current_service() failed: %s\n",
 				  tcon->global->tcon_global_id,
 				  tcon->global->share_name,
 				  nt_errstr(status)));
-- 
2.17.1


From 470d451e1352c1fd76d363d51b9247ef60136f5f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 14 Jun 2018 08:29:45 +0200
Subject: [PATCH 17/52] smbd: remove set_current_service() from
 defer_rename_done()

The change_to_user() above already called chdir_current_service().
And for smb2 we don't have per packet conn->case_sensitive anyway.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/smb2_setinfo.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c
index 9cd4fdf92024..4958bb8f16e7 100644
--- a/source3/smbd/smb2_setinfo.c
+++ b/source3/smbd/smb2_setinfo.c
@@ -302,12 +302,6 @@ static void defer_rename_done(struct tevent_req *subreq)
 		return;
 	}
 
-	ok = set_current_service(state->smb2req->tcon->compat, 0, true);
-	if (!ok) {
-		tevent_req_nterror(state->req, NT_STATUS_ACCESS_DENIED);
-		return;
-	}
-
 	/* Do we still need to wait ? */
 	lck = get_existing_share_mode_lock(state->req, state->fsp->file_id);
 	if (lck == NULL) {
-- 
2.17.1


From 5a4abe1e4a35dedd72c1cf8000efc893897c73dd Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 14 Jun 2018 08:29:45 +0200
Subject: [PATCH 18/52] smbd: remove set_current_service() from
 smbd_smb2_request_check_tcon()

The change_to_user() above already called chdir_current_service().
And for smb2 we don't have per packet conn->case_sensitive anyway.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/smb2_server.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index a82161879c13..3ecc1189a877 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -1846,10 +1846,6 @@ static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
-	if (!set_current_service(tcon->compat, 0, true)) {
-		return NT_STATUS_ACCESS_DENIED;
-	}
-
 	req->tcon = tcon;
 	req->last_tid = in_tid;
 
-- 
2.17.1


From 9ed27dc76f61ff1172fd18fa2e065cfbbd2026c0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 13 Jun 2018 13:30:33 +0200
Subject: [PATCH 19/52] smbd: call chdir_current_service() in
 change_to_user_internal() and pop_conn_ctx()

change_to_user() should be the one and only function for the whole
impersonation processing. So we also need to stack the
chdir_current_service() behaviour for become_user/unbecome_user,
so we may need to call vfs_ChDir(ctx_p->conn, ctx_p->conn->cwd_fname);
in pop_conn_ctx().

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/include/smb.h  |  2 ++
 source3/smbd/globals.h |  2 ++
 source3/smbd/uid.c     | 54 ++++++++++++++++++++++++++++++++++++------
 3 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/source3/include/smb.h b/source3/include/smb.h
index 5e83ee90afe2..9ec654308521 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -156,6 +156,8 @@ struct sys_notify_context {
 struct current_user {
 	struct connection_struct *conn;
 	uint64_t vuid; /* SMB2 compat */
+	bool need_chdir;
+	bool done_chdir;
 	struct security_unix_token ut;
 	struct security_token *nt_user_token;
 };
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 384599be1df2..057645bedeeb 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -89,6 +89,8 @@ extern uint16_t fnf_handle;
 struct conn_ctx {
 	connection_struct *conn;
 	uint64_t vuid;
+	bool need_chdir;
+	bool done_chdir;
 	userdom_struct user_info;
 };
 /* A stack of current_user connection contexts. */
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 913d4f3aa0a1..289727d95746 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -52,6 +52,8 @@ bool change_to_guest(void)
 
 	current_user.conn = NULL;
 	current_user.vuid = UID_FIELD_INVALID;
+	current_user.need_chdir = false;
+	current_user.done_chdir = false;
 
 	TALLOC_FREE(pass);
 
@@ -295,6 +297,7 @@ 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");
@@ -369,12 +372,26 @@ static bool change_to_user_internal(connection_struct *conn,
 
 	current_user.conn = conn;
 	current_user.vuid = vuid;
+	current_user.need_chdir = conn->tcon_done;
 
-	DEBUG(5, ("Impersonated user: uid=(%d,%d), gid=(%d,%d)\n",
-		 (int)getuid(),
-		 (int)geteuid(),
-		 (int)getgid(),
-		 (int)getegid()));
+	if (current_user.need_chdir) {
+		ok = chdir_current_service(conn);
+		if (!ok) {
+			DBG_ERR("chdir_current_service() failed!\n");
+			return false;
+		}
+		current_user.done_chdir = true;
+	}
+
+	if (CHECK_DEBUGLVL(DBGLVL_INFO)) {
+		char cwdbuf[PATH_MAX+1] = { 0, };
+		DBG_INFO("Impersonated user: uid=(%d,%d), gid=(%d,%d), cwd=[%s]\n",
+			 (int)getuid(),
+			 (int)geteuid(),
+			 (int)getgid(),
+			 (int)getegid(),
+			 getcwd(cwdbuf, sizeof(cwdbuf)));
+	}
 
 	return true;
 }
@@ -424,6 +441,8 @@ bool smbd_change_to_root_user(void)
 
 	current_user.conn = NULL;
 	current_user.vuid = UID_FIELD_INVALID;
+	current_user.need_chdir = false;
+	current_user.done_chdir = false;
 
 	return(True);
 }
@@ -485,6 +504,8 @@ static void push_conn_ctx(void)
 
 	ctx_p->conn = current_user.conn;
 	ctx_p->vuid = current_user.vuid;
+	ctx_p->need_chdir = current_user.need_chdir;
+	ctx_p->done_chdir = current_user.done_chdir;
 	ctx_p->user_info = current_user_info;
 
 	DEBUG(4, ("push_conn_ctx(%llu) : conn_ctx_stack_ndx = %d\n",
@@ -510,11 +531,30 @@ static void pop_conn_ctx(void)
 	set_current_user_info(ctx_p->user_info.smb_name,
 			      ctx_p->user_info.unix_name,
 			      ctx_p->user_info.domain);
+
+	/*
+	 * Check if the current context did a chdir_current_service()
+	 * and restore the cwd_fname of the previous context
+	 * if needed.
+	 */
+	if (current_user.done_chdir && ctx_p->need_chdir) {
+		int ret;
+
+		ret = vfs_ChDir(ctx_p->conn, ctx_p->conn->cwd_fname);
+		if (ret != 0) {
+			DBG_ERR("vfs_ChDir() failed!\n");
+			smb_panic("vfs_ChDir() failed!\n");
+		}
+	}
+
 	current_user.conn = ctx_p->conn;
 	current_user.vuid = ctx_p->vuid;
+	current_user.need_chdir = ctx_p->need_chdir;
+	current_user.done_chdir = ctx_p->done_chdir;
 
-	ctx_p->conn = NULL;
-	ctx_p->vuid = UID_FIELD_INVALID;
+	*ctx_p = (struct conn_ctx) {
+		.vuid = UID_FIELD_INVALID,
+	};
 }
 
 /****************************************************************************
-- 
2.17.1


From 367a33cec10abaa44ed693e522e193915fd1fed4 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 14 Jun 2018 11:18:13 +0200
Subject: [PATCH 20/52] smbd: let switch_message() only call
 chdir_current_service() for SMBtdis/SMBexit

These are the two opcodes with DO_CHDIR, we don't want the
set_current_case_sensitive() logic for them,
so we don't need the full set_current_service() anymore.

The AS_USER case is already handled before, set_current_case_sensitive()
is called directly before change_to_user(), which already
calls chdir_current_service().

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/process.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 7babf4d5699f..88362711632b 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1654,11 +1654,14 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 			}
 		}
 
-		if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
-					 (flags & (AS_USER|DO_CHDIR)
-					  ?True:False))) {
-			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
-			return conn;
+		if (flags & DO_CHDIR) {
+			bool ok;
+
+			ok = chdir_current_service(conn);
+			if (!ok) {
+				reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+				return conn;
+			}
 		}
 		conn->num_smb_operations++;
 	}
-- 
2.17.1


From dc98da2d3a00d4361587df32358a35387eb33a88 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 14 Jun 2018 11:22:31 +0200
Subject: [PATCH 21/52] smbd: remove unused set_current_service()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/proto.h   |  1 -
 source3/smbd/service.c | 20 --------------------
 2 files changed, 21 deletions(-)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index a6b8a05cb4c6..0c4c68187c22 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1063,7 +1063,6 @@ bool set_conn_connectpath(connection_struct *conn, const char *connectpath);
 NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum);
 void set_current_case_sensitive(connection_struct *conn, uint16_t flags);
 bool chdir_current_service(connection_struct *conn);
-bool set_current_service(connection_struct *conn, uint16_t flags, bool do_chdir);
 void load_registry_shares(void);
 int add_home_service(const char *service, const char *username, const char *homedir);
 int find_service(TALLOC_CTX *ctx, const char *service, char **p_service_out);
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 612c88357ef7..a22a0270cd79 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -168,26 +168,6 @@ bool chdir_current_service(connection_struct *conn)
 	return true;
 }
 
-bool set_current_service(connection_struct *conn, uint16_t flags, bool do_chdir)
-{
-	bool ok;
-
-	if (conn == NULL)  {
-		return false;
-	}
-
-	set_current_case_sensitive(conn, flags);
-
-	if (do_chdir) {
-		ok = chdir_current_service(conn);
-		if (!ok) {
-			return false;
-		}
-	}
-
-	return true;
-}
-
 /****************************************************************************
  do some basic sainity checks on the share.  
  This function modifies dev, ecode.
-- 
2.17.1


From 1541ebc0d630a3230346f0f1a248f1dc271415fe Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 16:30:13 +0200
Subject: [PATCH 22/52] smbd: avoid calling set_current_user_info() twice with
 AS_USER (SMB1)

It will be called via change_to_user().

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/process.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 88362711632b..54f7753e736c 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1571,9 +1571,16 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 		}
 	}
 
-	if (session != NULL) {
+	if (session != NULL && !(flags & AS_USER)) {
 		struct user_struct *vuser = session->compat;
 
+		/*
+		 * change_to_user() implies set_current_user_info()
+		 * and chdir_connect_service().
+		 *
+		 * So we only call set_current_user_info if
+		 * we don't have AS_USER specified.
+		 */
 		if (vuser) {
 			set_current_user_info(
 				vuser->session_info->unix_info->sanitized_username,
@@ -1601,6 +1608,10 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 
 		set_current_case_sensitive(conn, SVAL(req->inbuf,smb_flg));
 
+		/*
+		 * change_to_user() implies set_current_user_info()
+		 * and chdir_connect_service().
+		 */
 		if (!change_to_user(conn,session_tag)) {
 			DEBUG(0, ("Error: Could not change to user. Removing "
 				"deferred open, mid=%llu.\n",
-- 
2.17.1


From 7d757e3b521955619e2f3f3ac356cf93ac1ee478 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 16:30:13 +0200
Subject: [PATCH 23/52] smbd: avoid calling set_current_user_info() twice with
 .need_tcon (SMB2)

It's already called via change_to_user().

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/smb2_server.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 3ecc1189a877..ed718b83958d 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -1960,10 +1960,6 @@ static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
 		return NT_STATUS_INVALID_HANDLE;
 	}
 
-	set_current_user_info(session_info->unix_info->sanitized_username,
-			      session_info->unix_info->unix_name,
-			      session_info->info->domain_name);
-
 	return NT_STATUS_OK;
 }
 
@@ -2340,9 +2336,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 	}
 
 	/*
-	 * Check if the client provided a valid session id,
-	 * if so smbd_smb2_request_check_session() calls
-	 * set_current_user_info().
+	 * Check if the client provided a valid session id.
 	 *
 	 * As some command don't require a valid session id
 	 * we defer the check of the session_status
@@ -2507,6 +2501,8 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 		 *
 		 * smbd_smb2_request_check_tcon()
 		 * calls change_to_user() on success.
+		 * Which implies set_current_user_info()
+		 * and chdir_current_service().
 		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
@@ -2522,6 +2518,22 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 			return smbd_smb2_request_error(req,
 				NT_STATUS_ACCESS_DENIED);
 		}
+	} else if (call->need_session) {
+		struct auth_session_info *session_info = NULL;
+
+		/*
+		 * Unless we also have need_tcon (see above),
+		 * we still need to call set_current_user_info().
+		 */
+
+		session_info = req->session->global->auth_session_info;
+		if (session_info == NULL) {
+			return NT_STATUS_INVALID_HANDLE;
+		}
+
+		set_current_user_info(session_info->unix_info->sanitized_username,
+				      session_info->unix_info->unix_name,
+				      session_info->info->domain_name);
 	}
 
 	if (req->was_encrypted || encryption_desired) {
-- 
2.17.1


From f7e1087ca249e1b14f6065017a8f601260796760 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 11:37:52 +0200
Subject: [PATCH 24/52] vfs_default: remove unused checks which are already
 caught by vfs_offload_token_check_handles()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/modules/vfs_default.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 82afb054a137..58df47ee6b4c 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1700,16 +1700,6 @@ static struct tevent_req *vfswrap_offload_write_send(
 		return tevent_req_post(req, ev);
 	}
 
-	if (src_fsp->op == NULL) {
-		tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
-		return tevent_req_post(req, ev);
-	}
-
-	if (dest_fsp->op == NULL) {
-		tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
-		return tevent_req_post(req, ev);
-	}
-
 	status = vfswrap_offload_write_loop(req);
 	if (!NT_STATUS_IS_OK(status)) {
 		tevent_req_nterror(req, status);
-- 
2.17.1


From 0886c9d00b4870472f6addb831449559ea414295 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 11:37:52 +0200
Subject: [PATCH 25/52] vfs_btrfs: remove unused checks which are already
 caught by vfs_offload_token_check_handles()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/modules/vfs_btrfs.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/source3/modules/vfs_btrfs.c b/source3/modules/vfs_btrfs.c
index 775e5f076116..4c07ebd36ecb 100644
--- a/source3/modules/vfs_btrfs.c
+++ b/source3/modules/vfs_btrfs.c
@@ -298,11 +298,6 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 		return tevent_req_post(req, ev);
 	}
 
-	if (src_fsp->op == NULL || dest_fsp->op == NULL) {
-		tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
-		return tevent_req_post(req, ev);
-	}
-
 	if (do_locking) {
 		init_strict_lock_struct(src_fsp,
 					src_fsp->op->global->open_persistent_id,
-- 
2.17.1


From 87dfe60789508360f6ce6f30b34597d6019708ed Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 12:40:21 +0200
Subject: [PATCH 26/52] vfs_btrfs: update
 s/btrfs_cc_state/btrfs_offload_write_state/ s/cc_state/state/

This matches our naming conventions used for tevent_req based functions.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/modules/vfs_btrfs.c | 60 ++++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 27 deletions(-)

diff --git a/source3/modules/vfs_btrfs.c b/source3/modules/vfs_btrfs.c
index 4c07ebd36ecb..cc082f7fbbf3 100644
--- a/source3/modules/vfs_btrfs.c
+++ b/source3/modules/vfs_btrfs.c
@@ -196,7 +196,7 @@ static NTSTATUS btrfs_offload_read_recv(struct tevent_req *req,
 	return NT_STATUS_OK;
 }
 
-struct btrfs_cc_state {
+struct btrfs_offload_write_state {
 	struct vfs_handle_struct *handle;
 	off_t copied;
 	struct tevent_req *subreq;	/* non-null if passed to next VFS fn */
@@ -213,8 +213,8 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 						off_t dest_off,
 						off_t num)
 {
-	struct tevent_req *req;
-	struct btrfs_cc_state *cc_state;
+	struct tevent_req *req = NULL;
+	struct btrfs_offload_write_state *state = NULL;
 	struct btrfs_ioctl_clone_range_args cr_args;
 	struct lock_struct src_lck;
 	struct lock_struct dest_lck;
@@ -225,12 +225,13 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 	bool do_locking = false;
 	NTSTATUS status;
 
-	req = tevent_req_create(mem_ctx, &cc_state, struct btrfs_cc_state);
+	req = tevent_req_create(mem_ctx, &state,
+				struct btrfs_offload_write_state);
 	if (req == NULL) {
 		return NULL;
 	}
 
-	cc_state->handle = handle;
+	state->handle = handle;
 
 	status = vfs_offload_token_db_fetch_fsp(btrfs_offload_ctx,
 						token, &src_fsp);
@@ -263,18 +264,19 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 	}
 
 	if (!handle_offload_write) {
-		cc_state->subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle,
-								cc_state, ev,
+		state->subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle,
+								state,
+								ev,
 								fsctl,
 								token,
 								transfer_offset,
 								dest_fsp,
 								dest_off,
 								num);
-		if (tevent_req_nomem(cc_state->subreq, req)) {
+		if (tevent_req_nomem(state->subreq, req)) {
 			return tevent_req_post(req, ev);
 		}
-		tevent_req_set_callback(cc_state->subreq,
+		tevent_req_set_callback(state->subreq,
 					btrfs_offload_write_done,
 					req);
 		return req;
@@ -343,19 +345,20 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 			  (unsigned long long)cr_args.src_offset,
 			  dest_fsp->fh->fd,
 			  (unsigned long long)cr_args.dest_offset));
-		cc_state->subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle,
-								cc_state, ev,
+		state->subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle,
+								state,
+								ev,
 								fsctl,
 								token,
 								transfer_offset,
 								dest_fsp,
 								dest_off,
 								num);
-		if (tevent_req_nomem(cc_state->subreq, req)) {
+		if (tevent_req_nomem(state->subreq, req)) {
 			return tevent_req_post(req, ev);
 		}
 		/* wait for subreq completion */
-		tevent_req_set_callback(cc_state->subreq,
+		tevent_req_set_callback(state->subreq,
 					btrfs_offload_write_done,
 					req);
 		return req;
@@ -363,7 +366,7 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 
 	DEBUG(5, ("BTRFS_IOC_CLONE_RANGE returned %d\n", ret));
 	/* BTRFS_IOC_CLONE_RANGE is all or nothing */
-	cc_state->copied = num;
+	state->copied = num;
 	tevent_req_done(req);
 	return tevent_req_post(req, ev);
 }
@@ -371,15 +374,17 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 /* only used if the request is passed through to next VFS module */
 static void btrfs_offload_write_done(struct tevent_req *subreq)
 {
-	struct tevent_req *req = tevent_req_callback_data(
-		subreq, struct tevent_req);
-	struct btrfs_cc_state *cc_state = tevent_req_data(req,
-							struct btrfs_cc_state);
+	struct tevent_req *req =
+		tevent_req_callback_data(subreq,
+		struct tevent_req);
+	struct btrfs_offload_write_state *state =
+		tevent_req_data(req,
+		struct btrfs_offload_write_state);
 	NTSTATUS status;
 
-	status = SMB_VFS_NEXT_OFFLOAD_WRITE_RECV(cc_state->handle,
-					      cc_state->subreq,
-					      &cc_state->copied);
+	status = SMB_VFS_NEXT_OFFLOAD_WRITE_RECV(state->handle,
+						 state->subreq,
+						 &state->copied);
 	if (tevent_req_nterror(req, status)) {
 		return;
 	}
@@ -387,12 +392,13 @@ static void btrfs_offload_write_done(struct tevent_req *subreq)
 }
 
 static NTSTATUS btrfs_offload_write_recv(struct vfs_handle_struct *handle,
-				      struct tevent_req *req,
-				      off_t *copied)
+					 struct tevent_req *req,
+					 off_t *copied)
 {
+	struct btrfs_offload_write_state *state =
+		tevent_req_data(req,
+		struct btrfs_offload_write_state);
 	NTSTATUS status;
-	struct btrfs_cc_state *cc_state = tevent_req_data(req,
-							struct btrfs_cc_state);
 
 	if (tevent_req_is_nterror(req, &status)) {
 		DEBUG(4, ("server side copy chunk failed: %s\n",
@@ -402,8 +408,8 @@ static NTSTATUS btrfs_offload_write_recv(struct vfs_handle_struct *handle,
 	}
 
 	DEBUG(10, ("server side copy chunk copied %llu\n",
-		   (unsigned long long)cc_state->copied));
-	*copied = cc_state->copied;
+		   (unsigned long long)state->copied));
+	*copied = state->copied;
 	tevent_req_received(req);
 	return NT_STATUS_OK;
 }
-- 
2.17.1


From bb3b51564dd7d32ed8e5744b92a441abcb101f48 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 12:40:21 +0200
Subject: [PATCH 27/52] vfs_btrfs: don't keep state->subreq in
 btrfs_offload_write_send/recv()

This can be a local variable as used in most of our tevent_req based
code.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/modules/vfs_btrfs.c | 49 +++++++++++++++++++------------------
 1 file changed, 25 insertions(+), 24 deletions(-)

diff --git a/source3/modules/vfs_btrfs.c b/source3/modules/vfs_btrfs.c
index cc082f7fbbf3..515859d6b90a 100644
--- a/source3/modules/vfs_btrfs.c
+++ b/source3/modules/vfs_btrfs.c
@@ -199,7 +199,6 @@ static NTSTATUS btrfs_offload_read_recv(struct tevent_req *req,
 struct btrfs_offload_write_state {
 	struct vfs_handle_struct *handle;
 	off_t copied;
-	struct tevent_req *subreq;	/* non-null if passed to next VFS fn */
 };
 static void btrfs_offload_write_done(struct tevent_req *subreq);
 
@@ -215,6 +214,7 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 {
 	struct tevent_req *req = NULL;
 	struct btrfs_offload_write_state *state = NULL;
+	struct tevent_req *subreq = NULL;
 	struct btrfs_ioctl_clone_range_args cr_args;
 	struct lock_struct src_lck;
 	struct lock_struct dest_lck;
@@ -264,19 +264,19 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 	}
 
 	if (!handle_offload_write) {
-		state->subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle,
-								state,
-								ev,
-								fsctl,
-								token,
-								transfer_offset,
-								dest_fsp,
-								dest_off,
-								num);
-		if (tevent_req_nomem(state->subreq, req)) {
+		subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle,
+							 state,
+							 ev,
+							 fsctl,
+							 token,
+							 transfer_offset,
+							 dest_fsp,
+							 dest_off,
+							 num);
+		if (tevent_req_nomem(subreq, req)) {
 			return tevent_req_post(req, ev);
 		}
-		tevent_req_set_callback(state->subreq,
+		tevent_req_set_callback(subreq,
 					btrfs_offload_write_done,
 					req);
 		return req;
@@ -345,20 +345,20 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 			  (unsigned long long)cr_args.src_offset,
 			  dest_fsp->fh->fd,
 			  (unsigned long long)cr_args.dest_offset));
-		state->subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle,
-								state,
-								ev,
-								fsctl,
-								token,
-								transfer_offset,
-								dest_fsp,
-								dest_off,
-								num);
-		if (tevent_req_nomem(state->subreq, req)) {
+		subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle,
+							 state,
+							 ev,
+							 fsctl,
+							 token,
+							 transfer_offset,
+							 dest_fsp,
+							 dest_off,
+							 num);
+		if (tevent_req_nomem(subreq, req)) {
 			return tevent_req_post(req, ev);
 		}
 		/* wait for subreq completion */
-		tevent_req_set_callback(state->subreq,
+		tevent_req_set_callback(subreq,
 					btrfs_offload_write_done,
 					req);
 		return req;
@@ -383,8 +383,9 @@ static void btrfs_offload_write_done(struct tevent_req *subreq)
 	NTSTATUS status;
 
 	status = SMB_VFS_NEXT_OFFLOAD_WRITE_RECV(state->handle,
-						 state->subreq,
+						 subreq,
 						 &state->copied);
+	TALLOC_FREE(subreq);
 	if (tevent_req_nterror(req, status)) {
 		return;
 	}
-- 
2.17.1


From d93db2d115bf477e1cfa85b0ece0d8f9b4b92c33 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 11:54:58 +0200
Subject: [PATCH 28/52] smbd: add {become,change_to}_user_by_fsp() helper
 functions

This can be used if a request operates on two fsp's,
e.g. the offload_write_send/recv code.
This is important if (at least) one of
the shares uses "force user".

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/proto.h |  2 ++
 source3/smbd/uid.c   | 10 ++++++++++
 2 files changed, 12 insertions(+)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 0c4c68187c22..f9f29230162c 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1196,6 +1196,7 @@ NTSTATUS check_user_share_access(connection_struct *conn,
 				uint32_t *p_share_access,
 				bool *p_readonly_share);
 bool change_to_user(connection_struct *conn, uint64_t vuid);
+bool change_to_user_by_fsp(struct files_struct *fsp);
 bool smbd_change_to_root_user(void);
 bool smbd_become_authenticated_pipe_user(struct auth_session_info *session_info);
 bool smbd_unbecome_authenticated_pipe_user(void);
@@ -1204,6 +1205,7 @@ void unbecome_root(void);
 void smbd_become_root(void);
 void smbd_unbecome_root(void);
 bool become_user(connection_struct *conn, uint64_t vuid);
+bool become_user_by_fsp(struct files_struct *fsp);
 bool become_user_by_session(connection_struct *conn,
 			    const struct auth_session_info *session_info);
 bool unbecome_user(void);
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 289727d95746..35d198b1899a 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -418,6 +418,11 @@ bool change_to_user(connection_struct *conn, uint64_t vuid)
 	return change_to_user_internal(conn, vuser->session_info, vuid);
 }
 
+bool change_to_user_by_fsp(struct files_struct *fsp)
+{
+	return change_to_user(fsp->conn, fsp->vuid);
+}
+
 static bool change_to_user_by_session(connection_struct *conn,
 				      const struct auth_session_info *session_info)
 {
@@ -604,6 +609,11 @@ bool become_user(connection_struct *conn, uint64_t vuid)
 	return True;
 }
 
+bool become_user_by_fsp(struct files_struct *fsp)
+{
+	return become_user(fsp->conn, fsp->vuid);
+}
+
 bool become_user_by_session(connection_struct *conn,
 			    const struct auth_session_info *session_info)
 {
-- 
2.17.1


From a83aaa68860ff0c9a8b3d6dc92ff3be65e01ba05 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 12:03:02 +0200
Subject: [PATCH 29/52] vfs_btrfs: make use of become_user_by_fsp() in order to
 switch between src and dst fsp

We can use become_user_by_fsp()/unbecome_user() as it spans only parts of
the btrfs_offload_write_send() function and never goes async in between.

This may matter if at least one share uses "force user".

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/modules/vfs_btrfs.c | 46 +++++++++++++++++++++++++++++++++----
 1 file changed, 41 insertions(+), 5 deletions(-)

diff --git a/source3/modules/vfs_btrfs.c b/source3/modules/vfs_btrfs.c
index 515859d6b90a..a11cb66d8e78 100644
--- a/source3/modules/vfs_btrfs.c
+++ b/source3/modules/vfs_btrfs.c
@@ -199,7 +199,26 @@ static NTSTATUS btrfs_offload_read_recv(struct tevent_req *req,
 struct btrfs_offload_write_state {
 	struct vfs_handle_struct *handle;
 	off_t copied;
+	bool need_unbecome_user;
 };
+
+static void btrfs_offload_write_cleanup(struct tevent_req *req,
+					enum tevent_req_state req_state)
+{
+	struct btrfs_offload_write_state *state =
+		tevent_req_data(req,
+		struct btrfs_offload_write_state);
+	bool ok;
+
+	if (!state->need_unbecome_user) {
+		return;
+	}
+
+	ok = unbecome_user();
+	SMB_ASSERT(ok);
+	state->need_unbecome_user = false;
+}
+
 static void btrfs_offload_write_done(struct tevent_req *subreq);
 
 static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *handle,
@@ -224,6 +243,7 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 	bool handle_offload_write = true;
 	bool do_locking = false;
 	NTSTATUS status;
+	bool ok;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct btrfs_offload_write_state);
@@ -233,6 +253,8 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 
 	state->handle = handle;
 
+	tevent_req_set_cleanup_fn(req, btrfs_offload_write_cleanup);
+
 	status = vfs_offload_token_db_fetch_fsp(btrfs_offload_ctx,
 						token, &src_fsp);
 	if (tevent_req_nterror(req, status)) {
@@ -289,6 +311,13 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 		return tevent_req_post(req, ev);
 	}
 
+	ok = become_user_by_fsp(src_fsp);
+	if (!ok) {
+		tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+		return tevent_req_post(req, ev);
+	}
+	state->need_unbecome_user = true;
+
 	status = vfs_stat_fsp(src_fsp);
 	if (tevent_req_nterror(req, status)) {
 		return tevent_req_post(req, ev);
@@ -307,17 +336,24 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
 					num,
 					READ_LOCK,
 					&src_lck);
+		if (!SMB_VFS_STRICT_LOCK_CHECK(src_fsp->conn, src_fsp, &src_lck)) {
+			tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+			return tevent_req_post(req, ev);
+		}
+	}
+
+	ok = unbecome_user();
+	SMB_ASSERT(ok);
+	state->need_unbecome_user = false;
+
+	if (do_locking) {
 		init_strict_lock_struct(dest_fsp,
-				       dest_fsp->op->global->open_persistent_id,
+					dest_fsp->op->global->open_persistent_id,
 					dest_off,
 					num,
 					WRITE_LOCK,
 					&dest_lck);
 
-		if (!SMB_VFS_STRICT_LOCK_CHECK(src_fsp->conn, src_fsp, &src_lck)) {
-			tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
-			return tevent_req_post(req, ev);
-		}
 		if (!SMB_VFS_STRICT_LOCK_CHECK(dest_fsp->conn, dest_fsp, &dest_lck)) {
 			tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
 			return tevent_req_post(req, ev);
-- 
2.17.1


From 8c92c42b95a4f1294e43e8e4d9cfb85b43dfa948 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 12:03:02 +0200
Subject: [PATCH 30/52] vfs_default: make use of change_to_user_by_fsp() in
 order to switch between src and dst fsp

This may matter if at least one share uses "force user".

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/modules/vfs_default.c | 42 +++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 58df47ee6b4c..baeb285eeb34 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1598,6 +1598,22 @@ struct vfswrap_offload_write_state {
 	size_t next_io_size;
 };
 
+static void vfswrap_offload_write_cleanup(struct tevent_req *req,
+					  enum tevent_req_state req_state)
+{
+	struct vfswrap_offload_write_state *state = tevent_req_data(
+		req, struct vfswrap_offload_write_state);
+	bool ok;
+
+	if (state->dst_fsp == NULL) {
+		return;
+	}
+
+	ok = change_to_user_by_fsp(state->dst_fsp);
+	SMB_ASSERT(ok);
+	state->dst_fsp = NULL;
+}
+
 static NTSTATUS vfswrap_offload_write_loop(struct tevent_req *req);
 
 static struct tevent_req *vfswrap_offload_write_send(
@@ -1616,6 +1632,7 @@ static struct tevent_req *vfswrap_offload_write_send(
 	size_t num = MIN(to_copy, COPYCHUNK_MAX_TOTAL_LEN);
 	files_struct *src_fsp = NULL;
 	NTSTATUS status;
+	bool ok;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct vfswrap_offload_write_state);
@@ -1633,6 +1650,8 @@ static struct tevent_req *vfswrap_offload_write_send(
 		.remaining = to_copy,
 	};
 
+	tevent_req_set_cleanup_fn(req, vfswrap_offload_write_cleanup);
+
 	switch (fsctl) {
 	case FSCTL_SRV_COPYCHUNK:
 	case FSCTL_SRV_COPYCHUNK_WRITE:
@@ -1676,6 +1695,12 @@ static struct tevent_req *vfswrap_offload_write_send(
 		return tevent_req_post(req, ev);
 	}
 
+	ok = change_to_user_by_fsp(src_fsp);
+	if (!ok) {
+		tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+		return tevent_req_post(req, ev);
+	}
+
 	state->buf = talloc_array(state, uint8_t, num);
 	if (tevent_req_nomem(state->buf, req)) {
 		return tevent_req_post(req, ev);
@@ -1719,6 +1744,10 @@ static NTSTATUS vfswrap_offload_write_loop(struct tevent_req *req)
 	struct lock_struct read_lck;
 	bool ok;
 
+	/*
+	 * This is called under the context of state->src_fsp.
+	 */
+
 	state->next_io_size = MIN(state->remaining, talloc_array_length(state->buf));
 
 	init_strict_lock_struct(state->src_fsp,
@@ -1778,6 +1807,12 @@ static void vfswrap_offload_write_read_done(struct tevent_req *subreq)
 
 	state->src_off += nread;
 
+	ok = change_to_user_by_fsp(state->dst_fsp);
+	if (!ok) {
+		tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+		return;
+	}
+
 	init_strict_lock_struct(state->dst_fsp,
 				state->dst_fsp->op->global->open_persistent_id,
 				state->dst_off,
@@ -1815,6 +1850,7 @@ static void vfswrap_offload_write_write_done(struct tevent_req *subreq)
 	struct vfs_aio_state aio_state;
 	ssize_t nwritten;
 	NTSTATUS status;
+	bool ok;
 
 	nwritten = SMB_VFS_PWRITE_RECV(subreq, &aio_state);
 	TALLOC_FREE(subreq);
@@ -1842,6 +1878,12 @@ static void vfswrap_offload_write_write_done(struct tevent_req *subreq)
 		return;
 	}
 
+	ok = change_to_user_by_fsp(state->src_fsp);
+	if (!ok) {
+		tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+		return;
+	}
+
 	status = vfswrap_offload_write_loop(req);
 	if (!NT_STATUS_IS_OK(status)) {
 		tevent_req_nterror(req, status);
-- 
2.17.1


From 78f3da6b3217cde18d7d96763d387c7856793917 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 31/52] vfs_default: maintain
 vfswrap_offload_write_state->{src_ev,dst_ev}

These get filled with impersonation wrappers in the following commits.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/modules/vfs_default.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index baeb285eeb34..ede11ad34ed9 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1584,13 +1584,14 @@ static NTSTATUS vfswrap_offload_read_recv(struct tevent_req *req,
 }
 
 struct vfswrap_offload_write_state {
-	struct tevent_context *ev;
 	uint8_t *buf;
 	bool read_lck_locked;
 	bool write_lck_locked;
 	DATA_BLOB *token;
+	struct tevent_context *src_ev;
 	struct files_struct *src_fsp;
 	off_t src_off;
+	struct tevent_context *dst_ev;
 	struct files_struct *dst_fsp;
 	off_t dst_off;
 	off_t to_copy;
@@ -1641,9 +1642,9 @@ static struct tevent_req *vfswrap_offload_write_send(
 	}
 
 	*state = (struct vfswrap_offload_write_state) {
-		.ev = ev,
 		.token = token,
 		.src_off = transfer_offset,
+		.dst_ev = ev,
 		.dst_fsp = dest_fsp,
 		.dst_off = dest_off,
 		.to_copy = to_copy,
@@ -1685,7 +1686,6 @@ static struct tevent_req *vfswrap_offload_write_send(
 	if (tevent_req_nterror(req, status)) {
 		return tevent_req_post(req, ev);
 	}
-	state->src_fsp = src_fsp;
 
 	DBG_DEBUG("server side copy chunk of length %" PRIu64 "\n", to_copy);
 
@@ -1701,6 +1701,9 @@ static struct tevent_req *vfswrap_offload_write_send(
 		return tevent_req_post(req, ev);
 	}
 
+	state->src_ev = state->src_fsp->conn->sconn->ev_ctx;
+	state->src_fsp = src_fsp;
+
 	state->buf = talloc_array(state, uint8_t, num);
 	if (tevent_req_nomem(state->buf, req)) {
 		return tevent_req_post(req, ev);
@@ -1765,7 +1768,7 @@ static NTSTATUS vfswrap_offload_write_loop(struct tevent_req *req)
 	}
 
 	subreq = SMB_VFS_PREAD_SEND(state,
-				    state->src_fsp->conn->sconn->ev_ctx,
+				    state->src_ev,
 				    state->src_fsp,
 				    state->buf,
 				    state->next_io_size,
@@ -1829,7 +1832,7 @@ static void vfswrap_offload_write_read_done(struct tevent_req *subreq)
 	}
 
 	subreq = SMB_VFS_PWRITE_SEND(state,
-				     state->ev,
+				     state->dst_ev,
 				     state->dst_fsp,
 				     state->buf,
 				     state->next_io_size,
-- 
2.17.1


From b805fd46f2f6f5f452edf5e808e72afa2ac3c817 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 32/52] smbd: rename smbXsrv_client->ev_ctx into
 smbXsrv_client->raw_ev_ctx

That makes it clearer that no tevent_context wrapper is used here
and the related code should really run without any (active) impersonation
as before.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/librpc/idl/smbXsrv.idl |  2 +-
 source3/smbd/process.c         |  4 ++--
 source3/smbd/smbXsrv_client.c  | 18 +++++++++++-------
 source3/smbd/smbXsrv_session.c | 10 +++++++---
 4 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index 26758113af47..935c40842523 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -107,7 +107,7 @@ interface smbXsrv
 
 	typedef [public] struct {
 		[ignore] smbXsrv_client_table		*table;
-		[ignore] struct tevent_context		*ev_ctx;
+		[ignore] struct tevent_context		*raw_ev_ctx;
 		[ignore] struct messaging_context	*msg_ctx;
 
 		[ref] smbXsrv_client_global0		*global;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 54f7753e736c..581fd605e72e 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3697,7 +3697,7 @@ NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
 	}
 	talloc_steal(frame, xconn);
 
-	xconn->ev_ctx = client->ev_ctx;
+	xconn->ev_ctx = client->raw_ev_ctx;
 	xconn->msg_ctx = client->msg_ctx;
 	xconn->transport.sock = sock_fd;
 	smbd_echo_init(xconn);
@@ -3848,7 +3848,7 @@ NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
 	xconn->smb1.sessions.done_sesssetup = false;
 	xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
 
-	xconn->transport.fde = tevent_add_fd(client->ev_ctx,
+	xconn->transport.fde = tevent_add_fd(client->raw_ev_ctx,
 					     xconn,
 					     sock_fd,
 					     TEVENT_FD_READ,
diff --git a/source3/smbd/smbXsrv_client.c b/source3/smbd/smbXsrv_client.c
index 30cf25276bed..3e0a1d51e5ae 100644
--- a/source3/smbd/smbXsrv_client.c
+++ b/source3/smbd/smbXsrv_client.c
@@ -507,7 +507,7 @@ NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
 		TALLOC_FREE(table);
 		return NT_STATUS_NO_MEMORY;
 	}
-	client->ev_ctx = ev_ctx;
+	client->raw_ev_ctx = ev_ctx;
 	client->msg_ctx = msg_ctx;
 
 	client->server_multi_channel_enabled = lp_server_multi_channel_support();
@@ -543,9 +543,11 @@ NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
 		NDR_PRINT_DEBUG(smbXsrv_clientB, &client_blob);
 	}
 
-	subreq = messaging_filtered_read_send(client, client->ev_ctx, client->msg_ctx,
-					      smbXsrv_client_connection_pass_filter,
-					      client);
+	subreq = messaging_filtered_read_send(client,
+					client->raw_ev_ctx,
+					client->msg_ctx,
+					smbXsrv_client_connection_pass_filter,
+					client);
 	if (subreq == NULL) {
 		TALLOC_FREE(client);
 		return NT_STATUS_NO_MEMORY;
@@ -678,9 +680,11 @@ static void smbXsrv_client_connection_pass_loop(struct tevent_req *subreq)
 next:
 	TALLOC_FREE(rec);
 
-	subreq = messaging_filtered_read_send(client, client->ev_ctx, client->msg_ctx,
-					      smbXsrv_client_connection_pass_filter,
-					      client);
+	subreq = messaging_filtered_read_send(client,
+					client->raw_ev_ctx,
+					client->msg_ctx,
+					smbXsrv_client_connection_pass_filter,
+					client);
 	if (subreq == NULL) {
 		const char *r;
 		r = "messaging_read_send(MSG_SMBXSRV_CONNECTION_PASS failed";
diff --git a/source3/smbd/smbXsrv_session.c b/source3/smbd/smbXsrv_session.c
index 121ff264a9cc..2c5b2ffe2fcd 100644
--- a/source3/smbd/smbXsrv_session.c
+++ b/source3/smbd/smbXsrv_session.c
@@ -258,7 +258,9 @@ static NTSTATUS smbXsrv_session_table_init(struct smbXsrv_connection *conn,
 
 	table->global.db_ctx = smbXsrv_session_global_db_ctx;
 
-	subreq = messaging_read_send(table, client->ev_ctx, client->msg_ctx,
+	subreq = messaging_read_send(table,
+				     client->raw_ev_ctx,
+				     client->msg_ctx,
 				     MSG_SMBXSRV_SESSION_CLOSE);
 	if (subreq == NULL) {
 		TALLOC_FREE(table);
@@ -376,7 +378,7 @@ static void smbXsrv_session_close_loop(struct tevent_req *subreq)
 		goto next;
 	}
 
-	subreq = smb2srv_session_shutdown_send(session, client->ev_ctx,
+	subreq = smb2srv_session_shutdown_send(session, client->raw_ev_ctx,
 					       session, NULL);
 	if (subreq == NULL) {
 		status = NT_STATUS_NO_MEMORY;
@@ -396,7 +398,9 @@ static void smbXsrv_session_close_loop(struct tevent_req *subreq)
 next:
 	TALLOC_FREE(rec);
 
-	subreq = messaging_read_send(table, client->ev_ctx, client->msg_ctx,
+	subreq = messaging_read_send(table,
+				     client->raw_ev_ctx,
+				     client->msg_ctx,
 				     MSG_SMBXSRV_SESSION_CLOSE);
 	if (subreq == NULL) {
 		const char *r;
-- 
2.17.1


From 3a4a2d3ba1d0ec186ebec35cd4bfebd87ec69531 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 33/52] smbd: replace xconn->ev_ctx with
 xconn->client->raw_ev_ctx

This is the same pointer and we don't have a lot of callers,
so we can just use one pointer.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/globals.h     |  2 --
 source3/smbd/oplock.c      |  3 ++-
 source3/smbd/process.c     | 18 +++++++++++-------
 source3/smbd/smb2_server.c |  3 ++-
 4 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 057645bedeeb..4f4519465b04 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -364,12 +364,10 @@ struct smbXsrv_connection {
 
 	struct smbXsrv_client *client;
 
-
 	const struct tsocket_address *local_address;
 	const struct tsocket_address *remote_address;
 	const char *remote_hostname;
 
-	struct tevent_context *ev_ctx;
 	struct messaging_context *msg_ctx;
 
 	enum protocol_types protocol;
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 0f95bb013984..6d37f35babe7 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -576,7 +576,8 @@ NTSTATUS downgrade_lease(struct smbXsrv_connection *xconn,
 			lck->data->modified = true;
 		}
 
-		tevent_schedule_immediate(state->im, xconn->ev_ctx,
+		tevent_schedule_immediate(state->im,
+					  xconn->client->raw_ev_ctx,
 					  downgrade_lease_additional_trigger,
 					  state);
 	}
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 581fd605e72e..48425a979ba2 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -2738,8 +2738,10 @@ static int release_ip(struct tevent_context *ev,
 		 * as we might be called from within ctdbd_migrate(),
 		 * we need to defer our action to the next event loop
 		 */
-		tevent_schedule_immediate(state->im, xconn->ev_ctx,
-					  smbd_release_ip_immediate, state);
+		tevent_schedule_immediate(state->im,
+					  xconn->client->raw_ev_ctx,
+					  smbd_release_ip_immediate,
+					  state);
 
 		/*
 		 * Make sure we don't get any io on the connection.
@@ -3388,14 +3390,16 @@ bool fork_echo_handler(struct smbXsrv_connection *xconn)
 		close(listener_pipe[0]);
 		set_blocking(listener_pipe[1], false);
 
-		status = smbd_reinit_after_fork(xconn->msg_ctx, xconn->ev_ctx,
-						true, "smbd-echo");
+		status = smbd_reinit_after_fork(xconn->msg_ctx,
+						xconn->client->raw_ev_ctx,
+						true,
+						"smbd-echo");
 		if (!NT_STATUS_IS_OK(status)) {
 			DEBUG(1, ("reinit_after_fork failed: %s\n",
 				  nt_errstr(status)));
 			exit(1);
 		}
-		initialize_password_db(true, xconn->ev_ctx);
+		initialize_password_db(true, xconn->client->raw_ev_ctx);
 		smbd_echo_loop(xconn, listener_pipe[1]);
 		exit(0);
 	}
@@ -3409,7 +3413,8 @@ bool fork_echo_handler(struct smbXsrv_connection *xconn)
 	 * Without smb signing this is the same as the normal smbd
 	 * listener. This needs to change once signing comes in.
 	 */
-	xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
+	xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(
+					xconn->client->raw_ev_ctx,
 					xconn,
 					xconn->smb1.echo_handler.trusted_fd,
 					TEVENT_FD_READ,
@@ -3697,7 +3702,6 @@ NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
 	}
 	talloc_steal(frame, xconn);
 
-	xconn->ev_ctx = client->raw_ev_ctx;
 	xconn->msg_ctx = client->msg_ctx;
 	xconn->transport.sock = sock_fd;
 	smbd_echo_init(xconn);
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index ed718b83958d..b65172253b45 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -227,7 +227,8 @@ static NTSTATUS smbd_initialize_smb2(struct smbXsrv_connection *xconn,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	xconn->transport.fde = tevent_add_fd(xconn->ev_ctx,
+	xconn->transport.fde = tevent_add_fd(
+					xconn->client->raw_ev_ctx,
 					xconn,
 					xconn->transport.sock,
 					TEVENT_FD_READ,
-- 
2.17.1


From 9dfdce97b888791c0b9d118bee18825d991a6ab1 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 34/52] smbd: replace xconn->msg_ctx with
 xconn->client->msg_ctx

This is the same pointer and we don't have a lot of callers,
so we can just use one pointer.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/globals.h         | 2 --
 source3/smbd/process.c         | 3 +--
 source3/smbd/smbXsrv_client.c  | 2 +-
 source3/smbd/smbXsrv_open.c    | 4 ++--
 source3/smbd/smbXsrv_session.c | 4 ++--
 source3/smbd/smbXsrv_tcon.c    | 2 +-
 6 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 4f4519465b04..492430f9bbec 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -368,8 +368,6 @@ struct smbXsrv_connection {
 	const struct tsocket_address *remote_address;
 	const char *remote_hostname;
 
-	struct messaging_context *msg_ctx;
-
 	enum protocol_types protocol;
 
 	struct {
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 48425a979ba2..53365b5f0345 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3390,7 +3390,7 @@ bool fork_echo_handler(struct smbXsrv_connection *xconn)
 		close(listener_pipe[0]);
 		set_blocking(listener_pipe[1], false);
 
-		status = smbd_reinit_after_fork(xconn->msg_ctx,
+		status = smbd_reinit_after_fork(xconn->client->msg_ctx,
 						xconn->client->raw_ev_ctx,
 						true,
 						"smbd-echo");
@@ -3702,7 +3702,6 @@ NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
 	}
 	talloc_steal(frame, xconn);
 
-	xconn->msg_ctx = client->msg_ctx;
 	xconn->transport.sock = sock_fd;
 	smbd_echo_init(xconn);
 	xconn->protocol = PROTOCOL_NONE;
diff --git a/source3/smbd/smbXsrv_client.c b/source3/smbd/smbXsrv_client.c
index 3e0a1d51e5ae..4cae8c5287e2 100644
--- a/source3/smbd/smbXsrv_client.c
+++ b/source3/smbd/smbXsrv_client.c
@@ -345,7 +345,7 @@ NTSTATUS smb2srv_client_connection_pass(struct smbd_smb2_request *smb2req,
 	iov.iov_base = blob.data;
 	iov.iov_len = blob.length;
 
-	status = messaging_send_iov(smb2req->xconn->msg_ctx,
+	status = messaging_send_iov(smb2req->xconn->client->msg_ctx,
 				    global->server_id,
 				    MSG_SMBXSRV_CONNECTION_PASS,
 				    &iov, 1,
diff --git a/source3/smbd/smbXsrv_open.c b/source3/smbd/smbXsrv_open.c
index 4ad0021cdf4f..2a2cf6973e7d 100644
--- a/source3/smbd/smbXsrv_open.c
+++ b/source3/smbd/smbXsrv_open.c
@@ -871,7 +871,7 @@ NTSTATUS smbXsrv_open_create(struct smbXsrv_connection *conn,
 	global->open_persistent_id = global->open_global_id;
 	global->open_volatile_id = op->local_id;
 
-	global->server_id = messaging_server_id(conn->msg_ctx);
+	global->server_id = messaging_server_id(conn->client->msg_ctx);
 	global->open_time = now;
 	global->open_owner = *current_sid;
 	if (conn->protocol >= PROTOCOL_SMB2_10) {
@@ -1416,7 +1416,7 @@ NTSTATUS smb2srv_open_recreate(struct smbXsrv_connection *conn,
 	op->status = NT_STATUS_FILE_CLOSED;
 
 	op->global->open_volatile_id = op->local_id;
-	op->global->server_id = messaging_server_id(conn->msg_ctx);
+	op->global->server_id = messaging_server_id(conn->client->msg_ctx);
 
 	ptr = op;
 	val = make_tdb_data((uint8_t const *)&ptr, sizeof(ptr));
diff --git a/source3/smbd/smbXsrv_session.c b/source3/smbd/smbXsrv_session.c
index 2c5b2ffe2fcd..3d8f0be06efa 100644
--- a/source3/smbd/smbXsrv_session.c
+++ b/source3/smbd/smbXsrv_session.c
@@ -1110,7 +1110,7 @@ static void smb2srv_session_close_previous_check(struct tevent_req *req)
 		return;
 	}
 
-	status = messaging_send(conn->msg_ctx,
+	status = messaging_send(conn->client->msg_ctx,
 				global->channels[0].server_id,
 				MSG_SMBXSRV_SESSION_CLOSE, &blob);
 	TALLOC_FREE(state->db_rec);
@@ -1362,7 +1362,7 @@ NTSTATUS smbXsrv_session_add_channel(struct smbXsrv_session *session,
 	c = &global->channels[global->num_channels];
 	ZERO_STRUCTP(c);
 
-	c->server_id = messaging_server_id(conn->msg_ctx);
+	c->server_id = messaging_server_id(conn->client->msg_ctx);
 	c->local_address = tsocket_address_string(conn->local_address,
 						  global->channels);
 	if (c->local_address == NULL) {
diff --git a/source3/smbd/smbXsrv_tcon.c b/source3/smbd/smbXsrv_tcon.c
index 5ad557e1f5e6..627eeb166d9a 100644
--- a/source3/smbd/smbXsrv_tcon.c
+++ b/source3/smbd/smbXsrv_tcon.c
@@ -1095,7 +1095,7 @@ NTSTATUS smb1srv_tcon_create(struct smbXsrv_connection *conn,
 			     NTTIME now,
 			     struct smbXsrv_tcon **_tcon)
 {
-	struct server_id id = messaging_server_id(conn->msg_ctx);
+	struct server_id id = messaging_server_id(conn->client->msg_ctx);
 
 	return smbXsrv_tcon_create(conn->client->tcon_table,
 				   conn->protocol,
-- 
2.17.1


From 25ccc0a5d309a0bff0e6aab012fc34613acb89ff Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 07:18:10 +0200
Subject: [PATCH 35/52] smbd: remove unused tevent_context argument from
 notify_init

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/notify.c     | 2 +-
 source3/smbd/notify_msg.c | 1 -
 source3/smbd/proto.h      | 1 -
 source3/smbd/service.c    | 2 +-
 source3/utils/status.c    | 1 -
 5 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index add59089187e..44c0b09432e7 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -539,7 +539,7 @@ void smbd_notifyd_restarted(struct messaging_context *msg,
 
 	TALLOC_FREE(sconn->notify_ctx);
 
-	sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx, sconn->ev_ctx,
+	sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx,
 					sconn, notify_callback);
 	if (sconn->notify_ctx == NULL) {
 		DBG_DEBUG("notify_init failed\n");
diff --git a/source3/smbd/notify_msg.c b/source3/smbd/notify_msg.c
index 3787df74bfd0..ff38b964914f 100644
--- a/source3/smbd/notify_msg.c
+++ b/source3/smbd/notify_msg.c
@@ -48,7 +48,6 @@ static int notify_context_destructor(struct notify_context *ctx);
 
 struct notify_context *notify_init(
 	TALLOC_CTX *mem_ctx, struct messaging_context *msg,
-	struct tevent_context *ev,
 	struct smbd_server_connection *sconn,
 	void (*callback)(struct smbd_server_connection *sconn,
 			 void *, struct timespec,
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index f9f29230162c..ab4a8d68d3f1 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -586,7 +586,6 @@ int fam_watch(TALLOC_CTX *mem_ctx,
 
 struct notify_context *notify_init(
 	TALLOC_CTX *mem_ctx, struct messaging_context *msg,
-	struct tevent_context *ev,
 	struct smbd_server_connection *sconn,
 	void (*callback)(struct smbd_server_connection *sconn,
 			 void *, struct timespec,
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index a22a0270cd79..a928de6c78f0 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -458,7 +458,7 @@ static NTSTATUS notify_init_sconn(struct smbd_server_connection *sconn)
 		return NT_STATUS_OK;
 	}
 
-	sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx, sconn->ev_ctx,
+	sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx,
 					sconn, notify_callback);
 	if (sconn->notify_ctx == NULL) {
 		return NT_STATUS_NO_MEMORY;
diff --git a/source3/utils/status.c b/source3/utils/status.c
index 6370f7002e8b..d04efedee3f6 100644
--- a/source3/utils/status.c
+++ b/source3/utils/status.c
@@ -735,7 +735,6 @@ int main(int argc, const char *argv[])
 		struct notify_context *n;
 
 		n = notify_init(talloc_tos(), msg_ctx,
-				messaging_tevent_context(msg_ctx),
 				NULL, NULL);
 		if (n == NULL) {
 			goto done;
-- 
2.17.1


From 8be68c9f3c83ae91dcaa3d781ecc3ca683bbfd17 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 36/52] s3:smb2_server: use req->xconn->client->raw_ev_ctx for
 smbd_smb2_request_pending_timer()

There's no need to use req->ev_ctx here just to do some network io.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/smb2_server.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index b65172253b45..ccbea87bfd0d 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -1482,8 +1482,14 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
 		data_blob_clear_free(&req->last_key);
 	}
 
+	/*
+	 * smbd_smb2_request_pending_timer() just send a packet
+	 * to the client and doesn't need any impersonation.
+	 * So we use req->xconn->client->raw_ev_ctx instead
+	 * of req->ev_ctx here.
+	 */
 	defer_endtime = timeval_current_ofs_usec(defer_time);
-	req->async_te = tevent_add_timer(req->sconn->ev_ctx,
+	req->async_te = tevent_add_timer(req->xconn->client->raw_ev_ctx,
 					 req, defer_endtime,
 					 smbd_smb2_request_pending_timer,
 					 req);
-- 
2.17.1


From 9ed5e1e2ea02f2beac60cb22f5883ea762827a0d Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 37/52] s3:smb2_server: use req->xconn->client->raw_ev_ctx for
 smbd_smb2_request_dispatch_immediate()

smbd_smb2_request_dispatch() will redo the impersonation anyway,
so we don't use req->ev_ctx.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/smb2_server.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index ccbea87bfd0d..46b747cabffa 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -2922,8 +2922,13 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
 			}
 		}
 
+		/*
+		 * smbd_smb2_request_dispatch() will redo the impersonation.
+		 * So we use req->xconn->client->raw_ev_ctx instead
+		 * of req->ev_ctx here.
+		 */
 		tevent_schedule_immediate(im,
-					req->sconn->ev_ctx,
+					req->xconn->client->raw_ev_ctx,
 					smbd_smb2_request_dispatch_immediate,
 					req);
 		return NT_STATUS_OK;
-- 
2.17.1


From 68fd4df97a9defbb86ff3f8f3db92a587344f643 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 38/52] smbd: use req->xconn->client->raw_ev_ctx for
 schedule_deferred_open_message_smb()

process_smb() will redo the impersonation anyway.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/process.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 53365b5f0345..99693ed1315b 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -822,7 +822,14 @@ bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
 				"scheduling mid %llu\n",
 				(unsigned long long)mid ));
 
-			te = tevent_add_timer(pml->sconn->ev_ctx,
+			/*
+			 * smbd_deferred_open_timer() calls
+			 * process_smb() to redispatch the request
+			 * including the required impersonation.
+			 *
+			 * So we can just use the raw tevent_context.
+			 */
+			te = tevent_add_timer(xconn->client->raw_ev_ctx,
 					      pml,
 					      timeval_zero(),
 					      smbd_deferred_open_timer,
-- 
2.17.1


From f2366301386307ed7b89a054450c8e2e59af1531 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 39/52] smbd: add smbd_server_connection->raw_ev_ctx pointer

This will replace smbd_server_connection->ev_ctx in the next commits.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/globals.h | 1 +
 source3/smbd/msdfs.c   | 5 +++--
 source3/smbd/process.c | 1 +
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 492430f9bbec..eebb314dbe55 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -873,6 +873,7 @@ struct smbd_server_connection {
 	const struct tsocket_address *remote_address;
 	const char *remote_hostname;
 	struct tevent_context *ev_ctx;
+	struct tevent_context *raw_ev_ctx;
 	struct messaging_context *msg_ctx;
 	struct notify_context *notify_ctx;
 	bool using_smb2;
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 59ef628322a3..53bcedcac964 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -257,12 +257,13 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	sconn->ev_ctx = samba_tevent_context_init(sconn);
-	if (sconn->ev_ctx == NULL) {
+	sconn->raw_ev_ctx = samba_tevent_context_init(sconn);
+	if (sconn->raw_ev_ctx == NULL) {
 		TALLOC_FREE(sconn);
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	sconn->ev_ctx = sconn->raw_ev_ctx;
 	sconn->msg_ctx = msg;
 
 	conn = conn_new(sconn);
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 99693ed1315b..03aa2254c156 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3924,6 +3924,7 @@ void smbd_process(struct tevent_context *ev_ctx,
 	sconn->client = client;
 
 	sconn->ev_ctx = ev_ctx;
+	sconn->raw_ev_ctx = ev_ctx;
 	sconn->msg_ctx = msg_ctx;
 
 	ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
-- 
2.17.1


From 68e195a0da189ace6b2d64a2728f26634e3126b1 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 40/52] vfs_glusterfs: explain that/why we use the raw
 tevent_context in init_gluster_aio()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/modules/vfs_glusterfs.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index c2af793016f2..02289a64e505 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -729,7 +729,16 @@ static bool init_gluster_aio(struct vfs_handle_struct *handle)
 	read_fd = fds[0];
 	write_fd = fds[1];
 
-	aio_read_event = tevent_add_fd(handle->conn->sconn->ev_ctx,
+	/*
+	 * We use the raw tevent context here,
+	 * as this is a global event handler.
+	 *
+	 * The tevent_req_defer_callback()
+	 * calls will make sure the results
+	 * of async calls are propagated
+	 * to the correct tevent_context.
+	 */
+	aio_read_event = tevent_add_fd(handle->conn->sconn->raw_ev_ctx,
 					NULL,
 					read_fd,
 					TEVENT_FD_READ,
-- 
2.17.1


From 66368326651729e7d00f4d7ef2d983ed4cc05373 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 41/52] smbd: explain that/why we use the raw tevent_context
 for update_write_time_handler()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/fileio.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index cde6a057ccda..1fe806e058d2 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -232,9 +232,17 @@ void trigger_write_time_update(struct files_struct *fsp)
 	DEBUG(5, ("Update write time %d usec later on %s\n",
 		  delay, fsp_str_dbg(fsp)));
 
-	/* trigger the update 2 seconds later */
+	/*
+	 * trigger the update 2 seconds later
+	 *
+	 * Note that update_write_time_handler()
+	 * => fsp_flush_write_time_update()
+	 * won't do any SMB_VFS calls and don't
+	 * need impersonation. So we use the
+	 * raw event context for this.
+	 */
 	fsp->update_write_time_event =
-		tevent_add_timer(fsp->conn->sconn->ev_ctx, NULL,
+		tevent_add_timer(fsp->conn->sconn->raw_ev_ctx, NULL,
 				 timeval_current_ofs_usec(delay),
 				 update_write_time_handler, fsp);
 }
-- 
2.17.1


From 5b956e3ab127501e84e4e8345ea387aca214efb3 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 42/52] smbd: explain that/why we use the raw tevent_context
 for lease_timeout_handler()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/oplock.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 6d37f35babe7..b13aae888202 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -338,6 +338,11 @@ static void lease_timeout_handler(struct tevent_context *ctx,
 	struct share_mode_lock *lck;
 	uint16_t old_epoch = lease->lease.lease_epoch;
 
+	/*
+	 * This function runs without any specific impersonation
+	 * and must not call any SMB_VFS operations!
+	 */
+
 	fsp = file_find_one_fsp_from_lease_key(lease->sconn,
 					       &lease->lease.lease_key);
 	if (fsp == NULL) {
@@ -429,7 +434,12 @@ bool fsp_lease_update(struct share_mode_lock *lck,
 
 			DEBUG(10,("%s: setup timeout handler\n", __func__));
 
-			lease->timeout = tevent_add_timer(lease->sconn->ev_ctx,
+			/*
+			 * lease_timeout_handler() only accesses locking.tdb
+			 * so we don't use any impersonation and use
+			 * the raw tevent context.
+			 */
+			lease->timeout = tevent_add_timer(lease->sconn->raw_ev_ctx,
 							  lease, t,
 							  lease_timeout_handler,
 							  lease);
-- 
2.17.1


From 36ada7189d3f7de38012d0a351ece810b58b502b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 43/52] smbd: explain that/why we use the raw tevent_context
 for oplock_timeout_handler()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/oplock.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index b13aae888202..f7654176a880 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -727,6 +727,11 @@ static void oplock_timeout_handler(struct tevent_context *ctx,
 {
 	files_struct *fsp = (files_struct *)private_data;
 
+	/*
+	 * Note this function doesn't run under any specific impersonation and
+	 * is not expected to call any SMB_VFS operation!
+	 */
+
 	SMB_ASSERT(fsp->sent_oplock_break != NO_BREAK_SENT);
 
 	/* Remove the timed event handler. */
@@ -761,8 +766,15 @@ static void add_oplock_timeout_handler(files_struct *fsp)
 			  "around\n"));
 	}
 
+	/*
+	 * For now we keep the logic and use the
+	 * raw event context. We're called from
+	 * the messaging system from a raw event context.
+	 * Also oplock_timeout_handler doesn't invoke
+	 * SMB_VFS calls.
+	 */
 	fsp->oplock_timeout =
-		tevent_add_timer(fsp->conn->sconn->ev_ctx, fsp,
+		tevent_add_timer(fsp->conn->sconn->raw_ev_ctx, fsp,
 				 timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0),
 				 oplock_timeout_handler, fsp);
 
-- 
2.17.1


From 0df03b5a74e17adbec388ecd890377c925bfd959 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 44/52] smbd: explain that/why we use the raw tevent_context
 for do_break_to_none()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/oplock.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index f7654176a880..34bebc61f7a7 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -1150,7 +1150,15 @@ static void contend_level2_oplocks_begin_default(files_struct *fsp,
 		TALLOC_FREE(state);
 		return;
 	}
-	tevent_schedule_immediate(im, sconn->ev_ctx, do_break_to_none, state);
+
+	/*
+	 * do_break_to_none() only operates on the
+	 * locking.tdb and send network packets to
+	 * the client. That doesn't require any
+	 * impersonation, so we just use the
+	 * raw tevent context here.
+	 */
+	tevent_schedule_immediate(im, sconn->raw_ev_ctx, do_break_to_none, state);
 }
 
 static void send_break_to_none(struct messaging_context *msg_ctx,
@@ -1177,6 +1185,11 @@ static void do_break_to_none(struct tevent_context *ctx,
 	struct share_mode_lock *lck;
 	struct share_mode_data *d;
 
+	/*
+	 * Note this function doesn't run under any specific impersonation and
+	 * is not expected to call any SMB_VFS operation!
+	 */
+
 	lck = get_existing_share_mode_lock(talloc_tos(), state->id);
 	if (lck == NULL) {
 		DEBUG(1, ("%s: failed to lock share mode entry for file %s.\n",
-- 
2.17.1


From f3b64f7bdfe10255d6006136d4f5a9575ce0c077 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 45/52] smbd: explain that/why we use the raw tevent_context
 for linux_oplock_signal_handler()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/oplock_linux.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c
index dd772bf6cb5b..7d1f0404512b 100644
--- a/source3/smbd/oplock_linux.c
+++ b/source3/smbd/oplock_linux.c
@@ -125,6 +125,12 @@ static void linux_oplock_signal_handler(struct tevent_context *ev_ctx,
 	int fd = info->si_fd;
 	files_struct *fsp;
 
+	/*
+	 * This function doesn't expect any specific impersonation, as it only
+	 * sends messages to other smbd processes. And messaging_send_iov_from()
+	 * already handles EACCES.
+	 */
+
 	fsp = file_find_fd(sconn, fd);
 	if (fsp == NULL) {
 		DEBUG(0,("linux_oplock_signal_handler: failed to find fsp for file fd=%d (file was closed ?)\n", fd ));
@@ -237,7 +243,13 @@ struct kernel_oplocks *linux_init_kernel_oplocks(struct smbd_server_connection *
 	ctx->ops = &linux_koplocks;
 	ctx->private_data = sconn;
 
-	se = tevent_add_signal(sconn->ev_ctx,
+	/*
+	 * linux_oplock_signal_handler() only
+	 * sends messages to other smbd processes
+	 * and doesn't require any impersonation.
+	 * So we can just use the raw tevent_context.
+	 */
+	se = tevent_add_signal(sconn->raw_ev_ctx,
 			       ctx,
 			       RT_SIGNAL_LEASE, SA_SIGINFO,
 			       linux_oplock_signal_handler,
-- 
2.17.1


From 437769e82184fea774f0b8eefcb231dd022991ea Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 46/52] smbd: use raw_ev_ctx to clear the MSG_SMB_CONF_UPDATED
 registration

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/process.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 03aa2254c156..dbcf13187cf2 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -4063,7 +4063,7 @@ void smbd_process(struct tevent_context *ev_ctx,
 			   ID_CACHE_KILL, smbd_id_cache_kill);
 
 	messaging_deregister(sconn->msg_ctx,
-			     MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
+			     MSG_SMB_CONF_UPDATED, sconn->raw_ev_ctx);
 	messaging_register(sconn->msg_ctx, sconn,
 			   MSG_SMB_CONF_UPDATED, smbd_conf_updated);
 
-- 
2.17.1


From 6d0a0684afa443d60d1418fb9305594889634bd2 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 47/52] smbd: add smbd_server_connection->{root,guest}_ev_ctx
 pointer

For now these are just the same as smbd_server_connection->ev_ctx,
but this will change in future and we'll use impersonation wrappers.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/globals.h | 2 ++
 source3/smbd/msdfs.c   | 2 ++
 source3/smbd/process.c | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index eebb314dbe55..1ac1b47b9d32 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -874,6 +874,8 @@ struct smbd_server_connection {
 	const char *remote_hostname;
 	struct tevent_context *ev_ctx;
 	struct tevent_context *raw_ev_ctx;
+	struct tevent_context *root_ev_ctx;
+	struct tevent_context *guest_ev_ctx;
 	struct messaging_context *msg_ctx;
 	struct notify_context *notify_ctx;
 	bool using_smb2;
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 53bcedcac964..39aef4f11168 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -264,6 +264,8 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 	}
 
 	sconn->ev_ctx = sconn->raw_ev_ctx;
+	sconn->root_ev_ctx = sconn->raw_ev_ctx;
+	sconn->guest_ev_ctx = sconn->raw_ev_ctx;
 	sconn->msg_ctx = msg;
 
 	conn = conn_new(sconn);
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index dbcf13187cf2..2363eb78ea52 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3925,6 +3925,8 @@ void smbd_process(struct tevent_context *ev_ctx,
 
 	sconn->ev_ctx = ev_ctx;
 	sconn->raw_ev_ctx = ev_ctx;
+	sconn->root_ev_ctx = ev_ctx;
+	sconn->guest_ev_ctx = ev_ctx;
 	sconn->msg_ctx = msg_ctx;
 
 	ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
-- 
2.17.1


From 24fb7844ac286c111454add4f8229a10129d0e8f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 48/52] smbd: use sconn->root_ev_ctx for brl_timeout_fn()

This already calls change_to_root_user(), which can be removed
later.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/blocking.c  | 6 +++++-
 source3/smbd/smb2_lock.c | 6 +++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 6cbf5c03e932..c281aae619de 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -135,7 +135,11 @@ static bool recalc_brl_timeout(struct smbd_server_connection *sconn)
 		    (int)from_now.tv_sec, (int)from_now.tv_usec));
 	}
 
-	sconn->smb1.locks.brl_timeout = tevent_add_timer(sconn->ev_ctx,
+	/*
+	 * brl_timeout_fn() calls change_to_root_user()
+	 * so we can use sconn->root_ev_ctx.
+	 */
+	sconn->smb1.locks.brl_timeout = tevent_add_timer(sconn->root_ev_ctx,
 							 NULL, next_timeout,
 							 brl_timeout_fn, sconn);
 	if (sconn->smb1.locks.brl_timeout == NULL) {
diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c
index a05470e52e4a..3cc591089a42 100644
--- a/source3/smbd/smb2_lock.c
+++ b/source3/smbd/smb2_lock.c
@@ -568,8 +568,12 @@ static bool recalc_smb2_brl_timeout(struct smbd_server_connection *sconn)
 			(int)from_now.tv_sec, (int)from_now.tv_usec));
 	}
 
+	/*
+	 * brl_timeout_fn() calls change_to_root_user()
+	 * so we can use sconn->root_ev_ctx.
+	 */
 	sconn->smb2.locks.brl_timeout = tevent_add_timer(
-				sconn->ev_ctx,
+				sconn->root_ev_ctx,
 				NULL,
 				next_timeout,
 				brl_timeout_fn,
-- 
2.17.1


From 70c5028614a0d8af78ad6a4f2c009def75dd5928 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 49/52] smbd: use sconn->root_ev_ctx for
 smbd_sig_{term,hup}_handler()

They already call change_to_root_user(), which can be removed
later.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/process.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 2363eb78ea52..d2553049cd25 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -977,7 +977,7 @@ static void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
 {
 	struct tevent_signal *se;
 
-	se = tevent_add_signal(sconn->ev_ctx,
+	se = tevent_add_signal(sconn->root_ev_ctx,
 			       sconn,
 			       SIGTERM, 0,
 			       smbd_sig_term_handler,
@@ -1007,7 +1007,7 @@ static void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
 {
 	struct tevent_signal *se;
 
-	se = tevent_add_signal(sconn->ev_ctx,
+	se = tevent_add_signal(sconn->root_ev_ctx,
 			       sconn,
 			       SIGHUP, 0,
 			       smbd_sig_hup_handler,
-- 
2.17.1


From 7304c526ade0c58fd08b7c5c93c0408ba74f224c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 50/52] smbd: add an effective connection_struct->user_ev_ctx
 that holds the event context used for the current user

This will be filled with an impersonation wrapper in the next commits.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/include/vfs.h             | 2 ++
 source3/modules/vfs_aio_pthread.c | 2 +-
 source3/modules/vfs_default.c     | 2 +-
 source3/modules/vfs_readonly.c    | 1 +
 source3/smbd/conn.c               | 7 +++++++
 source3/smbd/msdfs.c              | 2 ++
 source3/smbd/uid.c                | 6 ++++++
 7 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 54ab1604b799..249cf0697792 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -398,6 +398,7 @@ typedef struct files_struct {
 
 struct vuid_cache_entry {
 	struct auth_session_info *session_info;
+	struct tevent_context *user_ev_ctx;
 	uint64_t vuid; /* SMB2 compat */
 	bool read_only;
 	uint32_t share_access;
@@ -445,6 +446,7 @@ typedef struct connection_struct {
 	 * on the vuid using this tid, this might change per SMB request.
 	 */
 	struct auth_session_info *session_info;
+	struct tevent_context *user_ev_ctx;
 
 	/*
 	 * If the "force group" parameter is set, this is the primary gid that
diff --git a/source3/modules/vfs_aio_pthread.c b/source3/modules/vfs_aio_pthread.c
index 88794bb7acc7..a9e2b09827bd 100644
--- a/source3/modules/vfs_aio_pthread.c
+++ b/source3/modules/vfs_aio_pthread.c
@@ -276,7 +276,7 @@ static int open_async(const files_struct *fsp,
 	}
 
 	subreq = pthreadpool_tevent_job_send(opd,
-					     fsp->conn->sconn->ev_ctx,
+					     fsp->conn->user_ev_ctx,
 					     fsp->conn->sconn->pool,
 					     aio_open_worker, opd);
 	if (subreq == NULL) {
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index ede11ad34ed9..082b70f5a98e 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1701,7 +1701,7 @@ static struct tevent_req *vfswrap_offload_write_send(
 		return tevent_req_post(req, ev);
 	}
 
-	state->src_ev = state->src_fsp->conn->sconn->ev_ctx;
+	state->src_ev = src_fsp->conn->user_ev_ctx;
 	state->src_fsp = src_fsp;
 
 	state->buf = talloc_array(state, uint8_t, num);
diff --git a/source3/modules/vfs_readonly.c b/source3/modules/vfs_readonly.c
index cde8ef973ca1..570eb7c4d15a 100644
--- a/source3/modules/vfs_readonly.c
+++ b/source3/modules/vfs_readonly.c
@@ -84,6 +84,7 @@ static int readonly_connect(vfs_handle_struct *handle,
       for (i=0; i< VUID_CACHE_SIZE; i++) {
         struct vuid_cache_entry *ent = &conn->vuid_cache->array[i];
         ent->vuid = UID_FIELD_INVALID;
+        ent->user_ev_ctx = NULL;
         TALLOC_FREE(ent->session_info);
         ent->read_only = false;
         ent->share_access = 0;
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index 8f472c0d2458..3b9aaac7834b 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -94,6 +94,12 @@ static void conn_clear_vuid_cache(connection_struct *conn, uint64_t vuid)
 
 		if (ent->vuid == vuid) {
 			ent->vuid = UID_FIELD_INVALID;
+
+			if (conn->user_ev_ctx == ent->user_ev_ctx) {
+				conn->user_ev_ctx = NULL;
+			}
+			ent->user_ev_ctx = NULL;
+
 			/*
 			 * We need to keep conn->session_info around
 			 * if it's equal to ent->session_info as a SMBulogoff
@@ -117,6 +123,7 @@ static void conn_clear_vuid_cache(connection_struct *conn, uint64_t vuid)
 			} else {
 				TALLOC_FREE(ent->session_info);
 			}
+
 			ent->read_only = False;
 			ent->share_access = 0;
 		}
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 39aef4f11168..3fba71bb084e 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -314,6 +314,8 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		vfs_user = get_current_username();
 	}
 
+	conn->user_ev_ctx = sconn->raw_ev_ctx;
+
 	set_conn_connectpath(conn, connpath);
 
 	/*
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 35d198b1899a..e021031a8b75 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -77,6 +77,7 @@ static void free_conn_session_info_if_unused(connection_struct *conn)
 		}
 	}
 	/* Not used, safe to free. */
+	conn->user_ev_ctx = NULL;
 	TALLOC_FREE(conn->session_info);
 }
 
@@ -202,6 +203,7 @@ static bool check_user_ok(connection_struct *conn,
 			}
 			free_conn_session_info_if_unused(conn);
 			conn->session_info = ent->session_info;
+			conn->user_ev_ctx = ent->user_ev_ctx;
 			conn->read_only = ent->read_only;
 			conn->share_access = ent->share_access;
 			conn->vuid = ent->vuid;
@@ -250,6 +252,8 @@ static bool check_user_ok(connection_struct *conn,
 		ent->session_info->unix_token->uid = sec_initial_uid();
 	}
 
+	ent->user_ev_ctx = conn->sconn->raw_ev_ctx;
+
 	/*
 	 * It's actually OK to call check_user_ok() with
 	 * vuid == UID_FIELD_INVALID as called from change_to_user_by_session().
@@ -262,6 +266,7 @@ static bool check_user_ok(connection_struct *conn,
 	free_conn_session_info_if_unused(conn);
 	conn->session_info = ent->session_info;
 	conn->vuid = ent->vuid;
+	conn->user_ev_ctx = ent->user_ev_ctx;
 	if (vuid == UID_FIELD_INVALID) {
 		/*
 		 * Not strictly needed, just make it really
@@ -270,6 +275,7 @@ static bool check_user_ok(connection_struct *conn,
 		ent->read_only = false;
 		ent->share_access = 0;
 		ent->session_info = NULL;
+		ent->user_ev_ctx = NULL;
 	}
 
 	conn->read_only = readonly_share;
-- 
2.17.1


From 12a9586afaa0870f369e66219e9048deca3b485d Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 51/52] smbd: add an effective {smb,smbd_smb2}_request->ev_ctx
 that holds the event context used for the request processing

In future this will an impersonation wrapper tevent_context based on the
user session.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/include/vfs.h                | 2 ++
 source3/smbd/aio.c                   | 8 ++++----
 source3/smbd/globals.h               | 3 +++
 source3/smbd/ipc.c                   | 4 ++--
 source3/smbd/open.c                  | 8 ++++----
 source3/smbd/pipes.c                 | 8 ++++----
 source3/smbd/process.c               | 8 ++++++++
 source3/smbd/reply.c                 | 2 +-
 source3/smbd/smb2_break.c            | 4 ++--
 source3/smbd/smb2_close.c            | 2 +-
 source3/smbd/smb2_create.c           | 6 +++---
 source3/smbd/smb2_flush.c            | 2 +-
 source3/smbd/smb2_getinfo.c          | 2 +-
 source3/smbd/smb2_glue.c             | 1 +
 source3/smbd/smb2_ioctl.c            | 2 +-
 source3/smbd/smb2_ioctl_named_pipe.c | 2 +-
 source3/smbd/smb2_lock.c             | 4 ++--
 source3/smbd/smb2_notify.c           | 4 ++--
 source3/smbd/smb2_query_directory.c  | 2 +-
 source3/smbd/smb2_read.c             | 2 +-
 source3/smbd/smb2_server.c           | 2 ++
 source3/smbd/smb2_sesssetup.c        | 4 ++--
 source3/smbd/smb2_setinfo.c          | 2 +-
 source3/smbd/smb2_tcon.c             | 4 ++--
 source3/smbd/smb2_write.c            | 2 +-
 25 files changed, 53 insertions(+), 37 deletions(-)

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 249cf0697792..4e5b78709034 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -514,6 +514,8 @@ struct smb_request {
 
 	size_t unread_bytes;
 	bool encrypted;
+	/* the tevent_context (wrapper) the request operates on */
+	struct tevent_context *ev_ctx;
 	connection_struct *conn;
 	struct smbd_server_connection *sconn;
 	struct smbXsrv_connection *xconn;
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index b984036e9f8e..c066ea1a9788 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -206,7 +206,7 @@ NTSTATUS schedule_aio_read_and_X(connection_struct *conn,
 	aio_ex->nbyte = smb_maxcnt;
 	aio_ex->offset = startpos;
 
-	req = SMB_VFS_PREAD_SEND(aio_ex, fsp->conn->sconn->ev_ctx,
+	req = SMB_VFS_PREAD_SEND(aio_ex, smbreq->ev_ctx,
 				 fsp,
 				 smb_buf(aio_ex->outbuf.data) + 1 /* pad */,
 				 smb_maxcnt, startpos);
@@ -459,7 +459,7 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
 	aio_ex->nbyte = numtowrite;
 	aio_ex->offset = startpos;
 
-	req = pwrite_fsync_send(aio_ex, fsp->conn->sconn->ev_ctx, fsp,
+	req = pwrite_fsync_send(aio_ex, smbreq->ev_ctx, fsp,
 				data, numtowrite, startpos,
 				aio_ex->write_through);
 	if (req == NULL) {
@@ -701,7 +701,7 @@ NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
 	aio_ex->nbyte = smb_maxcnt;
 	aio_ex->offset = startpos;
 
-	req = SMB_VFS_PREAD_SEND(aio_ex, fsp->conn->sconn->ev_ctx, fsp,
+	req = SMB_VFS_PREAD_SEND(aio_ex, smbreq->ev_ctx, fsp,
 				 preadbuf->data, smb_maxcnt, startpos);
 	if (req == NULL) {
 		DEBUG(0, ("smb2: SMB_VFS_PREAD_SEND failed. "
@@ -850,7 +850,7 @@ NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
 	aio_ex->nbyte = in_data.length;
 	aio_ex->offset = in_offset;
 
-	req = pwrite_fsync_send(aio_ex, fsp->conn->sconn->ev_ctx, fsp,
+	req = pwrite_fsync_send(aio_ex, smbreq->ev_ctx, fsp,
 				in_data.data, in_data.length, in_offset,
 				write_through);
 	if (req == NULL) {
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 1ac1b47b9d32..7d7058727bfb 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -701,6 +701,9 @@ struct smbd_smb2_request {
 	struct smbXsrv_tcon *tcon;
 	uint32_t last_tid;
 
+	/* the tevent_context (wrapper) the request operates on */
+	struct tevent_context *ev_ctx;
+
 	int current_idx;
 	bool do_signing;
 	/* Was the request encrypted? */
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index f1c8ea0c2ed4..85236e0102f2 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -281,7 +281,7 @@ static void api_dcerpc_cmd(connection_struct *conn, struct smb_request *req,
 	state->num_data = length;
 	state->max_read = max_read;
 
-	subreq = np_write_send(state, req->sconn->ev_ctx, state->handle,
+	subreq = np_write_send(state, req->ev_ctx, state->handle,
 			       state->data, length);
 	if (subreq == NULL) {
 		TALLOC_FREE(state);
@@ -330,7 +330,7 @@ static void api_dcerpc_cmd_write_done(struct tevent_req *subreq)
 		goto send;
 	}
 
-	subreq = np_read_send(state, req->sconn->ev_ctx,
+	subreq = np_read_send(state, req->ev_ctx,
 			      state->handle, state->data, state->max_read);
 	if (subreq == NULL) {
 		reply_nterror(req, NT_STATUS_NO_MEMORY);
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 4b28e7ff9a26..db5eb4e459b6 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -2408,7 +2408,7 @@ static void defer_open(struct share_mode_lock *lck,
 	DBG_DEBUG("defering mid %" PRIu64 "\n", req->mid);
 
 	watch_req = dbwrap_watched_watch_send(watch_state,
-					      req->sconn->ev_ctx,
+					      req->ev_ctx,
 					      lck->data->record,
 					      (struct server_id){0});
 	if (watch_req == NULL) {
@@ -2416,7 +2416,7 @@ static void defer_open(struct share_mode_lock *lck,
 	}
 	tevent_req_set_callback(watch_req, defer_open_done, watch_state);
 
-	ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
+	ok = tevent_req_set_endtime(watch_req, req->ev_ctx, abs_timeout);
 	if (!ok) {
 		exit_server("tevent_req_set_endtime failed");
 	}
@@ -2508,7 +2508,7 @@ static void setup_kernel_oplock_poll_open(struct timeval request_time,
 	 * As this timer event is owned by req, it will
 	 * disappear if req it talloc_freed.
 	 */
-	open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
+	open_rec->te = tevent_add_timer(req->ev_ctx,
 					req,
 					timeval_current_ofs(1, 0),
 					kernel_oplock_poll_open_timer,
@@ -2695,7 +2695,7 @@ static void schedule_async_open(struct timeval request_time,
 		exit_server("push_deferred_open_message_smb failed");
 	}
 
-	open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
+	open_rec->te = tevent_add_timer(req->ev_ctx,
 					req,
 					timeval_current_ofs(20, 0),
 					schedule_async_open_timer,
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 4be57bc2a5f0..c945f0f61776 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -67,7 +67,7 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
 			 conn->sconn->remote_address,
 			 conn->sconn->local_address,
 			 conn->session_info,
-			 conn->sconn->ev_ctx,
+			 smb_req->ev_ctx,
 			 conn->sconn->msg_ctx,
 			 &fsp->fake_file_handle);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -206,7 +206,7 @@ void reply_pipe_write(struct smb_request *req)
 	DEBUG(6, ("reply_pipe_write: %s, name: %s len: %d\n", fsp_fnum_dbg(fsp),
 		  fsp_str_dbg(fsp), (int)state->numtowrite));
 
-	subreq = np_write_send(state, req->sconn->ev_ctx,
+	subreq = np_write_send(state, req->ev_ctx,
 			       fsp->fake_file_handle, data, state->numtowrite);
 	if (subreq == NULL) {
 		TALLOC_FREE(state);
@@ -322,7 +322,7 @@ void reply_pipe_write_and_X(struct smb_request *req)
 		state->numtowrite -= 2;
 	}
 
-	subreq = np_write_send(state, req->sconn->ev_ctx,
+	subreq = np_write_send(state, req->ev_ctx,
 			       fsp->fake_file_handle, data, state->numtowrite);
 	if (subreq == NULL) {
 		TALLOC_FREE(state);
@@ -435,7 +435,7 @@ void reply_pipe_read_and_X(struct smb_request *req)
 	state->outbuf = req->outbuf;
 	req->outbuf = NULL;
 
-	subreq = np_read_send(state, req->sconn->ev_ctx,
+	subreq = np_read_send(state, req->ev_ctx,
 			      fsp->fake_file_handle, data,
 			      state->smb_maxcnt);
 	if (subreq == NULL) {
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index d2553049cd25..e730676ef361 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1506,6 +1506,8 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 
 	errno = 0;
 
+	req->ev_ctx = NULL;
+
 	if (!xconn->smb1.negprot.done) {
 		switch (type) {
 			/*
@@ -1640,6 +1642,8 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
 			return conn;
 		}
+
+		req->ev_ctx = conn->user_ev_ctx;
 	} else if (flags & AS_GUEST) {
 		/*
 		 * Does this protocol need to be run as guest? (Only archane
@@ -1649,9 +1653,13 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
 			return conn;
 		}
+
+		req->ev_ctx = req->sconn->guest_ev_ctx;
 	} else {
 		/* This call needs to be run as root */
 		change_to_root_user();
+
+		req->ev_ctx = req->sconn->root_ev_ctx;
 	}
 
 	/* load service specific parameters */
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 1b99664cbd8b..5afe57d11cb7 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -5392,7 +5392,7 @@ void reply_close(struct smb_request *req)
 		 */
 
 		fsp->deferred_close = tevent_wait_send(
-			fsp, fsp->conn->sconn->ev_ctx);
+			fsp, req->ev_ctx);
 		if (fsp->deferred_close == NULL) {
 			status = NT_STATUS_NO_MEMORY;
 			goto done;
diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c
index 86529ed2e1f8..21fbef42dced 100644
--- a/source3/smbd/smb2_break.c
+++ b/source3/smbd/smb2_break.c
@@ -86,7 +86,7 @@ NTSTATUS smbd_smb2_request_process_break(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
 	}
 
-	subreq = smbd_smb2_oplock_break_send(req, req->sconn->ev_ctx,
+	subreq = smbd_smb2_oplock_break_send(req, req->ev_ctx,
 					     req, in_fsp, in_oplock_level);
 	if (subreq == NULL) {
 		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
@@ -265,7 +265,7 @@ static NTSTATUS smbd_smb2_request_process_lease_break(
 	in_lease_key.data[1] = BVAL(inbody, 16);
 	in_lease_state = IVAL(inbody, 24);
 
-	subreq = smbd_smb2_lease_break_send(req, req->sconn->ev_ctx, req,
+	subreq = smbd_smb2_lease_break_send(req, req->ev_ctx, req,
 					    in_lease_key, in_lease_state);
 	if (subreq == NULL) {
 		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c
index 992b52929ec4..33863d32f5f2 100644
--- a/source3/smbd/smb2_close.c
+++ b/source3/smbd/smb2_close.c
@@ -70,7 +70,7 @@ NTSTATUS smbd_smb2_request_process_close(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_close_send(req, req->sconn->ev_ctx,
+	subreq = smbd_smb2_close_send(req, req->ev_ctx,
 				      req, in_fsp, in_flags);
 	if (subreq == NULL) {
 		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 3f38af5dde27..8fbea238698c 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -228,7 +228,7 @@ NTSTATUS smbd_smb2_request_process_create(struct smbd_smb2_request *smb2req)
 	}
 
 	tsubreq = smbd_smb2_create_send(smb2req,
-				       smb2req->sconn->ev_ctx,
+				       smb2req->ev_ctx,
 				       smb2req,
 				       in_oplock_level,
 				       in_impersonation_level,
@@ -1763,7 +1763,7 @@ bool schedule_deferred_open_message_smb2(
 		(unsigned long long)mid ));
 
 	tevent_schedule_immediate(state->im,
-			smb2req->sconn->ev_ctx,
+			smb2req->ev_ctx,
 			smbd_smb2_create_request_dispatch_immediate,
 			smb2req);
 
@@ -1795,7 +1795,7 @@ static bool smbd_smb2_create_cancel(struct tevent_req *req)
 
 	remove_deferred_open_message_smb2_internal(smb2req, mid);
 
-	tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
+	tevent_req_defer_callback(req, smb2req->ev_ctx);
 	tevent_req_nterror(req, NT_STATUS_CANCELLED);
 	return true;
 }
diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c
index 470a8df49442..4f815a6f5b0c 100644
--- a/source3/smbd/smb2_flush.c
+++ b/source3/smbd/smb2_flush.c
@@ -58,7 +58,7 @@ NTSTATUS smbd_smb2_request_process_flush(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_flush_send(req, req->sconn->ev_ctx,
+	subreq = smbd_smb2_flush_send(req, req->ev_ctx,
 				      req, in_fsp);
 	if (subreq == NULL) {
 		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index 694e9f83b754..da82bf523787 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -120,7 +120,7 @@ NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_getinfo_send(req, req->sconn->ev_ctx,
+	subreq = smbd_smb2_getinfo_send(req, req->ev_ctx,
 					req, in_fsp,
 					in_info_type,
 					in_file_info_class,
diff --git a/source3/smbd/smb2_glue.c b/source3/smbd/smb2_glue.c
index 6a73ec050e24..cccc763c3425 100644
--- a/source3/smbd/smb2_glue.c
+++ b/source3/smbd/smb2_glue.c
@@ -46,6 +46,7 @@ struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req)
 	smbreq->conn = req->tcon->compat;
 	smbreq->sconn = req->sconn;
 	smbreq->xconn = req->xconn;
+	smbreq->ev_ctx = req->ev_ctx;
 	smbreq->smbpid = (uint16_t)IVAL(inhdr, SMB2_HDR_PID);
 	smbreq->flags2 = FLAGS2_UNICODE_STRINGS |
 			 FLAGS2_32_BIT_ERROR_CODES |
diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c
index be70e3a09128..451733c1a659 100644
--- a/source3/smbd/smb2_ioctl.c
+++ b/source3/smbd/smb2_ioctl.c
@@ -217,7 +217,7 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
 		break;
 	}
 
-	subreq = smbd_smb2_ioctl_send(req, req->sconn->ev_ctx,
+	subreq = smbd_smb2_ioctl_send(req, req->ev_ctx,
 				      req, in_fsp,
 				      in_ctl_code,
 				      in_input_buffer,
diff --git a/source3/smbd/smb2_ioctl_named_pipe.c b/source3/smbd/smb2_ioctl_named_pipe.c
index f9e3dec049c0..f8012ae19203 100644
--- a/source3/smbd/smb2_ioctl_named_pipe.c
+++ b/source3/smbd/smb2_ioctl_named_pipe.c
@@ -143,7 +143,7 @@ static void smbd_smb2_ioctl_pipe_write_done(struct tevent_req *subreq)
 		(unsigned int)state->out_output.length ));
 
 	subreq = np_read_send(state->smbreq->conn,
-			      state->smb2req->sconn->ev_ctx,
+			      state->smb2req->ev_ctx,
 			      state->fsp->fake_file_handle,
 			      state->out_output.data,
 			      state->out_output.length);
diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c
index 3cc591089a42..da5a54df6233 100644
--- a/source3/smbd/smb2_lock.c
+++ b/source3/smbd/smb2_lock.c
@@ -134,7 +134,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_lock_send(req, req->sconn->ev_ctx,
+	subreq = smbd_smb2_lock_send(req, req->ev_ctx,
 				     req, in_fsp,
 				     in_lock_count,
 				     in_locks);
@@ -368,7 +368,7 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
 	}
 
 	if (async) {
-		tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
+		tevent_req_defer_callback(req, smb2req->ev_ctx);
 		SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
 		return req;
 	}
diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c
index 242415625567..e49e76d96413 100644
--- a/source3/smbd/smb2_notify.c
+++ b/source3/smbd/smb2_notify.c
@@ -94,7 +94,7 @@ NTSTATUS smbd_smb2_request_process_notify(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_notify_send(req, req->sconn->ev_ctx,
+	subreq = smbd_smb2_notify_send(req, req->ev_ctx,
 				       req, in_fsp,
 				       in_flags,
 				       in_output_buffer_length,
@@ -355,7 +355,7 @@ static void smbd_smb2_notify_reply(struct smb_request *smbreq,
 		}
 	}
 
-	tevent_req_defer_callback(req, state->smb2req->sconn->ev_ctx);
+	tevent_req_defer_callback(req, state->smb2req->ev_ctx);
 
 	if (!NT_STATUS_IS_OK(state->status)) {
 		tevent_req_nterror(req, state->status);
diff --git a/source3/smbd/smb2_query_directory.c b/source3/smbd/smb2_query_directory.c
index 700f43e31262..50a5bca5d7b2 100644
--- a/source3/smbd/smb2_query_directory.c
+++ b/source3/smbd/smb2_query_directory.c
@@ -124,7 +124,7 @@ NTSTATUS smbd_smb2_request_process_query_directory(struct smbd_smb2_request *req
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_query_directory_send(req, req->sconn->ev_ctx,
+	subreq = smbd_smb2_query_directory_send(req, req->ev_ctx,
 				     req, in_fsp,
 				     in_file_info_class,
 				     in_flags,
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index a7d2496bc6f3..065a5cd5fc69 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -97,7 +97,7 @@ NTSTATUS smbd_smb2_request_process_read(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_read_send(req, req->sconn->ev_ctx,
+	subreq = smbd_smb2_read_send(req, req->ev_ctx,
 				     req, in_fsp,
 				     in_flags,
 				     in_length,
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 46b747cabffa..0c1ac3238918 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -2614,8 +2614,10 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 		SMB_ASSERT(call->fileid_ofs == 0);
 		/* This call needs to be run as root */
 		change_to_root_user();
+		req->ev_ctx = req->sconn->root_ev_ctx;
 	} else {
 		SMB_ASSERT(call->need_tcon);
+		req->ev_ctx = req->tcon->compat->user_ev_ctx;
 	}
 
 #define _INBYTES(_r) \
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 5e1e8b4ec579..fe5835b83f34 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -95,7 +95,7 @@ NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *smb2req)
 	in_security_buffer.length = in_security_length;
 
 	subreq = smbd_smb2_session_setup_wrap_send(smb2req,
-						   smb2req->sconn->ev_ctx,
+						   smb2req->ev_ctx,
 						   smb2req,
 						   in_session_id,
 						   in_flags,
@@ -1218,7 +1218,7 @@ NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, status);
 	}
 
-	subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
+	subreq = smbd_smb2_logoff_send(req, req->ev_ctx, req);
 	if (subreq == NULL) {
 		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
 	}
diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c
index 4958bb8f16e7..5a6a28a323e2 100644
--- a/source3/smbd/smb2_setinfo.c
+++ b/source3/smbd/smb2_setinfo.c
@@ -107,7 +107,7 @@ NTSTATUS smbd_smb2_request_process_setinfo(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_setinfo_send(req, req->sconn->ev_ctx,
+	subreq = smbd_smb2_setinfo_send(req, req->ev_ctx,
 					req, in_fsp,
 					in_info_type,
 					in_file_info_class,
diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
index ebd31602efcd..3a4a15d3059e 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -94,7 +94,7 @@ NTSTATUS smbd_smb2_request_process_tcon(struct smbd_smb2_request *req)
 	}
 
 	subreq = smbd_smb2_tree_connect_send(req,
-					     req->sconn->ev_ctx,
+					     req->ev_ctx,
 					     req,
 					     in_path_string);
 	if (subreq == NULL) {
@@ -491,7 +491,7 @@ NTSTATUS smbd_smb2_request_process_tdis(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, status);
 	}
 
-	subreq = smbd_smb2_tdis_send(req, req->sconn->ev_ctx, req);
+	subreq = smbd_smb2_tdis_send(req, req->ev_ctx, req);
 	if (subreq == NULL) {
 		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
 	}
diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c
index ee95bd317aef..d5ab12ecc21a 100644
--- a/source3/smbd/smb2_write.c
+++ b/source3/smbd/smb2_write.c
@@ -109,7 +109,7 @@ NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req)
 		return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
 	}
 
-	subreq = smbd_smb2_write_send(req, req->sconn->ev_ctx,
+	subreq = smbd_smb2_write_send(req, req->ev_ctx,
 				      req, in_fsp,
 				      in_data_buffer,
 				      in_offset,
-- 
2.17.1


From c85f63963a5b6f9d6642b246007039d667d57eef Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 52/52] smbd: remove unused smbd_server_connection->ev_ctx

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/globals.h | 1 -
 source3/smbd/msdfs.c   | 1 -
 source3/smbd/process.c | 1 -
 3 files changed, 3 deletions(-)

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 7d7058727bfb..f463da8a36e0 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -875,7 +875,6 @@ struct smbd_server_connection {
 	const struct tsocket_address *local_address;
 	const struct tsocket_address *remote_address;
 	const char *remote_hostname;
-	struct tevent_context *ev_ctx;
 	struct tevent_context *raw_ev_ctx;
 	struct tevent_context *root_ev_ctx;
 	struct tevent_context *guest_ev_ctx;
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 3fba71bb084e..bac9d8f6bf66 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -263,7 +263,6 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	sconn->ev_ctx = sconn->raw_ev_ctx;
 	sconn->root_ev_ctx = sconn->raw_ev_ctx;
 	sconn->guest_ev_ctx = sconn->raw_ev_ctx;
 	sconn->msg_ctx = msg;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index e730676ef361..a3571ee811ab 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3931,7 +3931,6 @@ void smbd_process(struct tevent_context *ev_ctx,
 	client->sconn = sconn;
 	sconn->client = client;
 
-	sconn->ev_ctx = ev_ctx;
 	sconn->raw_ev_ctx = ev_ctx;
 	sconn->root_ev_ctx = ev_ctx;
 	sconn->guest_ev_ctx = ev_ctx;
-- 
2.17.1

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20180617/794a8dcf/signature.sig>


More information about the samba-technical mailing list