source: branches/samba-3.2.x/source/smbd/service.c@ 234

Last change on this file since 234 was 232, checked in by Herwig Bauernfeind, 16 years ago

Update 3.2 branch to 3.2.8

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