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