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
2009-11-21 18:17:16 +03:00
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 .
2009-11-21 18:17:16 +03:00
2000-04-17 08:46:10 +04: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 .
2009-11-21 18:17:16 +03:00
2000-04-17 08:46:10 +04:00
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"
2011-02-25 19:14:22 +03:00
# include "system/passwd.h"
2010-08-05 04:25:37 +04:00
# include "secrets.h"
2011-03-25 04:28:05 +03:00
# include "auth.h"
2000-04-17 08:46:10 +04:00
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 )
{
2012-01-27 05:10:44 +04:00
TALLOC_FREE ( local_machine ) ;
2008-01-07 16:15:48 +03:00
}
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 ;
size_t len ;
2002-08-17 21:00:51 +04:00
2010-08-28 16:15:31 +04:00
if ( already_perm ) {
return true ;
}
2012-01-27 05:10:44 +04:00
tmp_local_machine = talloc_strdup ( NULL , local_name ) ;
2007-11-10 02:09:16 +03:00
if ( ! tmp_local_machine ) {
return false ;
}
2004-05-11 18:54:54 +04:00
trim_char ( tmp_local_machine , ' ' , ' ' ) ;
2012-01-27 05:10:44 +04:00
TALLOC_FREE ( local_machine ) ;
2007-11-10 02:09:16 +03:00
len = strlen ( tmp_local_machine ) ;
2012-01-27 05:10:44 +04:00
local_machine = ( char * ) TALLOC_ZERO ( NULL , len + 1 ) ;
2007-11-10 02:09:16 +03:00
if ( ! local_machine ) {
2012-01-27 05:10:44 +04:00
TALLOC_FREE ( tmp_local_machine ) ;
2007-11-10 02:09:16 +03:00
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 ) ;
2012-08-09 04:01:00 +04:00
if ( ! strlower_m ( local_machine ) ) {
TALLOC_FREE ( tmp_local_machine ) ;
return false ;
}
2012-01-27 05:10:44 +04:00
TALLOC_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 ) {
2011-06-09 09:31:03 +04:00
return lp_netbios_name ( ) ;
2007-11-10 02:09:16 +03:00
}
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
2012-01-27 05:10:44 +04:00
tmp_remote_machine = talloc_strdup ( NULL , remote_name ) ;
2007-11-10 02:09:16 +03:00
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
2012-01-27 05:10:44 +04:00
TALLOC_FREE ( remote_machine ) ;
2007-11-10 02:09:16 +03:00
len = strlen ( tmp_remote_machine ) ;
2012-01-27 05:10:44 +04:00
remote_machine = ( char * ) TALLOC_ZERO ( NULL , len + 1 ) ;
2007-11-10 02:09:16 +03:00
if ( ! remote_machine ) {
2012-01-27 05:10:44 +04:00
TALLOC_FREE ( tmp_remote_machine ) ;
2007-11-10 02:09:16 +03:00
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 ) ;
2012-08-09 04:01:00 +04:00
if ( ! strlower_m ( remote_machine ) ) {
TALLOC_FREE ( tmp_remote_machine ) ;
return false ;
}
2012-01-27 05:10:44 +04:00
TALLOC_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
2012-01-27 05:10:44 +04:00
tmp = talloc_strdup ( NULL , name ) ;
2007-11-10 02:09:16 +03:00
if ( ! tmp ) {
return ;
}
trim_char ( tmp , ' ' , ' ' ) ;
2012-08-09 04:01:00 +04:00
if ( ! strlower_m ( tmp ) ) {
TALLOC_FREE ( tmp ) ;
return ;
}
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 ) {
2012-01-27 05:10:44 +04:00
TALLOC_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
}
2012-01-27 05:10:44 +04:00
TALLOC_FREE ( smb_user_name ) ;
smb_user_name = ( char * ) TALLOC_ZERO ( NULL , len + 1 ) ;
2007-11-10 02:09:16 +03:00
if ( ! smb_user_name ) {
2012-01-27 05:10:44 +04:00
TALLOC_FREE ( tmp ) ;
2007-11-10 02:09:16 +03:00
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
2012-01-27 05:10:44 +04:00
TALLOC_FREE ( tmp ) ;
2007-11-10 02:09:16 +03:00
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
}
2010-08-28 18:33:00 +04:00
static char sub_peeraddr [ INET6_ADDRSTRLEN ] ;
2012-01-27 02:53:43 +04:00
static const char * sub_peername = NULL ;
2010-08-28 18:33:00 +04:00
static char sub_sockaddr [ INET6_ADDRSTRLEN ] ;
void sub_set_socket_ids ( const char * peeraddr , const char * peername ,
const char * sockaddr )
{
const char * addr = peeraddr ;
if ( strnequal ( addr , " ::ffff: " , 7 ) ) {
addr + = 7 ;
}
strlcpy ( sub_peeraddr , addr , sizeof ( sub_peeraddr ) ) ;
2012-01-27 02:53:43 +04:00
if ( sub_peername ! = NULL & &
sub_peername ! = sub_peeraddr ) {
2012-01-27 05:10:44 +04:00
talloc_free ( discard_const_p ( char , sub_peername ) ) ;
2012-01-27 02:53:43 +04:00
sub_peername = NULL ;
}
2012-01-27 05:10:44 +04:00
sub_peername = talloc_strdup ( NULL , peername ) ;
2010-08-28 18:33:00 +04:00
if ( sub_peername = = NULL ) {
sub_peername = sub_peeraddr ;
}
/*
* Shouldn ' t we do the : : ffff : cancellation here as well ? The
2012-01-27 05:10:44 +04:00
* original code in talloc_sub_basic ( ) did not do it , so I ' m
2010-08-28 18:33:00 +04:00
* leaving it out here as well for compatibility .
*/
strlcpy ( sub_sockaddr , sockaddr , sizeof ( sub_sockaddr ) ) ;
}
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 ,
2009-01-21 01:08:33 +03:00
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 . 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 .
2012-01-27 05:10:44 +04:00
str must be a talloced string .
2006-03-09 18:51:55 +03:00
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
2012-01-27 05:10:44 +04: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 ;
2009-11-21 18:17:16 +03:00
2006-03-09 18:51:55 +03:00
/* reserve space for use later add %$() chars */
2012-01-27 05:10:44 +04:00
if ( ( envname = talloc_array ( talloc_tos ( ) , char , copylen + 1 + 4 ) ) = = NULL ) {
2006-03-09 18:51:55 +03:00
return NULL ;
}
2009-11-21 18:17:16 +03:00
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 ) ) ;
2012-01-27 05:10:44 +04:00
TALLOC_FREE ( envname ) ;
2006-03-09 18:51:55 +03:00
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 ) ;
2012-01-27 05:10:44 +04:00
TALLOC_FREE ( envname ) ;
2009-11-21 18:17:16 +03:00
2006-03-09 18:51:55 +03: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 {
2011-06-09 09:31:03 +04:00
server_name = talloc_strdup ( ctx , lp_netbios_name ( ) ) ;
2007-11-10 02:09:16 +03:00
}
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 ;
2009-11-21 18:17:16 +03:00
2012-01-27 05:10:44 +04:00
if ( ( s = talloc_sub_basic ( talloc_tos ( ) , 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
}
2009-11-21 18:17:16 +03:00
2012-01-27 05:10:44 +04:00
TALLOC_FREE ( s ) ;
2000-04-17 08:46:10 +04:00
}
/****************************************************************************
Do some standard substitutions in a string .
2012-01-27 05:10:44 +04:00
This function will return an talloced string that has to be freed .
2006-03-09 18:51:55 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-01-27 05:10:44 +04:00
char * talloc_sub_basic ( TALLOC_CTX * mem_ctx ,
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 ;
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 */
2009-11-21 18:17:16 +03:00
2006-03-07 21:00:21 +03:00
if ( ! str ) {
2012-01-27 05:10:44 +04:00
DEBUG ( 0 , ( " talloc_sub_basic: NULL source string! This should not happen \n " ) ) ;
2003-12-08 20:40:44 +03:00
return NULL ;
}
2009-11-21 18:17:16 +03:00
2012-01-27 05:10:44 +04:00
a_string = talloc_strdup ( mem_ctx , str ) ;
2002-07-15 14:35:28 +04:00
if ( a_string = = NULL ) {
2012-01-27 05:10:44 +04:00
DEBUG ( 0 , ( " talloc_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 ' :
2009-03-19 04:20:11 +03:00
r = strlower_talloc ( tmp_ctx , 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 ;
2013-11-27 20:21:01 +04:00
if ( domain_name ! = NULL & & domain_name [ 0 ] ! = ' \0 ' ) {
r = talloc_asprintf ( tmp_ctx ,
" %s%c%s " ,
domain_name ,
* lp_winbind_separator ( ) ,
smb_name ) ;
} else {
r = talloc_strdup ( tmp_ctx , smb_name ) ;
}
2006-03-07 21:00:21 +03:00
if ( r = = NULL ) {
goto error ;
}
2013-11-27 20:21:01 +04:00
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 ' :
2009-03-19 04:20:11 +03:00
r = strupper_talloc ( tmp_ctx , 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 ' : {
2010-08-28 18:33:00 +04:00
a_string = realloc_string_sub (
a_string , " %I " ,
sub_peeraddr [ 0 ] ? sub_peeraddr : " 0.0.0.0 " ) ;
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 ' :
2010-08-14 12:22:12 +04:00
a_string = realloc_string_sub (
a_string , " %i " ,
2010-08-28 18:33:00 +04:00
sub_sockaddr [ 0 ] ? sub_sockaddr : " 0.0.0.0 " ) ;
2006-03-09 18:51:55 +03:00
break ;
2002-07-15 14:35:28 +04:00
case ' L ' :
2011-05-13 22:23:36 +04:00
if ( strncasecmp_m ( p , " %LOGONSERVER% " , strlen ( " %LOGONSERVER% " ) ) = = 0 ) {
2006-03-09 18:51:55 +03:00
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 {
2011-06-09 09:31:03 +04:00
a_string = realloc_string_sub ( a_string , " %L " , lp_netbios_name ( ) ) ;
2006-03-07 21:00:21 +03:00
}
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 ' :
2010-08-28 18:33:00 +04:00
a_string = realloc_string_sub ( a_string , " %M " ,
2012-01-27 02:53:43 +04:00
sub_peername ? sub_peername : " " ) ;
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 ' :
2012-03-24 23:17:08 +04:00
slprintf ( pidstr , sizeof ( pidstr ) - 1 , " %d " , ( int ) 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 ' :
2009-01-16 00:27:52 +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 ;
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 + + ;
2009-03-19 04:20:11 +03:00
TALLOC_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 :
2012-01-27 05:10:44 +04:00
TALLOC_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 ,
2013-11-18 17:58:04 +04:00
const char * grpname ,
2002-07-15 14:35:28 +04:00
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
}
2009-11-21 18:17:16 +03:00
2002-07-15 14:35:28 +04:00
for ( b = s = a_string ; ( p = strchr_m ( s , ' % ' ) ) ; s = a_string + ( p - b ) ) {
2009-11-21 18:17:16 +03:00
2006-03-07 21:00:21 +03:00
b = a_string ;
2009-11-21 18:17:16 +03:00
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 ) {
2013-11-18 17:58:04 +04:00
const char * name ;
if ( grpname ! = NULL ) {
name = grpname ;
} else {
name = gidtoname ( gid ) ;
}
a_string = talloc_string_sub ( tmp_ctx ,
a_string ,
" %G " ,
name ) ;
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 ) {
2013-11-18 17:58:04 +04:00
const char * name ;
if ( grpname ! = NULL ) {
name = grpname ;
} else {
name = gidtoname ( gid ) ;
}
a_string = talloc_string_sub ( tmp_ctx ,
a_string ,
" %g " ,
name ) ;
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
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-01-27 05:10:44 +04:00
char * talloc_sub_advanced ( TALLOC_CTX * ctx ,
const char * servicename ,
const char * user ,
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
2012-01-27 05:10:44 +04:00
a_string = talloc_strdup ( talloc_tos ( ) , str ) ;
2002-07-15 14:35:28 +04:00
if ( a_string = = NULL ) {
2012-01-27 05:10:44 +04:00
DEBUG ( 0 , ( " talloc_sub_advanced: Out of memory! \n " ) ) ;
2002-07-15 14:35:28 +04:00
return NULL ;
}
2009-11-21 18:17:16 +03:00
2002-07-15 14:35:28 +04:00
for ( b = s = a_string ; ( p = strchr_m ( s , ' % ' ) ) ; s = a_string + ( p - b ) ) {
2009-11-21 18:17:16 +03:00
2006-03-07 21:00:21 +03:00
b = a_string ;
2009-11-21 18:17:16 +03:00
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 ;
2009-11-21 18:17:16 +03:00
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 ;
2009-11-21 18:17:16 +03:00
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
}
2012-01-27 05:10:44 +04:00
ret_string = talloc_sub_basic ( ctx , smb_name , domain_name , a_string ) ;
TALLOC_FREE ( a_string ) ;
2002-07-15 14:35:28 +04:00
return ret_string ;
}
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
{
2012-01-27 05:10:44 +04:00
char * s = talloc_sub_advanced ( talloc_tos ( ) ,
servicename , user , connectpath ,
gid , smb_name , domain_name , str ) ;
2007-11-28 01:35:30 +03:00
2012-01-27 05:10:44 +04:00
if ( ! s ) {
return ;
2006-03-09 18:51:55 +03:00
}
2012-01-27 05:10:44 +04:00
strlcpy ( str , s , len ) ;
TALLOC_FREE ( s ) ;
2000-04-19 08:01:16 +04:00
}
2007-10-11 00:34:30 +04:00
2011-05-30 10:16:08 +04:00
/******************************************************************************
version of standard_sub_basic ( ) for string lists ; uses talloc_sub_basic ( )
for the work
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool str_list_sub_basic ( char * * list , const char * smb_name ,
const char * domain_name )
{
TALLOC_CTX * ctx = list ;
char * s , * tmpstr ;
while ( * list ) {
s = * list ;
tmpstr = talloc_sub_basic ( ctx , smb_name , domain_name , s ) ;
if ( ! tmpstr ) {
DEBUG ( 0 , ( " str_list_sub_basic: "
2012-01-27 05:10:44 +04:00
" talloc_sub_basic() return NULL! \n " ) ) ;
2011-05-30 10:16:08 +04:00
return false ;
}
TALLOC_FREE ( * list ) ;
* list = tmpstr ;
list + + ;
}
return true ;
}