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