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