2006-03-20 03:28:12 +03:00
/*
Unix SMB / CIFS implementation .
Samba utility functions
Copyright ( C ) Andrew Tridgell 1992 - 1998
Copyright ( C ) Jeremy Allison 2001 - 2002
Copyright ( C ) Simo Sorce 2001
Copyright ( C ) Jim McDonough ( jmcd @ us . ibm . com ) 2003.
Copyright ( C ) James J Myers 2003
2007-08-31 03:15:12 +04:00
Copyright ( C ) Jelmer Vernooij 2005 - 2007
2006-03-20 03:28:12 +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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-03-20 03:28:12 +03:00
( 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
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-03-20 03:28:12 +03:00
*/
# include "includes.h"
# include "dynconfig.h"
# include "system/network.h"
# include "system/filesys.h"
2007-08-31 03:15:12 +04:00
# include "system/dir.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2006-03-20 03:28:12 +03:00
/**
* @ file
* @ brief Misc utility functions
*/
2007-10-01 22:52:55 +04:00
_PUBLIC_ bool lp_is_mydomain ( struct loadparm_context * lp_ctx ,
const char * domain )
{
return strequal ( lp_workgroup ( lp_ctx ) , domain ) ;
}
2006-03-20 03:28:12 +03:00
/**
see if a string matches either our primary or one of our secondary
netbios aliases . do a case insensitive match
*/
2007-10-01 22:52:55 +04:00
_PUBLIC_ bool lp_is_myname ( struct loadparm_context * lp_ctx , const char * name )
2006-03-20 03:28:12 +03:00
{
const char * * aliases ;
int i ;
2007-10-01 22:52:55 +04:00
if ( strcasecmp ( name , lp_netbios_name ( lp_ctx ) ) = = 0 ) {
2007-10-07 01:39:52 +04:00
return true ;
2006-03-20 03:28:12 +03:00
}
2007-10-01 22:52:55 +04:00
aliases = lp_netbios_aliases ( lp_ctx ) ;
2006-03-20 03:28:12 +03:00
for ( i = 0 ; aliases & & aliases [ i ] ; i + + ) {
if ( strcasecmp ( name , aliases [ i ] ) = = 0 ) {
2007-10-07 01:39:52 +04:00
return true ;
2006-03-20 03:28:12 +03:00
}
}
2007-10-07 01:39:52 +04:00
return false ;
2006-03-20 03:28:12 +03:00
}
/**
A useful function for returning a path in the Samba lock directory .
* */
2007-10-01 22:52:55 +04:00
_PUBLIC_ char * lock_path ( TALLOC_CTX * mem_ctx , struct loadparm_context * lp_ctx ,
const char * name )
2006-03-20 03:28:12 +03:00
{
char * fname , * dname ;
if ( name = = NULL ) {
return NULL ;
}
if ( name [ 0 ] = = 0 | | name [ 0 ] = = ' / ' | | strstr ( name , " :/ " ) ) {
return talloc_strdup ( mem_ctx , name ) ;
}
2007-10-01 22:52:55 +04:00
dname = talloc_strdup ( mem_ctx , lp_lockdir ( lp_ctx ) ) ;
2006-03-20 03:28:12 +03:00
trim_string ( dname , " " , " / " ) ;
if ( ! directory_exist ( dname ) ) {
mkdir ( dname , 0755 ) ;
}
fname = talloc_asprintf ( mem_ctx , " %s/%s " , dname , name ) ;
talloc_free ( dname ) ;
return fname ;
}
2007-01-24 05:48:40 +03:00
/**
* @ brief Returns an absolute path to a file in the directory containing the current config file
*
* @ param name File to find , relative to the config file directory .
*
* @ retval Pointer to a talloc ' ed string containing the full path .
* */
2007-10-01 22:52:55 +04:00
_PUBLIC_ char * config_path ( TALLOC_CTX * mem_ctx , struct loadparm_context * lp_ctx ,
const char * name )
2007-01-24 05:48:40 +03:00
{
char * fname , * config_dir , * p ;
2007-10-01 22:52:55 +04:00
config_dir = talloc_strdup ( mem_ctx , lp_configfile ( lp_ctx ) ) ;
2007-01-24 05:48:40 +03:00
p = strrchr ( config_dir , ' / ' ) ;
if ( ! p ) {
return NULL ;
}
p [ 0 ] = ' \0 ' ;
fname = talloc_asprintf ( mem_ctx , " %s/%s " , config_dir , name ) ;
talloc_free ( config_dir ) ;
return fname ;
}
2006-03-20 03:28:12 +03:00
/**
* @ brief Returns an absolute path to a file in the Samba private directory .
*
* @ param name File to find , relative to PRIVATEDIR .
* if name is not relative , then use it as - is
*
* @ retval Pointer to a talloc ' ed string containing the full path .
* */
2007-10-01 22:52:55 +04:00
_PUBLIC_ char * private_path ( TALLOC_CTX * mem_ctx ,
struct loadparm_context * lp_ctx ,
const char * name )
2006-03-20 03:28:12 +03:00
{
char * fname ;
if ( name = = NULL ) {
return NULL ;
}
if ( name [ 0 ] = = 0 | | name [ 0 ] = = ' / ' | | strstr ( name , " :/ " ) ) {
return talloc_strdup ( mem_ctx , name ) ;
}
2007-10-01 22:52:55 +04:00
fname = talloc_asprintf ( mem_ctx , " %s/%s " , lp_private_dir ( lp_ctx ) , name ) ;
2006-03-20 03:28:12 +03:00
return fname ;
}
/**
return a path in the smbd . tmp directory , where all temporary file
for smbd go . If NULL is passed for name then return the directory
path itself
*/
2007-10-01 22:52:55 +04:00
_PUBLIC_ char * smbd_tmp_path ( TALLOC_CTX * mem_ctx ,
struct loadparm_context * lp_ctx ,
const char * name )
2006-03-20 03:28:12 +03:00
{
char * fname , * dname ;
2007-10-01 22:52:55 +04:00
dname = private_path ( mem_ctx , lp_ctx , " smbd.tmp " ) ;
2006-03-20 03:28:12 +03:00
if ( ! directory_exist ( dname ) ) {
mkdir ( dname , 0755 ) ;
}
if ( name = = NULL ) {
return dname ;
}
fname = talloc_asprintf ( mem_ctx , " %s/%s " , dname , name ) ;
talloc_free ( dname ) ;
return fname ;
}
2007-08-31 03:15:12 +04:00
/**
* Obtain the init function from a shared library file
*/
_PUBLIC_ init_module_fn load_module ( TALLOC_CTX * mem_ctx , const char * path )
{
void * handle ;
void * init_fn ;
handle = dlopen ( path , RTLD_NOW ) ;
if ( handle = = NULL ) {
DEBUG ( 0 , ( " Unable to open %s: %s \n " , path , dlerror ( ) ) ) ;
return NULL ;
}
init_fn = dlsym ( handle , " init_module " ) ;
if ( init_fn = = NULL ) {
DEBUG ( 0 , ( " Unable to find init_module() in %s: %s \n " , path , dlerror ( ) ) ) ;
DEBUG ( 1 , ( " Loading module '%s' failed \n " , path ) ) ;
dlclose ( handle ) ;
return NULL ;
}
return ( init_module_fn ) init_fn ;
}
/**
* Obtain list of init functions from the modules in the specified
* directory
*/
_PUBLIC_ init_module_fn * load_modules ( TALLOC_CTX * mem_ctx , const char * path )
{
DIR * dir ;
struct dirent * entry ;
char * filename ;
int success = 0 ;
init_module_fn * ret = talloc_array ( mem_ctx , init_module_fn , 2 ) ;
ret [ 0 ] = NULL ;
dir = opendir ( path ) ;
if ( dir = = NULL ) {
talloc_free ( ret ) ;
return NULL ;
}
while ( ( entry = readdir ( dir ) ) ) {
if ( ISDOT ( entry - > d_name ) | | ISDOTDOT ( entry - > d_name ) )
continue ;
filename = talloc_asprintf ( mem_ctx , " %s/%s " , path , entry - > d_name ) ;
ret [ success ] = load_module ( mem_ctx , filename ) ;
if ( ret [ success ] ) {
ret = talloc_realloc ( mem_ctx , ret , init_module_fn , success + 2 ) ;
success + + ;
ret [ success ] = NULL ;
}
talloc_free ( filename ) ;
}
closedir ( dir ) ;
return ret ;
}
/**
* Run the specified init functions .
*
* @ return true if all functions ran successfully , false otherwise
*/
_PUBLIC_ bool run_init_functions ( init_module_fn * fns )
{
int i ;
bool ret = true ;
if ( fns = = NULL )
return true ;
for ( i = 0 ; fns [ i ] ; i + + ) { ret & = ( bool ) NT_STATUS_IS_OK ( fns [ i ] ( ) ) ; }
return ret ;
}
2007-10-01 22:52:55 +04:00
static char * modules_path ( TALLOC_CTX * mem_ctx , struct loadparm_context * lp_ctx ,
const char * name )
2006-03-20 03:28:12 +03:00
{
2006-10-29 20:40:19 +03:00
const char * env_moduledir = getenv ( " LD_SAMBA_MODULE_PATH " ) ;
return talloc_asprintf ( mem_ctx , " %s/%s " ,
2007-10-01 22:52:55 +04:00
env_moduledir ? env_moduledir : lp_modulesdir ( lp_ctx ) ,
name ) ;
2006-03-20 03:28:12 +03:00
}
/**
* Load the initialization functions from DSO files for a specific subsystem .
*
* Will return an array of function pointers to initialization functions
*/
2007-10-01 22:52:55 +04:00
_PUBLIC_ init_module_fn * load_samba_modules ( TALLOC_CTX * mem_ctx , struct loadparm_context * lp_ctx , const char * subsystem )
2006-03-20 03:28:12 +03:00
{
2007-10-01 22:52:55 +04:00
char * path = modules_path ( mem_ctx , lp_ctx , subsystem ) ;
2006-03-20 03:28:12 +03:00
init_module_fn * ret ;
ret = load_modules ( mem_ctx , path ) ;
talloc_free ( path ) ;
return ret ;
}
2007-10-01 22:52:55 +04:00
_PUBLIC_ const char * lp_messaging_path ( TALLOC_CTX * mem_ctx ,
struct loadparm_context * lp_ctx )
{
return smbd_tmp_path ( mem_ctx , lp_ctx , " messaging " ) ;
}
2006-03-20 03:28:12 +03:00
2007-12-06 19:16:40 +03:00
struct smb_iconv_convenience * global_smb_iconv_convenience = NULL ;
struct smb_iconv_convenience * smb_iconv_convenience_init_lp ( TALLOC_CTX * mem_ctx ,
struct loadparm_context * lp_ctx )
{
return smb_iconv_convenience_init ( mem_ctx , lp_dos_charset ( lp_ctx ) ,
lp_unix_charset ( lp_ctx ) ,
lp_display_charset ( lp_ctx ) ,
lp_parm_bool ( lp_ctx , NULL , " iconv " , " native " , true ) ) ;
}
_PUBLIC_ void reload_charcnv ( void )
{
talloc_free ( global_smb_iconv_convenience ) ;
global_smb_iconv_convenience = smb_iconv_convenience_init_lp ( talloc_autofree_context ( ) , global_loadparm ) ;
}