2008-02-28 19:23:20 +03:00
/*
Unix SMB / Netbios implementation .
SMB client library implementation
Copyright ( C ) Andrew Tridgell 1998
Copyright ( C ) Richard Sharpe 2000 , 2002
Copyright ( C ) John Terpstra 2000
Copyright ( C ) Tom Jansen ( Ninja ISD ) 2002
Copyright ( C ) Derrell Lipman 2003 - 2008
Copyright ( C ) Jeremy Allison 2007 , 2008
2010-12-31 12:07:45 +03:00
2008-02-28 19:23:20 +03:00
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 3 of the License , or
( at your option ) any later version .
2010-12-31 12:07:45 +03:00
2008-02-28 19:23:20 +03:00
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 .
2010-12-31 12:07:45 +03:00
2008-02-28 19:23:20 +03:00
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2011-05-06 13:47:43 +04:00
# include "libsmb/libsmb.h"
2008-02-28 19:23:20 +03:00
# include "libsmbclient.h"
# include "libsmb_internal.h"
2010-08-05 04:25:37 +04:00
# include "secrets.h"
2008-02-28 19:23:20 +03:00
/*
* Is the logging working / configfile read ?
*/
2009-05-13 22:37:17 +04:00
static bool SMBC_initialized = false ;
static unsigned int initialized_ctx_count = 0 ;
static void * initialized_ctx_count_mutex = NULL ;
/*
* Do some module - and library - wide intializations
*/
static void
SMBC_module_init ( void * punused )
{
bool conf_loaded = False ;
char * home = NULL ;
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2010-12-31 12:07:45 +03:00
2011-02-18 05:59:05 +03:00
load_case_tables_library ( ) ;
2010-12-31 12:07:45 +03:00
2010-10-29 07:19:32 +04:00
setup_logging ( " libsmbclient " , DEBUG_STDOUT ) ;
2009-05-13 22:37:17 +04:00
/* Here we would open the smb.conf file if needed ... */
2010-12-31 12:07:45 +03:00
2009-05-13 22:37:17 +04:00
home = getenv ( " HOME " ) ;
if ( home ) {
char * conf = NULL ;
if ( asprintf ( & conf , " %s/.smb/smb.conf " , home ) > 0 ) {
2011-07-26 14:46:08 +04:00
if ( lp_load_client ( conf ) ) {
2009-05-13 22:37:17 +04:00
conf_loaded = True ;
} else {
DEBUG ( 5 , ( " Could not load config file: %s \n " ,
conf ) ) ;
}
SAFE_FREE ( conf ) ;
}
}
2010-12-31 12:07:45 +03:00
2009-05-13 22:37:17 +04:00
if ( ! conf_loaded ) {
/*
* Well , if that failed , try the get_dyn_CONFIGFILE
* Which points to the standard locn , and if that
* fails , silently ignore it and use the internal
* defaults . . .
*/
2010-12-31 12:07:45 +03:00
2011-07-26 14:46:08 +04:00
if ( ! lp_load_client ( get_dyn_CONFIGFILE ( ) ) ) {
2009-05-13 22:37:17 +04:00
DEBUG ( 5 , ( " Could not load config file: %s \n " ,
get_dyn_CONFIGFILE ( ) ) ) ;
} else if ( home ) {
char * conf ;
/*
* We loaded the global config file . Now lets
* load user - specific modifications to the
* global config .
*/
if ( asprintf ( & conf ,
" %s/.smb/smb.conf.append " ,
home ) > 0 ) {
2011-07-26 14:46:08 +04:00
if ( ! lp_load_client_no_reinit ( conf ) ) {
2009-05-13 22:37:17 +04:00
DEBUG ( 10 ,
( " Could not append config file: "
" %s \n " ,
conf ) ) ;
}
SAFE_FREE ( conf ) ;
}
}
}
2010-12-31 12:07:45 +03:00
2009-05-13 22:37:17 +04:00
load_interfaces ( ) ; /* Load the list of interfaces ... */
2010-12-31 12:07:45 +03:00
2009-05-13 22:37:17 +04:00
reopen_logs ( ) ; /* Get logging working ... */
2010-12-31 12:07:45 +03:00
2009-05-13 22:37:17 +04:00
/*
* Block SIGPIPE ( from lib / util_sock . c : write ( ) )
* It is not needed and should not stop execution
*/
BlockSignals ( True , SIGPIPE ) ;
2010-12-31 12:07:45 +03:00
2009-05-13 22:37:17 +04:00
/* Create the mutex we'll use to protect initialized_ctx_count */
if ( SMB_THREAD_CREATE_MUTEX ( " initialized_ctx_count_mutex " ,
initialized_ctx_count_mutex ) ! = 0 ) {
smb_panic ( " SMBC_module_init: "
" failed to create 'initialized_ctx_count' mutex " ) ;
}
TALLOC_FREE ( frame ) ;
}
2009-05-29 03:08:36 +04:00
static void
2009-05-13 22:37:17 +04:00
SMBC_module_terminate ( void )
{
secrets_shutdown ( ) ;
gfree_all ( ) ;
SMBC_initialized = false ;
}
2008-02-28 19:23:20 +03:00
/*
* Get a new empty handle to fill in with your own info
*/
SMBCCTX *
smbc_new_context ( void )
{
2008-03-02 04:44:21 +03:00
SMBCCTX * context ;
2010-12-31 12:07:45 +03:00
2009-05-13 22:37:17 +04:00
/* The first call to this function should initialize the module */
SMB_THREAD_ONCE ( & SMBC_initialized , SMBC_module_init , NULL ) ;
2008-03-02 04:44:21 +03:00
/*
* All newly added context fields should be placed in
* SMBC_internal_data , not directly in SMBCCTX .
*/
context = SMB_MALLOC_P ( SMBCCTX ) ;
if ( ! context ) {
errno = ENOMEM ;
return NULL ;
}
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
ZERO_STRUCTP ( context ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
context - > internal = SMB_MALLOC_P ( struct SMBC_internal_data ) ;
if ( ! context - > internal ) {
SAFE_FREE ( context ) ;
errno = ENOMEM ;
return NULL ;
}
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
/* Initialize the context and establish reasonable defaults */
ZERO_STRUCTP ( context - > internal ) ;
2010-12-31 12:07:45 +03:00
2008-03-04 02:13:33 +03:00
smbc_setDebug ( context , 0 ) ;
smbc_setTimeout ( context , 20000 ) ;
2010-12-31 12:07:45 +03:00
2008-03-04 02:13:33 +03:00
smbc_setOptionFullTimeNames ( context , False ) ;
smbc_setOptionOpenShareMode ( context , SMBC_SHAREMODE_DENY_NONE ) ;
smbc_setOptionSmbEncryptionLevel ( context , SMBC_ENCRYPTLEVEL_NONE ) ;
2010-01-24 21:24:10 +03:00
smbc_setOptionUseCCache ( context , True ) ;
2009-01-17 21:33:25 +03:00
smbc_setOptionCaseSensitive ( context , False ) ;
2008-03-04 02:13:33 +03:00
smbc_setOptionBrowseMaxLmbCount ( context , 3 ) ; /* # LMBs to query */
smbc_setOptionUrlEncodeReaddirEntries ( context , False ) ;
smbc_setOptionOneSharePerServer ( context , False ) ;
2010-01-26 12:51:32 +03:00
if ( getenv ( " LIBSMBCLIENT_NO_CCACHE " ) = = NULL ) {
smbc_setOptionUseCCache ( context , true ) ;
}
2010-12-31 12:07:45 +03:00
2008-03-04 02:13:33 +03:00
smbc_setFunctionAuthData ( context , SMBC_get_auth_data ) ;
smbc_setFunctionCheckServer ( context , SMBC_check_server ) ;
smbc_setFunctionRemoveUnusedServer ( context , SMBC_remove_unused_server ) ;
2010-12-31 12:07:45 +03:00
2008-03-04 02:13:33 +03:00
smbc_setOptionUserData ( context , NULL ) ;
smbc_setFunctionAddCachedServer ( context , SMBC_add_cached_server ) ;
smbc_setFunctionGetCachedServer ( context , SMBC_get_cached_server ) ;
smbc_setFunctionRemoveCachedServer ( context , SMBC_remove_cached_server ) ;
smbc_setFunctionPurgeCachedServers ( context , SMBC_purge_cached_servers ) ;
2010-12-31 12:07:45 +03:00
2008-03-04 02:13:33 +03:00
smbc_setFunctionOpen ( context , SMBC_open_ctx ) ;
smbc_setFunctionCreat ( context , SMBC_creat_ctx ) ;
smbc_setFunctionRead ( context , SMBC_read_ctx ) ;
smbc_setFunctionWrite ( context , SMBC_write_ctx ) ;
smbc_setFunctionClose ( context , SMBC_close_ctx ) ;
smbc_setFunctionUnlink ( context , SMBC_unlink_ctx ) ;
smbc_setFunctionRename ( context , SMBC_rename_ctx ) ;
smbc_setFunctionLseek ( context , SMBC_lseek_ctx ) ;
smbc_setFunctionFtruncate ( context , SMBC_ftruncate_ctx ) ;
smbc_setFunctionStat ( context , SMBC_stat_ctx ) ;
2009-02-12 18:39:17 +03:00
smbc_setFunctionStatVFS ( context , SMBC_statvfs_ctx ) ;
smbc_setFunctionFstatVFS ( context , SMBC_fstatvfs_ctx ) ;
2008-03-04 02:13:33 +03:00
smbc_setFunctionFstat ( context , SMBC_fstat_ctx ) ;
smbc_setFunctionOpendir ( context , SMBC_opendir_ctx ) ;
smbc_setFunctionClosedir ( context , SMBC_closedir_ctx ) ;
smbc_setFunctionReaddir ( context , SMBC_readdir_ctx ) ;
smbc_setFunctionGetdents ( context , SMBC_getdents_ctx ) ;
smbc_setFunctionMkdir ( context , SMBC_mkdir_ctx ) ;
smbc_setFunctionRmdir ( context , SMBC_rmdir_ctx ) ;
smbc_setFunctionTelldir ( context , SMBC_telldir_ctx ) ;
smbc_setFunctionLseekdir ( context , SMBC_lseekdir_ctx ) ;
smbc_setFunctionFstatdir ( context , SMBC_fstatdir_ctx ) ;
smbc_setFunctionChmod ( context , SMBC_chmod_ctx ) ;
smbc_setFunctionUtimes ( context , SMBC_utimes_ctx ) ;
smbc_setFunctionSetxattr ( context , SMBC_setxattr_ctx ) ;
smbc_setFunctionGetxattr ( context , SMBC_getxattr_ctx ) ;
smbc_setFunctionRemovexattr ( context , SMBC_removexattr_ctx ) ;
smbc_setFunctionListxattr ( context , SMBC_listxattr_ctx ) ;
2010-12-31 12:07:45 +03:00
2008-03-04 02:13:33 +03:00
smbc_setFunctionOpenPrintJob ( context , SMBC_open_print_job_ctx ) ;
smbc_setFunctionPrintFile ( context , SMBC_print_file_ctx ) ;
smbc_setFunctionListPrintJobs ( context , SMBC_list_print_jobs_ctx ) ;
smbc_setFunctionUnlinkPrintJob ( context , SMBC_unlink_print_job_ctx ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
return context ;
2008-02-28 19:23:20 +03:00
}
/*
* Free a context
*
* Returns 0 on success . Otherwise returns 1 , the SMBCCTX is _not_ freed
* and thus you ' ll be leaking memory if not handled properly .
*
*/
int
smbc_free_context ( SMBCCTX * context ,
int shutdown_ctx )
{
2008-03-02 04:44:21 +03:00
if ( ! context ) {
errno = EBADF ;
return 1 ;
2008-02-28 19:23:20 +03:00
}
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
if ( shutdown_ctx ) {
SMBCFILE * f ;
DEBUG ( 1 , ( " Performing aggressive shutdown. \n " ) ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
f = context - > internal - > files ;
while ( f ) {
2008-03-04 02:13:33 +03:00
smbc_getFunctionClose ( context ) ( context , f ) ;
2008-03-02 04:44:21 +03:00
f = f - > next ;
}
context - > internal - > files = NULL ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
/* First try to remove the servers the nice way. */
2008-03-04 02:13:33 +03:00
if ( smbc_getFunctionPurgeCachedServers ( context ) ( context ) ) {
2008-03-02 04:44:21 +03:00
SMBCSRV * s ;
SMBCSRV * next ;
DEBUG ( 1 , ( " Could not purge all servers, "
" Nice way shutdown failed. \n " ) ) ;
s = context - > internal - > servers ;
while ( s ) {
2011-07-11 16:29:28 +04:00
DEBUG ( 1 , ( " Forced shutdown: %p (cli=%p) \n " ,
s , s - > cli ) ) ;
2008-03-02 04:44:21 +03:00
cli_shutdown ( s - > cli ) ;
2008-03-04 02:13:33 +03:00
smbc_getFunctionRemoveCachedServer ( context ) ( context ,
2008-03-02 04:44:21 +03:00
s ) ;
next = s - > next ;
DLIST_REMOVE ( context - > internal - > servers , s ) ;
SAFE_FREE ( s ) ;
s = next ;
}
context - > internal - > servers = NULL ;
}
2008-02-28 19:23:20 +03:00
}
2008-03-02 04:44:21 +03:00
else {
/* This is the polite way */
2008-03-04 02:13:33 +03:00
if ( smbc_getFunctionPurgeCachedServers ( context ) ( context ) ) {
2008-03-02 04:44:21 +03:00
DEBUG ( 1 , ( " Could not purge all servers, "
" free_context failed. \n " ) ) ;
errno = EBUSY ;
return 1 ;
}
if ( context - > internal - > servers ) {
DEBUG ( 1 , ( " Active servers in context, "
" free_context failed. \n " ) ) ;
errno = EBUSY ;
return 1 ;
}
if ( context - > internal - > files ) {
DEBUG ( 1 , ( " Active files in context, "
" free_context failed. \n " ) ) ;
errno = EBUSY ;
return 1 ;
}
2008-02-28 19:23:20 +03:00
}
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
/* Things we have to clean up */
2008-03-04 02:13:33 +03:00
smbc_setWorkgroup ( context , NULL ) ;
smbc_setNetbiosName ( context , NULL ) ;
smbc_setUser ( context , NULL ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
DEBUG ( 3 , ( " Context %p successfully freed \n " , context ) ) ;
2008-07-15 16:57:32 +04:00
2009-03-18 00:53:06 +03:00
/* Free any DFS auth context. */
TALLOC_FREE ( context - > internal - > auth_info ) ;
2008-08-13 00:35:15 +04:00
SAFE_FREE ( context - > internal ) ;
SAFE_FREE ( context ) ;
2008-07-15 16:57:32 +04:00
2009-05-13 22:37:17 +04:00
/* Protect access to the count of contexts in use */
if ( SMB_THREAD_LOCK ( initialized_ctx_count_mutex ) ! = 0 ) {
smb_panic ( " error locking 'initialized_ctx_count' " ) ;
}
2008-08-13 00:35:15 +04:00
if ( initialized_ctx_count ) {
initialized_ctx_count - - ;
}
2008-07-15 16:57:32 +04:00
2009-05-13 22:37:17 +04:00
if ( initialized_ctx_count = = 0 ) {
SMBC_module_terminate ( ) ;
}
/* Unlock the mutex */
if ( SMB_THREAD_UNLOCK ( initialized_ctx_count_mutex ) ! = 0 ) {
smb_panic ( " error unlocking 'initialized_ctx_count' " ) ;
2008-08-13 00:35:15 +04:00
}
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
return 0 ;
2008-02-28 19:23:20 +03:00
}
2008-03-02 04:44:21 +03:00
/**
* Deprecated interface . Do not use . Instead , use the various
* smbc_setOption * ( ) functions or smbc_setFunctionAuthDataWithContext ( ) .
2008-02-28 19:23:20 +03:00
*/
void
smbc_option_set ( SMBCCTX * context ,
char * option_name ,
. . . /* option_value */ )
{
2008-03-02 04:44:21 +03:00
va_list ap ;
union {
int i ;
bool b ;
smbc_get_auth_data_with_context_fn auth_fn ;
void * v ;
const char * s ;
} option_value ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
va_start ( ap , option_name ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
if ( strcmp ( option_name , " debug_to_stderr " ) = = 0 ) {
option_value . b = ( bool ) va_arg ( ap , int ) ;
smbc_setOptionDebugToStderr ( context , option_value . b ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " full_time_names " ) = = 0 ) {
option_value . b = ( bool ) va_arg ( ap , int ) ;
smbc_setOptionFullTimeNames ( context , option_value . b ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " open_share_mode " ) = = 0 ) {
option_value . i = va_arg ( ap , int ) ;
smbc_setOptionOpenShareMode ( context , option_value . i ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " auth_function " ) = = 0 ) {
option_value . auth_fn =
va_arg ( ap , smbc_get_auth_data_with_context_fn ) ;
smbc_setFunctionAuthDataWithContext ( context , option_value . auth_fn ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " user_data " ) = = 0 ) {
option_value . v = va_arg ( ap , void * ) ;
smbc_setOptionUserData ( context , option_value . v ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " smb_encrypt_level " ) = = 0 ) {
option_value . s = va_arg ( ap , const char * ) ;
if ( strcmp ( option_value . s , " none " ) = = 0 ) {
smbc_setOptionSmbEncryptionLevel ( context ,
SMBC_ENCRYPTLEVEL_NONE ) ;
} else if ( strcmp ( option_value . s , " request " ) = = 0 ) {
smbc_setOptionSmbEncryptionLevel ( context ,
SMBC_ENCRYPTLEVEL_REQUEST ) ;
} else if ( strcmp ( option_value . s , " require " ) = = 0 ) {
smbc_setOptionSmbEncryptionLevel ( context ,
SMBC_ENCRYPTLEVEL_REQUIRE ) ;
}
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " browse_max_lmb_count " ) = = 0 ) {
option_value . i = va_arg ( ap , int ) ;
smbc_setOptionBrowseMaxLmbCount ( context , option_value . i ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " urlencode_readdir_entries " ) = = 0 ) {
option_value . b = ( bool ) va_arg ( ap , int ) ;
smbc_setOptionUrlEncodeReaddirEntries ( context , option_value . b ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " one_share_per_server " ) = = 0 ) {
option_value . b = ( bool ) va_arg ( ap , int ) ;
smbc_setOptionOneSharePerServer ( context , option_value . b ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " use_kerberos " ) = = 0 ) {
option_value . b = ( bool ) va_arg ( ap , int ) ;
smbc_setOptionUseKerberos ( context , option_value . b ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " fallback_after_kerberos " ) = = 0 ) {
option_value . b = ( bool ) va_arg ( ap , int ) ;
smbc_setOptionFallbackAfterKerberos ( context , option_value . b ) ;
2010-12-31 12:07:45 +03:00
2010-01-24 21:24:10 +03:00
} else if ( strcmp ( option_name , " use_ccache " ) = = 0 ) {
option_value . b = ( bool ) va_arg ( ap , int ) ;
smbc_setOptionUseCCache ( context , option_value . b ) ;
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " no_auto_anonymous_login " ) = = 0 ) {
option_value . b = ( bool ) va_arg ( ap , int ) ;
smbc_setOptionNoAutoAnonymousLogin ( context , option_value . b ) ;
2008-02-29 21:34:35 +03:00
}
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
va_end ( ap ) ;
2008-02-28 19:23:20 +03:00
}
/*
2008-03-02 04:44:21 +03:00
* Deprecated interface . Do not use . Instead , use the various
* smbc_getOption * ( ) functions .
2008-02-28 19:23:20 +03:00
*/
void *
smbc_option_get ( SMBCCTX * context ,
char * option_name )
{
2008-03-02 04:44:21 +03:00
if ( strcmp ( option_name , " debug_stderr " ) = = 0 ) {
2008-02-28 19:23:20 +03:00
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
2008-03-02 04:44:21 +03:00
return ( void * ) ( intptr_t ) smbc_getOptionDebugToStderr ( context ) ;
2008-02-28 19:23:20 +03:00
# else
2008-03-02 04:44:21 +03:00
return ( void * ) smbc_getOptionDebugToStderr ( context ) ;
2008-02-28 19:23:20 +03:00
# endif
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " full_time_names " ) = = 0 ) {
2008-02-28 19:23:20 +03:00
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
2008-03-02 04:44:21 +03:00
return ( void * ) ( intptr_t ) smbc_getOptionFullTimeNames ( context ) ;
2008-02-28 19:23:20 +03:00
# else
2008-03-02 04:44:21 +03:00
return ( void * ) smbc_getOptionFullTimeNames ( context ) ;
2008-02-28 19:23:20 +03:00
# endif
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " open_share_mode " ) = = 0 ) {
2008-02-28 19:23:20 +03:00
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
2008-03-02 04:44:21 +03:00
return ( void * ) ( intptr_t ) smbc_getOptionOpenShareMode ( context ) ;
2008-02-28 19:23:20 +03:00
# else
2008-03-02 04:44:21 +03:00
return ( void * ) smbc_getOptionOpenShareMode ( context ) ;
2008-02-28 19:23:20 +03:00
# endif
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " auth_function " ) = = 0 ) {
return ( void * ) smbc_getFunctionAuthDataWithContext ( context ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " user_data " ) = = 0 ) {
return smbc_getOptionUserData ( context ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " smb_encrypt_level " ) = = 0 ) {
switch ( smbc_getOptionSmbEncryptionLevel ( context ) )
{
case 0 :
2011-05-05 21:41:59 +04:00
return discard_const_p ( void , " none " ) ;
2008-03-02 04:44:21 +03:00
case 1 :
2011-05-05 21:41:59 +04:00
return discard_const_p ( void , " request " ) ;
2008-03-02 04:44:21 +03:00
case 2 :
2011-05-05 21:41:59 +04:00
return discard_const_p ( void , " require " ) ;
2008-03-02 04:44:21 +03:00
}
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " smb_encrypt_on " ) = = 0 ) {
SMBCSRV * s ;
unsigned int num_servers = 0 ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
for ( s = context - > internal - > servers ; s ; s = s - > next ) {
num_servers + + ;
2011-07-18 21:46:59 +04:00
if ( ! cli_state_encryption_on ( s - > cli ) ) {
2008-03-02 04:44:21 +03:00
return ( void * ) false ;
}
}
2008-02-28 19:23:20 +03:00
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
2008-03-02 04:44:21 +03:00
return ( void * ) ( intptr_t ) ( bool ) ( num_servers > 0 ) ;
2008-02-28 19:23:20 +03:00
# else
2008-03-02 04:44:21 +03:00
return ( void * ) ( bool ) ( num_servers > 0 ) ;
2008-02-28 19:23:20 +03:00
# endif
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " browse_max_lmb_count " ) = = 0 ) {
2008-02-28 19:23:20 +03:00
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
2008-03-02 04:44:21 +03:00
return ( void * ) ( intptr_t ) smbc_getOptionBrowseMaxLmbCount ( context ) ;
2008-02-28 19:23:20 +03:00
# else
2008-03-02 04:44:21 +03:00
return ( void * ) smbc_getOptionBrowseMaxLmbCount ( context ) ;
2008-02-28 19:23:20 +03:00
# endif
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " urlencode_readdir_entries " ) = = 0 ) {
2008-02-28 19:23:20 +03:00
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
2008-03-02 04:44:21 +03:00
return ( void * ) ( intptr_t ) smbc_getOptionUrlEncodeReaddirEntries ( context ) ;
2008-02-28 19:23:20 +03:00
# else
2008-03-02 04:44:21 +03:00
return ( void * ) ( bool ) smbc_getOptionUrlEncodeReaddirEntries ( context ) ;
2008-02-28 19:23:20 +03:00
# endif
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " one_share_per_server " ) = = 0 ) {
2008-02-28 19:23:20 +03:00
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
2008-03-02 04:44:21 +03:00
return ( void * ) ( intptr_t ) smbc_getOptionOneSharePerServer ( context ) ;
2008-02-28 19:23:20 +03:00
# else
2008-03-02 04:44:21 +03:00
return ( void * ) ( bool ) smbc_getOptionOneSharePerServer ( context ) ;
2008-02-28 19:23:20 +03:00
# endif
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " use_kerberos " ) = = 0 ) {
2008-02-28 19:23:20 +03:00
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
2008-03-02 04:44:21 +03:00
return ( void * ) ( intptr_t ) smbc_getOptionUseKerberos ( context ) ;
2008-02-28 19:23:20 +03:00
# else
2008-03-02 04:44:21 +03:00
return ( void * ) ( bool ) smbc_getOptionUseKerberos ( context ) ;
2008-02-28 19:23:20 +03:00
# endif
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " fallback_after_kerberos " ) = = 0 ) {
2008-02-28 19:23:20 +03:00
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
2008-03-02 04:44:21 +03:00
return ( void * ) ( intptr_t ) smbc_getOptionFallbackAfterKerberos ( context ) ;
2008-02-28 19:23:20 +03:00
# else
2008-03-02 04:44:21 +03:00
return ( void * ) ( bool ) smbc_getOptionFallbackAfterKerberos ( context ) ;
2008-02-28 19:23:20 +03:00
# endif
2010-12-31 12:07:45 +03:00
2010-01-24 21:24:10 +03:00
} else if ( strcmp ( option_name , " use_ccache " ) = = 0 ) {
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
return ( void * ) ( intptr_t ) smbc_getOptionUseCCache ( context ) ;
# else
return ( void * ) ( bool ) smbc_getOptionUseCCache ( context ) ;
# endif
2008-03-02 04:44:21 +03:00
} else if ( strcmp ( option_name , " no_auto_anonymous_login " ) = = 0 ) {
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
return ( void * ) ( intptr_t ) smbc_getOptionNoAutoAnonymousLogin ( context ) ;
# else
return ( void * ) ( bool ) smbc_getOptionNoAutoAnonymousLogin ( context ) ;
# endif
}
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
return NULL ;
2008-02-28 19:23:20 +03:00
}
/*
* Initialize the library , etc .
*
* We accept a struct containing handle information .
* valid values for info - > debug from 0 to 100 ,
* and insist that info - > fn must be non - null .
*/
SMBCCTX *
smbc_init_context ( SMBCCTX * context )
{
2008-03-02 04:44:21 +03:00
int pid ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
if ( ! context ) {
errno = EBADF ;
return NULL ;
2008-02-28 19:23:20 +03:00
}
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
/* Do not initialise the same client twice */
if ( context - > internal - > initialized ) {
2008-03-02 05:19:52 +03:00
return NULL ;
2008-03-02 04:44:21 +03:00
}
2010-12-31 12:07:45 +03:00
2008-03-17 18:34:25 +03:00
if ( ( ! smbc_getFunctionAuthData ( context ) & &
! smbc_getFunctionAuthDataWithContext ( context ) ) | |
2008-03-04 02:13:33 +03:00
smbc_getDebug ( context ) < 0 | |
smbc_getDebug ( context ) > 100 ) {
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
errno = EINVAL ;
return NULL ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
}
2010-12-31 12:07:45 +03:00
2008-03-04 02:13:33 +03:00
if ( ! smbc_getUser ( context ) ) {
2008-02-28 19:23:20 +03:00
/*
2008-03-02 04:44:21 +03:00
* FIXME : Is this the best way to get the user info ?
2008-02-28 19:23:20 +03:00
*/
2010-01-16 04:22:35 +03:00
char * user = getenv ( " USER " ) ;
2008-03-02 04:44:21 +03:00
/* walk around as "guest" if no username can be found */
2008-03-04 02:13:33 +03:00
if ( ! user ) {
user = SMB_STRDUP ( " guest " ) ;
} else {
user = SMB_STRDUP ( user ) ;
}
if ( ! user ) {
errno = ENOMEM ;
return NULL ;
}
smbc_setUser ( context , user ) ;
2010-01-16 04:22:35 +03:00
SAFE_FREE ( user ) ;
if ( ! smbc_getUser ( context ) ) {
errno = ENOMEM ;
return NULL ;
}
2008-03-02 04:44:21 +03:00
}
2010-12-31 12:07:45 +03:00
2008-03-04 02:13:33 +03:00
if ( ! smbc_getNetbiosName ( context ) ) {
2008-03-02 04:44:21 +03:00
/*
* We try to get our netbios name from the config . If that
* fails we fall back on constructing our netbios name from
* our hostname etc
*/
2008-03-04 02:13:33 +03:00
char * netbios_name ;
2011-06-09 09:31:03 +04:00
if ( lp_netbios_name ( ) ) {
netbios_name = SMB_STRDUP ( lp_netbios_name ( ) ) ;
2008-03-04 02:13:33 +03:00
} else {
2008-03-02 04:44:21 +03:00
/*
* Hmmm , I want to get hostname as well , but I am too
* lazy for the moment
*/
pid = sys_getpid ( ) ;
2008-03-04 02:13:33 +03:00
netbios_name = ( char * ) SMB_MALLOC ( 17 ) ;
if ( ! netbios_name ) {
2008-03-02 04:44:21 +03:00
errno = ENOMEM ;
return NULL ;
}
2008-03-04 02:13:33 +03:00
slprintf ( netbios_name , 16 ,
" smbc%s%d " , smbc_getUser ( context ) , pid ) ;
2008-03-02 04:44:21 +03:00
}
2008-03-04 02:13:33 +03:00
if ( ! netbios_name ) {
errno = ENOMEM ;
return NULL ;
}
2010-12-31 12:07:45 +03:00
2008-03-04 02:13:33 +03:00
smbc_setNetbiosName ( context , netbios_name ) ;
2010-01-16 04:22:35 +03:00
SAFE_FREE ( netbios_name ) ;
if ( ! smbc_getNetbiosName ( context ) ) {
errno = ENOMEM ;
return NULL ;
}
2008-03-02 04:44:21 +03:00
}
2010-12-31 12:07:45 +03:00
2008-03-04 02:13:33 +03:00
DEBUG ( 1 , ( " Using netbios name %s. \n " , smbc_getNetbiosName ( context ) ) ) ;
2010-12-31 12:07:45 +03:00
2008-03-04 02:13:33 +03:00
if ( ! smbc_getWorkgroup ( context ) ) {
char * workgroup ;
2008-03-02 04:44:21 +03:00
if ( lp_workgroup ( ) ) {
2008-03-04 02:13:33 +03:00
workgroup = SMB_STRDUP ( lp_workgroup ( ) ) ;
2008-03-02 04:44:21 +03:00
}
else {
/* TODO: Think about a decent default workgroup */
2008-03-04 02:13:33 +03:00
workgroup = SMB_STRDUP ( " samba " ) ;
2008-02-28 19:23:20 +03:00
}
2008-03-04 02:13:33 +03:00
if ( ! workgroup ) {
errno = ENOMEM ;
return NULL ;
}
smbc_setWorkgroup ( context , workgroup ) ;
2010-01-16 04:22:35 +03:00
SAFE_FREE ( workgroup ) ;
if ( ! smbc_getWorkgroup ( context ) ) {
errno = ENOMEM ;
return NULL ;
}
2008-02-28 19:23:20 +03:00
}
2010-12-31 12:07:45 +03:00
2008-03-04 02:13:33 +03:00
DEBUG ( 1 , ( " Using workgroup %s. \n " , smbc_getWorkgroup ( context ) ) ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
/* shortest timeout is 1 second */
2008-03-04 02:13:33 +03:00
if ( smbc_getTimeout ( context ) > 0 & & smbc_getTimeout ( context ) < 1000 )
smbc_setTimeout ( context , 1000 ) ;
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
context - > internal - > initialized = True ;
2009-05-13 22:37:17 +04:00
/* Protect access to the count of contexts in use */
if ( SMB_THREAD_LOCK ( initialized_ctx_count_mutex ) ! = 0 ) {
smb_panic ( " error locking 'initialized_ctx_count' " ) ;
}
2008-08-13 00:35:15 +04:00
initialized_ctx_count + + ;
2009-05-13 22:37:17 +04:00
/* Unlock the mutex */
if ( SMB_THREAD_UNLOCK ( initialized_ctx_count_mutex ) ! = 0 ) {
smb_panic ( " error unlocking 'initialized_ctx_count' " ) ;
}
2010-12-31 12:07:45 +03:00
2008-03-02 04:44:21 +03:00
return context ;
2008-02-28 19:23:20 +03:00
}
/* Return the verion of samba, and thus libsmbclient */
const char *
smbc_version ( void )
{
2009-01-16 00:27:52 +03:00
return samba_version_string ( ) ;
2008-02-28 19:23:20 +03:00
}
2008-07-09 04:44:39 +04:00
/*
* Set the credentials so DFS will work when following referrals .
2009-03-18 00:53:06 +03:00
* This function is broken and must be removed . No SMBCCTX arg . . .
* JRA .
2008-07-09 04:44:39 +04:00
*/
2009-03-18 00:53:06 +03:00
2008-07-09 04:44:39 +04:00
void
2009-02-23 21:50:11 +03:00
smbc_set_credentials ( const char * workgroup ,
2009-03-18 00:53:06 +03:00
const char * user ,
const char * password ,
smbc_bool use_kerberos ,
const char * signing_state )
2008-07-09 04:44:39 +04:00
{
2009-03-18 00:53:06 +03:00
d_printf ( " smbc_set_credentials is obsolete. Replace with smbc_set_credentials_with_fallback(). \n " ) ;
2008-07-09 04:44:39 +04:00
}
2009-02-20 07:00:46 +03:00
void smbc_set_credentials_with_fallback ( SMBCCTX * context ,
2009-02-21 03:41:41 +03:00
const char * workgroup ,
const char * user ,
const char * password )
2009-02-20 07:00:46 +03:00
{
smbc_bool use_kerberos = false ;
const char * signing_state = " off " ;
2009-08-07 09:42:51 +04:00
struct user_auth_info * auth_info = NULL ;
2009-03-18 00:53:06 +03:00
2009-08-07 09:42:51 +04:00
if ( ! context ) {
return ;
}
if ( ! workgroup | | ! * workgroup ) {
workgroup = smbc_getWorkgroup ( context ) ;
2009-03-18 00:53:06 +03:00
}
2009-08-07 09:42:51 +04:00
if ( ! user ) {
user = smbc_getUser ( context ) ;
}
2009-02-20 17:51:36 +03:00
2009-08-07 09:42:51 +04:00
if ( ! password ) {
password = " " ;
2009-02-20 07:00:46 +03:00
}
2009-03-18 00:53:06 +03:00
auth_info = user_auth_info_init ( NULL ) ;
2009-08-07 09:42:51 +04:00
if ( ! auth_info ) {
2009-03-18 00:53:06 +03:00
DEBUG ( 0 , ( " smbc_set_credentials_with_fallback: allocation fail \n " ) ) ;
return ;
}
2009-02-20 07:00:46 +03:00
if ( smbc_getOptionUseKerberos ( context ) ) {
use_kerberos = True ;
}
2011-11-02 21:55:55 +04:00
if ( lp_client_signing ( ) ! = SMB_SIGNING_OFF ) {
signing_state = " if_required " ;
2009-02-20 07:00:46 +03:00
}
2011-11-02 21:55:55 +04:00
if ( lp_client_signing ( ) = = SMB_SIGNING_REQUIRED ) {
signing_state = " required " ;
2009-02-20 07:00:46 +03:00
}
2009-03-18 00:53:06 +03:00
set_cmdline_auth_info_username ( auth_info , user ) ;
2011-06-08 09:41:24 +04:00
set_cmdline_auth_info_domain ( auth_info , workgroup ) ;
2009-03-18 00:53:06 +03:00
set_cmdline_auth_info_password ( auth_info , password ) ;
set_cmdline_auth_info_use_kerberos ( auth_info , use_kerberos ) ;
set_cmdline_auth_info_signing_state ( auth_info , signing_state ) ;
set_cmdline_auth_info_fallback_after_kerberos ( auth_info ,
smbc_getOptionFallbackAfterKerberos ( context ) ) ;
2010-01-24 21:24:10 +03:00
set_cmdline_auth_info_use_ccache (
auth_info , smbc_getOptionUseCCache ( context ) ) ;
2009-02-20 07:00:46 +03:00
2009-03-18 00:53:06 +03:00
TALLOC_FREE ( context - > internal - > auth_info ) ;
context - > internal - > auth_info = auth_info ;
2009-02-20 07:00:46 +03:00
}