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