5b54aecd12f1ca774e019a74c294a74f525d5bca
[vlendec/samba-autobuild/.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
627         conn->veto_list = NULL;
628         conn->hide_list = NULL;
629         conn->veto_oplock_list = NULL;
630         conn->aio_write_behind_list = NULL;
631
632         conn->read_only = lp_read_only(SNUM(conn));
633
634         status = set_conn_force_user_group(conn, snum);
635         if (!NT_STATUS_IS_OK(status)) {
636                 goto err_root_exit;
637         }
638
639         conn->vuid = vuser->vuid;
640
641         {
642                 char *s = talloc_sub_advanced(talloc_tos(),
643                                         lp_servicename(talloc_tos(), SNUM(conn)),
644                                         conn->session_info->unix_info->unix_name,
645                                         conn->connectpath,
646                                         conn->session_info->unix_token->gid,
647                                         conn->session_info->unix_info->sanitized_username,
648                                         conn->session_info->info->domain_name,
649                                         lp_path(talloc_tos(), snum));
650                 if (!s) {
651                         status = NT_STATUS_NO_MEMORY;
652                         goto err_root_exit;
653                 }
654
655                 if (!set_conn_connectpath(conn,s)) {
656                         TALLOC_FREE(s);
657                         status = NT_STATUS_NO_MEMORY;
658                         goto err_root_exit;
659                 }
660                 DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
661                          lp_servicename(talloc_tos(), snum)));
662                 TALLOC_FREE(s);
663         }
664
665         /*
666          * Set up the share security descriptor.
667          * NOTE - we use the *INCOMING USER* session_info
668          * here, as does (indirectly) change_to_user(),
669          * which can be called on any incoming packet.
670          * This way we set up the share access based
671          * on the authenticated user, not the forced
672          * user. See bug:
673          *
674          * https://bugzilla.samba.org/show_bug.cgi?id=9878
675          */
676
677         status = check_user_share_access(conn,
678                                         vuser->session_info,
679                                         &conn->share_access,
680                                         &conn->read_only);
681         if (!NT_STATUS_IS_OK(status)) {
682                 goto err_root_exit;
683         }
684
685         /* Initialise VFS function pointers */
686
687         if (!smbd_vfs_init(conn)) {
688                 DEBUG(0, ("vfs_init failed for service %s\n",
689                           lp_servicename(talloc_tos(), snum)));
690                 status = NT_STATUS_BAD_NETWORK_NAME;
691                 goto err_root_exit;
692         }
693
694 /* ROOT Activities: */
695         /* explicitly check widelinks here so that we can correctly warn
696          * in the logs. */
697         widelinks_warning(snum);
698
699         /*
700          * Enforce the max connections parameter.
701          */
702
703         if ((lp_max_connections(snum) > 0)
704             && (count_current_connections(lp_servicename(talloc_tos(), SNUM(conn)), True) >=
705                 lp_max_connections(snum))) {
706
707                 DEBUG(1, ("Max connections (%d) exceeded for %s\n",
708                           lp_max_connections(snum),
709                           lp_servicename(talloc_tos(), snum)));
710                 status = NT_STATUS_INSUFFICIENT_RESOURCES;
711                 goto err_root_exit;
712         }
713
714         /* Invoke VFS make connection hook - this must be the first
715            filesystem operation that we do. */
716
717         if (SMB_VFS_CONNECT(conn, lp_servicename(talloc_tos(), snum),
718                             conn->session_info->unix_info->unix_name) < 0) {
719                 DBG_WARNING("SMB_VFS_CONNECT for service '%s' at '%s' failed: %s\n",
720                             lp_servicename(talloc_tos(), snum), conn->connectpath,
721                             strerror(errno));
722                 status = NT_STATUS_UNSUCCESSFUL;
723                 goto err_root_exit;
724         }
725
726         /* Any error exit after here needs to call the disconnect hook. */
727         on_err_call_dis_hook = true;
728
729         if ((!conn->printer) && (!conn->ipc) &&
730             lp_change_notify()) {
731
732                 status = notify_init_sconn(sconn);
733                 if (!NT_STATUS_IS_OK(status)) {
734                         goto err_root_exit;
735                 }
736         }
737
738         if (lp_kernel_oplocks(snum)) {
739                 init_kernel_oplocks(conn->sconn);
740         }
741
742         /*
743          * Fix compatibility issue pointed out by Volker.
744          * We pass the conn->connectpath to the preexec
745          * scripts as a parameter, so attempt to canonicalize
746          * it here before calling the preexec scripts.
747          * We ignore errors here, as it is possible that
748          * the conn->connectpath doesn't exist yet and
749          * the preexec scripts will create them.
750          */
751
752         (void)canonicalize_connect_path(conn);
753
754         /* Preexecs are done here as they might make the dir we are to ChDir
755          * to below */
756         /* execute any "root preexec = " line */
757         if (*lp_root_preexec(talloc_tos(), snum)) {
758                 char *cmd = talloc_sub_advanced(talloc_tos(),
759                                         lp_servicename(talloc_tos(), SNUM(conn)),
760                                         conn->session_info->unix_info->unix_name,
761                                         conn->connectpath,
762                                         conn->session_info->unix_token->gid,
763                                         conn->session_info->unix_info->sanitized_username,
764                                         conn->session_info->info->domain_name,
765                                         lp_root_preexec(talloc_tos(), snum));
766                 DEBUG(5,("cmd=%s\n",cmd));
767                 ret = smbrun(cmd,NULL);
768                 TALLOC_FREE(cmd);
769                 if (ret != 0 && lp_root_preexec_close(snum)) {
770                         DEBUG(1,("root preexec gave %d - failing "
771                                  "connection\n", ret));
772                         status = NT_STATUS_ACCESS_DENIED;
773                         goto err_root_exit;
774                 }
775         }
776
777 /* USER Activites: */
778         if (!change_to_user(conn, conn->vuid)) {
779                 /* No point continuing if they fail the basic checks */
780                 DEBUG(0,("Can't become connected user!\n"));
781                 status = NT_STATUS_LOGON_FAILURE;
782                 goto err_root_exit;
783         }
784
785         effuid = geteuid();
786         effgid = getegid();
787
788         /* Remember that a different vuid can connect later without these
789          * checks... */
790
791         /* Preexecs are done here as they might make the dir we are to ChDir
792          * to below */
793
794         /* execute any "preexec = " line */
795         if (*lp_preexec(talloc_tos(), snum)) {
796                 char *cmd = talloc_sub_advanced(talloc_tos(),
797                                         lp_servicename(talloc_tos(), SNUM(conn)),
798                                         conn->session_info->unix_info->unix_name,
799                                         conn->connectpath,
800                                         conn->session_info->unix_token->gid,
801                                         conn->session_info->unix_info->sanitized_username,
802                                         conn->session_info->info->domain_name,
803                                         lp_preexec(talloc_tos(), snum));
804                 ret = smbrun(cmd,NULL);
805                 TALLOC_FREE(cmd);
806                 if (ret != 0 && lp_preexec_close(snum)) {
807                         DEBUG(1,("preexec gave %d - failing connection\n",
808                                  ret));
809                         status = NT_STATUS_ACCESS_DENIED;
810                         goto err_root_exit;
811                 }
812         }
813
814 #ifdef WITH_FAKE_KASERVER
815         if (lp_afs_share(snum)) {
816                 afs_login(conn);
817         }
818 #endif
819
820         /*
821          * we've finished with the user stuff - go back to root
822          * so the SMB_VFS_STAT call will only fail on path errors,
823          * not permission problems.
824          */
825         change_to_root_user();
826 /* ROOT Activites: */
827
828         /*
829          * If widelinks are disallowed we need to canonicalise the connect
830          * path here to ensure we don't have any symlinks in the
831          * connectpath. We will be checking all paths on this connection are
832          * below this directory. We must do this after the VFS init as we
833          * depend on the realpath() pointer in the vfs table. JRA.
834          */
835         if (!lp_widelinks(snum)) {
836                 if (!canonicalize_connect_path(conn)) {
837                         DEBUG(0, ("canonicalize_connect_path failed "
838                         "for service %s, path %s\n",
839                                 lp_servicename(talloc_tos(), snum),
840                                 conn->connectpath));
841                         status = NT_STATUS_BAD_NETWORK_NAME;
842                         goto err_root_exit;
843                 }
844         }
845
846         /* Add veto/hide lists */
847         if (!IS_IPC(conn) && !IS_PRINT(conn)) {
848                 set_namearray( &conn->veto_list,
849                                lp_veto_files(talloc_tos(), snum));
850                 set_namearray( &conn->hide_list,
851                                lp_hide_files(talloc_tos(), snum));
852                 set_namearray( &conn->veto_oplock_list,
853                                lp_veto_oplock_files(talloc_tos(), snum));
854                 set_namearray( &conn->aio_write_behind_list,
855                                 lp_aio_write_behind(talloc_tos(), snum));
856         }
857         smb_fname_cpath = synthetic_smb_fname(talloc_tos(),
858                                         conn->connectpath,
859                                         NULL,
860                                         NULL,
861                                         0);
862         if (smb_fname_cpath == NULL) {
863                 status = NT_STATUS_NO_MEMORY;
864                 goto err_root_exit;
865         }
866
867         /* win2000 does not check the permissions on the directory
868            during the tree connect, instead relying on permission
869            check during individual operations. To match this behaviour
870            I have disabled this chdir check (tridge) */
871         /* the alternative is just to check the directory exists */
872
873         if ((ret = SMB_VFS_STAT(conn, smb_fname_cpath)) != 0 ||
874             !S_ISDIR(smb_fname_cpath->st.st_ex_mode)) {
875                 if (ret == 0 && !S_ISDIR(smb_fname_cpath->st.st_ex_mode)) {
876                         DEBUG(0,("'%s' is not a directory, when connecting to "
877                                  "[%s]\n", conn->connectpath,
878                                  lp_servicename(talloc_tos(), snum)));
879                 } else {
880                         DEBUG(0,("'%s' does not exist or permission denied "
881                                  "when connecting to [%s] Error was %s\n",
882                                  conn->connectpath,
883                                  lp_servicename(talloc_tos(), snum),
884                                  strerror(errno) ));
885                 }
886                 status = NT_STATUS_BAD_NETWORK_NAME;
887                 goto err_root_exit;
888         }
889         conn->base_share_dev = smb_fname_cpath->st.st_ex_dev;
890
891         talloc_free(conn->origpath);
892         conn->origpath = talloc_strdup(conn, conn->connectpath);
893
894         /* Figure out the characteristics of the underlying filesystem. This
895          * assumes that all the filesystem mounted withing a share path have
896          * the same characteristics, which is likely but not guaranteed.
897          */
898
899         conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
900
901         /*
902          * Print out the 'connected as' stuff here as we need
903          * to know the effective uid and gid we will be using
904          * (at least initially).
905          */
906
907         if( DEBUGLVL( IS_IPC(conn) ? 3 : 2 ) ) {
908                 dbgtext( "%s (%s) ", get_remote_machine_name(),
909                          tsocket_address_string(conn->sconn->remote_address,
910                                                 talloc_tos()) );
911                 dbgtext( "%s", srv_is_signing_active(xconn) ? "signed " : "");
912                 dbgtext( "connect to service %s ",
913                          lp_servicename(talloc_tos(), snum) );
914                 dbgtext( "initially as user %s ",
915                          conn->session_info->unix_info->unix_name );
916                 dbgtext( "(uid=%d, gid=%d) ", (int)effuid, (int)effgid );
917                 dbgtext( "(pid %d)\n", (int)getpid() );
918         }
919
920         return status;
921
922   err_root_exit:
923
924         TALLOC_FREE(smb_fname_cpath);
925         /* We must exit this function as root. */
926         if (geteuid() != 0) {
927                 change_to_root_user();
928         }
929         if (on_err_call_dis_hook) {
930                 /* Call VFS disconnect hook */
931                 SMB_VFS_DISCONNECT(conn);
932         }
933         return status;
934 }
935
936 /****************************************************************************
937  Make a connection to a service from SMB1. Internal interface.
938 ****************************************************************************/
939
940 static connection_struct *make_connection_smb1(struct smb_request *req,
941                                         NTTIME now,
942                                         int snum, struct user_struct *vuser,
943                                         const char *pdev,
944                                         NTSTATUS *pstatus)
945 {
946         struct smbXsrv_tcon *tcon;
947         NTSTATUS status;
948         struct connection_struct *conn;
949
950         status = smb1srv_tcon_create(req->xconn, now, &tcon);
951         if (!NT_STATUS_IS_OK(status)) {
952                 DEBUG(0,("make_connection_smb1: Couldn't find free tcon %s.\n",
953                          nt_errstr(status)));
954                 *pstatus = status;
955                 return NULL;
956         }
957
958         conn = conn_new(req->sconn);
959         if (!conn) {
960                 TALLOC_FREE(tcon);
961
962                 DEBUG(0,("make_connection_smb1: Couldn't find free connection.\n"));
963                 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
964                 return NULL;
965         }
966
967         conn->cnum = tcon->global->tcon_wire_id;
968         conn->tcon = tcon;
969
970         *pstatus = make_connection_snum(req->xconn,
971                                         conn,
972                                         snum,
973                                         vuser,
974                                         pdev);
975         if (!NT_STATUS_IS_OK(*pstatus)) {
976                 conn_free(conn);
977                 TALLOC_FREE(tcon);
978                 return NULL;
979         }
980
981         tcon->global->share_name = lp_servicename(tcon->global, SNUM(conn));
982         if (tcon->global->share_name == NULL) {
983                 conn_free(conn);
984                 TALLOC_FREE(tcon);
985                 *pstatus = NT_STATUS_NO_MEMORY;
986                 return NULL;
987         }
988         tcon->global->session_global_id =
989                 vuser->session->global->session_global_id;
990
991         tcon->compat = talloc_move(tcon, &conn);
992         tcon->status = NT_STATUS_OK;
993
994         *pstatus = smbXsrv_tcon_update(tcon);
995         if (!NT_STATUS_IS_OK(*pstatus)) {
996                 TALLOC_FREE(tcon);
997                 return NULL;
998         }
999
1000         return tcon->compat;
1001 }
1002
1003 /****************************************************************************
1004  Make a connection to a service from SMB2. External SMB2 interface.
1005  We must set cnum before claiming connection.
1006 ****************************************************************************/
1007
1008 connection_struct *make_connection_smb2(struct smbd_smb2_request *req,
1009                                         struct smbXsrv_tcon *tcon,
1010                                         int snum,
1011                                         struct user_struct *vuser,
1012                                         const char *pdev,
1013                                         NTSTATUS *pstatus)
1014 {
1015         struct smbd_server_connection *sconn = req->sconn;
1016         connection_struct *conn = conn_new(sconn);
1017         if (!conn) {
1018                 DEBUG(0,("make_connection_smb2: Couldn't find free connection.\n"));
1019                 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
1020                 return NULL;
1021         }
1022
1023         conn->cnum = tcon->global->tcon_wire_id;
1024         conn->tcon = tcon;
1025
1026         *pstatus = make_connection_snum(req->xconn,
1027                                         conn,
1028                                         snum,
1029                                         vuser,
1030                                         pdev);
1031         if (!NT_STATUS_IS_OK(*pstatus)) {
1032                 conn_free(conn);
1033                 return NULL;
1034         }
1035         return conn;
1036 }
1037
1038 /****************************************************************************
1039  Make a connection to a service. External SMB1 interface.
1040  *
1041  * @param service 
1042 ****************************************************************************/
1043
1044 connection_struct *make_connection(struct smb_request *req,
1045                                    NTTIME now,
1046                                    const char *service_in,
1047                                    const char *pdev, uint64_t vuid,
1048                                    NTSTATUS *status)
1049 {
1050         struct smbd_server_connection *sconn = req->sconn;
1051         uid_t euid;
1052         struct user_struct *vuser = NULL;
1053         char *service = NULL;
1054         fstring dev;
1055         int snum = -1;
1056
1057         fstrcpy(dev, pdev);
1058
1059         /* This must ONLY BE CALLED AS ROOT. As it exits this function as
1060          * root. */
1061         if (!non_root_mode() && (euid = geteuid()) != 0) {
1062                 DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot "
1063                          "(%u)\n", (unsigned int)euid ));
1064                 smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
1065         }
1066
1067         if (conn_num_open(sconn) > 2047) {
1068                 *status = NT_STATUS_INSUFF_SERVER_RESOURCES;
1069                 return NULL;
1070         }
1071
1072         vuser = get_valid_user_struct(sconn, vuid);
1073         if (!vuser) {
1074                 DEBUG(1,("make_connection: refusing to connect with "
1075                          "no session setup\n"));
1076                 *status = NT_STATUS_ACCESS_DENIED;
1077                 return NULL;
1078         }
1079
1080         /* Logic to try and connect to the correct [homes] share, preferably
1081            without too many getpwnam() lookups.  This is particulary nasty for
1082            winbind usernames, where the share name isn't the same as unix
1083            username.
1084
1085            The snum of the homes share is stored on the vuser at session setup
1086            time.
1087         */
1088
1089         if (strequal(service_in,HOMES_NAME)) {
1090                 if (vuser->homes_snum == -1) {
1091                         DEBUG(2, ("[homes] share not available for "
1092                                   "this user because it was not found "
1093                                   "or created at session setup "
1094                                   "time\n"));
1095                         *status = NT_STATUS_BAD_NETWORK_NAME;
1096                         return NULL;
1097                 }
1098                 DEBUG(5, ("making a connection to [homes] service "
1099                           "created at session setup time\n"));
1100                 return make_connection_smb1(req, now,
1101                                             vuser->homes_snum,
1102                                             vuser,
1103                                             dev, status);
1104         } else if ((vuser->homes_snum != -1)
1105                    && strequal(service_in,
1106                                lp_servicename(talloc_tos(), vuser->homes_snum))) {
1107                 DEBUG(5, ("making a connection to 'homes' service [%s] "
1108                           "created at session setup time\n", service_in));
1109                 return make_connection_smb1(req, now,
1110                                             vuser->homes_snum,
1111                                             vuser,
1112                                             dev, status);
1113         }
1114
1115         service = talloc_strdup(talloc_tos(), service_in);
1116         if (!service) {
1117                 *status = NT_STATUS_NO_MEMORY;
1118                 return NULL;
1119         }
1120
1121         if (!strlower_m(service)) {
1122                 DEBUG(2, ("strlower_m %s failed\n", service));
1123                 *status = NT_STATUS_INVALID_PARAMETER;
1124                 return NULL;
1125         }
1126
1127         snum = find_service(talloc_tos(), service, &service);
1128         if (!service) {
1129                 *status = NT_STATUS_NO_MEMORY;
1130                 return NULL;
1131         }
1132
1133         if (snum < 0) {
1134                 if (strequal(service,"IPC$") ||
1135                     (lp_enable_asu_support() && strequal(service,"ADMIN$"))) {
1136                         DEBUG(3,("refusing IPC connection to %s\n", service));
1137                         *status = NT_STATUS_ACCESS_DENIED;
1138                         return NULL;
1139                 }
1140
1141                 DEBUG(3,("%s (%s) couldn't find service %s\n",
1142                         get_remote_machine_name(),
1143                         tsocket_address_string(
1144                                 sconn->remote_address, talloc_tos()),
1145                         service));
1146                 *status = NT_STATUS_BAD_NETWORK_NAME;
1147                 return NULL;
1148         }
1149
1150         /* Handle non-Dfs clients attempting connections to msdfs proxy */
1151         if (lp_host_msdfs() && (*lp_msdfs_proxy(talloc_tos(), snum) != '\0'))  {
1152                 DEBUG(3, ("refusing connection to dfs proxy share '%s' "
1153                           "(pointing to %s)\n", 
1154                         service, lp_msdfs_proxy(talloc_tos(), snum)));
1155                 *status = NT_STATUS_BAD_NETWORK_NAME;
1156                 return NULL;
1157         }
1158
1159         DEBUG(5, ("making a connection to 'normal' service %s\n", service));
1160
1161         return make_connection_smb1(req, now, snum, vuser,
1162                                     dev, status);
1163 }
1164
1165 /****************************************************************************
1166  Close a cnum.
1167 ****************************************************************************/
1168
1169 void close_cnum(connection_struct *conn, uint64_t vuid)
1170 {
1171         file_close_conn(conn);
1172
1173         if (!IS_IPC(conn)) {
1174                 dptr_closecnum(conn);
1175         }
1176
1177         change_to_root_user();
1178
1179         DEBUG(IS_IPC(conn)?3:2, ("%s (%s) closed connection to service %s\n",
1180                                  get_remote_machine_name(),
1181                                  tsocket_address_string(conn->sconn->remote_address,
1182                                                         talloc_tos()),
1183                                  lp_servicename(talloc_tos(), SNUM(conn))));
1184
1185         /* make sure we leave the directory available for unmount */
1186         vfs_ChDir(conn, "/");
1187
1188         /* Call VFS disconnect hook */
1189         SMB_VFS_DISCONNECT(conn);
1190
1191         /* execute any "postexec = " line */
1192         if (*lp_postexec(talloc_tos(), SNUM(conn)) &&
1193             change_to_user(conn, vuid))  {
1194                 char *cmd = talloc_sub_advanced(talloc_tos(),
1195                                         lp_servicename(talloc_tos(), SNUM(conn)),
1196                                         conn->session_info->unix_info->unix_name,
1197                                         conn->connectpath,
1198                                         conn->session_info->unix_token->gid,
1199                                         conn->session_info->unix_info->sanitized_username,
1200                                         conn->session_info->info->domain_name,
1201                                         lp_postexec(talloc_tos(), SNUM(conn)));
1202                 smbrun(cmd,NULL);
1203                 TALLOC_FREE(cmd);
1204                 change_to_root_user();
1205         }
1206
1207         change_to_root_user();
1208         /* execute any "root postexec = " line */
1209         if (*lp_root_postexec(talloc_tos(), SNUM(conn)))  {
1210                 char *cmd = talloc_sub_advanced(talloc_tos(),
1211                                         lp_servicename(talloc_tos(), SNUM(conn)),
1212                                         conn->session_info->unix_info->unix_name,
1213                                         conn->connectpath,
1214                                         conn->session_info->unix_token->gid,
1215                                         conn->session_info->unix_info->sanitized_username,
1216                                         conn->session_info->info->domain_name,
1217                                         lp_root_postexec(talloc_tos(), SNUM(conn)));
1218                 smbrun(cmd,NULL);
1219                 TALLOC_FREE(cmd);
1220         }
1221
1222         conn_free(conn);
1223 }