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