1998-08-17 17:11:34 +04:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
service ( connection ) opening and closing
Copyright ( C ) Andrew Tridgell 1992 - 1998
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
extern int DEBUGLEVEL ;
1999-12-13 16:27:58 +03:00
extern struct timeval smb_last_time ;
1998-08-17 17:11:34 +04:00
extern int case_default ;
extern BOOL case_preserve ;
extern BOOL short_case_preserve ;
extern BOOL case_mangle ;
extern BOOL case_sensitive ;
extern BOOL use_mangled_map ;
extern fstring remote_machine ;
2001-01-23 04:52:30 +03:00
extern userdom_struct current_user_info ;
1998-08-17 17:11:34 +04:00
extern fstring remote_machine ;
/****************************************************************************
load parameters specific to a connection / service
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL become_service ( connection_struct * conn , BOOL do_chdir )
{
extern char magic_char ;
static connection_struct * last_conn ;
int snum ;
if ( ! conn ) {
last_conn = NULL ;
return ( False ) ;
}
1999-12-13 16:27:58 +03:00
conn - > lastused = smb_last_time . tv_sec ;
1998-08-17 17:11:34 +04:00
snum = SNUM ( conn ) ;
if ( do_chdir & &
2000-09-27 23:09:59 +04:00
vfs_ChDir ( conn , conn - > connectpath ) ! = 0 & &
vfs_ChDir ( conn , conn - > origpath ) ! = 0 ) {
1998-08-17 17:11:34 +04:00
DEBUG ( 0 , ( " chdir (%s) failed \n " ,
conn - > connectpath ) ) ;
return ( False ) ;
}
if ( conn = = last_conn )
return ( True ) ;
last_conn = conn ;
case_default = lp_defaultcase ( snum ) ;
case_preserve = lp_preservecase ( snum ) ;
short_case_preserve = lp_shortpreservecase ( snum ) ;
case_mangle = lp_casemangle ( snum ) ;
case_sensitive = lp_casesensitive ( snum ) ;
magic_char = lp_magicchar ( snum ) ;
use_mangled_map = ( * lp_mangled_map ( snum ) ? True : False ) ;
return ( True ) ;
}
2001-01-24 22:34:53 +03:00
/****************************************************************************
Add a home service . Returns the new service number or - 1 if fail .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int add_home_service ( char * service , char * homedir )
{
int iHomeService ;
int iService ;
fstring new_service ;
char * usr_p = NULL ;
if ( ! service | | ! homedir )
return - 1 ;
if ( ( iHomeService = lp_servicenumber ( HOMES_NAME ) ) < 0 )
return - 1 ;
/*
* If this is a winbindd provided username , remove
* the domain component before adding the service .
* Log a warning if the " path= " parameter does not
* include any macros .
*/
fstrcpy ( new_service , service ) ;
if ( ( usr_p = strchr ( service , * lp_winbind_separator ( ) ) ) ! = NULL )
fstrcpy ( new_service , usr_p + 1 ) ;
lp_add_home ( new_service , iHomeService , homedir ) ;
iService = lp_servicenumber ( new_service ) ;
return iService ;
}
1998-08-17 17:11:34 +04:00
/****************************************************************************
2001-01-24 22:34:53 +03:00
Find a service entry . service is always in dos codepage .
1998-08-17 17:11:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-24 22:34:53 +03:00
1998-08-17 17:11:34 +04:00
int find_service ( char * service )
{
int iService ;
1999-12-13 16:27:58 +03:00
all_string_sub ( service , " \\ " , " / " , 0 ) ;
1998-08-17 17:11:34 +04:00
iService = lp_servicenumber ( service ) ;
/* now handle the special case of a home directory */
if ( iService < 0 )
{
1999-12-13 16:27:58 +03:00
char * phome_dir = get_user_home_dir ( service ) ;
1998-08-17 17:11:34 +04:00
1999-12-13 16:27:58 +03:00
if ( ! phome_dir )
1998-08-17 17:11:34 +04:00
{
/*
* Try mapping the servicename , it may
* be a Windows to unix mapped user name .
*/
if ( map_username ( service ) )
1999-12-13 16:27:58 +03:00
phome_dir = get_user_home_dir ( service ) ;
1998-08-17 17:11:34 +04:00
}
DEBUG ( 3 , ( " checking for home directory %s gave %s \n " , service ,
phome_dir ? phome_dir : " (NULL) " ) ) ;
2001-01-24 22:34:53 +03:00
iService = add_home_service ( service , phome_dir ) ;
1998-08-17 17:11:34 +04:00
}
/* If we still don't have a service, attempt to add it as a printer. */
if ( iService < 0 )
{
int iPrinterService ;
if ( ( iPrinterService = lp_servicenumber ( PRINTERS_NAME ) ) > = 0 )
{
char * pszTemp ;
DEBUG ( 3 , ( " checking whether %s is a valid printer name... \n " , service ) ) ;
pszTemp = PRINTCAP ;
if ( ( pszTemp ! = NULL ) & & pcap_printername_ok ( service , pszTemp ) )
{
DEBUG ( 3 , ( " %s is a valid printer name \n " , service ) ) ;
DEBUG ( 3 , ( " adding %s as a printer service \n " , service ) ) ;
lp_add_printer ( service , iPrinterService ) ;
iService = lp_servicenumber ( service ) ;
if ( iService < 0 )
DEBUG ( 0 , ( " failed to add %s as a printer service! \n " , service ) ) ;
}
else
DEBUG ( 3 , ( " %s is not a valid printer name \n " , service ) ) ;
}
}
2000-02-03 08:17:25 +03:00
/* Check for default vfs service? Unsure whether to implement this */
if ( iService < 0 )
{
}
1998-08-17 17:11:34 +04:00
/* just possibly it's a default service? */
if ( iService < 0 )
{
char * pdefservice = lp_defaultservice ( ) ;
1998-11-29 09:23:16 +03:00
if ( pdefservice & & * pdefservice & &
! strequal ( pdefservice , service ) & &
! strstr ( service , " .. " ) )
1998-08-17 17:11:34 +04:00
{
/*
* We need to do a local copy here as lp_defaultservice ( )
* returns one of the rotating lp_string buffers that
* could get overwritten by the recursive find_service ( ) call
* below . Fix from Josef Hinteregger < joehtg @ joehtg . co . at > .
*/
pstring defservice ;
pstrcpy ( defservice , pdefservice ) ;
iService = find_service ( defservice ) ;
if ( iService > = 0 )
{
1999-12-13 16:27:58 +03:00
all_string_sub ( service , " _ " , " / " , 0 ) ;
1998-08-17 17:11:34 +04:00
iService = lp_add_service ( service , iService ) ;
}
}
}
if ( iService > = 0 )
if ( ! VALID_SNUM ( iService ) )
{
DEBUG ( 0 , ( " Invalid snum %d for %s \n " , iService , service ) ) ;
iService = - 1 ;
}
if ( iService < 0 )
DEBUG ( 3 , ( " find_service() failed to find service %s \n " , service ) ) ;
return ( iService ) ;
}
/****************************************************************************
make a connection to a service
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
connection_struct * make_connection ( char * service , char * user , char * password , int pwlen , char * dev , uint16 vuid , int * ecode )
{
int snum ;
1999-12-13 16:27:58 +03:00
struct passwd * pass = NULL ;
1998-08-17 17:11:34 +04:00
BOOL guest = False ;
BOOL force = False ;
connection_struct * conn ;
1999-12-13 16:27:58 +03:00
int ret ;
1998-08-17 17:11:34 +04:00
strlower ( service ) ;
snum = find_service ( service ) ;
if ( snum < 0 ) {
2001-03-13 03:31:07 +03:00
if ( strequal ( service , " IPC$ " ) | | strequal ( service , " ADMIN$ " ) ) {
1998-08-17 17:11:34 +04:00
DEBUG ( 3 , ( " refusing IPC connection \n " ) ) ;
* ecode = ERRnoipc ;
return NULL ;
}
DEBUG ( 0 , ( " %s (%s) couldn't find service %s \n " ,
2000-04-11 17:55:53 +04:00
remote_machine , client_addr ( ) , service ) ) ;
2000-05-23 05:27:19 +04:00
* ecode = ERRnosuchshare ;
1998-08-17 17:11:34 +04:00
return NULL ;
}
if ( strequal ( service , HOMES_NAME ) ) {
1999-12-13 16:27:58 +03:00
if ( * user & & Get_Pwnam ( user , True ) ) {
fstring dos_username ;
fstrcpy ( dos_username , user ) ;
unix_to_dos ( dos_username , True ) ;
return ( make_connection ( dos_username , user , password ,
1998-08-17 17:11:34 +04:00
pwlen , dev , vuid , ecode ) ) ;
1999-12-13 16:27:58 +03:00
}
1998-08-17 17:11:34 +04:00
if ( lp_security ( ) ! = SEC_SHARE ) {
if ( validated_username ( vuid ) ) {
1999-12-13 16:27:58 +03:00
fstring dos_username ;
fstrcpy ( user , validated_username ( vuid ) ) ;
fstrcpy ( dos_username , user ) ;
unix_to_dos ( dos_username , True ) ;
return ( make_connection ( dos_username , user , password , pwlen , dev , vuid , ecode ) ) ;
1998-08-17 17:11:34 +04:00
}
} else {
2001-01-23 04:52:30 +03:00
/* Security = share. Try with current_user_info.smb_name
1998-08-17 17:11:34 +04:00
* as the username . */
2001-01-23 04:52:30 +03:00
if ( * current_user_info . smb_name ) {
1999-12-13 16:27:58 +03:00
fstring dos_username ;
2001-01-23 04:52:30 +03:00
fstrcpy ( user , current_user_info . smb_name ) ;
1999-12-13 16:27:58 +03:00
fstrcpy ( dos_username , user ) ;
unix_to_dos ( dos_username , True ) ;
return ( make_connection ( dos_username , user , password , pwlen , dev , vuid , ecode ) ) ;
1998-08-17 17:11:34 +04:00
}
}
}
if ( ! lp_snum_ok ( snum ) | |
2000-04-11 17:55:53 +04:00
! check_access ( smbd_server_fd ( ) ,
1998-08-17 17:11:34 +04:00
lp_hostsallow ( snum ) , lp_hostsdeny ( snum ) ) ) {
* ecode = ERRaccess ;
return NULL ;
}
/* you can only connect to the IPC$ service as an ipc device */
2001-03-13 03:31:07 +03:00
if ( strequal ( service , " IPC$ " ) | | strequal ( service , " ADMIN$ " ) )
1998-08-17 17:11:34 +04:00
pstrcpy ( dev , " IPC " ) ;
if ( * dev = = ' ? ' | | ! * dev ) {
if ( lp_print_ok ( snum ) ) {
pstrcpy ( dev , " LPT1: " ) ;
} else {
pstrcpy ( dev , " A: " ) ;
}
}
/* if the request is as a printer and you can't print then refuse */
strupper ( dev ) ;
if ( ! lp_print_ok ( snum ) & & ( strncmp ( dev , " LPT " , 3 ) = = 0 ) ) {
DEBUG ( 1 , ( " Attempt to connect to non-printer as a printer \n " ) ) ;
* ecode = ERRinvdevice ;
return NULL ;
}
2000-07-25 10:10:59 +04:00
/* Behave as a printer if we are supposed to */
if ( lp_print_ok ( snum ) & & ( strcmp ( dev , " A: " ) = = 0 ) ) {
pstrcpy ( dev , " LPT1: " ) ;
}
1998-08-17 17:11:34 +04:00
/* lowercase the user name */
strlower ( user ) ;
2001-01-24 01:13:41 +03:00
/* add it as a possible user name if we
are in share mode security */
if ( lp_security ( ) = = SEC_SHARE ) {
add_session_user ( service ) ;
}
1998-08-17 17:11:34 +04:00
/* shall we let them in? */
if ( ! authorise_login ( snum , user , password , pwlen , & guest , & force , vuid ) ) {
2000-05-12 18:28:46 +04:00
DEBUG ( 2 , ( " Invalid username/password for %s [%s] \n " , service , user ) ) ;
1998-08-17 17:11:34 +04:00
* ecode = ERRbadpw ;
return NULL ;
}
conn = conn_new ( ) ;
if ( ! conn ) {
DEBUG ( 0 , ( " Couldn't find free connection. \n " ) ) ;
* ecode = ERRnoresource ;
return NULL ;
}
/* find out some info about the user */
2000-05-10 18:48:33 +04:00
pass = smb_getpwnam ( user , True ) ;
1998-08-17 17:11:34 +04:00
if ( pass = = NULL ) {
DEBUG ( 0 , ( " Couldn't find account %s \n " , user ) ) ;
* ecode = ERRbaduid ;
conn_free ( conn ) ;
return NULL ;
}
conn - > read_only = lp_readonly ( snum ) ;
2001-04-09 10:36:38 +04:00
1998-08-17 17:11:34 +04:00
{
pstring list ;
StrnCpy ( list , lp_readlist ( snum ) , sizeof ( pstring ) - 1 ) ;
1999-12-13 16:27:58 +03:00
pstring_sub ( list , " %S " , service ) ;
1998-08-17 17:11:34 +04:00
if ( user_in_list ( user , list ) )
conn - > read_only = True ;
StrnCpy ( list , lp_writelist ( snum ) , sizeof ( pstring ) - 1 ) ;
1999-12-13 16:27:58 +03:00
pstring_sub ( list , " %S " , service ) ;
1998-08-17 17:11:34 +04:00
if ( user_in_list ( user , list ) )
conn - > read_only = False ;
}
/* admin user check */
/* JRA - original code denied admin user if the share was
marked read_only . Changed as I don ' t think this is needed ,
but old code left in case there is a problem here .
*/
if ( user_in_list ( user , lp_admin_users ( snum ) )
#if 0
& & ! conn - > read_only
# endif
) {
conn - > admin_user = True ;
DEBUG ( 0 , ( " %s logged in as admin user (root privileges) \n " , user ) ) ;
} else {
conn - > admin_user = False ;
}
conn - > force_user = force ;
conn - > vuid = vuid ;
conn - > uid = pass - > pw_uid ;
conn - > gid = pass - > pw_gid ;
2000-04-11 17:55:53 +04:00
safe_strcpy ( conn - > client_address , client_addr ( ) , sizeof ( conn - > client_address ) - 1 ) ;
1998-08-17 17:11:34 +04:00
conn - > num_files_open = 0 ;
conn - > lastused = time ( NULL ) ;
conn - > service = snum ;
conn - > used = True ;
conn - > printer = ( strncmp ( dev , " LPT " , 3 ) = = 0 ) ;
2001-03-13 03:31:07 +03:00
conn - > ipc = ( ( strncmp ( dev , " IPC " , 3 ) = = 0 ) | | strequal ( dev , " ADMIN$ " ) ) ;
1998-08-17 17:11:34 +04:00
conn - > dirptr = NULL ;
conn - > veto_list = NULL ;
conn - > hide_list = NULL ;
conn - > veto_oplock_list = NULL ;
string_set ( & conn - > dirpath , " " ) ;
string_set ( & conn - > user , user ) ;
2000-08-04 02:38:43 +04:00
conn - > nt_user_token = NULL ;
1999-12-13 16:27:58 +03:00
/*
* If force user is true , then store the
* given userid and also the primary groupid
* of the user we ' re forcing .
*/
if ( * lp_force_user ( snum ) ) {
struct passwd * pass2 ;
pstring fuser ;
pstrcpy ( fuser , lp_force_user ( snum ) ) ;
1999-04-04 10:22:22 +04:00
1999-12-13 16:27:58 +03:00
/* Allow %S to be used by force user. */
pstring_sub ( fuser , " %S " , service ) ;
1999-04-04 10:22:22 +04:00
1999-12-13 16:27:58 +03:00
pass2 = ( struct passwd * ) Get_Pwnam ( fuser , True ) ;
if ( pass2 ) {
conn - > uid = pass2 - > pw_uid ;
conn - > gid = pass2 - > pw_gid ;
string_set ( & conn - > user , fuser ) ;
fstrcpy ( user , fuser ) ;
conn - > force_user = True ;
DEBUG ( 3 , ( " Forced user %s \n " , fuser ) ) ;
} else {
DEBUG ( 1 , ( " Couldn't find user %s \n " , fuser ) ) ;
}
1999-04-04 10:22:22 +04:00
}
2000-08-31 11:11:45 +04:00
/* admin users always run as uid=0 */
if ( conn - > admin_user ) {
conn - > uid = 0 ;
}
1998-08-17 17:11:34 +04:00
# ifdef HAVE_GETGRNAM
1999-12-13 16:27:58 +03:00
/*
* If force group is true , then override
* any groupid stored for the connecting user .
*/
1998-08-17 17:11:34 +04:00
if ( * lp_force_group ( snum ) ) {
2000-10-13 05:59:14 +04:00
gid_t gid ;
1998-08-17 17:11:34 +04:00
pstring gname ;
1999-12-13 16:27:58 +03:00
pstring tmp_gname ;
BOOL user_must_be_member = False ;
1998-08-17 17:11:34 +04:00
1999-12-13 16:27:58 +03:00
StrnCpy ( tmp_gname , lp_force_group ( snum ) , sizeof ( pstring ) - 1 ) ;
if ( tmp_gname [ 0 ] = = ' + ' ) {
user_must_be_member = True ;
StrnCpy ( gname , & tmp_gname [ 1 ] , sizeof ( pstring ) - 2 ) ;
} else {
StrnCpy ( gname , tmp_gname , sizeof ( pstring ) - 1 ) ;
}
1998-08-17 17:11:34 +04:00
/* default service may be a group name */
1999-12-13 16:27:58 +03:00
pstring_sub ( gname , " %S " , service ) ;
2000-10-13 05:59:14 +04:00
gid = nametogid ( gname ) ;
1998-08-17 17:11:34 +04:00
2000-10-13 05:59:14 +04:00
if ( gid ! = ( gid_t ) - 1 ) {
1999-12-13 16:27:58 +03:00
/*
* If the user has been forced and the forced group starts
* with a ' + ' , then we only set the group to be the forced
* group if the forced user is a member of that group .
* Otherwise , the meaning of the ' + ' would be ignored .
*/
if ( conn - > force_user & & user_must_be_member ) {
2000-10-13 05:59:14 +04:00
if ( user_in_group_list ( user , gname ) ) {
conn - > gid = gid ;
1999-12-13 16:27:58 +03:00
DEBUG ( 3 , ( " Forced group %s for member %s \n " , gname , user ) ) ;
}
} else {
2000-10-13 05:59:14 +04:00
conn - > gid = gid ;
1999-12-13 16:27:58 +03:00
DEBUG ( 3 , ( " Forced group %s \n " , gname ) ) ;
}
1998-08-17 17:11:34 +04:00
} else {
DEBUG ( 1 , ( " Couldn't find group %s \n " , gname ) ) ;
}
}
1999-12-13 16:27:58 +03:00
# endif /* HAVE_GETGRNAM */
1998-08-17 17:11:34 +04:00
{
pstring s ;
pstrcpy ( s , lp_pathname ( snum ) ) ;
2000-04-19 08:01:16 +04:00
standard_sub_conn ( conn , s ) ;
1998-08-17 17:11:34 +04:00
string_set ( & conn - > connectpath , s ) ;
DEBUG ( 3 , ( " Connect path is %s \n " , s ) ) ;
}
/* groups stuff added by ih */
conn - > ngroups = 0 ;
conn - > groups = NULL ;
2000-11-17 06:15:18 +03:00
/* Find all the groups this uid is in and
store them . Used by become_user ( ) */
initialise_groups ( conn - > user , conn - > uid , conn - > gid ) ;
get_current_groups ( & conn - > ngroups , & conn - > groups ) ;
1998-08-17 17:11:34 +04:00
2000-11-17 06:15:18 +03:00
/* check number of connections */
if ( ! claim_connection ( conn ,
lp_servicename ( SNUM ( conn ) ) ,
lp_max_connections ( SNUM ( conn ) ) ,
False ) ) {
DEBUG ( 1 , ( " too many connections - rejected \n " ) ) ;
* ecode = ERRnoresource ;
conn_free ( conn ) ;
return NULL ;
}
1998-08-17 17:11:34 +04:00
2001-01-04 22:27:08 +03:00
conn - > nt_user_token = create_nt_token ( conn - > uid , conn - > gid ,
2000-12-12 08:29:47 +03:00
conn - > ngroups , conn - > groups ,
guest ) ;
2000-08-04 02:38:43 +04:00
2001-04-12 01:19:25 +04:00
/*
* New code to check if there ' s a share security descripter
* added from NT server manager . This is done after the
* smb . conf checks are done as we need a uid and token . JRA .
*/
{
BOOL can_write = share_access_check ( conn , snum , vuid , FILE_WRITE_DATA ) ;
if ( ! can_write ) {
if ( ! share_access_check ( conn , snum , vuid , FILE_READ_DATA ) ) {
/* No access, read or write. */
* ecode = ERRaccess ;
DEBUG ( 0 , ( " make_connection: connection to %s denied due to security descriptor. \n " ,
service ) ) ;
conn_free ( conn ) ;
return NULL ;
} else {
conn - > read_only = True ;
}
}
}
2000-08-04 02:38:43 +04:00
/* Initialise VFS function pointers */
if ( * lp_vfsobj ( SNUM ( conn ) ) ) {
# ifdef HAVE_LIBDL
/* Loadable object file */
if ( ! vfs_init_custom ( conn ) ) {
2000-11-07 00:44:33 +03:00
DEBUG ( 0 , ( " vfs_init failed \n " ) ) ;
conn_free ( conn ) ;
2000-08-04 02:38:43 +04:00
return NULL ;
}
# else
DEBUG ( 0 , ( " No libdl present - cannot use VFS objects \n " ) ) ;
conn_free ( conn ) ;
return NULL ;
# endif
} else {
/* Normal share - initialise with disk access functions */
vfs_init_default ( conn ) ;
}
1998-08-17 17:11:34 +04:00
/* execute any "root preexec = " line */
if ( * lp_rootpreexec ( SNUM ( conn ) ) ) {
pstring cmd ;
pstrcpy ( cmd , lp_rootpreexec ( SNUM ( conn ) ) ) ;
2000-04-19 08:01:16 +04:00
standard_sub_conn ( conn , cmd ) ;
1998-08-17 17:11:34 +04:00
DEBUG ( 5 , ( " cmd=%s \n " , cmd ) ) ;
2001-04-13 23:12:06 +04:00
ret = smbrun ( cmd , NULL ) ;
1999-12-13 16:27:58 +03:00
if ( ret ! = 0 & & lp_rootpreexec_close ( SNUM ( conn ) ) ) {
DEBUG ( 1 , ( " preexec gave %d - failing connection \n " , ret ) ) ;
conn_free ( conn ) ;
* ecode = ERRsrverror ;
return NULL ;
}
1998-08-17 17:11:34 +04:00
}
if ( ! become_user ( conn , conn - > vuid ) ) {
DEBUG ( 0 , ( " Can't become connected user! \n " ) ) ;
2000-11-17 06:15:18 +03:00
yield_connection ( conn ,
lp_servicename ( SNUM ( conn ) ) ,
lp_max_connections ( SNUM ( conn ) ) ) ;
1998-08-17 17:11:34 +04:00
conn_free ( conn ) ;
* ecode = ERRbadpw ;
return NULL ;
}
2000-09-27 23:09:59 +04:00
if ( vfs_ChDir ( conn , conn - > connectpath ) ! = 0 ) {
2001-03-27 03:21:29 +04:00
DEBUG ( 0 , ( " %s (%s) Can't change directory to %s (%s) \n " ,
remote_machine , conn - > client_address ,
1998-08-17 17:11:34 +04:00
conn - > connectpath , strerror ( errno ) ) ) ;
unbecome_user ( ) ;
2000-11-17 06:15:18 +03:00
yield_connection ( conn ,
lp_servicename ( SNUM ( conn ) ) ,
lp_max_connections ( SNUM ( conn ) ) ) ;
1998-08-17 17:11:34 +04:00
conn_free ( conn ) ;
2000-05-23 05:27:19 +04:00
* ecode = ERRnosuchshare ;
1998-08-17 17:11:34 +04:00
return NULL ;
}
string_set ( & conn - > origpath , conn - > connectpath ) ;
# if SOFTLINK_OPTIMISATION
/* resolve any soft links early */
{
pstring s ;
pstrcpy ( s , conn - > connectpath ) ;
2000-09-27 23:09:59 +04:00
vfs_GetWd ( conn , s ) ;
1998-08-17 17:11:34 +04:00
string_set ( & conn - > connectpath , s ) ;
2000-09-27 23:09:59 +04:00
vfs_ChDir ( conn , conn - > connectpath ) ;
1998-08-17 17:11:34 +04:00
}
# endif
add_session_user ( user ) ;
/* execute any "preexec = " line */
if ( * lp_preexec ( SNUM ( conn ) ) ) {
pstring cmd ;
pstrcpy ( cmd , lp_preexec ( SNUM ( conn ) ) ) ;
2000-04-19 08:01:16 +04:00
standard_sub_conn ( conn , cmd ) ;
2001-04-13 23:12:06 +04:00
ret = smbrun ( cmd , NULL ) ;
1999-12-13 16:27:58 +03:00
if ( ret ! = 0 & & lp_preexec_close ( SNUM ( conn ) ) ) {
DEBUG ( 1 , ( " preexec gave %d - failing connection \n " , ret ) ) ;
conn_free ( conn ) ;
* ecode = ERRsrverror ;
return NULL ;
}
}
/*
* Print out the ' connected as ' stuff here as we need
* to know the effective uid and gid we will be using .
*/
if ( DEBUGLVL ( IS_IPC ( conn ) ? 3 : 1 ) ) {
dbgtext ( " %s (%s) " , remote_machine , conn - > client_address ) ;
dbgtext ( " connect to service %s " , lp_servicename ( SNUM ( conn ) ) ) ;
dbgtext ( " as user %s " , user ) ;
dbgtext ( " (uid=%d, gid=%d) " , ( int ) geteuid ( ) , ( int ) getegid ( ) ) ;
2000-05-02 06:23:41 +04:00
dbgtext ( " (pid %d) \n " , ( int ) sys_getpid ( ) ) ;
1998-08-17 17:11:34 +04:00
}
/* we've finished with the sensitive stuff */
unbecome_user ( ) ;
/* Add veto/hide lists */
if ( ! IS_IPC ( conn ) & & ! IS_PRINT ( conn ) ) {
set_namearray ( & conn - > veto_list , lp_veto_files ( SNUM ( conn ) ) ) ;
set_namearray ( & conn - > hide_list , lp_hide_files ( SNUM ( conn ) ) ) ;
set_namearray ( & conn - > veto_oplock_list , lp_veto_oplocks ( SNUM ( conn ) ) ) ;
}
2000-02-03 08:17:25 +03:00
/* Invoke VFS make connection hook */
2000-08-04 02:38:43 +04:00
if ( conn - > vfs_ops . connect ) {
2000-10-06 07:21:49 +04:00
if ( conn - > vfs_ops . connect ( conn , service , user ) < 0 )
2000-08-04 02:38:43 +04:00
return NULL ;
}
2000-02-03 08:17:25 +03:00
2000-08-04 02:38:43 +04:00
return ( conn ) ;
1998-08-17 17:11:34 +04:00
}
/****************************************************************************
close a cnum
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void close_cnum ( connection_struct * conn , uint16 vuid )
{
DirCacheFlush ( SNUM ( conn ) ) ;
unbecome_user ( ) ;
DEBUG ( IS_IPC ( conn ) ? 3 : 1 , ( " %s (%s) closed connection to service %s \n " ,
1999-12-13 16:27:58 +03:00
remote_machine , conn - > client_address ,
1998-08-17 17:11:34 +04:00
lp_servicename ( SNUM ( conn ) ) ) ) ;
2000-02-03 08:17:25 +03:00
if ( conn - > vfs_ops . disconnect ! = NULL ) {
/* Call VFS disconnect hook */
2000-10-06 07:21:49 +04:00
conn - > vfs_ops . disconnect ( conn ) ;
2000-02-03 08:17:25 +03:00
}
1998-08-17 17:11:34 +04:00
yield_connection ( conn ,
lp_servicename ( SNUM ( conn ) ) ,
lp_max_connections ( SNUM ( conn ) ) ) ;
file_close_conn ( conn ) ;
dptr_closecnum ( conn ) ;
/* execute any "postexec = " line */
if ( * lp_postexec ( SNUM ( conn ) ) & &
become_user ( conn , vuid ) ) {
pstring cmd ;
pstrcpy ( cmd , lp_postexec ( SNUM ( conn ) ) ) ;
2000-04-19 08:01:16 +04:00
standard_sub_conn ( conn , cmd ) ;
2001-04-13 23:12:06 +04:00
smbrun ( cmd , NULL ) ;
1998-08-17 17:11:34 +04:00
unbecome_user ( ) ;
}
unbecome_user ( ) ;
/* execute any "root postexec = " line */
if ( * lp_rootpostexec ( SNUM ( conn ) ) ) {
pstring cmd ;
pstrcpy ( cmd , lp_rootpostexec ( SNUM ( conn ) ) ) ;
2000-04-19 08:01:16 +04:00
standard_sub_conn ( conn , cmd ) ;
2001-04-13 23:12:06 +04:00
smbrun ( cmd , NULL ) ;
1998-08-17 17:11:34 +04:00
}
conn_free ( conn ) ;
}
2001-06-20 07:05:09 +04:00