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