[Patches] Preparation for tevent impersonation (part1)

Jeremy Allison jra at samba.org
Thu Jun 14 17:34:15 UTC 2018


On Thu, Jun 14, 2018 at 10:24:41AM -0700, Jeremy Allison via samba-technical wrote:
> On Thu, Jun 14, 2018 at 01:16:44PM -0400, jim via samba-technical wrote:
> > On 6/14/2018 1:12 PM, Jeremy Allison via samba-technical wrote:
> > > On Thu, Jun 14, 2018 at 10:03:42AM -0700, Jeremy Allison via samba-technical wrote:
> > > > On Thu, Jun 14, 2018 at 06:48:39PM +0200, Stefan Metzmacher wrote:
> > > > > 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).
> > > > FYI: Descriptions for patches 22/41 and 23/41 are incorrect,
> > > > missing signed-off-by in patch 37/41.
> > > > 
> > > > Other than that RB+ - looks good to me.
> > > > 
> > > > However I'm getting an interesting autobuild failure
> > > > when I push:
> > > > 
> > > > I'm looking into it !
> > > Found it !
> > > 
> > > source3/smbd/pysmbd.c:static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode)
> > > 
> > > return an ACL created on a talloc stackframe
> > > that is freed. The additional patch is needed
> > > I think. Can you add on top and review ?
> > > 
> > > Thanks,
> > > 
> > > 	Jeremy.
> > You should free the acl in the failure cases (like before) since you return
> > NULL to the caller.
> 
> Good point. Here's an updated patch. This maybe should be
> better merged into the original changed patch #6.
> 
> I'll let metze decide.

Here is an updated complete patchset with the
descriptions for patches 22/41 and 23/41 fixed,
added signed-off-by in patch 37/41 and the make_simple_acl()
fixes merged into patch 6/41.

I'm good with this version if you're happy.

Jeremy.
-------------- next part --------------
From 1153cc929befc493daade44bdc8d582d3e00882f 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>
Reviewed-by: Jeremy Allison <jra 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 238998d920d..51495f970db 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 4611e9748c2..36e0a25a7dd 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 c4941d84ccd..76fd9349fb4 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 2b08d580f35..ca1eda91879 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 9b6209619c3..f07ad925472 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.18.0.rc1.244.gcf134e6275-goog


From c1f18d745596cce30ca7ca2df551138ea3f1c18d 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>
Reviewed-by: Jeremy Allison <jra 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 76fd9349fb4..c4648ce2b6a 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 f9a89194cc5..2bdce560c38 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 2c33387bf6d..c25abf01ac9 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 6854527500d..90906a204d4 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 7a5ac4c4bc8..5f72da0f996 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 f07ad925472..3715a51c152 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.18.0.rc1.244.gcf134e6275-goog


From f816bff287bf056d8309d9f7752e0b1652d89309 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>
Reviewed-by: Jeremy Allison <jra 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 3c23d745eee..d6fbe93fcbb 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 5f72da0f996..ed12e504bf8 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.18.0.rc1.244.gcf134e6275-goog


From 0a18927aa412db2c09fe1cc45740865fba015fd5 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>
Reviewed-by: Jeremy Allison <jra 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 daaf95cb665..592cdf73f0a 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.18.0.rc1.244.gcf134e6275-goog


From 5663aff19d2c8c2415e05e9d76eae17801254e51 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>
Reviewed-by: Jeremy Allison <jra 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 592cdf73f0a..700ce78a773 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.18.0.rc1.244.gcf134e6275-goog


From 705926338e85feae7c6a273e47c7bc9d5213dfc5 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 and
 clean up the frame hierarchy in make_simple_acl().

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/pysmbd.c | 52 ++++++++++++++++++++++++-------------------
 1 file changed, 29 insertions(+), 23 deletions(-)

diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
index 700ce78a773..ae361e97707 100644
--- a/source3/smbd/pysmbd.c
+++ b/source3/smbd/pysmbd.c
@@ -268,103 +268,104 @@ static int set_acl_entry_perms(SMB_ACL_ENTRY_T entry, mode_t perm_mask)
 	return 0;
 }
 
