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