[Patches] Preparation for tevent impersonation (part1)

Stefan Metzmacher metze at samba.org
Tue Jun 12 06:30:26 UTC 2018


Hi,

as some of you already know I'm working on "tevent impersonation".
In order to add path based async SMB_VFS calls, we need to make sure
that vfs modules still don't have to take care of calling
{become,change_to}_user() within async processing.
This is currently done at the SMB layer when dispatching the request.
As it's possible to have more than one user session per connection (smbd
child), it's quite possible that the unix identity may change between
the async _SEND() function and possible async event handlers.
Things like "force user" add further complexity.

In source3/smbd/smb2_setinfo.c:defer_rename_done() we already have
some code to recover the impersonation explicitly.

In order to prevent having to deal with this complexity in every
tevent based callback, which may introduce security problems
if someone forgets to add it, I implemented a wrapper infrastructure
in tevent. This can be used to change the impersonation/global state
before and after calling the regular event handler. It could also
be used to for additional tracing of blocking event handlers.

The highlevel trigger for this is Ralph's work to make our
directory enumeration async using our pthreadpool infrastructure,
there're also some impersonation requirements, but more on that later.

There're a few work in progress branches:

https://git.samba.org/?p=metze/samba/wip.git;a=shortlog;h=refs/heads/master4-impersonate-ok
https://git.samba.org/?p=metze/samba/wip.git;a=shortlog;h=refs/heads/master4-impersonate
https://git.samba.org/?p=metze/samba/wip.git;a=shortlog;h=refs/heads/master4-async-dosmode

The attached patches are from master4-impersonate-ok, they mostly
prepare things, e.g. adding talloc_stackframe()'s in more places.

The most important thing is the create_conn_struct_tos[_cwd]()
functions with much stricter requirements to create fake
connection_structs, we no longer let the caller pass in
an tevent context (we create a temporary one), as it's really not
possible to use these fake contexts for real async processing.
We also make sure we cleanup the fake contexts in a destructor
in a common way.

They passed private autobuilds...

Please review and push:-)

Thanks!
metze
-------------- next part --------------
From 9eca815a1b2067df6520b7ed87fe959c09ef3cf4 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Wed, 23 May 2018 16:35:20 +0200
Subject: [PATCH 01/40] printing: remove unused arguments from load_printers()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/printing/load.c          |  3 +--
 source3/printing/load.h          |  3 +--
 source3/printing/queue_process.c |  2 +-
 source3/printing/spoolssd.c      | 12 ++++--------
 source3/smbd/server_reload.c     |  4 ++--
 5 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/source3/printing/load.c b/source3/printing/load.c
index 238998d920d7..51495f970db6 100644
--- a/source3/printing/load.c
+++ b/source3/printing/load.c
@@ -62,8 +62,7 @@ static void add_auto_printers(void)
 /***************************************************************************
 load automatic printer services from pre-populated pcap cache
 ***************************************************************************/
-void load_printers(struct tevent_context *ev,
-		   struct messaging_context *msg_ctx)
+void load_printers(void)
 {
 	SMB_ASSERT(pcap_cache_loaded(NULL));
 
diff --git a/source3/printing/load.h b/source3/printing/load.h
index 4611e9748c2d..36e0a25a7dda 100644
--- a/source3/printing/load.h
+++ b/source3/printing/load.h
@@ -22,7 +22,6 @@
 
 /* The following definitions come from printing/load.c  */
 
-void load_printers(struct tevent_context *ev,
-		   struct messaging_context *msg_ctx);
+void load_printers(void);
 
 #endif /* _PRINTING_LOAD_H_ */
diff --git a/source3/printing/queue_process.c b/source3/printing/queue_process.c
index c4941d84ccd7..76fd9349fb45 100644
--- a/source3/printing/queue_process.c
+++ b/source3/printing/queue_process.c
@@ -484,7 +484,7 @@ void printing_subsystem_update(struct tevent_context *ev_ctx,
 {
 	if (background_lpq_updater_pid != -1) {
 		if (pcap_cache_loaded(NULL)) {
-			load_printers(ev_ctx, msg_ctx);
+			load_printers();
 		}
 		if (force) {
 			/* Send a sighup to the background process.
diff --git a/source3/printing/spoolssd.c b/source3/printing/spoolssd.c
index 2b08d580f356..ca1eda918790 100644
--- a/source3/printing/spoolssd.c
+++ b/source3/printing/spoolssd.c
@@ -105,7 +105,7 @@ static void update_conf(struct tevent_context *ev,
 {
 	change_to_root_user();
 	lp_load_global(get_dyn_CONFIGFILE());
-	load_printers(ev, msg);
+	load_printers();
 
 	spoolss_reopen_logs(spoolss_child_id);
 	if (spoolss_child_id == 0) {
@@ -212,13 +212,9 @@ static void spoolss_chld_sig_hup_handler(struct tevent_context *ev,
 					 void *siginfo,
 					 void *pvt)
 {
-	struct messaging_context *msg_ctx;
-
-	msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
-
 	change_to_root_user();
 	DEBUG(1,("Reloading printers after SIGHUP\n"));
-	load_printers(ev, msg_ctx);
+	load_printers();
 	spoolss_reopen_logs(spoolss_child_id);
 }
 
@@ -293,7 +289,7 @@ static bool spoolss_child_init(struct tevent_context *ev_ctx,
 	 * ourselves. If pcap has not been loaded yet, then ignore, we will get
 	 * a message as soon as the bq process completes the reload. */
 	if (pcap_cache_loaded(NULL)) {
-		load_printers(ev_ctx, msg_ctx);
+		load_printers();
 	}
 
 	/* try to reinit rpc queues */
@@ -704,7 +700,7 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx,
 	 * client enumeration anyway.
 	 */
 	if (pcap_cache_loaded(NULL)) {
-		load_printers(ev_ctx, msg_ctx);
+		load_printers();
 	}
 
 	mem_ctx = talloc_new(NULL);
diff --git a/source3/smbd/server_reload.c b/source3/smbd/server_reload.c
index 9b6209619c30..f07ad9254720 100644
--- a/source3/smbd/server_reload.c
+++ b/source3/smbd/server_reload.c
@@ -79,7 +79,7 @@ void delete_and_reload_printers(struct tevent_context *ev,
 	reload_last_pcap_time = pcap_last_update;
 
 	/* Get pcap printers updated */
-	load_printers(ev, msg_ctx);
+	load_printers();
 
 	n_services = lp_numservices();
 	pnum = lp_servicenumber(PRINTERS_NAME);
@@ -110,7 +110,7 @@ void delete_and_reload_printers(struct tevent_context *ev,
 	}
 
 	/* Make sure deleted printers are gone */
-	load_printers(ev, msg_ctx);
+	load_printers();
 
 	talloc_free(frame);
 }
-- 
2.17.1


From 93c858776a6356aea3acb6489733d1d214fe674f Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Wed, 23 May 2018 16:35:20 +0200
Subject: [PATCH 02/40] printing: remove unused arguments from
 delete_and_reload_printers()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/printing/queue_process.c            | 2 +-
 source3/rpc_server/spoolss/srv_spoolss_nt.c | 4 ++--
 source3/rpc_server/srvsvc/srv_srvsvc_nt.c   | 2 +-
 source3/smbd/lanman.c                       | 2 +-
 source3/smbd/proto.h                        | 3 +--
 source3/smbd/server_reload.c                | 7 +------
 6 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/source3/printing/queue_process.c b/source3/printing/queue_process.c
index 76fd9349fb45..c4648ce2b6ac 100644
--- a/source3/printing/queue_process.c
+++ b/source3/printing/queue_process.c
@@ -123,7 +123,7 @@ static void delete_and_reload_printers_full(struct tevent_context *ev,
 	}
 
 	/* finally, purge old snums */
-	delete_and_reload_printers(ev, msg_ctx);
+	delete_and_reload_printers();
 
 	TALLOC_FREE(session_info);
 }
diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index f9a89194cc57..2bdce560c38b 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -1694,7 +1694,7 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
 	 * inventory on open as well.
 	 */
 	become_root();
-	delete_and_reload_printers(server_event_context(), p->msg_ctx);
+	delete_and_reload_printers();
 	unbecome_root();
 
 	/* some sanity check because you can open a printer or a print server */
@@ -4403,7 +4403,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
 	 * printer process updates printer_list.tdb at regular intervals.
 	 */
 	become_root();
-	delete_and_reload_printers(server_event_context(), msg_ctx);
+	delete_and_reload_printers();
 	unbecome_root();
 
 	n_services = lp_numservices();
diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
index 2c33387bf6d0..c25abf01ac97 100644
--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
@@ -563,7 +563,7 @@ static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
 
 	/* Ensure all the usershares are loaded. */
 	become_root();
-	delete_and_reload_printers(server_event_context(), p->msg_ctx);
+	delete_and_reload_printers();
 	load_usershare_shares(NULL, connections_snum_used);
 	load_registry_shares();
 	num_services = lp_numservices();
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 6854527500dd..90906a204d4f 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -2100,7 +2100,7 @@ static bool api_RNetShareEnum(struct smbd_server_connection *sconn,
 
 	/* Ensure all the usershares are loaded. */
 	become_root();
-	delete_and_reload_printers(sconn->ev_ctx, sconn->msg_ctx);
+	delete_and_reload_printers();
 	load_registry_shares();
 	count = load_usershare_shares(NULL, connections_snum_used);
 	unbecome_root();
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 7a5ac4c4bc8b..5f72da0f9963 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1051,8 +1051,7 @@ const struct security_token *sec_ctx_active_token(void);
 
 struct memcache *smbd_memcache(void);
 bool snum_is_shared_printer(int snum);
-void delete_and_reload_printers(struct tevent_context *ev,
-				struct messaging_context *msg_ctx);
+void delete_and_reload_printers(void);
 bool reload_services(struct smbd_server_connection *sconn,
 		     bool (*snumused) (struct smbd_server_connection *, int),
 		     bool test);
diff --git a/source3/smbd/server_reload.c b/source3/smbd/server_reload.c
index f07ad9254720..3715a51c1529 100644
--- a/source3/smbd/server_reload.c
+++ b/source3/smbd/server_reload.c
@@ -48,13 +48,8 @@ bool snum_is_shared_printer(int snum)
  *
  * This function should normally only be called as a callback on a successful
  * pcap_cache_reload(), or on client enumeration.
- *
- * @param[in] ev        The event context.
- *
- * @param[in] msg_ctx   The messaging context.
  */
-void delete_and_reload_printers(struct tevent_context *ev,
-				struct messaging_context *msg_ctx)
+void delete_and_reload_printers(void)
 {
 	int n_services;
 	int pnum;
-- 
2.17.1


From 273c2e5c17251a4dbd0be7ba68460a9e2e07a1bd Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 15:59:43 +0200
Subject: [PATCH 03/40] smbd: add create_conn_struct_tos[_cwd]() helper
 functions

This makes it more obvious that the returned connection_struct
is only temporary (and allocated on talloc_tos()!)
It will never allow async requests on a long term
tevent context! So we create a short term event context.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/msdfs.c | 125 +++++++++++++++++++++++++++++++++++++++++++
 source3/smbd/proto.h |  16 ++++++
 2 files changed, 141 insertions(+)

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 3c23d745eee1..d6fbe93fcbb7 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -448,6 +448,131 @@ NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
 	return NT_STATUS_OK;
 }
 
+static int conn_struct_tos_destructor(struct conn_struct_tos *c)
+{
+	if (c->oldcwd_fname != NULL) {
+		vfs_ChDir(c->conn, c->oldcwd_fname);
+		TALLOC_FREE(c->oldcwd_fname);
+	}
+	SMB_VFS_DISCONNECT(c->conn);
+	conn_free(c->conn);
+	return 0;
+}
+
+/********************************************************
+ Fake up a connection struct for the VFS layer, for use in
+ applications (such as the python bindings), that do not want the
+ global working directory changed under them.
+
+ SMB_VFS_CONNECT requires root privileges.
+ This temporary uses become_root() and unbecome_root().
+
+ But further impersonation has to be cone by the caller.
+*********************************************************/
+NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
+				int snum,
+				const char *path,
+				const struct auth_session_info *session_info,
+				struct conn_struct_tos **_c)
+{
+	struct conn_struct_tos *c = NULL;
+	struct tevent_context *ev = NULL;
+	NTSTATUS status;
+
+	*_c = NULL;
+
+	c = talloc_zero(talloc_tos(), struct conn_struct_tos);
+	if (c == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	ev = samba_tevent_context_init(c);
+	if (ev == NULL) {
+		TALLOC_FREE(c);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	status = create_conn_struct(c,
+				    ev,
+				    msg,
+				    &c->conn,
+				    snum,
+				    path,
+				    session_info);
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(c);
+		return status;
+	}
+	talloc_steal(c, c->conn);
+
+	talloc_set_destructor(c, conn_struct_tos_destructor);
+
+	*_c = c;
+	return NT_STATUS_OK;
+}
+
+/********************************************************
+ Fake up a connection struct for the VFS layer.
+ Note: this performs a vfs connect and CHANGES CWD !!!! JRA.
+
+ See also the comment for create_conn_struct_tos() above!
+
+ The CWD change is reverted by the destructor of
+ conn_struct_tos when the current talloc_tos() is destroyed.
+*********************************************************/
+NTSTATUS create_conn_struct_tos_cwd(struct messaging_context *msg,
+				    int snum,
+				    const char *path,
+				    const struct auth_session_info *session_info,
+				    struct conn_struct_tos **_c)
+{
+	struct conn_struct_tos *c = NULL;
+	struct smb_filename smb_fname_connectpath = {0};
+	NTSTATUS status;
+
+	*_c = NULL;
+
+	status = create_conn_struct_tos(msg,
+					snum,
+					path,
+					session_info,
+					&c);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	/*
+	 * Windows seems to insist on doing trans2getdfsreferral() calls on
+	 * the IPC$ share as the anonymous user. If we try to chdir as that
+	 * user we will fail.... WTF ? JRA.
+	 */
+
+	c->oldcwd_fname = vfs_GetWd(c, c->conn);
+	if (c->oldcwd_fname == NULL) {
+		status = map_nt_error_from_unix(errno);
+		DEBUG(3, ("vfs_GetWd failed: %s\n", strerror(errno)));
+		TALLOC_FREE(c);
+		return status;
+	}
+
+	smb_fname_connectpath = (struct smb_filename) {
+		.base_name = c->conn->connectpath
+	};
+
+	if (vfs_ChDir(c->conn, &smb_fname_connectpath) != 0) {
+		status = map_nt_error_from_unix(errno);
+		DBG_NOTICE("Can't ChDir to new conn path %s. "
+			   "Error was %s\n",
+			   c->conn->connectpath, strerror(errno));
+		TALLOC_FREE(c->oldcwd_fname);
+		TALLOC_FREE(c);
+		return status;
+	}
+
+	*_c = c;
+	return NT_STATUS_OK;
+}
+
 static void shuffle_strlist(char **list, int count)
 {
 	int i;
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 5f72da0f9963..ed12e504bf8b 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -514,6 +514,22 @@ NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
 				const char *path,
 				const struct auth_session_info *session_info,
 				struct smb_filename **poldcwd_fname);
+struct connection_struct;
+struct smb_filename;
+struct conn_struct_tos {
+	struct connection_struct *conn;
+	struct smb_filename *oldcwd_fname;
+};
+NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
+				int snum,
+				const char *path,
+				const struct auth_session_info *session_info,
+				struct conn_struct_tos **_c);
+NTSTATUS create_conn_struct_tos_cwd(struct messaging_context *msg,
+				    int snum,
+				    const char *path,
+				    const struct auth_session_info *session_info,
+				    struct conn_struct_tos **_c);
 
 /* The following definitions come from smbd/negprot.c  */
 
-- 
2.17.1


From 6c86e4c46b9471ac666bc25c321e3685c2862c10 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 07:38:24 +0200
Subject: [PATCH 04/40] pysmbd: remove useless explicit conn_free() from
 set_nt_acl_conn()

The following TALLOC_FREE(frame); will do the same via
conn_free_wrapper().

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/pysmbd.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
index daaf95cb6658..592cdf73f0a2 100644
--- a/source3/smbd/pysmbd.c
+++ b/source3/smbd/pysmbd.c
@@ -194,7 +194,6 @@ static NTSTATUS set_nt_acl_conn(const char *fname,
 
 	SMB_VFS_CLOSE(fsp);
 
-	conn_free(conn);
 	TALLOC_FREE(frame);
 
 	umask(saved_umask);
-- 
2.17.1


From 08b6e56f258156d2b5cabc087b06942626782978 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 16:16:19 +0200
Subject: [PATCH 05/40] pysmbd: consitently use talloc_stackframe() for
 temporary memory

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/pysmbd.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
index 592cdf73f0a2..700ce78a7732 100644
--- a/source3/smbd/pysmbd.c
+++ b/source3/smbd/pysmbd.c
@@ -580,28 +580,28 @@ static PyObject *py_smbd_get_nt_acl(PyObject *self, PyObject *args, PyObject *kw
 	int security_info_wanted;
 	PyObject *py_sd;
 	struct security_descriptor *sd;
-	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+	TALLOC_CTX *frame = talloc_stackframe();
 	connection_struct *conn;
 	NTSTATUS status;
 
 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|z", discard_const_p(char *, kwnames),
 					 &fname, &security_info_wanted, &service)) {
-		TALLOC_FREE(tmp_ctx);
+		TALLOC_FREE(frame);
 		return NULL;
 	}
 
-	conn = get_conn(tmp_ctx, service);
+	conn = get_conn(frame, service);
 	if (!conn) {
-		TALLOC_FREE(tmp_ctx);
+		TALLOC_FREE(frame);
 		return NULL;
 	}
 
-	status = get_nt_acl_conn(tmp_ctx, fname, conn, security_info_wanted, &sd);
+	status = get_nt_acl_conn(frame, fname, conn, security_info_wanted, &sd);
 	PyErr_NTSTATUS_IS_ERR_RAISE(status);
 
 	py_sd = py_return_ndr_struct("samba.dcerpc.security", "descriptor", sd, sd);
 
-	TALLOC_FREE(tmp_ctx);
+	TALLOC_FREE(frame);
 
 	return py_sd;
 }
@@ -662,28 +662,20 @@ static PyObject *py_smbd_get_sys_acl(PyObject *self, PyObject *args, PyObject *k
 	struct smb_acl_t *acl;
 	int acl_type;
 	TALLOC_CTX *frame = talloc_stackframe();
-	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
 	connection_struct *conn;
 	char *service = NULL;
 	struct smb_filename *smb_fname = NULL;
 
-	if (!tmp_ctx) {
-		PyErr_NoMemory();
-		return NULL;
-	}
-
 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|z",
 					 discard_const_p(char *, kwnames),
 					 &fname, &acl_type, &service)) {
 		TALLOC_FREE(frame);
-		TALLOC_FREE(tmp_ctx);
 		return NULL;
 	}
 
 	conn = get_conn(frame, service);
 	if (!conn) {
 		TALLOC_FREE(frame);
-		TALLOC_FREE(tmp_ctx);
 		return NULL;
 	}
 
@@ -692,20 +684,17 @@ static PyObject *py_smbd_get_sys_acl(PyObject *self, PyObject *args, PyObject *k
 					lp_posix_pathnames());
 	if (smb_fname == NULL) {
 		TALLOC_FREE(frame);
-		TALLOC_FREE(tmp_ctx);
 		return NULL;
 	}
-	acl = SMB_VFS_SYS_ACL_GET_FILE( conn, smb_fname, acl_type, tmp_ctx);
+	acl = SMB_VFS_SYS_ACL_GET_FILE( conn, smb_fname, acl_type, frame);
 	if (!acl) {
 		TALLOC_FREE(frame);
-		TALLOC_FREE(tmp_ctx);
 		return PyErr_SetFromErrno(PyExc_OSError);
 	}
 
 	py_acl = py_return_ndr_struct("samba.dcerpc.smb_acl", "t", acl, acl);
 
 	TALLOC_FREE(frame);
-	TALLOC_FREE(tmp_ctx);
 
 	return py_acl;
 }
-- 
2.17.1


From 66aa9298c7a756a8c4dfe090816644fe72432365 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 16:16:19 +0200
Subject: [PATCH 06/40] pysmbd: remove explicit talloc_stackframe() from
 get_conn() and name it get_conn_tos()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/pysmbd.c | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
index 700ce78a7732..1b4d2cd1e9b0 100644
--- a/source3/smbd/pysmbd.c
+++ b/source3/smbd/pysmbd.c
@@ -43,33 +43,29 @@ static int conn_free_wrapper(connection_struct *conn)
 	return 0;
 };
 
