smbd: remove dead code
[samba.git] / source3 / smbd / service.c
index 484461dfee93a177d9bf245b97f2cf6a13d2c681..ea99f0d2129d83fc3eb52baa43e7930e92a295ea 100644 (file)
 #include "printing/pcap.h"
 #include "passdb/lookup_sid.h"
 #include "auth.h"
+#include "../auth/auth_util.h"
 #include "lib/param/loadparm.h"
 #include "messages.h"
 #include "lib/afs/afs_funcs.h"
 #include "lib/util_path.h"
 
-static bool canonicalize_connect_path(connection_struct *conn)
+bool canonicalize_connect_path(connection_struct *conn)
 {
        bool ret;
        struct smb_filename con_fname = { .base_name = conn->connectpath };
@@ -65,22 +66,23 @@ bool set_conn_connectpath(connection_struct *conn, const char *connectpath)
                return false;
        }
 
-       DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
-               lp_servicename(talloc_tos(), SNUM(conn)), destname ));
+       DBG_DEBUG("service %s, connectpath = %s\n",
+                 lp_const_servicename(SNUM(conn)), destname);
 
        talloc_free(conn->connectpath);
        conn->connectpath = destname;
        /*
-        * Ensure conn->cwd_fname is initialized.
+        * Ensure conn->cwd_fsp->fsp_name is initialized.
         * start as conn->connectpath.
         */
