LCOV - code coverage report
Current view: top level - source3/smbd - service.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 341 516 66.1 %
Date: 2021-09-23 10:06:22 Functions: 16 16 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    service (connection) opening and closing
       4             :    Copyright (C) Andrew Tridgell 1992-1998
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "system/filesys.h"
      22             : #include "system/passwd.h" /* uid_wrapper */
      23             : #include "../lib/tsocket/tsocket.h"
      24             : #include "smbd/smbd.h"
      25             : #include "smbd/globals.h"
      26             : #include "../librpc/gen_ndr/netlogon.h"
      27             : #include "../libcli/security/security.h"
      28             : #include "printing/pcap.h"
      29             : #include "passdb/lookup_sid.h"
      30             : #include "auth.h"
      31             : #include "../auth/auth_util.h"
      32             : #include "lib/param/loadparm.h"
      33             : #include "messages.h"
      34             : #include "lib/afs/afs_funcs.h"
      35             : #include "lib/util_path.h"
      36             : #include "lib/util/string_wrappers.h"
      37             : 
      38       88818 : bool canonicalize_connect_path(connection_struct *conn)
      39             : {
      40             :         bool ret;
      41       88818 :         struct smb_filename con_fname = { .base_name = conn->connectpath };
      42       88818 :         struct smb_filename *resolved_fname = SMB_VFS_REALPATH(conn, talloc_tos(),
      43             :                                                 &con_fname);
      44       88818 :         if (resolved_fname == NULL) {
      45          58 :                 return false;
      46             :         }
      47       88760 :         ret = set_conn_connectpath(conn,resolved_fname->base_name);
      48       88760 :         TALLOC_FREE(resolved_fname);
      49       88760 :         return ret;
      50             : }
      51             : 
      52             : /****************************************************************************
      53             :  Ensure when setting connectpath it is a canonicalized (no ./ // or ../)
      54             :  absolute path stating in / and not ending in /.
      55             : ****************************************************************************/
      56             : 
      57      135336 : bool set_conn_connectpath(connection_struct *conn, const char *connectpath)
      58             : {
      59             :         char *destname;
      60             : 
      61      135336 :         if (connectpath == NULL || connectpath[0] == '\0') {
      62           0 :                 return false;
      63             :         }
      64             : 
      65      135336 :         destname = canonicalize_absolute_path(conn, connectpath);
      66      135336 :         if (destname == NULL) {
      67           0 :                 return false;
      68             :         }
      69             : 
      70      135336 :         DBG_DEBUG("service %s, connectpath = %s\n",
      71             :                   lp_const_servicename(SNUM(conn)), destname);
      72             : 
      73      135336 :         talloc_free(conn->connectpath);
      74      135336 :         conn->connectpath = destname;
      75             :         /*
      76             :          * Ensure conn->cwd_fsp->fsp_name is initialized.
      77             :          * start as conn->connectpath.
      78             :          */
      79      135336 :         TALLOC_FREE(conn->cwd_fsp->fsp_name);
      80      148574 :         conn->cwd_fsp->fsp_name = synthetic_smb_fname(conn,
      81      135336 :                                 conn->connectpath,
      82             :                                 NULL,
      83             :                                 NULL,
      84             :                                 0,
      85             :                                 0);
      86      135336 :         if (conn->cwd_fsp->fsp_name == NULL) {
      87           0 :                 return false;
      88             :         }
      89      135336 :         return true;
      90             : }
      91             : 
      92             : /****************************************************************************
      93             :  Load parameters specific to a connection/service.
      94             : ****************************************************************************/
      95             : 
      96      338339 : void set_current_case_sensitive(connection_struct *conn, uint16_t flags)
      97             : {
      98             :         int snum;
      99             :         enum remote_arch_types ra_type;
     100             : 
     101      338339 :         SMB_ASSERT(conn != NULL);
     102             : 
     103      338339 :         snum = SNUM(conn);
     104             : 
     105      338339 :         if ((conn == last_conn) && (last_flags == flags)) {
     106      323841 :                 return;
     107             :         }
     108             : 
     109        7317 :         last_conn = conn;
     110        7317 :         last_flags = flags;
     111             : 
     112             :         /*
     113             :          * Obey the client case sensitivity requests - only for clients that
     114             :          * support it. */
     115        7317 :         switch (lp_case_sensitive(snum)) {
     116        7257 :         case Auto:
     117             :                 /*
     118             :                  * We need this uglyness due to DOS/Win9x clients that lie
     119             :                  * about case insensitivity. */
     120        7257 :                 ra_type = get_remote_arch();
     121        7257 :                 if (conn->sconn->using_smb2) {
     122           0 :                         conn->case_sensitive = false;
     123        7257 :                 } else if ((ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
     124             :                         /*
     125             :                          * Client can't support per-packet case sensitive
     126             :                          * pathnames. */
     127           0 :                         conn->case_sensitive = false;
     128             :                 } else {
     129        7257 :                         conn->case_sensitive =
     130        7257 :                                         !(flags & FLAG_CASELESS_PATHNAMES);
     131             :                 }
     132        7160 :         break;
     133          60 :         case True:
     134          60 :                 conn->case_sensitive = true;
     135          60 :                 break;
     136           0 :         default:
     137           0 :                 conn->case_sensitive = false;
     138           0 :                 break;
     139             :         }
     140        7220 :         return;
     141             : }
     142             : 
     143     1860772 : bool chdir_current_service(connection_struct *conn)
     144             : {
     145     3496566 :         const struct smb_filename connectpath_fname = {
     146     1860772 :                 .base_name = conn->connectpath,
     147             :         };
     148     1860772 :         int saved_errno = 0;
     149     1860772 :         char *utok_str = NULL;
     150             :         int ret;
     151             : 
     152     1860772 :         conn->lastused_count++;
     153             : 
     154     1860772 :         ret = vfs_ChDir(conn, &connectpath_fname);
     155     1860772 :         if (ret == 0) {
     156     1844996 :                 return true;
     157             :         }
     158         136 :         saved_errno = errno;
     159             : 
     160         136 :         utok_str = utok_string(talloc_tos(),
     161         136 :                                conn->session_info->unix_token);
     162         136 :         if (utok_str == NULL) {
     163           0 :                 errno = saved_errno;
     164           0 :                 return false;
     165             :         }
     166             : 
     167         136 :         DBG_ERR("vfs_ChDir(%s) failed: %s. Current token: %s\n",
     168             :                 conn->connectpath,
     169             :                 strerror(saved_errno),
     170             :                 utok_str);
     171             : 
     172         136 :         if (saved_errno != 0) {
     173         136 :                 errno = saved_errno;
     174             :         }
     175         136 :         return false;
     176             : }
     177             : 
     178             : /****************************************************************************
     179             :  do some basic sainity checks on the share.  
     180             :  This function modifies dev, ecode.
     181             : ****************************************************************************/
     182             : 
     183       42316 : static NTSTATUS share_sanity_checks(const struct tsocket_address *remote_address,
     184             :                                     const char *rhost,
     185             :                                     int snum,
     186             :                                     fstring dev)
     187             : {
     188             :         char *raddr;
     189             : 
     190       42316 :         raddr = tsocket_address_inet_addr_string(remote_address,
     191             :                                                  talloc_tos());
     192       42316 :         if (raddr == NULL) {
     193           0 :                 return NT_STATUS_NO_MEMORY;
     194             :         }
     195             : 
     196       81038 :         if (!lp_snum_ok(snum) ||
     197       42316 :             !allow_access(lp_hosts_deny(snum), lp_hosts_allow(snum),
     198             :                           rhost, raddr)) {
     199           0 :                 return NT_STATUS_ACCESS_DENIED;
     200             :         }
     201             : 
     202       42316 :         if (dev[0] == '?' || !dev[0]) {
     203       39697 :                 if (lp_printable(snum)) {
     204          28 :                         fstrcpy(dev,"LPT1:");
     205       39669 :                 } else if (strequal(lp_fstype(snum), "IPC")) {
     206       20905 :                         fstrcpy(dev, "IPC");
     207             :                 } else {
     208       18764 :                         fstrcpy(dev,"A:");
     209             :                 }
     210             :         }
     211             : 
     212       42316 :         if (!strupper_m(dev)) {
     213           0 :                 DEBUG(2,("strupper_m %s failed\n", dev));
     214           0 :                 return NT_STATUS_INVALID_PARAMETER;
     215             :         }
     216             : 
     217       42316 :         if (lp_printable(snum)) {
     218          28 :                 if (!strequal(dev, "LPT1:")) {
     219           0 :                         return NT_STATUS_BAD_DEVICE_TYPE;
     220             :                 }
     221       42288 :         } else if (strequal(lp_fstype(snum), "IPC")) {
     222       23404 :                 if (!strequal(dev, "IPC")) {
     223          27 :                         return NT_STATUS_BAD_DEVICE_TYPE;
     224             :                 }
     225       18884 :         } else if (!strequal(dev, "A:")) {
     226          27 :                 return NT_STATUS_BAD_DEVICE_TYPE;
     227             :         }
     228             : 
     229             :         /* Behave as a printer if we are supposed to */
     230       42262 :         if (lp_printable(snum) && (strcmp(dev, "A:") == 0)) {
     231           0 :                 fstrcpy(dev, "LPT1:");
     232             :         }
     233             : 
     234       42262 :         return NT_STATUS_OK;
     235             : }
     236             : 
     237             : /*
     238             :  * Go through lookup_name etc to find the force'd group.  
     239             :  *
     240             :  * Create a new token from src_token, replacing the primary group sid with the
     241             :  * one found.
     242             :  */
     243             : 
     244         130 : static NTSTATUS find_forced_group(bool force_user,
     245             :                                   int snum, const char *username,
     246             :                                   struct dom_sid *pgroup_sid,
     247             :                                   gid_t *pgid)
     248             : {
     249         130 :         NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
     250         130 :         TALLOC_CTX *frame = talloc_stackframe();
     251         111 :         const struct loadparm_substitution *lp_sub =
     252          19 :                 loadparm_s3_global_substitution();
     253             :         struct dom_sid group_sid;
     254             :         enum lsa_SidType type;
     255             :         char *groupname;
     256         130 :         bool user_must_be_member = False;
     257             :         gid_t gid;
     258             : 
     259         130 :         groupname = lp_force_group(talloc_tos(), lp_sub, snum);
     260         130 :         if (groupname == NULL) {
     261           0 :                 DEBUG(1, ("talloc_strdup failed\n"));
     262           0 :                 result = NT_STATUS_NO_MEMORY;
     263           0 :                 goto done;
     264             :         }
     265             : 
     266         130 :         if (groupname[0] == '+') {
     267           0 :                 user_must_be_member = True;
     268           0 :                 groupname += 1;
     269             :         }
     270             : 
     271         130 :         groupname = talloc_string_sub(talloc_tos(), groupname,
     272             :                                       "%S", lp_const_servicename(snum));
     273         130 :         if (groupname == NULL) {
     274           0 :                 DEBUG(1, ("talloc_string_sub failed\n"));
     275           0 :                 result = NT_STATUS_NO_MEMORY;
     276           0 :                 goto done;
     277             :         }
     278             : 
     279         130 :         if (!lookup_name_smbconf(talloc_tos(), groupname,
     280             :                          LOOKUP_NAME_ALL|LOOKUP_NAME_GROUP,
     281             :                          NULL, NULL, &group_sid, &type)) {
     282           0 :                 DEBUG(10, ("lookup_name_smbconf(%s) failed\n",
     283             :                            groupname));
     284           0 :                 goto done;
     285             :         }
     286             : 
     287         130 :         if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
     288           0 :             (type != SID_NAME_WKN_GRP)) {
     289           0 :                 DEBUG(10, ("%s is a %s, not a group\n", groupname,
     290             :                            sid_type_lookup(type)));
     291           0 :                 goto done;
     292             :         }
     293             : 
     294         130 :         if (!sid_to_gid(&group_sid, &gid)) {
     295             :                 struct dom_sid_buf buf;
     296           0 :                 DEBUG(10, ("sid_to_gid(%s) for %s failed\n",
     297             :                            dom_sid_str_buf(&group_sid, &buf), groupname));
     298           0 :                 goto done;
     299             :         }
     300             : 
     301             :         /*
     302             :          * If the user has been forced and the forced group starts with a '+',
     303             :          * then we only set the group to be the forced group if the forced
     304             :          * user is a member of that group.  Otherwise, the meaning of the '+'
     305             :          * would be ignored.
     306             :          */
     307             : 
     308         130 :         if (force_user && user_must_be_member) {
     309           0 :                 if (user_in_group_sid(username, &group_sid)) {
     310           0 :                         sid_copy(pgroup_sid, &group_sid);
     311           0 :                         *pgid = gid;
     312           0 :                         DEBUG(3,("Forced group %s for member %s\n",
     313             :                                  groupname, username));
     314             :                 } else {
     315           0 :                         DEBUG(0,("find_forced_group: forced user %s is not a member "
     316             :                                 "of forced group %s. Disallowing access.\n",
     317             :                                 username, groupname ));
     318           0 :                         result = NT_STATUS_MEMBER_NOT_IN_GROUP;
     319           0 :                         goto done;
     320             :                 }
     321             :         } else {
     322         130 :                 sid_copy(pgroup_sid, &group_sid);
     323         130 :                 *pgid = gid;
     324         130 :                 DEBUG(3,("Forced group %s\n", groupname));
     325             :         }
     326             : 
     327         130 :         result = NT_STATUS_OK;
     328         130 :  done:
     329         130 :         TALLOC_FREE(frame);
     330         130 :         return result;
     331             : }
     332             : 
     333             : /****************************************************************************
     334             :   Create an auth_session_info structure for a connection_struct
     335             : ****************************************************************************/
     336             : 
     337       42262 : static NTSTATUS create_connection_session_info(struct smbd_server_connection *sconn,
     338             :                                               TALLOC_CTX *mem_ctx, int snum,
     339             :                                               struct auth_session_info *session_info,
     340             :                                               struct auth_session_info **presult)
     341             : {
     342             :         struct auth_session_info *result;
     343             : 
     344       42262 :         if (lp_guest_only(snum)) {
     345         128 :                 return make_session_info_guest(mem_ctx, presult);
     346             :         }
     347             : 
     348             :         /*
     349             :          * This is the normal security != share case where we have a
     350             :          * valid vuid from the session setup.                 */
     351             : 
     352       42134 :         if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
     353         970 :                 if (!lp_guest_ok(snum)) {
     354           4 :                         DBG_WARNING("guest user (from session setup) "
     355             :                                   "not permitted to access this share "
     356             :                                   "(%s)\n", lp_const_servicename(snum));
     357           4 :                         return NT_STATUS_ACCESS_DENIED;
     358             :                 }
     359             :         } else {
     360       41164 :                 if (!user_ok_token(session_info->unix_info->unix_name,
     361       41164 :                                    session_info->info->domain_name,
     362       41164 :                                    session_info->security_token, snum)) {
     363           8 :                         DBG_WARNING("user '%s' (from session setup) not "
     364             :                                   "permitted to access this share "
     365             :                                   "(%s)\n",
     366             :                                   session_info->unix_info->unix_name,
     367             :                                   lp_const_servicename(snum));
     368           8 :                         return NT_STATUS_ACCESS_DENIED;
     369             :                 }
     370             :         }
     371             : 
     372       42122 :         result = copy_session_info(mem_ctx, session_info);
     373       42122 :         if (result == NULL) {
     374           0 :                 return NT_STATUS_NO_MEMORY;
     375             :         }
     376             : 
     377       42122 :         *presult = result;
     378       42122 :         return NT_STATUS_OK;
     379             : }
     380             : 
     381             : /****************************************************************************
     382             :   Set relevant user and group settings corresponding to force user/group
     383             :   configuration for the given snum.
     384             : ****************************************************************************/
     385             : 
     386       42344 : NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
     387             : {
     388       38762 :         const struct loadparm_substitution *lp_sub =
     389        3582 :                 loadparm_s3_global_substitution();
     390             :         NTSTATUS status;
     391             : 
     392       42344 :         if (*lp_force_user(talloc_tos(), lp_sub, snum)) {
     393             : 
     394             :                 /*
     395             :                  * Replace conn->session_info with a completely faked up one
     396             :                  * from the username we are forced into :-)
     397             :                  */
     398             : 
     399             :                 char *fuser;
     400             :                 char *sanitized_username;
     401             :                 struct auth_session_info *forced_serverinfo;
     402             :                 bool guest;
     403             : 
     404         246 :                 fuser = talloc_string_sub(conn, lp_force_user(talloc_tos(), lp_sub, snum), "%S",
     405             :                                           lp_const_servicename(snum));
     406         246 :                 if (fuser == NULL) {
     407           0 :                         return NT_STATUS_NO_MEMORY;
     408             :                 }
     409             : 
     410         246 :                 guest = security_session_user_level(conn->session_info, NULL) < SECURITY_USER;
     411             : 
     412         246 :                 status = make_session_info_from_username(
     413             :                         conn, fuser,
     414             :                         guest,
     415             :                         &forced_serverinfo);
     416         246 :                 if (!NT_STATUS_IS_OK(status)) {
     417           0 :                         return status;
     418             :                 }
     419             : 
     420             :                 /* We don't want to replace the original sanitized_username
     421             :                    as it is the original user given in the connect attempt.
     422             :                    This is used in '%U' substitutions. */
     423         246 :                 sanitized_username = discard_const_p(char,
     424             :                         forced_serverinfo->unix_info->sanitized_username);
     425         246 :                 TALLOC_FREE(sanitized_username);
     426         492 :                 forced_serverinfo->unix_info->sanitized_username =
     427         459 :                         talloc_move(forced_serverinfo->unix_info,
     428             :                                 &conn->session_info->unix_info->sanitized_username);
     429             : 
     430         246 :                 TALLOC_FREE(conn->session_info);
     431         246 :                 conn->session_info = forced_serverinfo;
     432             : 
     433         246 :                 conn->force_user = true;
     434         246 :                 DEBUG(3,("Forced user %s\n", fuser));
     435             :         }
     436             : 
     437             :         /*
     438             :          * If force group is true, then override
     439             :          * any groupid stored for the connecting user.
     440             :          */
     441             : 
     442       42344 :         if (*lp_force_group(talloc_tos(), lp_sub, snum)) {
     443             : 
     444         463 :                 status = find_forced_group(
     445         241 :                         conn->force_user, snum, conn->session_info->unix_info->unix_name,
     446         130 :                         &conn->session_info->security_token->sids[1],
     447         130 :                         &conn->session_info->unix_token->gid);
     448             : 
     449         130 :                 if (!NT_STATUS_IS_OK(status)) {
     450           0 :                         return status;
     451             :                 }
     452             : 
     453             :                 /*
     454             :                  * We need to cache this gid, to use within
     455             :                  * change_to_user() separately from the conn->session_info
     456             :                  * struct. We only use conn->session_info directly if
     457             :                  * "force_user" was set.
     458             :                  */
     459         130 :                 conn->force_group_gid = conn->session_info->unix_token->gid;
     460             :         }
     461             : 
     462       42344 :         return NT_STATUS_OK;
     463             : }
     464             : 
     465       18693 : static NTSTATUS notify_init_sconn(struct smbd_server_connection *sconn)
     466             : {
     467             :         NTSTATUS status;
     468             : 
     469       18693 :         if (sconn->notify_ctx != NULL) {
     470        1387 :                 return NT_STATUS_OK;
     471             :         }
     472             : 
     473       17306 :         sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx,
     474             :                                         sconn, notify_callback);
     475       17306 :         if (sconn->notify_ctx == NULL) {
     476           0 :                 return NT_STATUS_NO_MEMORY;
     477             :         }
     478             : 
     479       17306 :         status = messaging_register(sconn->msg_ctx, sconn,
     480             :                                     MSG_SMB_NOTIFY_CANCEL_DELETED,
     481             :                                     smbd_notify_cancel_deleted);
     482       17306 :         if (!NT_STATUS_IS_OK(status)) {
     483           0 :                 DBG_DEBUG("messaging_register failed: %s\n",
     484             :                           nt_errstr(status));
     485           0 :                 TALLOC_FREE(sconn->notify_ctx);
     486           0 :                 return status;
     487             :         }
     488             : 
     489       17306 :         status = messaging_register(sconn->msg_ctx, sconn,
     490             :                                     MSG_SMB_NOTIFY_STARTED,
     491             :                                     smbd_notifyd_restarted);
     492       17306 :         if (!NT_STATUS_IS_OK(status)) {
     493           0 :                 DBG_DEBUG("messaging_register failed: %s\n",
     494             :                           nt_errstr(status));
     495           0 :                 messaging_deregister(sconn->msg_ctx,
     496             :                                      MSG_SMB_NOTIFY_CANCEL_DELETED, sconn);
     497           0 :                 TALLOC_FREE(sconn->notify_ctx);
     498           0 :                 return status;
     499             :         }
     500             : 
     501       17306 :         return NT_STATUS_OK;
     502             : }
     503             : 
     504             : /****************************************************************************
     505             :   Make a connection, given the snum to connect to, and the vuser of the
     506             :   connecting user if appropriate.
     507             : ****************************************************************************/
     508             : 
     509       42316 : static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
     510             :                                         connection_struct *conn,
     511             :                                         int snum,
     512             :                                         struct smbXsrv_session *session,
     513             :                                         const char *pdev)
     514             : {
     515       42316 :         struct smbd_server_connection *sconn = xconn->client->sconn;
     516       38722 :         const struct loadparm_substitution *lp_sub =
     517        3594 :                 loadparm_s3_global_substitution();
     518       42316 :         struct smb_filename *smb_fname_cpath = NULL;
     519             :         fstring dev;
     520             :         int ret;
     521       42316 :         bool on_err_call_dis_hook = false;
     522             :         uid_t effuid;
     523             :         gid_t effgid;
     524             :         NTSTATUS status;
     525             :         bool ok;
     526             : 
     527       42316 :         fstrcpy(dev, pdev);
     528             : 
     529       42316 :         status = share_sanity_checks(sconn->remote_address,
     530             :                                        sconn->remote_hostname,
     531             :                                        snum,
     532             :                                        dev);
     533       42316 :         if (NT_STATUS_IS_ERR(status)) {
     534          48 :                 goto err_root_exit;
     535             :         }
     536             : 
     537       42262 :         conn->params->service = snum;
     538             : 
     539       80936 :         status = create_connection_session_info(sconn,
     540       42262 :                 conn, snum, session->global->auth_session_info,
     541             :                 &conn->session_info);
     542             : 
     543       42262 :         if (!NT_STATUS_IS_OK(status)) {
     544          12 :                 DEBUG(1, ("create_connection_session_info failed: %s\n",
     545             :                           nt_errstr(status)));
     546          12 :                 goto err_root_exit;
     547             :         }
     548             : 
     549       42250 :         if (lp_guest_only(snum)) {
     550         128 :                 conn->force_user = true;
     551             :         }
     552             : 
     553       42250 :         conn->num_files_open = 0;
     554       42250 :         conn->lastused = conn->lastused_count = time(NULL);
     555       42250 :         conn->printer = (strncmp(dev,"LPT",3) == 0);
     556       82697 :         conn->ipc = ( (strncmp(dev,"IPC",3) == 0) ||
     557       18873 :                       ( lp_enable_asu_support() && strequal(dev,"ADMIN$")) );
     558             : 
     559             :         /* Case options for the share. */
     560       42250 :         conn_setup_case_options(conn);
     561             : 
     562       42250 :         conn->encrypt_level = lp_server_smb_encrypt(snum);
     563       42250 :         if (conn->encrypt_level > SMB_ENCRYPTION_OFF) {
     564         238 :                 if (lp_server_smb_encrypt(-1) == SMB_ENCRYPTION_OFF) {
     565          12 :                         if (conn->encrypt_level == SMB_ENCRYPTION_REQUIRED) {
     566           0 :                                 DBG_ERR("Service [%s] requires encryption, but "
     567             :                                         "it is disabled globally!\n",
     568             :                                         lp_const_servicename(snum));
     569           0 :                                 status = NT_STATUS_ACCESS_DENIED;
     570           0 :                                 goto err_root_exit;
     571             :                         }
     572          12 :                         conn->encrypt_level = SMB_ENCRYPTION_OFF;
     573             :                 }
     574             :         }
     575             : 
     576       42250 :         conn->veto_list = NULL;
     577       42250 :         conn->hide_list = NULL;
     578       42250 :         conn->veto_oplock_list = NULL;
     579       42250 :         conn->aio_write_behind_list = NULL;
     580             : 
     581       42250 :         conn->read_only = lp_read_only(SNUM(conn));
     582             : 
     583       42250 :         status = set_conn_force_user_group(conn, snum);
     584       42250 :         if (!NT_STATUS_IS_OK(status)) {
     585           0 :                 goto err_root_exit;
     586             :         }
     587             : 
     588       42250 :         conn->vuid = session->global->session_wire_id;
     589             : 
     590             :         {
     591      196922 :                 char *s = talloc_sub_full(talloc_tos(),
     592       42250 :                                         lp_const_servicename(SNUM(conn)),
     593       41723 :                                         conn->session_info->unix_info->unix_name,
     594       42250 :                                         conn->connectpath,
     595       42250 :                                         conn->session_info->unix_token->gid,
     596       42250 :                                         conn->session_info->unix_info->sanitized_username,
     597       42250 :                                         conn->session_info->info->domain_name,
     598       42250 :                                         lp_path(talloc_tos(), lp_sub, snum));
     599       42250 :                 if (!s) {
     600           0 :                         status = NT_STATUS_NO_MEMORY;
     601           0 :                         goto err_root_exit;
     602             :                 }
     603             : 
     604       42250 :                 if (!set_conn_connectpath(conn,s)) {
     605           0 :                         TALLOC_FREE(s);
     606           0 :                         status = NT_STATUS_NO_MEMORY;
     607           0 :                         goto err_root_exit;
     608             :                 }
     609       42250 :                 DBG_NOTICE("Connect path is '%s' for service [%s]\n", s,
     610             :                            lp_const_servicename(snum));
     611       42250 :                 TALLOC_FREE(s);
     612             :         }
     613             : 
     614             :         /*
     615             :          * Set up the share security descriptor.
     616             :          * NOTE - we use the *INCOMING USER* session_info
     617             :          * here, as does (indirectly) change_to_user(),
     618             :          * which can be called on any incoming packet.
     619             :          * This way we set up the share access based
     620             :          * on the authenticated user, not the forced
     621             :          * user. See bug:
     622             :          *
     623             :          * https://bugzilla.samba.org/show_bug.cgi?id=9878
     624             :          */
     625             : 
     626       80918 :         status = check_user_share_access(conn,
     627       42250 :                                         session->global->auth_session_info,
     628             :                                         &conn->share_access,
     629             :                                         &conn->read_only);
     630       42250 :         if (!NT_STATUS_IS_OK(status)) {
     631           4 :                 goto err_root_exit;
     632             :         }
     633             : 
     634             :         /* Initialise VFS function pointers */
     635             : 
     636       42246 :         if (!smbd_vfs_init(conn)) {
     637           0 :                 DBG_ERR("vfs_init failed for service %s\n",
     638             :                         lp_const_servicename(snum));
     639           0 :                 status = NT_STATUS_BAD_NETWORK_NAME;
     640           0 :                 goto err_root_exit;
     641             :         }
     642             : 
     643             : /* ROOT Activities: */
     644             :         /* explicitly check widelinks here so that we can correctly warn
     645             :          * in the logs. */
     646       42246 :         widelinks_warning(snum);
     647             : 
     648             :         /*
     649             :          * Enforce the max connections parameter.
     650             :          */
     651             : 
     652       42246 :         if ((lp_max_connections(snum) > 0)
     653           0 :             && (count_current_connections(lp_const_servicename(SNUM(conn)), true) >=
     654           0 :                 lp_max_connections(snum))) {
     655             : 
     656           0 :                 DBG_WARNING("Max connections (%d) exceeded for %s\n",
     657             :                           lp_max_connections(snum),
     658             :                           lp_const_servicename(snum));
     659           0 :                 status = NT_STATUS_INSUFFICIENT_RESOURCES;
     660           0 :                 goto err_root_exit;
     661             :         }
     662             : 
     663             :         /* Invoke VFS make connection hook - this must be the first
     664             :            filesystem operation that we do. */
     665             : 
     666       42246 :         if (SMB_VFS_CONNECT(conn, lp_const_servicename(snum),
     667             :                             conn->session_info->unix_info->unix_name) < 0) {
     668           0 :                 DBG_WARNING("SMB_VFS_CONNECT for service '%s' at '%s' failed: %s\n",
     669             :                             lp_const_servicename(snum), conn->connectpath,
     670             :                             strerror(errno));
     671           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     672           0 :                 goto err_root_exit;
     673             :         }
     674             : 
     675             :         /* Any error exit after here needs to call the disconnect hook. */
     676       42246 :         on_err_call_dis_hook = true;
     677             : 
     678       61087 :         if ((!conn->printer) && (!conn->ipc) &&
     679       18841 :             lp_change_notify()) {
     680             : 
     681       18693 :                 status = notify_init_sconn(sconn);
     682       18693 :                 if (!NT_STATUS_IS_OK(status)) {
     683           0 :                         goto err_root_exit;
     684             :                 }
     685             :         }
     686             : 
     687       42246 :         if (lp_kernel_oplocks(snum)) {
     688          17 :                 init_kernel_oplocks(conn->sconn);
     689             :         }
     690             : 
     691             :         /*
     692             :          * Fix compatibility issue pointed out by Volker.
     693             :          * We pass the conn->connectpath to the preexec
     694             :          * scripts as a parameter, so attempt to canonicalize
     695             :          * it here before calling the preexec scripts.
     696             :          * We ignore errors here, as it is possible that
     697             :          * the conn->connectpath doesn't exist yet and
     698             :          * the preexec scripts will create them.
     699             :          */
     700             : 
     701       42246 :         (void)canonicalize_connect_path(conn);
     702             : 
     703             :         /* Preexecs are done here as they might make the dir we are to ChDir
     704             :          * to below */
     705             :         /* execute any "root preexec = " line */
     706       42246 :         if (*lp_root_preexec(talloc_tos(), lp_sub, snum)) {
     707          50 :                 char *cmd = talloc_sub_full(talloc_tos(),
     708          10 :                                         lp_const_servicename(SNUM(conn)),
     709          10 :                                         conn->session_info->unix_info->unix_name,
     710          10 :                                         conn->connectpath,
     711          10 :                                         conn->session_info->unix_token->gid,
     712          10 :                                         conn->session_info->unix_info->sanitized_username,
     713          10 :                                         conn->session_info->info->domain_name,
     714          10 :                                         lp_root_preexec(talloc_tos(), lp_sub, snum));
     715          10 :                 DEBUG(5,("cmd=%s\n",cmd));
     716          10 :                 ret = smbrun(cmd, NULL, NULL);
     717          10 :                 TALLOC_FREE(cmd);
     718          10 :                 if (ret != 0 && lp_root_preexec_close(snum)) {
     719           0 :                         DEBUG(1,("root preexec gave %d - failing "
     720             :                                  "connection\n", ret));
     721           0 :                         status = NT_STATUS_ACCESS_DENIED;
     722           0 :                         goto err_root_exit;
     723             :                 }
     724             :         }
     725             : 
     726             : /* USER Activites: */
     727       42246 :         if (!change_to_user_and_service(conn, conn->vuid)) {
     728             :                 /* No point continuing if they fail the basic checks */
     729           0 :                 DEBUG(0,("Can't become connected user!\n"));
     730           0 :                 status = NT_STATUS_LOGON_FAILURE;
     731           0 :                 goto err_root_exit;
     732             :         }
     733             : 
     734       42246 :         effuid = geteuid();
     735       42246 :         effgid = getegid();
     736             : 
     737             :         /* Remember that a different vuid can connect later without these
     738             :          * checks... */
     739             : 
     740             :         /* Preexecs are done here as they might make the dir we are to ChDir
     741             :          * to below */
     742             : 
     743             :         /* execute any "preexec = " line */
     744       42246 :         if (*lp_preexec(talloc_tos(), lp_sub, snum)) {
     745           0 :                 char *cmd = talloc_sub_full(talloc_tos(),
     746           0 :                                         lp_const_servicename(SNUM(conn)),
     747           0 :                                         conn->session_info->unix_info->unix_name,
     748           0 :                                         conn->connectpath,
     749           0 :                                         conn->session_info->unix_token->gid,
     750           0 :                                         conn->session_info->unix_info->sanitized_username,
     751           0 :                                         conn->session_info->info->domain_name,
     752           0 :                                         lp_preexec(talloc_tos(), lp_sub, snum));
     753           0 :                 ret = smbrun(cmd, NULL, NULL);
     754           0 :                 TALLOC_FREE(cmd);
     755           0 :                 if (ret != 0 && lp_preexec_close(snum)) {
     756           0 :                         DEBUG(1,("preexec gave %d - failing connection\n",
     757             :                                  ret));
     758           0 :                         status = NT_STATUS_ACCESS_DENIED;
     759           0 :                         goto err_root_exit;
     760             :                 }
     761             :         }
     762             : 
     763             : #ifdef WITH_FAKE_KASERVER
     764             :         if (lp_afs_share(snum)) {
     765             :                 afs_login(conn);
     766             :         }
     767             : #endif
     768             : 
     769             :         /*
     770             :          * we've finished with the user stuff - go back to root
     771             :          * so the SMB_VFS_STAT call will only fail on path errors,
     772             :          * not permission problems.
     773             :          */
     774       42246 :         change_to_root_user();
     775             : /* ROOT Activites: */
     776             : 
     777             :         /*
     778             :          * Canonicalise the connect
     779             :          * path here to ensure we don't have any symlinks in the
     780             :          * connectpath. We will be checking all paths on this connection are
     781             :          * below this directory. We must do this after the VFS init as we
     782             :          * depend on the realpath() pointer in the vfs table. JRA.
     783             :          */
     784       42246 :         ok = canonicalize_connect_path(conn);
     785       42246 :         if (!ok) {
     786          24 :                 DBG_ERR("canonicalize_connect_path failed "
     787             :                 "for service %s, path %s\n",
     788             :                         lp_const_servicename(snum),
     789             :                         conn->connectpath);
     790          24 :                 status = NT_STATUS_BAD_NETWORK_NAME;
     791          24 :                 goto err_root_exit;
     792             :         }
     793             : 
     794             :         /* Add veto/hide lists */
     795       42222 :         if (!IS_IPC(conn) && !IS_PRINT(conn)) {
     796       18817 :                 set_namearray( &conn->veto_list,
     797       18817 :                                lp_veto_files(talloc_tos(), lp_sub, snum));
     798       18817 :                 set_namearray( &conn->hide_list,
     799       18817 :                                lp_hide_files(talloc_tos(), lp_sub, snum));
     800       18817 :                 set_namearray( &conn->veto_oplock_list,
     801       18817 :                                lp_veto_oplock_files(talloc_tos(), lp_sub, snum));
     802       18817 :                 set_namearray( &conn->aio_write_behind_list,
     803       18817 :                                 lp_aio_write_behind(talloc_tos(), lp_sub, snum));
     804             :         }
     805       42222 :         smb_fname_cpath = synthetic_smb_fname(talloc_tos(),
     806       42222 :                                         conn->connectpath,
     807             :                                         NULL,
     808             :                                         NULL,
     809             :                                         0,
     810             :                                         0);
     811       42222 :         if (smb_fname_cpath == NULL) {
     812           0 :                 status = NT_STATUS_NO_MEMORY;
     813           0 :                 goto err_root_exit;
     814             :         }
     815             : 
     816             :         /* win2000 does not check the permissions on the directory
     817             :            during the tree connect, instead relying on permission
     818             :            check during individual operations. To match this behaviour
     819             :            I have disabled this chdir check (tridge) */
     820             :         /* the alternative is just to check the directory exists */
     821             : 
     822       80863 :         if ((ret = SMB_VFS_STAT(conn, smb_fname_cpath)) != 0 ||
     823       42222 :             !S_ISDIR(smb_fname_cpath->st.st_ex_mode)) {
     824           0 :                 if (ret == 0 && !S_ISDIR(smb_fname_cpath->st.st_ex_mode)) {
     825           0 :                         DBG_ERR("'%s' is not a directory, when connecting to "
     826             :                                  "[%s]\n", conn->connectpath,
     827             :                                  lp_const_servicename(snum));
     828             :                 } else {
     829           0 :                         DBG_ERR("'%s' does not exist or permission denied "
     830             :                                  "when connecting to [%s] Error was %s\n",
     831             :                                  conn->connectpath,
     832             :                                  lp_const_servicename(snum),
     833             :                                  strerror(errno));
     834             :                 }
     835           0 :                 status = NT_STATUS_BAD_NETWORK_NAME;
     836           0 :                 goto err_root_exit;
     837             :         }
     838       42222 :         conn->base_share_dev = smb_fname_cpath->st.st_ex_dev;
     839             : 
     840             :         /* Figure out the characteristics of the underlying filesystem. This
     841             :          * assumes that all the filesystem mounted within a share path have
     842             :          * the same characteristics, which is likely but not guaranteed.
     843             :          */
     844             : 
     845       42222 :         conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
     846             : 
     847             :         /*
     848             :          * Print out the 'connected as' stuff here as we need
     849             :          * to know the effective uid and gid we will be using
     850             :          * (at least initially).
     851             :          */
     852             : 
     853       42222 :         if( DEBUGLVL( IS_IPC(conn) ? 3 : 2 ) ) {
     854           0 :                 dbgtext( "%s (%s) ", get_remote_machine_name(),
     855           0 :                          tsocket_address_string(conn->sconn->remote_address,
     856             :                                                 talloc_tos()) );
     857           0 :                 dbgtext( "%s", srv_is_signing_active(xconn) ? "signed " : "");
     858           0 :                 dbgtext( "connect to service %s ",
     859             :                          lp_const_servicename(snum) );
     860           0 :                 dbgtext( "initially as user %s ",
     861           0 :                          conn->session_info->unix_info->unix_name );
     862           0 :                 dbgtext( "(uid=%d, gid=%d) ", (int)effuid, (int)effgid );
     863           0 :                 dbgtext( "(pid %d)\n", (int)getpid() );
     864             :         }
     865             : 
     866       42222 :         conn->tcon_done = true;
     867       42222 :         return NT_STATUS_OK;
     868             : 
     869          88 :   err_root_exit:
     870             : 
     871          88 :         TALLOC_FREE(smb_fname_cpath);
     872             :         /* We must exit this function as root. */
     873          94 :         if (geteuid() != 0) {
     874           0 :                 change_to_root_user();
     875             :         }
     876          94 :         if (on_err_call_dis_hook) {
     877             :                 /* Call VFS disconnect hook */
     878          24 :                 SMB_VFS_DISCONNECT(conn);
     879             :         }
     880          94 :         return status;
     881             : }
     882             : 
     883             : /****************************************************************************
     884             :  Make a connection to a service from SMB1. Internal interface.
     885             : ****************************************************************************/
     886             : 
     887        7586 : static connection_struct *make_connection_smb1(struct smb_request *req,
     888             :                                         NTTIME now,
     889             :                                         int snum,
     890             :                                         const char *pdev,
     891             :                                         NTSTATUS *pstatus)
     892             : {
     893        7239 :         const struct loadparm_substitution *lp_sub =
     894         347 :                 loadparm_s3_global_substitution();
     895             :         struct smbXsrv_tcon *tcon;
     896             :         NTSTATUS status;
     897             :         struct connection_struct *conn;
     898             : 
     899        7586 :         status = smb1srv_tcon_create(req->xconn, now, &tcon);
     900        7586 :         if (!NT_STATUS_IS_OK(status)) {
     901           0 :                 DEBUG(0,("make_connection_smb1: Couldn't find free tcon %s.\n",
     902             :                          nt_errstr(status)));
     903           0 :                 *pstatus = status;
     904           0 :                 return NULL;
     905             :         }
     906             : 
     907        7586 :         conn = conn_new(req->sconn);
     908        7586 :         if (!conn) {
     909           0 :                 TALLOC_FREE(tcon);
     910             : 
     911           0 :                 DEBUG(0,("make_connection_smb1: Couldn't find free connection.\n"));
     912           0 :                 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
     913           0 :                 return NULL;
     914             :         }
     915             : 
     916        7586 :         conn->cnum = tcon->global->tcon_wire_id;
     917        7586 :         conn->tcon = tcon;
     918             : 
     919        7586 :         *pstatus = make_connection_snum(req->xconn,
     920             :                                         conn,
     921             :                                         snum,
     922             :                                         req->session,
     923             :                                         pdev);
     924        7586 :         if (!NT_STATUS_IS_OK(*pstatus)) {
     925          58 :                 conn_free(conn);
     926          58 :                 TALLOC_FREE(tcon);
     927          52 :                 return NULL;
     928             :         }
     929             : 
     930        7528 :         tcon->global->share_name = lp_servicename(tcon->global, lp_sub, SNUM(conn));
     931        7528 :         if (tcon->global->share_name == NULL) {
     932           0 :                 conn_free(conn);
     933           0 :                 TALLOC_FREE(tcon);
     934           0 :                 *pstatus = NT_STATUS_NO_MEMORY;
     935           0 :                 return NULL;
     936             :         }
     937       14579 :         tcon->global->session_global_id =
     938       14579 :                 req->session->global->session_global_id;
     939             : 
     940        7528 :         tcon->compat = talloc_move(tcon, &conn);
     941        7528 :         tcon->status = NT_STATUS_OK;
     942             : 
     943        7528 :         *pstatus = smbXsrv_tcon_update(tcon);
     944        7528 :         if (!NT_STATUS_IS_OK(*pstatus)) {
     945           0 :                 TALLOC_FREE(tcon);
     946           0 :                 return NULL;
     947             :         }
     948             : 
     949        7528 :         return tcon->compat;
     950             : }
     951             : 
     952             : /****************************************************************************
     953             :  Make a connection to a service from SMB2. External SMB2 interface.
     954             :  We must set cnum before claiming connection.
     955             : ****************************************************************************/
     956             : 
     957       34730 : connection_struct *make_connection_smb2(struct smbd_smb2_request *req,
     958             :                                         struct smbXsrv_tcon *tcon,
     959             :                                         int snum,
     960             :                                         const char *pdev,
     961             :                                         NTSTATUS *pstatus)
     962             : {
     963       34730 :         struct smbd_server_connection *sconn = req->sconn;
     964       34730 :         connection_struct *conn = conn_new(sconn);
     965       34730 :         if (!conn) {
     966           0 :                 DEBUG(0,("make_connection_smb2: Couldn't find free connection.\n"));
     967           0 :                 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
     968           0 :                 return NULL;
     969             :         }
     970             : 
     971       34730 :         conn->cnum = tcon->global->tcon_wire_id;
     972       34730 :         conn->tcon = tcon;
     973             : 
     974       34730 :         *pstatus = make_connection_snum(req->xconn,
     975             :                                         conn,
     976             :                                         snum,
     977             :                                         req->session,
     978             :                                         pdev);
     979       34730 :         if (!NT_STATUS_IS_OK(*pstatus)) {
     980          36 :                 conn_free(conn);
     981          36 :                 return NULL;
     982             :         }
     983       34304 :         return conn;
     984             : }
     985             : 
     986             : /****************************************************************************
     987             :  Make a connection to a service. External SMB1 interface.
     988             :  *
     989             :  * @param service 
     990             : ****************************************************************************/
     991             : 
     992        7594 : connection_struct *make_connection(struct smb_request *req,
     993             :                                    NTTIME now,
     994             :                                    const char *service_in,
     995             :                                    const char *pdev, uint64_t vuid,
     996             :                                    NTSTATUS *status)
     997             : {
     998        7594 :         struct smbd_server_connection *sconn = req->sconn;
     999        7594 :         struct smbXsrv_session *session = req->session;
    1000        7246 :         const struct loadparm_substitution *lp_sub =
    1001         348 :                 loadparm_s3_global_substitution();
    1002             :         uid_t euid;
    1003        7594 :         char *service = NULL;
    1004             :         fstring dev;
    1005        7594 :         int snum = -1;
    1006             : 
    1007        7594 :         fstrcpy(dev, pdev);
    1008             : 
    1009             :         /* This must ONLY BE CALLED AS ROOT. As it exits this function as
    1010             :          * root. */
    1011        7594 :         if (!non_root_mode() && (euid = geteuid()) != 0) {
    1012           0 :                 DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot "
    1013             :                          "(%u)\n", (unsigned int)euid ));
    1014           0 :                 smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
    1015             :         }
    1016             : 
    1017        7594 :         if (conn_num_open(sconn) > 2047) {
    1018           0 :                 *status = NT_STATUS_INSUFF_SERVER_RESOURCES;
    1019           0 :                 return NULL;
    1020             :         }
    1021             : 
    1022        7594 :         if (session == NULL) {
    1023           0 :                 DEBUG(1,("make_connection: refusing to connect with "
    1024             :                          "no session setup\n"));
    1025           0 :                 *status = NT_STATUS_ACCESS_DENIED;
    1026           0 :                 return NULL;
    1027             :         }
    1028             : 
    1029             :         /* Logic to try and connect to the correct [homes] share, preferably
    1030             :            without too many getpwnam() lookups.  This is particulary nasty for
    1031             :            winbind usernames, where the share name isn't the same as unix
    1032             :            username.
    1033             :         */
    1034             : 
    1035        7594 :         if (strequal(service_in,HOMES_NAME)) {
    1036           0 :                 if (session->homes_snum == -1) {
    1037           0 :                         DEBUG(2, ("[homes] share not available for "
    1038             :                                   "this user because it was not found "
    1039             :                                   "or created at session setup "
    1040             :                                   "time\n"));
    1041           0 :                         *status = NT_STATUS_BAD_NETWORK_NAME;
    1042           0 :                         return NULL;
    1043             :                 }
    1044           0 :                 DEBUG(5, ("making a connection to [homes] service "
    1045             :                           "created at session setup time\n"));
    1046           0 :                 return make_connection_smb1(req, now,
    1047           0 :                                             session->homes_snum,
    1048             :                                             dev, status);
    1049        7594 :         } else if ((session->homes_snum != -1)
    1050        4400 :                    && strequal(service_in,
    1051        4400 :                                lp_const_servicename(session->homes_snum))) {
    1052           0 :                 DEBUG(5, ("making a connection to 'homes' service [%s] "
    1053             :                           "created at session setup time\n", service_in));
    1054           0 :                 return make_connection_smb1(req, now,
    1055           0 :                                             session->homes_snum,
    1056             :                                             dev, status);
    1057             :         }
    1058             : 
    1059        7594 :         service = talloc_strdup(talloc_tos(), service_in);
    1060        7594 :         if (!service) {
    1061           0 :                 *status = NT_STATUS_NO_MEMORY;
    1062           0 :                 return NULL;
    1063             :         }
    1064             : 
    1065        7594 :         if (!strlower_m(service)) {
    1066           0 :                 DEBUG(2, ("strlower_m %s failed\n", service));
    1067           0 :                 *status = NT_STATUS_INVALID_PARAMETER;
    1068           0 :                 return NULL;
    1069             :         }
    1070             : 
    1071        7594 :         snum = find_service(talloc_tos(), service, &service);
    1072        7594 :         if (!service) {
    1073           0 :                 *status = NT_STATUS_NO_MEMORY;
    1074           0 :                 return NULL;
    1075             :         }
    1076             : 
    1077        7594 :         if (snum < 0) {
    1078          16 :                 if (strequal(service,"IPC$") ||
    1079           8 :                     (lp_enable_asu_support() && strequal(service,"ADMIN$"))) {
    1080           0 :                         DEBUG(3,("refusing IPC connection to %s\n", service));
    1081           0 :                         *status = NT_STATUS_ACCESS_DENIED;
    1082           0 :                         return NULL;
    1083             :                 }
    1084             : 
    1085           8 :                 DEBUG(3,("%s (%s) couldn't find service %s\n",
    1086             :                         get_remote_machine_name(),
    1087             :                         tsocket_address_string(
    1088             :                                 sconn->remote_address, talloc_tos()),
    1089             :                         service));
    1090           8 :                 *status = NT_STATUS_BAD_NETWORK_NAME;
    1091           8 :                 return NULL;
    1092             :         }
    1093             : 
    1094             :         /* Handle non-Dfs clients attempting connections to msdfs proxy */
    1095        7586 :         if (lp_host_msdfs() && (*lp_msdfs_proxy(talloc_tos(), lp_sub, snum) != '\0'))  {
    1096           0 :                 DEBUG(3, ("refusing connection to dfs proxy share '%s' "
    1097             :                           "(pointing to %s)\n", 
    1098             :                         service, lp_msdfs_proxy(talloc_tos(), lp_sub, snum)));
    1099           0 :                 *status = NT_STATUS_BAD_NETWORK_NAME;
    1100           0 :                 return NULL;
    1101             :         }
    1102             : 
    1103        7586 :         DEBUG(5, ("making a connection to 'normal' service %s\n", service));
    1104             : 
    1105        7586 :         return make_connection_smb1(req, now, snum,
    1106             :                                     dev, status);
    1107             : }
    1108             : 
    1109             : /****************************************************************************
    1110             :  Close a cnum.
    1111             : ****************************************************************************/
    1112             : 
    1113       42172 : void close_cnum(connection_struct *conn, uint64_t vuid)
    1114             : {
    1115       42172 :         char rootpath[2] = { '/', '\0'};
    1116       42172 :         struct smb_filename root_fname = { .base_name = rootpath };
    1117       38595 :         const struct loadparm_substitution *lp_sub =
    1118        3577 :                 loadparm_s3_global_substitution();
    1119             : 
    1120       42172 :         file_close_conn(conn);
    1121             : 
    1122       42172 :         change_to_root_user();
    1123             : 
    1124       42172 :         DEBUG(IS_IPC(conn)?3:2, ("%s (%s) closed connection to service %s\n",
    1125             :                                  get_remote_machine_name(),
    1126             :                                  tsocket_address_string(conn->sconn->remote_address,
    1127             :                                                         talloc_tos()),
    1128             :                                  lp_const_servicename(SNUM(conn))));
    1129             : 
    1130             :         /* make sure we leave the directory available for unmount */
    1131       42172 :         vfs_ChDir(conn, &root_fname);
    1132             : 
    1133             :         /* Call VFS disconnect hook */
    1134       42172 :         SMB_VFS_DISCONNECT(conn);
    1135             : 
    1136             :         /* execute any "postexec = " line */
    1137       42172 :         if (*lp_postexec(talloc_tos(), lp_sub, SNUM(conn)) &&
    1138           0 :             change_to_user_and_service(conn, vuid))  {
    1139           0 :                 char *cmd = talloc_sub_full(talloc_tos(),
    1140           0 :                                         lp_const_servicename(SNUM(conn)),
    1141           0 :                                         conn->session_info->unix_info->unix_name,
    1142           0 :                                         conn->connectpath,
    1143           0 :                                         conn->session_info->unix_token->gid,
    1144           0 :                                         conn->session_info->unix_info->sanitized_username,
    1145           0 :                                         conn->session_info->info->domain_name,
    1146           0 :                                         lp_postexec(talloc_tos(), lp_sub, SNUM(conn)));
    1147           0 :                 smbrun(cmd, NULL, NULL);
    1148           0 :                 TALLOC_FREE(cmd);
    1149           0 :                 change_to_root_user();
    1150             :         }
    1151             : 
    1152       42172 :         change_to_root_user();
    1153             :         /* execute any "root postexec = " line */
    1154       42172 :         if (*lp_root_postexec(talloc_tos(), lp_sub, SNUM(conn)))  {
    1155           0 :                 char *cmd = talloc_sub_full(talloc_tos(),
    1156           0 :                                         lp_const_servicename(SNUM(conn)),
    1157           0 :                                         conn->session_info->unix_info->unix_name,
    1158           0 :                                         conn->connectpath,
    1159           0 :                                         conn->session_info->unix_token->gid,
    1160           0 :                                         conn->session_info->unix_info->sanitized_username,
    1161           0 :                                         conn->session_info->info->domain_name,
    1162           0 :                                         lp_root_postexec(talloc_tos(), lp_sub, SNUM(conn)));
    1163           0 :                 smbrun(cmd, NULL, NULL);
    1164           0 :                 TALLOC_FREE(cmd);
    1165             :         }
    1166             : 
    1167       42172 :         conn_free(conn);
    1168       42172 : }

Generated by: LCOV version 1.13