aeb0e0f31d059364c18222329ecfd1a17aa233fd
[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 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 pstring 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         if (!service_ok(res)) {
316                 /* this is actually never reached, since 
317                  * service_ok only returns False if the service
318                  * entry does not have a service name, and we _know_
319                  * we do have a service name here... */
320                 res = -1;
321         }
322
323  error:
324
325         TALLOC_FREE(key);
326         return res;
327 }
328
329 void load_registry_shares(void)
330 {
331         struct registry_key *key;
332         char *name;
333         WERROR err;
334         int i;
335
336         if (!lp_registry_shares()) {
337                 return;
338         }
339
340         err = reg_open_path(NULL, KEY_SMBCONF, REG_KEY_READ,
341                             get_root_nt_token(), &key);
342         if (!(W_ERROR_IS_OK(err))) {
343                 return;
344         }
345
346         for (i=0; W_ERROR_IS_OK(reg_enumkey(key, key, i, &name, NULL)); i++) {
347                 load_registry_service(name);
348                 TALLOC_FREE(name);
349         }
350
351         TALLOC_FREE(key);
352         return;
353 }
354
355 /**
356  * Find a service entry.
357  *
358  * @param service is modified (to canonical form??)
359  **/
360
361 int find_service(fstring service)
362 {
363         int iService;
364
365         all_string_sub(service,"\\","/",0);
366
367         iService = lp_servicenumber(service);
368
369         /* now handle the special case of a home directory */
370         if (iService < 0) {
371                 char *phome_dir = get_user_home_dir(service);
372
373                 if(!phome_dir) {
374                         /*
375                          * Try mapping the servicename, it may
376                          * be a Windows to unix mapped user name.
377                          */
378                         if(map_username(service))
379                                 phome_dir = get_user_home_dir(service);
380                 }
381
382                 DEBUG(3,("checking for home directory %s gave %s\n",service,
383                         phome_dir?phome_dir:"(NULL)"));
384
385                 iService = add_home_service(service,service /* 'username' */, phome_dir);
386         }
387
388         /* If we still don't have a service, attempt to add it as a printer. */
389         if (iService < 0) {
390                 int iPrinterService;
391
392                 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
393                         DEBUG(3,("checking whether %s is a valid printer name...\n", service));
394                         if (pcap_printername_ok(service)) {
395                                 DEBUG(3,("%s is a valid printer name\n", service));
396                                 DEBUG(3,("adding %s as a printer service\n", service));
397                                 lp_add_printer(service, iPrinterService);
398                                 iService = lp_servicenumber(service);
399                                 if (iService < 0) {
400                                         DEBUG(0,("failed to add %s as a printer service!\n", service));
401                                 }
402                         } else {
403                                 DEBUG(3,("%s is not a valid printer name\n", service));
404                         }
405                 }
406         }
407
408         /* Check for default vfs service?  Unsure whether to implement this */
409         if (iService < 0) {
410         }
411
412         /* Is it a usershare service ? */
413         if (iService < 0 && *lp_usershare_path()) {
414                 /* Ensure the name is canonicalized. */
415                 strlower_m(service);
416                 iService = load_usershare_service(service);
417         }
418
419         /* just possibly it's a default service? */
420         if (iService < 0) {
421                 char *pdefservice = lp_defaultservice();
422                 if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr_m(service,"..")) {
423                         /*
424                          * We need to do a local copy here as lp_defaultservice() 
425                          * returns one of the rotating lp_string buffers that
426                          * could get overwritten by the recursive find_service() call
427                          * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
428                          */
429                         pstring defservice;
430                         pstrcpy(defservice, pdefservice);
431
432                         /* Disallow anything except explicit share names. */
433                         if (strequal(defservice,HOMES_NAME) ||
434                                         strequal(defservice, PRINTERS_NAME) ||
435                                         strequal(defservice, "IPC$")) {
436                                 goto fail;
437                         }
438
439                         iService = find_service(defservice);
440                         if (iService >= 0) {
441                                 all_string_sub(service, "_","/",0);
442                                 iService = lp_add_service(service, iService);
443                         }
444                 }
445         }
446
447         if (iService < 0) {
448                 iService = load_registry_service(service);
449         }
450
451         if (iService >= 0) {
452                 if (!VALID_SNUM(iService)) {
453                         DEBUG(0,("Invalid snum %d for %s\n",iService, service));
454                         iService = -1;
455                 }
456         }
457
458   fail:
459
460         if (iService < 0)
461                 DEBUG(3,("find_service() failed to find service %s\n", service));
462
463         return (iService);
464 }
465
466
467 /****************************************************************************
468  do some basic sainity checks on the share.  
469  This function modifies dev, ecode.
470 ****************************************************************************/
471
472 static NTSTATUS share_sanity_checks(int snum, fstring dev) 
473 {
474         
475         if (!lp_snum_ok(snum) || 
476             !check_access(smbd_server_fd(), 
477                           lp_hostsallow(snum), lp_hostsdeny(snum))) {    
478                 return NT_STATUS_ACCESS_DENIED;
479         }
480
481         if (dev[0] == '?' || !dev[0]) {
482                 if (lp_print_ok(snum)) {
483                         fstrcpy(dev,"LPT1:");
484                 } else if (strequal(lp_fstype(snum), "IPC")) {
485                         fstrcpy(dev, "IPC");
486                 } else {
487                         fstrcpy(dev,"A:");
488                 }
489         }
490
491         strupper_m(dev);
492
493         if (lp_print_ok(snum)) {
494                 if (!strequal(dev, "LPT1:")) {
495                         return NT_STATUS_BAD_DEVICE_TYPE;
496                 }
497         } else if (strequal(lp_fstype(snum), "IPC")) {
498                 if (!strequal(dev, "IPC")) {
499                         return NT_STATUS_BAD_DEVICE_TYPE;
500                 }
501         } else if (!strequal(dev, "A:")) {
502                 return NT_STATUS_BAD_DEVICE_TYPE;
503         }
504
505         /* Behave as a printer if we are supposed to */
506         if (lp_print_ok(snum) && (strcmp(dev, "A:") == 0)) {
507                 fstrcpy(dev, "LPT1:");
508         }
509
510         return NT_STATUS_OK;
511 }
512
513 static NTSTATUS find_forced_user(connection_struct *conn, BOOL vuser_is_guest, fstring username)
514 {
515         int snum = conn->params->service;
516         char *fuser, *found_username;
517         NTSTATUS result;
518
519         if (!(fuser = talloc_string_sub(conn->mem_ctx, lp_force_user(snum), "%S",
520                                         lp_servicename(snum)))) {
521                 return NT_STATUS_NO_MEMORY;
522         }
523
524         result = create_token_from_username(conn->mem_ctx, fuser, vuser_is_guest,
525                                             &conn->uid, &conn->gid, &found_username,
526                                             &conn->nt_user_token);
527         if (!NT_STATUS_IS_OK(result)) {
528                 return result;
529         }
530
531         fstrcpy(username, found_username);
532
533         TALLOC_FREE(fuser);
534         TALLOC_FREE(found_username);
535         return NT_STATUS_OK;
536 }
537
538 /*
539  * Go through lookup_name etc to find the force'd group.  
540  *
541  * Create a new token from src_token, replacing the primary group sid with the
542  * one found.
543  */
544
545 static NTSTATUS find_forced_group(BOOL force_user,
546                                   int snum, const char *username,
547                                   DOM_SID *pgroup_sid,
548                                   gid_t *pgid)
549 {
550         NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
551         TALLOC_CTX *mem_ctx;
552         DOM_SID group_sid;
553         enum lsa_SidType type;
554         char *groupname;
555         BOOL user_must_be_member = False;
556         gid_t gid;
557
558         ZERO_STRUCTP(pgroup_sid);
559         *pgid = (gid_t)-1;
560
561         mem_ctx = talloc_new(NULL);
562         if (mem_ctx == NULL) {
563                 DEBUG(0, ("talloc_new failed\n"));
564                 return NT_STATUS_NO_MEMORY;
565         }
566
567         groupname = talloc_strdup(mem_ctx, lp_force_group(snum));
568         if (groupname == NULL) {
569                 DEBUG(1, ("talloc_strdup failed\n"));
570                 result = NT_STATUS_NO_MEMORY;
571                 goto done;
572         }
573
574         if (groupname[0] == '+') {
575                 user_must_be_member = True;
576                 groupname += 1;
577         }
578
579         groupname = talloc_string_sub(mem_ctx, groupname,
580                                       "%S", lp_servicename(snum));
581
582         if (!lookup_name_smbconf(mem_ctx, groupname,
583                          LOOKUP_NAME_ALL|LOOKUP_NAME_GROUP,
584                          NULL, NULL, &group_sid, &type)) {
585                 DEBUG(10, ("lookup_name_smbconf(%s) failed\n",
586                            groupname));
587                 goto done;
588         }
589
590         if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
591             (type != SID_NAME_WKN_GRP)) {
592                 DEBUG(10, ("%s is a %s, not a group\n", groupname,
593                            sid_type_lookup(type)));
594                 goto done;
595         }
596
597         if (!sid_to_gid(&group_sid, &gid)) {
598                 DEBUG(10, ("sid_to_gid(%s) for %s failed\n",
599                            sid_string_static(&group_sid), groupname));
600                 goto done;
601         }
602
603         /*
604          * If the user has been forced and the forced group starts with a '+',
605          * then we only set the group to be the forced group if the forced
606          * user is a member of that group.  Otherwise, the meaning of the '+'
607          * would be ignored.
608          */
609
610         if (force_user && user_must_be_member) {
611                 if (user_in_group_sid(username, &group_sid)) {
612                         sid_copy(pgroup_sid, &group_sid);
613                         *pgid = gid;
614                         DEBUG(3,("Forced group %s for member %s\n",
615                                  groupname, username));
616                 } else {
617                         DEBUG(0,("find_forced_group: forced user %s is not a member "
618                                 "of forced group %s. Disallowing access.\n",
619                                 username, groupname ));
620                         result = NT_STATUS_MEMBER_NOT_IN_GROUP;
621                         goto done;
622                 }
623         } else {
624                 sid_copy(pgroup_sid, &group_sid);
625                 *pgid = gid;
626                 DEBUG(3,("Forced group %s\n", groupname));
627         }
628
629         result = NT_STATUS_OK;
630  done:
631         TALLOC_FREE(mem_ctx);
632         return result;
633 }
634
635 /****************************************************************************
636   Make a connection, given the snum to connect to, and the vuser of the
637   connecting user if appropriate.
638 ****************************************************************************/
639
640 static connection_struct *make_connection_snum(int snum, user_struct *vuser,
641                                                DATA_BLOB password, 
642                                                const char *pdev,
643                                                NTSTATUS *status)
644 {
645         struct passwd *pass = NULL;
646         BOOL guest = False;
647         connection_struct *conn;
648         SMB_STRUCT_STAT st;
649         fstring user;
650         fstring dev;
651         int ret;
652
653         *user = 0;
654         fstrcpy(dev, pdev);
655         SET_STAT_INVALID(st);
656
657         if (NT_STATUS_IS_ERR(*status = share_sanity_checks(snum, dev))) {
658                 return NULL;
659         }       
660
661         conn = conn_new();
662         if (!conn) {
663                 DEBUG(0,("Couldn't find free connection.\n"));
664                 *status = NT_STATUS_INSUFFICIENT_RESOURCES;
665                 return NULL;
666         }
667
668         conn->params->service = snum;
669         conn->nt_user_token = NULL;
670
671         if (lp_guest_only(snum)) {
672                 const char *guestname = lp_guestaccount();
673                 NTSTATUS status2;
674                 char *found_username = NULL;
675
676                 guest = True;
677                 pass = getpwnam_alloc(NULL, guestname);
678                 if (!pass) {
679                         DEBUG(0,("make_connection_snum: Invalid guest "
680                                  "account %s??\n",guestname));
681                         conn_free(conn);
682                         *status = NT_STATUS_NO_SUCH_USER;
683                         return NULL;
684                 }
685                 status2 = create_token_from_username(conn->mem_ctx, pass->pw_name, True,
686                                                      &conn->uid, &conn->gid,
687                                                      &found_username,
688                                                      &conn->nt_user_token);
689                 if (!NT_STATUS_IS_OK(status2)) {
690                         TALLOC_FREE(pass);
691                         conn_free(conn);
692                         *status = status2;
693                         return NULL;
694                 }
695                 fstrcpy(user, found_username);
696                 string_set(&conn->user,user);
697                 conn->force_user = True;
698                 TALLOC_FREE(found_username);
699                 TALLOC_FREE(pass);
700                 DEBUG(3,("Guest only user %s\n",user));
701         } else if (vuser) {
702                 if (vuser->guest) {
703                         if (!lp_guest_ok(snum)) {
704                                 DEBUG(2, ("guest user (from session setup) "
705                                           "not permitted to access this share "
706                                           "(%s)\n", lp_servicename(snum)));
707                                       conn_free(conn);
708                                       *status = NT_STATUS_ACCESS_DENIED;
709                                       return NULL;
710                         }
711                 } else {
712                         if (!user_ok_token(vuser->user.unix_name,
713                                            vuser->nt_user_token, snum)) {
714                                 DEBUG(2, ("user '%s' (from session setup) not "
715                                           "permitted to access this share "
716                                           "(%s)\n", vuser->user.unix_name,
717                                           lp_servicename(snum)));
718                                 conn_free(conn);
719                                 *status = NT_STATUS_ACCESS_DENIED;
720                                 return NULL;
721                         }
722                 }
723                 conn->vuid = vuser->vuid;
724                 conn->uid = vuser->uid;
725                 conn->gid = vuser->gid;
726                 string_set(&conn->user,vuser->user.unix_name);
727                 fstrcpy(user,vuser->user.unix_name);
728                 guest = vuser->guest; 
729         } else if (lp_security() == SEC_SHARE) {
730                 NTSTATUS status2;
731                 char *found_username = NULL;
732
733                 /* add it as a possible user name if we 
734                    are in share mode security */
735                 add_session_user(lp_servicename(snum));
736                 /* shall we let them in? */
737                 if (!authorise_login(snum,user,password,&guest)) {
738                         DEBUG( 2, ( "Invalid username/password for [%s]\n", 
739                                     lp_servicename(snum)) );
740                         conn_free(conn);
741                         *status = NT_STATUS_WRONG_PASSWORD;
742                         return NULL;
743                 }
744                 pass = Get_Pwnam(user);
745                 status2 = create_token_from_username(conn->mem_ctx, pass->pw_name, True,
746                                                      &conn->uid, &conn->gid,
747                                                      &found_username,
748                                                      &conn->nt_user_token);
749                 if (!NT_STATUS_IS_OK(status2)) {
750                         conn_free(conn);
751                         *status = status2;
752                         return NULL;
753                 }
754                 fstrcpy(user, found_username);
755                 string_set(&conn->user,user);
756                 TALLOC_FREE(found_username);
757                 conn->force_user = True;
758         } else {
759                 DEBUG(0, ("invalid VUID (vuser) but not in security=share\n"));
760                 conn_free(conn);
761                 *status = NT_STATUS_ACCESS_DENIED;
762                 return NULL;
763         }
764
765         add_session_user(user);
766
767         safe_strcpy(conn->client_address, client_addr(), 
768                     sizeof(conn->client_address)-1);
769         conn->num_files_open = 0;
770         conn->lastused = conn->lastused_count = time(NULL);
771         conn->used = True;
772         conn->printer = (strncmp(dev,"LPT",3) == 0);
773         conn->ipc = ( (strncmp(dev,"IPC",3) == 0) ||
774                       ( lp_enable_asu_support() && strequal(dev,"ADMIN$")) );
775         conn->dirptr = NULL;
776
777         /* Case options for the share. */
778         if (lp_casesensitive(snum) == Auto) {
779                 /* We will be setting this per packet. Set to be case
780                  * insensitive for now. */
781                 conn->case_sensitive = False;
782         } else {
783                 conn->case_sensitive = (BOOL)lp_casesensitive(snum);
784         }
785
786         conn->case_preserve = lp_preservecase(snum);
787         conn->short_case_preserve = lp_shortpreservecase(snum);
788
789         conn->veto_list = NULL;
790         conn->hide_list = NULL;
791         conn->veto_oplock_list = NULL;
792         string_set(&conn->dirpath,"");
793         string_set(&conn->user,user);
794
795         conn->read_only = lp_readonly(SNUM(conn));
796         conn->admin_user = False;
797
798         /*
799          * If force user is true, then store the given userid and the gid of
800          * the user we're forcing.
801          * For auxiliary groups see below.
802          */
803         
804         if (*lp_force_user(snum)) {
805                 NTSTATUS status2;
806
807                 status2 = find_forced_user(conn,
808                                 (vuser != NULL) && vuser->guest,
809                                 user);
810                 if (!NT_STATUS_IS_OK(status2)) {
811                         conn_free(conn);
812                         *status = status2;
813                         return NULL;
814                 }
815                 string_set(&conn->user,user);
816                 conn->force_user = True;
817                 DEBUG(3,("Forced user %s\n",user));       
818         }
819
820         /*
821          * If force group is true, then override
822          * any groupid stored for the connecting user.
823          */
824         
825         if (*lp_force_group(snum)) {
826                 NTSTATUS status2;
827                 DOM_SID group_sid;
828
829                 status2 = find_forced_group(conn->force_user,
830                                             snum, user,
831                                             &group_sid, &conn->gid);
832                 if (!NT_STATUS_IS_OK(status2)) {
833                         conn_free(conn);
834                         *status = status2;
835                         return NULL;
836                 }
837
838                 if ((conn->nt_user_token == NULL) && (vuser != NULL)) {
839
840                         /* Not force user and not security=share, but force
841                          * group. vuser has a token to copy */
842                         
843                         conn->nt_user_token = dup_nt_token(
844                                 NULL, vuser->nt_user_token);
845                         if (conn->nt_user_token == NULL) {
846                                 DEBUG(0, ("dup_nt_token failed\n"));
847                                 conn_free(conn);
848                                 *status = NT_STATUS_NO_MEMORY;
849                                 return NULL;
850                         }
851                 }
852
853                 /* If conn->nt_user_token is still NULL, we have
854                  * security=share. This means ignore the SID, as we had no
855                  * vuser to copy from */
856
857                 if (conn->nt_user_token != NULL) {
858                         /* Overwrite the primary group sid */
859                         sid_copy(&conn->nt_user_token->user_sids[1],
860                                  &group_sid);
861
862                 }
863                 conn->force_group = True;
864         }
865
866         if (conn->nt_user_token != NULL) {
867                 size_t i;
868
869                 /* We have a share-specific token from force [user|group].
870                  * This means we have to create the list of unix groups from
871                  * the list of sids. */
872
873                 conn->ngroups = 0;
874                 conn->groups = NULL;
875
876                 for (i=0; i<conn->nt_user_token->num_sids; i++) {
877                         gid_t gid;
878                         DOM_SID *sid = &conn->nt_user_token->user_sids[i];
879
880                         if (!sid_to_gid(sid, &gid)) {
881                                 DEBUG(10, ("Could not convert SID %s to gid, "
882                                            "ignoring it\n",
883                                            sid_string_static(sid)));
884                                 continue;
885                         }
886                         if (!add_gid_to_array_unique(conn->mem_ctx, gid, &conn->groups,
887                                                 &conn->ngroups)) {
888                                 DEBUG(0, ("add_gid_to_array_unique failed\n"));
889                                 conn_free(conn);
890                                 *status = NT_STATUS_NO_MEMORY;
891                                 return NULL;
892                         }
893                 }
894         }
895
896         {
897                 pstring s;
898                 pstrcpy(s,lp_pathname(snum));
899                 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
900                                       conn->connectpath, conn->gid,
901                                       get_current_username(),
902                                       current_user_info.domain,
903                                       s, sizeof(s));
904                 set_conn_connectpath(conn,s);
905                 DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
906                          lp_servicename(snum)));
907         }
908
909         /*
910          * New code to check if there's a share security descripter
911          * added from NT server manager. This is done after the
912          * smb.conf checks are done as we need a uid and token. JRA.
913          *
914          */
915
916         {
917                 BOOL can_write = False;
918                 NT_USER_TOKEN *token = conn->nt_user_token ?
919                         conn->nt_user_token :
920                         (vuser ? vuser->nt_user_token : NULL);
921
922                 /*
923                  * I don't believe this can happen. But the
924                  * logic above is convoluted enough to confuse
925                  * automated checkers, so be sure. JRA.
926                  */
927
928                 if (token == NULL) {
929                         DEBUG(0,("make_connection: connection to %s "
930                                  "denied due to missing "
931                                  "NT token.\n",
932                                   lp_servicename(snum)));
933                         conn_free(conn);
934                         *status = NT_STATUS_ACCESS_DENIED;
935                         return NULL;
936                 }
937
938                 can_write = share_access_check(token,
939                                                     lp_servicename(snum),
940                                                     FILE_WRITE_DATA);
941
942                 if (!can_write) {
943                         if (!share_access_check(token,
944                                                 lp_servicename(snum),
945                                                 FILE_READ_DATA)) {
946                                 /* No access, read or write. */
947                                 DEBUG(0,("make_connection: connection to %s "
948                                          "denied due to security "
949                                          "descriptor.\n",
950                                           lp_servicename(snum)));
951                                 conn_free(conn);
952                                 *status = NT_STATUS_ACCESS_DENIED;
953                                 return NULL;
954                         } else {
955                                 conn->read_only = True;
956                         }
957                 }
958         }
959         /* Initialise VFS function pointers */
960
961         if (!smbd_vfs_init(conn)) {
962                 DEBUG(0, ("vfs_init failed for service %s\n",
963                           lp_servicename(snum)));
964                 conn_free(conn);
965                 *status = NT_STATUS_BAD_NETWORK_NAME;
966                 return NULL;
967         }
968
969         /*
970          * If widelinks are disallowed we need to canonicalise the connect
971          * path here to ensure we don't have any symlinks in the
972          * connectpath. We will be checking all paths on this connection are
973          * below this directory. We must do this after the VFS init as we
974          * depend on the realpath() pointer in the vfs table. JRA.
975          */
976         if (!lp_widelinks(snum)) {
977                 pstring s;
978                 pstrcpy(s,conn->connectpath);
979                 canonicalize_path(conn, s);
980                 set_conn_connectpath(conn,s);
981         }
982
983         if ((!conn->printer) && (!conn->ipc)) {
984                 conn->notify_ctx = notify_init(conn->mem_ctx, server_id_self(),
985                                                smbd_messaging_context(),
986                                                smbd_event_context(),
987                                                conn);
988         }
989
990 /* ROOT Activities: */  
991         /*
992          * Enforce the max connections parameter.
993          */
994
995         if ((lp_max_connections(snum) > 0)
996             && (count_current_connections(lp_servicename(SNUM(conn)), True) >=
997                 lp_max_connections(snum))) {
998
999                 DEBUG(1, ("Max connections (%d) exceeded for %s\n",
1000                           lp_max_connections(snum), lp_servicename(snum)));
1001                 conn_free(conn);
1002                 *status = NT_STATUS_INSUFFICIENT_RESOURCES;
1003                 return NULL;
1004         }  
1005
1006         /*
1007          * Get us an entry in the connections db
1008          */
1009         if (!claim_connection(conn, lp_servicename(snum), 0)) {
1010                 DEBUG(1, ("Could not store connections entry\n"));
1011                 conn_free(conn);
1012                 *status = NT_STATUS_INTERNAL_DB_ERROR;
1013                 return NULL;
1014         }  
1015
1016         /* Preexecs are done here as they might make the dir we are to ChDir
1017          * to below */
1018         /* execute any "root preexec = " line */
1019         if (*lp_rootpreexec(snum)) {
1020                 pstring cmd;
1021                 pstrcpy(cmd,lp_rootpreexec(snum));
1022                 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
1023                                       conn->connectpath, conn->gid,
1024                                       get_current_username(),
1025                                       current_user_info.domain,
1026                                       cmd, sizeof(cmd));
1027                 DEBUG(5,("cmd=%s\n",cmd));
1028                 ret = smbrun(cmd,NULL);
1029                 if (ret != 0 && lp_rootpreexec_close(snum)) {
1030                         DEBUG(1,("root preexec gave %d - failing "
1031                                  "connection\n", ret));
1032                         yield_connection(conn, lp_servicename(snum));
1033                         conn_free(conn);
1034                         *status = NT_STATUS_ACCESS_DENIED;
1035                         return NULL;
1036                 }
1037         }
1038
1039 /* USER Activites: */
1040         if (!change_to_user(conn, conn->vuid)) {
1041                 /* No point continuing if they fail the basic checks */
1042                 DEBUG(0,("Can't become connected user!\n"));
1043                 yield_connection(conn, lp_servicename(snum));
1044                 conn_free(conn);
1045                 *status = NT_STATUS_LOGON_FAILURE;
1046                 return NULL;
1047         }
1048
1049         /* Remember that a different vuid can connect later without these
1050          * checks... */
1051         
1052         /* Preexecs are done here as they might make the dir we are to ChDir
1053          * to below */
1054
1055         /* execute any "preexec = " line */
1056         if (*lp_preexec(snum)) {
1057                 pstring cmd;
1058                 pstrcpy(cmd,lp_preexec(snum));
1059                 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
1060                                       conn->connectpath, conn->gid,
1061                                       get_current_username(),
1062                                       current_user_info.domain,
1063                                       cmd, sizeof(cmd));
1064                 ret = smbrun(cmd,NULL);
1065                 if (ret != 0 && lp_preexec_close(snum)) {
1066                         DEBUG(1,("preexec gave %d - failing connection\n",
1067                                  ret));
1068                         change_to_root_user();
1069                         yield_connection(conn, lp_servicename(snum));
1070                         conn_free(conn);
1071                         *status = NT_STATUS_ACCESS_DENIED;
1072                         return NULL;
1073                 }
1074         }
1075
1076 #ifdef WITH_FAKE_KASERVER
1077         if (lp_afs_share(snum)) {
1078                 afs_login(conn);
1079         }
1080 #endif
1081         
1082         /* Add veto/hide lists */
1083         if (!IS_IPC(conn) && !IS_PRINT(conn)) {
1084                 set_namearray( &conn->veto_list, lp_veto_files(snum));
1085                 set_namearray( &conn->hide_list, lp_hide_files(snum));
1086                 set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(snum));
1087         }
1088         
1089         /* Invoke VFS make connection hook - do this before the VFS_STAT call
1090            to allow any filesystems needing user credentials to initialize
1091            themselves. */
1092
1093         if (SMB_VFS_CONNECT(conn, lp_servicename(snum), user) < 0) {
1094                 DEBUG(0,("make_connection: VFS make connection failed!\n"));
1095                 change_to_root_user();
1096                 yield_connection(conn, lp_servicename(snum));
1097                 conn_free(conn);
1098                 *status = NT_STATUS_UNSUCCESSFUL;
1099                 return NULL;
1100         }
1101
1102         /* win2000 does not check the permissions on the directory
1103            during the tree connect, instead relying on permission
1104            check during individual operations. To match this behaviour
1105            I have disabled this chdir check (tridge) */
1106         /* the alternative is just to check the directory exists */
1107         if ((ret = SMB_VFS_STAT(conn, conn->connectpath, &st)) != 0 ||
1108             !S_ISDIR(st.st_mode)) {
1109                 if (ret == 0 && !S_ISDIR(st.st_mode)) {
1110                         DEBUG(0,("'%s' is not a directory, when connecting to "
1111                                  "[%s]\n", conn->connectpath,
1112                                  lp_servicename(snum)));
1113                 } else {
1114                         DEBUG(0,("'%s' does not exist or permission denied "
1115                                  "when connecting to [%s] Error was %s\n",
1116                                  conn->connectpath, lp_servicename(snum),
1117                                  strerror(errno) ));
1118                 }
1119                 change_to_root_user();
1120                 /* Call VFS disconnect hook */    
1121                 SMB_VFS_DISCONNECT(conn);
1122                 yield_connection(conn, lp_servicename(snum));
1123                 conn_free(conn);
1124                 *status = NT_STATUS_BAD_NETWORK_NAME;
1125                 return NULL;
1126         }
1127         
1128         string_set(&conn->origpath,conn->connectpath);
1129         
1130 #if SOFTLINK_OPTIMISATION
1131         /* resolve any soft links early if possible */
1132         if (vfs_ChDir(conn,conn->connectpath) == 0) {
1133                 pstring s;
1134                 pstrcpy(s,conn->connectpath);
1135                 vfs_GetWd(conn,s);
1136                 set_conn_connectpath(conn,s);
1137                 vfs_ChDir(conn,conn->connectpath);
1138         }
1139 #endif
1140         
1141         /*
1142          * Print out the 'connected as' stuff here as we need
1143          * to know the effective uid and gid we will be using
1144          * (at least initially).
1145          */
1146
1147         if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
1148                 dbgtext( "%s (%s) ", get_remote_machine_name(),
1149                          conn->client_address );
1150                 dbgtext( "%s", srv_is_signing_active() ? "signed " : "");
1151                 dbgtext( "connect to service %s ", lp_servicename(snum) );
1152                 dbgtext( "initially as user %s ", user );
1153                 dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
1154                 dbgtext( "(pid %d)\n", (int)sys_getpid() );
1155         }
1156         
1157         /* we've finished with the user stuff - go back to root */
1158         change_to_root_user();
1159         return(conn);
1160 }
1161
1162 /***************************************************************************************
1163  Simple wrapper function for make_connection() to include a call to 
1164  vfs_chdir()
1165  **************************************************************************************/
1166  
1167 connection_struct *make_connection_with_chdir(const char *service_in,
1168                                               DATA_BLOB password, 
1169                                               const char *dev, uint16 vuid,
1170                                               NTSTATUS *status)
1171 {
1172         connection_struct *conn = NULL;
1173         
1174         conn = make_connection(service_in, password, dev, vuid, status);
1175         
1176         /*
1177          * make_connection() does not change the directory for us any more
1178          * so we have to do it as a separate step  --jerry
1179          */
1180          
1181         if ( conn && vfs_ChDir(conn,conn->connectpath) != 0 ) {
1182                 DEBUG(0,("move_driver_to_download_area: Can't change "
1183                          "directory to %s for [print$] (%s)\n",
1184                          conn->connectpath,strerror(errno)));
1185                 yield_connection(conn, lp_servicename(SNUM(conn)));
1186                 conn_free(conn);
1187                 *status = NT_STATUS_UNSUCCESSFUL;
1188                 return NULL;
1189         }
1190         
1191         return conn;
1192 }
1193
1194 /****************************************************************************
1195  Make a connection to a service.
1196  *
1197  * @param service 
1198 ****************************************************************************/
1199
1200 connection_struct *make_connection(const char *service_in, DATA_BLOB password, 
1201                                    const char *pdev, uint16 vuid,
1202                                    NTSTATUS *status)
1203 {
1204         uid_t euid;
1205         user_struct *vuser = NULL;
1206         fstring service;
1207         fstring dev;
1208         int snum = -1;
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(), 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 }