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