s3:smbd: move tcon specific globals to struct smbd_server_connection
[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         destname = SMB_STRDUP(connectpath);
60         if (!destname) {
61                 return false;
62         }
63         d = destname;
64
65         *d++ = '/'; /* Always start with root. */
66
67         while (*s) {
68                 if (*s == '/') {
69                         /* Eat multiple '/' */
70                         while (*s == '/') {
71                                 s++;
72                         }
73                         if ((d > destname + 1) && (*s != '\0')) {
74                                 *d++ = '/';
75                         }
76                         start_of_name_component = True;
77                         continue;
78                 }
79
80                 if (start_of_name_component) {
81                         if ((s[0] == '.') && (s[1] == '.') && (s[2] == '/' || s[2] == '\0')) {
82                                 /* Uh oh - "/../" or "/..\0" ! */
83
84                                 /* Go past the ../ or .. */
85                                 if (s[2] == '/') {
86                                         s += 3;
87                                 } else {
88                                         s += 2; /* Go past the .. */
89                                 }
90
91                                 /* If  we just added a '/' - delete it */
92                                 if ((d > destname) && (*(d-1) == '/')) {
93                                         *(d-1) = '\0';
94                                         d--;
95                                 }
96
97                                 /* Are we at the start ? Can't go back further if so. */
98                                 if (d <= destname) {
99                                         *d++ = '/'; /* Can't delete root */
100                                         continue;
101                                 }
102                                 /* Go back one level... */
103                                 /* Decrement d first as d points to the *next* char to write into. */
104                                 for (d--; d > destname; d--) {
105                                         if (*d == '/') {
106                                                 break;
107                                         }
108                                 }
109                                 /* We're still at the start of a name component, just the previous one. */
110                                 continue;
111                         } else if ((s[0] == '.') && ((s[1] == '\0') || s[1] == '/')) {
112                                 /* Component of pathname can't be "." only - skip the '.' . */
113                                 if (s[1] == '/') {
114                                         s += 2;
115                                 } else {
116                                         s++;
117                                 }
118                                 continue;
119                         }
120                 }
121
122                 if (!(*s & 0x80)) {
123                         *d++ = *s++;
124                 } else {
125                         size_t siz;
126                         /* Get the size of the next MB character. */
127                         next_codepoint(s,&siz);
128                         switch(siz) {
129                                 case 5:
130                                         *d++ = *s++;
131                                         /*fall through*/
132                                 case 4:
133                                         *d++ = *s++;
134                                         /*fall through*/
135                                 case 3:
136                                         *d++ = *s++;
137                                         /*fall through*/
138                                 case 2:
139                                         *d++ = *s++;
140                                         /*fall through*/
141                                 case 1:
142                                         *d++ = *s++;
143                                         break;
144                                 default:
145                                         break;
146                         }
147                 }
148                 start_of_name_component = false;
149         }
150         *d = '\0';
151
152         /* And must not end in '/' */
153         if (d > destname + 1 && (*(d-1) == '/')) {
154                 *(d-1) = '\0';
155         }
156
157         DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
158                 lp_servicename(SNUM(conn)), destname ));
159
160         string_set(&conn->connectpath, destname);
161         SAFE_FREE(destname);
162         return true;
163 }
164
165 /****************************************************************************
166  Load parameters specific to a connection/service.
167 ****************************************************************************/
168
169 bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir)
170 {
171         int snum;
172
173         if (!conn)  {
174                 last_conn = NULL;
175                 return(False);
176         }
177
178         conn->lastused_count++;
179
180         snum = SNUM(conn);
181   
182         if (do_chdir &&
183             vfs_ChDir(conn,conn->connectpath) != 0 &&
184             vfs_ChDir(conn,conn->origpath) != 0) {
185                 DEBUG(0,("chdir (%s) failed\n",
186                          conn->connectpath));
187                 return(False);
188         }
189
190         if ((conn == last_conn) && (last_flags == flags)) {
191                 return(True);
192         }
193
194         last_conn = conn;
195         last_flags = flags;
196         
197         /* Obey the client case sensitivity requests - only for clients that support it. */
198         switch (lp_casesensitive(snum)) {
199                 case Auto:
200                         {
201                                 /* We need this uglyness due to DOS/Win9x clients that lie about case insensitivity. */
202                                 enum remote_arch_types ra_type = get_remote_arch();
203                                 if ((ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
204                                         /* Client can't support per-packet case sensitive pathnames. */
205                                         conn->case_sensitive = False;
206                                 } else {
207                                         conn->case_sensitive = !(flags & FLAG_CASELESS_PATHNAMES);
208                                 }
209                         }
210                         break;
211                 case True:
212                         conn->case_sensitive = True;
213                         break;
214                 default:
215                         conn->case_sensitive = False;
216                         break;
217         }
218         return(True);
219 }
220
221 static int load_registry_service(const char *servicename)
222 {
223         if (!lp_registry_shares()) {
224                 return -1;
225         }
226
227         if ((servicename == NULL) || (*servicename == '\0')) {
228                 return -1;
229         }
230
231         if (strequal(servicename, GLOBAL_NAME)) {
232                 return -2;
233         }
234
235         if (!process_registry_service(servicename)) {
236                 return -1;
237         }
238
239         return lp_servicenumber(servicename);
240 }
241
242 void load_registry_shares(void)
243 {
244         DEBUG(8, ("load_registry_shares()\n"));
245         if (!lp_registry_shares()) {
246                 return;
247         }
248
249         process_registry_shares();
250
251         return;
252 }
253
254 /****************************************************************************
255  Add a home service. Returns the new service number or -1 if fail.
256 ****************************************************************************/
257
258 int add_home_service(const char *service, const char *username, const char *homedir)
259 {
260         int iHomeService;
261
262         if (!service || !homedir)
263                 return -1;
264
265         if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0) {
266                 if ((iHomeService = load_registry_service(HOMES_NAME)) < 0) {
267                         return -1;
268                 }
269         }
270
271         /*
272          * If this is a winbindd provided username, remove
273          * the domain component before adding the service.
274          * Log a warning if the "path=" parameter does not
275          * include any macros.
276          */
277
278         {
279                 const char *p = strchr(service,*lp_winbind_separator());
280
281                 /* We only want the 'user' part of the string */
282                 if (p) {
283                         service = p + 1;
284                 }
285         }
286
287         if (!lp_add_home(service, iHomeService, username, homedir)) {
288                 return -1;
289         }
290         
291         return lp_servicenumber(service);
292
293 }
294
295 /**
296  * Find a service entry.
297  *
298  * @param service is modified (to canonical form??)
299  **/
300
301 int find_service(fstring service)
302 {
303         int iService;
304         struct smbd_server_connection *sconn = smbd_server_conn;
305
306         all_string_sub(service,"\\","/",0);
307
308         iService = lp_servicenumber(service);
309
310         /* now handle the special case of a home directory */
311         if (iService < 0) {
312                 char *phome_dir = get_user_home_dir(talloc_tos(), service);
313
314                 if(!phome_dir) {
315                         /*
316                          * Try mapping the servicename, it may
317                          * be a Windows to unix mapped user name.
318                          */
319                         if(map_username(sconn, service))
320                                 phome_dir = get_user_home_dir(
321                                         talloc_tos(), service);
322                 }
323
324                 DEBUG(3,("checking for home directory %s gave %s\n",service,
325                         phome_dir?phome_dir:"(NULL)"));
326
327                 iService = add_home_service(service,service /* 'username' */, phome_dir);
328         }
329
330         /* If we still don't have a service, attempt to add it as a printer. */
331         if (iService < 0) {
332                 int iPrinterService;
333
334                 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) < 0) {
335                         iPrinterService = load_registry_service(PRINTERS_NAME);
336                 }
337                 if (iPrinterService) {
338                         DEBUG(3,("checking whether %s is a valid printer name...\n", service));
339                         if (pcap_printername_ok(service)) {
340                                 DEBUG(3,("%s is a valid printer name\n", service));
341                                 DEBUG(3,("adding %s as a printer service\n", service));
342                                 lp_add_printer(service, iPrinterService);
343                                 iService = lp_servicenumber(service);
344                                 if (iService < 0) {
345                                         DEBUG(0,("failed to add %s as a printer service!\n", service));
346                                 }
347                         } else {
348                                 DEBUG(3,("%s is not a valid printer name\n", service));
349                         }
350                 }
351         }
352
353         /* Check for default vfs service?  Unsure whether to implement this */
354         if (iService < 0) {
355         }
356
357         if (iService < 0) {
358                 iService = load_registry_service(service);
359         }
360
361         /* Is it a usershare service ? */
362         if (iService < 0 && *lp_usershare_path()) {
363                 /* Ensure the name is canonicalized. */
364                 strlower_m(service);
365                 iService = load_usershare_service(service);
366         }
367
368         /* just possibly it's a default service? */
369         if (iService < 0) {
370                 char *pdefservice = lp_defaultservice();
371                 if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr_m(service,"..")) {
372                         /*
373                          * We need to do a local copy here as lp_defaultservice() 
374                          * returns one of the rotating lp_string buffers that
375                          * could get overwritten by the recursive find_service() call
376                          * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
377                          */
378                         char *defservice = SMB_STRDUP(pdefservice);
379
380                         if (!defservice) {
381                                 goto fail;
382                         }
383
384                         /* Disallow anything except explicit share names. */
385                         if (strequal(defservice,HOMES_NAME) ||
386                                         strequal(defservice, PRINTERS_NAME) ||
387                                         strequal(defservice, "IPC$")) {
388                                 SAFE_FREE(defservice);
389                                 goto fail;
390                         }
391
392                         iService = find_service(defservice);
393                         if (iService >= 0) {
394                                 all_string_sub(service, "_","/",0);
395                                 iService = lp_add_service(service, iService);
396                         }
397                         SAFE_FREE(defservice);
398                 }
399         }
400
401         if (iService >= 0) {
402                 if (!VALID_SNUM(iService)) {
403                         DEBUG(0,("Invalid snum %d for %s\n",iService, service));
404                         iService = -1;
405                 }
406         }
407
408   fail:
409
410         if (iService < 0)
411                 DEBUG(3,("find_service() failed to find service %s\n", service));
412
413         return (iService);
414 }
415
416
417 /****************************************************************************
418  do some basic sainity checks on the share.  
419  This function modifies dev, ecode.
420 ****************************************************************************/
421
422 static NTSTATUS share_sanity_checks(int snum, fstring dev) 
423 {
424         
425         if (!lp_snum_ok(snum) || 
426             !check_access(smbd_server_fd(), 
427                           lp_hostsallow(snum), lp_hostsdeny(snum))) {    
428                 return NT_STATUS_ACCESS_DENIED;
429         }
430
431         if (dev[0] == '?' || !dev[0]) {
432                 if (lp_print_ok(snum)) {
433                         fstrcpy(dev,"LPT1:");
434                 } else if (strequal(lp_fstype(snum), "IPC")) {
435                         fstrcpy(dev, "IPC");
436                 } else {
437                         fstrcpy(dev,"A:");
438                 }
439         }
440
441         strupper_m(dev);
442
443         if (lp_print_ok(snum)) {
444                 if (!strequal(dev, "LPT1:")) {
445                         return NT_STATUS_BAD_DEVICE_TYPE;
446                 }
447         } else if (strequal(lp_fstype(snum), "IPC")) {
448                 if (!strequal(dev, "IPC")) {
449                         return NT_STATUS_BAD_DEVICE_TYPE;
450                 }
451         } else if (!strequal(dev, "A:")) {
452                 return NT_STATUS_BAD_DEVICE_TYPE;
453         }
454
455         /* Behave as a printer if we are supposed to */
456         if (lp_print_ok(snum) && (strcmp(dev, "A:") == 0)) {
457                 fstrcpy(dev, "LPT1:");
458         }
459
460         return NT_STATUS_OK;
461 }
462
463 /*
464  * Go through lookup_name etc to find the force'd group.  
465  *
466  * Create a new token from src_token, replacing the primary group sid with the
467  * one found.
468  */
469
470 static NTSTATUS find_forced_group(bool force_user,
471                                   int snum, const char *username,
472                                   DOM_SID *pgroup_sid,
473                                   gid_t *pgid)
474 {
475         NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
476         TALLOC_CTX *frame = talloc_stackframe();
477         DOM_SID group_sid;
478         enum lsa_SidType type;
479         char *groupname;
480         bool user_must_be_member = False;
481         gid_t gid;
482
483         groupname = talloc_strdup(talloc_tos(), lp_force_group(snum));
484         if (groupname == NULL) {
485                 DEBUG(1, ("talloc_strdup failed\n"));
486                 result = NT_STATUS_NO_MEMORY;
487                 goto done;
488         }
489
490         if (groupname[0] == '+') {
491                 user_must_be_member = True;
492                 groupname += 1;
493         }
494
495         groupname = talloc_string_sub(talloc_tos(), groupname,
496                                       "%S", lp_servicename(snum));
497         if (groupname == NULL) {
498                 DEBUG(1, ("talloc_string_sub failed\n"));
499                 result = NT_STATUS_NO_MEMORY;
500                 goto done;
501         }
502
503         if (!lookup_name_smbconf(talloc_tos(), groupname,
504                          LOOKUP_NAME_ALL|LOOKUP_NAME_GROUP,
505                          NULL, NULL, &group_sid, &type)) {
506                 DEBUG(10, ("lookup_name_smbconf(%s) failed\n",
507                            groupname));
508                 goto done;
509         }
510
511         if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
512             (type != SID_NAME_WKN_GRP)) {
513                 DEBUG(10, ("%s is a %s, not a group\n", groupname,
514                            sid_type_lookup(type)));
515                 goto done;
516         }
517
518         if (!sid_to_gid(&group_sid, &gid)) {
519                 DEBUG(10, ("sid_to_gid(%s) for %s failed\n",
520                            sid_string_dbg(&group_sid), groupname));
521                 goto done;
522         }
523
524         /*
525          * If the user has been forced and the forced group starts with a '+',
526          * then we only set the group to be the forced group if the forced
527          * user is a member of that group.  Otherwise, the meaning of the '+'
528          * would be ignored.
529          */
530
531         if (force_user && user_must_be_member) {
532                 if (user_in_group_sid(username, &group_sid)) {
533                         sid_copy(pgroup_sid, &group_sid);
534                         *pgid = gid;
535                         DEBUG(3,("Forced group %s for member %s\n",
536                                  groupname, username));
537                 } else {
538                         DEBUG(0,("find_forced_group: forced user %s is not a member "
539                                 "of forced group %s. Disallowing access.\n",
540                                 username, groupname ));
541                         result = NT_STATUS_MEMBER_NOT_IN_GROUP;
542                         goto done;
543                 }
544         } else {
545                 sid_copy(pgroup_sid, &group_sid);
546                 *pgid = gid;
547                 DEBUG(3,("Forced group %s\n", groupname));
548         }
549
550         result = NT_STATUS_OK;
551  done:
552         TALLOC_FREE(frame);
553         return result;
554 }
555
556 /****************************************************************************
557   Create an auth_serversupplied_info structure for a connection_struct
558 ****************************************************************************/
559
560 static NTSTATUS create_connection_server_info(struct smbd_server_connection *sconn,
561                                               TALLOC_CTX *mem_ctx, int snum,
562                                               struct auth_serversupplied_info *vuid_serverinfo,
563                                               DATA_BLOB password,
564                                               struct auth_serversupplied_info **presult)
565 {
566         if (lp_guest_only(snum)) {
567                 return make_server_info_guest(mem_ctx, presult);
568         }
569
570         if (vuid_serverinfo != NULL) {
571
572                 struct auth_serversupplied_info *result;
573
574                 /*
575                  * This is the normal security != share case where we have a
576                  * valid vuid from the session setup.                 */
577
578                 if (vuid_serverinfo->guest) {
579                         if (!lp_guest_ok(snum)) {
580                                 DEBUG(2, ("guest user (from session setup) "
581                                           "not permitted to access this share "
582                                           "(%s)\n", lp_servicename(snum)));
583                                 return NT_STATUS_ACCESS_DENIED;
584                         }
585                 } else {
586                         if (!user_ok_token(vuid_serverinfo->unix_name,
587                                            pdb_get_domain(vuid_serverinfo->sam_account),
588                                            vuid_serverinfo->ptok, snum)) {
589                                 DEBUG(2, ("user '%s' (from session setup) not "
590                                           "permitted to access this share "
591                                           "(%s)\n",
592                                           vuid_serverinfo->unix_name,
593                                           lp_servicename(snum)));
594                                 return NT_STATUS_ACCESS_DENIED;
595                         }
596                 }
597
598                 result = copy_serverinfo(mem_ctx, vuid_serverinfo);
599                 if (result == NULL) {
600                         return NT_STATUS_NO_MEMORY;
601                 }
602
603                 *presult = result;
604                 return NT_STATUS_OK;
605         }
606
607         if (lp_security() == SEC_SHARE) {
608
609                 fstring user;
610                 bool guest;
611
612                 /* add the sharename as a possible user name if we
613                    are in share mode security */
614
615                 add_session_user(sconn, lp_servicename(snum));
616
617                 /* shall we let them in? */
618
619                 if (!authorise_login(sconn, snum,user,password,&guest)) {
620                         DEBUG( 2, ( "Invalid username/password for [%s]\n",
621                                     lp_servicename(snum)) );
622                         return NT_STATUS_WRONG_PASSWORD;
623                 }
624
625                 return make_serverinfo_from_username(mem_ctx, user, guest,
626                                                      presult);
627         }
628
629         DEBUG(0, ("invalid VUID (vuser) but not in security=share\n"));
630         return NT_STATUS_ACCESS_DENIED;
631 }
632
633
634 /****************************************************************************
635   Make a connection, given the snum to connect to, and the vuser of the
636   connecting user if appropriate.
637 ****************************************************************************/
638
639 static connection_struct *make_connection_snum(
640                                         struct smbd_server_connection *sconn,
641                                         int snum, user_struct *vuser,
642                                         DATA_BLOB password,
643                                         const char *pdev,
644                                         NTSTATUS *pstatus)
645 {
646         connection_struct *conn;
647         SMB_STRUCT_STAT st;
648         fstring dev;
649         int ret;
650         char addr[INET6_ADDRSTRLEN];
651         bool on_err_call_dis_hook = false;
652         NTSTATUS status;
653
654         fstrcpy(dev, pdev);
655         SET_STAT_INVALID(st);
656
657         if (NT_STATUS_IS_ERR(*pstatus = share_sanity_checks(snum, dev))) {
658                 return NULL;
659         }       
660
661         conn = conn_new(sconn);
662         if (!conn) {
663                 DEBUG(0,("Couldn't find free connection.\n"));
664                 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
665                 return NULL;
666         }
667
668         conn->params->service = snum;
669
670         status = create_connection_server_info(sconn,
671                 conn, snum, vuser ? vuser->server_info : NULL, password,
672                 &conn->server_info);
673
674         if (!NT_STATUS_IS_OK(status)) {
675                 DEBUG(1, ("create_connection_server_info failed: %s\n",
676                           nt_errstr(status)));
677                 *pstatus = status;
678                 conn_free(sconn, conn);
679                 return NULL;
680         }
681
682         if ((lp_guest_only(snum)) || (lp_security() == SEC_SHARE)) {
683                 conn->force_user = true;
684         }
685
686         add_session_user(sconn, conn->server_info->unix_name);
687
688         safe_strcpy(conn->client_address,
689                         client_addr(get_client_fd(),addr,sizeof(addr)), 
690                         sizeof(conn->client_address)-1);
691         conn->num_files_open = 0;
692         conn->lastused = conn->lastused_count = time(NULL);
693         conn->used = True;
694         conn->printer = (strncmp(dev,"LPT",3) == 0);
695         conn->ipc = ( (strncmp(dev,"IPC",3) == 0) ||
696                       ( lp_enable_asu_support() && strequal(dev,"ADMIN$")) );
697         conn->dirptr = NULL;
698
699         /* Case options for the share. */
700         if (lp_casesensitive(snum) == Auto) {
701                 /* We will be setting this per packet. Set to be case
702                  * insensitive for now. */
703                 conn->case_sensitive = False;
704         } else {
705                 conn->case_sensitive = (bool)lp_casesensitive(snum);
706         }
707
708         conn->case_preserve = lp_preservecase(snum);
709         conn->short_case_preserve = lp_shortpreservecase(snum);
710
711         conn->encrypt_level = lp_smb_encrypt(snum);
712
713         conn->veto_list = NULL;
714         conn->hide_list = NULL;
715         conn->veto_oplock_list = NULL;
716         conn->aio_write_behind_list = NULL;
717         string_set(&conn->dirpath,"");
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(sconn, 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(sconn, 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(sconn, 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(sconn, 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(sconn, 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(sconn, 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(sconn, 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(sconn, 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(sconn, 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(sconn, 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(sconn, 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(sconn, 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         /* win2000 does not check the permissions on the directory
995            during the tree connect, instead relying on permission
996            check during individual operations. To match this behaviour
997            I have disabled this chdir check (tridge) */
998         /* the alternative is just to check the directory exists */
999         if ((ret = SMB_VFS_STAT(conn, conn->connectpath, &st)) != 0 ||
1000             !S_ISDIR(st.st_ex_mode)) {
1001                 if (ret == 0 && !S_ISDIR(st.st_ex_mode)) {
1002                         DEBUG(0,("'%s' is not a directory, when connecting to "
1003                                  "[%s]\n", conn->connectpath,
1004                                  lp_servicename(snum)));
1005                 } else {
1006                         DEBUG(0,("'%s' does not exist or permission denied "
1007                                  "when connecting to [%s] Error was %s\n",
1008                                  conn->connectpath, lp_servicename(snum),
1009                                  strerror(errno) ));
1010                 }
1011                 *pstatus = NT_STATUS_BAD_NETWORK_NAME;
1012                 goto err_root_exit;
1013         }
1014
1015         string_set(&conn->origpath,conn->connectpath);
1016
1017 #if SOFTLINK_OPTIMISATION
1018         /* resolve any soft links early if possible */
1019         if (vfs_ChDir(conn,conn->connectpath) == 0) {
1020                 TALLOC_CTX *ctx = talloc_tos();
1021                 char *s = vfs_GetWd(ctx,s);
1022                 if (!s) {
1023                         *status = map_nt_error_from_unix(errno);
1024                         goto err_root_exit;
1025                 }
1026                 if (!set_conn_connectpath(conn,s)) {
1027                         *status = NT_STATUS_NO_MEMORY;
1028                         goto err_root_exit;
1029                 }
1030                 vfs_ChDir(conn,conn->connectpath);
1031         }
1032 #endif
1033
1034         /* Figure out the characteristics of the underlying filesystem. This
1035          * assumes that all the filesystem mounted withing a share path have
1036          * the same characteristics, which is likely but not guaranteed.
1037          */
1038
1039         conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn);
1040
1041         /*
1042          * Print out the 'connected as' stuff here as we need
1043          * to know the effective uid and gid we will be using
1044          * (at least initially).
1045          */
1046
1047         if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
1048                 dbgtext( "%s (%s) ", get_remote_machine_name(),
1049                          conn->client_address );
1050                 dbgtext( "%s", srv_is_signing_active(smbd_server_conn) ? "signed " : "");
1051                 dbgtext( "connect to service %s ", lp_servicename(snum) );
1052                 dbgtext( "initially as user %s ",
1053                          conn->server_info->unix_name );
1054                 dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
1055                 dbgtext( "(pid %d)\n", (int)sys_getpid() );
1056         }
1057
1058         /* we've finished with the user stuff - go back to root */
1059         change_to_root_user();
1060         return(conn);
1061
1062   err_root_exit:
1063
1064         change_to_root_user();
1065         if (on_err_call_dis_hook) {
1066                 /* Call VFS disconnect hook */
1067                 SMB_VFS_DISCONNECT(conn);
1068         }
1069         yield_connection(conn, lp_servicename(snum));
1070         conn_free(sconn, conn);
1071         return NULL;
1072 }
1073
1074 /****************************************************************************
1075  Make a connection to a service.
1076  *
1077  * @param service 
1078 ****************************************************************************/
1079
1080 connection_struct *make_connection(struct smbd_server_connection *sconn,
1081                                    const char *service_in, DATA_BLOB password,
1082                                    const char *pdev, uint16 vuid,
1083                                    NTSTATUS *status)
1084 {
1085         uid_t euid;
1086         user_struct *vuser = NULL;
1087         fstring service;
1088         fstring dev;
1089         int snum = -1;
1090         char addr[INET6_ADDRSTRLEN];
1091
1092         fstrcpy(dev, pdev);
1093
1094         /* This must ONLY BE CALLED AS ROOT. As it exits this function as
1095          * root. */
1096         if (!non_root_mode() && (euid = geteuid()) != 0) {
1097                 DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot "
1098                          "(%u)\n", (unsigned int)euid ));
1099                 smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
1100         }
1101
1102         if (conn_num_open(sconn) > 2047) {
1103                 *status = NT_STATUS_INSUFF_SERVER_RESOURCES;
1104                 return NULL;
1105         }
1106
1107         if(lp_security() != SEC_SHARE) {
1108                 vuser = get_valid_user_struct(sconn, vuid);
1109                 if (!vuser) {
1110                         DEBUG(1,("make_connection: refusing to connect with "
1111                                  "no session setup\n"));
1112                         *status = NT_STATUS_ACCESS_DENIED;
1113                         return NULL;
1114                 }
1115         }
1116
1117         /* Logic to try and connect to the correct [homes] share, preferably
1118            without too many getpwnam() lookups.  This is particulary nasty for
1119            winbind usernames, where the share name isn't the same as unix
1120            username.
1121
1122            The snum of the homes share is stored on the vuser at session setup
1123            time.
1124         */
1125
1126         if (strequal(service_in,HOMES_NAME)) {
1127                 if(lp_security() != SEC_SHARE) {
1128                         DATA_BLOB no_pw = data_blob_null;
1129                         if (vuser->homes_snum == -1) {
1130                                 DEBUG(2, ("[homes] share not available for "
1131                                           "this user because it was not found "
1132                                           "or created at session setup "
1133                                           "time\n"));
1134                                 *status = NT_STATUS_BAD_NETWORK_NAME;
1135                                 return NULL;
1136                         }
1137                         DEBUG(5, ("making a connection to [homes] service "
1138                                   "created at session setup time\n"));
1139                         return make_connection_snum(sconn,
1140                                                     vuser->homes_snum,
1141                                                     vuser, no_pw, 
1142                                                     dev, status);
1143                 } else {
1144                         /* Security = share. Try with
1145                          * current_user_info.smb_name as the username.  */
1146                         if (*current_user_info.smb_name) {
1147                                 fstring unix_username;
1148                                 fstrcpy(unix_username,
1149                                         current_user_info.smb_name);
1150                                 map_username(sconn, unix_username);
1151                                 snum = find_service(unix_username);
1152                         } 
1153                         if (snum != -1) {
1154                                 DEBUG(5, ("making a connection to 'homes' "
1155                                           "service %s based on "
1156                                           "security=share\n", service_in));
1157                                 return make_connection_snum(sconn,
1158                                                             snum, NULL,
1159                                                             password,
1160                                                             dev, status);
1161                         }
1162                 }
1163         } else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1)
1164                    && strequal(service_in,
1165                                lp_servicename(vuser->homes_snum))) {
1166                 DATA_BLOB no_pw = data_blob_null;
1167                 DEBUG(5, ("making a connection to 'homes' service [%s] "
1168                           "created at session setup time\n", service_in));
1169                 return make_connection_snum(sconn,
1170                                             vuser->homes_snum,
1171                                             vuser, no_pw, 
1172                                             dev, status);
1173         }
1174         
1175         fstrcpy(service, service_in);
1176
1177         strlower_m(service);
1178
1179         snum = find_service(service);
1180
1181         if (snum < 0) {
1182                 if (strequal(service,"IPC$") ||
1183                     (lp_enable_asu_support() && strequal(service,"ADMIN$"))) {
1184                         DEBUG(3,("refusing IPC connection to %s\n", service));
1185                         *status = NT_STATUS_ACCESS_DENIED;
1186                         return NULL;
1187                 }
1188
1189                 DEBUG(0,("%s (%s) couldn't find service %s\n",
1190                         get_remote_machine_name(),
1191                         client_addr(get_client_fd(),addr,sizeof(addr)),
1192                         service));
1193                 *status = NT_STATUS_BAD_NETWORK_NAME;
1194                 return NULL;
1195         }
1196
1197         /* Handle non-Dfs clients attempting connections to msdfs proxy */
1198         if (lp_host_msdfs() && (*lp_msdfs_proxy(snum) != '\0'))  {
1199                 DEBUG(3, ("refusing connection to dfs proxy share '%s' "
1200                           "(pointing to %s)\n", 
1201                         service, lp_msdfs_proxy(snum)));
1202                 *status = NT_STATUS_BAD_NETWORK_NAME;
1203                 return NULL;
1204         }
1205
1206         DEBUG(5, ("making a connection to 'normal' service %s\n", service));
1207
1208         return make_connection_snum(sconn, snum, vuser,
1209                                     password,
1210                                     dev, status);
1211 }
1212
1213 /****************************************************************************
1214  Close a cnum.
1215 ****************************************************************************/
1216
1217 void close_cnum(struct smbd_server_connection *sconn,
1218                 connection_struct *conn, uint16 vuid)
1219 {
1220         file_close_conn(conn);
1221
1222         if (!IS_IPC(conn)) {
1223                 dptr_closecnum(conn);
1224         }
1225
1226         change_to_root_user();
1227
1228         DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
1229                                  get_remote_machine_name(),
1230                                  conn->client_address,
1231                                  lp_servicename(SNUM(conn))));
1232
1233         /* Call VFS disconnect hook */    
1234         SMB_VFS_DISCONNECT(conn);
1235
1236         yield_connection(conn, lp_servicename(SNUM(conn)));
1237
1238         /* make sure we leave the directory available for unmount */
1239         vfs_ChDir(conn, "/");
1240
1241         /* execute any "postexec = " line */
1242         if (*lp_postexec(SNUM(conn)) && 
1243             change_to_user(conn, vuid))  {
1244                 char *cmd = talloc_sub_advanced(talloc_tos(),
1245                                         lp_servicename(SNUM(conn)),
1246                                         conn->server_info->unix_name,
1247                                         conn->connectpath,
1248                                         conn->server_info->utok.gid,
1249                                         conn->server_info->sanitized_username,
1250                                         pdb_get_domain(conn->server_info->sam_account),
1251                                         lp_postexec(SNUM(conn)));
1252                 smbrun(cmd,NULL);
1253                 TALLOC_FREE(cmd);
1254                 change_to_root_user();
1255         }
1256
1257         change_to_root_user();
1258         /* execute any "root postexec = " line */
1259         if (*lp_rootpostexec(SNUM(conn)))  {
1260                 char *cmd = talloc_sub_advanced(talloc_tos(),
1261                                         lp_servicename(SNUM(conn)),
1262                                         conn->server_info->unix_name,
1263                                         conn->connectpath,
1264                                         conn->server_info->utok.gid,
1265                                         conn->server_info->sanitized_username,
1266                                         pdb_get_domain(conn->server_info->sam_account),
1267                                         lp_rootpostexec(SNUM(conn)));
1268                 smbrun(cmd,NULL);
1269                 TALLOC_FREE(cmd);
1270         }
1271
1272         conn_free(sconn, conn);
1273 }