-static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode)
+static SMB_ACL_T make_simple_acl(TALLOC_CTX *mem_ctx,
+			gid_t gid,
+			mode_t chmod_mode)
 {
-	TALLOC_CTX *frame = talloc_stackframe();
-
 	mode_t mode = SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE;
 
 	mode_t mode_user = (chmod_mode & 0700) >> 6;
 	mode_t mode_group = (chmod_mode & 070) >> 3;
 	mode_t mode_other = chmod_mode &  07;
 	SMB_ACL_ENTRY_T entry;
-	SMB_ACL_T acl = sys_acl_init(frame);
+	SMB_ACL_T acl = sys_acl_init(mem_ctx);
 
 	if (!acl) {
 		return NULL;
 	}
 
 	if (sys_acl_create_entry(&acl, &entry) != 0) {
-		TALLOC_FREE(frame);
+		TALLOC_FREE(acl);
 		return NULL;
 	}
 
 	if (sys_acl_set_tag_type(entry, SMB_ACL_USER_OBJ) != 0) {
-		TALLOC_FREE(frame);
+		TALLOC_FREE(acl);
 		return NULL;
 	}
 
 	if (set_acl_entry_perms(entry, mode_user) != 0) {
-		TALLOC_FREE(frame);
+		TALLOC_FREE(acl);
 		return NULL;
 	}
 
 	if (sys_acl_create_entry(&acl, &entry) != 0) {
-		TALLOC_FREE(frame);
+		TALLOC_FREE(acl);
 		return NULL;
 	}
 
 	if (sys_acl_set_tag_type(entry, SMB_ACL_GROUP_OBJ) != 0) {
-		TALLOC_FREE(frame);
+		TALLOC_FREE(acl);
 		return NULL;
 	}
 
 	if (set_acl_entry_perms(entry, mode_group) != 0) {
-		TALLOC_FREE(frame);
+		TALLOC_FREE(acl);
 		return NULL;
 	}
 
 	if (sys_acl_create_entry(&acl, &entry) != 0) {
-		TALLOC_FREE(frame);
+		TALLOC_FREE(acl);
 		return NULL;
 	}
 
 	if (sys_acl_set_tag_type(entry, SMB_ACL_OTHER) != 0) {
-		TALLOC_FREE(frame);
+		TALLOC_FREE(acl);
 		return NULL;
 	}
 
 	if (set_acl_entry_perms(entry, mode_other) != 0) {
-		TALLOC_FREE(frame);
+		TALLOC_FREE(acl);
 		return NULL;
 	}
 
 	if (gid != -1) {
 		if (sys_acl_create_entry(&acl, &entry) != 0) {
-			TALLOC_FREE(frame);
+			TALLOC_FREE(acl);
 			return NULL;
 		}
 
 		if (sys_acl_set_tag_type(entry, SMB_ACL_GROUP) != 0) {
-			TALLOC_FREE(frame);
+			TALLOC_FREE(acl);
 			return NULL;
 		}
 
 		if (sys_acl_set_qualifier(entry, &gid) != 0) {
-			TALLOC_FREE(frame);
+			TALLOC_FREE(acl);
 			return NULL;
 		}
 
 		if (set_acl_entry_perms(entry, mode_group) != 0) {
-			TALLOC_FREE(frame);
+			TALLOC_FREE(acl);
 			return NULL;
 		}
 	}
 
 	if (sys_acl_create_entry(&acl, &entry) != 0) {
-		TALLOC_FREE(frame);
+		TALLOC_FREE(acl);
 		return NULL;
 	}
 
 	if (sys_acl_set_tag_type(entry, SMB_ACL_MASK) != 0) {
-		TALLOC_FREE(frame);
+		TALLOC_FREE(acl);
 		return NULL;
 	}
 
 	if (set_acl_entry_perms(entry, mode) != 0) {
-		TALLOC_FREE(frame);
+		TALLOC_FREE(acl);
 		return NULL;
 	}
+
 	return acl;
 }
 
@@ -386,17 +387,21 @@ static PyObject *py_smbd_set_simple_acl(PyObject *self, PyObject *args, PyObject
 					 &fname, &mode, &gid, &service))
 		return NULL;
 
-	acl = make_simple_acl(gid, mode);
-
 	frame = talloc_stackframe();
 
+	acl = make_simple_acl(frame, gid, mode);
+	if (acl == NULL) {
+		TALLOC_FREE(frame);
+		return NULL;
+	}
+
 	conn = get_conn(frame, service);
 	if (!conn) {
+		TALLOC_FREE(frame);
 		return NULL;
 	}
 
 	ret = set_sys_acl_conn(fname, SMB_ACL_TYPE_ACCESS, acl, conn);
