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