2000-04-17 08:46:10 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2000-04-17 08:46:10 +04:00
string substitution functions
Copyright ( C ) Andrew Tridgell 1992 - 2000
2006-03-09 18:51:55 +03:00
Copyright ( C ) Gerald Carter 2006
2000-04-17 08:46:10 +04: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-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2000-04-17 08:46:10 +04: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 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2000-04-17 08:46:10 +04:00
*/
# include "includes.h"
2005-04-06 20:28:04 +04:00
extern struct current_user current_user ;
2001-01-23 04:52:30 +03:00
userdom_struct current_user_info ;
2000-04-17 08:46:10 +04:00
fstring remote_proto = " UNKNOWN " ;
2007-11-10 02:09:16 +03:00
/**
2003-03-18 12:52:55 +03:00
* Set the ' local ' machine name
* @ param local_name the name we are being called
* @ param if this is the ' final ' name for us , not be be changed again
*/
2002-08-17 21:00:51 +04:00
2007-11-10 02:09:16 +03:00
static char * local_machine ;
2008-01-07 16:15:48 +03:00
void free_local_machine_name ( void )
{
SAFE_FREE ( local_machine ) ;
}
2007-11-10 02:09:16 +03:00
bool set_local_machine_name ( const char * local_name , bool perm )
2002-08-17 21:00:51 +04:00
{
2007-11-10 02:09:16 +03:00
static bool already_perm = false ;
char * tmp_local_machine = NULL ;
2007-11-04 08:34:46 +03:00
char addr [ INET6_ADDRSTRLEN ] ;
2007-11-10 02:09:16 +03:00
size_t len ;
2002-08-17 21:00:51 +04:00
2007-11-10 02:09:16 +03:00
tmp_local_machine = SMB_STRDUP ( local_name ) ;
if ( ! tmp_local_machine ) {
return false ;
}
2004-05-11 18:54:54 +04:00
trim_char ( tmp_local_machine , ' ' , ' ' ) ;
2003-04-23 05:34:56 +04:00
/*
* Windows NT / 2 k uses " *SMBSERVER " and XP uses " *SMBSERV "
2007-11-10 02:09:16 +03:00
* arrggg ! ! !
2003-04-23 05:34:56 +04:00
*/
2007-11-10 02:09:16 +03:00
if ( strequal ( tmp_local_machine , " *SMBSERVER " ) | |
strequal ( tmp_local_machine , " *SMBSERV " ) ) {
SAFE_FREE ( local_machine ) ;
local_machine = SMB_STRDUP ( client_socket_addr ( get_client_fd ( ) ,
addr , sizeof ( addr ) ) ) ;
SAFE_FREE ( tmp_local_machine ) ;
return local_machine ? true : false ;
2004-05-11 18:54:54 +04:00
}
2003-04-23 05:21:42 +04:00
2007-11-10 02:09:16 +03:00
if ( already_perm ) {
return true ;
}
SAFE_FREE ( local_machine ) ;
len = strlen ( tmp_local_machine ) ;
local_machine = SMB_CALLOC_ARRAY ( char , len + 1 ) ;
if ( ! local_machine ) {
SAFE_FREE ( tmp_local_machine ) ;
return false ;
}
2007-11-16 00:18:42 +03:00
/* alpha_strcpy includes the space for the terminating nul. */
2007-11-10 02:09:16 +03:00
alpha_strcpy ( local_machine , tmp_local_machine ,
2007-11-16 00:18:42 +03:00
SAFE_NETBIOS_CHARS , len + 1 ) ;
2007-11-10 02:09:16 +03:00
strlower_m ( local_machine ) ;
SAFE_FREE ( tmp_local_machine ) ;
2003-03-18 12:52:55 +03:00
already_perm = perm ;
2007-11-10 02:09:16 +03:00
return true ;
}
const char * get_local_machine_name ( void )
{
if ( ! local_machine | | ! * local_machine ) {
return global_myname ( ) ;
}
return local_machine ;
2002-08-17 21:00:51 +04:00
}
2007-11-10 02:09:16 +03:00
/**
2003-03-18 12:52:55 +03:00
* Set the ' remote ' machine name
* @ param remote_name the name our client wants to be called by
* @ param if this is the ' final ' name for them , not be be changed again
*/
2007-11-10 02:09:16 +03:00
static char * remote_machine ;
bool set_remote_machine_name ( const char * remote_name , bool perm )
2002-08-17 21:00:51 +04:00
{
2007-10-19 04:40:25 +04:00
static bool already_perm = False ;
2007-11-10 02:09:16 +03:00
char * tmp_remote_machine ;
size_t len ;
2003-03-18 12:52:55 +03:00
2007-11-10 02:09:16 +03:00
if ( already_perm ) {
return true ;
}
2003-03-18 12:52:55 +03:00
2007-11-10 02:09:16 +03:00
tmp_remote_machine = SMB_STRDUP ( remote_name ) ;
if ( ! tmp_remote_machine ) {
return false ;
}
2003-09-05 23:59:55 +04:00
trim_char ( tmp_remote_machine , ' ' , ' ' ) ;
2007-11-10 02:09:16 +03:00
SAFE_FREE ( remote_machine ) ;
len = strlen ( tmp_remote_machine ) ;
remote_machine = SMB_CALLOC_ARRAY ( char , len + 1 ) ;
if ( ! remote_machine ) {
SAFE_FREE ( tmp_remote_machine ) ;
return false ;
}
2007-11-16 00:18:42 +03:00
/* alpha_strcpy includes the space for the terminating nul. */
2007-11-10 02:09:16 +03:00
alpha_strcpy ( remote_machine , tmp_remote_machine ,
2007-11-16 00:18:42 +03:00
SAFE_NETBIOS_CHARS , len + 1 ) ;
2003-07-27 06:43:22 +04:00
strlower_m ( remote_machine ) ;
2007-11-10 02:09:16 +03:00
SAFE_FREE ( tmp_remote_machine ) ;
2002-08-17 21:00:51 +04:00
2007-11-10 02:09:16 +03:00
already_perm = perm ;
return true ;
2002-08-17 21:00:51 +04:00
}
2007-11-10 02:09:16 +03:00
const char * get_remote_machine_name ( void )
2002-08-17 21:00:51 +04:00
{
2007-11-10 02:09:16 +03:00
return remote_machine ? remote_machine : " " ;
2002-08-17 21:00:51 +04:00
}
2003-08-29 03:57:34 +04:00
/*******************************************************************
Setup the string used by % U substitution .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-20 03:53:24 +03:00
2007-11-10 02:09:16 +03:00
static char * smb_user_name ;
2002-11-20 03:53:24 +03:00
void sub_set_smb_name ( const char * name )
{
2007-11-10 02:09:16 +03:00
char * tmp ;
size_t len ;
bool is_machine_account = false ;
2002-11-20 03:53:24 +03:00
/* don't let anonymous logins override the name */
2007-11-10 02:09:16 +03:00
if ( ! name | | ! * name ) {
2003-08-29 03:57:34 +04:00
return ;
2007-11-10 02:09:16 +03:00
}
2002-11-20 03:53:24 +03:00
2007-11-10 02:09:16 +03:00
tmp = SMB_STRDUP ( name ) ;
if ( ! tmp ) {
return ;
}
trim_char ( tmp , ' ' , ' ' ) ;
strlower_m ( tmp ) ;
2005-11-11 00:10:24 +03:00
2007-11-10 02:09:16 +03:00
len = strlen ( tmp ) ;
2005-11-11 00:10:24 +03:00
2007-11-10 02:09:16 +03:00
if ( len = = 0 ) {
SAFE_FREE ( tmp ) ;
2005-11-11 00:10:24 +03:00
return ;
2007-11-10 02:09:16 +03:00
}
2005-11-11 00:10:24 +03:00
/* long story but here goes....we have to allow usernames
ending in ' $ ' as they are valid machine account names .
So check for a machine account and re - add the ' $ '
at the end after the call to alpha_strcpy ( ) . - - jerry */
2007-11-10 02:09:16 +03:00
if ( tmp [ len - 1 ] = = ' $ ' ) {
2005-11-11 00:10:24 +03:00
is_machine_account = True ;
2007-11-10 02:09:16 +03:00
}
SAFE_FREE ( smb_user_name ) ;
smb_user_name = SMB_CALLOC_ARRAY ( char , len + 1 ) ;
if ( ! smb_user_name ) {
SAFE_FREE ( tmp ) ;
return ;
}
2007-11-16 00:18:42 +03:00
/* alpha_strcpy includes the space for the terminating nul. */
2007-11-10 02:09:16 +03:00
alpha_strcpy ( smb_user_name , tmp ,
SAFE_NETBIOS_CHARS ,
2007-11-16 00:18:42 +03:00
len + 1 ) ;
2005-11-11 00:10:24 +03:00
2007-11-10 02:09:16 +03:00
SAFE_FREE ( tmp ) ;
if ( is_machine_account ) {
len = strlen ( smb_user_name ) ;
2005-11-11 00:10:24 +03:00
smb_user_name [ len - 1 ] = ' $ ' ;
}
2002-11-20 03:53:24 +03:00
}
2007-11-10 02:09:16 +03:00
static const char * get_smb_user_name ( void )
{
return smb_user_name ? smb_user_name : " " ;
}
2003-08-29 03:57:34 +04:00
/*******************************************************************
Setup the strings used by substitutions . Called per packet . Ensure
% U name is set correctly also .
2008-04-30 19:42:39 +04:00
smb_name must be sanitized by alpha_strcpy
2003-08-29 03:57:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-04-30 19:42:39 +04:00
void set_current_user_info ( const char * smb_name , const char * unix_name ,
const char * full_name , const char * domain )
2003-08-29 03:57:34 +04:00
{
2008-04-30 19:42:39 +04:00
fstrcpy ( current_user_info . smb_name , smb_name ) ;
fstrcpy ( current_user_info . unix_name , unix_name ) ;
fstrcpy ( current_user_info . full_name , full_name ) ;
fstrcpy ( current_user_info . domain , domain ) ;
2003-08-29 03:57:34 +04:00
/* The following is safe as current_user_info.smb_name
2007-08-21 05:43:22 +04:00
* has already been sanitised in register_existing_vuid . */
2007-11-10 02:09:16 +03:00
sub_set_smb_name ( current_user_info . smb_name ) ;
2003-08-29 03:57:34 +04:00
}
2002-11-20 03:53:24 +03:00
2005-02-02 19:05:55 +03:00
/*******************************************************************
2007-11-10 02:09:16 +03:00
Return the current active user name .
2005-02-02 19:05:55 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-11-10 02:09:16 +03:00
const char * get_current_username ( void )
2005-02-02 19:05:55 +03:00
{
2007-11-10 02:09:16 +03:00
if ( current_user_info . smb_name [ 0 ] = = ' \0 ' ) {
return get_smb_user_name ( ) ;
}
2005-02-02 19:05:55 +03:00
2007-11-10 02:09:16 +03:00
return current_user_info . smb_name ;
2005-02-02 19:05:55 +03:00
}
2000-04-17 08:46:10 +04:00
/*******************************************************************
2006-03-09 18:51:55 +03:00
Given a pointer to a % $ ( NAME ) in p and the whole string in str
expand it as an environment variable .
Return a new allocated and expanded string .
2000-04-17 08:46:10 +04:00
Based on code by Branko Cibej < branko . cibej @ hermes . si >
When this is called p points at the ' % ' character .
2006-03-09 18:51:55 +03:00
May substitute multiple occurrencies of the same env var .
2000-04-17 08:46:10 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-17 02:32:10 +03:00
2006-03-09 18:51:55 +03:00
static char * realloc_expand_env_var ( char * str , char * p )
2000-04-17 08:46:10 +04:00
{
2006-03-09 18:51:55 +03:00
char * envname ;
2000-04-17 08:46:10 +04:00
char * envval ;
char * q , * r ;
int copylen ;
2006-03-09 18:51:55 +03:00
if ( p [ 0 ] ! = ' % ' | | p [ 1 ] ! = ' $ ' | | p [ 2 ] ! = ' ( ' ) {
return str ;
}
2000-04-17 08:46:10 +04:00
/*
* Look for the terminating ' ) ' .
*/
2001-07-04 11:36:09 +04:00
if ( ( q = strchr_m ( p , ' ) ' ) ) = = NULL ) {
2000-04-17 08:46:10 +04:00
DEBUG ( 0 , ( " expand_env_var: Unterminated environment variable [%s] \n " , p ) ) ;
2006-03-09 18:51:55 +03:00
return str ;
2000-04-17 08:46:10 +04:00
}
/*
* Extract the name from within the % $ ( NAME ) string .
*/
2006-03-09 18:51:55 +03:00
r = p + 3 ;
copylen = q - r ;
/* reserve space for use later add %$() chars */
if ( ( envname = ( char * ) SMB_MALLOC ( copylen + 1 + 4 ) ) = = NULL ) {
return NULL ;
}
2000-04-17 08:46:10 +04:00
strncpy ( envname , r , copylen ) ;
envname [ copylen ] = ' \0 ' ;
if ( ( envval = getenv ( envname ) ) = = NULL ) {
DEBUG ( 0 , ( " expand_env_var: Environment variable [%s] not set \n " , envname ) ) ;
2006-03-09 18:51:55 +03:00
SAFE_FREE ( envname ) ;
return str ;
2000-04-17 08:46:10 +04:00
}
/*
* Copy the full % $ ( NAME ) into envname so it
* can be replaced .
*/
2006-03-09 18:51:55 +03:00
copylen = q + 1 - p ;
2000-04-17 08:46:10 +04:00
strncpy ( envname , p , copylen ) ;
envname [ copylen ] = ' \0 ' ;
2006-03-09 18:51:55 +03:00
r = realloc_string_sub ( str , envname , envval ) ;
SAFE_FREE ( envname ) ;
return r ;
2000-04-17 08:46:10 +04:00
}
2002-07-15 14:35:28 +04:00
/*******************************************************************
2006-03-09 18:51:55 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static char * longvar_domainsid ( void )
{
DOM_SID sid ;
2007-12-16 00:00:39 +03:00
fstring tmp ;
2006-03-09 18:51:55 +03:00
char * sid_string ;
if ( ! secrets_fetch_domain_sid ( lp_workgroup ( ) , & sid ) ) {
return NULL ;
}
2007-12-16 00:47:30 +03:00
sid_string = SMB_STRDUP ( sid_to_fstring ( tmp , & sid ) ) ;
2006-03-09 18:51:55 +03:00
if ( ! sid_string ) {
DEBUG ( 0 , ( " longvar_domainsid: failed to dup SID string! \n " ) ) ;
}
return sid_string ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct api_longvar {
const char * name ;
char * ( * fn ) ( void ) ;
} ;
2007-09-04 14:15:04 +04:00
static struct api_longvar longvar_table [ ] = {
2006-03-09 18:51:55 +03:00
{ " DomainSID " , longvar_domainsid } ,
{ NULL , NULL }
} ;
static char * get_longvar_val ( const char * varname )
{
int i ;
DEBUG ( 7 , ( " get_longvar_val: expanding variable [%s] \n " , varname ) ) ;
for ( i = 0 ; longvar_table [ i ] . name ; i + + ) {
if ( strequal ( longvar_table [ i ] . name , varname ) ) {
return longvar_table [ i ] . fn ( ) ;
}
}
return NULL ;
}
/*******************************************************************
Expand the long smb . conf variable names given a pointer to a % ( NAME ) .
Return the number of characters by which the pointer should be advanced .
2002-07-15 14:35:28 +04:00
When this is called p points at the ' % ' character .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-03-09 18:51:55 +03:00
static char * realloc_expand_longvar ( char * str , char * p )
2002-07-15 14:35:28 +04:00
{
2006-03-09 18:51:55 +03:00
fstring varname ;
char * value ;
2002-07-15 14:35:28 +04:00
char * q , * r ;
int copylen ;
2006-03-09 18:51:55 +03:00
if ( p [ 0 ] ! = ' % ' | | p [ 1 ] ! = ' ( ' ) {
2002-07-15 14:35:28 +04:00
return str ;
2006-03-09 18:51:55 +03:00
}
2002-07-15 14:35:28 +04:00
2006-03-09 18:51:55 +03:00
/* Look for the terminating ')'.*/
2002-07-15 14:35:28 +04:00
if ( ( q = strchr_m ( p , ' ) ' ) ) = = NULL ) {
2006-03-09 18:51:55 +03:00
DEBUG ( 0 , ( " realloc_expand_longvar: Unterminated environment variable [%s] \n " , p ) ) ;
2002-07-15 14:35:28 +04:00
return str ;
}
2006-03-09 18:51:55 +03:00
/* Extract the name from within the %(NAME) string.*/
2002-07-15 14:35:28 +04:00
2006-03-09 18:51:55 +03:00
r = p + 2 ;
copylen = MIN ( ( q - r ) , ( sizeof ( varname ) - 1 ) ) ;
strncpy ( varname , r , copylen ) ;
varname [ copylen ] = ' \0 ' ;
2002-07-15 14:35:28 +04:00
2006-03-09 18:51:55 +03:00
if ( ( value = get_longvar_val ( varname ) ) = = NULL ) {
DEBUG ( 0 , ( " realloc_expand_longvar: Variable [%s] not set. Skipping \n " , varname ) ) ;
2002-07-15 14:35:28 +04:00
return str ;
}
2006-03-09 18:51:55 +03:00
/* Copy the full %(NAME) into envname so it can be replaced.*/
2002-07-15 14:35:28 +04:00
2006-03-09 18:51:55 +03:00
copylen = MIN ( ( q + 1 - p ) , ( sizeof ( varname ) - 1 ) ) ;
strncpy ( varname , p , copylen ) ;
varname [ copylen ] = ' \0 ' ;
r = realloc_string_sub ( str , varname , value ) ;
SAFE_FREE ( value ) ;
2007-11-10 02:09:16 +03:00
2006-03-09 18:51:55 +03:00
/* skip over the %(varname) */
2007-11-10 02:09:16 +03:00
2002-07-15 14:35:28 +04:00
return r ;
}
2000-04-17 08:46:10 +04:00
/*******************************************************************
Patch from jkf @ soton . ac . uk
Added this to implement % p ( NIS auto - map version of % H )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-17 02:32:10 +03:00
2007-11-10 02:09:16 +03:00
static const char * automount_path ( const char * user_name )
2000-04-17 08:46:10 +04:00
{
2007-11-10 02:09:16 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
const char * server_path ;
2000-04-17 08:46:10 +04:00
/* use the passwd entry as the default */
/* this will be the default if WITH_AUTOMOUNT is not used or fails */
2002-01-17 02:32:10 +03:00
2007-12-19 17:02:59 +03:00
server_path = talloc_strdup ( ctx , get_user_home_dir ( ctx , user_name ) ) ;
2007-11-10 02:09:16 +03:00
if ( ! server_path ) {
return " " ;
}
2000-04-17 08:46:10 +04:00
# if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2001-03-27 01:52:43 +04:00
if ( lp_nis_home_map ( ) ) {
2005-10-18 22:17:45 +04:00
const char * home_path_start ;
2007-12-05 04:48:38 +03:00
char * automount_value = automount_lookup ( ctx , user_name ) ;
2001-03-27 01:52:43 +04:00
2007-12-05 04:48:38 +03:00
if ( automount_value & & strlen ( automount_value ) > 0 ) {
2001-07-04 11:36:09 +04:00
home_path_start = strchr_m ( automount_value , ' : ' ) ;
2001-03-27 01:52:43 +04:00
if ( home_path_start ! = NULL ) {
2007-11-10 02:09:16 +03:00
DEBUG ( 5 , ( " NIS lookup succeeded. "
" Home path is: %s \n " ,
home_path_start ?
( home_path_start + 1 ) : " " ) ) ;
server_path = talloc_strdup ( ctx ,
home_path_start + 1 ) ;
2008-03-21 13:41:15 +03:00
if ( ! server_path ) {
server_path = " " ;
}
2001-03-27 01:52:43 +04:00
}
} else {
2007-11-10 02:09:16 +03:00
/* NIS key lookup failed: default to
* user home directory from password file */
DEBUG ( 5 , ( " NIS lookup failed. Using Home path from "
" passwd file. Home path is: %s \n " , server_path ) ) ;
2000-04-17 08:46:10 +04:00
}
}
# endif
DEBUG ( 4 , ( " Home server path: %s \n " , server_path ) ) ;
2007-11-10 02:09:16 +03:00
return server_path ;
2000-04-17 08:46:10 +04:00
}
/*******************************************************************
Patch from jkf @ soton . ac . uk
This is Luke ' s original function with the NIS lookup code
moved out to a separate function .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-17 02:32:10 +03:00
2002-08-17 21:00:51 +04:00
static const char * automount_server ( const char * user_name )
2000-04-17 08:46:10 +04:00
{
2007-11-10 02:09:16 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
const char * server_name ;
const char * local_machine_name = get_local_machine_name ( ) ;
2000-04-17 08:46:10 +04:00
/* use the local machine name as the default */
/* this will be the default if WITH_AUTOMOUNT is not used or fails */
2007-11-10 02:09:16 +03:00
if ( local_machine_name & & * local_machine_name ) {
server_name = talloc_strdup ( ctx , local_machine_name ) ;
} else {
server_name = talloc_strdup ( ctx , global_myname ( ) ) ;
}
2000-04-17 08:46:10 +04:00
2007-11-10 02:09:16 +03:00
if ( ! server_name ) {
return " " ;
}
# if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2002-01-17 02:32:10 +03:00
if ( lp_nis_home_map ( ) ) {
2007-11-10 02:09:16 +03:00
char * p ;
char * srv ;
2007-12-05 04:48:38 +03:00
char * automount_value = automount_lookup ( ctx , user_name ) ;
2007-11-10 02:09:16 +03:00
if ( ! automount_value ) {
return " " ;
}
srv = talloc_strdup ( ctx , automount_value ) ;
2008-03-21 13:42:42 +03:00
if ( ! srv ) {
return " " ;
}
2007-11-10 02:09:16 +03:00
p = strchr_m ( srv , ' : ' ) ;
if ( ! p ) {
return " " ;
}
* p = ' \0 ' ;
server_name = srv ;
DEBUG ( 5 , ( " NIS lookup succeeded. Home server %s \n " ,
server_name ) ) ;
2000-04-17 08:46:10 +04:00
}
# endif
DEBUG ( 4 , ( " Home server: %s \n " , server_name ) ) ;
2007-11-10 02:09:16 +03:00
return server_name ;
2000-04-17 08:46:10 +04:00
}
/****************************************************************************
Do some standard substitutions in a string .
2002-07-15 14:35:28 +04:00
len is the length in bytes of the space allowed in string str . If zero means
don ' t allow expansions .
2000-04-17 08:46:10 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-17 02:32:10 +03:00
2006-07-11 22:01:26 +04:00
void standard_sub_basic ( const char * smb_name , const char * domain_name ,
char * str , size_t len )
2000-04-17 08:46:10 +04:00
{
2006-03-09 18:51:55 +03:00
char * s ;
2006-07-11 22:01:26 +04:00
if ( ( s = alloc_sub_basic ( smb_name , domain_name , str ) ) ! = NULL ) {
2006-03-09 18:51:55 +03:00
strncpy ( str , s , len ) ;
2000-04-23 12:30:37 +04:00
}
2002-07-15 14:35:28 +04:00
2006-03-09 18:51:55 +03:00
SAFE_FREE ( s ) ;
2002-07-15 14:35:28 +04:00
2000-04-17 08:46:10 +04:00
}
/****************************************************************************
Do some standard substitutions in a string .
2002-07-15 14:35:28 +04:00
This function will return an allocated string that have to be freed .
2000-04-17 08:46:10 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-17 02:32:10 +03:00
2006-07-11 22:01:26 +04:00
char * talloc_sub_basic ( TALLOC_CTX * mem_ctx , const char * smb_name ,
const char * domain_name , const char * str )
2000-04-17 08:46:10 +04:00
{
2002-07-15 14:35:28 +04:00
char * a , * t ;
2006-03-09 18:51:55 +03:00
2006-07-11 22:01:26 +04:00
if ( ( a = alloc_sub_basic ( smb_name , domain_name , str ) ) = = NULL ) {
2006-03-07 21:00:21 +03:00
return NULL ;
}
2002-07-15 14:35:28 +04:00
t = talloc_strdup ( mem_ctx , a ) ;
SAFE_FREE ( a ) ;
return t ;
}
2006-03-09 18:51:55 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-07-11 22:01:26 +04:00
char * alloc_sub_basic ( const char * smb_name , const char * domain_name ,
const char * str )
2002-07-15 14:35:28 +04:00
{
2006-03-07 21:00:21 +03:00
char * b , * p , * s , * r , * a_string ;
2007-06-10 21:02:09 +04:00
fstring pidstr , vnnstr ;
2007-11-04 04:15:45 +03:00
char addr [ INET6_ADDRSTRLEN ] ;
2002-08-17 21:00:51 +04:00
const char * local_machine_name = get_local_machine_name ( ) ;
2008-03-28 17:49:13 +03:00
TALLOC_CTX * tmp_ctx = NULL ;
2002-07-15 14:35:28 +04:00
2006-03-07 21:00:21 +03:00
/* workaround to prevent a crash while looking at bug #687 */
2003-12-08 20:40:44 +03:00
2006-03-07 21:00:21 +03:00
if ( ! str ) {
2003-12-08 20:40:44 +03:00
DEBUG ( 0 , ( " alloc_sub_basic: NULL source string! This should not happen \n " ) ) ;
return NULL ;
}
2004-12-07 21:25:53 +03:00
a_string = SMB_STRDUP ( str ) ;
2002-07-15 14:35:28 +04:00
if ( a_string = = NULL ) {
2006-07-11 22:01:26 +04:00
DEBUG ( 0 , ( " alloc_sub_basic: Out of memory! \n " ) ) ;
2002-07-15 14:35:28 +04:00
return NULL ;
}
2008-03-28 17:49:13 +03:00
tmp_ctx = talloc_stackframe ( ) ;
2002-07-15 14:35:28 +04:00
for ( b = s = a_string ; ( p = strchr_m ( s , ' % ' ) ) ; s = a_string + ( p - b ) ) {
r = NULL ;
2006-03-07 21:00:21 +03:00
b = a_string ;
2008-03-28 17:49:13 +03:00
2002-07-15 14:35:28 +04:00
switch ( * ( p + 1 ) ) {
case ' U ' :
r = strdup_lower ( smb_name ) ;
2006-03-07 21:00:21 +03:00
if ( r = = NULL ) {
goto error ;
}
a_string = realloc_string_sub ( a_string , " %U " , r ) ;
2002-07-15 14:35:28 +04:00
break ;
2007-12-19 17:02:59 +03:00
case ' G ' : {
struct passwd * pass ;
2004-12-07 21:25:53 +03:00
r = SMB_STRDUP ( smb_name ) ;
2006-03-07 21:00:21 +03:00
if ( r = = NULL ) {
goto error ;
}
2008-03-28 17:49:13 +03:00
pass = Get_Pwnam_alloc ( tmp_ctx , r ) ;
2007-12-19 17:02:59 +03:00
if ( pass ! = NULL ) {
a_string = realloc_string_sub (
a_string , " %G " ,
gidtoname ( pass - > pw_gid ) ) ;
}
TALLOC_FREE ( pass ) ;
2002-07-15 14:35:28 +04:00
break ;
2007-12-19 17:02:59 +03:00
}
2002-07-15 14:35:28 +04:00
case ' D ' :
2006-07-11 22:01:26 +04:00
r = strdup_upper ( domain_name ) ;
2006-03-07 21:00:21 +03:00
if ( r = = NULL ) {
goto error ;
}
a_string = realloc_string_sub ( a_string , " %D " , r ) ;
2002-07-15 14:35:28 +04:00
break ;
2008-03-14 01:02:58 +03:00
case ' I ' : {
int offset = 0 ;
client_addr ( get_client_fd ( ) , addr , sizeof ( addr ) ) ;
if ( strnequal ( addr , " ::ffff: " , 7 ) ) {
offset = 7 ;
}
2007-11-04 04:41:26 +03:00
a_string = realloc_string_sub ( a_string , " %I " ,
2008-03-14 01:02:58 +03:00
addr + offset ) ;
2002-07-15 14:35:28 +04:00
break ;
2008-03-14 01:02:58 +03:00
}
2006-03-09 18:51:55 +03:00
case ' i ' :
2007-11-04 08:34:46 +03:00
a_string = realloc_string_sub ( a_string , " %i " ,
2007-11-04 09:20:10 +03:00
client_socket_addr ( get_client_fd ( ) , addr , sizeof ( addr ) ) ) ;
2006-03-09 18:51:55 +03:00
break ;
2002-07-15 14:35:28 +04:00
case ' L ' :
2006-03-09 18:51:55 +03:00
if ( StrnCaseCmp ( p , " %LOGONSERVER% " , strlen ( " %LOGONSERVER% " ) ) = = 0 ) {
break ;
}
2006-03-07 21:00:21 +03:00
if ( local_machine_name & & * local_machine_name ) {
a_string = realloc_string_sub ( a_string , " %L " , local_machine_name ) ;
} else {
a_string = realloc_string_sub ( a_string , " %L " , global_myname ( ) ) ;
}
2002-07-15 14:35:28 +04:00
break ;
2003-11-05 07:34:31 +03:00
case ' N ' :
2006-03-07 21:00:21 +03:00
a_string = realloc_string_sub ( a_string , " %N " , automount_server ( smb_name ) ) ;
2003-11-05 07:34:31 +03:00
break ;
2002-07-15 14:35:28 +04:00
case ' M ' :
2007-11-04 09:20:10 +03:00
a_string = realloc_string_sub ( a_string , " %M " , client_name ( get_client_fd ( ) ) ) ;
2002-07-15 14:35:28 +04:00
break ;
case ' R ' :
2006-03-07 21:00:21 +03:00
a_string = realloc_string_sub ( a_string , " %R " , remote_proto ) ;
2002-07-15 14:35:28 +04:00
break ;
case ' T ' :
2008-03-28 17:49:13 +03:00
a_string = realloc_string_sub ( a_string , " %T " , current_timestring ( tmp_ctx , False ) ) ;
2002-07-15 14:35:28 +04:00
break ;
case ' a ' :
2007-11-10 02:09:16 +03:00
a_string = realloc_string_sub ( a_string , " %a " ,
get_remote_arch_str ( ) ) ;
2002-07-15 14:35:28 +04:00
break ;
case ' d ' :
slprintf ( pidstr , sizeof ( pidstr ) - 1 , " %d " , ( int ) sys_getpid ( ) ) ;
2006-03-07 21:00:21 +03:00
a_string = realloc_string_sub ( a_string , " %d " , pidstr ) ;
2002-07-15 14:35:28 +04:00
break ;
case ' h ' :
2006-03-07 21:00:21 +03:00
a_string = realloc_string_sub ( a_string , " %h " , myhostname ( ) ) ;
2002-07-15 14:35:28 +04:00
break ;
case ' m ' :
2008-06-18 16:50:53 +04:00
a_string = realloc_string_sub ( a_string , " %m " ,
remote_machine
? remote_machine
: " " ) ;
2002-07-15 14:35:28 +04:00
break ;
case ' v ' :
2006-03-07 21:00:21 +03:00
a_string = realloc_string_sub ( a_string , " %v " , SAMBA_VERSION_STRING ) ;
2002-07-15 14:35:28 +04:00
break ;
2006-01-20 23:22:23 +03:00
case ' w ' :
2006-03-07 21:00:21 +03:00
a_string = realloc_string_sub ( a_string , " %w " , lp_winbind_separator ( ) ) ;
2006-01-20 23:22:23 +03:00
break ;
2002-07-15 14:35:28 +04:00
case ' $ ' :
2006-03-07 21:00:21 +03:00
a_string = realloc_expand_env_var ( a_string , p ) ; /* Expand environment variables */
2002-07-15 14:35:28 +04:00
break ;
2006-03-09 18:51:55 +03:00
case ' ( ' :
a_string = realloc_expand_longvar ( a_string , p ) ;
break ;
2007-06-10 21:02:09 +04:00
case ' V ' :
slprintf ( vnnstr , sizeof ( vnnstr ) - 1 , " %u " , get_my_vnn ( ) ) ;
a_string = realloc_string_sub ( a_string , " %V " , vnnstr ) ;
break ;
2002-07-15 14:35:28 +04:00
default :
break ;
}
p + + ;
SAFE_FREE ( r ) ;
2008-03-28 17:49:13 +03:00
if ( a_string = = NULL ) {
goto done ;
2006-03-07 21:00:21 +03:00
}
2002-07-15 14:35:28 +04:00
}
2008-03-28 17:49:13 +03:00
goto done ;
2006-03-07 21:00:21 +03:00
2002-07-15 14:35:28 +04:00
error :
SAFE_FREE ( a_string ) ;
2008-03-28 17:49:13 +03:00
done :
TALLOC_FREE ( tmp_ctx ) ;
return a_string ;
2000-04-17 08:46:10 +04:00
}
/****************************************************************************
2002-07-15 14:35:28 +04:00
Do some specific substitutions in a string .
This function will return an allocated string that have to be freed .
2000-04-17 08:46:10 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-17 02:32:10 +03:00
2002-07-15 14:35:28 +04:00
char * talloc_sub_specified ( TALLOC_CTX * mem_ctx ,
const char * input_string ,
const char * username ,
const char * domain ,
uid_t uid ,
gid_t gid )
2002-01-17 02:32:10 +03:00
{
2006-07-11 22:01:26 +04:00
char * a_string ;
char * ret_string = NULL ;
char * b , * p , * s ;
TALLOC_CTX * tmp_ctx ;
if ( ! ( tmp_ctx = talloc_new ( mem_ctx ) ) ) {
DEBUG ( 0 , ( " talloc_new failed \n " ) ) ;
2006-03-07 21:00:21 +03:00
return NULL ;
}
2002-01-17 02:32:10 +03:00
2006-07-11 22:01:26 +04:00
a_string = talloc_strdup ( tmp_ctx , input_string ) ;
2002-07-15 14:35:28 +04:00
if ( a_string = = NULL ) {
2006-07-11 22:01:26 +04:00
DEBUG ( 0 , ( " talloc_sub_specified: Out of memory! \n " ) ) ;
goto done ;
2002-07-15 14:35:28 +04:00
}
for ( b = s = a_string ; ( p = strchr_m ( s , ' % ' ) ) ; s = a_string + ( p - b ) ) {
2006-03-07 21:00:21 +03:00
b = a_string ;
2002-07-15 14:35:28 +04:00
switch ( * ( p + 1 ) ) {
case ' U ' :
2006-07-11 22:01:26 +04:00
a_string = talloc_string_sub (
tmp_ctx , a_string , " %U " , username ) ;
2002-07-15 14:35:28 +04:00
break ;
case ' u ' :
2006-07-11 22:01:26 +04:00
a_string = talloc_string_sub (
tmp_ctx , a_string , " %u " , username ) ;
2002-07-15 14:35:28 +04:00
break ;
case ' G ' :
if ( gid ! = - 1 ) {
2006-07-11 22:01:26 +04:00
a_string = talloc_string_sub (
tmp_ctx , a_string , " %G " ,
gidtoname ( gid ) ) ;
2002-07-15 14:35:28 +04:00
} else {
2006-07-11 22:01:26 +04:00
a_string = talloc_string_sub (
tmp_ctx , a_string ,
" %G " , " NO_GROUP " ) ;
2002-07-15 14:35:28 +04:00
}
break ;
case ' g ' :
if ( gid ! = - 1 ) {
2006-07-11 22:01:26 +04:00
a_string = talloc_string_sub (
tmp_ctx , a_string , " %g " ,
gidtoname ( gid ) ) ;
2002-07-15 14:35:28 +04:00
} else {
2006-07-11 22:01:26 +04:00
a_string = talloc_string_sub (
tmp_ctx , a_string , " %g " , " NO_GROUP " ) ;
2002-07-15 14:35:28 +04:00
}
break ;
case ' D ' :
2006-07-11 22:01:26 +04:00
a_string = talloc_string_sub ( tmp_ctx , a_string ,
" %D " , domain ) ;
2002-07-15 14:35:28 +04:00
break ;
case ' N ' :
2006-07-11 22:01:26 +04:00
a_string = talloc_string_sub (
tmp_ctx , a_string , " %N " ,
automount_server ( username ) ) ;
2002-07-15 14:35:28 +04:00
break ;
default :
break ;
}
p + + ;
2006-03-07 21:00:21 +03:00
if ( a_string = = NULL ) {
2006-07-11 22:01:26 +04:00
goto done ;
2002-07-15 14:35:28 +04:00
}
}
2006-07-11 22:01:26 +04:00
/* Watch out, using "mem_ctx" here, so all intermediate stuff goes
* away with the TALLOC_FREE ( tmp_ctx ) further down . */
2002-07-15 14:35:28 +04:00
2006-07-11 22:01:26 +04:00
ret_string = talloc_sub_basic ( mem_ctx , username , domain , a_string ) ;
2006-03-09 18:51:55 +03:00
2006-07-11 22:01:26 +04:00
done :
TALLOC_FREE ( tmp_ctx ) ;
return ret_string ;
2002-07-15 14:35:28 +04:00
}
2006-03-09 18:51:55 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-07-15 02:06:38 +04:00
static char * alloc_sub_advanced ( const char * servicename , const char * user ,
2006-07-11 22:01:26 +04:00
const char * connectpath , gid_t gid ,
const char * smb_name , const char * domain_name ,
const char * str )
2002-07-15 14:35:28 +04:00
{
char * a_string , * ret_string ;
2007-12-19 17:02:59 +03:00
char * b , * p , * s ;
2002-07-15 14:35:28 +04:00
2004-12-07 21:25:53 +03:00
a_string = SMB_STRDUP ( str ) ;
2002-07-15 14:35:28 +04:00
if ( a_string = = NULL ) {
2006-05-07 21:11:40 +04:00
DEBUG ( 0 , ( " alloc_sub_advanced: Out of memory! \n " ) ) ;
2002-07-15 14:35:28 +04:00
return NULL ;
}
for ( b = s = a_string ; ( p = strchr_m ( s , ' % ' ) ) ; s = a_string + ( p - b ) ) {
2006-03-07 21:00:21 +03:00
b = a_string ;
2002-01-17 02:32:10 +03:00
switch ( * ( p + 1 ) ) {
2002-07-15 14:35:28 +04:00
case ' N ' :
2006-03-07 21:00:21 +03:00
a_string = realloc_string_sub ( a_string , " %N " , automount_server ( user ) ) ;
2002-07-15 14:35:28 +04:00
break ;
2007-12-19 17:02:59 +03:00
case ' H ' : {
char * h ;
if ( ( h = get_user_home_dir ( talloc_tos ( ) , user ) ) )
2006-03-07 21:00:21 +03:00
a_string = realloc_string_sub ( a_string , " %H " , h ) ;
2007-12-19 17:02:59 +03:00
TALLOC_FREE ( h ) ;
2002-07-15 14:35:28 +04:00
break ;
2007-12-19 17:02:59 +03:00
}
2002-07-15 14:35:28 +04:00
case ' P ' :
2006-03-07 21:00:21 +03:00
a_string = realloc_string_sub ( a_string , " %P " , connectpath ) ;
2002-07-15 14:35:28 +04:00
break ;
2002-01-17 02:32:10 +03:00
case ' S ' :
2006-07-11 22:01:26 +04:00
a_string = realloc_string_sub ( a_string , " %S " , servicename ) ;
2002-07-15 14:35:28 +04:00
break ;
case ' g ' :
2006-03-07 21:00:21 +03:00
a_string = realloc_string_sub ( a_string , " %g " , gidtoname ( gid ) ) ;
2002-07-15 14:35:28 +04:00
break ;
case ' u ' :
2006-03-07 21:00:21 +03:00
a_string = realloc_string_sub ( a_string , " %u " , user ) ;
2002-01-17 02:32:10 +03:00
break ;
2002-07-15 14:35:28 +04:00
/* Patch from jkf@soton.ac.uk Left the %N (NIS
* server name ) in standard_sub_basic as it is
* a feature for logon servers , hence uses the
* username . The % p ( NIS server path ) code is
* here as it is used instead of the default
* " path = " string in [ homes ] and so needs the
* service name , not the username . */
2002-01-17 02:32:10 +03:00
case ' p ' :
2006-07-11 22:01:26 +04:00
a_string = realloc_string_sub ( a_string , " %p " ,
automount_path ( servicename ) ) ;
2002-01-17 02:32:10 +03:00
break ;
2002-07-15 14:35:28 +04:00
default :
2002-01-17 02:32:10 +03:00
break ;
}
2002-07-15 14:35:28 +04:00
p + + ;
2006-03-07 21:00:21 +03:00
if ( a_string = = NULL ) {
2002-07-15 14:35:28 +04:00
return NULL ;
}
2002-01-17 02:32:10 +03:00
}
2006-07-11 22:01:26 +04:00
ret_string = alloc_sub_basic ( smb_name , domain_name , a_string ) ;
2002-07-15 14:35:28 +04:00
SAFE_FREE ( a_string ) ;
return ret_string ;
}
2006-07-15 02:06:38 +04:00
/*
* This obviously is inefficient and needs to be merged into
* alloc_sub_advanced . . .
*/
char * talloc_sub_advanced ( TALLOC_CTX * mem_ctx ,
2007-11-28 01:35:30 +03:00
const char * servicename , const char * user ,
const char * connectpath , gid_t gid ,
2006-07-15 02:06:38 +04:00
const char * smb_name , const char * domain_name ,
const char * str )
{
char * a , * t ;
if ( ! ( a = alloc_sub_advanced ( servicename , user , connectpath , gid ,
smb_name , domain_name , str ) ) ) {
return NULL ;
}
t = talloc_strdup ( mem_ctx , a ) ;
SAFE_FREE ( a ) ;
return t ;
}
2007-11-28 01:35:30 +03:00
void standard_sub_advanced ( const char * servicename , const char * user ,
const char * connectpath , gid_t gid ,
2006-07-11 22:01:26 +04:00
const char * smb_name , const char * domain_name ,
char * str , size_t len )
2000-04-17 08:46:10 +04:00
{
2006-03-09 18:51:55 +03:00
char * s ;
2007-11-28 01:35:30 +03:00
2006-07-11 22:01:26 +04:00
s = alloc_sub_advanced ( servicename , user , connectpath ,
gid , smb_name , domain_name , str ) ;
2006-03-09 18:51:55 +03:00
if ( s ) {
strncpy ( str , s , len ) ;
SAFE_FREE ( s ) ;
}
2000-04-19 08:01:16 +04:00
}
2007-10-11 00:34:30 +04:00
/****************************************************************************
2007-11-28 01:35:30 +03:00
Do some standard substitutions in a string .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-11 00:34:30 +04:00
2007-11-28 01:35:30 +03:00
char * standard_sub_conn ( TALLOC_CTX * ctx , connection_struct * conn , const char * str )
2007-10-11 00:34:30 +04:00
{
2007-11-28 01:35:30 +03:00
return talloc_sub_advanced ( ctx ,
lp_servicename ( SNUM ( conn ) ) ,
2008-05-08 18:06:42 +04:00
conn - > server_info - > unix_name ,
2007-11-28 01:35:30 +03:00
conn - > connectpath ,
2008-06-19 18:54:12 +04:00
conn - > server_info - > utok . gid ,
2007-11-28 01:35:30 +03:00
get_smb_user_name ( ) ,
" " ,
str ) ;
2007-10-11 00:34:30 +04:00
}