Replace find_forced_user by a direct call to make_serverinfo_from_username
[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 /*
527  * Go through lookup_name etc to find the force'd group.  
528  *
529  * Create a new token from src_token, replacing the primary group sid with the
530  * one found.
531  */
532
533 static NTSTATUS find_forced_group(bool force_user,
534                                   int snum, const char *username,
535                                   DOM_SID *pgroup_sid,
536                                   gid_t *pgid)
537 {
538         NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
539         TALLOC_CTX *frame = talloc_stackframe();
540         DOM_SID group_sid;
541         enum lsa_SidType type;
542         char *groupname;
543         bool user_must_be_member = False;
544         gid_t gid;
545
546         ZERO_STRUCTP(pgroup_sid);
547         *pgid = (gid_t)-1;
548
549         groupname = talloc_strdup(talloc_tos(), lp_force_group(snum));
550         if (groupname == NULL) {
551                 DEBUG(1, ("talloc_strdup failed\n"));
552                 result = NT_STATUS_NO_MEMORY;
553                 goto done;
554         }
555
556         if (groupname[0] == '+') {
557                 user_must_be_member = True;
558                 groupname += 1;
559         }
560
561         groupname = talloc_string_sub(talloc_tos(), groupname,
562                                       "%S", lp_servicename(snum));
563
564         if (!lookup_name_smbconf(talloc_tos(), groupname,
565                          LOOKUP_NAME_ALL|LOOKUP_NAME_GROUP,
566                          NULL, NULL, &group_sid, &type)) {
567                 DEBUG(10, ("lookup_name_smbconf(%s) failed\n",
568                            groupname));
569                 goto done;
570         }
571
572         if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
573             (type != SID_NAME_WKN_GRP)) {
574                 DEBUG(10, ("%s is a %s, not a group\n", groupname,
575                            sid_type_lookup(type)));
576                 goto done;
577         }
578
579         if (!sid_to_gid(&group_sid, &gid)) {
580                 DEBUG(10, ("sid_to_gid(%s) for %s failed\n",
581                            sid_string_dbg(&group_sid), groupname));
582                 goto done;
583         }
584
585         /*
586          * If the user has been forced and the forced group starts with a '+',
587          * then we only set the group to be the forced group if the forced
588          * user is a member of that group.  Otherwise, the meaning of the '+'
589          * would be ignored.
590          */
591
592         if (force_user && user_must_be_member) {
593                 if (user_in_group_sid(username, &group_sid)) {
594                         sid_copy(pgroup_sid, &group_sid);
595                         *pgid = gid;
596                         DEBUG(3,("Forced group %s for member %s\n",
597                                  groupname, username));
598                 } else {
599                         DEBUG(0,("find_forced_group: forced user %s is not a member "
600                                 "of forced group %s. Disallowing access.\n",
601                                 username, groupname ));
602                         result = NT_STATUS_MEMBER_NOT_IN_GROUP;
603                         goto done;
604                 }
605         } else {
606                 sid_copy(pgroup_sid, &group_sid);
607                 *pgid = gid;
608                 DEBUG(3,("Forced group %s\n", groupname));
609         }
610
611         result = NT_STATUS_OK;
612  done:
613         TALLOC_FREE(frame);
614         return result;
615 }
616
617 /****************************************************************************
618   Create an auth_serversupplied_info structure for a connection_struct
619 ****************************************************************************/
620
621 static NTSTATUS create_connection_server_info(TALLOC_CTX *mem_ctx, int snum,
622                                               struct auth_serversupplied_info *vuid_serverinfo,
623                                               DATA_BLOB password,
624                                               struct auth_serversupplied_info **presult)
625 {
626         if (lp_guest_only(snum)) {
627                 return make_server_info_guest(mem_ctx, presult);
628         }
629
630         if (vuid_serverinfo != NULL) {
631
632                 struct auth_serversupplied_info *result;
633
634                 /*
635                  * This is the normal security != share case where we have a
636                  * valid vuid from the session setup.                 */
637
638                 if (vuid_serverinfo->guest) {
639                         if (!lp_guest_ok(snum)) {
640                                 DEBUG(2, ("guest user (from session setup) "
641                                           "not permitted to access this share "
642                                           "(%s)\n", lp_servicename(snum)));
643                                 return NT_STATUS_ACCESS_DENIED;
644                         }
645                 } else {
646                         if (!user_ok_token(vuid_serverinfo->unix_name,
647                                            vuid_serverinfo->ptok, snum)) {
648                                 DEBUG(2, ("user '%s' (from session setup) not "
649                                           "permitted to access this share "
650                                           "(%s)\n",
651                                           vuid_serverinfo->unix_name,
652                                           lp_servicename(snum)));
653                                 return NT_STATUS_ACCESS_DENIED;
654                         }
655                 }
656
657                 result = copy_serverinfo(mem_ctx, vuid_serverinfo);
658                 if (result == NULL) {
659                         return NT_STATUS_NO_MEMORY;
660                 }
661
662                 *presult = result;
663                 return NT_STATUS_OK;
664         }
665
666         if (lp_security() == SEC_SHARE) {
667
668                 fstring user;
669                 bool guest;
670
671                 /* add the sharename as a possible user name if we
672                    are in share mode security */
673
674                 add_session_user(lp_servicename(snum));
675
676                 /* shall we let them in? */
677
678                 if (!authorise_login(snum,user,password,&guest)) {
679                         DEBUG( 2, ( "Invalid username/password for [%s]\n",
680                                     lp_servicename(snum)) );
681                         return NT_STATUS_WRONG_PASSWORD;
682                 }
683
684                 return make_serverinfo_from_username(mem_ctx, user, guest,
685                                                      presult);
686         }
687
688         DEBUG(0, ("invalid VUID (vuser) but not in security=share\n"));
689         return NT_STATUS_ACCESS_DENIED;
690 }
691
692
693 /****************************************************************************
694   Make a connection, given the snum to connect to, and the vuser of the
695   connecting user if appropriate.
696 ****************************************************************************/
697
698 static connection_struct *make_connection_snum(int snum, user_struct *vuser,
699                                                DATA_BLOB password, 
700                                                const char *pdev,
701                                                NTSTATUS *pstatus)
702 {
703         connection_struct *conn;
704         SMB_STRUCT_STAT st;
705         fstring dev;
706         int ret;
707         char addr[INET6_ADDRSTRLEN];
708         bool on_err_call_dis_hook = false;
709         NTSTATUS status;
710
711         fstrcpy(dev, pdev);
712         SET_STAT_INVALID(st);
713
714         if (NT_STATUS_IS_ERR(*pstatus = share_sanity_checks(snum, dev))) {
715                 return NULL;
716         }       
717
718         conn = conn_new();
719         if (!conn) {
720                 DEBUG(0,("Couldn't find free connection.\n"));
721                 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
722                 return NULL;
723         }
724
725         conn->params->service = snum;
726         conn->nt_user_token = NULL;
727
728         status = create_connection_server_info(
729                 conn, snum, vuser ? vuser->server_info : NULL, password,
730                 &conn->server_info);
731
732         if (!NT_STATUS_IS_OK(status)) {
733                 DEBUG(0, ("create_connection_server_info failed: %s\n",
734                           nt_errstr(status)));
735                 *pstatus = status;
736                 conn_free(conn);
737                 return NULL;
738         }
739
740         if ((lp_guest_only(snum)) || (lp_security() == SEC_SHARE)) {
741                 conn->force_user = true;
742         }
743
744
745         add_session_user(conn->server_info->unix_name);
746
747         safe_strcpy(conn->client_address,
748                         client_addr(get_client_fd(),addr,sizeof(addr)), 
749                         sizeof(conn->client_address)-1);
750         conn->num_files_open = 0;
751         conn->lastused = conn->lastused_count = time(NULL);
752         conn->used = True;
753         conn->printer = (strncmp(dev,"LPT",3) == 0);
754         conn->ipc = ( (strncmp(dev,"IPC",3) == 0) ||
755                       ( lp_enable_asu_support() && strequal(dev,"ADMIN$")) );
756         conn->dirptr = NULL;
757
758         /* Case options for the share. */
759         if (lp_casesensitive(snum) == Auto) {
760                 /* We will be setting this per packet. Set to be case
761                  * insensitive for now. */
762                 conn->case_sensitive = False;
763         } else {
764                 conn->case_sensitive = (bool)lp_casesensitive(snum);
765         }
766
767         conn->case_preserve = lp_preservecase(snum);
768         conn->short_case_preserve = lp_shortpreservecase(snum);
769
770         conn->encrypt_level = lp_smb_encrypt(snum);
771
772         conn->veto_list = NULL;
773         conn->hide_list = NULL;
774         conn->veto_oplock_list = NULL;
775         conn->aio_write_behind_list = NULL;
776         string_set(&conn->dirpath,"");
777
778         conn->read_only = lp_readonly(SNUM(conn));
779         conn->admin_user = False;
780
781         /*
782          * If force user is true, then store the given userid and the gid of
783          * the user we're forcing.
784          * For auxiliary groups see below.
785          */
786         
787         if (*lp_force_user(snum)) {
788                 char *fuser;
789                 struct auth_serversupplied_info *forced_serverinfo;
790
791                 fuser = talloc_string_sub(conn, lp_force_user(snum), "%S",
792                                           lp_servicename(snum));
793                 if (fuser == NULL) {
794                         conn_free(conn);
795                         *pstatus = NT_STATUS_NO_MEMORY;
796                         return NULL;
797                 }
798
799                 status = make_serverinfo_from_username(
800                         conn, fuser, conn->server_info->guest,
801                         &forced_serverinfo);
802                 if (!NT_STATUS_IS_OK(status)) {
803                         conn_free(conn);
804                         *pstatus = status;
805                         return NULL;
806                 }
807
808                 TALLOC_FREE(conn->server_info);
809                 conn->server_info = forced_serverinfo;
810
811                 conn->force_user = True;
812                 DEBUG(3,("Forced user %s\n", fuser));
813         }
814
815         conn->vuid = (vuser != NULL) ? vuser->vuid : UID_FIELD_INVALID;
816
817         conn->uid = conn->server_info->uid;
818         conn->gid = conn->server_info->gid;
819         string_set(&conn->user, conn->server_info->unix_name);
820
821         /*
822          * If force group is true, then override
823          * any groupid stored for the connecting user.
824          */
825         
826         if (*lp_force_group(snum)) {
827                 DOM_SID group_sid;
828
829                 status = find_forced_group(conn->force_user, snum,
830                                            conn->user,
831                                            &group_sid, &conn->gid);
832                 if (!NT_STATUS_IS_OK(status)) {
833                         conn_free(conn);
834                         *pstatus = status;
835                         return NULL;
836                 }
837
838                 if ((conn->nt_user_token == NULL) && (vuser != NULL)) {
839
840                         /* Not force user and not security=share, but force
841                          * group. vuser has a token to copy */
842                         
843                         conn->nt_user_token = dup_nt_token(
844                                 NULL, vuser->server_info->ptok);
845                         if (conn->nt_user_token == NULL) {
846                                 DEBUG(0, ("dup_nt_token failed\n"));
847                                 conn_free(conn);
848                                 *pstatus = NT_STATUS_NO_MEMORY;
849                                 return NULL;
850                         }
851                 }
852
853                 /* If conn->nt_user_token is still NULL, we have
854                  * security=share. This means ignore the SID, as we had no
855                  * vuser to copy from */
856
857                 if (conn->nt_user_token != NULL) {
858                         /* Overwrite the primary group sid */
859                         sid_copy(&conn->nt_user_token->user_sids[1],
860                                  &group_sid);
861
862                 }
863         }
864
865         if (conn->nt_user_token != NULL) {
866                 size_t i;
867
868                 /* We have a share-specific token from force [user|group].
869                  * This means we have to create the list of unix groups from
870                  * the list of sids. */
871
872                 conn->ngroups = 0;
873                 conn->groups = NULL;
874
875                 for (i=0; i<conn->nt_user_token->num_sids; i++) {
876                         gid_t gid;
877                         DOM_SID *sid = &conn->nt_user_token->user_sids[i];
878
879                         if (!sid_to_gid(sid, &gid)) {
880                                 DEBUG(10, ("Could not convert SID %s to gid, "
881                                            "ignoring it\n",
882                                            sid_string_dbg(sid)));
883                                 continue;
884                         }
885                         if (!add_gid_to_array_unique(conn, gid, &conn->groups,
886                                                 &conn->ngroups)) {
887                                 DEBUG(0, ("add_gid_to_array_unique failed\n"));
888                                 conn_free(conn);
889                                 *pstatus = NT_STATUS_NO_MEMORY;
890                                 return NULL;
891                         }
892                 }
893         }
894
895         {
896                 char *s = talloc_sub_advanced(talloc_tos(),
897                                         lp_servicename(SNUM(conn)), conn->user,
898                                         conn->connectpath, conn->gid,
899                                         get_current_username(),
900                                         current_user_info.domain,
901                                         lp_pathname(snum));
902                 if (!s) {
903                         conn_free(conn);
904                         *pstatus = NT_STATUS_NO_MEMORY;
905                         return NULL;
906                 }
907
908                 if (!set_conn_connectpath(conn,s)) {
909                         TALLOC_FREE(s);
910                         conn_free(conn);
911                         *pstatus = NT_STATUS_NO_MEMORY;
912                         return NULL;
913                 }
914                 DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
915                          lp_servicename(snum)));
916                 TALLOC_FREE(s);
917         }
918
919         /*
920          * New code to check if there's a share security descripter
921          * added from NT server manager. This is done after the
922          * smb.conf checks are done as we need a uid and token. JRA.
923          *
924          */
925
926         {
927                 bool can_write = False;
928                 NT_USER_TOKEN *token = conn->nt_user_token ?
929                         conn->nt_user_token :
930                         (vuser ? vuser->server_info->ptok : NULL);
931
932                 /*
933                  * I don't believe this can happen. But the
934                  * logic above is convoluted enough to confuse
935                  * automated checkers, so be sure. JRA.
936                  */
937
938                 if (token == NULL) {
939                         DEBUG(0,("make_connection: connection to %s "
940                                  "denied due to missing "
941                                  "NT token.\n",
942                                   lp_servicename(snum)));
943                         conn_free(conn);
944                         *pstatus = NT_STATUS_ACCESS_DENIED;
945                         return NULL;
946                 }
947
948                 can_write = share_access_check(token,
949                                                     lp_servicename(snum),
950                                                     FILE_WRITE_DATA);
951
952                 if (!can_write) {
953                         if (!share_access_check(token,
954                                                 lp_servicename(snum),
955                                                 FILE_READ_DATA)) {
956                                 /* No access, read or write. */
957                                 DEBUG(0,("make_connection: connection to %s "
958                                          "denied due to security "
959                                          "descriptor.\n",
960                                           lp_servicename(snum)));
961                                 conn_free(conn);
962                                 *pstatus = NT_STATUS_ACCESS_DENIED;
963                                 return NULL;
964                         } else {
965                                 conn->read_only = True;
966                         }
967                 }
968         }
969         /* Initialise VFS function pointers */
970
971         if (!smbd_vfs_init(conn)) {
972                 DEBUG(0, ("vfs_init failed for service %s\n",
973                           lp_servicename(snum)));
974                 conn_free(conn);
975                 *pstatus = NT_STATUS_BAD_NETWORK_NAME;
976                 return NULL;
977         }
978
979         /*
980          * If widelinks are disallowed we need to canonicalise the connect
981          * path here to ensure we don't have any symlinks in the
982          * connectpath. We will be checking all paths on this connection are
983          * below this directory. We must do this after the VFS init as we
984          * depend on the realpath() pointer in the vfs table. JRA.
985          */
986         if (!lp_widelinks(snum)) {
987                 if (!canonicalize_connect_path(conn)) {
988                         DEBUG(0, ("canonicalize_connect_path failed "
989                         "for service %s, path %s\n",
990                                 lp_servicename(snum),
991                                 conn->connectpath));
992                         conn_free(conn);
993                         *pstatus = NT_STATUS_BAD_NETWORK_NAME;
994                         return NULL;
995                 }
996         }
997
998         if ((!conn->printer) && (!conn->ipc)) {
999                 conn->notify_ctx = notify_init(conn, server_id_self(),
1000                                                smbd_messaging_context(),
1001                                                smbd_event_context(),
1002                                                conn);
1003         }
1004
1005 /* ROOT Activities: */  
1006         /*
1007          * Enforce the max connections parameter.
1008          */
1009
1010         if ((lp_max_connections(snum) > 0)
1011             && (count_current_connections(lp_servicename(SNUM(conn)), True) >=
1012                 lp_max_connections(snum))) {
1013
1014                 DEBUG(1, ("Max connections (%d) exceeded for %s\n",
1015                           lp_max_connections(snum), lp_servicename(snum)));
1016                 conn_free(conn);
1017                 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
1018                 return NULL;
1019         }  
1020
1021         /*
1022          * Get us an entry in the connections db
1023          */
1024         if (!claim_connection(conn, lp_servicename(snum), 0)) {
1025                 DEBUG(1, ("Could not store connections entry\n"));
1026                 conn_free(conn);
1027                 *pstatus = NT_STATUS_INTERNAL_DB_ERROR;
1028                 return NULL;
1029         }  
1030
1031         /* Preexecs are done here as they might make the dir we are to ChDir
1032          * to below */
1033         /* execute any "root preexec = " line */
1034         if (*lp_rootpreexec(snum)) {
1035                 char *cmd = talloc_sub_advanced(talloc_tos(),
1036                                         lp_servicename(SNUM(conn)), conn->user,
1037                                         conn->connectpath, conn->gid,
1038                                         get_current_username(),
1039                                         current_user_info.domain,
1040                                         lp_rootpreexec(snum));
1041                 DEBUG(5,("cmd=%s\n",cmd));
1042                 ret = smbrun(cmd,NULL);
1043                 TALLOC_FREE(cmd);
1044                 if (ret != 0 && lp_rootpreexec_close(snum)) {
1045                         DEBUG(1,("root preexec gave %d - failing "
1046                                  "connection\n", ret));
1047                         yield_connection(conn, lp_servicename(snum));
1048                         conn_free(conn);
1049                         *pstatus = NT_STATUS_ACCESS_DENIED;
1050                         return NULL;
1051                 }
1052         }
1053
1054 /* USER Activites: */
1055         if (!change_to_user(conn, conn->vuid)) {
1056                 /* No point continuing if they fail the basic checks */
1057                 DEBUG(0,("Can't become connected user!\n"));
1058                 yield_connection(conn, lp_servicename(snum));
1059                 conn_free(conn);
1060                 *pstatus = NT_STATUS_LOGON_FAILURE;
1061                 return NULL;
1062         }
1063
1064         /* Remember that a different vuid can connect later without these
1065          * checks... */
1066         
1067         /* Preexecs are done here as they might make the dir we are to ChDir
1068          * to below */
1069
1070         /* execute any "preexec = " line */
1071         if (*lp_preexec(snum)) {
1072                 char *cmd = talloc_sub_advanced(talloc_tos(),
1073                                         lp_servicename(SNUM(conn)), conn->user,
1074                                         conn->connectpath, conn->gid,
1075                                         get_current_username(),
1076                                         current_user_info.domain,
1077                                         lp_preexec(snum));
1078                 ret = smbrun(cmd,NULL);
1079                 TALLOC_FREE(cmd);
1080                 if (ret != 0 && lp_preexec_close(snum)) {
1081                         DEBUG(1,("preexec gave %d - failing connection\n",
1082                                  ret));
1083                         *pstatus = NT_STATUS_ACCESS_DENIED;
1084                         goto err_root_exit;
1085                 }
1086         }
1087
1088 #ifdef WITH_FAKE_KASERVER
1089         if (lp_afs_share(snum)) {
1090                 afs_login(conn);
1091         }
1092 #endif
1093         
1094         /* Add veto/hide lists */
1095         if (!IS_IPC(conn) && !IS_PRINT(conn)) {
1096                 set_namearray( &conn->veto_list, lp_veto_files(snum));
1097                 set_namearray( &conn->hide_list, lp_hide_files(snum));
1098                 set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(snum));
1099         }
1100         
1101         /* Invoke VFS make connection hook - do this before the VFS_STAT call
1102            to allow any filesystems needing user credentials to initialize
1103            themselves. */
1104
1105         if (SMB_VFS_CONNECT(conn, lp_servicename(snum), conn->user) < 0) {
1106                 DEBUG(0,("make_connection: VFS make connection failed!\n"));
1107                 *pstatus = NT_STATUS_UNSUCCESSFUL;
1108                 goto err_root_exit;
1109         }
1110
1111         /* Any error exit after here needs to call the disconnect hook. */
1112         on_err_call_dis_hook = true;
1113
1114         /* win2000 does not check the permissions on the directory
1115            during the tree connect, instead relying on permission
1116            check during individual operations. To match this behaviour
1117            I have disabled this chdir check (tridge) */
1118         /* the alternative is just to check the directory exists */
1119         if ((ret = SMB_VFS_STAT(conn, conn->connectpath, &st)) != 0 ||
1120             !S_ISDIR(st.st_mode)) {
1121                 if (ret == 0 && !S_ISDIR(st.st_mode)) {
1122                         DEBUG(0,("'%s' is not a directory, when connecting to "
1123                                  "[%s]\n", conn->connectpath,
1124                                  lp_servicename(snum)));
1125                 } else {
1126                         DEBUG(0,("'%s' does not exist or permission denied "
1127                                  "when connecting to [%s] Error was %s\n",
1128                                  conn->connectpath, lp_servicename(snum),
1129                                  strerror(errno) ));
1130                 }
1131                 *pstatus = NT_STATUS_BAD_NETWORK_NAME;
1132                 goto err_root_exit;
1133         }
1134
1135         string_set(&conn->origpath,conn->connectpath);
1136
1137 #if SOFTLINK_OPTIMISATION
1138         /* resolve any soft links early if possible */
1139         if (vfs_ChDir(conn,conn->connectpath) == 0) {
1140                 TALLOC_CTX *ctx = talloc_tos();
1141                 char *s = vfs_GetWd(ctx,s);
1142                 if (!s) {
1143                         *status = map_nt_error_from_unix(errno);
1144                         goto err_root_exit;
1145                 }
1146                 if (!set_conn_connectpath(conn,s)) {
1147                         *status = NT_STATUS_NO_MEMORY;
1148                         goto err_root_exit;
1149                 }
1150                 vfs_ChDir(conn,conn->connectpath);
1151         }
1152 #endif
1153
1154         /* Figure out the characteristics of the underlying filesystem. This
1155          * assumes that all the filesystem mounted withing a share path have
1156          * the same characteristics, which is likely but not guaranteed.
1157          */
1158
1159         conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn);
1160
1161         /*
1162          * Print out the 'connected as' stuff here as we need
1163          * to know the effective uid and gid we will be using
1164          * (at least initially).
1165          */
1166
1167         if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
1168                 dbgtext( "%s (%s) ", get_remote_machine_name(),
1169                          conn->client_address );
1170                 dbgtext( "%s", srv_is_signing_active() ? "signed " : "");
1171                 dbgtext( "connect to service %s ", lp_servicename(snum) );
1172                 dbgtext( "initially as user %s ", conn->user );
1173                 dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
1174                 dbgtext( "(pid %d)\n", (int)sys_getpid() );
1175         }
1176
1177         /* we've finished with the user stuff - go back to root */
1178         change_to_root_user();
1179         return(conn);
1180
1181   err_root_exit:
1182
1183         change_to_root_user();
1184         if (on_err_call_dis_hook) {
1185                 /* Call VFS disconnect hook */
1186                 SMB_VFS_DISCONNECT(conn);
1187         }
1188         yield_connection(conn, lp_servicename(snum));
1189         conn_free(conn);
1190         return NULL;
1191 }
1192
1193 /***************************************************************************************
1194  Simple wrapper function for make_connection() to include a call to 
1195  vfs_chdir()
1196  **************************************************************************************/
1197  
1198 connection_struct *make_connection_with_chdir(const char *service_in,
1199                                               DATA_BLOB password, 
1200                                               const char *dev, uint16 vuid,
1201                                               NTSTATUS *status)
1202 {
1203         connection_struct *conn = NULL;
1204         
1205         conn = make_connection(service_in, password, dev, vuid, status);
1206         
1207         /*
1208          * make_connection() does not change the directory for us any more
1209          * so we have to do it as a separate step  --jerry
1210          */
1211          
1212         if ( conn && vfs_ChDir(conn,conn->connectpath) != 0 ) {
1213                 DEBUG(0,("move_driver_to_download_area: Can't change "
1214                          "directory to %s for [print$] (%s)\n",
1215                          conn->connectpath,strerror(errno)));
1216                 yield_connection(conn, lp_servicename(SNUM(conn)));
1217                 conn_free(conn);
1218                 *status = NT_STATUS_UNSUCCESSFUL;
1219                 return NULL;
1220         }
1221         
1222         return conn;
1223 }
1224
1225 /****************************************************************************
1226  Make a connection to a service.
1227  *
1228  * @param service 
1229 ****************************************************************************/
1230
1231 connection_struct *make_connection(const char *service_in, DATA_BLOB password, 
1232                                    const char *pdev, uint16 vuid,
1233                                    NTSTATUS *status)
1234 {
1235         uid_t euid;
1236         user_struct *vuser = NULL;
1237         fstring service;
1238         fstring dev;
1239         int snum = -1;
1240         char addr[INET6_ADDRSTRLEN];
1241
1242         fstrcpy(dev, pdev);
1243
1244         /* This must ONLY BE CALLED AS ROOT. As it exits this function as
1245          * root. */
1246         if (!non_root_mode() && (euid = geteuid()) != 0) {
1247                 DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot "
1248                          "(%u)\n", (unsigned int)euid ));
1249                 smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
1250         }
1251
1252         if (conn_num_open() > 2047) {
1253                 *status = NT_STATUS_INSUFF_SERVER_RESOURCES;
1254                 return NULL;
1255         }
1256
1257         if(lp_security() != SEC_SHARE) {
1258                 vuser = get_valid_user_struct(vuid);
1259                 if (!vuser) {
1260                         DEBUG(1,("make_connection: refusing to connect with "
1261                                  "no session setup\n"));
1262                         *status = NT_STATUS_ACCESS_DENIED;
1263                         return NULL;
1264                 }
1265         }
1266
1267         /* Logic to try and connect to the correct [homes] share, preferably
1268            without too many getpwnam() lookups.  This is particulary nasty for
1269            winbind usernames, where the share name isn't the same as unix
1270            username.
1271
1272            The snum of the homes share is stored on the vuser at session setup
1273            time.
1274         */
1275
1276         if (strequal(service_in,HOMES_NAME)) {
1277                 if(lp_security() != SEC_SHARE) {
1278                         DATA_BLOB no_pw = data_blob_null;
1279                         if (vuser->homes_snum == -1) {
1280                                 DEBUG(2, ("[homes] share not available for "
1281                                           "this user because it was not found "
1282                                           "or created at session setup "
1283                                           "time\n"));
1284                                 *status = NT_STATUS_BAD_NETWORK_NAME;
1285                                 return NULL;
1286                         }
1287                         DEBUG(5, ("making a connection to [homes] service "
1288                                   "created at session setup time\n"));
1289                         return make_connection_snum(vuser->homes_snum,
1290                                                     vuser, no_pw, 
1291                                                     dev, status);
1292                 } else {
1293                         /* Security = share. Try with
1294                          * current_user_info.smb_name as the username.  */
1295                         if (*current_user_info.smb_name) {
1296                                 fstring unix_username;
1297                                 fstrcpy(unix_username,
1298                                         current_user_info.smb_name);
1299                                 map_username(unix_username);
1300                                 snum = find_service(unix_username);
1301                         } 
1302                         if (snum != -1) {
1303                                 DEBUG(5, ("making a connection to 'homes' "
1304                                           "service %s based on "
1305                                           "security=share\n", service_in));
1306                                 return make_connection_snum(snum, NULL,
1307                                                             password,
1308                                                             dev, status);
1309                         }
1310                 }
1311         } else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1)
1312                    && strequal(service_in,
1313                                lp_servicename(vuser->homes_snum))) {
1314                 DATA_BLOB no_pw = data_blob_null;
1315                 DEBUG(5, ("making a connection to 'homes' service [%s] "
1316                           "created at session setup time\n", service_in));
1317                 return make_connection_snum(vuser->homes_snum,
1318                                             vuser, no_pw, 
1319                                             dev, status);
1320         }
1321         
1322         fstrcpy(service, service_in);
1323
1324         strlower_m(service);
1325
1326         snum = find_service(service);
1327
1328         if (snum < 0) {
1329                 if (strequal(service,"IPC$") ||
1330                     (lp_enable_asu_support() && strequal(service,"ADMIN$"))) {
1331                         DEBUG(3,("refusing IPC connection to %s\n", service));
1332                         *status = NT_STATUS_ACCESS_DENIED;
1333                         return NULL;
1334                 }
1335
1336                 DEBUG(0,("%s (%s) couldn't find service %s\n",
1337                         get_remote_machine_name(),
1338                         client_addr(get_client_fd(),addr,sizeof(addr)),
1339                         service));
1340                 *status = NT_STATUS_BAD_NETWORK_NAME;
1341                 return NULL;
1342         }
1343
1344         /* Handle non-Dfs clients attempting connections to msdfs proxy */
1345         if (lp_host_msdfs() && (*lp_msdfs_proxy(snum) != '\0'))  {
1346                 DEBUG(3, ("refusing connection to dfs proxy share '%s' "
1347                           "(pointing to %s)\n", 
1348                         service, lp_msdfs_proxy(snum)));
1349                 *status = NT_STATUS_BAD_NETWORK_NAME;
1350                 return NULL;
1351         }
1352
1353         DEBUG(5, ("making a connection to 'normal' service %s\n", service));
1354
1355         return make_connection_snum(snum, vuser,
1356                                     password,
1357                                     dev, status);
1358 }
1359
1360 /****************************************************************************
1361  Close a cnum.
1362 ****************************************************************************/
1363
1364 void close_cnum(connection_struct *conn, uint16 vuid)
1365 {
1366         if (IS_IPC(conn)) {
1367                 pipe_close_conn(conn);
1368         } else {
1369                 file_close_conn(conn);
1370                 dptr_closecnum(conn);
1371         }
1372
1373         change_to_root_user();
1374
1375         DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
1376                                  get_remote_machine_name(),
1377                                  conn->client_address,
1378                                  lp_servicename(SNUM(conn))));
1379
1380         /* Call VFS disconnect hook */    
1381         SMB_VFS_DISCONNECT(conn);
1382
1383         yield_connection(conn, lp_servicename(SNUM(conn)));
1384
1385         /* make sure we leave the directory available for unmount */
1386         vfs_ChDir(conn, "/");
1387
1388         /* execute any "postexec = " line */
1389         if (*lp_postexec(SNUM(conn)) && 
1390             change_to_user(conn, vuid))  {
1391                 char *cmd = talloc_sub_advanced(talloc_tos(),
1392                                         lp_servicename(SNUM(conn)), conn->user,
1393                                         conn->connectpath, conn->gid,
1394                                         get_current_username(),
1395                                         current_user_info.domain,
1396                                         lp_postexec(SNUM(conn)));
1397                 smbrun(cmd,NULL);
1398                 TALLOC_FREE(cmd);
1399                 change_to_root_user();
1400         }
1401
1402         change_to_root_user();
1403         /* execute any "root postexec = " line */
1404         if (*lp_rootpostexec(SNUM(conn)))  {
1405                 char *cmd = talloc_sub_advanced(talloc_tos(),
1406                                         lp_servicename(SNUM(conn)), conn->user,
1407                                         conn->connectpath, conn->gid,
1408                                         get_current_username(),
1409                                         current_user_info.domain,
1410                                         lp_rootpostexec(SNUM(conn)));
1411                 smbrun(cmd,NULL);
1412                 TALLOC_FREE(cmd);
1413         }
1414
1415         conn_free(conn);
1416 }