[Patches] Preparation for tevent impersonation (part1)

Stefan Metzmacher metze at samba.org
Thu Jun 14 16:48:39 UTC 2018


Hi Jeremy,

> OK, finishing up the review with this patch inserted
> before #6 in the previous set. Should get this finished
> (and pushed) tomorrow.

Here's an updated patchset.

The author of the first two commits is fixed and the commit message
of the last one is extended (as requested by Andreas).

Thanks!
metze

-------------- next part --------------
From a6a5732b5bbf87425d2ed5656088c326430b34a7 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 16:35:20 +0200
Subject: [PATCH 01/41] 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 14cb5a759d6aaad08b1a397b36f44d1e917f06d6 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 23 May 2018 16:35:20 +0200
Subject: [PATCH 02/41] 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 5997d8dd45f0f2890ddeba7651c04f051f0425dd 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/41] 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 c00a2e1acd9d78335c5c65ae528ee458eda8f609 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/41] 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 db25e72d0aef75fa833c2e772078520773916082 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/41] 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 0cd2fe65903dd20e04be5d74219ad8939ebb2ab8 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/41] pysmbd: fix some talloc_stackframe() memory leaks

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

diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
index 700ce78a7732..a89d80620f1a 100644
--- a/source3/smbd/pysmbd.c
+++ b/source3/smbd/pysmbd.c
@@ -281,6 +281,7 @@ static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode)
 	SMB_ACL_T acl = sys_acl_init(frame);
 
 	if (!acl) {
+		TALLOC_FREE(frame);
 		return NULL;
 	}
 
@@ -365,6 +366,8 @@ static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode)
 		TALLOC_FREE(frame);
 		return NULL;
 	}
+
+	TALLOC_FREE(frame);
 	return acl;
 }
 
@@ -392,6 +395,7 @@ static PyObject *py_smbd_set_simple_acl(PyObject *self, PyObject *args, PyObject
 
 	conn = get_conn(frame, service);
 	if (!conn) {
+		TALLOC_FREE(frame);
 		return NULL;
 	}
 
@@ -433,6 +437,7 @@ static PyObject *py_smbd_chown(PyObject *self, PyObject *args, PyObject *kwargs)
 
 	conn = get_conn(frame, service);
 	if (!conn) {
+		TALLOC_FREE(frame);
 		return NULL;
 	}
 
-- 
2.17.1


From 17e42b018cdd7da96d52c16b5a238ecf71bb82d4 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/41] 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 a89d80620f1a..c8435ec494dd 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;
@@ -393,7 +389,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) {
 		TALLOC_FREE(frame);
 		return NULL;
@@ -435,7 +431,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) {
 		TALLOC_FREE(frame);
 		return NULL;
@@ -494,7 +490,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;
@@ -560,7 +556,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;
@@ -595,7 +591,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;
@@ -637,7 +633,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;
@@ -678,7 +674,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 9de552aacf509641b946431390a4fcd27abe9cbd 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 08/41] 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 c8435ec494dd..4e4299ca5d71 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 628ce8626ad5cf53233a3877e0a11574cc0d27fc 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 09/41] 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 167f7b74b83630c9bd6bd3b6b7b20b30fff42c2a 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 10/41] 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 3a7aff7077f00877b8226242fbde7b3fff7c44d9 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 11/41] 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 42d0cebf666c138e349efc2f8855e4aa68e1f2bb 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/41] 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 e064dabc4ede8e11c7d9e0c3f86de66462e1eb15 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/41] 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 948451886c4f4387eb638367ab789e55eb15b777 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/41] 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 86b570d5a3e7fc7d36ba85083fd32b5ada031607 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 15/41] 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 8db6665781fc95ad093f586dead872b57efe185d 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/41] 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 20becd984a306e3bcb2e965420f1da6cac9d3606 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/41] 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 2da139eac669173dd46962ef0a06e6a6b8055767 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/41] 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 33023f9e8455c59580333915558d2c6bda9422b8 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 19/41] 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 21ac2b511b75f1c8d4ccf6a5cc8a494665f66ee7 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/41] 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 eb7c2bbaa49063bc622539e9c89d9402993b7e08 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 21/41] 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 e4177762ed26edf8066768b09cd8b542657d45f1 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/41] 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 cabf97b02e0090c1a5cca61087b931d7a07f584f 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 23/41] 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 277705421c169709cd61e8873e000564b578f2fb 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/41] 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 dc619f4bd654b088cd72409f1052c059c5aafa57 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/41] 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 ac0f65317a40124698484354418968e0f9fcdeac 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/41] 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 f8cf9d834b79fc51174999c316bf7d5d384efab4 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 27/41] 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 f772184042e708da25877ce73cca42231938511d 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/41] 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 2bfaa3dbdb1873ebf4eb944dae4647a6f9cc96e5 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/41] 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 1d5d3cd42dde31b1dbb397b2c0d16bf6873e32e0 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 30/41] 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 ceb51982a5b6b25bdc1df6aa22dd7c7747180727 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/41] 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 d9296aa2a6f010f73e788d2125f1173f99002bb7 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/41] 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 9eeb3be97d32c8d576e195c9d35eff3c6d5ff70b 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/41] 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 870ec747240756de3e28b48b5cbda3f3089729de 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/41] 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 94e9fd469ca2a526f1ec7db2f33905bed84d804b 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/41] 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 31beccde35d279a4ea7d73a67e2d16f0c9662aa5 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 36/41] 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 ad436d03d76bb75da5999efaf89d1fa23f7b9a08 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 37/41] 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 9970b273852070661e14519b73d9a9c859dfc2ed 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 38/41] 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 3fce831dda469f7ed1cbc8eb7ef0c9a3e7de734d 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 39/41] 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 5e93321f61d3d9f2e40a7196d12cc170f064ef6e 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 40/41] 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 b59181ff8423f48154d54c7951df2f2a4b688191 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 41/41] smbd: don't call change_to_root_user() before
 change_to_guest()

This is just an optimization and it makes it clearer
that calling change_to_root_user() just before change_to_guest()
is useless and confusing.

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/20180614/fcadd0e3/signature.sig>


More information about the samba-technical mailing list