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