2 Unix SMB/CIFS implementation.
3 service (connection) opening and closing
4 Copyright (C) Andrew Tridgell 1992-1998
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 2 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 extern userdom_struct current_user_info
;
25 static BOOL
canonicalize_path(connection_struct
*conn
, pstring path
)
27 #ifdef REALPATH_TAKES_NULL
28 char *resolved_name
= SMB_VFS_REALPATH(conn
,path
,NULL
);
32 pstrcpy(path
, resolved_name
);
33 SAFE_FREE(resolved_name
);
37 char resolved_name_buf
[PATH_MAX
+1];
39 pstring resolved_name_buf
;
41 char *resolved_name
= SMB_VFS_REALPATH(conn
,path
,resolved_name_buf
);
45 pstrcpy(path
, resolved_name
);
47 #endif /* REALPATH_TAKES_NULL */
50 /****************************************************************************
51 Ensure when setting connectpath it is a canonicalized (no ./ // or ../)
52 absolute path stating in / and not ending in /.
53 Observent people will notice a similarity between this and check_path_syntax :-).
54 ****************************************************************************/
56 void set_conn_connectpath(connection_struct
*conn
, const pstring connectpath
)
60 const char *s
= connectpath
;
61 BOOL start_of_name_component
= True
;
63 *d
++ = '/'; /* Always start with root. */
67 /* Eat multiple '/' */
71 if ((d
> destname
+ 1) && (*s
!= '\0')) {
74 start_of_name_component
= True
;
78 if (start_of_name_component
) {
79 if ((s
[0] == '.') && (s
[1] == '.') && (s
[2] == '/' || s
[2] == '\0')) {
80 /* Uh oh - "/../" or "/..\0" ! */
82 /* Go past the ../ or .. */
86 s
+= 2; /* Go past the .. */
89 /* If we just added a '/' - delete it */
90 if ((d
> destname
) && (*(d
-1) == '/')) {
95 /* Are we at the start ? Can't go back further if so. */
97 *d
++ = '/'; /* Can't delete root */
100 /* Go back one level... */
101 /* Decrement d first as d points to the *next* char to write into. */
102 for (d
--; d
> destname
; d
--) {
107 /* We're still at the start of a name component, just the previous one. */
109 } else if ((s
[0] == '.') && ((s
[1] == '\0') || s
[1] == '/')) {
110 /* Component of pathname can't be "." only - skip the '.' . */
124 /* Get the size of the next MB character. */
125 next_codepoint(s
,&siz
);
146 start_of_name_component
= False
;
150 /* And must not end in '/' */
151 if (d
> destname
+ 1 && (*(d
-1) == '/')) {
155 DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
156 lp_servicename(SNUM(conn
)), destname
));
158 string_set(&conn
->connectpath
, destname
);
161 /****************************************************************************
162 Load parameters specific to a connection/service.
163 ****************************************************************************/
165 BOOL
set_current_service(connection_struct
*conn
, uint16 flags
, BOOL do_chdir
)
167 static connection_struct
*last_conn
;
168 static uint16 last_flags
;
176 conn
->lastused_count
++;
181 vfs_ChDir(conn
,conn
->connectpath
) != 0 &&
182 vfs_ChDir(conn
,conn
->origpath
) != 0) {
183 DEBUG(0,("chdir (%s) failed\n",
188 if ((conn
== last_conn
) && (last_flags
== flags
)) {
195 /* Obey the client case sensitivity requests - only for clients that support it. */
196 switch (lp_casesensitive(snum
)) {
199 /* We need this uglyness due to DOS/Win9x clients that lie about case insensitivity. */
200 enum remote_arch_types ra_type
= get_remote_arch();
201 if ((ra_type
!= RA_SAMBA
) && (ra_type
!= RA_CIFSFS
)) {
202 /* Client can't support per-packet case sensitive pathnames. */
203 conn
->case_sensitive
= False
;
205 conn
->case_sensitive
= !(flags
& FLAG_CASELESS_PATHNAMES
);
210 conn
->case_sensitive
= True
;
213 conn
->case_sensitive
= False
;
219 /****************************************************************************
220 Add a home service. Returns the new service number or -1 if fail.
221 ****************************************************************************/
223 int add_home_service(const char *service
, const char *username
, const char *homedir
)
227 if (!service
|| !homedir
)
230 if ((iHomeService
= lp_servicenumber(HOMES_NAME
)) < 0)
234 * If this is a winbindd provided username, remove
235 * the domain component before adding the service.
236 * Log a warning if the "path=" parameter does not
237 * include any macros.
241 const char *p
= strchr(service
,*lp_winbind_separator());
243 /* We only want the 'user' part of the string */
249 if (!lp_add_home(service
, iHomeService
, username
, homedir
)) {
253 return lp_servicenumber(service
);
259 * Find a service entry.
261 * @param service is modified (to canonical form??)
264 int find_service(fstring service
)
268 all_string_sub(service
,"\\","/",0);
270 iService
= lp_servicenumber(service
);
272 /* now handle the special case of a home directory */
274 char *phome_dir
= get_user_home_dir(service
);
278 * Try mapping the servicename, it may
279 * be a Windows to unix mapped user name.
281 if(map_username(service
))
282 phome_dir
= get_user_home_dir(service
);
285 DEBUG(3,("checking for home directory %s gave %s\n",service
,
286 phome_dir
?phome_dir
:"(NULL)"));
288 iService
= add_home_service(service
,service
/* 'username' */, phome_dir
);
291 /* If we still don't have a service, attempt to add it as a printer. */
295 if ((iPrinterService
= lp_servicenumber(PRINTERS_NAME
)) >= 0) {
296 DEBUG(3,("checking whether %s is a valid printer name...\n", service
));
297 if (pcap_printername_ok(service
)) {
298 DEBUG(3,("%s is a valid printer name\n", service
));
299 DEBUG(3,("adding %s as a printer service\n", service
));
300 lp_add_printer(service
, iPrinterService
);
301 iService
= lp_servicenumber(service
);
303 DEBUG(0,("failed to add %s as a printer service!\n", service
));
306 DEBUG(3,("%s is not a valid printer name\n", service
));
311 /* Check for default vfs service? Unsure whether to implement this */
315 /* Is it a usershare service ? */
316 if (iService
< 0 && *lp_usershare_path()) {
317 /* Ensure the name is canonicalized. */
319 iService
= load_usershare_service(service
);
322 /* just possibly it's a default service? */
324 char *pdefservice
= lp_defaultservice();
325 if (pdefservice
&& *pdefservice
&& !strequal(pdefservice
,service
) && !strstr_m(service
,"..")) {
327 * We need to do a local copy here as lp_defaultservice()
328 * returns one of the rotating lp_string buffers that
329 * could get overwritten by the recursive find_service() call
330 * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
333 pstrcpy(defservice
, pdefservice
);
335 /* Disallow anything except explicit share names. */
336 if (strequal(defservice
,HOMES_NAME
) ||
337 strequal(defservice
, PRINTERS_NAME
) ||
338 strequal(defservice
, "IPC$")) {
342 iService
= find_service(defservice
);
344 all_string_sub(service
, "_","/",0);
345 iService
= lp_add_service(service
, iService
);
351 if (!VALID_SNUM(iService
)) {
352 DEBUG(0,("Invalid snum %d for %s\n",iService
, service
));
360 DEBUG(3,("find_service() failed to find service %s\n", service
));
366 /****************************************************************************
367 do some basic sainity checks on the share.
368 This function modifies dev, ecode.
369 ****************************************************************************/
371 static NTSTATUS
share_sanity_checks(int snum
, fstring dev
)
374 if (!lp_snum_ok(snum
) ||
375 !check_access(smbd_server_fd(),
376 lp_hostsallow(snum
), lp_hostsdeny(snum
))) {
377 return NT_STATUS_ACCESS_DENIED
;
380 if (dev
[0] == '?' || !dev
[0]) {
381 if (lp_print_ok(snum
)) {
382 fstrcpy(dev
,"LPT1:");
383 } else if (strequal(lp_fstype(snum
), "IPC")) {
392 if (lp_print_ok(snum
)) {
393 if (!strequal(dev
, "LPT1:")) {
394 return NT_STATUS_BAD_DEVICE_TYPE
;
396 } else if (strequal(lp_fstype(snum
), "IPC")) {
397 if (!strequal(dev
, "IPC")) {
398 return NT_STATUS_BAD_DEVICE_TYPE
;
400 } else if (!strequal(dev
, "A:")) {
401 return NT_STATUS_BAD_DEVICE_TYPE
;
404 /* Behave as a printer if we are supposed to */
405 if (lp_print_ok(snum
) && (strcmp(dev
, "A:") == 0)) {
406 fstrcpy(dev
, "LPT1:");
412 static NTSTATUS
find_forced_user(connection_struct
*conn
, BOOL vuser_is_guest
, fstring username
)
414 int snum
= conn
->params
->service
;
415 char *fuser
, *found_username
;
418 if (!(fuser
= talloc_string_sub(conn
->mem_ctx
, lp_force_user(snum
), "%S",
419 lp_servicename(snum
)))) {
420 return NT_STATUS_NO_MEMORY
;
423 result
= create_token_from_username(conn
->mem_ctx
, fuser
, vuser_is_guest
,
424 &conn
->uid
, &conn
->gid
, &found_username
,
425 &conn
->nt_user_token
);
426 if (!NT_STATUS_IS_OK(result
)) {
430 fstrcpy(username
, found_username
);
433 TALLOC_FREE(found_username
);
438 * Go through lookup_name etc to find the force'd group.
440 * Create a new token from src_token, replacing the primary group sid with the
444 static NTSTATUS
find_forced_group(BOOL force_user
,
445 int snum
, const char *username
,
449 NTSTATUS result
= NT_STATUS_NO_SUCH_GROUP
;
452 enum lsa_SidType type
;
454 BOOL user_must_be_member
= False
;
457 ZERO_STRUCTP(pgroup_sid
);
460 mem_ctx
= talloc_new(NULL
);
461 if (mem_ctx
== NULL
) {
462 DEBUG(0, ("talloc_new failed\n"));
463 return NT_STATUS_NO_MEMORY
;
466 groupname
= talloc_strdup(mem_ctx
, lp_force_group(snum
));
467 if (groupname
== NULL
) {
468 DEBUG(1, ("talloc_strdup failed\n"));
469 result
= NT_STATUS_NO_MEMORY
;
473 if (groupname
[0] == '+') {
474 user_must_be_member
= True
;
478 groupname
= talloc_string_sub(mem_ctx
, groupname
,
479 "%S", lp_servicename(snum
));
481 if (!lookup_name_smbconf(mem_ctx
, groupname
,
482 LOOKUP_NAME_ALL
|LOOKUP_NAME_GROUP
,
483 NULL
, NULL
, &group_sid
, &type
)) {
484 DEBUG(10, ("lookup_name_smbconf(%s) failed\n",
489 if ((type
!= SID_NAME_DOM_GRP
) && (type
!= SID_NAME_ALIAS
) &&
490 (type
!= SID_NAME_WKN_GRP
)) {
491 DEBUG(10, ("%s is a %s, not a group\n", groupname
,
492 sid_type_lookup(type
)));
496 if (!sid_to_gid(&group_sid
, &gid
)) {
497 DEBUG(10, ("sid_to_gid(%s) for %s failed\n",
498 sid_string_static(&group_sid
), groupname
));
503 * If the user has been forced and the forced group starts with a '+',
504 * then we only set the group to be the forced group if the forced
505 * user is a member of that group. Otherwise, the meaning of the '+'
509 if (force_user
&& user_must_be_member
) {
510 if (user_in_group_sid(username
, &group_sid
)) {
511 sid_copy(pgroup_sid
, &group_sid
);
513 DEBUG(3,("Forced group %s for member %s\n",
514 groupname
, username
));
516 DEBUG(0,("find_forced_group: forced user %s is not a member "
517 "of forced group %s. Disallowing access.\n",
518 username
, groupname
));
519 result
= NT_STATUS_MEMBER_NOT_IN_GROUP
;
523 sid_copy(pgroup_sid
, &group_sid
);
525 DEBUG(3,("Forced group %s\n", groupname
));
528 result
= NT_STATUS_OK
;
530 TALLOC_FREE(mem_ctx
);
534 /****************************************************************************
535 Make a connection, given the snum to connect to, and the vuser of the
536 connecting user if appropriate.
537 ****************************************************************************/
539 static connection_struct
*make_connection_snum(int snum
, user_struct
*vuser
,
544 struct passwd
*pass
= NULL
;
546 connection_struct
*conn
;
554 SET_STAT_INVALID(st
);
556 if (NT_STATUS_IS_ERR(*status
= share_sanity_checks(snum
, dev
))) {
562 DEBUG(0,("Couldn't find free connection.\n"));
563 *status
= NT_STATUS_INSUFFICIENT_RESOURCES
;
567 conn
->params
->service
= snum
;
568 conn
->nt_user_token
= NULL
;
570 if (lp_guest_only(snum
)) {
571 const char *guestname
= lp_guestaccount();
573 char *found_username
= NULL
;
576 pass
= getpwnam_alloc(NULL
, guestname
);
578 DEBUG(0,("make_connection_snum: Invalid guest "
579 "account %s??\n",guestname
));
581 *status
= NT_STATUS_NO_SUCH_USER
;
584 status2
= create_token_from_username(conn
->mem_ctx
, pass
->pw_name
, True
,
585 &conn
->uid
, &conn
->gid
,
587 &conn
->nt_user_token
);
588 if (!NT_STATUS_IS_OK(status2
)) {
594 fstrcpy(user
, found_username
);
595 string_set(&conn
->user
,user
);
596 conn
->force_user
= True
;
597 TALLOC_FREE(found_username
);
599 DEBUG(3,("Guest only user %s\n",user
));
602 if (!lp_guest_ok(snum
)) {
603 DEBUG(2, ("guest user (from session setup) "
604 "not permitted to access this share "
605 "(%s)\n", lp_servicename(snum
)));
607 *status
= NT_STATUS_ACCESS_DENIED
;
611 if (!user_ok_token(vuser
->user
.unix_name
,
612 vuser
->nt_user_token
, snum
)) {
613 DEBUG(2, ("user '%s' (from session setup) not "
614 "permitted to access this share "
615 "(%s)\n", vuser
->user
.unix_name
,
616 lp_servicename(snum
)));
618 *status
= NT_STATUS_ACCESS_DENIED
;
622 conn
->vuid
= vuser
->vuid
;
623 conn
->uid
= vuser
->uid
;
624 conn
->gid
= vuser
->gid
;
625 string_set(&conn
->user
,vuser
->user
.unix_name
);
626 fstrcpy(user
,vuser
->user
.unix_name
);
627 guest
= vuser
->guest
;
628 } else if (lp_security() == SEC_SHARE
) {
630 char *found_username
= NULL
;
632 /* add it as a possible user name if we
633 are in share mode security */
634 add_session_user(lp_servicename(snum
));
635 /* shall we let them in? */
636 if (!authorise_login(snum
,user
,password
,&guest
)) {
637 DEBUG( 2, ( "Invalid username/password for [%s]\n",
638 lp_servicename(snum
)) );
640 *status
= NT_STATUS_WRONG_PASSWORD
;
643 pass
= Get_Pwnam(user
);
644 status2
= create_token_from_username(conn
->mem_ctx
, pass
->pw_name
, True
,
645 &conn
->uid
, &conn
->gid
,
647 &conn
->nt_user_token
);
648 if (!NT_STATUS_IS_OK(status2
)) {
653 fstrcpy(user
, found_username
);
654 string_set(&conn
->user
,user
);
655 TALLOC_FREE(found_username
);
656 conn
->force_user
= True
;
658 DEBUG(0, ("invalid VUID (vuser) but not in security=share\n"));
660 *status
= NT_STATUS_ACCESS_DENIED
;
664 add_session_user(user
);
666 safe_strcpy(conn
->client_address
, client_addr(),
667 sizeof(conn
->client_address
)-1);
668 conn
->num_files_open
= 0;
669 conn
->lastused
= conn
->lastused_count
= time(NULL
);
671 conn
->printer
= (strncmp(dev
,"LPT",3) == 0);
672 conn
->ipc
= ( (strncmp(dev
,"IPC",3) == 0) ||
673 ( lp_enable_asu_support() && strequal(dev
,"ADMIN$")) );
676 /* Case options for the share. */
677 if (lp_casesensitive(snum
) == Auto
) {
678 /* We will be setting this per packet. Set to be case
679 * insensitive for now. */
680 conn
->case_sensitive
= False
;
682 conn
->case_sensitive
= (BOOL
)lp_casesensitive(snum
);
685 conn
->case_preserve
= lp_preservecase(snum
);
686 conn
->short_case_preserve
= lp_shortpreservecase(snum
);
688 conn
->veto_list
= NULL
;
689 conn
->hide_list
= NULL
;
690 conn
->veto_oplock_list
= NULL
;
691 conn
->aio_write_behind_list
= NULL
;
692 string_set(&conn
->dirpath
,"");
693 string_set(&conn
->user
,user
);
695 conn
->read_only
= lp_readonly(SNUM(conn
));
696 conn
->admin_user
= False
;
699 * If force user is true, then store the given userid and the gid of
700 * the user we're forcing.
701 * For auxiliary groups see below.
704 if (*lp_force_user(snum
)) {
707 status2
= find_forced_user(conn
,
708 (vuser
!= NULL
) && vuser
->guest
,
710 if (!NT_STATUS_IS_OK(status2
)) {
715 string_set(&conn
->user
,user
);
716 conn
->force_user
= True
;
717 DEBUG(3,("Forced user %s\n",user
));
721 * If force group is true, then override
722 * any groupid stored for the connecting user.
725 if (*lp_force_group(snum
)) {
729 status2
= find_forced_group(conn
->force_user
,
731 &group_sid
, &conn
->gid
);
732 if (!NT_STATUS_IS_OK(status2
)) {
738 if ((conn
->nt_user_token
== NULL
) && (vuser
!= NULL
)) {
740 /* Not force user and not security=share, but force
741 * group. vuser has a token to copy */
743 conn
->nt_user_token
= dup_nt_token(
744 NULL
, vuser
->nt_user_token
);
745 if (conn
->nt_user_token
== NULL
) {
746 DEBUG(0, ("dup_nt_token failed\n"));
748 *status
= NT_STATUS_NO_MEMORY
;
753 /* If conn->nt_user_token is still NULL, we have
754 * security=share. This means ignore the SID, as we had no
755 * vuser to copy from */
757 if (conn
->nt_user_token
!= NULL
) {
758 /* Overwrite the primary group sid */
759 sid_copy(&conn
->nt_user_token
->user_sids
[1],
763 conn
->force_group
= True
;
766 if (conn
->nt_user_token
!= NULL
) {
769 /* We have a share-specific token from force [user|group].
770 * This means we have to create the list of unix groups from
771 * the list of sids. */
776 for (i
=0; i
<conn
->nt_user_token
->num_sids
; i
++) {
778 DOM_SID
*sid
= &conn
->nt_user_token
->user_sids
[i
];
780 if (!sid_to_gid(sid
, &gid
)) {
781 DEBUG(10, ("Could not convert SID %s to gid, "
783 sid_string_static(sid
)));
786 if (!add_gid_to_array_unique(conn
->mem_ctx
, gid
, &conn
->groups
,
788 DEBUG(0, ("add_gid_to_array_unique failed\n"));
790 *status
= NT_STATUS_NO_MEMORY
;
798 pstrcpy(s
,lp_pathname(snum
));
799 standard_sub_advanced(lp_servicename(SNUM(conn
)), conn
->user
,
800 conn
->connectpath
, conn
->gid
,
801 get_current_username(),
802 current_user_info
.domain
,
804 set_conn_connectpath(conn
,s
);
805 DEBUG(3,("Connect path is '%s' for service [%s]\n",s
,
806 lp_servicename(snum
)));
810 * New code to check if there's a share security descripter
811 * added from NT server manager. This is done after the
812 * smb.conf checks are done as we need a uid and token. JRA.
817 BOOL can_write
= False
;
818 NT_USER_TOKEN
*token
= conn
->nt_user_token
?
819 conn
->nt_user_token
:
820 (vuser
? vuser
->nt_user_token
: NULL
);
823 * I don't believe this can happen. But the
824 * logic above is convoluted enough to confuse
825 * automated checkers, so be sure. JRA.
829 DEBUG(0,("make_connection: connection to %s "
830 "denied due to missing "
832 lp_servicename(snum
)));
834 *status
= NT_STATUS_ACCESS_DENIED
;
838 can_write
= share_access_check(token
,
839 lp_servicename(snum
),
843 if (!share_access_check(token
,
844 lp_servicename(snum
),
846 /* No access, read or write. */
847 DEBUG(0,("make_connection: connection to %s "
848 "denied due to security "
850 lp_servicename(snum
)));
852 *status
= NT_STATUS_ACCESS_DENIED
;
855 conn
->read_only
= True
;
859 /* Initialise VFS function pointers */
861 if (!smbd_vfs_init(conn
)) {
862 DEBUG(0, ("vfs_init failed for service %s\n",
863 lp_servicename(snum
)));
865 *status
= NT_STATUS_BAD_NETWORK_NAME
;
870 * If widelinks are disallowed we need to canonicalise the connect
871 * path here to ensure we don't have any symlinks in the
872 * connectpath. We will be checking all paths on this connection are
873 * below this directory. We must do this after the VFS init as we
874 * depend on the realpath() pointer in the vfs table. JRA.
876 if (!lp_widelinks(snum
)) {
878 pstrcpy(s
,conn
->connectpath
);
879 canonicalize_path(conn
, s
);
880 set_conn_connectpath(conn
,s
);
883 if ((!conn
->printer
) && (!conn
->ipc
)) {
884 conn
->notify_ctx
= notify_init(conn
->mem_ctx
, server_id_self(),
885 smbd_messaging_context(),
886 smbd_event_context(),
890 /* ROOT Activities: */
891 /* check number of connections */
892 if (!claim_connection(conn
,
893 lp_servicename(snum
),
894 lp_max_connections(snum
),
896 DEBUG(1,("too many connections - rejected\n"));
898 *status
= NT_STATUS_INSUFFICIENT_RESOURCES
;
902 /* Preexecs are done here as they might make the dir we are to ChDir
904 /* execute any "root preexec = " line */
905 if (*lp_rootpreexec(snum
)) {
907 pstrcpy(cmd
,lp_rootpreexec(snum
));
908 standard_sub_advanced(lp_servicename(SNUM(conn
)), conn
->user
,
909 conn
->connectpath
, conn
->gid
,
910 get_current_username(),
911 current_user_info
.domain
,
913 DEBUG(5,("cmd=%s\n",cmd
));
914 ret
= smbrun(cmd
,NULL
);
915 if (ret
!= 0 && lp_rootpreexec_close(snum
)) {
916 DEBUG(1,("root preexec gave %d - failing "
917 "connection\n", ret
));
918 yield_connection(conn
, lp_servicename(snum
));
920 *status
= NT_STATUS_ACCESS_DENIED
;
925 /* USER Activites: */
926 if (!change_to_user(conn
, conn
->vuid
)) {
927 /* No point continuing if they fail the basic checks */
928 DEBUG(0,("Can't become connected user!\n"));
929 yield_connection(conn
, lp_servicename(snum
));
931 *status
= NT_STATUS_LOGON_FAILURE
;
935 /* Remember that a different vuid can connect later without these
938 /* Preexecs are done here as they might make the dir we are to ChDir
941 /* execute any "preexec = " line */
942 if (*lp_preexec(snum
)) {
944 pstrcpy(cmd
,lp_preexec(snum
));
945 standard_sub_advanced(lp_servicename(SNUM(conn
)), conn
->user
,
946 conn
->connectpath
, conn
->gid
,
947 get_current_username(),
948 current_user_info
.domain
,
950 ret
= smbrun(cmd
,NULL
);
951 if (ret
!= 0 && lp_preexec_close(snum
)) {
952 DEBUG(1,("preexec gave %d - failing connection\n",
954 change_to_root_user();
955 yield_connection(conn
, lp_servicename(snum
));
957 *status
= NT_STATUS_ACCESS_DENIED
;
962 #ifdef WITH_FAKE_KASERVER
963 if (lp_afs_share(snum
)) {
968 /* Add veto/hide lists */
969 if (!IS_IPC(conn
) && !IS_PRINT(conn
)) {
970 set_namearray( &conn
->veto_list
, lp_veto_files(snum
));
971 set_namearray( &conn
->hide_list
, lp_hide_files(snum
));
972 set_namearray( &conn
->veto_oplock_list
, lp_veto_oplocks(snum
));
975 /* Invoke VFS make connection hook - do this before the VFS_STAT call
976 to allow any filesystems needing user credentials to initialize
979 if (SMB_VFS_CONNECT(conn
, lp_servicename(snum
), user
) < 0) {
980 DEBUG(0,("make_connection: VFS make connection failed!\n"));
981 change_to_root_user();
982 yield_connection(conn
, lp_servicename(snum
));
984 *status
= NT_STATUS_UNSUCCESSFUL
;
988 /* win2000 does not check the permissions on the directory
989 during the tree connect, instead relying on permission
990 check during individual operations. To match this behaviour
991 I have disabled this chdir check (tridge) */
992 /* the alternative is just to check the directory exists */
993 if ((ret
= SMB_VFS_STAT(conn
, conn
->connectpath
, &st
)) != 0 ||
994 !S_ISDIR(st
.st_mode
)) {
995 if (ret
== 0 && !S_ISDIR(st
.st_mode
)) {
996 DEBUG(0,("'%s' is not a directory, when connecting to "
997 "[%s]\n", conn
->connectpath
,
998 lp_servicename(snum
)));
1000 DEBUG(0,("'%s' does not exist or permission denied "
1001 "when connecting to [%s] Error was %s\n",
1002 conn
->connectpath
, lp_servicename(snum
),
1005 change_to_root_user();
1006 /* Call VFS disconnect hook */
1007 SMB_VFS_DISCONNECT(conn
);
1008 yield_connection(conn
, lp_servicename(snum
));
1010 *status
= NT_STATUS_BAD_NETWORK_NAME
;
1014 string_set(&conn
->origpath
,conn
->connectpath
);
1016 #if SOFTLINK_OPTIMISATION
1017 /* resolve any soft links early if possible */
1018 if (vfs_ChDir(conn
,conn
->connectpath
) == 0) {
1020 pstrcpy(s
,conn
->connectpath
);
1022 set_conn_connectpath(conn
,s
);
1023 vfs_ChDir(conn
,conn
->connectpath
);
1028 * Print out the 'connected as' stuff here as we need
1029 * to know the effective uid and gid we will be using
1030 * (at least initially).
1033 if( DEBUGLVL( IS_IPC(conn
) ? 3 : 1 ) ) {
1034 dbgtext( "%s (%s) ", get_remote_machine_name(),
1035 conn
->client_address
);
1036 dbgtext( "%s", srv_is_signing_active() ? "signed " : "");
1037 dbgtext( "connect to service %s ", lp_servicename(snum
) );
1038 dbgtext( "initially as user %s ", user
);
1039 dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
1040 dbgtext( "(pid %d)\n", (int)sys_getpid() );
1043 /* we've finished with the user stuff - go back to root */
1044 change_to_root_user();
1048 /***************************************************************************************
1049 Simple wrapper function for make_connection() to include a call to
1051 **************************************************************************************/
1053 connection_struct
*make_connection_with_chdir(const char *service_in
,
1055 const char *dev
, uint16 vuid
,
1058 connection_struct
*conn
= NULL
;
1060 conn
= make_connection(service_in
, password
, dev
, vuid
, status
);
1063 * make_connection() does not change the directory for us any more
1064 * so we have to do it as a separate step --jerry
1067 if ( conn
&& vfs_ChDir(conn
,conn
->connectpath
) != 0 ) {
1068 DEBUG(0,("move_driver_to_download_area: Can't change "
1069 "directory to %s for [print$] (%s)\n",
1070 conn
->connectpath
,strerror(errno
)));
1071 yield_connection(conn
, lp_servicename(SNUM(conn
)));
1073 *status
= NT_STATUS_UNSUCCESSFUL
;
1080 /****************************************************************************
1081 Make a connection to a service.
1084 ****************************************************************************/
1086 connection_struct
*make_connection(const char *service_in
, DATA_BLOB password
,
1087 const char *pdev
, uint16 vuid
,
1091 user_struct
*vuser
= NULL
;
1098 /* This must ONLY BE CALLED AS ROOT. As it exits this function as
1100 if (!non_root_mode() && (euid
= geteuid()) != 0) {
1101 DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot "
1102 "(%u)\n", (unsigned int)euid
));
1103 smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
1106 if (conn_num_open() > 2047) {
1107 *status
= NT_STATUS_INSUFF_SERVER_RESOURCES
;
1111 if(lp_security() != SEC_SHARE
) {
1112 vuser
= get_valid_user_struct(vuid
);
1114 DEBUG(1,("make_connection: refusing to connect with "
1115 "no session setup\n"));
1116 *status
= NT_STATUS_ACCESS_DENIED
;
1121 /* Logic to try and connect to the correct [homes] share, preferably
1122 without too many getpwnam() lookups. This is particulary nasty for
1123 winbind usernames, where the share name isn't the same as unix
1126 The snum of the homes share is stored on the vuser at session setup
1130 if (strequal(service_in
,HOMES_NAME
)) {
1131 if(lp_security() != SEC_SHARE
) {
1132 DATA_BLOB no_pw
= data_blob(NULL
, 0);
1133 if (vuser
->homes_snum
== -1) {
1134 DEBUG(2, ("[homes] share not available for "
1135 "this user because it was not found "
1136 "or created at session setup "
1138 *status
= NT_STATUS_BAD_NETWORK_NAME
;
1141 DEBUG(5, ("making a connection to [homes] service "
1142 "created at session setup time\n"));
1143 return make_connection_snum(vuser
->homes_snum
,
1147 /* Security = share. Try with
1148 * current_user_info.smb_name as the username. */
1149 if (*current_user_info
.smb_name
) {
1150 fstring unix_username
;
1151 fstrcpy(unix_username
,
1152 current_user_info
.smb_name
);
1153 map_username(unix_username
);
1154 snum
= find_service(unix_username
);
1157 DEBUG(5, ("making a connection to 'homes' "
1158 "service %s based on "
1159 "security=share\n", service_in
));
1160 return make_connection_snum(snum
, NULL
,
1165 } else if ((lp_security() != SEC_SHARE
) && (vuser
->homes_snum
!= -1)
1166 && strequal(service_in
,
1167 lp_servicename(vuser
->homes_snum
))) {
1168 DATA_BLOB no_pw
= data_blob(NULL
, 0);
1169 DEBUG(5, ("making a connection to 'homes' service [%s] "
1170 "created at session setup time\n", service_in
));
1171 return make_connection_snum(vuser
->homes_snum
,
1176 fstrcpy(service
, service_in
);
1178 strlower_m(service
);
1180 snum
= find_service(service
);
1183 if (strequal(service
,"IPC$") ||
1184 (lp_enable_asu_support() && strequal(service
,"ADMIN$"))) {
1185 DEBUG(3,("refusing IPC connection to %s\n", service
));
1186 *status
= NT_STATUS_ACCESS_DENIED
;
1190 DEBUG(0,("%s (%s) couldn't find service %s\n",
1191 get_remote_machine_name(), client_addr(), service
));
1192 *status
= NT_STATUS_BAD_NETWORK_NAME
;
1196 /* Handle non-Dfs clients attempting connections to msdfs proxy */
1197 if (lp_host_msdfs() && (*lp_msdfs_proxy(snum
) != '\0')) {
1198 DEBUG(3, ("refusing connection to dfs proxy share '%s' "
1199 "(pointing to %s)\n",
1200 service
, lp_msdfs_proxy(snum
)));
1201 *status
= NT_STATUS_BAD_NETWORK_NAME
;
1205 DEBUG(5, ("making a connection to 'normal' service %s\n", service
));
1207 return make_connection_snum(snum
, vuser
,
1212 /****************************************************************************
1214 ****************************************************************************/
1216 void close_cnum(connection_struct
*conn
, uint16 vuid
)
1219 pipe_close_conn(conn
);
1221 file_close_conn(conn
);
1222 dptr_closecnum(conn
);
1225 change_to_root_user();
1227 DEBUG(IS_IPC(conn
)?3:1, ("%s (%s) closed connection to service %s\n",
1228 get_remote_machine_name(),
1229 conn
->client_address
,
1230 lp_servicename(SNUM(conn
))));
1232 /* Call VFS disconnect hook */
1233 SMB_VFS_DISCONNECT(conn
);
1235 yield_connection(conn
, lp_servicename(SNUM(conn
)));
1237 /* make sure we leave the directory available for unmount */
1238 vfs_ChDir(conn
, "/");
1240 /* execute any "postexec = " line */
1241 if (*lp_postexec(SNUM(conn
)) &&
1242 change_to_user(conn
, vuid
)) {
1244 pstrcpy(cmd
,lp_postexec(SNUM(conn
)));
1245 standard_sub_advanced(lp_servicename(SNUM(conn
)), conn
->user
,
1246 conn
->connectpath
, conn
->gid
,
1247 get_current_username(),
1248 current_user_info
.domain
,
1251 change_to_root_user();
1254 change_to_root_user();
1255 /* execute any "root postexec = " line */
1256 if (*lp_rootpostexec(SNUM(conn
))) {
1258 pstrcpy(cmd
,lp_rootpostexec(SNUM(conn
)));
1259 standard_sub_advanced(lp_servicename(SNUM(conn
)), conn
->user
,
1260 conn
->connectpath
, conn
->gid
,
1261 get_current_username(),
1262 current_user_info
.domain
,