-static connection_struct *get_conn(TALLOC_CTX *mem_ctx, const char *service)
+static connection_struct *get_conn_tos(const char *service)
 {
 	connection_struct *conn;
-	TALLOC_CTX *frame = talloc_stackframe();
 	int snum = -1;
 	NTSTATUS status;
 
 	if (!posix_locking_init(false)) {
 		PyErr_NoMemory();
-		TALLOC_FREE(frame);
 		return NULL;
 	}
 
 	if (service) {
 		snum = lp_servicenumber(service);
 		if (snum == -1) {
-			TALLOC_FREE(frame);
 			PyErr_SetString(PyExc_RuntimeError, "unknown service");
 			return NULL;
 		}
 	}
 
-	status = create_conn_struct(mem_ctx, NULL, NULL, &conn, snum, "/",
+	status = create_conn_struct(talloc_tos(), NULL, NULL, &conn, snum, "/",
 					    NULL);
 	PyErr_NTSTATUS_IS_ERR_RAISE(status);
 
-	TALLOC_FREE(frame);
 	/* Ignore read-only and share restrictions */
 	conn->read_only = false;
 	conn->share_access = SEC_RIGHTS_FILE_ALL;
@@ -390,7 +386,7 @@ static PyObject *py_smbd_set_simple_acl(PyObject *self, PyObject *args, PyObject
 
 	frame = talloc_stackframe();
 
-	conn = get_conn(frame, service);
+	conn = get_conn_tos(service);
 	if (!conn) {
 		return NULL;
 	}
@@ -431,7 +427,7 @@ static PyObject *py_smbd_chown(PyObject *self, PyObject *args, PyObject *kwargs)
 
 	frame = talloc_stackframe();
 
-	conn = get_conn(frame, service);
+	conn = get_conn_tos(service);
 	if (!conn) {
 		return NULL;
 	}
@@ -489,7 +485,7 @@ static PyObject *py_smbd_unlink(PyObject *self, PyObject *args, PyObject *kwargs
 		return NULL;
 	}
 
-	conn = get_conn(frame, service);
+	conn = get_conn_tos(service);
 	if (!conn) {
 		TALLOC_FREE(frame);
 		return NULL;
@@ -555,7 +551,7 @@ static PyObject *py_smbd_set_nt_acl(PyObject *self, PyObject *args, PyObject *kw
 		return NULL;
 	}
 
-	conn = get_conn(frame, service);
+	conn = get_conn_tos(service);
 	if (!conn) {
 		TALLOC_FREE(frame);
 		return NULL;
@@ -590,7 +586,7 @@ static PyObject *py_smbd_get_nt_acl(PyObject *self, PyObject *args, PyObject *kw
 		return NULL;
 	}
 
-	conn = get_conn(frame, service);
+	conn = get_conn_tos(service);
 	if (!conn) {
 		TALLOC_FREE(frame);
 		return NULL;
@@ -632,7 +628,7 @@ static PyObject *py_smbd_set_sys_acl(PyObject *self, PyObject *args, PyObject *k
 		return NULL;
 	}
 
-	conn = get_conn(frame, service);
+	conn = get_conn_tos(service);
 	if (!conn) {
 		TALLOC_FREE(frame);
 		return NULL;
@@ -673,7 +669,7 @@ static PyObject *py_smbd_get_sys_acl(PyObject *self, PyObject *args, PyObject *k
 		return NULL;
 	}
 
-	conn = get_conn(frame, service);
+	conn = get_conn_tos(service);
 	if (!conn) {
 		TALLOC_FREE(frame);
 		return NULL;
-- 
2.17.1


From 6bb93a9b6f6963e7f9c16611e25ccacac99e0027 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 16:16:19 +0200
Subject: [PATCH 07/40] pysmbd: make use of create_conn_struct_tos()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/pysmbd.c | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
index 1b4d2cd1e9b0..a919b93aab2c 100644
--- a/source3/smbd/pysmbd.c
+++ b/source3/smbd/pysmbd.c
@@ -37,15 +37,9 @@ extern const struct generic_mapping file_generic_mapping;
 #undef  DBGC_CLASS
 #define DBGC_CLASS DBGC_ACLS
 
-static int conn_free_wrapper(connection_struct *conn)
-{
-	conn_free(conn);
-	return 0;
-};
-
 static connection_struct *get_conn_tos(const char *service)
 {
-	connection_struct *conn;
+	struct conn_struct_tos *c = NULL;
 	int snum = -1;
 	NTSTATUS status;
 
@@ -62,15 +56,17 @@ static connection_struct *get_conn_tos(const char *service)
 		}
 	}
 
-	status = create_conn_struct(talloc_tos(), NULL, NULL, &conn, snum, "/",
-					    NULL);
+	status = create_conn_struct_tos(NULL,
+					snum,
+					"/",
+					NULL,
+					&c);
 	PyErr_NTSTATUS_IS_ERR_RAISE(status);
 
 	/* Ignore read-only and share restrictions */
-	conn->read_only = false;
-	conn->share_access = SEC_RIGHTS_FILE_ALL;
-	talloc_set_destructor(conn, conn_free_wrapper);
-	return conn;
+	c->conn->read_only = false;
+	c->conn->share_access = SEC_RIGHTS_FILE_ALL;
+	return c->conn;
 }
 
 static int set_sys_acl_conn(const char *fname,
-- 
2.17.1


From 037e7275b37ebf8eaabbf768cb07d0b6dd5d58c0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 16:34:04 +0200
Subject: [PATCH 08/40] smbd: make use of create_conn_struct_tos() in
 get_nt_acl_no_snum()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/posix_acls.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index fb074772134a..70834d5fc7d7 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -4570,7 +4570,7 @@ NTSTATUS get_nt_acl_no_snum(TALLOC_CTX *ctx, const char *fname,
 				struct security_descriptor **sd)
 {
 	TALLOC_CTX *frame = talloc_stackframe();
-	connection_struct *conn;
+	struct conn_struct_tos *c = NULL;
 	NTSTATUS status = NT_STATUS_OK;
 	struct smb_filename *smb_fname = synthetic_smb_fname(talloc_tos(),
 						fname,
@@ -4588,14 +4588,11 @@ NTSTATUS get_nt_acl_no_snum(TALLOC_CTX *ctx, const char *fname,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = create_conn_struct(ctx,
-				server_event_context(),
-				server_messaging_context(),
-				&conn,
-				-1,
-				"/",
-				NULL);
-
+	status = create_conn_struct_tos(server_messaging_context(),
+					-1,
+					"/",
+					NULL,
+					&c);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0,("create_conn_struct returned %s.\n",
 			nt_errstr(status)));
@@ -4603,7 +4600,7 @@ NTSTATUS get_nt_acl_no_snum(TALLOC_CTX *ctx, const char *fname,
 		return status;
 	}
 
-	status = SMB_VFS_GET_NT_ACL(conn,
+	status = SMB_VFS_GET_NT_ACL(c->conn,
 				smb_fname,
 				security_info_wanted,
 				ctx,
@@ -4613,7 +4610,6 @@ NTSTATUS get_nt_acl_no_snum(TALLOC_CTX *ctx, const char *fname,
 			  nt_errstr(status)));
 	}
 
-	conn_free(conn);
 	TALLOC_FREE(frame);
 
 	return status;
-- 
2.17.1


From 18d706d9a7e269c11fd627291dd5cd898d37766b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 16:41:32 +0200
Subject: [PATCH 09/40] s3:rpc_server/fss: use talloc_stackframe() for
 temporary memory

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/rpc_server/fss/srv_fss_agent.c | 161 +++++++++++--------------
 1 file changed, 68 insertions(+), 93 deletions(-)

diff --git a/source3/rpc_server/fss/srv_fss_agent.c b/source3/rpc_server/fss/srv_fss_agent.c
index 0e5c82ec5e91..846b1047670c 100644
--- a/source3/rpc_server/fss/srv_fss_agent.c
+++ b/source3/rpc_server/fss/srv_fss_agent.c
@@ -144,6 +144,7 @@ static void fss_vfs_conn_destroy(struct connection_struct *conn);
 static bool snap_path_exists(TALLOC_CTX *ctx, struct messaging_context *msg_ctx,
 			     struct fss_sc *sc)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	SMB_STRUCT_STAT st;
 	struct connection_struct *conn = NULL;
 	struct smb_filename *smb_fname = NULL;
@@ -161,13 +162,13 @@ static bool snap_path_exists(TALLOC_CTX *ctx, struct messaging_context *msg_ctx,
 	}
 
 	share = sc->smaps->share_name;
-	snum = find_service(ctx, share, &service);
+	snum = find_service(frame, share, &service);
 
 	if ((snum == -1) || (service == NULL)) {
 		goto out;
 	}
 
-	status = fss_vfs_conn_create(ctx, server_event_context(),
+	status = fss_vfs_conn_create(frame, server_event_context(),
 				     msg_ctx, NULL, snum, &conn);
 
 	if(!NT_STATUS_IS_OK(status)) {
@@ -188,7 +189,7 @@ out:
 	if (conn) {
 		fss_vfs_conn_destroy(conn);
 	}
-	TALLOC_FREE(service);
+	TALLOC_FREE(frame);
 	return result;
 }
 
@@ -747,11 +748,7 @@ uint32_t _fss_AddToShadowCopySet(struct pipes_struct *p,
 	char *path_name;
 	struct connection_struct *conn;
 	NTSTATUS status;
-	TALLOC_CTX *tmp_ctx = talloc_new(p->mem_ctx);
-	if (tmp_ctx == NULL) {
-		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
-		goto err_out;
-	}
+	TALLOC_CTX *frame = talloc_stackframe();
 
 	if (!fss_permitted(p)) {
 		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
@@ -764,26 +761,26 @@ uint32_t _fss_AddToShadowCopySet(struct pipes_struct *p,
 		goto err_tmp_free;
 	}
 
-	status = fss_unc_parse(tmp_ctx, r->in.ShareName, NULL, &share);
+	status = fss_unc_parse(frame, r->in.ShareName, NULL, &share);
 	if (!NT_STATUS_IS_OK(status)) {
 		ret = fss_ntstatus_map(status);
 		goto err_tmp_free;
 	}
 
-	snum = find_service(tmp_ctx, share, &service);
+	snum = find_service(frame, share, &service);
 	if ((snum == -1) || (service == NULL)) {
 		DEBUG(0, ("share at %s not found\n", r->in.ShareName));
 		ret = HRES_ERROR_V(HRES_E_INVALIDARG);
 		goto err_tmp_free;
 	}
 
-	path_name = lp_path(tmp_ctx, snum);
+	path_name = lp_path(frame, snum);
 	if (path_name == NULL) {
 		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
 		goto err_tmp_free;
 	}
 
-	status = fss_vfs_conn_create(tmp_ctx, server_event_context(),
+	status = fss_vfs_conn_create(frame, server_event_context(),
 				     p->msg_ctx, p->session_info, snum, &conn);
 	if (!NT_STATUS_IS_OK(status)) {
 		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
@@ -796,7 +793,7 @@ uint32_t _fss_AddToShadowCopySet(struct pipes_struct *p,
 		goto err_tmp_free;
 	}
 
-	status = SMB_VFS_SNAP_CHECK_PATH(conn, tmp_ctx, path_name, &base_vol);
+	status = SMB_VFS_SNAP_CHECK_PATH(conn, frame, path_name, &base_vol);
 	unbecome_user();
 	fss_vfs_conn_destroy(conn);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -878,7 +875,7 @@ uint32_t _fss_AddToShadowCopySet(struct pipes_struct *p,
 	sc_set->state = FSS_SC_ADDED;
 	r->out.pShadowCopyId = &sc->id;
 
-	talloc_free(tmp_ctx);
+	TALLOC_FREE(frame);
 	return 0;
 
 err_sc_free:
@@ -886,8 +883,7 @@ err_sc_free:
 err_tmr_restart:
 	fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set, &fss_global.seq_tmr);
 err_tmp_free:
-	talloc_free(tmp_ctx);
-err_out:
+	TALLOC_FREE(frame);
 	return ret;
 }
 
@@ -899,28 +895,32 @@ static NTSTATUS commit_sc_with_conn(TALLOC_CTX *mem_ctx,
 				    char **base_path,
 				    char **snap_path)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	NTSTATUS status;
 	bool rw;
 	struct connection_struct *conn;
 	int snum;
 	char *service;
 
-	snum = find_service(mem_ctx, sc->smaps->share_name, &service);
+	snum = find_service(frame, sc->smaps->share_name, &service);
 	if ((snum == -1) || (service == NULL)) {
 		DEBUG(0, ("share at %s not found\n", sc->smaps->share_name));
+		TALLOC_FREE(frame);
 		return NT_STATUS_UNSUCCESSFUL;
 	}
 
-	status = fss_vfs_conn_create(mem_ctx,
+	status = fss_vfs_conn_create(frame,
 				     ev, msg_ctx, session_info,
 				     snum, &conn);
 	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(frame);
 		return status;
 	}
 
 	if (!become_user_by_session(conn, session_info)) {
 		DEBUG(0, ("failed to become user\n"));
 		fss_vfs_conn_destroy(conn);
+		TALLOC_FREE(frame);
 		return NT_STATUS_ACCESS_DENIED;
 	}
 	rw = ((sc->sc_set->context & ATTR_AUTO_RECOVERY) == ATTR_AUTO_RECOVERY);
@@ -932,9 +932,11 @@ static NTSTATUS commit_sc_with_conn(TALLOC_CTX *mem_ctx,
 	fss_vfs_conn_destroy(conn);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("snap create failed: %s\n", nt_errstr(status)));
+		TALLOC_FREE(frame);
 		return status;
 	}
 
+	TALLOC_FREE(frame);
 	return status;
 }
 
@@ -946,17 +948,11 @@ uint32_t _fss_CommitShadowCopySet(struct pipes_struct *p,
 	uint32_t commit_count;
 	NTSTATUS status;
 	NTSTATUS saved_status;
-	TALLOC_CTX *tmp_ctx;
+	TALLOC_CTX *frame = talloc_stackframe();
 
 	if (!fss_permitted(p)) {
 		status = NT_STATUS_ACCESS_DENIED;
-		goto err_out;
-	}
-
-	tmp_ctx = talloc_new(p->mem_ctx);
-	if (tmp_ctx == NULL) {
-		status = NT_STATUS_NO_MEMORY;
-		goto err_out;
+		goto err_tmp_free;
 	}
 
 	sc_set = sc_set_lookup(fss_global.sc_sets, &r->in.ShadowCopySetId);
@@ -978,7 +974,7 @@ uint32_t _fss_CommitShadowCopySet(struct pipes_struct *p,
 	for (sc = sc_set->scs; sc; sc = sc->next) {
 		char *base_path;
 		char *snap_path;
-		status = commit_sc_with_conn(tmp_ctx, server_event_context(),
+		status = commit_sc_with_conn(frame, server_event_context(),
 					     p->msg_ctx, p->session_info, sc,
 					     &base_path, &snap_path);
 		if (!NT_STATUS_IS_OK(status)) {
@@ -1012,7 +1008,7 @@ uint32_t _fss_CommitShadowCopySet(struct pipes_struct *p,
 
 	fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set,
 			 &fss_global.seq_tmr);
-	talloc_free(tmp_ctx);
+	TALLOC_FREE(frame);
 	return 0;
 
 err_state_revert:
@@ -1020,8 +1016,7 @@ err_state_revert:
 	fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set,
 			 &fss_global.seq_tmr);
 err_tmp_free:
-	talloc_free(tmp_ctx);
-err_out:
+	TALLOC_FREE(frame);
 	return fss_ntstatus_map(status);
 }
 
@@ -1156,10 +1151,7 @@ uint32_t _fss_ExposeShadowCopySet(struct pipes_struct *p,
 	struct smbconf_ctx *rconf_ctx;
 	sbcErr cerr;
 	char *fconf_path;
-	TALLOC_CTX *tmp_ctx = talloc_new(p->mem_ctx);
-	if (tmp_ctx == NULL) {
-		return HRES_ERROR_V(HRES_E_OUTOFMEMORY);
-	}
+	TALLOC_CTX *frame = talloc_stackframe();
 
 	if (!fss_permitted(p)) {
 		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
@@ -1186,19 +1178,19 @@ uint32_t _fss_ExposeShadowCopySet(struct pipes_struct *p,
 	 * definition may be located in either. The snapshot share definition
 	 * is always written to the registry.
 	 */
-	cerr = smbconf_init(tmp_ctx, &rconf_ctx, "registry");
+	cerr = smbconf_init(frame, &rconf_ctx, "registry");
 	if (!SBC_ERROR_IS_OK(cerr)) {
 		DEBUG(0, ("failed registry smbconf init: %s\n",
 			  sbcErrorString(cerr)));
 		ret = HRES_ERROR_V(HRES_E_FAIL);
 		goto err_tmr_restart;
 	}
-	fconf_path = talloc_asprintf(tmp_ctx, "file:%s", get_dyn_CONFIGFILE());
+	fconf_path = talloc_asprintf(frame, "file:%s", get_dyn_CONFIGFILE());
 	if (fconf_path == NULL) {
 		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
 		goto err_tmr_restart;
 	}
-	cerr = smbconf_init(tmp_ctx, &fconf_ctx, fconf_path);
+	cerr = smbconf_init(frame, &fconf_ctx, fconf_path);
 	if (!SBC_ERROR_IS_OK(cerr)) {
 		DEBUG(0, ("failed %s smbconf init: %s\n",
 			  fconf_path, sbcErrorString(cerr)));
@@ -1218,7 +1210,7 @@ uint32_t _fss_ExposeShadowCopySet(struct pipes_struct *p,
 	}
 
 	for (sc = sc_set->scs; sc; sc = sc->next) {
-		ret = fss_sc_expose(fconf_ctx, rconf_ctx, tmp_ctx, sc);
+		ret = fss_sc_expose(fconf_ctx, rconf_ctx, frame, sc);
 		if (ret) {
 			DEBUG(0,("failed to expose shadow copy of %s\n",
 				 sc->volume_name));
@@ -1252,7 +1244,7 @@ uint32_t _fss_ExposeShadowCopySet(struct pipes_struct *p,
 	}
 	/* start message sequence timer */
 	fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set, &fss_global.seq_tmr);
-	talloc_free(tmp_ctx);
+	TALLOC_FREE(frame);
 	return 0;
 
 err_cancel:
@@ -1261,7 +1253,7 @@ err_cancel:
 err_tmr_restart:
 	fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set, &fss_global.seq_tmr);
 err_out:
-	talloc_free(tmp_ctx);
+	TALLOC_FREE(frame);
 	return ret;
 }
 
@@ -1358,54 +1350,51 @@ uint32_t _fss_IsPathSupported(struct pipes_struct *p,
 	NTSTATUS status;
 	struct connection_struct *conn;
 	char *share;
-	TALLOC_CTX *tmp_ctx = talloc_new(p->mem_ctx);
-	if (tmp_ctx == NULL) {
-		return HRES_ERROR_V(HRES_E_OUTOFMEMORY);
-	}
+	TALLOC_CTX *frame = talloc_stackframe();
 
 	if (!fss_permitted(p)) {
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_ACCESSDENIED);
 	}
 
-	status = fss_unc_parse(tmp_ctx, r->in.ShareName, NULL, &share);
+	status = fss_unc_parse(frame, r->in.ShareName, NULL, &share);
 	if (!NT_STATUS_IS_OK(status)) {
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return fss_ntstatus_map(status);
 	}
 
-	snum = find_service(tmp_ctx, share, &service);
+	snum = find_service(frame, share, &service);
 	if ((snum == -1) || (service == NULL)) {
 		DEBUG(0, ("share at %s not found\n", r->in.ShareName));
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_INVALIDARG);
 	}
 
-	status = fss_vfs_conn_create(tmp_ctx, server_event_context(),
+	status = fss_vfs_conn_create(frame, server_event_context(),
 				     p->msg_ctx, p->session_info, snum, &conn);
 	if (!NT_STATUS_IS_OK(status)) {
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_ACCESSDENIED);
 	}
 	if (!become_user_by_session(conn, p->session_info)) {
 		DEBUG(0, ("failed to become user\n"));
-		talloc_free(tmp_ctx);
 		fss_vfs_conn_destroy(conn);
+		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_ACCESSDENIED);
 	}
-	status = SMB_VFS_SNAP_CHECK_PATH(conn, tmp_ctx,
-					 lp_path(tmp_ctx, snum),
+	status = SMB_VFS_SNAP_CHECK_PATH(conn, frame,
+					 lp_path(frame, snum),
 					 &base_vol);
 	unbecome_user();
 	fss_vfs_conn_destroy(conn);
 	if (!NT_STATUS_IS_OK(status)) {
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return FSRVP_E_NOT_SUPPORTED;
 	}
 
 	*r->out.OwnerMachineName = lp_netbios_name();
 	*r->out.SupportedByThisProvider = 1;
-	talloc_free(tmp_ctx);
+	TALLOC_FREE(frame);
 	return 0;
 }
 
@@ -1429,20 +1418,16 @@ uint32_t _fss_GetShareMapping(struct pipes_struct *p,
 	struct fss_sc_smap *sc_smap;
 	char *share;
 	struct fssagent_share_mapping_1 *sm_out;
-
-	TALLOC_CTX *tmp_ctx = talloc_new(p->mem_ctx);
-	if (tmp_ctx == NULL) {
-		return HRES_ERROR_V(HRES_E_OUTOFMEMORY);
-	}
+	TALLOC_CTX *frame = talloc_stackframe();
 
 	if (!fss_permitted(p)) {
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_ACCESSDENIED);
 	}
 
 	sc_set = sc_set_lookup(fss_global.sc_sets, &r->in.ShadowCopySetId);
 	if (sc_set == NULL) {
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_INVALIDARG);
 	}
 
@@ -1457,36 +1442,36 @@ uint32_t _fss_GetShareMapping(struct pipes_struct *p,
 	 || (sc_set->state == FSS_SC_ADDED)
 	 || (sc_set->state == FSS_SC_CREATING)
 	 || (sc_set->state == FSS_SC_COMMITED)) {
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return 0x80042311;	/* documented magic value */
 	}
 
 	sc = sc_lookup(sc_set->scs, &r->in.ShadowCopyId);
 	if (sc == NULL) {
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_INVALIDARG);
 	}
 
-	status = fss_unc_parse(tmp_ctx, r->in.ShareName, NULL, &share);
+	status = fss_unc_parse(frame, r->in.ShareName, NULL, &share);
 	if (!NT_STATUS_IS_OK(status)) {
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return fss_ntstatus_map(status);
 	}
 
 	sc_smap = sc_smap_lookup(sc->smaps, share);
 	if (sc_smap == NULL) {
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_INVALIDARG);
 	}
 
 	if (r->in.Level != 1) {
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_INVALIDARG);
 	}
 
 	sm_out = talloc_zero(p->mem_ctx, struct fssagent_share_mapping_1);
 	if (sm_out == NULL) {
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_OUTOFMEMORY);
 	}
 	sm_out->ShadowCopySetId = sc_set->id;
@@ -1496,13 +1481,13 @@ uint32_t _fss_GetShareMapping(struct pipes_struct *p,
 					       sc_smap->share_name);
 	if (sm_out->ShareNameUNC == NULL) {
 		talloc_free(sm_out);
-		talloc_free(tmp_ctx);
+		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_OUTOFMEMORY);
 	}
 	sm_out->ShadowCopyShareName = sc_smap->sc_share_name;
 	unix_to_nt_time(&sm_out->tstamp, sc->create_ts);
 	r->out.ShareMapping->ShareMapping1 = sm_out;
-	talloc_free(tmp_ctx);
+	TALLOC_FREE(frame);
 
 	/* reset msg sequence timer */
 	TALLOC_FREE(fss_global.seq_tmr);
@@ -1518,12 +1503,9 @@ static NTSTATUS sc_smap_unexpose(struct messaging_context *msg_ctx,
 	struct smbconf_ctx *conf_ctx;
 	sbcErr cerr;
 	bool is_modified = false;
-	TALLOC_CTX *tmp_ctx = talloc_new(sc_smap);
-	if (tmp_ctx == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
+	TALLOC_CTX *frame = talloc_stackframe();
 
-	cerr = smbconf_init(tmp_ctx, &conf_ctx, "registry");
+	cerr = smbconf_init(frame, &conf_ctx, "registry");
 	if (!SBC_ERROR_IS_OK(cerr)) {
 		DEBUG(0, ("failed registry smbconf init: %s\n",
 			  sbcErrorString(cerr)));
@@ -1588,14 +1570,14 @@ err_conf:
 	talloc_free(conf_ctx);
 	unbecome_root();
 err_tmp:
-	talloc_free(tmp_ctx);
+	TALLOC_FREE(frame);
 	return ret;
 
 err_cancel:
 	smbconf_transaction_cancel(conf_ctx);
 	talloc_free(conf_ctx);
 	unbecome_root();
-	talloc_free(tmp_ctx);
+	TALLOC_FREE(frame);
 	return ret;
 }
 
@@ -1607,20 +1589,14 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
 	struct fss_sc_smap *sc_smap;
 	char *share;
 	NTSTATUS status;
-	TALLOC_CTX *tmp_ctx;
+	TALLOC_CTX *frame = talloc_stackframe();
 	struct connection_struct *conn;
 	int snum;
 	char *service;
 
 	if (!fss_permitted(p)) {
 		status = NT_STATUS_ACCESS_DENIED;
-		goto err_out;
-	}
-
-	tmp_ctx = talloc_new(p->mem_ctx);
-	if (tmp_ctx == NULL) {
-		status = NT_STATUS_NO_MEMORY;
-		goto err_out;
+		goto err_tmp_free;
 	}
 
 	sc_set = sc_set_lookup(fss_global.sc_sets, &r->in.ShadowCopySetId);
@@ -1642,7 +1618,7 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
 		goto err_tmp_free;
 	}
 
-	status = fss_unc_parse(tmp_ctx, r->in.ShareName, NULL, &share);
+	status = fss_unc_parse(frame, r->in.ShareName, NULL, &share);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto err_tmp_free;
 	}
@@ -1670,14 +1646,14 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
 		goto err_tmp_free;
 	}
 
-	snum = find_service(tmp_ctx, sc_smap->share_name, &service);
+	snum = find_service(frame, sc_smap->share_name, &service);
 	if ((snum == -1) || (service == NULL)) {
 		DEBUG(0, ("share at %s not found\n", sc_smap->share_name));
 		status = NT_STATUS_UNSUCCESSFUL;
 		goto err_tmp_free;
 	}
 
-	status = fss_vfs_conn_create(tmp_ctx, server_event_context(),
+	status = fss_vfs_conn_create(frame, server_event_context(),
 				     p->msg_ctx, p->session_info, snum, &conn);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto err_tmp_free;
@@ -1688,7 +1664,7 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
 		goto err_conn_destroy;
 	}
 
-	status = SMB_VFS_SNAP_DELETE(conn, tmp_ctx, sc->volume_name,
+	status = SMB_VFS_SNAP_DELETE(conn, frame, sc->volume_name,
 				     sc->sc_path);
 	unbecome_user();
 	if (!NT_STATUS_IS_OK(status)) {
@@ -1725,8 +1701,7 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
 err_conn_destroy:
 	fss_vfs_conn_destroy(conn);
 err_tmp_free:
-	talloc_free(tmp_ctx);
-err_out:
+	talloc_free(frame);
 	return fss_ntstatus_map(status);
 }
 
-- 
2.17.1


From ed0348c3cccd9923fe5cf4fb4676d0c24d7b02ac Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:34:18 +0200
Subject: [PATCH 10/40] s3:rpc_server/fss: make use of create_conn_struct_tos()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/rpc_server/fss/srv_fss_agent.c | 72 +++++++-------------------
 1 file changed, 20 insertions(+), 52 deletions(-)

diff --git a/source3/rpc_server/fss/srv_fss_agent.c b/source3/rpc_server/fss/srv_fss_agent.c
index 846b1047670c..33cbca87d73f 100644
--- a/source3/rpc_server/fss/srv_fss_agent.c
+++ b/source3/rpc_server/fss/srv_fss_agent.c
@@ -132,13 +132,10 @@ static NTSTATUS fss_unc_parse(TALLOC_CTX *mem_ctx,
 	return NT_STATUS_OK;
 }
 
-static NTSTATUS fss_vfs_conn_create(TALLOC_CTX *mem_ctx,
-				    struct tevent_context *ev,
-				    struct messaging_context *msg_ctx,
+static NTSTATUS fss_conn_create_tos(struct messaging_context *msg_ctx,
 				    struct auth_session_info *session_info,
 				    int snum,
 				    struct connection_struct **conn_out);
-static void fss_vfs_conn_destroy(struct connection_struct *conn);
 
 /* test if system path exists */
 static bool snap_path_exists(TALLOC_CTX *ctx, struct messaging_context *msg_ctx,
@@ -168,9 +165,7 @@ static bool snap_path_exists(TALLOC_CTX *ctx, struct messaging_context *msg_ctx,
 		goto out;
 	}
 
-	status = fss_vfs_conn_create(frame, server_event_context(),
-				     msg_ctx, NULL, snum, &conn);
-
+	status = fss_conn_create_tos(msg_ctx, NULL, snum, &conn);
 	if(!NT_STATUS_IS_OK(status)) {
 		goto out;
 	}
@@ -186,9 +181,6 @@ static bool snap_path_exists(TALLOC_CTX *ctx, struct messaging_context *msg_ctx,
 	}
 	result = true;
 out:
-	if (conn) {
-		fss_vfs_conn_destroy(conn);
-	}
 	TALLOC_FREE(frame);
 	return result;
 }
@@ -289,45 +281,34 @@ out:
 	return status;
 }
 
-static NTSTATUS fss_vfs_conn_create(TALLOC_CTX *mem_ctx,
-				    struct tevent_context *ev,
-				    struct messaging_context *msg_ctx,
+static NTSTATUS fss_conn_create_tos(struct messaging_context *msg_ctx,
 				    struct auth_session_info *session_info,
 				    int snum,
 				    struct connection_struct **conn_out)
 {
-	struct connection_struct *conn = NULL;
+	struct conn_struct_tos *c = NULL;
 	NTSTATUS status;
 
-	status = create_conn_struct(mem_ctx, ev, msg_ctx, &conn,
-				    snum, lp_path(mem_ctx, snum),
-				    session_info);
+	status = create_conn_struct_tos(msg_ctx,
+					snum,
+					lp_path(talloc_tos(), snum),
+					session_info,
+					&c);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0,("failed to create conn for vfs: %s\n",
 			 nt_errstr(status)));
 		return status;
 	}
 
-	status = set_conn_force_user_group(conn, snum);
+	status = set_conn_force_user_group(c->conn, snum);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("failed set force user / group\n"));
-		goto err_free_conn;
+		TALLOC_FREE(c);
+		return status;
 	}
 
-	*conn_out = conn;
-
+	*conn_out = c->conn;
 	return NT_STATUS_OK;
-
-err_free_conn:
-	SMB_VFS_DISCONNECT(conn);
-	conn_free(conn);
-	return status;
-}
-
-static void fss_vfs_conn_destroy(struct connection_struct *conn)
-{
-	SMB_VFS_DISCONNECT(conn);
-	conn_free(conn);
 }
 
 static struct fss_sc_set *sc_set_lookup(struct fss_sc_set *sc_set_head,
@@ -780,22 +761,19 @@ uint32_t _fss_AddToShadowCopySet(struct pipes_struct *p,
 		goto err_tmp_free;
 	}
 
-	status = fss_vfs_conn_create(frame, server_event_context(),
-				     p->msg_ctx, p->session_info, snum, &conn);
+	status = fss_conn_create_tos(p->msg_ctx, p->session_info, snum, &conn);
 	if (!NT_STATUS_IS_OK(status)) {
 		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
 		goto err_tmp_free;
 	}
 	if (!become_user_by_session(conn, p->session_info)) {
 		DEBUG(0, ("failed to become user\n"));
-		fss_vfs_conn_destroy(conn);
 		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
 		goto err_tmp_free;
 	}
 
 	status = SMB_VFS_SNAP_CHECK_PATH(conn, frame, path_name, &base_vol);
 	unbecome_user();
-	fss_vfs_conn_destroy(conn);
 	if (!NT_STATUS_IS_OK(status)) {
 		ret = FSRVP_E_NOT_SUPPORTED;
 		goto err_tmp_free;
@@ -909,9 +887,7 @@ static NTSTATUS commit_sc_with_conn(TALLOC_CTX *mem_ctx,
 		return NT_STATUS_UNSUCCESSFUL;
 	}
 
-	status = fss_vfs_conn_create(frame,
-				     ev, msg_ctx, session_info,
-				     snum, &conn);
+	status = fss_conn_create_tos(msg_ctx, session_info, snum, &conn);
 	if (!NT_STATUS_IS_OK(status)) {
 		TALLOC_FREE(frame);
 		return status;
@@ -919,7 +895,6 @@ static NTSTATUS commit_sc_with_conn(TALLOC_CTX *mem_ctx,
 
 	if (!become_user_by_session(conn, session_info)) {
 		DEBUG(0, ("failed to become user\n"));
-		fss_vfs_conn_destroy(conn);
 		TALLOC_FREE(frame);
 		return NT_STATUS_ACCESS_DENIED;
 	}
@@ -929,7 +904,6 @@ static NTSTATUS commit_sc_with_conn(TALLOC_CTX *mem_ctx,
 				     &sc->create_ts, rw,
 				     base_path, snap_path);
 	unbecome_user();
-	fss_vfs_conn_destroy(conn);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("snap create failed: %s\n", nt_errstr(status)));
 		TALLOC_FREE(frame);
@@ -1370,15 +1344,13 @@ uint32_t _fss_IsPathSupported(struct pipes_struct *p,
 		return HRES_ERROR_V(HRES_E_INVALIDARG);
 	}
 
-	status = fss_vfs_conn_create(frame, server_event_context(),
-				     p->msg_ctx, p->session_info, snum, &conn);
+	status = fss_conn_create_tos(p->msg_ctx, p->session_info, snum, &conn);
 	if (!NT_STATUS_IS_OK(status)) {
 		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_ACCESSDENIED);
 	}
 	if (!become_user_by_session(conn, p->session_info)) {
 		DEBUG(0, ("failed to become user\n"));
-		fss_vfs_conn_destroy(conn);
 		TALLOC_FREE(frame);
 		return HRES_ERROR_V(HRES_E_ACCESSDENIED);
 	}
@@ -1386,7 +1358,6 @@ uint32_t _fss_IsPathSupported(struct pipes_struct *p,
 					 lp_path(frame, snum),
 					 &base_vol);
 	unbecome_user();
-	fss_vfs_conn_destroy(conn);
 	if (!NT_STATUS_IS_OK(status)) {
 		TALLOC_FREE(frame);
 		return FSRVP_E_NOT_SUPPORTED;
@@ -1653,22 +1624,21 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
 		goto err_tmp_free;
 	}
 
-	status = fss_vfs_conn_create(frame, server_event_context(),
-				     p->msg_ctx, p->session_info, snum, &conn);
+	status = fss_conn_create_tos(p->msg_ctx, p->session_info, snum, &conn);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto err_tmp_free;
 	}
 	if (!become_user_by_session(conn, p->session_info)) {
 		DEBUG(0, ("failed to become user\n"));
 		status = NT_STATUS_ACCESS_DENIED;
-		goto err_conn_destroy;
+		goto err_tmp_free;
 	}
 
 	status = SMB_VFS_SNAP_DELETE(conn, frame, sc->volume_name,
 				     sc->sc_path);
 	unbecome_user();
 	if (!NT_STATUS_IS_OK(status)) {
-		goto err_conn_destroy;
+		goto err_tmp_free;
 	}
 
 	/* XXX set timeout r->in.TimeOutInMilliseconds */
@@ -1698,10 +1668,8 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
 	}
 
 	status = NT_STATUS_OK;
-err_conn_destroy:
-	fss_vfs_conn_destroy(conn);
 err_tmp_free:
-	talloc_free(frame);
+	TALLOC_FREE(frame);
 	return fss_ntstatus_map(status);
 }
 
-- 
2.17.1


From 4f409859f8948d7ca01dd829c3239bfcab9cfb08 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:40:27 +0200
Subject: [PATCH 11/40] smbd: add an explicit talloc_stackframe() to
 {create,remove}_msdfs_link()

This makes further changes simpler.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/msdfs.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index d6fbe93fcbb7..aeae02ed7887 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -1428,6 +1428,7 @@ static bool junction_to_local_path(const struct junction_map *jucn,
 
 bool create_msdfs_link(const struct junction_map *jucn)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	char *path = NULL;
 	struct smb_filename *cwd_fname = NULL;
 	char *msdfs_link = NULL;
@@ -1438,6 +1439,7 @@ bool create_msdfs_link(const struct junction_map *jucn)
 	struct smb_filename *smb_fname = NULL;
 
 	if(!junction_to_local_path(jucn, &path, &conn, &cwd_fname)) {
+		TALLOC_FREE(frame);
 		return False;
 	}
 
@@ -1478,7 +1480,7 @@ bool create_msdfs_link(const struct junction_map *jucn)
 	DEBUG(5,("create_msdfs_link: Creating new msdfs link: %s -> %s\n",
 		path, msdfs_link));
 
-	smb_fname = synthetic_smb_fname(talloc_tos(),
+	smb_fname = synthetic_smb_fname(frame,
 				path,
 				NULL,
 				NULL,
@@ -1506,16 +1508,16 @@ bool create_msdfs_link(const struct junction_map *jucn)
 	ret = True;
 
 out:
-	TALLOC_FREE(smb_fname);
 	vfs_ChDir(conn, cwd_fname);
-	TALLOC_FREE(cwd_fname);
 	SMB_VFS_DISCONNECT(conn);
 	conn_free(conn);
+	TALLOC_FREE(frame);
 	return ret;
 }
 
 bool remove_msdfs_link(const struct junction_map *jucn)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	char *path = NULL;
 	struct smb_filename *cwd_fname = NULL;
 	connection_struct *conn;
@@ -1523,15 +1525,17 @@ bool remove_msdfs_link(const struct junction_map *jucn)
 	struct smb_filename *smb_fname;
 
 	if (!junction_to_local_path(jucn, &path, &conn, &cwd_fname)) {
+		TALLOC_FREE(frame);
 		return false;
 	}
 
-	smb_fname = synthetic_smb_fname(talloc_tos(),
+	smb_fname = synthetic_smb_fname(frame,
 					path,
 					NULL,
 					NULL,
 					0);
 	if (smb_fname == NULL) {
+		TALLOC_FREE(frame);
 		errno = ENOMEM;
 		return false;
 	}
@@ -1540,11 +1544,10 @@ bool remove_msdfs_link(const struct junction_map *jucn)
 		ret = True;
 	}
 
-	TALLOC_FREE(smb_fname);
 	vfs_ChDir(conn, cwd_fname);
-	TALLOC_FREE(cwd_fname);
 	SMB_VFS_DISCONNECT(conn);
 	conn_free(conn);
+	TALLOC_FREE(frame);
 	return ret;
 }
 
-- 
2.17.1


From 1ec56e7b0931b0467a716388fc140ac9954cbfa3 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:40:27 +0200
Subject: [PATCH 12/40] smbd: add an explicit talloc_stackframe() to
 get_referred_path()

This makes further changes simpler.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/msdfs.c | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index aeae02ed7887..c5e80b1ef989 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -1082,15 +1082,17 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
 			   int *consumedcntp,
 			   bool *self_referralp)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	struct connection_struct *conn;
 	char *targetpath = NULL;
 	int snum;
 	NTSTATUS status = NT_STATUS_NOT_FOUND;
 	bool dummy;
-	struct dfs_path *pdp = talloc(ctx, struct dfs_path);
+	struct dfs_path *pdp = talloc_zero(frame, struct dfs_path);
 	struct smb_filename *oldcwd_fname = NULL;
 
 	if (!pdp) {
+		TALLOC_FREE(frame);
 		return NT_STATUS_NO_MEMORY;
 	}
 
@@ -1099,13 +1101,14 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
 	status = parse_dfs_path(NULL, dfs_path, False, allow_broken_path,
 				pdp, &dummy);
 	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(frame);
 		return status;
 	}
 
 	jucn->service_name = talloc_strdup(ctx, pdp->servicename);
 	jucn->volume_name = talloc_strdup(ctx, pdp->reqpath);
 	if (!jucn->service_name || !jucn->volume_name) {
-		TALLOC_FREE(pdp);
+		TALLOC_FREE(frame);
 		return NT_STATUS_NO_MEMORY;
 	}
 
@@ -1114,15 +1117,17 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
 	if(snum < 0) {
 		char *service_name = NULL;
 		if ((snum = find_service(ctx, jucn->service_name, &service_name)) < 0) {
+			TALLOC_FREE(frame);
 			return NT_STATUS_NOT_FOUND;
 		}
 		if (!service_name) {
+			TALLOC_FREE(frame);
 			return NT_STATUS_NO_MEMORY;
 		}
 		TALLOC_FREE(jucn->service_name);
 		jucn->service_name = talloc_strdup(ctx, service_name);
 		if (!jucn->service_name) {
-			TALLOC_FREE(pdp);
+			TALLOC_FREE(frame);
 			return NT_STATUS_NO_MEMORY;
 		}
 	}
@@ -1131,7 +1136,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
 		DEBUG(3,("get_referred_path: |%s| in dfs path %s is not "
 			"a dfs root.\n",
 			pdp->servicename, dfs_path));
-		TALLOC_FREE(pdp);
+		TALLOC_FREE(frame);
 		return NT_STATUS_NOT_FOUND;
 	}
 
@@ -1149,7 +1154,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
 		int refcount;
 
 		if (*lp_msdfs_proxy(talloc_tos(), snum) == '\0') {
-			TALLOC_FREE(pdp);
+			TALLOC_FREE(frame);
 			return self_ref(ctx,
 					dfs_path,
 					jucn,
@@ -1162,36 +1167,34 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
  		 * the configured target share.
  		 */
 
-		tmp = talloc_asprintf(talloc_tos(), "msdfs:%s",
-				      lp_msdfs_proxy(talloc_tos(), snum));
+		tmp = talloc_asprintf(frame, "msdfs:%s",
+				      lp_msdfs_proxy(frame, snum));
 		if (tmp == NULL) {
-			TALLOC_FREE(pdp);
+			TALLOC_FREE(frame);
 			return NT_STATUS_NO_MEMORY;
 		}
 
 		if (!parse_msdfs_symlink(ctx, snum, tmp, &ref, &refcount)) {
-			TALLOC_FREE(tmp);
-			TALLOC_FREE(pdp);
+			TALLOC_FREE(frame);
 			return NT_STATUS_INVALID_PARAMETER;
 		}
-		TALLOC_FREE(tmp);
 		jucn->referral_count = refcount;
 		jucn->referral_list = ref;
 		*consumedcntp = strlen(dfs_path);
-		TALLOC_FREE(pdp);
+		TALLOC_FREE(frame);
 		return NT_STATUS_OK;
 	}
 
-	status = create_conn_struct_cwd(ctx,
+	status = create_conn_struct_cwd(frame,
 					server_event_context(),
 					server_messaging_context(),
 					&conn,
 					snum,
-					lp_path(talloc_tos(), snum),
+					lp_path(frame, snum),
 					NULL,
 					&oldcwd_fname);
 	if (!NT_STATUS_IS_OK(status)) {
-		TALLOC_FREE(pdp);
+		TALLOC_FREE(frame);
 		return status;
 	}
 
@@ -1205,7 +1208,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
 		conn->sconn->remote_address =
 			tsocket_address_copy(remote_address, conn->sconn);
 		if (conn->sconn->remote_address == NULL) {
-			TALLOC_FREE(pdp);
+			TALLOC_FREE(frame);
 			return NT_STATUS_NO_MEMORY;
 		}
 	}
@@ -1213,7 +1216,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
 		conn->sconn->local_address =
 			tsocket_address_copy(local_address, conn->sconn);
 		if (conn->sconn->local_address == NULL) {
-			TALLOC_FREE(pdp);
+			TALLOC_FREE(frame);
 			return NT_STATUS_NO_MEMORY;
 		}
 	}
@@ -1256,10 +1259,9 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
 	status = NT_STATUS_OK;
  err_exit:
 	vfs_ChDir(conn, oldcwd_fname);
-	TALLOC_FREE(oldcwd_fname);
 	SMB_VFS_DISCONNECT(conn);
 	conn_free(conn);
-	TALLOC_FREE(pdp);
+	TALLOC_FREE(frame);
 	return status;
 }
 
-- 
2.17.1


From b137f63352c8e0c3a75d5b57411dedb093165f5e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:40:27 +0200
Subject: [PATCH 13/40] smbd: add an explicit talloc_stackframe() to
 count_dfs_links()

This makes further changes simpler.

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

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index c5e80b1ef989..4e20358f5670 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -1559,18 +1559,20 @@ bool remove_msdfs_link(const struct junction_map *jucn)
 
 static int count_dfs_links(TALLOC_CTX *ctx, int snum)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	size_t cnt = 0;
 	DIR *dirp = NULL;
 	const char *dname = NULL;
 	char *talloced = NULL;
-	const char *connect_path = lp_path(talloc_tos(), snum);
-	const char *msdfs_proxy = lp_msdfs_proxy(talloc_tos(), snum);
+	const char *connect_path = lp_path(frame, snum);
+	const char *msdfs_proxy = lp_msdfs_proxy(frame, snum);
 	connection_struct *conn;
 	NTSTATUS status;
 	struct smb_filename *cwd_fname = NULL;
 	struct smb_filename *smb_fname = NULL;
 
 	if(*connect_path == '\0') {
+		TALLOC_FREE(frame);
 		return 0;
 	}
 
@@ -1578,7 +1580,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
 	 * Fake up a connection struct for the VFS layer.
 	 */
 
-	status = create_conn_struct_cwd(talloc_tos(),
+	status = create_conn_struct_cwd(frame,
 					server_event_context(),
 					server_messaging_context(),
 					&conn,
@@ -1589,6 +1591,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(3, ("create_conn_struct failed: %s\n",
 			  nt_errstr(status)));
+		TALLOC_FREE(frame);
 		return 0;
 	}
 
@@ -1600,7 +1603,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
 		goto out;
 	}
 
-	smb_fname = synthetic_smb_fname(talloc_tos(),
+	smb_fname = synthetic_smb_fname(frame,
 					".",
 					NULL,
 					NULL,
@@ -1618,7 +1621,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
 	while ((dname = vfs_readdirname(conn, dirp, NULL, &talloced))
 	       != NULL) {
 		struct smb_filename *smb_dname =
-			synthetic_smb_fname(talloc_tos(),
+			synthetic_smb_fname(frame,
 					dname,
 					NULL,
 					NULL,
@@ -1636,11 +1639,10 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
 	SMB_VFS_CLOSEDIR(conn,dirp);
 
 out:
-	TALLOC_FREE(smb_fname);
 	vfs_ChDir(conn, cwd_fname);
-	TALLOC_FREE(cwd_fname);
 	SMB_VFS_DISCONNECT(conn);
 	conn_free(conn);
+	TALLOC_FREE(frame);
 	return cnt;
 }
 
-- 
2.17.1


From cb38420a01345193e127930ed5097ea2685cf778 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:40:27 +0200
Subject: [PATCH 14/40] smbd: add an explicit talloc_stackframe() to
 form_junctions()

This makes further changes simpler.

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

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 4e20358f5670..53a4dd2dfcc9 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -1654,13 +1654,14 @@ static int form_junctions(TALLOC_CTX *ctx,
 				struct junction_map *jucn,
 				size_t jn_remain)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	size_t cnt = 0;
 	DIR *dirp = NULL;
 	const char *dname = NULL;
 	char *talloced = NULL;
-	const char *connect_path = lp_path(talloc_tos(), snum);
-	char *service_name = lp_servicename(talloc_tos(), snum);
-	const char *msdfs_proxy = lp_msdfs_proxy(talloc_tos(), snum);
+	const char *connect_path = lp_path(frame, snum);
+	char *service_name = lp_servicename(frame, snum);
+	const char *msdfs_proxy = lp_msdfs_proxy(frame, snum);
 	connection_struct *conn;
 	struct referral *ref = NULL;
 	struct smb_filename *cwd_fname = NULL;
@@ -1668,10 +1669,12 @@ static int form_junctions(TALLOC_CTX *ctx,
 	NTSTATUS status;
 
 	if (jn_remain == 0) {
+		TALLOC_FREE(frame);
 		return 0;
 	}
 
 	if(*connect_path == '\0') {
+		TALLOC_FREE(frame);
 		return 0;
 	}
 
@@ -1679,7 +1682,7 @@ static int form_junctions(TALLOC_CTX *ctx,
 	 * Fake up a connection struct for the VFS layer.
 	 */
 
-	status = create_conn_struct_cwd(ctx,
+	status = create_conn_struct_cwd(frame,
 					server_event_context(),
 					server_messaging_context(),
 					&conn,
@@ -1690,6 +1693,7 @@ static int form_junctions(TALLOC_CTX *ctx,
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(3, ("create_conn_struct failed: %s\n",
 			  nt_errstr(status)));
+		TALLOC_FREE(frame);
 		return 0;
 	}
 
@@ -1732,7 +1736,7 @@ static int form_junctions(TALLOC_CTX *ctx,
 		goto out;
 	}
 
-	smb_fname = synthetic_smb_fname(talloc_tos(),
+	smb_fname = synthetic_smb_fname(frame,
 					".",
 					NULL,
 					NULL,
@@ -1799,10 +1803,9 @@ out:
 		SMB_VFS_CLOSEDIR(conn,dirp);
 	}
 
-	TALLOC_FREE(smb_fname);
 	vfs_ChDir(conn, cwd_fname);
-	TALLOC_FREE(cwd_fname);
 	conn_free(conn);
+	TALLOC_FREE(frame);
 	return cnt;
 }
 
-- 
2.17.1


From 59c39fe069ac4e3cb8a9b51da0555ebf3bc90bff Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:55:02 +0200
Subject: [PATCH 15/40] smbd: convert junction_to_local_path() to use
 create_conn_struct_tos_cwd()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/msdfs.c | 48 +++++++++++++++++++-------------------------
 1 file changed, 21 insertions(+), 27 deletions(-)

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 53a4dd2dfcc9..cfa9e7602b71 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -1391,40 +1391,38 @@ bool create_junction(TALLOC_CTX *ctx,
  Forms a valid Unix pathname from the junction
  **********************************************************************/
 
-static bool junction_to_local_path(const struct junction_map *jucn,
-				   char **pp_path_out,
-				   connection_struct **conn_out,
-				   struct smb_filename **oldpath_fname)
+static bool junction_to_local_path_tos(const struct junction_map *jucn,
+				       char **pp_path_out,
+				       connection_struct **conn_out)
 {
+	struct conn_struct_tos *c = NULL;
 	int snum;
+	char *path_out = NULL;
 	NTSTATUS status;
 
 	snum = lp_servicenumber(jucn->service_name);
 	if(snum < 0) {
 		return False;
 	}
-	status = create_conn_struct_cwd(talloc_tos(),
-					server_event_context(),
-					server_messaging_context(),
-					conn_out,
-					snum,
-					lp_path(talloc_tos(), snum),
-					NULL,
-					oldpath_fname);
+	status = create_conn_struct_tos_cwd(server_messaging_context(),
+					    snum,
+					    lp_path(talloc_tos(), snum),
+					    NULL,
+					    &c);
 	if (!NT_STATUS_IS_OK(status)) {
 		return False;
 	}
 
-	*pp_path_out = talloc_asprintf(*conn_out,
+	path_out = talloc_asprintf(c,
 			"%s/%s",
 			lp_path(talloc_tos(), snum),
 			jucn->volume_name);
-	if (!*pp_path_out) {
-		vfs_ChDir(*conn_out, *oldpath_fname);
-		SMB_VFS_DISCONNECT(*conn_out);
-		conn_free(*conn_out);
+	if (path_out == NULL) {
+		TALLOC_FREE(c);
 		return False;
 	}
+	*pp_path_out = path_out;
+	*conn_out = c->conn;
 	return True;
 }
 
@@ -1432,15 +1430,16 @@ bool create_msdfs_link(const struct junction_map *jucn)
 {
 	TALLOC_CTX *frame = talloc_stackframe();
 	char *path = NULL;
-	struct smb_filename *cwd_fname = NULL;
 	char *msdfs_link = NULL;
 	connection_struct *conn;
 	int i=0;
 	bool insert_comma = False;
 	bool ret = False;
 	struct smb_filename *smb_fname = NULL;
+	bool ok;
 
-	if(!junction_to_local_path(jucn, &path, &conn, &cwd_fname)) {
+	ok = junction_to_local_path_tos(jucn, &path, &conn);
+	if (!ok) {
 		TALLOC_FREE(frame);
 		return False;
 	}
@@ -1510,9 +1509,6 @@ bool create_msdfs_link(const struct junction_map *jucn)
 	ret = True;
 
 out:
-	vfs_ChDir(conn, cwd_fname);
-	SMB_VFS_DISCONNECT(conn);
-	conn_free(conn);
 	TALLOC_FREE(frame);
 	return ret;
 }
@@ -1521,12 +1517,13 @@ bool remove_msdfs_link(const struct junction_map *jucn)
 {
 	TALLOC_CTX *frame = talloc_stackframe();
 	char *path = NULL;
-	struct smb_filename *cwd_fname = NULL;
 	connection_struct *conn;
 	bool ret = False;
 	struct smb_filename *smb_fname;
+	bool ok;
 
-	if (!junction_to_local_path(jucn, &path, &conn, &cwd_fname)) {
+	ok = junction_to_local_path_tos(jucn, &path, &conn);
+	if (!ok) {
 		TALLOC_FREE(frame);
 		return false;
 	}
@@ -1546,9 +1543,6 @@ bool remove_msdfs_link(const struct junction_map *jucn)
 		ret = True;
 	}
 
-	vfs_ChDir(conn, cwd_fname);
-	SMB_VFS_DISCONNECT(conn);
-	conn_free(conn);
 	TALLOC_FREE(frame);
 	return ret;
 }
-- 
2.17.1


From 58bcb0e9adb7e454107ac680068f159bce8f855e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:55:02 +0200
Subject: [PATCH 16/40] smbd: convert get_referred_path() to use
 create_conn_struct_tos_cwd()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/msdfs.c | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index cfa9e7602b71..fcf7b9c3dda0 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -1083,13 +1083,13 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
 			   bool *self_referralp)
 {
 	TALLOC_CTX *frame = talloc_stackframe();
-	struct connection_struct *conn;
+	struct conn_struct_tos *c = NULL;
+	struct connection_struct *conn = NULL;
 	char *targetpath = NULL;
 	int snum;
 	NTSTATUS status = NT_STATUS_NOT_FOUND;
 	bool dummy;
 	struct dfs_path *pdp = talloc_zero(frame, struct dfs_path);
-	struct smb_filename *oldcwd_fname = NULL;
 
 	if (!pdp) {
 		TALLOC_FREE(frame);
@@ -1185,18 +1185,16 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
 		return NT_STATUS_OK;
 	}
 
-	status = create_conn_struct_cwd(frame,
-					server_event_context(),
-					server_messaging_context(),
-					&conn,
-					snum,
-					lp_path(frame, snum),
-					NULL,
-					&oldcwd_fname);
+	status = create_conn_struct_tos_cwd(server_messaging_context(),
+					    snum,
+					    lp_path(frame, snum),
+					    NULL,
+					    &c);
 	if (!NT_STATUS_IS_OK(status)) {
 		TALLOC_FREE(frame);
 		return status;
 	}
+	conn = c->conn;
 
 	/*
 	 * TODO
@@ -1258,9 +1256,6 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
 
 	status = NT_STATUS_OK;
  err_exit:
-	vfs_ChDir(conn, oldcwd_fname);
-	SMB_VFS_DISCONNECT(conn);
-	conn_free(conn);
 	TALLOC_FREE(frame);
 	return status;
 }
-- 
2.17.1


From fbe4fc826038a2e35f9af9abc696ba20ec46147d Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:55:02 +0200
Subject: [PATCH 17/40] smbd: convert count_dfs_links() to use
 create_conn_struct_tos_cwd()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/msdfs.c | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index fcf7b9c3dda0..57e5b2072392 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -1555,9 +1555,9 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
 	char *talloced = NULL;
 	const char *connect_path = lp_path(frame, snum);
 	const char *msdfs_proxy = lp_msdfs_proxy(frame, snum);
-	connection_struct *conn;
+	struct conn_struct_tos *c = NULL;
+	connection_struct *conn = NULL;
 	NTSTATUS status;
-	struct smb_filename *cwd_fname = NULL;
 	struct smb_filename *smb_fname = NULL;
 
 	if(*connect_path == '\0') {
@@ -1569,20 +1569,18 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
 	 * Fake up a connection struct for the VFS layer.
 	 */
 
-	status = create_conn_struct_cwd(frame,
-					server_event_context(),
-					server_messaging_context(),
-					&conn,
-					snum,
-					connect_path,
-					NULL,
-					&cwd_fname);
+	status = create_conn_struct_tos_cwd(server_messaging_context(),
+					    snum,
+					    connect_path,
+					    NULL,
+					    &c);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(3, ("create_conn_struct failed: %s\n",
 			  nt_errstr(status)));
 		TALLOC_FREE(frame);
 		return 0;
 	}
+	conn = c->conn;
 
 	/* Count a link for the msdfs root - convention */
 	cnt = 1;
@@ -1628,9 +1626,6 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
 	SMB_VFS_CLOSEDIR(conn,dirp);
 
 out:
-	vfs_ChDir(conn, cwd_fname);
-	SMB_VFS_DISCONNECT(conn);
-	conn_free(conn);
 	TALLOC_FREE(frame);
 	return cnt;
 }
-- 
2.17.1


From 24fd88fef84fd001df68dcab1f6fc4934e2c6df2 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:55:02 +0200
Subject: [PATCH 18/40] smbd: convert form_junctions() to use
 create_conn_struct_tos_cwd()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/msdfs.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 57e5b2072392..18fae96f2e58 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -1646,9 +1646,9 @@ static int form_junctions(TALLOC_CTX *ctx,
 	const char *connect_path = lp_path(frame, snum);
 	char *service_name = lp_servicename(frame, snum);
 	const char *msdfs_proxy = lp_msdfs_proxy(frame, snum);
-	connection_struct *conn;
+	struct conn_struct_tos *c = NULL;
+	connection_struct *conn = NULL;
 	struct referral *ref = NULL;
-	struct smb_filename *cwd_fname = NULL;
 	struct smb_filename *smb_fname = NULL;
 	NTSTATUS status;
 
@@ -1666,20 +1666,18 @@ static int form_junctions(TALLOC_CTX *ctx,
 	 * Fake up a connection struct for the VFS layer.
 	 */
 
-	status = create_conn_struct_cwd(frame,
-					server_event_context(),
-					server_messaging_context(),
-					&conn,
-					snum,
-					connect_path,
-					NULL,
-					&cwd_fname);
+	status = create_conn_struct_tos_cwd(server_messaging_context(),
+					    snum,
+					    connect_path,
+					    NULL,
+					    &c);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(3, ("create_conn_struct failed: %s\n",
 			  nt_errstr(status)));
 		TALLOC_FREE(frame);
 		return 0;
 	}
+	conn = c->conn;
 
 	/* form a junction for the msdfs root - convention
 	   DO NOT REMOVE THIS: NT clients will not work with us
@@ -1787,8 +1785,6 @@ out:
 		SMB_VFS_CLOSEDIR(conn,dirp);
 	}
 
-	vfs_ChDir(conn, cwd_fname);
-	conn_free(conn);
 	TALLOC_FREE(frame);
 	return cnt;
 }
-- 
2.17.1


From a8db5fce195e3c1fac9651dddff2fa0ede0ec8ef Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:40:27 +0200
Subject: [PATCH 19/40] s3:rpc_server/srvsvc: add an explicit
 talloc_stackframe() to _srvsvc_NetGetFileSecurity()

This makes further changes simpler.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
index c25abf01ac97..3eb9734507dd 100644
--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
@@ -2314,6 +2314,7 @@ WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
 				  struct srvsvc_NetGetFileSecurity *r)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	struct smb_filename *smb_fname = NULL;
 	size_t sd_size;
 	char *servicename = NULL;
@@ -2333,7 +2334,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
 		werr = WERR_NERR_NETNAMENOTFOUND;
 		goto error_exit;
 	}
-	snum = find_service(talloc_tos(), r->in.share, &servicename);
+	snum = find_service(frame, r->in.share, &servicename);
 	if (!servicename) {
 		werr = WERR_NOT_ENOUGH_MEMORY;
 		goto error_exit;
@@ -2344,11 +2345,11 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
 		goto error_exit;
 	}
 
-	nt_status = create_conn_struct_cwd(talloc_tos(),
+	nt_status = create_conn_struct_cwd(frame,
 					   server_event_context(),
 					   server_messaging_context(),
 					   &conn,
-					   snum, lp_path(talloc_tos(), snum),
+					   snum, lp_path(frame, snum),
 					   p->session_info, &oldcwd_fname);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(10, ("create_conn_struct failed: %s\n",
@@ -2357,7 +2358,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
 		goto error_exit;
 	}
 
-	nt_status = filename_convert(talloc_tos(),
+	nt_status = filename_convert(frame,
 					conn,
 					r->in.file,
 					ucf_flags,
@@ -2434,7 +2435,6 @@ error_exit:
 
 	if (oldcwd_fname) {
                 vfs_ChDir(conn, oldcwd_fname);
-                TALLOC_FREE(oldcwd_fname);
 	}
 
 	if (conn) {
@@ -2442,8 +2442,7 @@ error_exit:
 		conn_free(conn);
 	}
 
-	TALLOC_FREE(smb_fname);
-
+	TALLOC_FREE(frame);
 	return werr;
 }
 
-- 
2.17.1


From 6247d2a5bf02b0a5cb0e13aad19cb87d806b2ebe Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:40:27 +0200
Subject: [PATCH 20/40] s3:rpc_server/srvsvc: add an explicit
 talloc_stackframe() to _srvsvc_NetSetFileSecurity()

This makes further changes simpler.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
index 3eb9734507dd..15bfdafa024a 100644
--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
@@ -2454,6 +2454,7 @@ error_exit:
 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
 				  struct srvsvc_NetSetFileSecurity *r)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	struct smb_filename *smb_fname = NULL;
 	char *servicename = NULL;
 	files_struct *fsp = NULL;
@@ -2474,7 +2475,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
 		goto error_exit;
 	}
 
-	snum = find_service(talloc_tos(), r->in.share, &servicename);
+	snum = find_service(frame, r->in.share, &servicename);
 	if (!servicename) {
 		werr = WERR_NOT_ENOUGH_MEMORY;
 		goto error_exit;
@@ -2486,11 +2487,11 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
 		goto error_exit;
 	}
 
-	nt_status = create_conn_struct_cwd(talloc_tos(),
+	nt_status = create_conn_struct_cwd(frame,
 					   server_event_context(),
 					   server_messaging_context(),
 					   &conn,
-					   snum, lp_path(talloc_tos(), snum),
+					   snum, lp_path(frame, snum),
 					   p->session_info, &oldcwd_fname);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(10, ("create_conn_struct failed: %s\n",
@@ -2499,7 +2500,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
 		goto error_exit;
 	}
 
-	nt_status = filename_convert(talloc_tos(),
+	nt_status = filename_convert(frame,
 					conn,
 					r->in.file,
 					ucf_flags,
@@ -2559,7 +2560,6 @@ error_exit:
 
 	if (oldcwd_fname) {
 		vfs_ChDir(conn, oldcwd_fname);
-		TALLOC_FREE(oldcwd_fname);
 	}
 
 	if (conn) {
@@ -2567,8 +2567,7 @@ error_exit:
 		conn_free(conn);
 	}
 
-	TALLOC_FREE(smb_fname);
-
+	TALLOC_FREE(frame);
 	return werr;
 }
 
-- 
2.17.1


From 8229f1d759620ce252bcb0d463c30df4c711f97b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:55:02 +0200
Subject: [PATCH 21/40] s3:rpc_server/srvsvc: convert form_junctions() to use
 _srvsvc_NetGetFileSecurity()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
index 15bfdafa024a..e11471e345ac 100644
--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
@@ -2321,11 +2321,11 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
 	SMB_STRUCT_STAT st;
 	NTSTATUS nt_status;
 	WERROR werr;
+	struct conn_struct_tos *c = NULL;
 	connection_struct *conn = NULL;
 	struct sec_desc_buf *sd_buf = NULL;
 	files_struct *fsp = NULL;
 	int snum;
-	struct smb_filename *oldcwd_fname = NULL;
 	uint32_t ucf_flags = 0;
 
 	ZERO_STRUCT(st);
@@ -2345,18 +2345,18 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
 		goto error_exit;
 	}
 
-	nt_status = create_conn_struct_cwd(frame,
-					   server_event_context(),
-					   server_messaging_context(),
-					   &conn,
-					   snum, lp_path(frame, snum),
-					   p->session_info, &oldcwd_fname);
+	nt_status = create_conn_struct_tos_cwd(server_messaging_context(),
+					       snum,
+					       lp_path(frame, snum),
+					       p->session_info,
+					       &c);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(10, ("create_conn_struct failed: %s\n",
 			   nt_errstr(nt_status)));
 		werr = ntstatus_to_werror(nt_status);
 		goto error_exit;
 	}
+	conn = c->conn;
 
 	nt_status = filename_convert(frame,
 					conn,
@@ -2433,15 +2433,6 @@ error_exit:
 		close_file(NULL, fsp, NORMAL_CLOSE);
 	}
 
-	if (oldcwd_fname) {
-                vfs_ChDir(conn, oldcwd_fname);
-	}
-
-	if (conn) {
-		SMB_VFS_DISCONNECT(conn);
-		conn_free(conn);
-	}
-
 	TALLOC_FREE(frame);
 	return werr;
 }
-- 
2.17.1


From d4c08b2b88cae66f59f01fdb0614ef694ff08664 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:55:02 +0200
Subject: [PATCH 22/40] s3:rpc_server/srvsvc: convert form_junctions() to use
 _srvsvc_NetSetFileSecurity()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
index e11471e345ac..e1963a40a0ce 100644
--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
@@ -2452,9 +2452,9 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
 	SMB_STRUCT_STAT st;
 	NTSTATUS nt_status;
 	WERROR werr;
+	struct conn_struct_tos *c = NULL;
 	connection_struct *conn = NULL;
 	int snum;
-	struct smb_filename *oldcwd_fname = NULL;
 	struct security_descriptor *psd = NULL;
 	uint32_t security_info_sent = 0;
 	uint32_t ucf_flags = 0;
@@ -2478,18 +2478,18 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
 		goto error_exit;
 	}
 
-	nt_status = create_conn_struct_cwd(frame,
-					   server_event_context(),
-					   server_messaging_context(),
-					   &conn,
-					   snum, lp_path(frame, snum),
-					   p->session_info, &oldcwd_fname);
+	nt_status = create_conn_struct_tos_cwd(server_messaging_context(),
+					       snum,
+					       lp_path(frame, snum),
+					       p->session_info,
+					       &c);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(10, ("create_conn_struct failed: %s\n",
 			   nt_errstr(nt_status)));
 		werr = ntstatus_to_werror(nt_status);
 		goto error_exit;
 	}
+	conn = c->conn;
 
 	nt_status = filename_convert(frame,
 					conn,
@@ -2549,15 +2549,6 @@ error_exit:
 		close_file(NULL, fsp, NORMAL_CLOSE);
 	}
 
-	if (oldcwd_fname) {
-		vfs_ChDir(conn, oldcwd_fname);
-	}
-
-	if (conn) {
-		SMB_VFS_DISCONNECT(conn);
-		conn_free(conn);
-	}
-
 	TALLOC_FREE(frame);
 	return werr;
 }
-- 
2.17.1


From d9d7400f59808db8b9ca4bd01021abd054ab22bb Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:40:27 +0200
Subject: [PATCH 23/40] printing: add more 'const' to read only input pointers

This makes it clearer that they won't be changed.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/include/nt_printing.h  |  8 ++++----
 source3/printing/nt_printing.c | 12 ++++++------
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h
index 688c6b9969e3..f01ffe5b32ff 100644
--- a/source3/include/nt_printing.h
+++ b/source3/include/nt_printing.h
@@ -164,13 +164,13 @@ bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
 bool delete_driver_files(const struct auth_session_info *server_info,
 			 const struct spoolss_DriverInfo8 *r);
 
-WERROR move_driver_to_download_area(struct auth_session_info *session_info,
-				    struct spoolss_AddDriverInfoCtr *r,
+WERROR move_driver_to_download_area(const struct auth_session_info *session_info,
+				    const struct spoolss_AddDriverInfoCtr *r,
 				    const char *driver_directory);
 
 WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
-			      struct auth_session_info *session_info,
-			      struct spoolss_AddDriverInfoCtr *r,
+			      const struct auth_session_info *session_info,
+			      const struct spoolss_AddDriverInfoCtr *r,
 			      uint32_t flags,
 			      const char **driver_directory);
 
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 1639bfd44066..52bba6fcb3d7 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -980,7 +980,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
 /****************************************************************************
 Determine the correct cVersion associated with an architecture and driver
 ****************************************************************************/
-static uint32_t get_correct_cversion(struct auth_session_info *session_info,
+static uint32_t get_correct_cversion(const struct auth_session_info *session_info,
 				   const char *architecture,
 				   const char *driverpath_in,
 				   const char *driver_directory,
@@ -1191,7 +1191,7 @@ static uint32_t get_correct_cversion(struct auth_session_info *session_info,
 } while (0);
 
 static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
-					   struct auth_session_info *session_info,
+					   const struct auth_session_info *session_info,
 					   const char *architecture,
 					   const char **driver_path,
 					   const char **data_file,
@@ -1306,8 +1306,8 @@ static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
 ****************************************************************************/
 
 WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
-			      struct auth_session_info *session_info,
-			      struct spoolss_AddDriverInfoCtr *r,
+			      const struct auth_session_info *session_info,
+			      const struct spoolss_AddDriverInfoCtr *r,
 			      uint32_t flags,
 			      const char **driver_directory)
 {
@@ -1472,8 +1472,8 @@ static WERROR move_driver_file_to_download_area(TALLOC_CTX *mem_ctx,
 	return ret;
 }
 
-WERROR move_driver_to_download_area(struct auth_session_info *session_info,
-				    struct spoolss_AddDriverInfoCtr *r,
+WERROR move_driver_to_download_area(const struct auth_session_info *session_info,
+				    const struct spoolss_AddDriverInfoCtr *r,
 				    const char *driver_directory)
 {
 	struct spoolss_AddDriverInfo3 *driver;
-- 
2.17.1


From 3f6653cdeea7d5e8e0a7ec2c848b185337fc83ae Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:40:27 +0200
Subject: [PATCH 24/40] printing: add an explicit talloc_stackframe() to
 get_correct_cversion()

This makes further changes simpler.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/printing/nt_printing.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 52bba6fcb3d7..5c4488009265 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -986,6 +986,7 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
 				   const char *driver_directory,
 				   WERROR *perr)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	int cversion = -1;
 	NTSTATUS          nt_status;
 	struct smb_filename *smb_fname = NULL;
@@ -1003,6 +1004,7 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
 	if (strcmp(architecture, SPL_ARCH_WIN40) == 0) {
 		DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
 		*perr = WERR_OK;
+		TALLOC_FREE(frame);
 		return 0;
 	}
 
@@ -1010,26 +1012,30 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
 	if (strcmp(architecture, SPL_ARCH_X64) == 0) {
 		DEBUG(10,("get_correct_cversion: Driver is x64, cversion = 3\n"));
 		*perr = WERR_OK;
+		TALLOC_FREE(frame);
 		return 3;
 	}
 
-	printdollar_snum = find_service(talloc_tos(), "print$", &printdollar);
+	printdollar_snum = find_service(frame, "print$", &printdollar);
 	if (!printdollar) {
 		*perr = WERR_NOT_ENOUGH_MEMORY;
+		TALLOC_FREE(frame);
 		return -1;
 	}
 	if (printdollar_snum == -1) {
 		*perr = WERR_BAD_NET_NAME;
+		TALLOC_FREE(frame);
 		return -1;
 	}
 
-	printdollar_path = lp_path(talloc_tos(), printdollar_snum);
+	printdollar_path = lp_path(frame, printdollar_snum);
 	if (printdollar_path == NULL) {
 		*perr = WERR_NOT_ENOUGH_MEMORY;
+		TALLOC_FREE(frame);
 		return -1;
 	}
 
-	working_dir = talloc_asprintf(talloc_tos(),
+	working_dir = talloc_asprintf(frame,
 				      "%s/%s",
 				      printdollar_path,
 				      architecture);
@@ -1038,13 +1044,13 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
 	 * directory, switch to the driver directory.
 	 */
 	if (driver_directory != NULL) {
-		working_dir = talloc_asprintf(talloc_tos(), "%s/%s/%s",
+		working_dir = talloc_asprintf(frame, "%s/%s/%s",
 					      printdollar_path,
 					      architecture,
 					      driver_directory);
 	}
 
-	nt_status = create_conn_struct_cwd(talloc_tos(),
+	nt_status = create_conn_struct_cwd(frame,
 					   server_event_context(),
 					   server_messaging_context(),
 					   &conn,
@@ -1055,6 +1061,7 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
 		DEBUG(0,("get_correct_cversion: create_conn_struct "
 			 "returned %s\n", nt_errstr(nt_status)));
 		*perr = ntstatus_to_werror(nt_status);
+		TALLOC_FREE(frame);
 		return -1;
 	}
 
@@ -1163,13 +1170,11 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
  error_exit:
 	unbecome_user();
  error_free_conn:
-	TALLOC_FREE(smb_fname);
 	if (fsp != NULL) {
 		close_file(NULL, fsp, NORMAL_CLOSE);
 	}
 	if (conn != NULL) {
 		vfs_ChDir(conn, oldcwd_fname);
-		TALLOC_FREE(oldcwd_fname);
 		SMB_VFS_DISCONNECT(conn);
 		conn_free(conn);
 	}
@@ -1177,6 +1182,7 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
 		cversion = -1;
 	}
 
+	TALLOC_FREE(frame);
 	return cversion;
 }
 
-- 
2.17.1


From 29d7e6ec8483362c242af1f3c8baa80854aa992c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:40:27 +0200
Subject: [PATCH 25/40] printing: add an explicit talloc_stackframe() to
 move_driver_to_download_area()

This makes further changes simpler.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/printing/nt_printing.c | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 5c4488009265..62ce57527477 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1482,6 +1482,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
 				    const struct spoolss_AddDriverInfoCtr *r,
 				    const char *driver_directory)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	struct spoolss_AddDriverInfo3 *driver;
 	struct spoolss_AddDriverInfo3 converted_driver;
 	const char *short_architecture;
@@ -1490,7 +1491,6 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
 	connection_struct *conn = NULL;
 	NTSTATUS nt_status;
 	int i;
-	TALLOC_CTX *ctx = talloc_tos();
 	int ver = 0;
 	struct smb_filename *oldcwd_fname = NULL;
 	char *printdollar = NULL;
@@ -1511,33 +1511,38 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
 		break;
 	default:
 		DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)r->level));
+		TALLOC_FREE(frame);
 		return WERR_INVALID_LEVEL;
 	}
 
 	short_architecture = get_short_archi(driver->architecture);
 	if (!short_architecture) {
+		TALLOC_FREE(frame);
 		return WERR_UNKNOWN_PRINTER_DRIVER;
 	}
 
-	printdollar_snum = find_service(ctx, "print$", &printdollar);
+	printdollar_snum = find_service(frame, "print$", &printdollar);
 	if (!printdollar) {
+		TALLOC_FREE(frame);
 		return WERR_NOT_ENOUGH_MEMORY;
 	}
 	if (printdollar_snum == -1) {
+		TALLOC_FREE(frame);
 		return WERR_BAD_NET_NAME;
 	}
 
-	nt_status = create_conn_struct_cwd(talloc_tos(),
+	nt_status = create_conn_struct_cwd(frame,
 					   server_event_context(),
 					   server_messaging_context(),
 					   &conn,
 					   printdollar_snum,
-					   lp_path(talloc_tos(), printdollar_snum),
+					   lp_path(frame, printdollar_snum),
 					   session_info, &oldcwd_fname);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0,("move_driver_to_download_area: create_conn_struct "
 			 "returned %s\n", nt_errstr(nt_status)));
 		err = ntstatus_to_werror(nt_status);
+		TALLOC_FREE(frame);
 		return err;
 	}
 
@@ -1554,7 +1559,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
 		goto err_free_conn;
 	}
 
-	new_dir = talloc_asprintf(ctx,
+	new_dir = talloc_asprintf(frame,
 				"%s/%d",
 				short_architecture,
 				driver->version);
@@ -1600,7 +1605,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
 
 	if (driver->driver_path && strlen(driver->driver_path)) {
 
-		err = move_driver_file_to_download_area(ctx,
+		err = move_driver_file_to_download_area(frame,
 							conn,
 							driver->driver_path,
 							short_architecture,
@@ -1615,7 +1620,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
 	if (driver->data_file && strlen(driver->data_file)) {
 		if (!strequal(driver->data_file, driver->driver_path)) {
 
-			err = move_driver_file_to_download_area(ctx,
+			err = move_driver_file_to_download_area(frame,
 								conn,
 								driver->data_file,
 								short_architecture,
@@ -1632,7 +1637,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
 		if (!strequal(driver->config_file, driver->driver_path) &&
 		    !strequal(driver->config_file, driver->data_file)) {
 
-			err = move_driver_file_to_download_area(ctx,
+			err = move_driver_file_to_download_area(frame,
 								conn,
 								driver->config_file,
 								short_architecture,
@@ -1650,7 +1655,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
 		    !strequal(driver->help_file, driver->data_file) &&
 		    !strequal(driver->help_file, driver->config_file)) {
 
-			err = move_driver_file_to_download_area(ctx,
+			err = move_driver_file_to_download_area(frame,
 								conn,
 								driver->help_file,
 								short_architecture,
@@ -1676,7 +1681,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
 					}
 				}
 
-				err = move_driver_file_to_download_area(ctx,
+				err = move_driver_file_to_download_area(frame,
 									conn,
 									driver->dependent_files->string[i],
 									short_architecture,
@@ -1695,15 +1700,13 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
  err_exit:
 	unbecome_user();
  err_free_conn:
-	TALLOC_FREE(smb_dname);
-
 	if (conn != NULL) {
 		vfs_ChDir(conn, oldcwd_fname);
-		TALLOC_FREE(oldcwd_fname);
 		SMB_VFS_DISCONNECT(conn);
 		conn_free(conn);
 	}
 
+	TALLOC_FREE(frame);
 	return err;
 }
 
-- 
2.17.1


From 850204cc50a1d4267ef928d8f565ff4956f7f9ba Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:40:27 +0200
Subject: [PATCH 26/40] printing: add an explicit talloc_stackframe() to
 delete_driver_files()

This makes further changes simpler.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/printing/nt_printing.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 62ce57527477..9d1a18213cbd 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -2053,6 +2053,7 @@ err_out:
 bool delete_driver_files(const struct auth_session_info *session_info,
 			 const struct spoolss_DriverInfo8 *r)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	const char *short_arch;
 	connection_struct *conn;
 	NTSTATUS nt_status;
@@ -2062,30 +2063,34 @@ bool delete_driver_files(const struct auth_session_info *session_info,
 	bool ret = false;
 
 	if (!r) {
+		TALLOC_FREE(frame);
 		return false;
 	}
 
 	DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n",
 		r->driver_name, r->version));
 
-	printdollar_snum = find_service(talloc_tos(), "print$", &printdollar);
+	printdollar_snum = find_service(frame, "print$", &printdollar);
 	if (!printdollar) {
+		TALLOC_FREE(frame);
 		return false;
 	}
 	if (printdollar_snum == -1) {
+		TALLOC_FREE(frame);
 		return false;
 	}
 
-	nt_status = create_conn_struct_cwd(talloc_tos(),
+	nt_status = create_conn_struct_cwd(frame,
 					   server_event_context(),
 					   server_messaging_context(),
 					   &conn,
 					   printdollar_snum,
-					   lp_path(talloc_tos(), printdollar_snum),
+					   lp_path(frame, printdollar_snum),
 					   session_info, &oldcwd_fname);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0,("delete_driver_files: create_conn_struct "
 			 "returned %s\n", nt_errstr(nt_status)));
+		TALLOC_FREE(frame);
 		return false;
 	}
 
@@ -2152,10 +2157,10 @@ bool delete_driver_files(const struct auth_session_info *session_info,
  err_free_conn:
 	if (conn != NULL) {
 		vfs_ChDir(conn, oldcwd_fname);
-		TALLOC_FREE(oldcwd_fname);
 		SMB_VFS_DISCONNECT(conn);
 		conn_free(conn);
 	}
+	TALLOC_FREE(frame);
 	return ret;
 }
 
-- 
2.17.1


From fe68f1ee6d226371bb530a8e45391521b2be2149 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:55:02 +0200
Subject: [PATCH 27/40] printing: convert get_correct_cversion() to use
 create_conn_struct_tos_cwd()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/printing/nt_printing.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 9d1a18213cbd..bda72f88dd28 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -991,8 +991,8 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
 	NTSTATUS          nt_status;
 	struct smb_filename *smb_fname = NULL;
 	files_struct      *fsp = NULL;
+	struct conn_struct_tos *c = NULL;
 	connection_struct *conn = NULL;
-	struct smb_filename *oldcwd_fname = NULL;
 	char *printdollar = NULL;
 	char *printdollar_path = NULL;
 	char *working_dir = NULL;
@@ -1050,13 +1050,11 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
 					      driver_directory);
 	}
 
-	nt_status = create_conn_struct_cwd(frame,
-					   server_event_context(),
-					   server_messaging_context(),
-					   &conn,
-					   printdollar_snum,
-					   working_dir,
-					   session_info, &oldcwd_fname);
+	nt_status = create_conn_struct_tos_cwd(server_messaging_context(),
+					       printdollar_snum,
+					       working_dir,
+					       session_info,
+					       &c);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0,("get_correct_cversion: create_conn_struct "
 			 "returned %s\n", nt_errstr(nt_status)));
@@ -1064,6 +1062,7 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
 		TALLOC_FREE(frame);
 		return -1;
 	}
+	conn = c->conn;
 
 	nt_status = set_conn_force_user_group(conn, printdollar_snum);
 	if (!NT_STATUS_IS_OK(nt_status)) {
@@ -1173,11 +1172,6 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
 	if (fsp != NULL) {
 		close_file(NULL, fsp, NORMAL_CLOSE);
 	}
-	if (conn != NULL) {
-		vfs_ChDir(conn, oldcwd_fname);
-		SMB_VFS_DISCONNECT(conn);
-		conn_free(conn);
-	}
 	if (!W_ERROR_IS_OK(*perr)) {
 		cversion = -1;
 	}
-- 
2.17.1


From 0b47e52df704ff0b05d26256bc040c4b350b4efe Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:55:02 +0200
Subject: [PATCH 28/40] printing: convert move_driver_to_download_area() to use
 create_conn_struct_tos_cwd()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/printing/nt_printing.c | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index bda72f88dd28..d0525e13c99a 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1482,11 +1482,11 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
 	const char *short_architecture;
 	struct smb_filename *smb_dname = NULL;
 	char *new_dir = NULL;
+	struct conn_struct_tos *c = NULL;
 	connection_struct *conn = NULL;
 	NTSTATUS nt_status;
 	int i;
 	int ver = 0;
-	struct smb_filename *oldcwd_fname = NULL;
 	char *printdollar = NULL;
 	int printdollar_snum;
 	WERROR err = WERR_OK;
@@ -1525,13 +1525,11 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
 		return WERR_BAD_NET_NAME;
 	}
 
-	nt_status = create_conn_struct_cwd(frame,
-					   server_event_context(),
-					   server_messaging_context(),
-					   &conn,
-					   printdollar_snum,
-					   lp_path(frame, printdollar_snum),
-					   session_info, &oldcwd_fname);
+	nt_status = create_conn_struct_tos_cwd(server_messaging_context(),
+					       printdollar_snum,
+					       lp_path(frame, printdollar_snum),
+					       session_info,
+					       &c);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0,("move_driver_to_download_area: create_conn_struct "
 			 "returned %s\n", nt_errstr(nt_status)));
@@ -1539,6 +1537,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
 		TALLOC_FREE(frame);
 		return err;
 	}
+	conn = c->conn;
 
 	nt_status = set_conn_force_user_group(conn, printdollar_snum);
 	if (!NT_STATUS_IS_OK(nt_status)) {
@@ -1694,12 +1693,6 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
  err_exit:
 	unbecome_user();
  err_free_conn:
-	if (conn != NULL) {
-		vfs_ChDir(conn, oldcwd_fname);
-		SMB_VFS_DISCONNECT(conn);
-		conn_free(conn);
-	}
-
 	TALLOC_FREE(frame);
 	return err;
 }
-- 
2.17.1


From 1c274613d4080fed858ab3eb3c568755ecbd9d33 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 17:55:02 +0200
Subject: [PATCH 29/40] printing: convert delete_driver_files() to use
 create_conn_struct_tos_cwd()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/printing/nt_printing.c | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index d0525e13c99a..633e350ff35f 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -2042,9 +2042,9 @@ bool delete_driver_files(const struct auth_session_info *session_info,
 {
 	TALLOC_CTX *frame = talloc_stackframe();
 	const char *short_arch;
-	connection_struct *conn;
+	struct conn_struct_tos *c = NULL;
+	connection_struct *conn = NULL;
 	NTSTATUS nt_status;
-	struct smb_filename *oldcwd_fname = NULL;
 	char *printdollar = NULL;
 	int printdollar_snum;
 	bool ret = false;
@@ -2067,19 +2067,18 @@ bool delete_driver_files(const struct auth_session_info *session_info,
 		return false;
 	}
 
-	nt_status = create_conn_struct_cwd(frame,
-					   server_event_context(),
-					   server_messaging_context(),
-					   &conn,
-					   printdollar_snum,
-					   lp_path(frame, printdollar_snum),
-					   session_info, &oldcwd_fname);
+	nt_status = create_conn_struct_tos_cwd(server_messaging_context(),
+					       printdollar_snum,
+					       lp_path(frame, printdollar_snum),
+					       session_info,
+					       &c);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0,("delete_driver_files: create_conn_struct "
 			 "returned %s\n", nt_errstr(nt_status)));
 		TALLOC_FREE(frame);
 		return false;
 	}
+	conn = c->conn;
 
 	nt_status = set_conn_force_user_group(conn, printdollar_snum);
 	if (!NT_STATUS_IS_OK(nt_status)) {
@@ -2142,11 +2141,6 @@ bool delete_driver_files(const struct auth_session_info *session_info,
  err_out:
 	unbecome_user();
  err_free_conn:
-	if (conn != NULL) {
-		vfs_ChDir(conn, oldcwd_fname);
-		SMB_VFS_DISCONNECT(conn);
-		conn_free(conn);
-	}
 	TALLOC_FREE(frame);
 	return ret;
 }
-- 
2.17.1


From 37f3f89153695fc8e8c9dd16e58901b89ed91bb3 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 08:49:29 +0200
Subject: [PATCH 30/40] smbd: remove unused create_conn_struct_cwd() function

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/msdfs.c | 62 --------------------------------------------
 source3/smbd/proto.h |  8 ------
 2 files changed, 70 deletions(-)

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 18fae96f2e58..256bb42d778e 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -386,68 +386,6 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
 	return status;
 }
 
-/********************************************************
- Fake up a connection struct for the VFS layer.
- Note: this performs a vfs connect and CHANGES CWD !!!! JRA.
-
- The old working directory is returned on *poldcwd, allocated on ctx.
-*********************************************************/
-
-NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
-				struct tevent_context *ev,
-				struct messaging_context *msg,
-				connection_struct **pconn,
-				int snum,
-				const char *path,
-				const struct auth_session_info *session_info,
-				struct smb_filename **poldcwd_fname)
-{
-	connection_struct *conn;
-	struct smb_filename *oldcwd_fname = NULL;
-	struct smb_filename smb_fname_connectpath = {0};
-
-	NTSTATUS status = create_conn_struct(ctx, ev,
-					     msg, &conn,
-					     snum, path,
-					     session_info);
-	if (!NT_STATUS_IS_OK(status)) {
-		return status;
-	}
-
-	/*
-	 * Windows seems to insist on doing trans2getdfsreferral() calls on
-	 * the IPC$ share as the anonymous user. If we try to chdir as that
-	 * user we will fail.... WTF ? JRA.
-	 */
-
-	oldcwd_fname = vfs_GetWd(ctx, conn);
-	if (oldcwd_fname == NULL) {
-		status = map_nt_error_from_unix(errno);
-		DEBUG(3, ("vfs_GetWd failed: %s\n", strerror(errno)));
-		conn_free(conn);
-		return status;
-	}
-
-	smb_fname_connectpath = (struct smb_filename) {
-		.base_name = conn->connectpath
-	};
-
-	if (vfs_ChDir(conn, &smb_fname_connectpath) != 0) {
-		status = map_nt_error_from_unix(errno);
-		DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. "
-			"Error was %s\n",
-			conn->connectpath, strerror(errno) ));
-		TALLOC_FREE(oldcwd_fname);
-		conn_free(conn);
-		return status;
-	}
-
-	*pconn = conn;
-	*poldcwd_fname = oldcwd_fname;
-
-	return NT_STATUS_OK;
-}
-
 static int conn_struct_tos_destructor(struct conn_struct_tos *c)
 {
 	if (c->oldcwd_fname != NULL) {
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index ed12e504bf8b..68dd566efd10 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -506,14 +506,6 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
 			    int snum,
 			    const char *path,
 			    const struct auth_session_info *session_info);
-NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
-				struct tevent_context *ev,
-				struct messaging_context *msg,
-				connection_struct **pconn,
-				int snum,
-				const char *path,
-				const struct auth_session_info *session_info,
-				struct smb_filename **poldcwd_fname);
 struct connection_struct;
 struct smb_filename;
 struct conn_struct_tos {
-- 
2.17.1


From fdbb71a06721c1ebb1b32ef126b951beeb48d8e9 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 08:49:29 +0200
Subject: [PATCH 31/40] vfstest: make use of create_conn_struct_tos()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/torture/vfstest.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/source3/torture/vfstest.c b/source3/torture/vfstest.c
index 17c19012384a..e17e6fc5c347 100644
--- a/source3/torture/vfstest.c
+++ b/source3/torture/vfstest.c
@@ -460,12 +460,12 @@ int main(int argc, const char *argv[])
 {
 	char *cmdstr = NULL;
 	struct cmd_set	**cmd_set;
+	struct conn_struct_tos *c = NULL;
 	struct vfs_state *vfs;
 	int i;
 	char *filename = NULL;
 	char cwd[MAXPATHLEN];
 	TALLOC_CTX *frame = talloc_stackframe();
-	struct tevent_context *ev;
 	struct auth_session_info *session_info = NULL;
 	NTSTATUS status = NT_STATUS_OK;
 
@@ -527,7 +527,7 @@ int main(int argc, const char *argv[])
 	sec_init();
 	init_guest_session_info(frame);
 	locking_init();
-	vfs = talloc_zero(NULL, struct vfs_state);
+	vfs = talloc_zero(frame, struct vfs_state);
 	if (vfs == NULL) {
 		return 1;
 	}
@@ -536,18 +536,15 @@ int main(int argc, const char *argv[])
 		return 1;
 	}
 
-	ev = server_event_context();
-
-	status = create_conn_struct(vfs,
-				ev,
-				server_messaging_context(),
-                                &vfs->conn,
-                                -1,
-                                getcwd(cwd, sizeof(cwd)),
-                                session_info);
+	status = create_conn_struct_tos(server_messaging_context(),
+					-1,
+					getcwd(cwd, sizeof(cwd)),
+					session_info,
+					&c);
 	if (!NT_STATUS_IS_OK(status)) {
 		return 1;
 	}
+	vfs->conn = c->conn;
 
 	vfs->conn->share_access = FILE_GENERIC_ALL;
 	vfs->conn->read_only = false;
-- 
2.17.1


From d1bd9ebdaba1d870863a0c85862b6cc12ae732bf Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 08:49:29 +0200
Subject: [PATCH 32/40] smbd: let create_conn_struct_tos() use
 create_conn_struct_as_root() directly

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

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 256bb42d778e..eff41f3419da 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -430,13 +430,15 @@ NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = create_conn_struct(c,
-				    ev,
-				    msg,
-				    &c->conn,
-				    snum,
-				    path,
-				    session_info);
+	become_root();
+	status = create_conn_struct_as_root(c,
+					    ev,
+					    msg,
+					    &c->conn,
+					    snum,
+					    path,
+					    session_info);
+	unbecome_root();
 	if (!NT_STATUS_IS_OK(status)) {
 		TALLOC_FREE(c);
 		return status;
-- 
2.17.1


From 666f1f3472ef4a9e08fb3966b224c30796dc1873 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 08:49:29 +0200
Subject: [PATCH 33/40] smbd: remove unused create_conn_struct() function

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/msdfs.c | 27 ---------------------------
 source3/smbd/proto.h |  7 -------
 2 files changed, 34 deletions(-)

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index eff41f3419da..9c8e32e31446 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -359,33 +359,6 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 	return NT_STATUS_OK;
 }
 
-/********************************************************
- Fake up a connection struct for the VFS layer, for use in
- applications (such as the python bindings), that do not want the
- global working directory changed under them.
-
- SMB_VFS_CONNECT requires root privileges.
-*********************************************************/
-
-NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
-			    struct tevent_context *ev,
-			    struct messaging_context *msg,
-			    connection_struct **pconn,
-			    int snum,
-			    const char *path,
-			    const struct auth_session_info *session_info)
-{
-	NTSTATUS status;
-	become_root();
-	status = create_conn_struct_as_root(ctx, ev,
-					    msg, pconn,
-					    snum, path,
-					    session_info);
-	unbecome_root();
-
-	return status;
-}
-
 static int conn_struct_tos_destructor(struct conn_struct_tos *c)
 {
 	if (c->oldcwd_fname != NULL) {
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 68dd566efd10..e4d0cf44e9b6 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -499,13 +499,6 @@ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx,
 				bool allow_broken_path,
 				char **pp_name_out,
 				bool *ppath_contains_wcard);
-NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
-			    struct tevent_context *ev,
-			    struct messaging_context *msg,
-			    connection_struct **pconn,
-			    int snum,
-			    const char *path,
-			    const struct auth_session_info *session_info);
 struct connection_struct;
 struct smb_filename;
 struct conn_struct_tos {
-- 
2.17.1


From 651f040a8c129740fc5f43da8b182dac4df94685 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 08:49:29 +0200
Subject: [PATCH 34/40] smbd: use pconn = talloc_move(ctx, &conn) in
 create_conn_struct_as_root()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/msdfs.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 9c8e32e31446..ff836138cd77 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -354,7 +354,7 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 	}
 
 	conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
-	*pconn = conn;
+	*pconn = talloc_move(ctx, &conn);
 
 	return NT_STATUS_OK;
 }
@@ -416,7 +416,6 @@ NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
 		TALLOC_FREE(c);
 		return status;
 	}
-	talloc_steal(c, c->conn);
 
 	talloc_set_destructor(c, conn_struct_tos_destructor);
 
-- 
2.17.1


From f5348aacefa3c09fb2e098ece6232f2f655ad77c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 08:49:29 +0200
Subject: [PATCH 35/40] smbd: call samba_tevent_context_init() within
 create_conn_struct_as_root()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/msdfs.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index ff836138cd77..1a6454b5c2be 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -240,7 +240,6 @@ static NTSTATUS parse_dfs_path(connection_struct *conn,
 *********************************************************/
 
 static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
-			    struct tevent_context *ev,
 			    struct messaging_context *msg,
 			    connection_struct **pconn,
 			    int snum,
@@ -258,7 +257,12 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	sconn->ev_ctx = ev;
+	sconn->ev_ctx = samba_tevent_context_init(sconn);
+	if (sconn->ev_ctx == NULL) {
+		TALLOC_FREE(sconn);
+		return NT_STATUS_NO_MEMORY;
+	}
+
 	sconn->msg_ctx = msg;
 
 	conn = conn_new(sconn);
@@ -387,7 +391,6 @@ NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
 				struct conn_struct_tos **_c)
 {
 	struct conn_struct_tos *c = NULL;
-	struct tevent_context *ev = NULL;
 	NTSTATUS status;
 
 	*_c = NULL;
@@ -397,15 +400,8 @@ NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	ev = samba_tevent_context_init(c);
-	if (ev == NULL) {
-		TALLOC_FREE(c);
-		return NT_STATUS_NO_MEMORY;
-	}
-
 	become_root();
 	status = create_conn_struct_as_root(c,
-					    ev,
 					    msg,
 					    &c->conn,
 					    snum,
-- 
2.17.1


From f8b6262697f1df4a007716657e6066c6e2f64ba7 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 08:53:47 +0200
Subject: [PATCH 36/40] vfs_glusterfs: use tevent_req_defer_callback() in order
 to use the correct event context

The callback and _recv() functions should be called from the same
event context that was passed to the _send() function.

In future the completion pipe should be replaced by
tevent_threaded_context_create()
---
 source3/modules/vfs_glusterfs.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index 985a895257fe..c2af793016f2 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -803,6 +803,14 @@ static struct tevent_req *vfs_gluster_pread_send(struct vfs_handle_struct
 		return tevent_req_post(req, ev);
 	}
 
+	/*
+	 * aio_glusterfs_done and aio_tevent_fd_done()
+	 * use the raw tevent context. We need to use
+	 * tevent_req_defer_callback() in order to
+	 * use the event context we're started with.
+	 */
+	tevent_req_defer_callback(req, ev);
+
 	PROFILE_TIMESTAMP(&state->start);
 	ret = glfs_pread_async(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle,
 				fsp), data, n, offset, 0, aio_glusterfs_done,
@@ -839,6 +847,14 @@ static struct tevent_req *vfs_gluster_pwrite_send(struct vfs_handle_struct
 		return tevent_req_post(req, ev);
 	}
 
+	/*
+	 * aio_glusterfs_done and aio_tevent_fd_done()
+	 * use the raw tevent context. We need to use
+	 * tevent_req_defer_callback() in order to
+	 * use the event context we're started with.
+	 */
+	tevent_req_defer_callback(req, ev);
+
 	PROFILE_TIMESTAMP(&state->start);
 	ret = glfs_pwrite_async(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle,
 				fsp), data, n, offset, 0, aio_glusterfs_done,
@@ -941,6 +957,14 @@ static struct tevent_req *vfs_gluster_fsync_send(struct vfs_handle_struct
 		return tevent_req_post(req, ev);
 	}
 
+	/*
+	 * aio_glusterfs_done and aio_tevent_fd_done()
+	 * use the raw tevent context. We need to use
+	 * tevent_req_defer_callback() in order to
+	 * use the event context we're started with.
+	 */
+	tevent_req_defer_callback(req, ev);
+
 	PROFILE_TIMESTAMP(&state->start);
 	ret = glfs_fsync_async(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle,
 				fsp), aio_glusterfs_done, state);
-- 
2.17.1


From 59bdd4d2f65abffe8aa51a3d2b683ebff6be9bdc Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 24 May 2018 09:49:40 +0200
Subject: [PATCH 37/40] smbd: make smbd_setup_sig_{term,hup}_handler() static

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/process.c | 4 ++--
 source3/smbd/proto.h   | 2 --
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 936b5351de7c..cf307b000727 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -966,7 +966,7 @@ static void smbd_sig_term_handler(struct tevent_context *ev,
 	exit_server_cleanly("termination signal");
 }
 
-void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
+static void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
 {
 	struct tevent_signal *se;
 
@@ -996,7 +996,7 @@ static void smbd_sig_hup_handler(struct tevent_context *ev,
 	reload_services(sconn, conn_snum_used, false);
 }
 
-void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
+static void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
 {
 	struct tevent_signal *se;
 
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index e4d0cf44e9b6..aacdeb44daf9 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -824,8 +824,6 @@ NTSTATUS make_default_filesystem_acl(
 
 /* The following definitions come from smbd/process.c  */
 
-void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn);
-void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn);
 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
 		  bool no_signing, uint32_t seqnum,
 		  bool do_encrypt,
-- 
2.17.1


From 7de7e16bf48d3e18fd832bda08a03793fd70d52e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 09:41:29 +0200
Subject: [PATCH 38/40] smbd: split out a fsp_flush_write_time_update()
 function from update_write_time_handler()

It's confusing to call update_write_time_handler() from anywhere,
it should only be called from within the event loop when the
timer expires.

This makes it more obvious that fsp_flush_write_time_update()
doesn't really need an tevent context argument.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/close.c   |  5 +----
 source3/smbd/durable.c |  5 +----
 source3/smbd/fileio.c  | 19 ++++++++++++++-----
 source3/smbd/proto.h   |  5 +----
 4 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 3324d3ec4e03..8581b04e8aaf 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -255,10 +255,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 
 	/* Ensure any pending write time updates are done. */
 	if (fsp->update_write_time_event) {
-		update_write_time_handler(fsp->conn->sconn->ev_ctx,
-					fsp->update_write_time_event,
-					timeval_current(),
-					(void *)fsp);
+		fsp_flush_write_time_update(fsp);
 	}
 
 	/*
diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c
index 602a96e1fe56..7d7a1b217514 100644
--- a/source3/smbd/durable.c
+++ b/source3/smbd/durable.c
@@ -194,10 +194,7 @@ NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp,
 
 	/* Ensure any pending write time updates are done. */
 	if (fsp->update_write_time_event) {
-		update_write_time_handler(fsp->conn->sconn->ev_ctx,
-					fsp->update_write_time_event,
-					timeval_current(),
-					(void *)fsp);
+		fsp_flush_write_time_update(fsp);
 	}
 
 	/*
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index 1c8bb41620c8..cde6a057ccda 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -160,12 +160,12 @@ static int wcp_file_size_change(files_struct *fsp)
 	return ret;
 }
 
-void update_write_time_handler(struct tevent_context *ctx,
-				      struct tevent_timer *te,
-				      struct timeval now,
-				      void *private_data)
+void fsp_flush_write_time_update(struct files_struct *fsp)
 {
-	files_struct *fsp = (files_struct *)private_data;
+	/*
+	 * Note this won't expect any impersonation!
+	 * So don't call any SMB_VFS operations here!
+	 */
 
 	DEBUG(5, ("Update write time on %s\n", fsp_str_dbg(fsp)));
 
@@ -180,6 +180,15 @@ void update_write_time_handler(struct tevent_context *ctx,
 	TALLOC_FREE(fsp->update_write_time_event);
 }
 
+static void update_write_time_handler(struct tevent_context *ctx,
+				      struct tevent_timer *te,
+				      struct timeval now,
+				      void *private_data)
+{
+	files_struct *fsp = (files_struct *)private_data;
+	fsp_flush_write_time_update(fsp);
+}
+
 /*********************************************************
  Schedule a write time update for WRITE_TIME_UPDATE_USEC_DELAY
  in the future.
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index aacdeb44daf9..2851d6d5f7df 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -320,10 +320,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32_t dosmode);
 /* The following definitions come from smbd/fileio.c  */
 
 ssize_t read_file(files_struct *fsp,char *data,off_t pos,size_t n);
-void update_write_time_handler(struct tevent_context *ctx,
-                                      struct tevent_timer *te,
-                                      struct timeval now,
-                                      void *private_data);
+void fsp_flush_write_time_update(struct files_struct *fsp);
 void trigger_write_time_update(struct files_struct *fsp);
 void trigger_write_time_update_immediate(struct files_struct *fsp);
 void mark_file_modified(files_struct *fsp);
-- 
2.17.1


From 0c43c333cf52ef83ab2363c6fd56857cf9620fc6 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 14:23:17 +0200
Subject: [PATCH 39/40] smbd: remove useless allow_access() check for AS_GUEST

We already call allow_access() when we accept the connection
in smbd_add_connection().

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/process.c | 23 -----------------------
 1 file changed, 23 deletions(-)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index cf307b000727..e0528f3498cc 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1661,33 +1661,10 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 	 * messenger service requests have this...)
 	 */
 	if (flags & AS_GUEST) {
-		char *raddr;
-		bool ok;
-
 		if (!change_to_guest()) {
 			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
 			return conn;
 		}
-
-		raddr = tsocket_address_inet_addr_string(xconn->remote_address,
-							 talloc_tos());
-		if (raddr == NULL) {
-			reply_nterror(req, NT_STATUS_NO_MEMORY);
-			return conn;
-		}
-
-		/*
-		 * Haven't we checked this in smbd_process already???
-		 */
-
-		ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
-				  xconn->remote_hostname, raddr);
-		TALLOC_FREE(raddr);
-
-		if (!ok) {
-			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
-			return conn;
-		}
 	}
 
 	/*
-- 
2.17.1


From 73512dbd2816a0413ad4e876a8190ccc95f1a143 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 14:26:37 +0200
Subject: [PATCH 40/40] smbd: don't call change_to_root_user() before
 change_to_guest()

We call change_to_guest() before set_current_service() now,
but that has no impact as we pass 'do_chdir=false'
as AS_GUEST is never mixed with AS_USER or DO_CHDIR.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/process.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index e0528f3498cc..1c54ca491462 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1624,6 +1624,15 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
 			return conn;
 		}
+	} else if (flags & AS_GUEST) {
+		/*
+		 * Does this protocol need to be run as guest? (Only archane
+		 * messenger service requests have this...)
+		 */
+		if (!change_to_guest()) {
+			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+			return conn;
+		}
 	} else {
 		/* This call needs to be run as root */
 		change_to_root_user();
@@ -1656,17 +1665,6 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 		conn->num_smb_operations++;
 	}
 
-	/*
-	 * Does this protocol need to be run as guest? (Only archane
-	 * messenger service requests have this...)
-	 */
-	if (flags & AS_GUEST) {
-		if (!change_to_guest()) {
-			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
-			return conn;
-		}
-	}
-
 	/*
 	 * Update encryption and signing state tracking flags that are
 	 * used by smbstatus to display signing and encryption status.
-- 
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/20180612/9d252b95/signature.sig>


More information about the samba-technical mailing list