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