2011-04-02 03:00:52 +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
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"
2012-01-30 13:53:18 +04:00
# include "auth_info.h"
2011-04-02 03:00:52 +04:00
# include "secrets.h"
2016-10-28 13:14:37 +03:00
# include "param/param.h"
# include "librpc/gen_ndr/samr.h"
# include "auth/credentials/credentials.h"
# include "auth/gensec/gensec.h"
2011-04-02 03:00:52 +04:00
/**************************************************************************n
Code to cope with username / password auth options from the commandline .
Used mainly in client tools .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-10-21 11:23:21 +03:00
struct user_auth_info {
2016-10-28 13:14:37 +03:00
struct cli_credentials * creds ;
struct loadparm_context * lp_ctx ;
2017-08-29 18:06:21 +03:00
bool got_username ;
2016-10-21 11:23:21 +03:00
bool got_pass ;
int signing_state ;
bool smb_encrypt ;
bool use_machine_account ;
bool use_pw_nt_hash ;
2016-10-28 13:14:37 +03:00
char * pw_nt_hash ;
2016-10-21 11:23:21 +03:00
} ;
2011-04-02 03:00:52 +04:00
struct user_auth_info * user_auth_info_init ( TALLOC_CTX * mem_ctx )
{
2016-10-28 13:14:37 +03:00
struct user_auth_info * result = NULL ;
2011-04-02 03:00:52 +04:00
2011-06-07 05:44:43 +04:00
result = talloc_zero ( mem_ctx , struct user_auth_info ) ;
2011-04-02 03:00:52 +04:00
if ( result = = NULL ) {
return NULL ;
}
2016-10-28 13:14:37 +03:00
result - > lp_ctx = loadparm_init_s3 ( result , loadparm_s3_helpers ( ) ) ;
if ( result - > lp_ctx = = NULL ) {
TALLOC_FREE ( result ) ;
return NULL ;
}
result - > creds = cli_credentials_init ( result ) ;
if ( result - > creds = = NULL ) {
TALLOC_FREE ( result ) ;
return NULL ;
}
cli_credentials_set_conf ( result - > creds , result - > lp_ctx ) ;
2011-11-02 21:41:50 +04:00
result - > signing_state = SMB_SIGNING_DEFAULT ;
2011-04-02 03:00:52 +04:00
return result ;
}
2016-10-28 13:14:37 +03:00
void set_cmdline_auth_info_guess ( struct user_auth_info * auth_info )
2011-04-02 03:00:52 +04:00
{
2016-10-28 13:14:37 +03:00
/*
* Note that cli_credentials_guess ( ) calls
* cli_credentials_set_conf ( ) again , which will
* hopefully cope with a reloaded smb . conf .
*/
cli_credentials_set_username ( auth_info - > creds , " GUEST " , CRED_GUESS_ENV ) ;
cli_credentials_guess ( auth_info - > creds , auth_info - > lp_ctx ) ;
2011-04-02 03:00:52 +04:00
}
2016-10-28 13:14:37 +03:00
void set_cmdline_auth_info_from_file ( struct user_auth_info * auth_info ,
const char * filename )
2011-04-02 03:00:52 +04:00
{
2016-10-28 13:14:37 +03:00
bool ok ;
2016-09-15 13:08:24 +03:00
2016-10-28 13:14:37 +03:00
ok = cli_credentials_parse_file ( auth_info - > creds , filename ,
CRED_SPECIFIED ) ;
if ( ! ok ) {
exit ( EIO ) ;
2016-09-15 13:08:24 +03:00
}
2017-08-29 18:06:21 +03:00
auth_info - > got_username = true ;
2016-10-28 13:14:37 +03:00
}
2016-09-15 13:08:24 +03:00
2016-10-28 13:14:37 +03:00
const char * get_cmdline_auth_info_username ( const struct user_auth_info * auth_info )
{
const char * username = NULL ;
2016-09-15 13:08:24 +03:00
2016-10-28 13:14:37 +03:00
username = cli_credentials_get_username ( auth_info - > creds ) ;
if ( username = = NULL ) {
return " " ;
2016-09-15 13:08:24 +03:00
}
2016-10-28 13:14:37 +03:00
return username ;
}
2016-09-15 13:08:24 +03:00
2016-10-28 13:14:37 +03:00
void set_cmdline_auth_info_username ( struct user_auth_info * auth_info ,
const char * username )
{
const char * new_val = NULL ;
2016-09-15 13:08:24 +03:00
2017-02-17 12:08:17 +03:00
if ( username = = NULL ) {
return ;
}
2016-10-28 13:14:37 +03:00
cli_credentials_parse_string ( auth_info - > creds ,
username ,
CRED_SPECIFIED ) ;
new_val = cli_credentials_get_username ( auth_info - > creds ) ;
2017-02-17 12:08:17 +03:00
if ( new_val = = NULL ) {
2011-04-02 03:00:52 +04:00
exit ( ENOMEM ) ;
}
2016-10-28 13:14:37 +03:00
2017-08-29 18:06:21 +03:00
auth_info - > got_username = true ;
2016-10-28 13:14:37 +03:00
if ( strchr_m ( username , ' % ' ) ! = NULL ) {
auth_info - > got_pass = true ;
}
2011-04-02 03:00:52 +04:00
}
2017-08-29 18:06:21 +03:00
void reset_cmdline_auth_info_username ( struct user_auth_info * auth_info )
{
const char * username = NULL ;
const char * new_val = NULL ;
if ( ! auth_info - > got_username ) {
return ;
}
username = cli_credentials_get_username ( auth_info - > creds ) ;
if ( username = = NULL ) {
return ;
}
if ( username [ 0 ] = = ' \0 ' ) {
return ;
}
cli_credentials_parse_string ( auth_info - > creds ,
username ,
CRED_SPECIFIED ) ;
new_val = cli_credentials_get_username ( auth_info - > creds ) ;
if ( new_val = = NULL ) {
exit ( ENOMEM ) ;
}
}
2011-04-02 03:00:52 +04:00
const char * get_cmdline_auth_info_domain ( const struct user_auth_info * auth_info )
{
2016-10-28 13:14:37 +03:00
const char * domain = NULL ;
domain = cli_credentials_get_domain ( auth_info - > creds ) ;
if ( domain = = NULL ) {
2011-04-02 03:00:52 +04:00
return " " ;
}
2016-10-28 13:14:37 +03:00
return domain ;
2011-04-02 03:00:52 +04:00
}
void set_cmdline_auth_info_domain ( struct user_auth_info * auth_info ,
const char * domain )
{
2016-10-28 13:14:37 +03:00
bool ok ;
ok = cli_credentials_set_domain ( auth_info - > creds , domain , CRED_SPECIFIED ) ;
if ( ! ok ) {
2011-04-02 03:00:52 +04:00
exit ( ENOMEM ) ;
}
}
const char * get_cmdline_auth_info_password ( const struct user_auth_info * auth_info )
{
2016-10-28 13:14:37 +03:00
const char * password = NULL ;
if ( auth_info - > pw_nt_hash ! = NULL ) {
return auth_info - > pw_nt_hash ;
}
if ( auth_info - > use_pw_nt_hash ) {
struct user_auth_info * ai =
discard_const_p ( struct user_auth_info , auth_info ) ;
struct samr_Password * nt_hash = NULL ;
nt_hash = cli_credentials_get_nt_hash ( ai - > creds ,
ai ) ;
if ( nt_hash = = NULL ) {
return " " ;
}
ai - > pw_nt_hash = hex_encode_talloc ( ai ,
nt_hash - > hash ,
sizeof ( nt_hash - > hash ) ) ;
TALLOC_FREE ( nt_hash ) ;
if ( ai - > pw_nt_hash = = NULL ) {
return " " ;
}
return auth_info - > pw_nt_hash ;
}
password = cli_credentials_get_password ( auth_info - > creds ) ;
if ( password = = NULL ) {
2011-04-02 03:00:52 +04:00
return " " ;
}
2016-10-28 13:14:37 +03:00
return password ;
2011-04-02 03:00:52 +04:00
}
void set_cmdline_auth_info_password ( struct user_auth_info * auth_info ,
const char * password )
{
2016-10-28 13:14:37 +03:00
bool ok ;
auth_info - > got_pass = true ;
if ( password ! = NULL & & strlen ( password ) = = 0 ) {
password = NULL ;
2011-04-02 03:00:52 +04:00
}
2016-10-28 13:14:37 +03:00
ok = cli_credentials_set_password ( auth_info - > creds ,
password ,
CRED_SPECIFIED ) ;
if ( ! ok ) {
2011-04-02 03:00:52 +04:00
exit ( ENOMEM ) ;
}
}
bool set_cmdline_auth_info_signing_state ( struct user_auth_info * auth_info ,
const char * arg )
{
2011-11-02 22:00:57 +04:00
auth_info - > signing_state = SMB_SIGNING_DEFAULT ;
2011-04-02 03:00:52 +04:00
if ( strequal ( arg , " off " ) | | strequal ( arg , " no " ) | |
strequal ( arg , " false " ) ) {
2011-11-02 22:00:57 +04:00
auth_info - > signing_state = SMB_SIGNING_OFF ;
2011-04-02 03:00:52 +04:00
} else if ( strequal ( arg , " on " ) | | strequal ( arg , " yes " ) | |
2011-11-02 22:00:57 +04:00
strequal ( arg , " if_required " ) | |
2011-04-02 03:00:52 +04:00
strequal ( arg , " true " ) | | strequal ( arg , " auto " ) ) {
2011-11-02 22:00:57 +04:00
auth_info - > signing_state = SMB_SIGNING_IF_REQUIRED ;
2011-04-02 03:00:52 +04:00
} else if ( strequal ( arg , " force " ) | | strequal ( arg , " required " ) | |
strequal ( arg , " forced " ) ) {
2011-11-02 22:00:57 +04:00
auth_info - > signing_state = SMB_SIGNING_REQUIRED ;
2011-04-02 03:00:52 +04:00
} else {
return false ;
}
return true ;
}
2016-10-21 11:16:26 +03:00
void set_cmdline_auth_info_signing_state_raw ( struct user_auth_info * auth_info ,
int signing_state )
{
auth_info - > signing_state = signing_state ;
}
2011-04-02 03:00:52 +04:00
int get_cmdline_auth_info_signing_state ( const struct user_auth_info * auth_info )
{
2016-11-03 19:16:43 +03:00
if ( auth_info - > smb_encrypt ) {
return SMB_SIGNING_REQUIRED ;
}
2011-04-02 03:00:52 +04:00
return auth_info - > signing_state ;
}
void set_cmdline_auth_info_use_ccache ( struct user_auth_info * auth_info , bool b )
{
2016-10-28 13:14:37 +03:00
uint32_t gensec_features ;
gensec_features = cli_credentials_get_gensec_features ( auth_info - > creds ) ;
gensec_features | = GENSEC_FEATURE_NTLM_CCACHE ;
cli_credentials_set_gensec_features ( auth_info - > creds , gensec_features ) ;
2011-04-02 03:00:52 +04:00
}
bool get_cmdline_auth_info_use_ccache ( const struct user_auth_info * auth_info )
{
2016-10-28 13:14:37 +03:00
uint32_t gensec_features ;
gensec_features = cli_credentials_get_gensec_features ( auth_info - > creds ) ;
if ( gensec_features & GENSEC_FEATURE_NTLM_CCACHE ) {
return true ;
}
return false ;
2011-04-02 03:00:52 +04:00
}
2012-06-11 16:01:08 +04:00
void set_cmdline_auth_info_use_pw_nt_hash ( struct user_auth_info * auth_info ,
bool b )
{
2016-10-28 13:14:37 +03:00
TALLOC_FREE ( auth_info - > pw_nt_hash ) ;
2012-06-11 16:01:08 +04:00
auth_info - > use_pw_nt_hash = b ;
2016-10-28 13:14:37 +03:00
cli_credentials_set_password_will_be_nt_hash ( auth_info - > creds , b ) ;
2012-06-11 16:01:08 +04:00
}
bool get_cmdline_auth_info_use_pw_nt_hash (
const struct user_auth_info * auth_info )
{
return auth_info - > use_pw_nt_hash ;
}
2011-04-02 03:00:52 +04:00
void set_cmdline_auth_info_use_kerberos ( struct user_auth_info * auth_info ,
bool b )
{
2016-10-28 13:14:37 +03:00
enum credentials_use_kerberos krb5_state ;
if ( b ) {
krb5_state = CRED_MUST_USE_KERBEROS ;
} else {
krb5_state = CRED_DONT_USE_KERBEROS ;
}
cli_credentials_set_kerberos_state ( auth_info - > creds , krb5_state ) ;
2011-04-02 03:00:52 +04:00
}
bool get_cmdline_auth_info_use_kerberos ( const struct user_auth_info * auth_info )
{
2016-10-28 13:14:37 +03:00
enum credentials_use_kerberos krb5_state ;
krb5_state = cli_credentials_get_kerberos_state ( auth_info - > creds ) ;
if ( krb5_state = = CRED_MUST_USE_KERBEROS ) {
return true ;
}
return false ;
2011-04-02 03:00:52 +04:00
}
void set_cmdline_auth_info_fallback_after_kerberos ( struct user_auth_info * auth_info ,
bool b )
{
2016-10-28 13:14:37 +03:00
enum credentials_use_kerberos krb5_state ;
krb5_state = cli_credentials_get_kerberos_state ( auth_info - > creds ) ;
switch ( krb5_state ) {
case CRED_MUST_USE_KERBEROS :
if ( b ) {
krb5_state = CRED_AUTO_USE_KERBEROS ;
}
break ;
case CRED_AUTO_USE_KERBEROS :
if ( ! b ) {
krb5_state = CRED_MUST_USE_KERBEROS ;
}
break ;
case CRED_DONT_USE_KERBEROS :
/* nothing to do */
break ;
}
cli_credentials_set_kerberos_state ( auth_info - > creds , krb5_state ) ;
2011-04-02 03:00:52 +04:00
}
bool get_cmdline_auth_info_fallback_after_kerberos ( const struct user_auth_info * auth_info )
{
2016-10-28 13:14:37 +03:00
enum credentials_use_kerberos krb5_state ;
krb5_state = cli_credentials_get_kerberos_state ( auth_info - > creds ) ;
if ( krb5_state = = CRED_AUTO_USE_KERBEROS ) {
return true ;
}
return false ;
2011-04-02 03:00:52 +04:00
}
/* This should only be used by lib/popt_common.c JRA */
void set_cmdline_auth_info_use_krb5_ticket ( struct user_auth_info * auth_info )
{
2016-10-28 13:14:37 +03:00
set_cmdline_auth_info_use_kerberos ( auth_info , true ) ;
2011-04-02 03:00:52 +04:00
auth_info - > got_pass = true ;
}
/* This should only be used by lib/popt_common.c JRA */
void set_cmdline_auth_info_smb_encrypt ( struct user_auth_info * auth_info )
{
auth_info - > smb_encrypt = true ;
}
void set_cmdline_auth_info_use_machine_account ( struct user_auth_info * auth_info )
{
2016-10-28 13:14:37 +03:00
cli_credentials_set_machine_account_pending ( auth_info - > creds ,
auth_info - > lp_ctx ) ;
2011-04-02 03:00:52 +04:00
auth_info - > use_machine_account = true ;
}
bool get_cmdline_auth_info_got_pass ( const struct user_auth_info * auth_info )
{
return auth_info - > got_pass ;
}
bool get_cmdline_auth_info_smb_encrypt ( const struct user_auth_info * auth_info )
{
return auth_info - > smb_encrypt ;
}
bool get_cmdline_auth_info_use_machine_account ( const struct user_auth_info * auth_info )
{
return auth_info - > use_machine_account ;
}
bool set_cmdline_auth_info_machine_account_creds ( struct user_auth_info * auth_info )
{
2016-10-28 13:14:37 +03:00
struct db_context * db_ctx = NULL ;
NTSTATUS status ;
2011-04-02 03:00:52 +04:00
if ( ! get_cmdline_auth_info_use_machine_account ( auth_info ) ) {
return false ;
}
2016-10-28 13:14:37 +03:00
db_ctx = secrets_db_ctx ( ) ;
if ( db_ctx = = NULL ) {
2011-04-02 03:00:52 +04:00
d_printf ( " ERROR: Unable to open secrets database \n " ) ;
return false ;
}
2016-10-28 13:14:37 +03:00
cli_credentials_set_domain ( auth_info - > creds , lpcfg_workgroup ( auth_info - > lp_ctx ) ,
CRED_SPECIFIED ) ;
2011-04-02 03:00:52 +04:00
2016-10-28 13:14:37 +03:00
status = cli_credentials_set_machine_account_db_ctx ( auth_info - > creds ,
auth_info - > lp_ctx ,
db_ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-04-02 03:00:52 +04:00
d_printf ( " ERROR: Unable to fetch machine password for "
2016-10-28 13:14:37 +03:00
" %s in domain %s - %s \n " ,
lpcfg_netbios_name ( auth_info - > lp_ctx ) ,
lpcfg_workgroup ( auth_info - > lp_ctx ) ,
nt_errstr ( status ) ) ;
2011-04-02 03:00:52 +04:00
return false ;
}
2016-10-28 13:14:37 +03:00
return true ;
}
2011-04-02 03:00:52 +04:00
2016-10-28 13:14:37 +03:00
static const char * cmdline_auth_info_pw_callback ( struct cli_credentials * creds )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
const char * name = NULL ;
char * label = NULL ;
char * ret = NULL ;
char pwd [ 256 ] = { 0 } ;
int rc ;
2011-04-02 03:00:52 +04:00
2016-10-28 13:14:37 +03:00
name = cli_credentials_get_unparsed_name ( creds , frame ) ;
if ( name = = NULL ) {
goto fail ;
}
label = talloc_asprintf ( frame , " Enter %s's password: " , name ) ;
if ( label = = NULL ) {
goto fail ;
}
rc = samba_getpass ( label , pwd , sizeof ( pwd ) , false , false ) ;
if ( rc ! = 0 ) {
goto fail ;
}
ret = talloc_strdup ( creds , pwd ) ;
if ( ret = = NULL ) {
goto fail ;
}
talloc_set_name_const ( ret , __location__ ) ;
fail :
ZERO_STRUCT ( pwd ) ;
TALLOC_FREE ( frame ) ;
return ret ;
2011-04-02 03:00:52 +04:00
}
/****************************************************************************
Ensure we have a password if one not given .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void set_cmdline_auth_info_getpass ( struct user_auth_info * auth_info )
{
if ( get_cmdline_auth_info_got_pass ( auth_info ) | |
2014-11-14 11:31:51 +03:00
get_cmdline_auth_info_use_ccache ( auth_info ) | |
get_cmdline_auth_info_use_kerberos ( auth_info ) ) {
2011-04-02 03:00:52 +04:00
/* Already got one... */
return ;
}
2016-10-28 13:14:37 +03:00
cli_credentials_set_password_callback ( auth_info - > creds ,
cmdline_auth_info_pw_callback ) ;
}
struct cli_credentials * get_cmdline_auth_info_creds (
const struct user_auth_info * auth_info )
{
return auth_info - > creds ;
2011-04-02 03:00:52 +04:00
}