[Patches] Preparation for tevent impersonation (part1)

Jeremy Allison jra at samba.org
Tue Jun 12 22:09:40 UTC 2018


On Tue, Jun 12, 2018 at 08:30:26AM +0200, Stefan Metzmacher via samba-technical wrote:
> 
> The attached patches are from master4-impersonate-ok, they mostly
> prepare things, e.g. adding talloc_stackframe()'s in more places.
> 
> The most important thing is the create_conn_struct_tos[_cwd]()
> functions with much stricter requirements to create fake
> connection_structs, we no longer let the caller pass in
> an tevent context (we create a temporary one), as it's really not
> possible to use these fake contexts for real async processing.
> We also make sure we cleanup the fake contexts in a destructor
> in a common way.
> 
> They passed private autobuilds...
> 
> Please review and push:-)

In patch [PATCH 06/40] pysmbd: remove explicit talloc_stackframe() from  get_conn() and name it get_conn_tos()

py_smbd_set_simple_acl()
py_smbd_chown()

are missing a TALLOC_FREE(frame) in their error paths.

-       conn = get_conn(frame, service);
+       conn = get_conn_tos(service);
        if (!conn) {
>>>>> NEEDS	TALLOC_FREE(frame);
                return NULL;
        }

This is an existing bug, but probably should be fixed
either in patch 06/40 or in an additional patch after
it.

Can you add that change ?

I'm still reviewing the rest, but I just wanted to say
I *love* the cleanups in the code.

Cheers,

	Jeremy



