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