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