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

Last change on this file since 205 was 137, checked in by Paul Smedley, 17 years ago

Update trunk to 3.2.0rc2

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