-       TALLOC_FREE(conn->cwd_fname);
-       conn->cwd_fname = synthetic_smb_fname(conn,
+       TALLOC_FREE(conn->cwd_fsp->fsp_name);
+       conn->cwd_fsp->fsp_name = synthetic_smb_fname(conn,
                                conn->connectpath,
                                NULL,
                                NULL,
+                               0,
                                0);
-       if (conn->cwd_fname == NULL) {
+       if (conn->cwd_fsp->fsp_name == NULL) {
                return false;
        }
        return true;
@@ -145,47 +147,46 @@ bool chdir_current_service(connection_struct *conn)
        const struct smb_filename origpath_fname = {
                .base_name = conn->origpath,
        };
+       int saved_errno = 0;
+       char *utok_str = NULL;
        int ret;
 
        conn->lastused_count++;
 
        ret = vfs_ChDir(conn, &connectpath_fname);
-       if (ret != 0) {
-               DEBUG(((errno!=EACCES)?0:3),
-                     ("chdir (%s) failed, reason: %s\n",
-                      conn->connectpath, strerror(errno)));
-               return false;
+       if (ret == 0) {
+               return true;
        }
+       saved_errno = errno;
 
-       ret = vfs_ChDir(conn, &origpath_fname);
-       if (ret != 0) {
-               DEBUG(((errno!=EACCES)?0:3),
-                       ("chdir (%s) failed, reason: %s\n",
-                       conn->origpath, strerror(errno)));
+       utok_str = utok_string(talloc_tos(),
+                              conn->session_info->unix_token);
+       if (utok_str == NULL) {
+               errno = saved_errno;
                return false;
        }
 
-       return true;
-}
-
-bool set_current_service(connection_struct *conn, uint16_t flags, bool do_chdir)
-{
-       bool ok;
+       DBG_ERR("vfs_ChDir(%s) failed: %s. Current token: %s\n",
+               conn->connectpath,
+               strerror(saved_errno),
+               utok_str);
 
-       if (conn == NULL)  {
-               return false;
+       ret = vfs_ChDir(conn, &origpath_fname);
+       if (ret == 0) {
+               TALLOC_FREE(utok_str);
+               return true;
        }
+       saved_errno = errno;
 
-       set_current_case_sensitive(conn, flags);
+       DBG_ERR("vfs_ChDir(%s) failed: %s. Current token: %s\n",
+               conn->origpath,
+               strerror(saved_errno),
+               utok_str);
 
-       if (do_chdir) {
-               ok = chdir_current_service(conn);
-               if (!ok) {
-                       return false;
-               }
+       if (saved_errno != 0) {
+               errno = saved_errno;
        }
-
-       return true;
+       return false;
 }
 
 /****************************************************************************
@@ -261,13 +262,15 @@ static NTSTATUS find_forced_group(bool force_user,
 {
        NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
        TALLOC_CTX *frame = talloc_stackframe();
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
        struct dom_sid group_sid;
        enum lsa_SidType type;
        char *groupname;
        bool user_must_be_member = False;
        gid_t gid;
 
-       groupname = lp_force_group(talloc_tos(), snum);
+       groupname = lp_force_group(talloc_tos(), lp_sub, snum);
        if (groupname == NULL) {
                DEBUG(1, ("talloc_strdup failed\n"));
                result = NT_STATUS_NO_MEMORY;
@@ -280,7 +283,7 @@ static NTSTATUS find_forced_group(bool force_user,
        }
 
        groupname = talloc_string_sub(talloc_tos(), groupname,
-                                     "%S", lp_servicename(talloc_tos(), snum));
+                                     "%S", lp_const_servicename(snum));
        if (groupname == NULL) {
                DEBUG(1, ("talloc_string_sub failed\n"));
                result = NT_STATUS_NO_MEMORY;
@@ -303,8 +306,9 @@ static NTSTATUS find_forced_group(bool force_user,
        }
 
        if (!sid_to_gid(&group_sid, &gid)) {
+               struct dom_sid_buf buf;
                DEBUG(10, ("sid_to_gid(%s) for %s failed\n",
-                          sid_string_dbg(&group_sid), groupname));
+                          dom_sid_str_buf(&group_sid, &buf), groupname));
                goto done;
        }
 
@@ -361,20 +365,20 @@ static NTSTATUS create_connection_session_info(struct smbd_server_connection *sc
 
        if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
                if (!lp_guest_ok(snum)) {
-                       DEBUG(2, ("guest user (from session setup) "
+                       DBG_WARNING("guest user (from session setup) "
                                  "not permitted to access this share "
-                                 "(%s)\n", lp_servicename(talloc_tos(), snum)));
+                                 "(%s)\n", lp_const_servicename(snum));
                        return NT_STATUS_ACCESS_DENIED;
                }
        } else {
                if (!user_ok_token(session_info->unix_info->unix_name,
                                   session_info->info->domain_name,
                                   session_info->security_token, snum)) {
-                       DEBUG(2, ("user '%s' (from session setup) not "
+                       DBG_WARNING("user '%s' (from session setup) not "
                                  "permitted to access this share "
                                  "(%s)\n",
                                  session_info->unix_info->unix_name,
-                                 lp_servicename(talloc_tos(), snum)));
+                                 lp_const_servicename(snum));
                        return NT_STATUS_ACCESS_DENIED;
                }
        }
@@ -395,9 +399,11 @@ static NTSTATUS create_connection_session_info(struct smbd_server_connection *sc
 
 NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
 {
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
        NTSTATUS status;
 
-       if (*lp_force_user(talloc_tos(), snum)) {
+       if (*lp_force_user(talloc_tos(), lp_sub, snum)) {
 
                /*
                 * Replace conn->session_info with a completely faked up one
@@ -409,7 +415,7 @@ NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
                struct auth_session_info *forced_serverinfo;
                bool guest;
 
-               fuser = talloc_string_sub(conn, lp_force_user(talloc_tos(), snum), "%S",
+               fuser = talloc_string_sub(conn, lp_force_user(talloc_tos(), lp_sub, snum), "%S",
                                          lp_const_servicename(snum));
                if (fuser == NULL) {
                        return NT_STATUS_NO_MEMORY;
@@ -447,7 +453,7 @@ NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
         * any groupid stored for the connecting user.
         */
 
-       if (*lp_force_group(talloc_tos(), snum)) {
+       if (*lp_force_group(talloc_tos(), lp_sub, snum)) {
 
                status = find_forced_group(
                        conn->force_user, snum, conn->session_info->unix_info->unix_name,
@@ -478,7 +484,7 @@ static NTSTATUS notify_init_sconn(struct smbd_server_connection *sconn)
                return NT_STATUS_OK;
        }
 
-       sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx, sconn->ev_ctx,
+       sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx,
                                        sconn, notify_callback);
        if (sconn->notify_ctx == NULL) {
                return NT_STATUS_NO_MEMORY;
@@ -516,10 +522,13 @@ static NTSTATUS notify_init_sconn(struct smbd_server_connection *sconn)
 
 static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
                                        connection_struct *conn,
-                                       int snum, struct user_struct *vuser,
+                                       int snum,
+                                       struct smbXsrv_session *session,
                                        const char *pdev)
 {
        struct smbd_server_connection *sconn = xconn->client->sconn;
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
        struct smb_filename *smb_fname_cpath = NULL;
        fstring dev;
        int ret;
@@ -527,6 +536,7 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
        uid_t effuid;
        gid_t effgid;
        NTSTATUS status;
+       bool ok;
 
        fstrcpy(dev, pdev);
 
@@ -541,7 +551,7 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
        conn->params->service = snum;
 
        status = create_connection_session_info(sconn,
-               conn, snum, vuser->session_info,
+               conn, snum, session->global->auth_session_info,
                &conn->session_info);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -578,7 +588,7 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
                        if (conn->encrypt_level == SMB_SIGNING_REQUIRED) {
                                DBG_ERR("Service [%s] requires encryption, but "
                                        "it is disabled globally!\n",
-                                       lp_servicename(talloc_tos(), snum));
+                                       lp_const_servicename(snum));
                                status = NT_STATUS_ACCESS_DENIED;
                                goto err_root_exit;
                        }
@@ -598,17 +608,17 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
                goto err_root_exit;
        }
 
-       conn->vuid = vuser->vuid;
+       conn->vuid = session->global->session_wire_id;
 
        {
-               char *s = talloc_sub_advanced(talloc_tos(),
-                                       lp_servicename(talloc_tos(), SNUM(conn)),
+               char *s = talloc_sub_full(talloc_tos(),
+                                       lp_const_servicename(SNUM(conn)),
                                        conn->session_info->unix_info->unix_name,
                                        conn->connectpath,
                                        conn->session_info->unix_token->gid,
                                        conn->session_info->unix_info->sanitized_username,
                                        conn->session_info->info->domain_name,
-                                       lp_path(talloc_tos(), snum));
+                                       lp_path(talloc_tos(), lp_sub, snum));
                if (!s) {
                        status = NT_STATUS_NO_MEMORY;
                        goto err_root_exit;
@@ -619,8 +629,8 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
                        status = NT_STATUS_NO_MEMORY;
                        goto err_root_exit;
                }
-               DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
-                        lp_servicename(talloc_tos(), snum)));
+               DBG_NOTICE("Connect path is '%s' for service [%s]\n", s,
+                          lp_const_servicename(snum));
                TALLOC_FREE(s);
        }
 
@@ -637,7 +647,7 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
         */
 
        status = check_user_share_access(conn,
-                                       vuser->session_info,
+                                       session->global->auth_session_info,
                                        &conn->share_access,
                                        &conn->read_only);
        if (!NT_STATUS_IS_OK(status)) {
@@ -647,8 +657,8 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
        /* Initialise VFS function pointers */
 
        if (!smbd_vfs_init(conn)) {
-               DEBUG(0, ("vfs_init failed for service %s\n",
-                         lp_servicename(talloc_tos(), snum)));
+               DBG_ERR("vfs_init failed for service %s\n",
+                       lp_const_servicename(snum));
                status = NT_STATUS_BAD_NETWORK_NAME;
                goto err_root_exit;
        }
@@ -663,12 +673,12 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
         */
 
        if ((lp_max_connections(snum) > 0)
-           && (count_current_connections(lp_servicename(talloc_tos(), SNUM(conn)), True) >=
+           && (count_current_connections(lp_const_servicename(SNUM(conn)), true) >=
                lp_max_connections(snum))) {
 
-               DEBUG(1, ("Max connections (%d) exceeded for %s\n",
+               DBG_WARNING("Max connections (%d) exceeded for %s\n",
                          lp_max_connections(snum),
-                         lp_servicename(talloc_tos(), snum)));
+                         lp_const_servicename(snum));
                status = NT_STATUS_INSUFFICIENT_RESOURCES;
                goto err_root_exit;
        }
@@ -676,10 +686,10 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
        /* Invoke VFS make connection hook - this must be the first
           filesystem operation that we do. */
 
-       if (SMB_VFS_CONNECT(conn, lp_servicename(talloc_tos(), snum),
+       if (SMB_VFS_CONNECT(conn, lp_const_servicename(snum),
                            conn->session_info->unix_info->unix_name) < 0) {
                DBG_WARNING("SMB_VFS_CONNECT for service '%s' at '%s' failed: %s\n",
-                           lp_servicename(talloc_tos(), snum), conn->connectpath,
+                           lp_const_servicename(snum), conn->connectpath,
                            strerror(errno));
                status = NT_STATUS_UNSUCCESSFUL;
                goto err_root_exit;
@@ -716,15 +726,15 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
        /* Preexecs are done here as they might make the dir we are to ChDir
         * to below */
        /* execute any "root preexec = " line */
-       if (*lp_root_preexec(talloc_tos(), snum)) {
-               char *cmd = talloc_sub_advanced(talloc_tos(),
-                                       lp_servicename(talloc_tos(), SNUM(conn)),
+       if (*lp_root_preexec(talloc_tos(), lp_sub, snum)) {
+               char *cmd = talloc_sub_full(talloc_tos(),
+                                       lp_const_servicename(SNUM(conn)),
                                        conn->session_info->unix_info->unix_name,
                                        conn->connectpath,
                                        conn->session_info->unix_token->gid,
                                        conn->session_info->unix_info->sanitized_username,
                                        conn->session_info->info->domain_name,
-                                       lp_root_preexec(talloc_tos(), snum));
+                                       lp_root_preexec(talloc_tos(), lp_sub, snum));
                DEBUG(5,("cmd=%s\n",cmd));
                ret = smbrun(cmd, NULL, NULL);
                TALLOC_FREE(cmd);
@@ -737,7 +747,7 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
        }
 
 /* USER Activites: */
-       if (!change_to_user(conn, conn->vuid)) {
+       if (!change_to_user_and_service(conn, conn->vuid)) {
                /* No point continuing if they fail the basic checks */
                DEBUG(0,("Can't become connected user!\n"));
                status = NT_STATUS_LOGON_FAILURE;
@@ -754,15 +764,15 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
         * to below */
 
        /* execute any "preexec = " line */
-       if (*lp_preexec(talloc_tos(), snum)) {
-               char *cmd = talloc_sub_advanced(talloc_tos(),
-                                       lp_servicename(talloc_tos(), SNUM(conn)),
+       if (*lp_preexec(talloc_tos(), lp_sub, snum)) {
+               char *cmd = talloc_sub_full(talloc_tos(),
+                                       lp_const_servicename(SNUM(conn)),
                                        conn->session_info->unix_info->unix_name,
                                        conn->connectpath,
                                        conn->session_info->unix_token->gid,
                                        conn->session_info->unix_info->sanitized_username,
                                        conn->session_info->info->domain_name,
-                                       lp_preexec(talloc_tos(), snum));
+                                       lp_preexec(talloc_tos(), lp_sub, snum));
                ret = smbrun(cmd, NULL, NULL);
                TALLOC_FREE(cmd);
                if (ret != 0 && lp_preexec_close(snum)) {
@@ -788,38 +798,38 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
 /* ROOT Activites: */
 
        /*
-        * If widelinks are disallowed we need to canonicalise the connect
+        * Canonicalise the connect
         * path here to ensure we don't have any symlinks in the
         * connectpath. We will be checking all paths on this connection are
         * below this directory. We must do this after the VFS init as we
         * depend on the realpath() pointer in the vfs table. JRA.
         */
-       if (!lp_widelinks(snum)) {
-               if (!canonicalize_connect_path(conn)) {
-                       DEBUG(0, ("canonicalize_connect_path failed "
-                       "for service %s, path %s\n",
-                               lp_servicename(talloc_tos(), snum),
-                               conn->connectpath));
-                       status = NT_STATUS_BAD_NETWORK_NAME;
-                       goto err_root_exit;
-               }
+       ok = canonicalize_connect_path(conn);
+       if (!ok) {
+               DBG_ERR("canonicalize_connect_path failed "
+               "for service %s, path %s\n",
+                       lp_const_servicename(snum),
+                       conn->connectpath);
+               status = NT_STATUS_BAD_NETWORK_NAME;
+               goto err_root_exit;
        }
 
        /* Add veto/hide lists */
        if (!IS_IPC(conn) && !IS_PRINT(conn)) {
                set_namearray( &conn->veto_list,
-                              lp_veto_files(talloc_tos(), snum));
+                              lp_veto_files(talloc_tos(), lp_sub, snum));
                set_namearray( &conn->hide_list,
-                              lp_hide_files(talloc_tos(), snum));
+                              lp_hide_files(talloc_tos(), lp_sub, snum));
                set_namearray( &conn->veto_oplock_list,
-                              lp_veto_oplock_files(talloc_tos(), snum));
+                              lp_veto_oplock_files(talloc_tos(), lp_sub, snum));
                set_namearray( &conn->aio_write_behind_list,
-                               lp_aio_write_behind(talloc_tos(), snum));
+                               lp_aio_write_behind(talloc_tos(), lp_sub, snum));
        }
        smb_fname_cpath = synthetic_smb_fname(talloc_tos(),
                                        conn->connectpath,
                                        NULL,
                                        NULL,
+                                       0,
                                        0);
        if (smb_fname_cpath == NULL) {
                status = NT_STATUS_NO_MEMORY;
@@ -835,15 +845,15 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
        if ((ret = SMB_VFS_STAT(conn, smb_fname_cpath)) != 0 ||
            !S_ISDIR(smb_fname_cpath->st.st_ex_mode)) {
                if (ret == 0 && !S_ISDIR(smb_fname_cpath->st.st_ex_mode)) {
-                       DEBUG(0,("'%s' is not a directory, when connecting to "
+                       DBG_ERR("'%s' is not a directory, when connecting to "
                                 "[%s]\n", conn->connectpath,
-                                lp_servicename(talloc_tos(), snum)));
+                                lp_const_servicename(snum));
                } else {
-                       DEBUG(0,("'%s' does not exist or permission denied "
+                       DBG_ERR("'%s' does not exist or permission denied "
                                 "when connecting to [%s] Error was %s\n",
                                 conn->connectpath,
-                                lp_servicename(talloc_tos(), snum),
-                                strerror(errno) ));
+                                lp_const_servicename(snum),
+                                strerror(errno));
                }
                status = NT_STATUS_BAD_NETWORK_NAME;
                goto err_root_exit;
@@ -854,7 +864,7 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
        conn->origpath = talloc_strdup(conn, conn->connectpath);
 
        /* Figure out the characteristics of the underlying filesystem. This
-        * assumes that all the filesystem mounted withing a share path have
+        * assumes that all the filesystem mounted within a share path have
         * the same characteristics, which is likely but not guaranteed.
         */
 
@@ -872,14 +882,15 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
                                                talloc_tos()) );
                dbgtext( "%s", srv_is_signing_active(xconn) ? "signed " : "");
                dbgtext( "connect to service %s ",
-                        lp_servicename(talloc_tos(), snum) );
+                        lp_const_servicename(snum) );
                dbgtext( "initially as user %s ",
                         conn->session_info->unix_info->unix_name );
                dbgtext( "(uid=%d, gid=%d) ", (int)effuid, (int)effgid );
                dbgtext( "(pid %d)\n", (int)getpid() );
        }
 
-       return status;
+       conn->tcon_done = true;
+       return NT_STATUS_OK;
 
   err_root_exit:
 
@@ -901,10 +912,12 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
 
 static connection_struct *make_connection_smb1(struct smb_request *req,
                                        NTTIME now,
-                                       int snum, struct user_struct *vuser,
+                                       int snum,
                                        const char *pdev,
                                        NTSTATUS *pstatus)
 {
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
        struct smbXsrv_tcon *tcon;
        NTSTATUS status;
        struct connection_struct *conn;
@@ -932,7 +945,7 @@ static connection_struct *make_connection_smb1(struct smb_request *req,
        *pstatus = make_connection_snum(req->xconn,
                                        conn,
                                        snum,
-                                       vuser,
+                                       req->session,
                                        pdev);
        if (!NT_STATUS_IS_OK(*pstatus)) {
                conn_free(conn);
@@ -940,7 +953,7 @@ static connection_struct *make_connection_smb1(struct smb_request *req,
                return NULL;
        }
 
-       tcon->global->share_name = lp_servicename(tcon->global, SNUM(conn));
+       tcon->global->share_name = lp_servicename(tcon->global, lp_sub, SNUM(conn));
        if (tcon->global->share_name == NULL) {
                conn_free(conn);
                TALLOC_FREE(tcon);
@@ -948,7 +961,7 @@ static connection_struct *make_connection_smb1(struct smb_request *req,
                return NULL;
        }
        tcon->global->session_global_id =
-               vuser->session->global->session_global_id;
+               req->session->global->session_global_id;
 
        tcon->compat = talloc_move(tcon, &conn);
        tcon->status = NT_STATUS_OK;
@@ -970,7 +983,6 @@ static connection_struct *make_connection_smb1(struct smb_request *req,
 connection_struct *make_connection_smb2(struct smbd_smb2_request *req,
                                        struct smbXsrv_tcon *tcon,
                                        int snum,
-                                       struct user_struct *vuser,
                                        const char *pdev,
                                        NTSTATUS *pstatus)
 {
@@ -988,7 +1000,7 @@ connection_struct *make_connection_smb2(struct smbd_smb2_request *req,
        *pstatus = make_connection_snum(req->xconn,
                                        conn,
                                        snum,
-                                       vuser,
+                                       req->session,
                                        pdev);
        if (!NT_STATUS_IS_OK(*pstatus)) {
                conn_free(conn);
@@ -1010,8 +1022,10 @@ connection_struct *make_connection(struct smb_request *req,
                                   NTSTATUS *status)
 {
        struct smbd_server_connection *sconn = req->sconn;
+       struct smbXsrv_session *session = req->session;
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
        uid_t euid;
-       struct user_struct *vuser = NULL;
        char *service = NULL;
        fstring dev;
        int snum = -1;
@@ -1031,8 +1045,7 @@ connection_struct *make_connection(struct smb_request *req,
                return NULL;
        }
 
-       vuser = get_valid_user_struct(sconn, vuid);
-       if (!vuser) {
+       if (session == NULL) {
                DEBUG(1,("make_connection: refusing to connect with "
                         "no session setup\n"));
                *status = NT_STATUS_ACCESS_DENIED;
@@ -1043,13 +1056,10 @@ connection_struct *make_connection(struct smb_request *req,
           without too many getpwnam() lookups.  This is particulary nasty for
           winbind usernames, where the share name isn't the same as unix
           username.
-
-          The snum of the homes share is stored on the vuser at session setup
-          time.
        */
 
        if (strequal(service_in,HOMES_NAME)) {
-               if (vuser->homes_snum == -1) {
+               if (session->homes_snum == -1) {
                        DEBUG(2, ("[homes] share not available for "
                                  "this user because it was not found "
                                  "or created at session setup "
@@ -1060,17 +1070,15 @@ connection_struct *make_connection(struct smb_request *req,
                DEBUG(5, ("making a connection to [homes] service "
                          "created at session setup time\n"));
                return make_connection_smb1(req, now,
-                                           vuser->homes_snum,
-                                           vuser,
+                                           session->homes_snum,
                                            dev, status);
-       } else if ((vuser->homes_snum != -1)
+       } else if ((session->homes_snum != -1)
                   && strequal(service_in,
-                              lp_servicename(talloc_tos(), vuser->homes_snum))) {
+                              lp_const_servicename(session->homes_snum))) {
                DEBUG(5, ("making a connection to 'homes' service [%s] "
                          "created at session setup time\n", service_in));
                return make_connection_smb1(req, now,
-                                           vuser->homes_snum,
-                                           vuser,
+                                           session->homes_snum,
                                            dev, status);
        }
 
@@ -1110,17 +1118,17 @@ connection_struct *make_connection(struct smb_request *req,
        }
 
        /* Handle non-Dfs clients attempting connections to msdfs proxy */
-       if (lp_host_msdfs() && (*lp_msdfs_proxy(talloc_tos(), snum) != '\0'))  {
+       if (lp_host_msdfs() && (*lp_msdfs_proxy(talloc_tos(), lp_sub, snum) != '\0'))  {
                DEBUG(3, ("refusing connection to dfs proxy share '%s' "
                          "(pointing to %s)\n", 
-                       service, lp_msdfs_proxy(talloc_tos(), snum)));
+                       service, lp_msdfs_proxy(talloc_tos(), lp_sub, snum)));
                *status = NT_STATUS_BAD_NETWORK_NAME;
                return NULL;
        }
 
        DEBUG(5, ("making a connection to 'normal' service %s\n", service));
 
-       return make_connection_smb1(req, now, snum, vuser,
+       return make_connection_smb1(req, now, snum,
                                    dev, status);
 }
 
@@ -1132,20 +1140,18 @@ void close_cnum(connection_struct *conn, uint64_t vuid)
 {
        char rootpath[2] = { '/', '\0'};
        struct smb_filename root_fname = { .base_name = rootpath };
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
 
        file_close_conn(conn);
 
-       if (!IS_IPC(conn)) {
-               dptr_closecnum(conn);
-       }
-
        change_to_root_user();
 
        DEBUG(IS_IPC(conn)?3:2, ("%s (%s) closed connection to service %s\n",
                                 get_remote_machine_name(),
                                 tsocket_address_string(conn->sconn->remote_address,
                                                        talloc_tos()),
-                                lp_servicename(talloc_tos(), SNUM(conn))));
+                                lp_const_servicename(SNUM(conn))));
 
        /* make sure we leave the directory available for unmount */
        vfs_ChDir(conn, &root_fname);
@@ -1154,16 +1160,16 @@ void close_cnum(connection_struct *conn, uint64_t vuid)
        SMB_VFS_DISCONNECT(conn);
 
        /* execute any "postexec = " line */
-       if (*lp_postexec(talloc_tos(), SNUM(conn)) &&
-           change_to_user(conn, vuid))  {
-               char *cmd = talloc_sub_advanced(talloc_tos(),
-                                       lp_servicename(talloc_tos(), SNUM(conn)),
+       if (*lp_postexec(talloc_tos(), lp_sub, SNUM(conn)) &&
+           change_to_user_and_service(conn, vuid))  {
+               char *cmd = talloc_sub_full(talloc_tos(),
+                                       lp_const_servicename(SNUM(conn)),
                                        conn->session_info->unix_info->unix_name,
                                        conn->connectpath,
                                        conn->session_info->unix_token->gid,
                                        conn->session_info->unix_info->sanitized_username,
                                        conn->session_info->info->domain_name,
-                                       lp_postexec(talloc_tos(), SNUM(conn)));
+                                       lp_postexec(talloc_tos(), lp_sub, SNUM(conn)));
                smbrun(cmd, NULL, NULL);
                TALLOC_FREE(cmd);
                change_to_root_user();
@@ -1171,15 +1177,15 @@ void close_cnum(connection_struct *conn, uint64_t vuid)
 
        change_to_root_user();
        /* execute any "root postexec = " line */
-       if (*lp_root_postexec(talloc_tos(), SNUM(conn)))  {
-               char *cmd = talloc_sub_advanced(talloc_tos(),
-                                       lp_servicename(talloc_tos(), SNUM(conn)),
+       if (*lp_root_postexec(talloc_tos(), lp_sub, SNUM(conn)))  {
+               char *cmd = talloc_sub_full(talloc_tos(),
+                                       lp_const_servicename(SNUM(conn)),
                                        conn->session_info->unix_info->unix_name,
                                        conn->connectpath,
                                        conn->session_info->unix_token->gid,
                                        conn->session_info->unix_info->sanitized_username,
                                        conn->session_info->info->domain_name,
-                                       lp_root_postexec(talloc_tos(), SNUM(conn)));
+                                       lp_root_postexec(talloc_tos(), lp_sub, SNUM(conn)));
                smbrun(cmd, NULL, NULL);
                TALLOC_FREE(cmd);
        }