2011-06-06 08:37:06 +04:00
/*
Unix SMB / CIFS implementation .
Samba utility functions
Copyright ( C ) Andrew Tridgell 1992 - 1998
Copyright ( C ) Jeremy Allison 2001 - 2007
Copyright ( C ) Simo Sorce 2001
Copyright ( C ) Jim McDonough < jmcd @ us . ibm . com > 2003
Copyright ( C ) James Peach 2006
2020-05-07 13:25:24 +03:00
Copyright ( c ) 2020 Andreas Schneider < asn @ samba . org >
2011-06-06 08:37:06 +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
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "dynconfig/dynconfig.h"
2017-06-22 17:10:52 +03:00
# include "lib/util/util_paths.h"
2020-05-07 13:25:24 +03:00
# include "system/passwd.h"
2011-06-06 08:37:06 +04:00
/**
* @ brief Returns an absolute path to a file in the Samba modules directory .
*
* @ param name File to find , relative to MODULESDIR .
*
* @ retval Pointer to a string containing the full path .
* */
char * modules_path ( TALLOC_CTX * mem_ctx , const char * name )
{
return talloc_asprintf ( mem_ctx , " %s/%s " , get_dyn_MODULESDIR ( ) , name ) ;
}
/**
* @ brief Returns an absolute path to a file in the Samba data directory .
*
* @ param name File to find , relative to CODEPAGEDIR .
*
* @ retval Pointer to a talloc ' ed string containing the full path .
* */
char * data_path ( TALLOC_CTX * mem_ctx , const char * name )
{
return talloc_asprintf ( mem_ctx , " %s/%s " , get_dyn_CODEPAGEDIR ( ) , name ) ;
}
/**
* @ brief Returns the platform specific shared library extension .
*
* @ retval Pointer to a const char * containing the extension .
* */
const char * shlib_ext ( void )
{
return get_dyn_SHLIBEXT ( ) ;
}
2020-05-07 13:25:24 +03:00
static char * get_user_home_dir ( TALLOC_CTX * mem_ctx )
{
struct passwd pwd = { 0 } ;
struct passwd * pwdbuf = NULL ;
2020-06-05 14:52:23 +03:00
char * buf = NULL ;
char * out = NULL ;
long int initlen ;
2020-06-09 04:52:50 +03:00
size_t len ;
2020-05-07 13:25:24 +03:00
int rc ;
2020-06-05 14:52:23 +03:00
initlen = sysconf ( _SC_GETPW_R_SIZE_MAX ) ;
if ( initlen = = - 1 ) {
len = 1024 ;
} else {
len = ( size_t ) initlen ;
}
buf = talloc_size ( mem_ctx , len ) ;
if ( buf = = NULL ) {
return NULL ;
}
rc = getpwuid_r ( getuid ( ) , & pwd , buf , len , & pwdbuf ) ;
2020-06-05 15:05:42 +03:00
while ( rc = = ERANGE ) {
size_t newlen = 2 * len ;
if ( newlen < len ) {
/* Overflow */
goto done ;
}
len = newlen ;
buf = talloc_realloc_size ( mem_ctx , buf , len ) ;
if ( buf = = NULL ) {
goto done ;
}
rc = getpwuid_r ( getuid ( ) , & pwd , buf , len , & pwdbuf ) ;
}
2020-05-07 13:25:24 +03:00
if ( rc ! = 0 | | pwdbuf = = NULL ) {
const char * szPath = getenv ( " HOME " ) ;
if ( szPath = = NULL ) {
2020-06-05 14:52:23 +03:00
goto done ;
2020-05-07 13:25:24 +03:00
}
2020-06-09 04:52:50 +03:00
len = strnlen ( szPath , PATH_MAX ) ;
if ( len > = PATH_MAX ) {
2020-07-13 20:08:47 +03:00
goto done ;
2020-05-15 22:18:02 +03:00
}
2020-06-05 14:52:23 +03:00
out = talloc_strdup ( mem_ctx , szPath ) ;
goto done ;
2020-05-07 13:25:24 +03:00
}
2020-06-05 14:52:23 +03:00
out = talloc_strdup ( mem_ctx , pwd . pw_dir ) ;
done :
TALLOC_FREE ( buf ) ;
return out ;
2020-05-07 13:25:24 +03:00
}
char * path_expand_tilde ( TALLOC_CTX * mem_ctx , const char * d )
{
char * h = NULL , * r = NULL ;
const char * p = NULL ;
struct stat sb = { 0 } ;
int rc ;
if ( d [ 0 ] ! = ' ~ ' ) {
return talloc_strdup ( mem_ctx , d ) ;
}
d + + ;
/* handle ~user/path */
p = strchr ( d , ' / ' ) ;
if ( p ! = NULL & & p > d ) {
struct passwd * pw ;
size_t s = p - d ;
char u [ 128 ] ;
if ( s > = sizeof ( u ) ) {
return NULL ;
}
memcpy ( u , d , s ) ;
u [ s ] = ' \0 ' ;
pw = getpwnam ( u ) ;
if ( pw = = NULL ) {
return NULL ;
}
h = talloc_strdup ( mem_ctx , pw - > pw_dir ) ;
} else {
p = d ;
h = get_user_home_dir ( mem_ctx ) ;
}
if ( h = = NULL ) {
return NULL ;
}
rc = stat ( h , & sb ) ;
if ( rc ! = 0 ) {
TALLOC_FREE ( h ) ;
return NULL ;
}
r = talloc_asprintf ( mem_ctx , " %s%s " , h , p ) ;
TALLOC_FREE ( h ) ;
return r ;
}