-	TALLOC_FREE(acl);
 
 	if (ret != 0) {
 		TALLOC_FREE(frame);
@@ -433,6 +438,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.18.0.rc1.244.gcf134e6275-goog


From 412163d023dff3c86008bfd1fb2cc7797ffbd0b9 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>
Reviewed-by: Jeremy Allison <jra 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 ae361e97707..638a6737640 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;
@@ -395,7 +391,7 @@ static PyObject *py_smbd_set_simple_acl(PyObject *self, PyObject *args, PyObject
 		return NULL;
 	}
 
-	conn = get_conn(frame, service);
+	conn = get_conn_tos(service);
 	if (!conn) {
 		TALLOC_FREE(frame);
 		return NULL;
@@ -436,7 +432,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;
@@ -495,7 +491,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;
@@ -561,7 +557,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;
@@ -596,7 +592,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;
@@ -638,7 +634,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;
@@ -679,7 +675,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.18.0.rc1.244.gcf134e6275-goog


From 3979d898c55b74d2c5fe89458c59ddbd93e10ca2 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>
Reviewed-by: Jeremy Allison <jra 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 638a6737640..ee918e1d727 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.18.0.rc1.244.gcf134e6275-goog


From 657c79173893a29400ed9b20d2a9e25f1c3ff03e 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>
Reviewed-by: Jeremy Allison <jra 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 fb074772134..70834d5fc7d 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.18.0.rc1.244.gcf134e6275-goog


From 3b380c65c79468a993617425466650924fa390b2 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>
Reviewed-by: Jeremy Allison <jra 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 0e5c82ec5e9..846b1047670 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.18.0.rc1.244.gcf134e6275-goog


From 2e7be0480356deae359948b1317a498c6500677e 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>
Reviewed-by: Jeremy Allison <jra 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 846b1047670..33cbca87d73 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.18.0.rc1.244.gcf134e6275-goog


From df9624814683f0ab7b1fddd2679e0a2bcb66f409 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>
Reviewed-by: Jeremy Allison <jra 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 d6fbe93fcbb..aeae02ed788 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.18.0.rc1.244.gcf134e6275-goog


From 260089828f36cbdd384828fa30e0cf93de696f92 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>
Reviewed-by: Jeremy Allison <jra 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 aeae02ed788..c5e80b1ef98 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.18.0.rc1.244.gcf134e6275-goog


From f7fa886eaaa6b7f1a6cf3261ab0f5fcf0587b1b6 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>
Reviewed-by: Jeremy Allison <jra 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 c5e80b1ef98..4e20358f567 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.18.0.rc1.244.gcf134e6275-goog


From 82bdeb18c247f7ac51380f1ade38aa92db3016a9 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>
Reviewed-by: Jeremy Allison <jra 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 4e20358f567..53a4dd2dfcc 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.18.0.rc1.244.gcf134e6275-goog


From ccb6cf42d149037dfeaa6d82979e8be79292ef99 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>
Reviewed-by: Jeremy Allison <jra 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 53a4dd2dfcc..cfa9e7602b7 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.18.0.rc1.244.gcf134e6275-goog


From d798e00e5215f7b9b05d94ce7ea7e41afe032577 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>
Reviewed-by: Jeremy Allison <jra 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 cfa9e7602b7..fcf7b9c3dda 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.18.0.rc1.244.gcf134e6275-goog


From 91d107067369e0b176962eeff58490fe3843b1c4 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>
Reviewed-by: Jeremy Allison <jra 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 fcf7b9c3dda..57e5b207239 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.18.0.rc1.244.gcf134e6275-goog


From 7745ec16fed97b595017ca1ae0cf568e327f4397 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>
Reviewed-by: Jeremy Allison <jra 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 57e5b207239..18fae96f2e5 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.18.0.rc1.244.gcf134e6275-goog


From 49b546de7d04812cb22fab970df5b2a21cc6b4ec 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>
Reviewed-by: Jeremy Allison <jra 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 c25abf01ac9..3eb9734507d 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.18.0.rc1.244.gcf134e6275-goog


From 1e7c0cd774204dcae5c7c9242ebfd3d6ab4b3e2e 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>
Reviewed-by: Jeremy Allison <jra 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 3eb9734507d..15bfdafa024 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.18.0.rc1.244.gcf134e6275-goog


From eb788cbb57fd4d86b8179e99d40beb4ff63999bd 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: _srvsvc_NetGetFileSecurity() to
 use create_conn_struct_tos_cwd()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra 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 15bfdafa024..e11471e345a 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.18.0.rc1.244.gcf134e6275-goog


From 2ba9b7e964501931c9d51e1c4033eb1a584355c5 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: _srvsvc_NetSetFileSecurity
 form_junctions() to use create_conn_struct_tos_cwd()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra 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 e11471e345a..e1963a40a0c 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.18.0.rc1.244.gcf134e6275-goog


From ea921862a171db3d4acef1c0d3eadc5ad8add1b3 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>
Reviewed-by: Jeremy Allison <jra 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 688c6b9969e..f01ffe5b32f 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 1639bfd4406..52bba6fcb3d 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.18.0.rc1.244.gcf134e6275-goog


From 5e7bdef2f8587e2a1e6a78c5c8b79972a0e54641 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>
Reviewed-by: Jeremy Allison <jra 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 52bba6fcb3d..5c448800926 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.18.0.rc1.244.gcf134e6275-goog


From bbabc3a5fdea1b67ad9b39ed637e0dbd5ac96804 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>
Reviewed-by: Jeremy Allison <jra 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 5c448800926..62ce5752747 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.18.0.rc1.244.gcf134e6275-goog


From c76c66c6794d2bc6835d181a2541e033d3e27411 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>
Reviewed-by: Jeremy Allison <jra 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 62ce5752747..9d1a18213cb 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.18.0.rc1.244.gcf134e6275-goog


From aa64b752e1555a313162fcb4a4a9594da200760e 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>
Reviewed-by: Jeremy Allison <jra 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 9d1a18213cb..bda72f88dd2 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.18.0.rc1.244.gcf134e6275-goog


From a1b6185da1ada821948581c290b15c83f275f3a4 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>
Reviewed-by: Jeremy Allison <jra 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 bda72f88dd2..d0525e13c99 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.18.0.rc1.244.gcf134e6275-goog


From 1c920289f889d1899e4d51c4add019b38e05b402 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>
Reviewed-by: Jeremy Allison <jra 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 d0525e13c99..633e350ff35 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.18.0.rc1.244.gcf134e6275-goog


From b8ef3e6b339aa6e00688a0f0338f2d29bf7b0dca 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>
Reviewed-by: Jeremy Allison <jra 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 18fae96f2e5..256bb42d778 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 ed12e504bf8..68dd566efd1 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.18.0.rc1.244.gcf134e6275-goog


From b2029d5c4f4d908b4d2801aeb4420fd74aaf3b24 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>
Reviewed-by: Jeremy Allison <jra 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 17c19012384..e17e6fc5c34 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.18.0.rc1.244.gcf134e6275-goog


From e2edfc68817e5938bb1ebb67fcea6ba025ef3ec5 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>
Reviewed-by: Jeremy Allison <jra 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 256bb42d778..eff41f3419d 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.18.0.rc1.244.gcf134e6275-goog


From eba84037d618644947cef7fd5249454bf6ffcb6f 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>
Reviewed-by: Jeremy Allison <jra 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 eff41f3419d..9c8e32e3144 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 68dd566efd1..e4d0cf44e9b 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.18.0.rc1.244.gcf134e6275-goog


From 8a731eb3d1cb7e70e6740bd4434be87879d75333 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>
Reviewed-by: Jeremy Allison <jra 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 9c8e32e3144..ff836138cd7 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.18.0.rc1.244.gcf134e6275-goog


From afb0cb7fcc3f1b24eb8ca193160e259ac75faa90 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>
Reviewed-by: Jeremy Allison <jra 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 ff836138cd7..1a6454b5c2b 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.18.0.rc1.244.gcf134e6275-goog


From edacdec3a17f96d6c5c56ec328fc698ff7066589 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()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
---
 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 985a895257f..c2af793016f 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.18.0.rc1.244.gcf134e6275-goog


From e20d4a6a1c01edcd049e2a6f66b89182fdcbf2f1 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>
Reviewed-by: Jeremy Allison <jra 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 936b5351de7..cf307b00072 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 e4d0cf44e9b..aacdeb44daf 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.18.0.rc1.244.gcf134e6275-goog


From 535cb910c9b614451a3042f9aecfc61440b60355 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>
Reviewed-by: Jeremy Allison <jra 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 3324d3ec4e0..8581b04e8aa 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 602a96e1fe5..7d7a1b21751 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 1c8bb41620c..cde6a057ccd 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 aacdeb44daf..2851d6d5f7d 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.18.0.rc1.244.gcf134e6275-goog


From 53452d23b5ba39c4a0c4cf7bef96e43c1a531c2c 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>
Reviewed-by: Jeremy Allison <jra 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 cf307b00072..e0528f3498c 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.18.0.rc1.244.gcf134e6275-goog


From 7c46dda3daa88cc89b63c3ffc420c652b5675107 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>
Reviewed-by: Jeremy Allison <jra 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 e0528f3498c..1c54ca49146 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.18.0.rc1.244.gcf134e6275-goog



More information about the samba-technical mailing list