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