> From 9eca815a1b2067df6520b7ed87fe959c09ef3cf4 Mon Sep 17 00:00:00 2001
> From: Ralph Boehme <slow at samba.org>
> Date: Wed, 23 May 2018 16:35:20 +0200
> Subject: [PATCH 01/40] printing: remove unused arguments from load_printers()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/printing/load.c          |  3 +--
>  source3/printing/load.h          |  3 +--
>  source3/printing/queue_process.c |  2 +-
>  source3/printing/spoolssd.c      | 12 ++++--------
>  source3/smbd/server_reload.c     |  4 ++--
>  5 files changed, 9 insertions(+), 15 deletions(-)
> 
> diff --git a/source3/printing/load.c b/source3/printing/load.c
> index 238998d920d7..51495f970db6 100644
> --- a/source3/printing/load.c
> +++ b/source3/printing/load.c
> @@ -62,8 +62,7 @@ static void add_auto_printers(void)
>  /***************************************************************************
>  load automatic printer services from pre-populated pcap cache
>  ***************************************************************************/
> -void load_printers(struct tevent_context *ev,
> -		   struct messaging_context *msg_ctx)
> +void load_printers(void)
>  {
>  	SMB_ASSERT(pcap_cache_loaded(NULL));
>  
> diff --git a/source3/printing/load.h b/source3/printing/load.h
> index 4611e9748c2d..36e0a25a7dda 100644
> --- a/source3/printing/load.h
> +++ b/source3/printing/load.h
> @@ -22,7 +22,6 @@
>  
>  /* The following definitions come from printing/load.c  */
>  
> -void load_printers(struct tevent_context *ev,
> -		   struct messaging_context *msg_ctx);
> +void load_printers(void);
>  
>  #endif /* _PRINTING_LOAD_H_ */
> diff --git a/source3/printing/queue_process.c b/source3/printing/queue_process.c
> index c4941d84ccd7..76fd9349fb45 100644
> --- a/source3/printing/queue_process.c
> +++ b/source3/printing/queue_process.c
> @@ -484,7 +484,7 @@ void printing_subsystem_update(struct tevent_context *ev_ctx,
>  {
>  	if (background_lpq_updater_pid != -1) {
>  		if (pcap_cache_loaded(NULL)) {
> -			load_printers(ev_ctx, msg_ctx);
> +			load_printers();
>  		}
>  		if (force) {
>  			/* Send a sighup to the background process.
> diff --git a/source3/printing/spoolssd.c b/source3/printing/spoolssd.c
> index 2b08d580f356..ca1eda918790 100644
> --- a/source3/printing/spoolssd.c
> +++ b/source3/printing/spoolssd.c
> @@ -105,7 +105,7 @@ static void update_conf(struct tevent_context *ev,
>  {
>  	change_to_root_user();
>  	lp_load_global(get_dyn_CONFIGFILE());
> -	load_printers(ev, msg);
> +	load_printers();
>  
>  	spoolss_reopen_logs(spoolss_child_id);
>  	if (spoolss_child_id == 0) {
> @@ -212,13 +212,9 @@ static void spoolss_chld_sig_hup_handler(struct tevent_context *ev,
>  					 void *siginfo,
>  					 void *pvt)
>  {
> -	struct messaging_context *msg_ctx;
> -
> -	msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
> -
>  	change_to_root_user();
>  	DEBUG(1,("Reloading printers after SIGHUP\n"));
> -	load_printers(ev, msg_ctx);
> +	load_printers();
>  	spoolss_reopen_logs(spoolss_child_id);
>  }
>  
> @@ -293,7 +289,7 @@ static bool spoolss_child_init(struct tevent_context *ev_ctx,
>  	 * ourselves. If pcap has not been loaded yet, then ignore, we will get
>  	 * a message as soon as the bq process completes the reload. */
>  	if (pcap_cache_loaded(NULL)) {
> -		load_printers(ev_ctx, msg_ctx);
> +		load_printers();
>  	}
>  
>  	/* try to reinit rpc queues */
> @@ -704,7 +700,7 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx,
>  	 * client enumeration anyway.
>  	 */
>  	if (pcap_cache_loaded(NULL)) {
> -		load_printers(ev_ctx, msg_ctx);
> +		load_printers();
>  	}
>  
>  	mem_ctx = talloc_new(NULL);
> diff --git a/source3/smbd/server_reload.c b/source3/smbd/server_reload.c
> index 9b6209619c30..f07ad9254720 100644
> --- a/source3/smbd/server_reload.c
> +++ b/source3/smbd/server_reload.c
> @@ -79,7 +79,7 @@ void delete_and_reload_printers(struct tevent_context *ev,
>  	reload_last_pcap_time = pcap_last_update;
>  
>  	/* Get pcap printers updated */
> -	load_printers(ev, msg_ctx);
> +	load_printers();
>  
>  	n_services = lp_numservices();
>  	pnum = lp_servicenumber(PRINTERS_NAME);
> @@ -110,7 +110,7 @@ void delete_and_reload_printers(struct tevent_context *ev,
>  	}
>  
>  	/* Make sure deleted printers are gone */
> -	load_printers(ev, msg_ctx);
> +	load_printers();
>  
>  	talloc_free(frame);
>  }
> -- 
> 2.17.1
> 
> 
> From 93c858776a6356aea3acb6489733d1d214fe674f Mon Sep 17 00:00:00 2001
> From: Ralph Boehme <slow at samba.org>
> Date: Wed, 23 May 2018 16:35:20 +0200
> Subject: [PATCH 02/40] printing: remove unused arguments from
>  delete_and_reload_printers()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/printing/queue_process.c            | 2 +-
>  source3/rpc_server/spoolss/srv_spoolss_nt.c | 4 ++--
>  source3/rpc_server/srvsvc/srv_srvsvc_nt.c   | 2 +-
>  source3/smbd/lanman.c                       | 2 +-
>  source3/smbd/proto.h                        | 3 +--
>  source3/smbd/server_reload.c                | 7 +------
>  6 files changed, 7 insertions(+), 13 deletions(-)
> 
> diff --git a/source3/printing/queue_process.c b/source3/printing/queue_process.c
> index 76fd9349fb45..c4648ce2b6ac 100644
> --- a/source3/printing/queue_process.c
> +++ b/source3/printing/queue_process.c
> @@ -123,7 +123,7 @@ static void delete_and_reload_printers_full(struct tevent_context *ev,
>  	}
>  
>  	/* finally, purge old snums */
> -	delete_and_reload_printers(ev, msg_ctx);
> +	delete_and_reload_printers();
>  
>  	TALLOC_FREE(session_info);
>  }
> diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
> index f9a89194cc57..2bdce560c38b 100644
> --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
> +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
> @@ -1694,7 +1694,7 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
>  	 * inventory on open as well.
>  	 */
>  	become_root();
> -	delete_and_reload_printers(server_event_context(), p->msg_ctx);
> +	delete_and_reload_printers();
>  	unbecome_root();
>  
>  	/* some sanity check because you can open a printer or a print server */
> @@ -4403,7 +4403,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
>  	 * printer process updates printer_list.tdb at regular intervals.
>  	 */
>  	become_root();
> -	delete_and_reload_printers(server_event_context(), msg_ctx);
> +	delete_and_reload_printers();
>  	unbecome_root();
>  
>  	n_services = lp_numservices();
> diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> index 2c33387bf6d0..c25abf01ac97 100644
> --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> @@ -563,7 +563,7 @@ static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
>  
>  	/* Ensure all the usershares are loaded. */
>  	become_root();
> -	delete_and_reload_printers(server_event_context(), p->msg_ctx);
> +	delete_and_reload_printers();
>  	load_usershare_shares(NULL, connections_snum_used);
>  	load_registry_shares();
>  	num_services = lp_numservices();
> diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
> index 6854527500dd..90906a204d4f 100644
> --- a/source3/smbd/lanman.c
> +++ b/source3/smbd/lanman.c
> @@ -2100,7 +2100,7 @@ static bool api_RNetShareEnum(struct smbd_server_connection *sconn,
>  
>  	/* Ensure all the usershares are loaded. */
>  	become_root();
> -	delete_and_reload_printers(sconn->ev_ctx, sconn->msg_ctx);
> +	delete_and_reload_printers();
>  	load_registry_shares();
>  	count = load_usershare_shares(NULL, connections_snum_used);
>  	unbecome_root();
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index 7a5ac4c4bc8b..5f72da0f9963 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -1051,8 +1051,7 @@ const struct security_token *sec_ctx_active_token(void);
>  
>  struct memcache *smbd_memcache(void);
>  bool snum_is_shared_printer(int snum);
> -void delete_and_reload_printers(struct tevent_context *ev,
> -				struct messaging_context *msg_ctx);
> +void delete_and_reload_printers(void);
>  bool reload_services(struct smbd_server_connection *sconn,
>  		     bool (*snumused) (struct smbd_server_connection *, int),
>  		     bool test);
> diff --git a/source3/smbd/server_reload.c b/source3/smbd/server_reload.c
> index f07ad9254720..3715a51c1529 100644
> --- a/source3/smbd/server_reload.c
> +++ b/source3/smbd/server_reload.c
> @@ -48,13 +48,8 @@ bool snum_is_shared_printer(int snum)
>   *
>   * This function should normally only be called as a callback on a successful
>   * pcap_cache_reload(), or on client enumeration.
> - *
> - * @param[in] ev        The event context.
> - *
> - * @param[in] msg_ctx   The messaging context.
>   */
> -void delete_and_reload_printers(struct tevent_context *ev,
> -				struct messaging_context *msg_ctx)
> +void delete_and_reload_printers(void)
>  {
>  	int n_services;
>  	int pnum;
> -- 
> 2.17.1
> 
> 
> From 273c2e5c17251a4dbd0be7ba68460a9e2e07a1bd Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 15:59:43 +0200
> Subject: [PATCH 03/40] smbd: add create_conn_struct_tos[_cwd]() helper
>  functions
> 
> This makes it more obvious that the returned connection_struct
> is only temporary (and allocated on talloc_tos()!)
> It will never allow async requests on a long term
> tevent context! So we create a short term event context.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 125 +++++++++++++++++++++++++++++++++++++++++++
>  source3/smbd/proto.h |  16 ++++++
>  2 files changed, 141 insertions(+)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index 3c23d745eee1..d6fbe93fcbb7 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -448,6 +448,131 @@ NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
>  	return NT_STATUS_OK;
>  }
>  
> +static int conn_struct_tos_destructor(struct conn_struct_tos *c)
> +{
> +	if (c->oldcwd_fname != NULL) {
> +		vfs_ChDir(c->conn, c->oldcwd_fname);
> +		TALLOC_FREE(c->oldcwd_fname);
> +	}
> +	SMB_VFS_DISCONNECT(c->conn);
> +	conn_free(c->conn);
> +	return 0;
> +}
> +
> +/********************************************************
> + Fake up a connection struct for the VFS layer, for use in
> + applications (such as the python bindings), that do not want the
> + global working directory changed under them.
> +
> + SMB_VFS_CONNECT requires root privileges.
> + This temporary uses become_root() and unbecome_root().
> +
> + But further impersonation has to be cone by the caller.
> +*********************************************************/
> +NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
> +				int snum,
> +				const char *path,
> +				const struct auth_session_info *session_info,
> +				struct conn_struct_tos **_c)
> +{
> +	struct conn_struct_tos *c = NULL;
> +	struct tevent_context *ev = NULL;
> +	NTSTATUS status;
> +
> +	*_c = NULL;
> +
> +	c = talloc_zero(talloc_tos(), struct conn_struct_tos);
> +	if (c == NULL) {
> +		return NT_STATUS_NO_MEMORY;
> +	}
> +
> +	ev = samba_tevent_context_init(c);
> +	if (ev == NULL) {
> +		TALLOC_FREE(c);
> +		return NT_STATUS_NO_MEMORY;
> +	}
> +
> +	status = create_conn_struct(c,
> +				    ev,
> +				    msg,
> +				    &c->conn,
> +				    snum,
> +				    path,
> +				    session_info);
> +	if (!NT_STATUS_IS_OK(status)) {
> +		TALLOC_FREE(c);
> +		return status;
> +	}
> +	talloc_steal(c, c->conn);
> +
> +	talloc_set_destructor(c, conn_struct_tos_destructor);
> +
> +	*_c = c;
> +	return NT_STATUS_OK;
> +}
> +
> +/********************************************************
> + Fake up a connection struct for the VFS layer.
> + Note: this performs a vfs connect and CHANGES CWD !!!! JRA.
> +
> + See also the comment for create_conn_struct_tos() above!
> +
> + The CWD change is reverted by the destructor of
> + conn_struct_tos when the current talloc_tos() is destroyed.
> +*********************************************************/
> +NTSTATUS create_conn_struct_tos_cwd(struct messaging_context *msg,
> +				    int snum,
> +				    const char *path,
> +				    const struct auth_session_info *session_info,
> +				    struct conn_struct_tos **_c)
> +{
> +	struct conn_struct_tos *c = NULL;
> +	struct smb_filename smb_fname_connectpath = {0};
> +	NTSTATUS status;
> +
> +	*_c = NULL;
> +
> +	status = create_conn_struct_tos(msg,
> +					snum,
> +					path,
> +					session_info,
> +					&c);
> +	if (!NT_STATUS_IS_OK(status)) {
> +		return status;
> +	}
> +
> +	/*
> +	 * Windows seems to insist on doing trans2getdfsreferral() calls on
> +	 * the IPC$ share as the anonymous user. If we try to chdir as that
> +	 * user we will fail.... WTF ? JRA.
> +	 */
> +
> +	c->oldcwd_fname = vfs_GetWd(c, c->conn);
> +	if (c->oldcwd_fname == NULL) {
> +		status = map_nt_error_from_unix(errno);
> +		DEBUG(3, ("vfs_GetWd failed: %s\n", strerror(errno)));
> +		TALLOC_FREE(c);
> +		return status;
> +	}
> +
> +	smb_fname_connectpath = (struct smb_filename) {
> +		.base_name = c->conn->connectpath
> +	};
> +
> +	if (vfs_ChDir(c->conn, &smb_fname_connectpath) != 0) {
> +		status = map_nt_error_from_unix(errno);
> +		DBG_NOTICE("Can't ChDir to new conn path %s. "
> +			   "Error was %s\n",
> +			   c->conn->connectpath, strerror(errno));
> +		TALLOC_FREE(c->oldcwd_fname);
> +		TALLOC_FREE(c);
> +		return status;
> +	}
> +
> +	*_c = c;
> +	return NT_STATUS_OK;
> +}
> +
>  static void shuffle_strlist(char **list, int count)
>  {
>  	int i;
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index 5f72da0f9963..ed12e504bf8b 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -514,6 +514,22 @@ NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
>  				const char *path,
>  				const struct auth_session_info *session_info,
>  				struct smb_filename **poldcwd_fname);
> +struct connection_struct;
> +struct smb_filename;
> +struct conn_struct_tos {
> +	struct connection_struct *conn;
> +	struct smb_filename *oldcwd_fname;
> +};
> +NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
> +				int snum,
> +				const char *path,
> +				const struct auth_session_info *session_info,
> +				struct conn_struct_tos **_c);
> +NTSTATUS create_conn_struct_tos_cwd(struct messaging_context *msg,
> +				    int snum,
> +				    const char *path,
> +				    const struct auth_session_info *session_info,
> +				    struct conn_struct_tos **_c);
>  
>  /* The following definitions come from smbd/negprot.c  */
>  
> -- 
> 2.17.1
> 
> 
> From 6c86e4c46b9471ac666bc25c321e3685c2862c10 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Fri, 25 May 2018 07:38:24 +0200
> Subject: [PATCH 04/40] pysmbd: remove useless explicit conn_free() from
>  set_nt_acl_conn()
> 
> The following TALLOC_FREE(frame); will do the same via
> conn_free_wrapper().
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/pysmbd.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
> index daaf95cb6658..592cdf73f0a2 100644
> --- a/source3/smbd/pysmbd.c
> +++ b/source3/smbd/pysmbd.c
> @@ -194,7 +194,6 @@ static NTSTATUS set_nt_acl_conn(const char *fname,
>  
>  	SMB_VFS_CLOSE(fsp);
>  
> -	conn_free(conn);
>  	TALLOC_FREE(frame);
>  
>  	umask(saved_umask);
> -- 
> 2.17.1
> 
> 
> From 08b6e56f258156d2b5cabc087b06942626782978 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 16:16:19 +0200
> Subject: [PATCH 05/40] pysmbd: consitently use talloc_stackframe() for
>  temporary memory
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/pysmbd.c | 25 +++++++------------------
>  1 file changed, 7 insertions(+), 18 deletions(-)
> 
> diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
> index 592cdf73f0a2..700ce78a7732 100644
> --- a/source3/smbd/pysmbd.c
> +++ b/source3/smbd/pysmbd.c
> @@ -580,28 +580,28 @@ static PyObject *py_smbd_get_nt_acl(PyObject *self, PyObject *args, PyObject *kw
>  	int security_info_wanted;
>  	PyObject *py_sd;
>  	struct security_descriptor *sd;
> -	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	connection_struct *conn;
>  	NTSTATUS status;
>  
>  	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|z", discard_const_p(char *, kwnames),
>  					 &fname, &security_info_wanted, &service)) {
> -		TALLOC_FREE(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return NULL;
>  	}
>  
> -	conn = get_conn(tmp_ctx, service);
> +	conn = get_conn(frame, service);
>  	if (!conn) {
> -		TALLOC_FREE(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return NULL;
>  	}
>  
> -	status = get_nt_acl_conn(tmp_ctx, fname, conn, security_info_wanted, &sd);
> +	status = get_nt_acl_conn(frame, fname, conn, security_info_wanted, &sd);
>  	PyErr_NTSTATUS_IS_ERR_RAISE(status);
>  
>  	py_sd = py_return_ndr_struct("samba.dcerpc.security", "descriptor", sd, sd);
>  
> -	TALLOC_FREE(tmp_ctx);
> +	TALLOC_FREE(frame);
>  
>  	return py_sd;
>  }
> @@ -662,28 +662,20 @@ static PyObject *py_smbd_get_sys_acl(PyObject *self, PyObject *args, PyObject *k
>  	struct smb_acl_t *acl;
>  	int acl_type;
>  	TALLOC_CTX *frame = talloc_stackframe();
> -	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
>  	connection_struct *conn;
>  	char *service = NULL;
>  	struct smb_filename *smb_fname = NULL;
>  
> -	if (!tmp_ctx) {
> -		PyErr_NoMemory();
> -		return NULL;
> -	}
> -
>  	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|z",
>  					 discard_const_p(char *, kwnames),
>  					 &fname, &acl_type, &service)) {
>  		TALLOC_FREE(frame);
> -		TALLOC_FREE(tmp_ctx);
>  		return NULL;
>  	}
>  
>  	conn = get_conn(frame, service);
>  	if (!conn) {
>  		TALLOC_FREE(frame);
> -		TALLOC_FREE(tmp_ctx);
>  		return NULL;
>  	}
>  
> @@ -692,20 +684,17 @@ static PyObject *py_smbd_get_sys_acl(PyObject *self, PyObject *args, PyObject *k
>  					lp_posix_pathnames());
>  	if (smb_fname == NULL) {
>  		TALLOC_FREE(frame);
> -		TALLOC_FREE(tmp_ctx);
>  		return NULL;
>  	}
> -	acl = SMB_VFS_SYS_ACL_GET_FILE( conn, smb_fname, acl_type, tmp_ctx);
> +	acl = SMB_VFS_SYS_ACL_GET_FILE( conn, smb_fname, acl_type, frame);
>  	if (!acl) {
>  		TALLOC_FREE(frame);
> -		TALLOC_FREE(tmp_ctx);
>  		return PyErr_SetFromErrno(PyExc_OSError);
>  	}
>  
>  	py_acl = py_return_ndr_struct("samba.dcerpc.smb_acl", "t", acl, acl);
>  
>  	TALLOC_FREE(frame);
> -	TALLOC_FREE(tmp_ctx);
>  
>  	return py_acl;
>  }
> -- 
> 2.17.1
> 
> 
> From 66aa9298c7a756a8c4dfe090816644fe72432365 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 16:16:19 +0200
> Subject: [PATCH 06/40] pysmbd: remove explicit talloc_stackframe() from
>  get_conn() and name it get_conn_tos()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/pysmbd.c | 22 +++++++++-------------
>  1 file changed, 9 insertions(+), 13 deletions(-)
> 
> diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
> index 700ce78a7732..1b4d2cd1e9b0 100644
> --- a/source3/smbd/pysmbd.c
> +++ b/source3/smbd/pysmbd.c
> @@ -43,33 +43,29 @@ static int conn_free_wrapper(connection_struct *conn)
>  	return 0;
>  };
>  
> -static connection_struct *get_conn(TALLOC_CTX *mem_ctx, const char *service)
> +static connection_struct *get_conn_tos(const char *service)
>  {
>  	connection_struct *conn;
> -	TALLOC_CTX *frame = talloc_stackframe();
>  	int snum = -1;
>  	NTSTATUS status;
>  
>  	if (!posix_locking_init(false)) {
>  		PyErr_NoMemory();
> -		TALLOC_FREE(frame);
>  		return NULL;
>  	}
>  
>  	if (service) {
>  		snum = lp_servicenumber(service);
>  		if (snum == -1) {
> -			TALLOC_FREE(frame);
>  			PyErr_SetString(PyExc_RuntimeError, "unknown service");
>  			return NULL;
>  		}
>  	}
>  
> -	status = create_conn_struct(mem_ctx, NULL, NULL, &conn, snum, "/",
> +	status = create_conn_struct(talloc_tos(), NULL, NULL, &conn, snum, "/",
>  					    NULL);
>  	PyErr_NTSTATUS_IS_ERR_RAISE(status);
>  
> -	TALLOC_FREE(frame);
>  	/* Ignore read-only and share restrictions */
>  	conn->read_only = false;
>  	conn->share_access = SEC_RIGHTS_FILE_ALL;
> @@ -390,7 +386,7 @@ static PyObject *py_smbd_set_simple_acl(PyObject *self, PyObject *args, PyObject
>  
>  	frame = talloc_stackframe();
>  
> -	conn = get_conn(frame, service);
> +	conn = get_conn_tos(service);
>  	if (!conn) {
>  		return NULL;
>  	}
> @@ -431,7 +427,7 @@ static PyObject *py_smbd_chown(PyObject *self, PyObject *args, PyObject *kwargs)
>  
>  	frame = talloc_stackframe();
>  
> -	conn = get_conn(frame, service);
> +	conn = get_conn_tos(service);
>  	if (!conn) {
>  		return NULL;
>  	}
> @@ -489,7 +485,7 @@ static PyObject *py_smbd_unlink(PyObject *self, PyObject *args, PyObject *kwargs
>  		return NULL;
>  	}
>  
> -	conn = get_conn(frame, service);
> +	conn = get_conn_tos(service);
>  	if (!conn) {
>  		TALLOC_FREE(frame);
>  		return NULL;
> @@ -555,7 +551,7 @@ static PyObject *py_smbd_set_nt_acl(PyObject *self, PyObject *args, PyObject *kw
>  		return NULL;
>  	}
>  
> -	conn = get_conn(frame, service);
> +	conn = get_conn_tos(service);
>  	if (!conn) {
>  		TALLOC_FREE(frame);
>  		return NULL;
> @@ -590,7 +586,7 @@ static PyObject *py_smbd_get_nt_acl(PyObject *self, PyObject *args, PyObject *kw
>  		return NULL;
>  	}
>  
> -	conn = get_conn(frame, service);
> +	conn = get_conn_tos(service);
>  	if (!conn) {
>  		TALLOC_FREE(frame);
>  		return NULL;
> @@ -632,7 +628,7 @@ static PyObject *py_smbd_set_sys_acl(PyObject *self, PyObject *args, PyObject *k
>  		return NULL;
>  	}
>  
> -	conn = get_conn(frame, service);
> +	conn = get_conn_tos(service);
>  	if (!conn) {
>  		TALLOC_FREE(frame);
>  		return NULL;
> @@ -673,7 +669,7 @@ static PyObject *py_smbd_get_sys_acl(PyObject *self, PyObject *args, PyObject *k
>  		return NULL;
>  	}
>  
> -	conn = get_conn(frame, service);
> +	conn = get_conn_tos(service);
>  	if (!conn) {
>  		TALLOC_FREE(frame);
>  		return NULL;
> -- 
> 2.17.1
> 
> 
> From 6bb93a9b6f6963e7f9c16611e25ccacac99e0027 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 16:16:19 +0200
> Subject: [PATCH 07/40] pysmbd: make use of create_conn_struct_tos()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/pysmbd.c | 22 +++++++++-------------
>  1 file changed, 9 insertions(+), 13 deletions(-)
> 
> diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
> index 1b4d2cd1e9b0..a919b93aab2c 100644
> --- a/source3/smbd/pysmbd.c
> +++ b/source3/smbd/pysmbd.c
> @@ -37,15 +37,9 @@ extern const struct generic_mapping file_generic_mapping;
>  #undef  DBGC_CLASS
>  #define DBGC_CLASS DBGC_ACLS
>  
> -static int conn_free_wrapper(connection_struct *conn)
> -{
> -	conn_free(conn);
> -	return 0;
> -};
> -
>  static connection_struct *get_conn_tos(const char *service)
>  {
> -	connection_struct *conn;
> +	struct conn_struct_tos *c = NULL;
>  	int snum = -1;
>  	NTSTATUS status;
>  
> @@ -62,15 +56,17 @@ static connection_struct *get_conn_tos(const char *service)
>  		}
>  	}
>  
> -	status = create_conn_struct(talloc_tos(), NULL, NULL, &conn, snum, "/",
> -					    NULL);
> +	status = create_conn_struct_tos(NULL,
> +					snum,
> +					"/",
> +					NULL,
> +					&c);
>  	PyErr_NTSTATUS_IS_ERR_RAISE(status);
>  
>  	/* Ignore read-only and share restrictions */
> -	conn->read_only = false;
> -	conn->share_access = SEC_RIGHTS_FILE_ALL;
> -	talloc_set_destructor(conn, conn_free_wrapper);
> -	return conn;
> +	c->conn->read_only = false;
> +	c->conn->share_access = SEC_RIGHTS_FILE_ALL;
> +	return c->conn;
>  }
>  
>  static int set_sys_acl_conn(const char *fname,
> -- 
> 2.17.1
> 
> 
> From 037e7275b37ebf8eaabbf768cb07d0b6dd5d58c0 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 16:34:04 +0200
> Subject: [PATCH 08/40] smbd: make use of create_conn_struct_tos() in
>  get_nt_acl_no_snum()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/posix_acls.c | 18 +++++++-----------
>  1 file changed, 7 insertions(+), 11 deletions(-)
> 
> diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
> index fb074772134a..70834d5fc7d7 100644
> --- a/source3/smbd/posix_acls.c
> +++ b/source3/smbd/posix_acls.c
> @@ -4570,7 +4570,7 @@ NTSTATUS get_nt_acl_no_snum(TALLOC_CTX *ctx, const char *fname,
>  				struct security_descriptor **sd)
>  {
>  	TALLOC_CTX *frame = talloc_stackframe();
> -	connection_struct *conn;
> +	struct conn_struct_tos *c = NULL;
>  	NTSTATUS status = NT_STATUS_OK;
>  	struct smb_filename *smb_fname = synthetic_smb_fname(talloc_tos(),
>  						fname,
> @@ -4588,14 +4588,11 @@ NTSTATUS get_nt_acl_no_snum(TALLOC_CTX *ctx, const char *fname,
>  		return NT_STATUS_NO_MEMORY;
>  	}
>  
> -	status = create_conn_struct(ctx,
> -				server_event_context(),
> -				server_messaging_context(),
> -				&conn,
> -				-1,
> -				"/",
> -				NULL);
> -
> +	status = create_conn_struct_tos(server_messaging_context(),
> +					-1,
> +					"/",
> +					NULL,
> +					&c);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		DEBUG(0,("create_conn_struct returned %s.\n",
>  			nt_errstr(status)));
> @@ -4603,7 +4600,7 @@ NTSTATUS get_nt_acl_no_snum(TALLOC_CTX *ctx, const char *fname,
>  		return status;
>  	}
>  
> -	status = SMB_VFS_GET_NT_ACL(conn,
> +	status = SMB_VFS_GET_NT_ACL(c->conn,
>  				smb_fname,
>  				security_info_wanted,
>  				ctx,
> @@ -4613,7 +4610,6 @@ NTSTATUS get_nt_acl_no_snum(TALLOC_CTX *ctx, const char *fname,
>  			  nt_errstr(status)));
>  	}
>  
> -	conn_free(conn);
>  	TALLOC_FREE(frame);
>  
>  	return status;
> -- 
> 2.17.1
> 
> 
> From 18d706d9a7e269c11fd627291dd5cd898d37766b Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 16:41:32 +0200
> Subject: [PATCH 09/40] s3:rpc_server/fss: use talloc_stackframe() for
>  temporary memory
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/rpc_server/fss/srv_fss_agent.c | 161 +++++++++++--------------
>  1 file changed, 68 insertions(+), 93 deletions(-)
> 
> diff --git a/source3/rpc_server/fss/srv_fss_agent.c b/source3/rpc_server/fss/srv_fss_agent.c
> index 0e5c82ec5e91..846b1047670c 100644
> --- a/source3/rpc_server/fss/srv_fss_agent.c
> +++ b/source3/rpc_server/fss/srv_fss_agent.c
> @@ -144,6 +144,7 @@ static void fss_vfs_conn_destroy(struct connection_struct *conn);
>  static bool snap_path_exists(TALLOC_CTX *ctx, struct messaging_context *msg_ctx,
>  			     struct fss_sc *sc)
>  {
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	SMB_STRUCT_STAT st;
>  	struct connection_struct *conn = NULL;
>  	struct smb_filename *smb_fname = NULL;
> @@ -161,13 +162,13 @@ static bool snap_path_exists(TALLOC_CTX *ctx, struct messaging_context *msg_ctx,
>  	}
>  
>  	share = sc->smaps->share_name;
> -	snum = find_service(ctx, share, &service);
> +	snum = find_service(frame, share, &service);
>  
>  	if ((snum == -1) || (service == NULL)) {
>  		goto out;
>  	}
>  
> -	status = fss_vfs_conn_create(ctx, server_event_context(),
> +	status = fss_vfs_conn_create(frame, server_event_context(),
>  				     msg_ctx, NULL, snum, &conn);
>  
>  	if(!NT_STATUS_IS_OK(status)) {
> @@ -188,7 +189,7 @@ out:
>  	if (conn) {
>  		fss_vfs_conn_destroy(conn);
>  	}
> -	TALLOC_FREE(service);
> +	TALLOC_FREE(frame);
>  	return result;
>  }
>  
> @@ -747,11 +748,7 @@ uint32_t _fss_AddToShadowCopySet(struct pipes_struct *p,
>  	char *path_name;
>  	struct connection_struct *conn;
>  	NTSTATUS status;
> -	TALLOC_CTX *tmp_ctx = talloc_new(p->mem_ctx);
> -	if (tmp_ctx == NULL) {
> -		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
> -		goto err_out;
> -	}
> +	TALLOC_CTX *frame = talloc_stackframe();
>  
>  	if (!fss_permitted(p)) {
>  		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
> @@ -764,26 +761,26 @@ uint32_t _fss_AddToShadowCopySet(struct pipes_struct *p,
>  		goto err_tmp_free;
>  	}
>  
> -	status = fss_unc_parse(tmp_ctx, r->in.ShareName, NULL, &share);
> +	status = fss_unc_parse(frame, r->in.ShareName, NULL, &share);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		ret = fss_ntstatus_map(status);
>  		goto err_tmp_free;
>  	}
>  
> -	snum = find_service(tmp_ctx, share, &service);
> +	snum = find_service(frame, share, &service);
>  	if ((snum == -1) || (service == NULL)) {
>  		DEBUG(0, ("share at %s not found\n", r->in.ShareName));
>  		ret = HRES_ERROR_V(HRES_E_INVALIDARG);
>  		goto err_tmp_free;
>  	}
>  
> -	path_name = lp_path(tmp_ctx, snum);
> +	path_name = lp_path(frame, snum);
>  	if (path_name == NULL) {
>  		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
>  		goto err_tmp_free;
>  	}
>  
> -	status = fss_vfs_conn_create(tmp_ctx, server_event_context(),
> +	status = fss_vfs_conn_create(frame, server_event_context(),
>  				     p->msg_ctx, p->session_info, snum, &conn);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
> @@ -796,7 +793,7 @@ uint32_t _fss_AddToShadowCopySet(struct pipes_struct *p,
>  		goto err_tmp_free;
>  	}
>  
> -	status = SMB_VFS_SNAP_CHECK_PATH(conn, tmp_ctx, path_name, &base_vol);
> +	status = SMB_VFS_SNAP_CHECK_PATH(conn, frame, path_name, &base_vol);
>  	unbecome_user();
>  	fss_vfs_conn_destroy(conn);
>  	if (!NT_STATUS_IS_OK(status)) {
> @@ -878,7 +875,7 @@ uint32_t _fss_AddToShadowCopySet(struct pipes_struct *p,
>  	sc_set->state = FSS_SC_ADDED;
>  	r->out.pShadowCopyId = &sc->id;
>  
> -	talloc_free(tmp_ctx);
> +	TALLOC_FREE(frame);
>  	return 0;
>  
>  err_sc_free:
> @@ -886,8 +883,7 @@ err_sc_free:
>  err_tmr_restart:
>  	fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set, &fss_global.seq_tmr);
>  err_tmp_free:
> -	talloc_free(tmp_ctx);
> -err_out:
> +	TALLOC_FREE(frame);
>  	return ret;
>  }
>  
> @@ -899,28 +895,32 @@ static NTSTATUS commit_sc_with_conn(TALLOC_CTX *mem_ctx,
>  				    char **base_path,
>  				    char **snap_path)
>  {
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	NTSTATUS status;
>  	bool rw;
>  	struct connection_struct *conn;
>  	int snum;
>  	char *service;
>  
> -	snum = find_service(mem_ctx, sc->smaps->share_name, &service);
> +	snum = find_service(frame, sc->smaps->share_name, &service);
>  	if ((snum == -1) || (service == NULL)) {
>  		DEBUG(0, ("share at %s not found\n", sc->smaps->share_name));
> +		TALLOC_FREE(frame);
>  		return NT_STATUS_UNSUCCESSFUL;
>  	}
>  
> -	status = fss_vfs_conn_create(mem_ctx,
> +	status = fss_vfs_conn_create(frame,
>  				     ev, msg_ctx, session_info,
>  				     snum, &conn);
>  	if (!NT_STATUS_IS_OK(status)) {
> +		TALLOC_FREE(frame);
>  		return status;
>  	}
>  
>  	if (!become_user_by_session(conn, session_info)) {
>  		DEBUG(0, ("failed to become user\n"));
>  		fss_vfs_conn_destroy(conn);
> +		TALLOC_FREE(frame);
>  		return NT_STATUS_ACCESS_DENIED;
>  	}
>  	rw = ((sc->sc_set->context & ATTR_AUTO_RECOVERY) == ATTR_AUTO_RECOVERY);
> @@ -932,9 +932,11 @@ static NTSTATUS commit_sc_with_conn(TALLOC_CTX *mem_ctx,
>  	fss_vfs_conn_destroy(conn);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		DEBUG(0, ("snap create failed: %s\n", nt_errstr(status)));
> +		TALLOC_FREE(frame);
>  		return status;
>  	}
>  
> +	TALLOC_FREE(frame);
>  	return status;
>  }
>  
> @@ -946,17 +948,11 @@ uint32_t _fss_CommitShadowCopySet(struct pipes_struct *p,
>  	uint32_t commit_count;
>  	NTSTATUS status;
>  	NTSTATUS saved_status;
> -	TALLOC_CTX *tmp_ctx;
> +	TALLOC_CTX *frame = talloc_stackframe();
>  
>  	if (!fss_permitted(p)) {
>  		status = NT_STATUS_ACCESS_DENIED;
> -		goto err_out;
> -	}
> -
> -	tmp_ctx = talloc_new(p->mem_ctx);
> -	if (tmp_ctx == NULL) {
> -		status = NT_STATUS_NO_MEMORY;
> -		goto err_out;
> +		goto err_tmp_free;
>  	}
>  
>  	sc_set = sc_set_lookup(fss_global.sc_sets, &r->in.ShadowCopySetId);
> @@ -978,7 +974,7 @@ uint32_t _fss_CommitShadowCopySet(struct pipes_struct *p,
>  	for (sc = sc_set->scs; sc; sc = sc->next) {
>  		char *base_path;
>  		char *snap_path;
> -		status = commit_sc_with_conn(tmp_ctx, server_event_context(),
> +		status = commit_sc_with_conn(frame, server_event_context(),
>  					     p->msg_ctx, p->session_info, sc,
>  					     &base_path, &snap_path);
>  		if (!NT_STATUS_IS_OK(status)) {
> @@ -1012,7 +1008,7 @@ uint32_t _fss_CommitShadowCopySet(struct pipes_struct *p,
>  
>  	fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set,
>  			 &fss_global.seq_tmr);
> -	talloc_free(tmp_ctx);
> +	TALLOC_FREE(frame);
>  	return 0;
>  
>  err_state_revert:
> @@ -1020,8 +1016,7 @@ err_state_revert:
>  	fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set,
>  			 &fss_global.seq_tmr);
>  err_tmp_free:
> -	talloc_free(tmp_ctx);
> -err_out:
> +	TALLOC_FREE(frame);
>  	return fss_ntstatus_map(status);
>  }
>  
> @@ -1156,10 +1151,7 @@ uint32_t _fss_ExposeShadowCopySet(struct pipes_struct *p,
>  	struct smbconf_ctx *rconf_ctx;
>  	sbcErr cerr;
>  	char *fconf_path;
> -	TALLOC_CTX *tmp_ctx = talloc_new(p->mem_ctx);
> -	if (tmp_ctx == NULL) {
> -		return HRES_ERROR_V(HRES_E_OUTOFMEMORY);
> -	}
> +	TALLOC_CTX *frame = talloc_stackframe();
>  
>  	if (!fss_permitted(p)) {
>  		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
> @@ -1186,19 +1178,19 @@ uint32_t _fss_ExposeShadowCopySet(struct pipes_struct *p,
>  	 * definition may be located in either. The snapshot share definition
>  	 * is always written to the registry.
>  	 */
> -	cerr = smbconf_init(tmp_ctx, &rconf_ctx, "registry");
> +	cerr = smbconf_init(frame, &rconf_ctx, "registry");
>  	if (!SBC_ERROR_IS_OK(cerr)) {
>  		DEBUG(0, ("failed registry smbconf init: %s\n",
>  			  sbcErrorString(cerr)));
>  		ret = HRES_ERROR_V(HRES_E_FAIL);
>  		goto err_tmr_restart;
>  	}
> -	fconf_path = talloc_asprintf(tmp_ctx, "file:%s", get_dyn_CONFIGFILE());
> +	fconf_path = talloc_asprintf(frame, "file:%s", get_dyn_CONFIGFILE());
>  	if (fconf_path == NULL) {
>  		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
>  		goto err_tmr_restart;
>  	}
> -	cerr = smbconf_init(tmp_ctx, &fconf_ctx, fconf_path);
> +	cerr = smbconf_init(frame, &fconf_ctx, fconf_path);
>  	if (!SBC_ERROR_IS_OK(cerr)) {
>  		DEBUG(0, ("failed %s smbconf init: %s\n",
>  			  fconf_path, sbcErrorString(cerr)));
> @@ -1218,7 +1210,7 @@ uint32_t _fss_ExposeShadowCopySet(struct pipes_struct *p,
>  	}
>  
>  	for (sc = sc_set->scs; sc; sc = sc->next) {
> -		ret = fss_sc_expose(fconf_ctx, rconf_ctx, tmp_ctx, sc);
> +		ret = fss_sc_expose(fconf_ctx, rconf_ctx, frame, sc);
>  		if (ret) {
>  			DEBUG(0,("failed to expose shadow copy of %s\n",
>  				 sc->volume_name));
> @@ -1252,7 +1244,7 @@ uint32_t _fss_ExposeShadowCopySet(struct pipes_struct *p,
>  	}
>  	/* start message sequence timer */
>  	fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set, &fss_global.seq_tmr);
> -	talloc_free(tmp_ctx);
> +	TALLOC_FREE(frame);
>  	return 0;
>  
>  err_cancel:
> @@ -1261,7 +1253,7 @@ err_cancel:
>  err_tmr_restart:
>  	fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set, &fss_global.seq_tmr);
>  err_out:
> -	talloc_free(tmp_ctx);
> +	TALLOC_FREE(frame);
>  	return ret;
>  }
>  
> @@ -1358,54 +1350,51 @@ uint32_t _fss_IsPathSupported(struct pipes_struct *p,
>  	NTSTATUS status;
>  	struct connection_struct *conn;
>  	char *share;
> -	TALLOC_CTX *tmp_ctx = talloc_new(p->mem_ctx);
> -	if (tmp_ctx == NULL) {
> -		return HRES_ERROR_V(HRES_E_OUTOFMEMORY);
> -	}
> +	TALLOC_CTX *frame = talloc_stackframe();
>  
>  	if (!fss_permitted(p)) {
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_ACCESSDENIED);
>  	}
>  
> -	status = fss_unc_parse(tmp_ctx, r->in.ShareName, NULL, &share);
> +	status = fss_unc_parse(frame, r->in.ShareName, NULL, &share);
>  	if (!NT_STATUS_IS_OK(status)) {
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return fss_ntstatus_map(status);
>  	}
>  
> -	snum = find_service(tmp_ctx, share, &service);
> +	snum = find_service(frame, share, &service);
>  	if ((snum == -1) || (service == NULL)) {
>  		DEBUG(0, ("share at %s not found\n", r->in.ShareName));
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_INVALIDARG);
>  	}
>  
> -	status = fss_vfs_conn_create(tmp_ctx, server_event_context(),
> +	status = fss_vfs_conn_create(frame, server_event_context(),
>  				     p->msg_ctx, p->session_info, snum, &conn);
>  	if (!NT_STATUS_IS_OK(status)) {
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_ACCESSDENIED);
>  	}
>  	if (!become_user_by_session(conn, p->session_info)) {
>  		DEBUG(0, ("failed to become user\n"));
> -		talloc_free(tmp_ctx);
>  		fss_vfs_conn_destroy(conn);
> +		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_ACCESSDENIED);
>  	}
> -	status = SMB_VFS_SNAP_CHECK_PATH(conn, tmp_ctx,
> -					 lp_path(tmp_ctx, snum),
> +	status = SMB_VFS_SNAP_CHECK_PATH(conn, frame,
> +					 lp_path(frame, snum),
>  					 &base_vol);
>  	unbecome_user();
>  	fss_vfs_conn_destroy(conn);
>  	if (!NT_STATUS_IS_OK(status)) {
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return FSRVP_E_NOT_SUPPORTED;
>  	}
>  
>  	*r->out.OwnerMachineName = lp_netbios_name();
>  	*r->out.SupportedByThisProvider = 1;
> -	talloc_free(tmp_ctx);
> +	TALLOC_FREE(frame);
>  	return 0;
>  }
>  
> @@ -1429,20 +1418,16 @@ uint32_t _fss_GetShareMapping(struct pipes_struct *p,
>  	struct fss_sc_smap *sc_smap;
>  	char *share;
>  	struct fssagent_share_mapping_1 *sm_out;
> -
> -	TALLOC_CTX *tmp_ctx = talloc_new(p->mem_ctx);
> -	if (tmp_ctx == NULL) {
> -		return HRES_ERROR_V(HRES_E_OUTOFMEMORY);
> -	}
> +	TALLOC_CTX *frame = talloc_stackframe();
>  
>  	if (!fss_permitted(p)) {
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_ACCESSDENIED);
>  	}
>  
>  	sc_set = sc_set_lookup(fss_global.sc_sets, &r->in.ShadowCopySetId);
>  	if (sc_set == NULL) {
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_INVALIDARG);
>  	}
>  
> @@ -1457,36 +1442,36 @@ uint32_t _fss_GetShareMapping(struct pipes_struct *p,
>  	 || (sc_set->state == FSS_SC_ADDED)
>  	 || (sc_set->state == FSS_SC_CREATING)
>  	 || (sc_set->state == FSS_SC_COMMITED)) {
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return 0x80042311;	/* documented magic value */
>  	}
>  
>  	sc = sc_lookup(sc_set->scs, &r->in.ShadowCopyId);
>  	if (sc == NULL) {
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_INVALIDARG);
>  	}
>  
> -	status = fss_unc_parse(tmp_ctx, r->in.ShareName, NULL, &share);
> +	status = fss_unc_parse(frame, r->in.ShareName, NULL, &share);
>  	if (!NT_STATUS_IS_OK(status)) {
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return fss_ntstatus_map(status);
>  	}
>  
>  	sc_smap = sc_smap_lookup(sc->smaps, share);
>  	if (sc_smap == NULL) {
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_INVALIDARG);
>  	}
>  
>  	if (r->in.Level != 1) {
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_INVALIDARG);
>  	}
>  
>  	sm_out = talloc_zero(p->mem_ctx, struct fssagent_share_mapping_1);
>  	if (sm_out == NULL) {
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_OUTOFMEMORY);
>  	}
>  	sm_out->ShadowCopySetId = sc_set->id;
> @@ -1496,13 +1481,13 @@ uint32_t _fss_GetShareMapping(struct pipes_struct *p,
>  					       sc_smap->share_name);
>  	if (sm_out->ShareNameUNC == NULL) {
>  		talloc_free(sm_out);
> -		talloc_free(tmp_ctx);
> +		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_OUTOFMEMORY);
>  	}
>  	sm_out->ShadowCopyShareName = sc_smap->sc_share_name;
>  	unix_to_nt_time(&sm_out->tstamp, sc->create_ts);
>  	r->out.ShareMapping->ShareMapping1 = sm_out;
> -	talloc_free(tmp_ctx);
> +	TALLOC_FREE(frame);
>  
>  	/* reset msg sequence timer */
>  	TALLOC_FREE(fss_global.seq_tmr);
> @@ -1518,12 +1503,9 @@ static NTSTATUS sc_smap_unexpose(struct messaging_context *msg_ctx,
>  	struct smbconf_ctx *conf_ctx;
>  	sbcErr cerr;
>  	bool is_modified = false;
> -	TALLOC_CTX *tmp_ctx = talloc_new(sc_smap);
> -	if (tmp_ctx == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> +	TALLOC_CTX *frame = talloc_stackframe();
>  
> -	cerr = smbconf_init(tmp_ctx, &conf_ctx, "registry");
> +	cerr = smbconf_init(frame, &conf_ctx, "registry");
>  	if (!SBC_ERROR_IS_OK(cerr)) {
>  		DEBUG(0, ("failed registry smbconf init: %s\n",
>  			  sbcErrorString(cerr)));
> @@ -1588,14 +1570,14 @@ err_conf:
>  	talloc_free(conf_ctx);
>  	unbecome_root();
>  err_tmp:
> -	talloc_free(tmp_ctx);
> +	TALLOC_FREE(frame);
>  	return ret;
>  
>  err_cancel:
>  	smbconf_transaction_cancel(conf_ctx);
>  	talloc_free(conf_ctx);
>  	unbecome_root();
> -	talloc_free(tmp_ctx);
> +	TALLOC_FREE(frame);
>  	return ret;
>  }
>  
> @@ -1607,20 +1589,14 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
>  	struct fss_sc_smap *sc_smap;
>  	char *share;
>  	NTSTATUS status;
> -	TALLOC_CTX *tmp_ctx;
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	struct connection_struct *conn;
>  	int snum;
>  	char *service;
>  
>  	if (!fss_permitted(p)) {
>  		status = NT_STATUS_ACCESS_DENIED;
> -		goto err_out;
> -	}
> -
> -	tmp_ctx = talloc_new(p->mem_ctx);
> -	if (tmp_ctx == NULL) {
> -		status = NT_STATUS_NO_MEMORY;
> -		goto err_out;
> +		goto err_tmp_free;
>  	}
>  
>  	sc_set = sc_set_lookup(fss_global.sc_sets, &r->in.ShadowCopySetId);
> @@ -1642,7 +1618,7 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
>  		goto err_tmp_free;
>  	}
>  
> -	status = fss_unc_parse(tmp_ctx, r->in.ShareName, NULL, &share);
> +	status = fss_unc_parse(frame, r->in.ShareName, NULL, &share);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		goto err_tmp_free;
>  	}
> @@ -1670,14 +1646,14 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
>  		goto err_tmp_free;
>  	}
>  
> -	snum = find_service(tmp_ctx, sc_smap->share_name, &service);
> +	snum = find_service(frame, sc_smap->share_name, &service);
>  	if ((snum == -1) || (service == NULL)) {
>  		DEBUG(0, ("share at %s not found\n", sc_smap->share_name));
>  		status = NT_STATUS_UNSUCCESSFUL;
>  		goto err_tmp_free;
>  	}
>  
> -	status = fss_vfs_conn_create(tmp_ctx, server_event_context(),
> +	status = fss_vfs_conn_create(frame, server_event_context(),
>  				     p->msg_ctx, p->session_info, snum, &conn);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		goto err_tmp_free;
> @@ -1688,7 +1664,7 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
>  		goto err_conn_destroy;
>  	}
>  
> -	status = SMB_VFS_SNAP_DELETE(conn, tmp_ctx, sc->volume_name,
> +	status = SMB_VFS_SNAP_DELETE(conn, frame, sc->volume_name,
>  				     sc->sc_path);
>  	unbecome_user();
>  	if (!NT_STATUS_IS_OK(status)) {
> @@ -1725,8 +1701,7 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
>  err_conn_destroy:
>  	fss_vfs_conn_destroy(conn);
>  err_tmp_free:
> -	talloc_free(tmp_ctx);
> -err_out:
> +	talloc_free(frame);
>  	return fss_ntstatus_map(status);
>  }
>  
> -- 
> 2.17.1
> 
> 
> From ed0348c3cccd9923fe5cf4fb4676d0c24d7b02ac Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:34:18 +0200
> Subject: [PATCH 10/40] s3:rpc_server/fss: make use of create_conn_struct_tos()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/rpc_server/fss/srv_fss_agent.c | 72 +++++++-------------------
>  1 file changed, 20 insertions(+), 52 deletions(-)
> 
> diff --git a/source3/rpc_server/fss/srv_fss_agent.c b/source3/rpc_server/fss/srv_fss_agent.c
> index 846b1047670c..33cbca87d73f 100644
> --- a/source3/rpc_server/fss/srv_fss_agent.c
> +++ b/source3/rpc_server/fss/srv_fss_agent.c
> @@ -132,13 +132,10 @@ static NTSTATUS fss_unc_parse(TALLOC_CTX *mem_ctx,
>  	return NT_STATUS_OK;
>  }
>  
> -static NTSTATUS fss_vfs_conn_create(TALLOC_CTX *mem_ctx,
> -				    struct tevent_context *ev,
> -				    struct messaging_context *msg_ctx,
> +static NTSTATUS fss_conn_create_tos(struct messaging_context *msg_ctx,
>  				    struct auth_session_info *session_info,
>  				    int snum,
>  				    struct connection_struct **conn_out);
> -static void fss_vfs_conn_destroy(struct connection_struct *conn);
>  
>  /* test if system path exists */
>  static bool snap_path_exists(TALLOC_CTX *ctx, struct messaging_context *msg_ctx,
> @@ -168,9 +165,7 @@ static bool snap_path_exists(TALLOC_CTX *ctx, struct messaging_context *msg_ctx,
>  		goto out;
>  	}
>  
> -	status = fss_vfs_conn_create(frame, server_event_context(),
> -				     msg_ctx, NULL, snum, &conn);
> -
> +	status = fss_conn_create_tos(msg_ctx, NULL, snum, &conn);
>  	if(!NT_STATUS_IS_OK(status)) {
>  		goto out;
>  	}
> @@ -186,9 +181,6 @@ static bool snap_path_exists(TALLOC_CTX *ctx, struct messaging_context *msg_ctx,
>  	}
>  	result = true;
>  out:
> -	if (conn) {
> -		fss_vfs_conn_destroy(conn);
> -	}
>  	TALLOC_FREE(frame);
>  	return result;
>  }
> @@ -289,45 +281,34 @@ out:
>  	return status;
>  }
>  
> -static NTSTATUS fss_vfs_conn_create(TALLOC_CTX *mem_ctx,
> -				    struct tevent_context *ev,
> -				    struct messaging_context *msg_ctx,
> +static NTSTATUS fss_conn_create_tos(struct messaging_context *msg_ctx,
>  				    struct auth_session_info *session_info,
>  				    int snum,
>  				    struct connection_struct **conn_out)
>  {
> -	struct connection_struct *conn = NULL;
> +	struct conn_struct_tos *c = NULL;
>  	NTSTATUS status;
>  
> -	status = create_conn_struct(mem_ctx, ev, msg_ctx, &conn,
> -				    snum, lp_path(mem_ctx, snum),
> -				    session_info);
> +	status = create_conn_struct_tos(msg_ctx,
> +					snum,
> +					lp_path(talloc_tos(), snum),
> +					session_info,
> +					&c);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		DEBUG(0,("failed to create conn for vfs: %s\n",
>  			 nt_errstr(status)));
>  		return status;
>  	}
>  
> -	status = set_conn_force_user_group(conn, snum);
> +	status = set_conn_force_user_group(c->conn, snum);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		DEBUG(0, ("failed set force user / group\n"));
> -		goto err_free_conn;
> +		TALLOC_FREE(c);
> +		return status;
>  	}
>  
> -	*conn_out = conn;
> -
> +	*conn_out = c->conn;
>  	return NT_STATUS_OK;
> -
> -err_free_conn:
> -	SMB_VFS_DISCONNECT(conn);
> -	conn_free(conn);
> -	return status;
> -}
> -
> -static void fss_vfs_conn_destroy(struct connection_struct *conn)
> -{
> -	SMB_VFS_DISCONNECT(conn);
> -	conn_free(conn);
>  }
>  
>  static struct fss_sc_set *sc_set_lookup(struct fss_sc_set *sc_set_head,
> @@ -780,22 +761,19 @@ uint32_t _fss_AddToShadowCopySet(struct pipes_struct *p,
>  		goto err_tmp_free;
>  	}
>  
> -	status = fss_vfs_conn_create(frame, server_event_context(),
> -				     p->msg_ctx, p->session_info, snum, &conn);
> +	status = fss_conn_create_tos(p->msg_ctx, p->session_info, snum, &conn);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
>  		goto err_tmp_free;
>  	}
>  	if (!become_user_by_session(conn, p->session_info)) {
>  		DEBUG(0, ("failed to become user\n"));
> -		fss_vfs_conn_destroy(conn);
>  		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
>  		goto err_tmp_free;
>  	}
>  
>  	status = SMB_VFS_SNAP_CHECK_PATH(conn, frame, path_name, &base_vol);
>  	unbecome_user();
> -	fss_vfs_conn_destroy(conn);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		ret = FSRVP_E_NOT_SUPPORTED;
>  		goto err_tmp_free;
> @@ -909,9 +887,7 @@ static NTSTATUS commit_sc_with_conn(TALLOC_CTX *mem_ctx,
>  		return NT_STATUS_UNSUCCESSFUL;
>  	}
>  
> -	status = fss_vfs_conn_create(frame,
> -				     ev, msg_ctx, session_info,
> -				     snum, &conn);
> +	status = fss_conn_create_tos(msg_ctx, session_info, snum, &conn);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		TALLOC_FREE(frame);
>  		return status;
> @@ -919,7 +895,6 @@ static NTSTATUS commit_sc_with_conn(TALLOC_CTX *mem_ctx,
>  
>  	if (!become_user_by_session(conn, session_info)) {
>  		DEBUG(0, ("failed to become user\n"));
> -		fss_vfs_conn_destroy(conn);
>  		TALLOC_FREE(frame);
>  		return NT_STATUS_ACCESS_DENIED;
>  	}
> @@ -929,7 +904,6 @@ static NTSTATUS commit_sc_with_conn(TALLOC_CTX *mem_ctx,
>  				     &sc->create_ts, rw,
>  				     base_path, snap_path);
>  	unbecome_user();
> -	fss_vfs_conn_destroy(conn);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		DEBUG(0, ("snap create failed: %s\n", nt_errstr(status)));
>  		TALLOC_FREE(frame);
> @@ -1370,15 +1344,13 @@ uint32_t _fss_IsPathSupported(struct pipes_struct *p,
>  		return HRES_ERROR_V(HRES_E_INVALIDARG);
>  	}
>  
> -	status = fss_vfs_conn_create(frame, server_event_context(),
> -				     p->msg_ctx, p->session_info, snum, &conn);
> +	status = fss_conn_create_tos(p->msg_ctx, p->session_info, snum, &conn);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_ACCESSDENIED);
>  	}
>  	if (!become_user_by_session(conn, p->session_info)) {
>  		DEBUG(0, ("failed to become user\n"));
> -		fss_vfs_conn_destroy(conn);
>  		TALLOC_FREE(frame);
>  		return HRES_ERROR_V(HRES_E_ACCESSDENIED);
>  	}
> @@ -1386,7 +1358,6 @@ uint32_t _fss_IsPathSupported(struct pipes_struct *p,
>  					 lp_path(frame, snum),
>  					 &base_vol);
>  	unbecome_user();
> -	fss_vfs_conn_destroy(conn);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		TALLOC_FREE(frame);
>  		return FSRVP_E_NOT_SUPPORTED;
> @@ -1653,22 +1624,21 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
>  		goto err_tmp_free;
>  	}
>  
> -	status = fss_vfs_conn_create(frame, server_event_context(),
> -				     p->msg_ctx, p->session_info, snum, &conn);
> +	status = fss_conn_create_tos(p->msg_ctx, p->session_info, snum, &conn);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		goto err_tmp_free;
>  	}
>  	if (!become_user_by_session(conn, p->session_info)) {
>  		DEBUG(0, ("failed to become user\n"));
>  		status = NT_STATUS_ACCESS_DENIED;
> -		goto err_conn_destroy;
> +		goto err_tmp_free;
>  	}
>  
>  	status = SMB_VFS_SNAP_DELETE(conn, frame, sc->volume_name,
>  				     sc->sc_path);
>  	unbecome_user();
>  	if (!NT_STATUS_IS_OK(status)) {
> -		goto err_conn_destroy;
> +		goto err_tmp_free;
>  	}
>  
>  	/* XXX set timeout r->in.TimeOutInMilliseconds */
> @@ -1698,10 +1668,8 @@ uint32_t _fss_DeleteShareMapping(struct pipes_struct *p,
>  	}
>  
>  	status = NT_STATUS_OK;
> -err_conn_destroy:
> -	fss_vfs_conn_destroy(conn);
>  err_tmp_free:
> -	talloc_free(frame);
> +	TALLOC_FREE(frame);
>  	return fss_ntstatus_map(status);
>  }
>  
> -- 
> 2.17.1
> 
> 
> From 4f409859f8948d7ca01dd829c3239bfcab9cfb08 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:40:27 +0200
> Subject: [PATCH 11/40] smbd: add an explicit talloc_stackframe() to
>  {create,remove}_msdfs_link()
> 
> This makes further changes simpler.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index d6fbe93fcbb7..aeae02ed7887 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -1428,6 +1428,7 @@ static bool junction_to_local_path(const struct junction_map *jucn,
>  
>  bool create_msdfs_link(const struct junction_map *jucn)
>  {
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	char *path = NULL;
>  	struct smb_filename *cwd_fname = NULL;
>  	char *msdfs_link = NULL;
> @@ -1438,6 +1439,7 @@ bool create_msdfs_link(const struct junction_map *jucn)
>  	struct smb_filename *smb_fname = NULL;
>  
>  	if(!junction_to_local_path(jucn, &path, &conn, &cwd_fname)) {
> +		TALLOC_FREE(frame);
>  		return False;
>  	}
>  
> @@ -1478,7 +1480,7 @@ bool create_msdfs_link(const struct junction_map *jucn)
>  	DEBUG(5,("create_msdfs_link: Creating new msdfs link: %s -> %s\n",
>  		path, msdfs_link));
>  
> -	smb_fname = synthetic_smb_fname(talloc_tos(),
> +	smb_fname = synthetic_smb_fname(frame,
>  				path,
>  				NULL,
>  				NULL,
> @@ -1506,16 +1508,16 @@ bool create_msdfs_link(const struct junction_map *jucn)
>  	ret = True;
>  
>  out:
> -	TALLOC_FREE(smb_fname);
>  	vfs_ChDir(conn, cwd_fname);
> -	TALLOC_FREE(cwd_fname);
>  	SMB_VFS_DISCONNECT(conn);
>  	conn_free(conn);
> +	TALLOC_FREE(frame);
>  	return ret;
>  }
>  
>  bool remove_msdfs_link(const struct junction_map *jucn)
>  {
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	char *path = NULL;
>  	struct smb_filename *cwd_fname = NULL;
>  	connection_struct *conn;
> @@ -1523,15 +1525,17 @@ bool remove_msdfs_link(const struct junction_map *jucn)
>  	struct smb_filename *smb_fname;
>  
>  	if (!junction_to_local_path(jucn, &path, &conn, &cwd_fname)) {
> +		TALLOC_FREE(frame);
>  		return false;
>  	}
>  
> -	smb_fname = synthetic_smb_fname(talloc_tos(),
> +	smb_fname = synthetic_smb_fname(frame,
>  					path,
>  					NULL,
>  					NULL,
>  					0);
>  	if (smb_fname == NULL) {
> +		TALLOC_FREE(frame);
>  		errno = ENOMEM;
>  		return false;
>  	}
> @@ -1540,11 +1544,10 @@ bool remove_msdfs_link(const struct junction_map *jucn)
>  		ret = True;
>  	}
>  
> -	TALLOC_FREE(smb_fname);
>  	vfs_ChDir(conn, cwd_fname);
> -	TALLOC_FREE(cwd_fname);
>  	SMB_VFS_DISCONNECT(conn);
>  	conn_free(conn);
> +	TALLOC_FREE(frame);
>  	return ret;
>  }
>  
> -- 
> 2.17.1
> 
> 
> From 1ec56e7b0931b0467a716388fc140ac9954cbfa3 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:40:27 +0200
> Subject: [PATCH 12/40] smbd: add an explicit talloc_stackframe() to
>  get_referred_path()
> 
> This makes further changes simpler.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 40 +++++++++++++++++++++-------------------
>  1 file changed, 21 insertions(+), 19 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index aeae02ed7887..c5e80b1ef989 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -1082,15 +1082,17 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
>  			   int *consumedcntp,
>  			   bool *self_referralp)
>  {
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	struct connection_struct *conn;
>  	char *targetpath = NULL;
>  	int snum;
>  	NTSTATUS status = NT_STATUS_NOT_FOUND;
>  	bool dummy;
> -	struct dfs_path *pdp = talloc(ctx, struct dfs_path);
> +	struct dfs_path *pdp = talloc_zero(frame, struct dfs_path);
>  	struct smb_filename *oldcwd_fname = NULL;
>  
>  	if (!pdp) {
> +		TALLOC_FREE(frame);
>  		return NT_STATUS_NO_MEMORY;
>  	}
>  
> @@ -1099,13 +1101,14 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
>  	status = parse_dfs_path(NULL, dfs_path, False, allow_broken_path,
>  				pdp, &dummy);
>  	if (!NT_STATUS_IS_OK(status)) {
> +		TALLOC_FREE(frame);
>  		return status;
>  	}
>  
>  	jucn->service_name = talloc_strdup(ctx, pdp->servicename);
>  	jucn->volume_name = talloc_strdup(ctx, pdp->reqpath);
>  	if (!jucn->service_name || !jucn->volume_name) {
> -		TALLOC_FREE(pdp);
> +		TALLOC_FREE(frame);
>  		return NT_STATUS_NO_MEMORY;
>  	}
>  
> @@ -1114,15 +1117,17 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
>  	if(snum < 0) {
>  		char *service_name = NULL;
>  		if ((snum = find_service(ctx, jucn->service_name, &service_name)) < 0) {
> +			TALLOC_FREE(frame);
>  			return NT_STATUS_NOT_FOUND;
>  		}
>  		if (!service_name) {
> +			TALLOC_FREE(frame);
>  			return NT_STATUS_NO_MEMORY;
>  		}
>  		TALLOC_FREE(jucn->service_name);
>  		jucn->service_name = talloc_strdup(ctx, service_name);
>  		if (!jucn->service_name) {
> -			TALLOC_FREE(pdp);
> +			TALLOC_FREE(frame);
>  			return NT_STATUS_NO_MEMORY;
>  		}
>  	}
> @@ -1131,7 +1136,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
>  		DEBUG(3,("get_referred_path: |%s| in dfs path %s is not "
>  			"a dfs root.\n",
>  			pdp->servicename, dfs_path));
> -		TALLOC_FREE(pdp);
> +		TALLOC_FREE(frame);
>  		return NT_STATUS_NOT_FOUND;
>  	}
>  
> @@ -1149,7 +1154,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
>  		int refcount;
>  
>  		if (*lp_msdfs_proxy(talloc_tos(), snum) == '\0') {
> -			TALLOC_FREE(pdp);
> +			TALLOC_FREE(frame);
>  			return self_ref(ctx,
>  					dfs_path,
>  					jucn,
> @@ -1162,36 +1167,34 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
>   		 * the configured target share.
>   		 */
>  
> -		tmp = talloc_asprintf(talloc_tos(), "msdfs:%s",
> -				      lp_msdfs_proxy(talloc_tos(), snum));
> +		tmp = talloc_asprintf(frame, "msdfs:%s",
> +				      lp_msdfs_proxy(frame, snum));
>  		if (tmp == NULL) {
> -			TALLOC_FREE(pdp);
> +			TALLOC_FREE(frame);
>  			return NT_STATUS_NO_MEMORY;
>  		}
>  
>  		if (!parse_msdfs_symlink(ctx, snum, tmp, &ref, &refcount)) {
> -			TALLOC_FREE(tmp);
> -			TALLOC_FREE(pdp);
> +			TALLOC_FREE(frame);
>  			return NT_STATUS_INVALID_PARAMETER;
>  		}
> -		TALLOC_FREE(tmp);
>  		jucn->referral_count = refcount;
>  		jucn->referral_list = ref;
>  		*consumedcntp = strlen(dfs_path);
> -		TALLOC_FREE(pdp);
> +		TALLOC_FREE(frame);
>  		return NT_STATUS_OK;
>  	}
>  
> -	status = create_conn_struct_cwd(ctx,
> +	status = create_conn_struct_cwd(frame,
>  					server_event_context(),
>  					server_messaging_context(),
>  					&conn,
>  					snum,
> -					lp_path(talloc_tos(), snum),
> +					lp_path(frame, snum),
>  					NULL,
>  					&oldcwd_fname);
>  	if (!NT_STATUS_IS_OK(status)) {
> -		TALLOC_FREE(pdp);
> +		TALLOC_FREE(frame);
>  		return status;
>  	}
>  
> @@ -1205,7 +1208,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
>  		conn->sconn->remote_address =
>  			tsocket_address_copy(remote_address, conn->sconn);
>  		if (conn->sconn->remote_address == NULL) {
> -			TALLOC_FREE(pdp);
> +			TALLOC_FREE(frame);
>  			return NT_STATUS_NO_MEMORY;
>  		}
>  	}
> @@ -1213,7 +1216,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
>  		conn->sconn->local_address =
>  			tsocket_address_copy(local_address, conn->sconn);
>  		if (conn->sconn->local_address == NULL) {
> -			TALLOC_FREE(pdp);
> +			TALLOC_FREE(frame);
>  			return NT_STATUS_NO_MEMORY;
>  		}
>  	}
> @@ -1256,10 +1259,9 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
>  	status = NT_STATUS_OK;
>   err_exit:
>  	vfs_ChDir(conn, oldcwd_fname);
> -	TALLOC_FREE(oldcwd_fname);
>  	SMB_VFS_DISCONNECT(conn);
>  	conn_free(conn);
> -	TALLOC_FREE(pdp);
> +	TALLOC_FREE(frame);
>  	return status;
>  }
>  
> -- 
> 2.17.1
> 
> 
> From b137f63352c8e0c3a75d5b57411dedb093165f5e Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:40:27 +0200
> Subject: [PATCH 13/40] smbd: add an explicit talloc_stackframe() to
>  count_dfs_links()
> 
> This makes further changes simpler.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index c5e80b1ef989..4e20358f5670 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -1559,18 +1559,20 @@ bool remove_msdfs_link(const struct junction_map *jucn)
>  
>  static int count_dfs_links(TALLOC_CTX *ctx, int snum)
>  {
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	size_t cnt = 0;
>  	DIR *dirp = NULL;
>  	const char *dname = NULL;
>  	char *talloced = NULL;
> -	const char *connect_path = lp_path(talloc_tos(), snum);
> -	const char *msdfs_proxy = lp_msdfs_proxy(talloc_tos(), snum);
> +	const char *connect_path = lp_path(frame, snum);
> +	const char *msdfs_proxy = lp_msdfs_proxy(frame, snum);
>  	connection_struct *conn;
>  	NTSTATUS status;
>  	struct smb_filename *cwd_fname = NULL;
>  	struct smb_filename *smb_fname = NULL;
>  
>  	if(*connect_path == '\0') {
> +		TALLOC_FREE(frame);
>  		return 0;
>  	}
>  
> @@ -1578,7 +1580,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
>  	 * Fake up a connection struct for the VFS layer.
>  	 */
>  
> -	status = create_conn_struct_cwd(talloc_tos(),
> +	status = create_conn_struct_cwd(frame,
>  					server_event_context(),
>  					server_messaging_context(),
>  					&conn,
> @@ -1589,6 +1591,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
>  	if (!NT_STATUS_IS_OK(status)) {
>  		DEBUG(3, ("create_conn_struct failed: %s\n",
>  			  nt_errstr(status)));
> +		TALLOC_FREE(frame);
>  		return 0;
>  	}
>  
> @@ -1600,7 +1603,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
>  		goto out;
>  	}
>  
> -	smb_fname = synthetic_smb_fname(talloc_tos(),
> +	smb_fname = synthetic_smb_fname(frame,
>  					".",
>  					NULL,
>  					NULL,
> @@ -1618,7 +1621,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
>  	while ((dname = vfs_readdirname(conn, dirp, NULL, &talloced))
>  	       != NULL) {
>  		struct smb_filename *smb_dname =
> -			synthetic_smb_fname(talloc_tos(),
> +			synthetic_smb_fname(frame,
>  					dname,
>  					NULL,
>  					NULL,
> @@ -1636,11 +1639,10 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
>  	SMB_VFS_CLOSEDIR(conn,dirp);
>  
>  out:
> -	TALLOC_FREE(smb_fname);
>  	vfs_ChDir(conn, cwd_fname);
> -	TALLOC_FREE(cwd_fname);
>  	SMB_VFS_DISCONNECT(conn);
>  	conn_free(conn);
> +	TALLOC_FREE(frame);
>  	return cnt;
>  }
>  
> -- 
> 2.17.1
> 
> 
> From cb38420a01345193e127930ed5097ea2685cf778 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:40:27 +0200
> Subject: [PATCH 14/40] smbd: add an explicit talloc_stackframe() to
>  form_junctions()
> 
> This makes further changes simpler.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 17 ++++++++++-------
>  1 file changed, 10 insertions(+), 7 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index 4e20358f5670..53a4dd2dfcc9 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -1654,13 +1654,14 @@ static int form_junctions(TALLOC_CTX *ctx,
>  				struct junction_map *jucn,
>  				size_t jn_remain)
>  {
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	size_t cnt = 0;
>  	DIR *dirp = NULL;
>  	const char *dname = NULL;
>  	char *talloced = NULL;
> -	const char *connect_path = lp_path(talloc_tos(), snum);
> -	char *service_name = lp_servicename(talloc_tos(), snum);
> -	const char *msdfs_proxy = lp_msdfs_proxy(talloc_tos(), snum);
> +	const char *connect_path = lp_path(frame, snum);
> +	char *service_name = lp_servicename(frame, snum);
> +	const char *msdfs_proxy = lp_msdfs_proxy(frame, snum);
>  	connection_struct *conn;
>  	struct referral *ref = NULL;
>  	struct smb_filename *cwd_fname = NULL;
> @@ -1668,10 +1669,12 @@ static int form_junctions(TALLOC_CTX *ctx,
>  	NTSTATUS status;
>  
>  	if (jn_remain == 0) {
> +		TALLOC_FREE(frame);
>  		return 0;
>  	}
>  
>  	if(*connect_path == '\0') {
> +		TALLOC_FREE(frame);
>  		return 0;
>  	}
>  
> @@ -1679,7 +1682,7 @@ static int form_junctions(TALLOC_CTX *ctx,
>  	 * Fake up a connection struct for the VFS layer.
>  	 */
>  
> -	status = create_conn_struct_cwd(ctx,
> +	status = create_conn_struct_cwd(frame,
>  					server_event_context(),
>  					server_messaging_context(),
>  					&conn,
> @@ -1690,6 +1693,7 @@ static int form_junctions(TALLOC_CTX *ctx,
>  	if (!NT_STATUS_IS_OK(status)) {
>  		DEBUG(3, ("create_conn_struct failed: %s\n",
>  			  nt_errstr(status)));
> +		TALLOC_FREE(frame);
>  		return 0;
>  	}
>  
> @@ -1732,7 +1736,7 @@ static int form_junctions(TALLOC_CTX *ctx,
>  		goto out;
>  	}
>  
> -	smb_fname = synthetic_smb_fname(talloc_tos(),
> +	smb_fname = synthetic_smb_fname(frame,
>  					".",
>  					NULL,
>  					NULL,
> @@ -1799,10 +1803,9 @@ out:
>  		SMB_VFS_CLOSEDIR(conn,dirp);
>  	}
>  
> -	TALLOC_FREE(smb_fname);
>  	vfs_ChDir(conn, cwd_fname);
> -	TALLOC_FREE(cwd_fname);
>  	conn_free(conn);
> +	TALLOC_FREE(frame);
>  	return cnt;
>  }
>  
> -- 
> 2.17.1
> 
> 
> From 59c39fe069ac4e3cb8a9b51da0555ebf3bc90bff Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:55:02 +0200
> Subject: [PATCH 15/40] smbd: convert junction_to_local_path() to use
>  create_conn_struct_tos_cwd()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 48 +++++++++++++++++++-------------------------
>  1 file changed, 21 insertions(+), 27 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index 53a4dd2dfcc9..cfa9e7602b71 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -1391,40 +1391,38 @@ bool create_junction(TALLOC_CTX *ctx,
>   Forms a valid Unix pathname from the junction
>   **********************************************************************/
>  
> -static bool junction_to_local_path(const struct junction_map *jucn,
> -				   char **pp_path_out,
> -				   connection_struct **conn_out,
> -				   struct smb_filename **oldpath_fname)
> +static bool junction_to_local_path_tos(const struct junction_map *jucn,
> +				       char **pp_path_out,
> +				       connection_struct **conn_out)
>  {
> +	struct conn_struct_tos *c = NULL;
>  	int snum;
> +	char *path_out = NULL;
>  	NTSTATUS status;
>  
>  	snum = lp_servicenumber(jucn->service_name);
>  	if(snum < 0) {
>  		return False;
>  	}
> -	status = create_conn_struct_cwd(talloc_tos(),
> -					server_event_context(),
> -					server_messaging_context(),
> -					conn_out,
> -					snum,
> -					lp_path(talloc_tos(), snum),
> -					NULL,
> -					oldpath_fname);
> +	status = create_conn_struct_tos_cwd(server_messaging_context(),
> +					    snum,
> +					    lp_path(talloc_tos(), snum),
> +					    NULL,
> +					    &c);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		return False;
>  	}
>  
> -	*pp_path_out = talloc_asprintf(*conn_out,
> +	path_out = talloc_asprintf(c,
>  			"%s/%s",
>  			lp_path(talloc_tos(), snum),
>  			jucn->volume_name);
> -	if (!*pp_path_out) {
> -		vfs_ChDir(*conn_out, *oldpath_fname);
> -		SMB_VFS_DISCONNECT(*conn_out);
> -		conn_free(*conn_out);
> +	if (path_out == NULL) {
> +		TALLOC_FREE(c);
>  		return False;
>  	}
> +	*pp_path_out = path_out;
> +	*conn_out = c->conn;
>  	return True;
>  }
>  
> @@ -1432,15 +1430,16 @@ bool create_msdfs_link(const struct junction_map *jucn)
>  {
>  	TALLOC_CTX *frame = talloc_stackframe();
>  	char *path = NULL;
> -	struct smb_filename *cwd_fname = NULL;
>  	char *msdfs_link = NULL;
>  	connection_struct *conn;
>  	int i=0;
>  	bool insert_comma = False;
>  	bool ret = False;
>  	struct smb_filename *smb_fname = NULL;
> +	bool ok;
>  
> -	if(!junction_to_local_path(jucn, &path, &conn, &cwd_fname)) {
> +	ok = junction_to_local_path_tos(jucn, &path, &conn);
> +	if (!ok) {
>  		TALLOC_FREE(frame);
>  		return False;
>  	}
> @@ -1510,9 +1509,6 @@ bool create_msdfs_link(const struct junction_map *jucn)
>  	ret = True;
>  
>  out:
> -	vfs_ChDir(conn, cwd_fname);
> -	SMB_VFS_DISCONNECT(conn);
> -	conn_free(conn);
>  	TALLOC_FREE(frame);
>  	return ret;
>  }
> @@ -1521,12 +1517,13 @@ bool remove_msdfs_link(const struct junction_map *jucn)
>  {
>  	TALLOC_CTX *frame = talloc_stackframe();
>  	char *path = NULL;
> -	struct smb_filename *cwd_fname = NULL;
>  	connection_struct *conn;
>  	bool ret = False;
>  	struct smb_filename *smb_fname;
> +	bool ok;
>  
> -	if (!junction_to_local_path(jucn, &path, &conn, &cwd_fname)) {
> +	ok = junction_to_local_path_tos(jucn, &path, &conn);
> +	if (!ok) {
>  		TALLOC_FREE(frame);
>  		return false;
>  	}
> @@ -1546,9 +1543,6 @@ bool remove_msdfs_link(const struct junction_map *jucn)
>  		ret = True;
>  	}
>  
> -	vfs_ChDir(conn, cwd_fname);
> -	SMB_VFS_DISCONNECT(conn);
> -	conn_free(conn);
>  	TALLOC_FREE(frame);
>  	return ret;
>  }
> -- 
> 2.17.1
> 
> 
> From 58bcb0e9adb7e454107ac680068f159bce8f855e Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:55:02 +0200
> Subject: [PATCH 16/40] smbd: convert get_referred_path() to use
>  create_conn_struct_tos_cwd()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 21 ++++++++-------------
>  1 file changed, 8 insertions(+), 13 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index cfa9e7602b71..fcf7b9c3dda0 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -1083,13 +1083,13 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
>  			   bool *self_referralp)
>  {
>  	TALLOC_CTX *frame = talloc_stackframe();
> -	struct connection_struct *conn;
> +	struct conn_struct_tos *c = NULL;
> +	struct connection_struct *conn = NULL;
>  	char *targetpath = NULL;
>  	int snum;
>  	NTSTATUS status = NT_STATUS_NOT_FOUND;
>  	bool dummy;
>  	struct dfs_path *pdp = talloc_zero(frame, struct dfs_path);
> -	struct smb_filename *oldcwd_fname = NULL;
>  
>  	if (!pdp) {
>  		TALLOC_FREE(frame);
> @@ -1185,18 +1185,16 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
>  		return NT_STATUS_OK;
>  	}
>  
> -	status = create_conn_struct_cwd(frame,
> -					server_event_context(),
> -					server_messaging_context(),
> -					&conn,
> -					snum,
> -					lp_path(frame, snum),
> -					NULL,
> -					&oldcwd_fname);
> +	status = create_conn_struct_tos_cwd(server_messaging_context(),
> +					    snum,
> +					    lp_path(frame, snum),
> +					    NULL,
> +					    &c);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		TALLOC_FREE(frame);
>  		return status;
>  	}
> +	conn = c->conn;
>  
>  	/*
>  	 * TODO
> @@ -1258,9 +1256,6 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
>  
>  	status = NT_STATUS_OK;
>   err_exit:
> -	vfs_ChDir(conn, oldcwd_fname);
> -	SMB_VFS_DISCONNECT(conn);
> -	conn_free(conn);
>  	TALLOC_FREE(frame);
>  	return status;
>  }
> -- 
> 2.17.1
> 
> 
> From fbe4fc826038a2e35f9af9abc696ba20ec46147d Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:55:02 +0200
> Subject: [PATCH 17/40] smbd: convert count_dfs_links() to use
>  create_conn_struct_tos_cwd()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 21 ++++++++-------------
>  1 file changed, 8 insertions(+), 13 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index fcf7b9c3dda0..57e5b2072392 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -1555,9 +1555,9 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
>  	char *talloced = NULL;
>  	const char *connect_path = lp_path(frame, snum);
>  	const char *msdfs_proxy = lp_msdfs_proxy(frame, snum);
> -	connection_struct *conn;
> +	struct conn_struct_tos *c = NULL;
> +	connection_struct *conn = NULL;
>  	NTSTATUS status;
> -	struct smb_filename *cwd_fname = NULL;
>  	struct smb_filename *smb_fname = NULL;
>  
>  	if(*connect_path == '\0') {
> @@ -1569,20 +1569,18 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
>  	 * Fake up a connection struct for the VFS layer.
>  	 */
>  
> -	status = create_conn_struct_cwd(frame,
> -					server_event_context(),
> -					server_messaging_context(),
> -					&conn,
> -					snum,
> -					connect_path,
> -					NULL,
> -					&cwd_fname);
> +	status = create_conn_struct_tos_cwd(server_messaging_context(),
> +					    snum,
> +					    connect_path,
> +					    NULL,
> +					    &c);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		DEBUG(3, ("create_conn_struct failed: %s\n",
>  			  nt_errstr(status)));
>  		TALLOC_FREE(frame);
>  		return 0;
>  	}
> +	conn = c->conn;
>  
>  	/* Count a link for the msdfs root - convention */
>  	cnt = 1;
> @@ -1628,9 +1626,6 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
>  	SMB_VFS_CLOSEDIR(conn,dirp);
>  
>  out:
> -	vfs_ChDir(conn, cwd_fname);
> -	SMB_VFS_DISCONNECT(conn);
> -	conn_free(conn);
>  	TALLOC_FREE(frame);
>  	return cnt;
>  }
> -- 
> 2.17.1
> 
> 
> From 24fd88fef84fd001df68dcab1f6fc4934e2c6df2 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:55:02 +0200
> Subject: [PATCH 18/40] smbd: convert form_junctions() to use
>  create_conn_struct_tos_cwd()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 20 ++++++++------------
>  1 file changed, 8 insertions(+), 12 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index 57e5b2072392..18fae96f2e58 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -1646,9 +1646,9 @@ static int form_junctions(TALLOC_CTX *ctx,
>  	const char *connect_path = lp_path(frame, snum);
>  	char *service_name = lp_servicename(frame, snum);
>  	const char *msdfs_proxy = lp_msdfs_proxy(frame, snum);
> -	connection_struct *conn;
> +	struct conn_struct_tos *c = NULL;
> +	connection_struct *conn = NULL;
>  	struct referral *ref = NULL;
> -	struct smb_filename *cwd_fname = NULL;
>  	struct smb_filename *smb_fname = NULL;
>  	NTSTATUS status;
>  
> @@ -1666,20 +1666,18 @@ static int form_junctions(TALLOC_CTX *ctx,
>  	 * Fake up a connection struct for the VFS layer.
>  	 */
>  
> -	status = create_conn_struct_cwd(frame,
> -					server_event_context(),
> -					server_messaging_context(),
> -					&conn,
> -					snum,
> -					connect_path,
> -					NULL,
> -					&cwd_fname);
> +	status = create_conn_struct_tos_cwd(server_messaging_context(),
> +					    snum,
> +					    connect_path,
> +					    NULL,
> +					    &c);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		DEBUG(3, ("create_conn_struct failed: %s\n",
>  			  nt_errstr(status)));
>  		TALLOC_FREE(frame);
>  		return 0;
>  	}
> +	conn = c->conn;
>  
>  	/* form a junction for the msdfs root - convention
>  	   DO NOT REMOVE THIS: NT clients will not work with us
> @@ -1787,8 +1785,6 @@ out:
>  		SMB_VFS_CLOSEDIR(conn,dirp);
>  	}
>  
> -	vfs_ChDir(conn, cwd_fname);
> -	conn_free(conn);
>  	TALLOC_FREE(frame);
>  	return cnt;
>  }
> -- 
> 2.17.1
> 
> 
> From a8db5fce195e3c1fac9651dddff2fa0ede0ec8ef Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:40:27 +0200
> Subject: [PATCH 19/40] s3:rpc_server/srvsvc: add an explicit
>  talloc_stackframe() to _srvsvc_NetGetFileSecurity()
> 
> This makes further changes simpler.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 13 ++++++-------
>  1 file changed, 6 insertions(+), 7 deletions(-)
> 
> diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> index c25abf01ac97..3eb9734507dd 100644
> --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> @@ -2314,6 +2314,7 @@ WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
>  WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
>  				  struct srvsvc_NetGetFileSecurity *r)
>  {
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	struct smb_filename *smb_fname = NULL;
>  	size_t sd_size;
>  	char *servicename = NULL;
> @@ -2333,7 +2334,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
>  		werr = WERR_NERR_NETNAMENOTFOUND;
>  		goto error_exit;
>  	}
> -	snum = find_service(talloc_tos(), r->in.share, &servicename);
> +	snum = find_service(frame, r->in.share, &servicename);
>  	if (!servicename) {
>  		werr = WERR_NOT_ENOUGH_MEMORY;
>  		goto error_exit;
> @@ -2344,11 +2345,11 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
>  		goto error_exit;
>  	}
>  
> -	nt_status = create_conn_struct_cwd(talloc_tos(),
> +	nt_status = create_conn_struct_cwd(frame,
>  					   server_event_context(),
>  					   server_messaging_context(),
>  					   &conn,
> -					   snum, lp_path(talloc_tos(), snum),
> +					   snum, lp_path(frame, snum),
>  					   p->session_info, &oldcwd_fname);
>  	if (!NT_STATUS_IS_OK(nt_status)) {
>  		DEBUG(10, ("create_conn_struct failed: %s\n",
> @@ -2357,7 +2358,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
>  		goto error_exit;
>  	}
>  
> -	nt_status = filename_convert(talloc_tos(),
> +	nt_status = filename_convert(frame,
>  					conn,
>  					r->in.file,
>  					ucf_flags,
> @@ -2434,7 +2435,6 @@ error_exit:
>  
>  	if (oldcwd_fname) {
>                  vfs_ChDir(conn, oldcwd_fname);
> -                TALLOC_FREE(oldcwd_fname);
>  	}
>  
>  	if (conn) {
> @@ -2442,8 +2442,7 @@ error_exit:
>  		conn_free(conn);
>  	}
>  
> -	TALLOC_FREE(smb_fname);
> -
> +	TALLOC_FREE(frame);
>  	return werr;
>  }
>  
> -- 
> 2.17.1
> 
> 
> From 6247d2a5bf02b0a5cb0e13aad19cb87d806b2ebe Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:40:27 +0200
> Subject: [PATCH 20/40] s3:rpc_server/srvsvc: add an explicit
>  talloc_stackframe() to _srvsvc_NetSetFileSecurity()
> 
> This makes further changes simpler.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 13 ++++++-------
>  1 file changed, 6 insertions(+), 7 deletions(-)
> 
> diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> index 3eb9734507dd..15bfdafa024a 100644
> --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> @@ -2454,6 +2454,7 @@ error_exit:
>  WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
>  				  struct srvsvc_NetSetFileSecurity *r)
>  {
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	struct smb_filename *smb_fname = NULL;
>  	char *servicename = NULL;
>  	files_struct *fsp = NULL;
> @@ -2474,7 +2475,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
>  		goto error_exit;
>  	}
>  
> -	snum = find_service(talloc_tos(), r->in.share, &servicename);
> +	snum = find_service(frame, r->in.share, &servicename);
>  	if (!servicename) {
>  		werr = WERR_NOT_ENOUGH_MEMORY;
>  		goto error_exit;
> @@ -2486,11 +2487,11 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
>  		goto error_exit;
>  	}
>  
> -	nt_status = create_conn_struct_cwd(talloc_tos(),
> +	nt_status = create_conn_struct_cwd(frame,
>  					   server_event_context(),
>  					   server_messaging_context(),
>  					   &conn,
> -					   snum, lp_path(talloc_tos(), snum),
> +					   snum, lp_path(frame, snum),
>  					   p->session_info, &oldcwd_fname);
>  	if (!NT_STATUS_IS_OK(nt_status)) {
>  		DEBUG(10, ("create_conn_struct failed: %s\n",
> @@ -2499,7 +2500,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
>  		goto error_exit;
>  	}
>  
> -	nt_status = filename_convert(talloc_tos(),
> +	nt_status = filename_convert(frame,
>  					conn,
>  					r->in.file,
>  					ucf_flags,
> @@ -2559,7 +2560,6 @@ error_exit:
>  
>  	if (oldcwd_fname) {
>  		vfs_ChDir(conn, oldcwd_fname);
> -		TALLOC_FREE(oldcwd_fname);
>  	}
>  
>  	if (conn) {
> @@ -2567,8 +2567,7 @@ error_exit:
>  		conn_free(conn);
>  	}
>  
> -	TALLOC_FREE(smb_fname);
> -
> +	TALLOC_FREE(frame);
>  	return werr;
>  }
>  
> -- 
> 2.17.1
> 
> 
> From 8229f1d759620ce252bcb0d463c30df4c711f97b Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:55:02 +0200
> Subject: [PATCH 21/40] s3:rpc_server/srvsvc: convert form_junctions() to use
>  _srvsvc_NetGetFileSecurity()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 23 +++++++----------------
>  1 file changed, 7 insertions(+), 16 deletions(-)
> 
> diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> index 15bfdafa024a..e11471e345ac 100644
> --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> @@ -2321,11 +2321,11 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
>  	SMB_STRUCT_STAT st;
>  	NTSTATUS nt_status;
>  	WERROR werr;
> +	struct conn_struct_tos *c = NULL;
>  	connection_struct *conn = NULL;
>  	struct sec_desc_buf *sd_buf = NULL;
>  	files_struct *fsp = NULL;
>  	int snum;
> -	struct smb_filename *oldcwd_fname = NULL;
>  	uint32_t ucf_flags = 0;
>  
>  	ZERO_STRUCT(st);
> @@ -2345,18 +2345,18 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
>  		goto error_exit;
>  	}
>  
> -	nt_status = create_conn_struct_cwd(frame,
> -					   server_event_context(),
> -					   server_messaging_context(),
> -					   &conn,
> -					   snum, lp_path(frame, snum),
> -					   p->session_info, &oldcwd_fname);
> +	nt_status = create_conn_struct_tos_cwd(server_messaging_context(),
> +					       snum,
> +					       lp_path(frame, snum),
> +					       p->session_info,
> +					       &c);
>  	if (!NT_STATUS_IS_OK(nt_status)) {
>  		DEBUG(10, ("create_conn_struct failed: %s\n",
>  			   nt_errstr(nt_status)));
>  		werr = ntstatus_to_werror(nt_status);
>  		goto error_exit;
>  	}
> +	conn = c->conn;
>  
>  	nt_status = filename_convert(frame,
>  					conn,
> @@ -2433,15 +2433,6 @@ error_exit:
>  		close_file(NULL, fsp, NORMAL_CLOSE);
>  	}
>  
> -	if (oldcwd_fname) {
> -                vfs_ChDir(conn, oldcwd_fname);
> -	}
> -
> -	if (conn) {
> -		SMB_VFS_DISCONNECT(conn);
> -		conn_free(conn);
> -	}
> -
>  	TALLOC_FREE(frame);
>  	return werr;
>  }
> -- 
> 2.17.1
> 
> 
> From d4c08b2b88cae66f59f01fdb0614ef694ff08664 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:55:02 +0200
> Subject: [PATCH 22/40] s3:rpc_server/srvsvc: convert form_junctions() to use
>  _srvsvc_NetSetFileSecurity()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 23 +++++++----------------
>  1 file changed, 7 insertions(+), 16 deletions(-)
> 
> diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> index e11471e345ac..e1963a40a0ce 100644
> --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
> @@ -2452,9 +2452,9 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
>  	SMB_STRUCT_STAT st;
>  	NTSTATUS nt_status;
>  	WERROR werr;
> +	struct conn_struct_tos *c = NULL;
>  	connection_struct *conn = NULL;
>  	int snum;
> -	struct smb_filename *oldcwd_fname = NULL;
>  	struct security_descriptor *psd = NULL;
>  	uint32_t security_info_sent = 0;
>  	uint32_t ucf_flags = 0;
> @@ -2478,18 +2478,18 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
>  		goto error_exit;
>  	}
>  
> -	nt_status = create_conn_struct_cwd(frame,
> -					   server_event_context(),
> -					   server_messaging_context(),
> -					   &conn,
> -					   snum, lp_path(frame, snum),
> -					   p->session_info, &oldcwd_fname);
> +	nt_status = create_conn_struct_tos_cwd(server_messaging_context(),
> +					       snum,
> +					       lp_path(frame, snum),
> +					       p->session_info,
> +					       &c);
>  	if (!NT_STATUS_IS_OK(nt_status)) {
>  		DEBUG(10, ("create_conn_struct failed: %s\n",
>  			   nt_errstr(nt_status)));
>  		werr = ntstatus_to_werror(nt_status);
>  		goto error_exit;
>  	}
> +	conn = c->conn;
>  
>  	nt_status = filename_convert(frame,
>  					conn,
> @@ -2549,15 +2549,6 @@ error_exit:
>  		close_file(NULL, fsp, NORMAL_CLOSE);
>  	}
>  
> -	if (oldcwd_fname) {
> -		vfs_ChDir(conn, oldcwd_fname);
> -	}
> -
> -	if (conn) {
> -		SMB_VFS_DISCONNECT(conn);
> -		conn_free(conn);
> -	}
> -
>  	TALLOC_FREE(frame);
>  	return werr;
>  }
> -- 
> 2.17.1
> 
> 
> From d9d7400f59808db8b9ca4bd01021abd054ab22bb Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:40:27 +0200
> Subject: [PATCH 23/40] printing: add more 'const' to read only input pointers
> 
> This makes it clearer that they won't be changed.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/include/nt_printing.h  |  8 ++++----
>  source3/printing/nt_printing.c | 12 ++++++------
>  2 files changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h
> index 688c6b9969e3..f01ffe5b32ff 100644
> --- a/source3/include/nt_printing.h
> +++ b/source3/include/nt_printing.h
> @@ -164,13 +164,13 @@ bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
>  bool delete_driver_files(const struct auth_session_info *server_info,
>  			 const struct spoolss_DriverInfo8 *r);
>  
> -WERROR move_driver_to_download_area(struct auth_session_info *session_info,
> -				    struct spoolss_AddDriverInfoCtr *r,
> +WERROR move_driver_to_download_area(const struct auth_session_info *session_info,
> +				    const struct spoolss_AddDriverInfoCtr *r,
>  				    const char *driver_directory);
>  
>  WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
> -			      struct auth_session_info *session_info,
> -			      struct spoolss_AddDriverInfoCtr *r,
> +			      const struct auth_session_info *session_info,
> +			      const struct spoolss_AddDriverInfoCtr *r,
>  			      uint32_t flags,
>  			      const char **driver_directory);
>  
> diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
> index 1639bfd44066..52bba6fcb3d7 100644
> --- a/source3/printing/nt_printing.c
> +++ b/source3/printing/nt_printing.c
> @@ -980,7 +980,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
>  /****************************************************************************
>  Determine the correct cVersion associated with an architecture and driver
>  ****************************************************************************/
> -static uint32_t get_correct_cversion(struct auth_session_info *session_info,
> +static uint32_t get_correct_cversion(const struct auth_session_info *session_info,
>  				   const char *architecture,
>  				   const char *driverpath_in,
>  				   const char *driver_directory,
> @@ -1191,7 +1191,7 @@ static uint32_t get_correct_cversion(struct auth_session_info *session_info,
>  } while (0);
>  
>  static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
> -					   struct auth_session_info *session_info,
> +					   const struct auth_session_info *session_info,
>  					   const char *architecture,
>  					   const char **driver_path,
>  					   const char **data_file,
> @@ -1306,8 +1306,8 @@ static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
>  ****************************************************************************/
>  
>  WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
> -			      struct auth_session_info *session_info,
> -			      struct spoolss_AddDriverInfoCtr *r,
> +			      const struct auth_session_info *session_info,
> +			      const struct spoolss_AddDriverInfoCtr *r,
>  			      uint32_t flags,
>  			      const char **driver_directory)
>  {
> @@ -1472,8 +1472,8 @@ static WERROR move_driver_file_to_download_area(TALLOC_CTX *mem_ctx,
>  	return ret;
>  }
>  
> -WERROR move_driver_to_download_area(struct auth_session_info *session_info,
> -				    struct spoolss_AddDriverInfoCtr *r,
> +WERROR move_driver_to_download_area(const struct auth_session_info *session_info,
> +				    const struct spoolss_AddDriverInfoCtr *r,
>  				    const char *driver_directory)
>  {
>  	struct spoolss_AddDriverInfo3 *driver;
> -- 
> 2.17.1
> 
> 
> From 3f6653cdeea7d5e8e0a7ec2c848b185337fc83ae Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:40:27 +0200
> Subject: [PATCH 24/40] printing: add an explicit talloc_stackframe() to
>  get_correct_cversion()
> 
> This makes further changes simpler.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/printing/nt_printing.c | 20 +++++++++++++-------
>  1 file changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
> index 52bba6fcb3d7..5c4488009265 100644
> --- a/source3/printing/nt_printing.c
> +++ b/source3/printing/nt_printing.c
> @@ -986,6 +986,7 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
>  				   const char *driver_directory,
>  				   WERROR *perr)
>  {
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	int cversion = -1;
>  	NTSTATUS          nt_status;
>  	struct smb_filename *smb_fname = NULL;
> @@ -1003,6 +1004,7 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
>  	if (strcmp(architecture, SPL_ARCH_WIN40) == 0) {
>  		DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
>  		*perr = WERR_OK;
> +		TALLOC_FREE(frame);
>  		return 0;
>  	}
>  
> @@ -1010,26 +1012,30 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
>  	if (strcmp(architecture, SPL_ARCH_X64) == 0) {
>  		DEBUG(10,("get_correct_cversion: Driver is x64, cversion = 3\n"));
>  		*perr = WERR_OK;
> +		TALLOC_FREE(frame);
>  		return 3;
>  	}
>  
> -	printdollar_snum = find_service(talloc_tos(), "print$", &printdollar);
> +	printdollar_snum = find_service(frame, "print$", &printdollar);
>  	if (!printdollar) {
>  		*perr = WERR_NOT_ENOUGH_MEMORY;
> +		TALLOC_FREE(frame);
>  		return -1;
>  	}
>  	if (printdollar_snum == -1) {
>  		*perr = WERR_BAD_NET_NAME;
> +		TALLOC_FREE(frame);
>  		return -1;
>  	}
>  
> -	printdollar_path = lp_path(talloc_tos(), printdollar_snum);
> +	printdollar_path = lp_path(frame, printdollar_snum);
>  	if (printdollar_path == NULL) {
>  		*perr = WERR_NOT_ENOUGH_MEMORY;
> +		TALLOC_FREE(frame);
>  		return -1;
>  	}
>  
> -	working_dir = talloc_asprintf(talloc_tos(),
> +	working_dir = talloc_asprintf(frame,
>  				      "%s/%s",
>  				      printdollar_path,
>  				      architecture);
> @@ -1038,13 +1044,13 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
>  	 * directory, switch to the driver directory.
>  	 */
>  	if (driver_directory != NULL) {
> -		working_dir = talloc_asprintf(talloc_tos(), "%s/%s/%s",
> +		working_dir = talloc_asprintf(frame, "%s/%s/%s",
>  					      printdollar_path,
>  					      architecture,
>  					      driver_directory);
>  	}
>  
> -	nt_status = create_conn_struct_cwd(talloc_tos(),
> +	nt_status = create_conn_struct_cwd(frame,
>  					   server_event_context(),
>  					   server_messaging_context(),
>  					   &conn,
> @@ -1055,6 +1061,7 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
>  		DEBUG(0,("get_correct_cversion: create_conn_struct "
>  			 "returned %s\n", nt_errstr(nt_status)));
>  		*perr = ntstatus_to_werror(nt_status);
> +		TALLOC_FREE(frame);
>  		return -1;
>  	}
>  
> @@ -1163,13 +1170,11 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
>   error_exit:
>  	unbecome_user();
>   error_free_conn:
> -	TALLOC_FREE(smb_fname);
>  	if (fsp != NULL) {
>  		close_file(NULL, fsp, NORMAL_CLOSE);
>  	}
>  	if (conn != NULL) {
>  		vfs_ChDir(conn, oldcwd_fname);
> -		TALLOC_FREE(oldcwd_fname);
>  		SMB_VFS_DISCONNECT(conn);
>  		conn_free(conn);
>  	}
> @@ -1177,6 +1182,7 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
>  		cversion = -1;
>  	}
>  
> +	TALLOC_FREE(frame);
>  	return cversion;
>  }
>  
> -- 
> 2.17.1
> 
> 
> From 29d7e6ec8483362c242af1f3c8baa80854aa992c Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:40:27 +0200
> Subject: [PATCH 25/40] printing: add an explicit talloc_stackframe() to
>  move_driver_to_download_area()
> 
> This makes further changes simpler.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/printing/nt_printing.c | 29 ++++++++++++++++-------------
>  1 file changed, 16 insertions(+), 13 deletions(-)
> 
> diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
> index 5c4488009265..62ce57527477 100644
> --- a/source3/printing/nt_printing.c
> +++ b/source3/printing/nt_printing.c
> @@ -1482,6 +1482,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>  				    const struct spoolss_AddDriverInfoCtr *r,
>  				    const char *driver_directory)
>  {
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	struct spoolss_AddDriverInfo3 *driver;
>  	struct spoolss_AddDriverInfo3 converted_driver;
>  	const char *short_architecture;
> @@ -1490,7 +1491,6 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>  	connection_struct *conn = NULL;
>  	NTSTATUS nt_status;
>  	int i;
> -	TALLOC_CTX *ctx = talloc_tos();
>  	int ver = 0;
>  	struct smb_filename *oldcwd_fname = NULL;
>  	char *printdollar = NULL;
> @@ -1511,33 +1511,38 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>  		break;
>  	default:
>  		DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)r->level));
> +		TALLOC_FREE(frame);
>  		return WERR_INVALID_LEVEL;
>  	}
>  
>  	short_architecture = get_short_archi(driver->architecture);
>  	if (!short_architecture) {
> +		TALLOC_FREE(frame);
>  		return WERR_UNKNOWN_PRINTER_DRIVER;
>  	}
>  
> -	printdollar_snum = find_service(ctx, "print$", &printdollar);
> +	printdollar_snum = find_service(frame, "print$", &printdollar);
>  	if (!printdollar) {
> +		TALLOC_FREE(frame);
>  		return WERR_NOT_ENOUGH_MEMORY;
>  	}
>  	if (printdollar_snum == -1) {
> +		TALLOC_FREE(frame);
>  		return WERR_BAD_NET_NAME;
>  	}
>  
> -	nt_status = create_conn_struct_cwd(talloc_tos(),
> +	nt_status = create_conn_struct_cwd(frame,
>  					   server_event_context(),
>  					   server_messaging_context(),
>  					   &conn,
>  					   printdollar_snum,
> -					   lp_path(talloc_tos(), printdollar_snum),
> +					   lp_path(frame, printdollar_snum),
>  					   session_info, &oldcwd_fname);
>  	if (!NT_STATUS_IS_OK(nt_status)) {
>  		DEBUG(0,("move_driver_to_download_area: create_conn_struct "
>  			 "returned %s\n", nt_errstr(nt_status)));
>  		err = ntstatus_to_werror(nt_status);
> +		TALLOC_FREE(frame);
>  		return err;
>  	}
>  
> @@ -1554,7 +1559,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>  		goto err_free_conn;
>  	}
>  
> -	new_dir = talloc_asprintf(ctx,
> +	new_dir = talloc_asprintf(frame,
>  				"%s/%d",
>  				short_architecture,
>  				driver->version);
> @@ -1600,7 +1605,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>  
>  	if (driver->driver_path && strlen(driver->driver_path)) {
>  
> -		err = move_driver_file_to_download_area(ctx,
> +		err = move_driver_file_to_download_area(frame,
>  							conn,
>  							driver->driver_path,
>  							short_architecture,
> @@ -1615,7 +1620,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>  	if (driver->data_file && strlen(driver->data_file)) {
>  		if (!strequal(driver->data_file, driver->driver_path)) {
>  
> -			err = move_driver_file_to_download_area(ctx,
> +			err = move_driver_file_to_download_area(frame,
>  								conn,
>  								driver->data_file,
>  								short_architecture,
> @@ -1632,7 +1637,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>  		if (!strequal(driver->config_file, driver->driver_path) &&
>  		    !strequal(driver->config_file, driver->data_file)) {
>  
> -			err = move_driver_file_to_download_area(ctx,
> +			err = move_driver_file_to_download_area(frame,
>  								conn,
>  								driver->config_file,
>  								short_architecture,
> @@ -1650,7 +1655,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>  		    !strequal(driver->help_file, driver->data_file) &&
>  		    !strequal(driver->help_file, driver->config_file)) {
>  
> -			err = move_driver_file_to_download_area(ctx,
> +			err = move_driver_file_to_download_area(frame,
>  								conn,
>  								driver->help_file,
>  								short_architecture,
> @@ -1676,7 +1681,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>  					}
>  				}
>  
> -				err = move_driver_file_to_download_area(ctx,
> +				err = move_driver_file_to_download_area(frame,
>  									conn,
>  									driver->dependent_files->string[i],
>  									short_architecture,
> @@ -1695,15 +1700,13 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>   err_exit:
>  	unbecome_user();
>   err_free_conn:
> -	TALLOC_FREE(smb_dname);
> -
>  	if (conn != NULL) {
>  		vfs_ChDir(conn, oldcwd_fname);
> -		TALLOC_FREE(oldcwd_fname);
>  		SMB_VFS_DISCONNECT(conn);
>  		conn_free(conn);
>  	}
>  
> +	TALLOC_FREE(frame);
>  	return err;
>  }
>  
> -- 
> 2.17.1
> 
> 
> From 850204cc50a1d4267ef928d8f565ff4956f7f9ba Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:40:27 +0200
> Subject: [PATCH 26/40] printing: add an explicit talloc_stackframe() to
>  delete_driver_files()
> 
> This makes further changes simpler.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/printing/nt_printing.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
> index 62ce57527477..9d1a18213cbd 100644
> --- a/source3/printing/nt_printing.c
> +++ b/source3/printing/nt_printing.c
> @@ -2053,6 +2053,7 @@ err_out:
>  bool delete_driver_files(const struct auth_session_info *session_info,
>  			 const struct spoolss_DriverInfo8 *r)
>  {
> +	TALLOC_CTX *frame = talloc_stackframe();
>  	const char *short_arch;
>  	connection_struct *conn;
>  	NTSTATUS nt_status;
> @@ -2062,30 +2063,34 @@ bool delete_driver_files(const struct auth_session_info *session_info,
>  	bool ret = false;
>  
>  	if (!r) {
> +		TALLOC_FREE(frame);
>  		return false;
>  	}
>  
>  	DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n",
>  		r->driver_name, r->version));
>  
> -	printdollar_snum = find_service(talloc_tos(), "print$", &printdollar);
> +	printdollar_snum = find_service(frame, "print$", &printdollar);
>  	if (!printdollar) {
> +		TALLOC_FREE(frame);
>  		return false;
>  	}
>  	if (printdollar_snum == -1) {
> +		TALLOC_FREE(frame);
>  		return false;
>  	}
>  
> -	nt_status = create_conn_struct_cwd(talloc_tos(),
> +	nt_status = create_conn_struct_cwd(frame,
>  					   server_event_context(),
>  					   server_messaging_context(),
>  					   &conn,
>  					   printdollar_snum,
> -					   lp_path(talloc_tos(), printdollar_snum),
> +					   lp_path(frame, printdollar_snum),
>  					   session_info, &oldcwd_fname);
>  	if (!NT_STATUS_IS_OK(nt_status)) {
>  		DEBUG(0,("delete_driver_files: create_conn_struct "
>  			 "returned %s\n", nt_errstr(nt_status)));
> +		TALLOC_FREE(frame);
>  		return false;
>  	}
>  
> @@ -2152,10 +2157,10 @@ bool delete_driver_files(const struct auth_session_info *session_info,
>   err_free_conn:
>  	if (conn != NULL) {
>  		vfs_ChDir(conn, oldcwd_fname);
> -		TALLOC_FREE(oldcwd_fname);
>  		SMB_VFS_DISCONNECT(conn);
>  		conn_free(conn);
>  	}
> +	TALLOC_FREE(frame);
>  	return ret;
>  }
>  
> -- 
> 2.17.1
> 
> 
> From fe68f1ee6d226371bb530a8e45391521b2be2149 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:55:02 +0200
> Subject: [PATCH 27/40] printing: convert get_correct_cversion() to use
>  create_conn_struct_tos_cwd()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/printing/nt_printing.c | 20 +++++++-------------
>  1 file changed, 7 insertions(+), 13 deletions(-)
> 
> diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
> index 9d1a18213cbd..bda72f88dd28 100644
> --- a/source3/printing/nt_printing.c
> +++ b/source3/printing/nt_printing.c
> @@ -991,8 +991,8 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
>  	NTSTATUS          nt_status;
>  	struct smb_filename *smb_fname = NULL;
>  	files_struct      *fsp = NULL;
> +	struct conn_struct_tos *c = NULL;
>  	connection_struct *conn = NULL;
> -	struct smb_filename *oldcwd_fname = NULL;
>  	char *printdollar = NULL;
>  	char *printdollar_path = NULL;
>  	char *working_dir = NULL;
> @@ -1050,13 +1050,11 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
>  					      driver_directory);
>  	}
>  
> -	nt_status = create_conn_struct_cwd(frame,
> -					   server_event_context(),
> -					   server_messaging_context(),
> -					   &conn,
> -					   printdollar_snum,
> -					   working_dir,
> -					   session_info, &oldcwd_fname);
> +	nt_status = create_conn_struct_tos_cwd(server_messaging_context(),
> +					       printdollar_snum,
> +					       working_dir,
> +					       session_info,
> +					       &c);
>  	if (!NT_STATUS_IS_OK(nt_status)) {
>  		DEBUG(0,("get_correct_cversion: create_conn_struct "
>  			 "returned %s\n", nt_errstr(nt_status)));
> @@ -1064,6 +1062,7 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
>  		TALLOC_FREE(frame);
>  		return -1;
>  	}
> +	conn = c->conn;
>  
>  	nt_status = set_conn_force_user_group(conn, printdollar_snum);
>  	if (!NT_STATUS_IS_OK(nt_status)) {
> @@ -1173,11 +1172,6 @@ static uint32_t get_correct_cversion(const struct auth_session_info *session_inf
>  	if (fsp != NULL) {
>  		close_file(NULL, fsp, NORMAL_CLOSE);
>  	}
> -	if (conn != NULL) {
> -		vfs_ChDir(conn, oldcwd_fname);
> -		SMB_VFS_DISCONNECT(conn);
> -		conn_free(conn);
> -	}
>  	if (!W_ERROR_IS_OK(*perr)) {
>  		cversion = -1;
>  	}
> -- 
> 2.17.1
> 
> 
> From 0b47e52df704ff0b05d26256bc040c4b350b4efe Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:55:02 +0200
> Subject: [PATCH 28/40] printing: convert move_driver_to_download_area() to use
>  create_conn_struct_tos_cwd()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/printing/nt_printing.c | 21 +++++++--------------
>  1 file changed, 7 insertions(+), 14 deletions(-)
> 
> diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
> index bda72f88dd28..d0525e13c99a 100644
> --- a/source3/printing/nt_printing.c
> +++ b/source3/printing/nt_printing.c
> @@ -1482,11 +1482,11 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>  	const char *short_architecture;
>  	struct smb_filename *smb_dname = NULL;
>  	char *new_dir = NULL;
> +	struct conn_struct_tos *c = NULL;
>  	connection_struct *conn = NULL;
>  	NTSTATUS nt_status;
>  	int i;
>  	int ver = 0;
> -	struct smb_filename *oldcwd_fname = NULL;
>  	char *printdollar = NULL;
>  	int printdollar_snum;
>  	WERROR err = WERR_OK;
> @@ -1525,13 +1525,11 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>  		return WERR_BAD_NET_NAME;
>  	}
>  
> -	nt_status = create_conn_struct_cwd(frame,
> -					   server_event_context(),
> -					   server_messaging_context(),
> -					   &conn,
> -					   printdollar_snum,
> -					   lp_path(frame, printdollar_snum),
> -					   session_info, &oldcwd_fname);
> +	nt_status = create_conn_struct_tos_cwd(server_messaging_context(),
> +					       printdollar_snum,
> +					       lp_path(frame, printdollar_snum),
> +					       session_info,
> +					       &c);
>  	if (!NT_STATUS_IS_OK(nt_status)) {
>  		DEBUG(0,("move_driver_to_download_area: create_conn_struct "
>  			 "returned %s\n", nt_errstr(nt_status)));
> @@ -1539,6 +1537,7 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>  		TALLOC_FREE(frame);
>  		return err;
>  	}
> +	conn = c->conn;
>  
>  	nt_status = set_conn_force_user_group(conn, printdollar_snum);
>  	if (!NT_STATUS_IS_OK(nt_status)) {
> @@ -1694,12 +1693,6 @@ WERROR move_driver_to_download_area(const struct auth_session_info *session_info
>   err_exit:
>  	unbecome_user();
>   err_free_conn:
> -	if (conn != NULL) {
> -		vfs_ChDir(conn, oldcwd_fname);
> -		SMB_VFS_DISCONNECT(conn);
> -		conn_free(conn);
> -	}
> -
>  	TALLOC_FREE(frame);
>  	return err;
>  }
> -- 
> 2.17.1
> 
> 
> From 1c274613d4080fed858ab3eb3c568755ecbd9d33 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 17:55:02 +0200
> Subject: [PATCH 29/40] printing: convert delete_driver_files() to use
>  create_conn_struct_tos_cwd()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/printing/nt_printing.c | 22 ++++++++--------------
>  1 file changed, 8 insertions(+), 14 deletions(-)
> 
> diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
> index d0525e13c99a..633e350ff35f 100644
> --- a/source3/printing/nt_printing.c
> +++ b/source3/printing/nt_printing.c
> @@ -2042,9 +2042,9 @@ bool delete_driver_files(const struct auth_session_info *session_info,
>  {
>  	TALLOC_CTX *frame = talloc_stackframe();
>  	const char *short_arch;
> -	connection_struct *conn;
> +	struct conn_struct_tos *c = NULL;
> +	connection_struct *conn = NULL;
>  	NTSTATUS nt_status;
> -	struct smb_filename *oldcwd_fname = NULL;
>  	char *printdollar = NULL;
>  	int printdollar_snum;
>  	bool ret = false;
> @@ -2067,19 +2067,18 @@ bool delete_driver_files(const struct auth_session_info *session_info,
>  		return false;
>  	}
>  
> -	nt_status = create_conn_struct_cwd(frame,
> -					   server_event_context(),
> -					   server_messaging_context(),
> -					   &conn,
> -					   printdollar_snum,
> -					   lp_path(frame, printdollar_snum),
> -					   session_info, &oldcwd_fname);
> +	nt_status = create_conn_struct_tos_cwd(server_messaging_context(),
> +					       printdollar_snum,
> +					       lp_path(frame, printdollar_snum),
> +					       session_info,
> +					       &c);
>  	if (!NT_STATUS_IS_OK(nt_status)) {
>  		DEBUG(0,("delete_driver_files: create_conn_struct "
>  			 "returned %s\n", nt_errstr(nt_status)));
>  		TALLOC_FREE(frame);
>  		return false;
>  	}
> +	conn = c->conn;
>  
>  	nt_status = set_conn_force_user_group(conn, printdollar_snum);
>  	if (!NT_STATUS_IS_OK(nt_status)) {
> @@ -2142,11 +2141,6 @@ bool delete_driver_files(const struct auth_session_info *session_info,
>   err_out:
>  	unbecome_user();
>   err_free_conn:
> -	if (conn != NULL) {
> -		vfs_ChDir(conn, oldcwd_fname);
> -		SMB_VFS_DISCONNECT(conn);
> -		conn_free(conn);
> -	}
>  	TALLOC_FREE(frame);
>  	return ret;
>  }
> -- 
> 2.17.1
> 
> 
> From 37f3f89153695fc8e8c9dd16e58901b89ed91bb3 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Fri, 25 May 2018 08:49:29 +0200
> Subject: [PATCH 30/40] smbd: remove unused create_conn_struct_cwd() function
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 62 --------------------------------------------
>  source3/smbd/proto.h |  8 ------
>  2 files changed, 70 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index 18fae96f2e58..256bb42d778e 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -386,68 +386,6 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
>  	return status;
>  }
>  
> -/********************************************************
> - Fake up a connection struct for the VFS layer.
> - Note: this performs a vfs connect and CHANGES CWD !!!! JRA.
> -
> - The old working directory is returned on *poldcwd, allocated on ctx.
> -*********************************************************/
> -
> -NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
> -				struct tevent_context *ev,
> -				struct messaging_context *msg,
> -				connection_struct **pconn,
> -				int snum,
> -				const char *path,
> -				const struct auth_session_info *session_info,
> -				struct smb_filename **poldcwd_fname)
> -{
> -	connection_struct *conn;
> -	struct smb_filename *oldcwd_fname = NULL;
> -	struct smb_filename smb_fname_connectpath = {0};
> -
> -	NTSTATUS status = create_conn_struct(ctx, ev,
> -					     msg, &conn,
> -					     snum, path,
> -					     session_info);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		return status;
> -	}
> -
> -	/*
> -	 * Windows seems to insist on doing trans2getdfsreferral() calls on
> -	 * the IPC$ share as the anonymous user. If we try to chdir as that
> -	 * user we will fail.... WTF ? JRA.
> -	 */
> -
> -	oldcwd_fname = vfs_GetWd(ctx, conn);
> -	if (oldcwd_fname == NULL) {
> -		status = map_nt_error_from_unix(errno);
> -		DEBUG(3, ("vfs_GetWd failed: %s\n", strerror(errno)));
> -		conn_free(conn);
> -		return status;
> -	}
> -
> -	smb_fname_connectpath = (struct smb_filename) {
> -		.base_name = conn->connectpath
> -	};
> -
> -	if (vfs_ChDir(conn, &smb_fname_connectpath) != 0) {
> -		status = map_nt_error_from_unix(errno);
> -		DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. "
> -			"Error was %s\n",
> -			conn->connectpath, strerror(errno) ));
> -		TALLOC_FREE(oldcwd_fname);
> -		conn_free(conn);
> -		return status;
> -	}
> -
> -	*pconn = conn;
> -	*poldcwd_fname = oldcwd_fname;
> -
> -	return NT_STATUS_OK;
> -}
> -
>  static int conn_struct_tos_destructor(struct conn_struct_tos *c)
>  {
>  	if (c->oldcwd_fname != NULL) {
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index ed12e504bf8b..68dd566efd10 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -506,14 +506,6 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
>  			    int snum,
>  			    const char *path,
>  			    const struct auth_session_info *session_info);
> -NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
> -				struct tevent_context *ev,
> -				struct messaging_context *msg,
> -				connection_struct **pconn,
> -				int snum,
> -				const char *path,
> -				const struct auth_session_info *session_info,
> -				struct smb_filename **poldcwd_fname);
>  struct connection_struct;
>  struct smb_filename;
>  struct conn_struct_tos {
> -- 
> 2.17.1
> 
> 
> From fdbb71a06721c1ebb1b32ef126b951beeb48d8e9 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Fri, 25 May 2018 08:49:29 +0200
> Subject: [PATCH 31/40] vfstest: make use of create_conn_struct_tos()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/torture/vfstest.c | 19 ++++++++-----------
>  1 file changed, 8 insertions(+), 11 deletions(-)
> 
> diff --git a/source3/torture/vfstest.c b/source3/torture/vfstest.c
> index 17c19012384a..e17e6fc5c347 100644
> --- a/source3/torture/vfstest.c
> +++ b/source3/torture/vfstest.c
> @@ -460,12 +460,12 @@ int main(int argc, const char *argv[])
>  {
>  	char *cmdstr = NULL;
>  	struct cmd_set	**cmd_set;
> +	struct conn_struct_tos *c = NULL;
>  	struct vfs_state *vfs;
>  	int i;
>  	char *filename = NULL;
>  	char cwd[MAXPATHLEN];
>  	TALLOC_CTX *frame = talloc_stackframe();
> -	struct tevent_context *ev;
>  	struct auth_session_info *session_info = NULL;
>  	NTSTATUS status = NT_STATUS_OK;
>  
> @@ -527,7 +527,7 @@ int main(int argc, const char *argv[])
>  	sec_init();
>  	init_guest_session_info(frame);
>  	locking_init();
> -	vfs = talloc_zero(NULL, struct vfs_state);
> +	vfs = talloc_zero(frame, struct vfs_state);
>  	if (vfs == NULL) {
>  		return 1;
>  	}
> @@ -536,18 +536,15 @@ int main(int argc, const char *argv[])
>  		return 1;
>  	}
>  
> -	ev = server_event_context();
> -
> -	status = create_conn_struct(vfs,
> -				ev,
> -				server_messaging_context(),
> -                                &vfs->conn,
> -                                -1,
> -                                getcwd(cwd, sizeof(cwd)),
> -                                session_info);
> +	status = create_conn_struct_tos(server_messaging_context(),
> +					-1,
> +					getcwd(cwd, sizeof(cwd)),
> +					session_info,
> +					&c);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		return 1;
>  	}
> +	vfs->conn = c->conn;
>  
>  	vfs->conn->share_access = FILE_GENERIC_ALL;
>  	vfs->conn->read_only = false;
> -- 
> 2.17.1
> 
> 
> From d1bd9ebdaba1d870863a0c85862b6cc12ae732bf Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Fri, 25 May 2018 08:49:29 +0200
> Subject: [PATCH 32/40] smbd: let create_conn_struct_tos() use
>  create_conn_struct_as_root() directly
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index 256bb42d778e..eff41f3419da 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -430,13 +430,15 @@ NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
>  		return NT_STATUS_NO_MEMORY;
>  	}
>  
> -	status = create_conn_struct(c,
> -				    ev,
> -				    msg,
> -				    &c->conn,
> -				    snum,
> -				    path,
> -				    session_info);
> +	become_root();
> +	status = create_conn_struct_as_root(c,
> +					    ev,
> +					    msg,
> +					    &c->conn,
> +					    snum,
> +					    path,
> +					    session_info);
> +	unbecome_root();
>  	if (!NT_STATUS_IS_OK(status)) {
>  		TALLOC_FREE(c);
>  		return status;
> -- 
> 2.17.1
> 
> 
> From 666f1f3472ef4a9e08fb3966b224c30796dc1873 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Fri, 25 May 2018 08:49:29 +0200
> Subject: [PATCH 33/40] smbd: remove unused create_conn_struct() function
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 27 ---------------------------
>  source3/smbd/proto.h |  7 -------
>  2 files changed, 34 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index eff41f3419da..9c8e32e31446 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -359,33 +359,6 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
>  	return NT_STATUS_OK;
>  }
>  
> -/********************************************************
> - Fake up a connection struct for the VFS layer, for use in
> - applications (such as the python bindings), that do not want the
> - global working directory changed under them.
> -
> - SMB_VFS_CONNECT requires root privileges.
> -*********************************************************/
> -
> -NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
> -			    struct tevent_context *ev,
> -			    struct messaging_context *msg,
> -			    connection_struct **pconn,
> -			    int snum,
> -			    const char *path,
> -			    const struct auth_session_info *session_info)
> -{
> -	NTSTATUS status;
> -	become_root();
> -	status = create_conn_struct_as_root(ctx, ev,
> -					    msg, pconn,
> -					    snum, path,
> -					    session_info);
> -	unbecome_root();
> -
> -	return status;
> -}
> -
>  static int conn_struct_tos_destructor(struct conn_struct_tos *c)
>  {
>  	if (c->oldcwd_fname != NULL) {
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index 68dd566efd10..e4d0cf44e9b6 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -499,13 +499,6 @@ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx,
>  				bool allow_broken_path,
>  				char **pp_name_out,
>  				bool *ppath_contains_wcard);
> -NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
> -			    struct tevent_context *ev,
> -			    struct messaging_context *msg,
> -			    connection_struct **pconn,
> -			    int snum,
> -			    const char *path,
> -			    const struct auth_session_info *session_info);
>  struct connection_struct;
>  struct smb_filename;
>  struct conn_struct_tos {
> -- 
> 2.17.1
> 
> 
> From 651f040a8c129740fc5f43da8b182dac4df94685 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Fri, 25 May 2018 08:49:29 +0200
> Subject: [PATCH 34/40] smbd: use pconn = talloc_move(ctx, &conn) in
>  create_conn_struct_as_root()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index 9c8e32e31446..ff836138cd77 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -354,7 +354,7 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
>  	}
>  
>  	conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
> -	*pconn = conn;
> +	*pconn = talloc_move(ctx, &conn);
>  
>  	return NT_STATUS_OK;
>  }
> @@ -416,7 +416,6 @@ NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
>  		TALLOC_FREE(c);
>  		return status;
>  	}
> -	talloc_steal(c, c->conn);
>  
>  	talloc_set_destructor(c, conn_struct_tos_destructor);
>  
> -- 
> 2.17.1
> 
> 
> From f5348aacefa3c09fb2e098ece6232f2f655ad77c Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Fri, 25 May 2018 08:49:29 +0200
> Subject: [PATCH 35/40] smbd: call samba_tevent_context_init() within
>  create_conn_struct_as_root()
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/msdfs.c | 16 ++++++----------
>  1 file changed, 6 insertions(+), 10 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index ff836138cd77..1a6454b5c2be 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -240,7 +240,6 @@ static NTSTATUS parse_dfs_path(connection_struct *conn,
>  *********************************************************/
>  
>  static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
> -			    struct tevent_context *ev,
>  			    struct messaging_context *msg,
>  			    connection_struct **pconn,
>  			    int snum,
> @@ -258,7 +257,12 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
>  		return NT_STATUS_NO_MEMORY;
>  	}
>  
> -	sconn->ev_ctx = ev;
> +	sconn->ev_ctx = samba_tevent_context_init(sconn);
> +	if (sconn->ev_ctx == NULL) {
> +		TALLOC_FREE(sconn);
> +		return NT_STATUS_NO_MEMORY;
> +	}
> +
>  	sconn->msg_ctx = msg;
>  
>  	conn = conn_new(sconn);
> @@ -387,7 +391,6 @@ NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
>  				struct conn_struct_tos **_c)
>  {
>  	struct conn_struct_tos *c = NULL;
> -	struct tevent_context *ev = NULL;
>  	NTSTATUS status;
>  
>  	*_c = NULL;
> @@ -397,15 +400,8 @@ NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
>  		return NT_STATUS_NO_MEMORY;
>  	}
>  
> -	ev = samba_tevent_context_init(c);
> -	if (ev == NULL) {
> -		TALLOC_FREE(c);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
>  	become_root();
>  	status = create_conn_struct_as_root(c,
> -					    ev,
>  					    msg,
>  					    &c->conn,
>  					    snum,
> -- 
> 2.17.1
> 
> 
> From f8b6262697f1df4a007716657e6066c6e2f64ba7 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Wed, 23 May 2018 08:53:47 +0200
> Subject: [PATCH 36/40] vfs_glusterfs: use tevent_req_defer_callback() in order
>  to use the correct event context
> 
> The callback and _recv() functions should be called from the same
> event context that was passed to the _send() function.
> 
> In future the completion pipe should be replaced by
> tevent_threaded_context_create()
> ---
>  source3/modules/vfs_glusterfs.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
> index 985a895257fe..c2af793016f2 100644
> --- a/source3/modules/vfs_glusterfs.c
> +++ b/source3/modules/vfs_glusterfs.c
> @@ -803,6 +803,14 @@ static struct tevent_req *vfs_gluster_pread_send(struct vfs_handle_struct
>  		return tevent_req_post(req, ev);
>  	}
>  
> +	/*
> +	 * aio_glusterfs_done and aio_tevent_fd_done()
> +	 * use the raw tevent context. We need to use
> +	 * tevent_req_defer_callback() in order to
> +	 * use the event context we're started with.
> +	 */
> +	tevent_req_defer_callback(req, ev);
> +
>  	PROFILE_TIMESTAMP(&state->start);
>  	ret = glfs_pread_async(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle,
>  				fsp), data, n, offset, 0, aio_glusterfs_done,
> @@ -839,6 +847,14 @@ static struct tevent_req *vfs_gluster_pwrite_send(struct vfs_handle_struct
>  		return tevent_req_post(req, ev);
>  	}
>  
> +	/*
> +	 * aio_glusterfs_done and aio_tevent_fd_done()
> +	 * use the raw tevent context. We need to use
> +	 * tevent_req_defer_callback() in order to
> +	 * use the event context we're started with.
> +	 */
> +	tevent_req_defer_callback(req, ev);
> +
>  	PROFILE_TIMESTAMP(&state->start);
>  	ret = glfs_pwrite_async(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle,
>  				fsp), data, n, offset, 0, aio_glusterfs_done,
> @@ -941,6 +957,14 @@ static struct tevent_req *vfs_gluster_fsync_send(struct vfs_handle_struct
>  		return tevent_req_post(req, ev);
>  	}
>  
> +	/*
> +	 * aio_glusterfs_done and aio_tevent_fd_done()
> +	 * use the raw tevent context. We need to use
> +	 * tevent_req_defer_callback() in order to
> +	 * use the event context we're started with.
> +	 */
> +	tevent_req_defer_callback(req, ev);
> +
>  	PROFILE_TIMESTAMP(&state->start);
>  	ret = glfs_fsync_async(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle,
>  				fsp), aio_glusterfs_done, state);
> -- 
> 2.17.1
> 
> 
> From 59bdd4d2f65abffe8aa51a3d2b683ebff6be9bdc Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Thu, 24 May 2018 09:49:40 +0200
> Subject: [PATCH 37/40] smbd: make smbd_setup_sig_{term,hup}_handler() static
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/process.c | 4 ++--
>  source3/smbd/proto.h   | 2 --
>  2 files changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/source3/smbd/process.c b/source3/smbd/process.c
> index 936b5351de7c..cf307b000727 100644
> --- a/source3/smbd/process.c
> +++ b/source3/smbd/process.c
> @@ -966,7 +966,7 @@ static void smbd_sig_term_handler(struct tevent_context *ev,
>  	exit_server_cleanly("termination signal");
>  }
>  
> -void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
> +static void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
>  {
>  	struct tevent_signal *se;
>  
> @@ -996,7 +996,7 @@ static void smbd_sig_hup_handler(struct tevent_context *ev,
>  	reload_services(sconn, conn_snum_used, false);
>  }
>  
> -void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
> +static void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
>  {
>  	struct tevent_signal *se;
>  
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index e4d0cf44e9b6..aacdeb44daf9 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -824,8 +824,6 @@ NTSTATUS make_default_filesystem_acl(
>  
>  /* The following definitions come from smbd/process.c  */
>  
> -void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn);
> -void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn);
>  bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
>  		  bool no_signing, uint32_t seqnum,
>  		  bool do_encrypt,
> -- 
> 2.17.1
> 
> 
> From 7de7e16bf48d3e18fd832bda08a03793fd70d52e Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Wed, 23 May 2018 09:41:29 +0200
> Subject: [PATCH 38/40] smbd: split out a fsp_flush_write_time_update()
>  function from update_write_time_handler()
> 
> It's confusing to call update_write_time_handler() from anywhere,
> it should only be called from within the event loop when the
> timer expires.
> 
> This makes it more obvious that fsp_flush_write_time_update()
> doesn't really need an tevent context argument.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/close.c   |  5 +----
>  source3/smbd/durable.c |  5 +----
>  source3/smbd/fileio.c  | 19 ++++++++++++++-----
>  source3/smbd/proto.h   |  5 +----
>  4 files changed, 17 insertions(+), 17 deletions(-)
> 
> diff --git a/source3/smbd/close.c b/source3/smbd/close.c
> index 3324d3ec4e03..8581b04e8aaf 100644
> --- a/source3/smbd/close.c
> +++ b/source3/smbd/close.c
> @@ -255,10 +255,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
>  
>  	/* Ensure any pending write time updates are done. */
>  	if (fsp->update_write_time_event) {
> -		update_write_time_handler(fsp->conn->sconn->ev_ctx,
> -					fsp->update_write_time_event,
> -					timeval_current(),
> -					(void *)fsp);
> +		fsp_flush_write_time_update(fsp);
>  	}
>  
>  	/*
> diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c
> index 602a96e1fe56..7d7a1b217514 100644
> --- a/source3/smbd/durable.c
> +++ b/source3/smbd/durable.c
> @@ -194,10 +194,7 @@ NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp,
>  
>  	/* Ensure any pending write time updates are done. */
>  	if (fsp->update_write_time_event) {
> -		update_write_time_handler(fsp->conn->sconn->ev_ctx,
> -					fsp->update_write_time_event,
> -					timeval_current(),
> -					(void *)fsp);
> +		fsp_flush_write_time_update(fsp);
>  	}
>  
>  	/*
> diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
> index 1c8bb41620c8..cde6a057ccda 100644
> --- a/source3/smbd/fileio.c
> +++ b/source3/smbd/fileio.c
> @@ -160,12 +160,12 @@ static int wcp_file_size_change(files_struct *fsp)
>  	return ret;
>  }
>  
> -void update_write_time_handler(struct tevent_context *ctx,
> -				      struct tevent_timer *te,
> -				      struct timeval now,
> -				      void *private_data)
> +void fsp_flush_write_time_update(struct files_struct *fsp)
>  {
> -	files_struct *fsp = (files_struct *)private_data;
> +	/*
> +	 * Note this won't expect any impersonation!
> +	 * So don't call any SMB_VFS operations here!
> +	 */
>  
>  	DEBUG(5, ("Update write time on %s\n", fsp_str_dbg(fsp)));
>  
> @@ -180,6 +180,15 @@ void update_write_time_handler(struct tevent_context *ctx,
>  	TALLOC_FREE(fsp->update_write_time_event);
>  }
>  
> +static void update_write_time_handler(struct tevent_context *ctx,
> +				      struct tevent_timer *te,
> +				      struct timeval now,
> +				      void *private_data)
> +{
> +	files_struct *fsp = (files_struct *)private_data;
> +	fsp_flush_write_time_update(fsp);
> +}
> +
>  /*********************************************************
>   Schedule a write time update for WRITE_TIME_UPDATE_USEC_DELAY
>   in the future.
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index aacdeb44daf9..2851d6d5f7df 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -320,10 +320,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32_t dosmode);
>  /* The following definitions come from smbd/fileio.c  */
>  
>  ssize_t read_file(files_struct *fsp,char *data,off_t pos,size_t n);
> -void update_write_time_handler(struct tevent_context *ctx,
> -                                      struct tevent_timer *te,
> -                                      struct timeval now,
> -                                      void *private_data);
> +void fsp_flush_write_time_update(struct files_struct *fsp);
>  void trigger_write_time_update(struct files_struct *fsp);
>  void trigger_write_time_update_immediate(struct files_struct *fsp);
>  void mark_file_modified(files_struct *fsp);
> -- 
> 2.17.1
> 
> 
> From 0c43c333cf52ef83ab2363c6fd56857cf9620fc6 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Wed, 23 May 2018 14:23:17 +0200
> Subject: [PATCH 39/40] smbd: remove useless allow_access() check for AS_GUEST
> 
> We already call allow_access() when we accept the connection
> in smbd_add_connection().
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/process.c | 23 -----------------------
>  1 file changed, 23 deletions(-)
> 
> diff --git a/source3/smbd/process.c b/source3/smbd/process.c
> index cf307b000727..e0528f3498cc 100644
> --- a/source3/smbd/process.c
> +++ b/source3/smbd/process.c
> @@ -1661,33 +1661,10 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
>  	 * messenger service requests have this...)
>  	 */
>  	if (flags & AS_GUEST) {
> -		char *raddr;
> -		bool ok;
> -
>  		if (!change_to_guest()) {
>  			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
>  			return conn;
>  		}
> -
> -		raddr = tsocket_address_inet_addr_string(xconn->remote_address,
> -							 talloc_tos());
> -		if (raddr == NULL) {
> -			reply_nterror(req, NT_STATUS_NO_MEMORY);
> -			return conn;
> -		}
> -
> -		/*
> -		 * Haven't we checked this in smbd_process already???
> -		 */
> -
> -		ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
> -				  xconn->remote_hostname, raddr);
> -		TALLOC_FREE(raddr);
> -
> -		if (!ok) {
> -			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
> -			return conn;
> -		}
>  	}
>  
>  	/*
> -- 
> 2.17.1
> 
> 
> From 73512dbd2816a0413ad4e876a8190ccc95f1a143 Mon Sep 17 00:00:00 2001
> From: Stefan Metzmacher <metze at samba.org>
> Date: Wed, 23 May 2018 14:26:37 +0200
> Subject: [PATCH 40/40] smbd: don't call change_to_root_user() before
>  change_to_guest()
> 
> We call change_to_guest() before set_current_service() now,
> but that has no impact as we pass 'do_chdir=false'
> as AS_GUEST is never mixed with AS_USER or DO_CHDIR.
> 
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> ---
>  source3/smbd/process.c | 20 +++++++++-----------
>  1 file changed, 9 insertions(+), 11 deletions(-)
> 
> diff --git a/source3/smbd/process.c b/source3/smbd/process.c
> index e0528f3498cc..1c54ca491462 100644
> --- a/source3/smbd/process.c
> +++ b/source3/smbd/process.c
> @@ -1624,6 +1624,15 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
>  			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
>  			return conn;
>  		}
> +	} else if (flags & AS_GUEST) {
> +		/*
> +		 * Does this protocol need to be run as guest? (Only archane
> +		 * messenger service requests have this...)
> +		 */
> +		if (!change_to_guest()) {
> +			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
> +			return conn;
> +		}
>  	} else {
>  		/* This call needs to be run as root */
>  		change_to_root_user();
> @@ -1656,17 +1665,6 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
>  		conn->num_smb_operations++;
>  	}
>  
> -	/*
> -	 * Does this protocol need to be run as guest? (Only archane
> -	 * messenger service requests have this...)
> -	 */
> -	if (flags & AS_GUEST) {
> -		if (!change_to_guest()) {
> -			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
> -			return conn;
> -		}
> -	}
> -
>  	/*
>  	 * Update encryption and signing state tracking flags that are
>  	 * used by smbstatus to display signing and encryption status.
> -- 
> 2.17.1
> 







More information about the samba-technical mailing list