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