@ -29,6 +29,7 @@
# include <sys/resource.h>
# endif
# include "common/username.h"
# include "getopt_long.h"
# include "libpq/pqcomm.h" /* needed for UNIXSOCK_PATH() */
# include "pg_config_paths.h"
@ -104,6 +105,7 @@ static char *dlpath = PKGLIBDIR;
static char * user = NULL ;
static _stringlist * extraroles = NULL ;
static _stringlist * extra_install = NULL ;
static char * config_auth_datadir = NULL ;
/* internal variables */
static const char * progname ;
@ -965,6 +967,150 @@ initialize_environment(void)
load_resultmap ( ) ;
}
# ifdef ENABLE_SSPI
/*
* Get account and domain / realm names for the current user . This is based on
* pg_SSPI_recvauth ( ) . The returned strings use static storage .
*/
static void
current_windows_user ( const char * * acct , const char * * dom )
{
static char accountname [ MAXPGPATH ] ;
static char domainname [ MAXPGPATH ] ;
HANDLE token ;
TOKEN_USER * tokenuser ;
DWORD retlen ;
DWORD accountnamesize = sizeof ( accountname ) ;
DWORD domainnamesize = sizeof ( domainname ) ;
SID_NAME_USE accountnameuse ;
if ( ! OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_READ , & token ) )
{
fprintf ( stderr ,
_ ( " %s: could not open process token: error code %lu \n " ) ,
progname , GetLastError ( ) ) ;
exit ( 2 ) ;
}
if ( ! GetTokenInformation ( token , TokenUser , NULL , 0 , & retlen ) & & GetLastError ( ) ! = 122 )
{
fprintf ( stderr ,
_ ( " %s: could not get token user size: error code %lu \n " ) ,
progname , GetLastError ( ) ) ;
exit ( 2 ) ;
}
tokenuser = malloc ( retlen ) ;
if ( ! GetTokenInformation ( token , TokenUser , tokenuser , retlen , & retlen ) )
{
fprintf ( stderr ,
_ ( " %s: could not get token user: error code %lu \n " ) ,
progname , GetLastError ( ) ) ;
exit ( 2 ) ;
}
if ( ! LookupAccountSid ( NULL , tokenuser - > User . Sid , accountname , & accountnamesize ,
domainname , & domainnamesize , & accountnameuse ) )
{
fprintf ( stderr ,
_ ( " %s: could not look up account SID: error code %lu \n " ) ,
progname , GetLastError ( ) ) ;
exit ( 2 ) ;
}
free ( tokenuser ) ;
* acct = accountname ;
* dom = domainname ;
}
/*
* Rewrite pg_hba . conf and pg_ident . conf to use SSPI authentication . Permit
* the current OS user to authenticate as the bootstrap superuser and as any
* user named in a - - create - role option .
*/
static void
config_sspi_auth ( const char * pgdata )
{
const char * accountname ,
* domainname ;
const char * username ;
char * errstr ;
char fname [ MAXPGPATH ] ;
int res ;
FILE * hba ,
* ident ;
_stringlist * sl ;
/*
* " username " , the initdb - chosen bootstrap superuser name , may always
* match " accountname " , the value SSPI authentication discovers . The
* underlying system functions do not clearly guarantee that .
*/
current_windows_user ( & accountname , & domainname ) ;
username = get_user_name ( & errstr ) ;
if ( username = = NULL )
{
fprintf ( stderr , " %s: %s \n " , progname , errstr ) ;
exit ( 2 ) ;
}
/* Check a Write outcome and report any error. */
# define CW(cond) \
do { \
if ( ! ( cond ) ) \
{ \
fprintf ( stderr , _ ( " %s: could not write to file \" %s \" : %s \n " ) , \
progname , fname , strerror ( errno ) ) ; \
exit ( 2 ) ; \
} \
} while ( 0 )
res = snprintf ( fname , sizeof ( fname ) , " %s/pg_hba.conf " , pgdata ) ;
if ( res < 0 | | res > = sizeof ( fname ) - 1 )
{
/*
* Truncating this name is a fatal error , because we must not fail to
* overwrite an original trust - authentication pg_hba . conf .
*/
fprintf ( stderr , _ ( " %s: directory name too long \n " ) , progname ) ;
exit ( 2 ) ;
}
hba = fopen ( fname , " w " ) ;
if ( hba = = NULL )
{
fprintf ( stderr , _ ( " %s: could not open file \" %s \" for writing: %s \n " ) ,
progname , fname , strerror ( errno ) ) ;
exit ( 2 ) ;
}
CW ( fputs ( " # Configuration written by config_sspi_auth() \n " , hba ) > = 0 ) ;
CW ( fputs ( " host all all 127.0.0.1/32 sspi include_realm=1 map=regress \n " ,
hba ) > = 0 ) ;
CW ( fclose ( hba ) = = 0 ) ;
snprintf ( fname , sizeof ( fname ) , " %s/pg_ident.conf " , pgdata ) ;
ident = fopen ( fname , " w " ) ;
if ( ident = = NULL )
{
fprintf ( stderr , _ ( " %s: could not open file \" %s \" for writing: %s \n " ) ,
progname , fname , strerror ( errno ) ) ;
exit ( 2 ) ;
}
CW ( fputs ( " # Configuration written by config_sspi_auth() \n " , ident ) > = 0 ) ;
/*
* Double - quote for the benefit of account names containing whitespace or
* ' # ' . Windows forbids the double - quote character itself , so don ' t
* bother escaping embedded double - quote characters .
*/
CW ( fprintf ( ident , " regress \" %s@%s \" \" %s \" \n " ,
accountname , domainname , username ) > = 0 ) ;
for ( sl = extraroles ; sl ; sl = sl - > next )
CW ( fprintf ( ident , " regress \" %s@%s \" \" %s \" \n " ,
accountname , domainname , sl - > str ) > = 0 ) ;
CW ( fclose ( ident ) = = 0 ) ;
}
# endif
/*
* Issue a command via psql , connecting to the specified database
*
@ -1957,6 +2103,7 @@ help(void)
printf ( _ ( " Usage: \n %s [OPTION]... [EXTRA-TEST]... \n " ) , progname ) ;
printf ( _ ( " \n " ) ) ;
printf ( _ ( " Options: \n " ) ) ;
printf ( _ ( " --config-auth=DATADIR update authentication settings for DATADIR \n " ) ) ;
printf ( _ ( " --create-role=ROLE create the specified role before testing \n " ) ) ;
printf ( _ ( " --dbname=DB use database DB (default \" regression \" ) \n " ) ) ;
printf ( _ ( " --debug turn on debug mode in programs that are run \n " ) ) ;
@ -2023,6 +2170,7 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc
{ " launcher " , required_argument , NULL , 21 } ,
{ " load-extension " , required_argument , NULL , 22 } ,
{ " extra-install " , required_argument , NULL , 23 } ,
{ " config-auth " , required_argument , NULL , 24 } ,
{ NULL , 0 , NULL , 0 }
} ;
@ -2137,6 +2285,9 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc
case 23 :
add_stringlist_item ( & extra_install , optarg ) ;
break ;
case 24 :
config_auth_datadir = pstrdup ( optarg ) ;
break ;
default :
/* getopt_long already emitted a complaint */
fprintf ( stderr , _ ( " \n Try \" %s -h \" for more information. \n " ) ,
@ -2154,6 +2305,14 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc
optind + + ;
}
if ( config_auth_datadir )
{
# ifdef ENABLE_SSPI
config_sspi_auth ( config_auth_datadir ) ;
# endif
exit ( 0 ) ;
}
if ( temp_install & & ! port_specified_by_user )
/*
@ -2298,6 +2457,18 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc
fclose ( pg_conf ) ;
# ifdef ENABLE_SSPI
/*
* Since we successfully used the same buffer for the much - longer
* " initdb " command , this can ' t truncate .
*/
snprintf ( buf , sizeof ( buf ) , " %s/data " , temp_install ) ;
config_sspi_auth ( buf ) ;
# elif !defined(HAVE_UNIX_SOCKETS)
# error Platform has no means to secure the test installation.
# endif
/*
* Check if there is a postmaster running already .
*/