2010-08-19 19:25:32 +04:00
/*
* GSSAPI Security Extensions
* Krb5 helpers
* Copyright ( C ) Simo Sorce 2010.
*
* 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 "smb_krb5.h"
# include "secrets.h"
2017-08-17 18:45:21 +03:00
# include "librpc/gen_ndr/secrets.h"
2010-09-01 19:58:33 +04:00
# include "gse_krb5.h"
2012-07-23 06:47:01 +04:00
# include "lib/param/loadparm.h"
2016-02-29 18:21:56 +03:00
# include "libads/kerberos_proto.h"
2020-08-07 21:17:34 +03:00
# include "lib/util/string_wrappers.h"
2010-08-19 19:25:32 +04:00
# ifdef HAVE_KRB5
static krb5_error_code flush_keytab ( krb5_context krbctx , krb5_keytab keytab )
{
krb5_error_code ret ;
2010-08-31 13:01:23 +04:00
krb5_kt_cursor kt_cursor ;
2010-08-19 19:25:32 +04:00
krb5_keytab_entry kt_entry ;
ZERO_STRUCT ( kt_entry ) ;
ret = krb5_kt_start_seq_get ( krbctx , keytab , & kt_cursor ) ;
2021-10-21 16:01:48 +03:00
if ( ret ! = 0 ) {
return ret ;
2010-08-19 19:25:32 +04:00
}
ret = krb5_kt_next_entry ( krbctx , keytab , & kt_entry , & kt_cursor ) ;
while ( ret = = 0 ) {
/* we need to close and reopen enumeration because we modify
* the keytab */
ret = krb5_kt_end_seq_get ( krbctx , keytab , & kt_cursor ) ;
2021-10-21 16:01:48 +03:00
if ( ret ! = 0 ) {
2010-08-19 19:25:32 +04:00
DEBUG ( 1 , ( __location__ " : krb5_kt_end_seq_get() "
" failed (%s) \n " , error_message ( ret ) ) ) ;
goto out ;
}
/* remove the entry */
ret = krb5_kt_remove_entry ( krbctx , keytab , & kt_entry ) ;
2021-10-21 16:01:48 +03:00
if ( ret ! = 0 ) {
2010-08-19 19:25:32 +04:00
DEBUG ( 1 , ( __location__ " : krb5_kt_remove_entry() "
" failed (%s) \n " , error_message ( ret ) ) ) ;
goto out ;
}
2019-08-08 16:15:14 +03:00
smb_krb5_kt_free_entry ( krbctx , & kt_entry ) ;
2010-08-19 19:25:32 +04:00
ZERO_STRUCT ( kt_entry ) ;
/* now reopen */
ret = krb5_kt_start_seq_get ( krbctx , keytab , & kt_cursor ) ;
2021-10-21 16:01:48 +03:00
if ( ret ! = 0 ) {
2010-08-19 19:25:32 +04:00
DEBUG ( 1 , ( __location__ " : krb5_kt_start_seq() failed "
" (%s) \n " , error_message ( ret ) ) ) ;
goto out ;
}
ret = krb5_kt_next_entry ( krbctx , keytab ,
& kt_entry , & kt_cursor ) ;
}
if ( ret ! = KRB5_KT_END & & ret ! = ENOENT ) {
DEBUG ( 1 , ( __location__ " : flushing keytab we got [%s]! \n " ,
error_message ( ret ) ) ) ;
}
2021-10-21 16:01:48 +03:00
ret = krb5_kt_end_seq_get ( krbctx , keytab , & kt_cursor ) ;
if ( ret ! = 0 ) {
DEBUG ( 1 , ( __location__ " : krb5_kt_end_seq_get() "
" failed (%s) \n " , error_message ( ret ) ) ) ;
goto out ;
}
2010-08-19 19:25:32 +04:00
ret = 0 ;
out :
return ret ;
}
static krb5_error_code fill_keytab_from_password ( krb5_context krbctx ,
krb5_keytab keytab ,
krb5_principal princ ,
krb5_kvno vno ,
2017-08-17 18:45:21 +03:00
struct secrets_domain_info1_password * pw )
2010-08-19 19:25:32 +04:00
{
krb5_error_code ret ;
krb5_enctype * enctypes ;
2017-08-17 18:45:21 +03:00
uint16_t i ;
2010-08-19 19:25:32 +04:00
2016-08-25 18:02:59 +03:00
ret = smb_krb5_get_allowed_etypes ( krbctx , & enctypes ) ;
2010-08-19 19:25:32 +04:00
if ( ret ) {
DEBUG ( 1 , ( __location__
" : Can't determine permitted enctypes! \n " ) ) ;
return ret ;
}
2017-08-17 18:45:21 +03:00
for ( i = 0 ; i < pw - > num_keys ; i + + ) {
krb5_keytab_entry kt_entry ;
2010-08-19 19:25:32 +04:00
krb5_keyblock * key = NULL ;
2017-08-17 18:45:21 +03:00
unsigned int ei ;
bool found_etype = false ;
2010-08-19 19:25:32 +04:00
2017-08-17 18:45:21 +03:00
for ( ei = 0 ; enctypes [ ei ] ! = 0 ; ei + + ) {
if ( ( uint32_t ) enctypes [ ei ] ! = pw - > keys [ i ] . keytype ) {
continue ;
}
found_etype = true ;
break ;
2010-09-03 00:07:00 +04:00
}
2010-08-19 19:25:32 +04:00
2017-08-17 18:45:21 +03:00
if ( ! found_etype ) {
2010-08-19 19:25:32 +04:00
continue ;
}
2017-08-17 18:45:21 +03:00
ZERO_STRUCT ( kt_entry ) ;
2010-08-19 19:25:32 +04:00
kt_entry . principal = princ ;
kt_entry . vno = vno ;
2017-08-17 18:45:21 +03:00
key = KRB5_KT_KEY ( & kt_entry ) ;
KRB5_KEY_TYPE ( key ) = pw - > keys [ i ] . keytype ;
KRB5_KEY_DATA ( key ) = pw - > keys [ i ] . value . data ;
KRB5_KEY_LENGTH ( key ) = pw - > keys [ i ] . value . length ;
2010-08-19 19:25:32 +04:00
ret = krb5_kt_add_entry ( krbctx , keytab , & kt_entry ) ;
if ( ret ) {
DEBUG ( 1 , ( __location__ " : Failed to add entry to "
" keytab for enctype %d (error: %s) \n " ,
2017-08-17 18:45:21 +03:00
( unsigned ) pw - > keys [ i ] . keytype ,
error_message ( ret ) ) ) ;
2010-08-19 19:25:32 +04:00
goto out ;
}
}
ret = 0 ;
out :
SAFE_FREE ( enctypes ) ;
return ret ;
}
# define SRV_MEM_KEYTAB_NAME "MEMORY:cifs_srv_keytab"
# define CLEARTEXT_PRIV_ENCTYPE -99
2012-01-20 14:51:59 +04:00
static krb5_error_code fill_mem_keytab_from_secrets ( krb5_context krbctx ,
krb5_keytab * keytab )
2010-08-19 19:25:32 +04:00
{
2017-08-17 18:45:21 +03:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2021-10-21 16:01:48 +03:00
krb5_error_code ret , ret2 ;
2017-08-17 18:45:21 +03:00
const char * domain = lp_workgroup ( ) ;
struct secrets_domain_info1 * info = NULL ;
const char * realm = NULL ;
const DATA_BLOB * ct = NULL ;
2010-09-01 00:28:00 +04:00
krb5_kt_cursor kt_cursor ;
2010-08-19 19:25:32 +04:00
krb5_keytab_entry kt_entry ;
krb5_principal princ = NULL ;
krb5_kvno kvno = 0 ; /* FIXME: fetch current vno from KDC ? */
2017-08-17 18:45:21 +03:00
NTSTATUS status ;
2010-08-19 19:25:32 +04:00
if ( ! secrets_init ( ) ) {
DEBUG ( 1 , ( __location__ " : secrets_init failed \n " ) ) ;
2017-08-17 18:45:21 +03:00
TALLOC_FREE ( frame ) ;
2010-08-19 19:25:32 +04:00
return KRB5_CONFIG_CANTOPEN ;
}
2017-08-17 18:45:21 +03:00
status = secrets_fetch_or_upgrade_domain_info ( domain ,
frame ,
& info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_WARNING ( " secrets_fetch_or_upgrade_domain_info(%s) - %s \n " ,
domain , nt_errstr ( status ) ) ;
TALLOC_FREE ( frame ) ;
2010-08-19 19:25:32 +04:00
return KRB5_LIBOS_CANTREADPWD ;
}
2017-08-17 18:45:21 +03:00
ct = & info - > password - > cleartext_blob ;
if ( info - > domain_info . dns_domain . string ! = NULL ) {
realm = strupper_talloc ( frame ,
info - > domain_info . dns_domain . string ) ;
if ( realm = = NULL ) {
TALLOC_FREE ( frame ) ;
return ENOMEM ;
}
}
2010-08-19 19:25:32 +04:00
ZERO_STRUCT ( kt_entry ) ;
2010-09-01 00:28:00 +04:00
ZERO_STRUCT ( kt_cursor ) ;
2010-08-19 19:25:32 +04:00
/* check if the keytab already has any entry */
ret = krb5_kt_start_seq_get ( krbctx , * keytab , & kt_cursor ) ;
2021-10-21 16:01:48 +03:00
if ( ret ! = 0 ) {
goto out ;
}
2010-08-19 19:25:32 +04:00
2021-10-21 16:01:48 +03:00
/* check if we have our special enctype used to hold
* the clear text password . If so , check it out so that
* we can verify if the keytab needs to be upgraded */
while ( ( ret = krb5_kt_next_entry ( krbctx , * keytab ,
& kt_entry , & kt_cursor ) ) = = 0 ) {
if ( smb_krb5_kt_get_enctype_from_entry ( & kt_entry ) = =
CLEARTEXT_PRIV_ENCTYPE ) {
break ;
2010-08-19 19:25:32 +04:00
}
2021-10-21 16:01:48 +03:00
smb_krb5_kt_free_entry ( krbctx , & kt_entry ) ;
ZERO_STRUCT ( kt_entry ) ;
}
2010-08-19 19:25:32 +04:00
2021-10-21 16:01:48 +03:00
ret2 = krb5_kt_end_seq_get ( krbctx , * keytab , & kt_cursor ) ;
if ( ret2 ! = 0 ) {
ret = ret2 ;
DEBUG ( 1 , ( __location__ " : krb5_kt_end_seq_get() "
" failed (%s) \n " , error_message ( ret ) ) ) ;
goto out ;
}
2010-08-19 19:25:32 +04:00
2021-10-21 16:01:48 +03:00
if ( ret ! = 0 & & ret ! = KRB5_KT_END & & ret ! = ENOENT ) {
/* Error parsing keytab */
DEBUG ( 1 , ( __location__ " : Failed to parse memory "
" keytab! \n " ) ) ;
goto out ;
}
if ( ret = = 0 ) {
/* found private entry,
* check if keytab is up to date */
2010-08-19 19:25:32 +04:00
2021-10-21 16:01:48 +03:00
if ( ( ct - > length = = KRB5_KEY_LENGTH ( KRB5_KT_KEY ( & kt_entry ) ) ) & &
2022-05-11 03:07:43 +03:00
( mem_equal_const_time ( KRB5_KEY_DATA ( KRB5_KT_KEY ( & kt_entry ) ) ,
ct - > data , ct - > length ) ) ) {
2021-10-21 16:01:48 +03:00
/* keytab is already up to date, return */
2010-08-19 19:25:32 +04:00
smb_krb5_kt_free_entry ( krbctx , & kt_entry ) ;
2021-10-21 16:01:48 +03:00
goto out ;
}
2010-08-19 19:25:32 +04:00
2021-10-21 16:01:48 +03:00
smb_krb5_kt_free_entry ( krbctx , & kt_entry ) ;
ZERO_STRUCT ( kt_entry ) ;
2010-08-19 19:25:32 +04:00
2021-10-21 16:01:48 +03:00
/* flush keytab, we need to regen it */
ret = flush_keytab ( krbctx , * keytab ) ;
if ( ret ) {
DEBUG ( 1 , ( __location__ " : Failed to flush "
" memory keytab! \n " ) ) ;
goto out ;
}
2016-12-31 15:45:51 +03:00
}
2010-08-19 19:25:32 +04:00
/* keytab is not up to date, fill it up */
2017-08-17 18:45:21 +03:00
ret = smb_krb5_make_principal ( krbctx , & princ , realm ,
info - > account_name , NULL ) ;
2010-08-19 19:25:32 +04:00
if ( ret ) {
DEBUG ( 1 , ( __location__ " : Failed to get host principal! \n " ) ) ;
goto out ;
}
ret = fill_keytab_from_password ( krbctx , * keytab ,
2017-08-17 18:45:21 +03:00
princ , kvno ,
info - > password ) ;
2010-08-19 19:25:32 +04:00
if ( ret ) {
2017-08-17 18:45:21 +03:00
DBG_WARNING ( " fill_keytab_from_password() failed for "
" info->password. \n . " ) ;
2010-08-19 19:25:32 +04:00
goto out ;
}
2017-08-17 18:45:21 +03:00
if ( info - > old_password ! = NULL ) {
2010-08-19 19:25:32 +04:00
ret = fill_keytab_from_password ( krbctx , * keytab ,
2017-08-17 18:45:21 +03:00
princ , kvno - 1 ,
info - > old_password ) ;
2010-08-19 19:25:32 +04:00
if ( ret ) {
2017-08-17 18:45:21 +03:00
DBG_WARNING ( " fill_keytab_from_password() failed for "
" info->old_password. \n . " ) ;
goto out ;
}
}
if ( info - > older_password ! = NULL ) {
ret = fill_keytab_from_password ( krbctx , * keytab ,
princ , kvno - 2 ,
info - > older_password ) ;
if ( ret ) {
DBG_WARNING ( " fill_keytab_from_password() failed for "
" info->older_password. \n . " ) ;
goto out ;
}
}
if ( info - > next_change ! = NULL ) {
ret = fill_keytab_from_password ( krbctx , * keytab ,
princ , kvno - 3 ,
info - > next_change - > password ) ;
if ( ret ) {
DBG_WARNING ( " fill_keytab_from_password() failed for "
" info->next_change->password. \n . " ) ;
2010-08-19 19:25:32 +04:00
goto out ;
}
}
/* add our private enctype + cleartext password so that we can
* update the keytab if secrets change later on */
ZERO_STRUCT ( kt_entry ) ;
kt_entry . principal = princ ;
kt_entry . vno = 0 ;
2010-09-01 00:28:00 +04:00
KRB5_KEY_TYPE ( KRB5_KT_KEY ( & kt_entry ) ) = CLEARTEXT_PRIV_ENCTYPE ;
2017-08-17 18:45:21 +03:00
KRB5_KEY_LENGTH ( KRB5_KT_KEY ( & kt_entry ) ) = ct - > length ;
KRB5_KEY_DATA ( KRB5_KT_KEY ( & kt_entry ) ) = ct - > data ;
2010-08-19 19:25:32 +04:00
ret = krb5_kt_add_entry ( krbctx , * keytab , & kt_entry ) ;
if ( ret ) {
DEBUG ( 1 , ( __location__ " : Failed to add entry to "
" keytab for private enctype (%d) (error: %s) \n " ,
CLEARTEXT_PRIV_ENCTYPE , error_message ( ret ) ) ) ;
goto out ;
}
ret = 0 ;
out :
if ( princ ) {
krb5_free_principal ( krbctx , princ ) ;
}
2017-08-17 18:45:21 +03:00
TALLOC_FREE ( frame ) ;
2010-08-19 19:25:32 +04:00
return ret ;
}
2012-01-20 14:51:59 +04:00
static krb5_error_code fill_mem_keytab_from_system_keytab ( krb5_context krbctx ,
2012-01-20 12:31:55 +04:00
krb5_keytab * mkeytab )
2010-08-19 19:25:32 +04:00
{
2012-01-20 12:31:55 +04:00
krb5_error_code ret = 0 ;
krb5_keytab keytab = NULL ;
2017-02-16 19:42:53 +03:00
krb5_kt_cursor kt_cursor = { 0 , } ;
krb5_keytab_entry kt_entry = { 0 , } ;
2012-01-20 12:31:55 +04:00
char * valid_princ_formats [ 7 ] = { NULL , NULL , NULL ,
NULL , NULL , NULL , NULL } ;
char * entry_princ_s = NULL ;
fstring my_name , my_fqdn ;
2016-10-18 13:51:16 +03:00
unsigned i ;
2012-01-20 12:31:55 +04:00
int err ;
/* Generate the list of principal names which we expect
* clients might want to use for authenticating to the file
* service . We allow name $ , { host , cifs } / { name , fqdn , name . REALM } . */
fstrcpy ( my_name , lp_netbios_name ( ) ) ;
my_fqdn [ 0 ] = ' \0 ' ;
name_to_fqdn ( my_fqdn , lp_netbios_name ( ) ) ;
err = asprintf ( & valid_princ_formats [ 0 ] ,
" %s$@%s " , my_name , lp_realm ( ) ) ;
if ( err = = - 1 ) {
ret = ENOMEM ;
goto out ;
}
err = asprintf ( & valid_princ_formats [ 1 ] ,
" host/%s@%s " , my_name , lp_realm ( ) ) ;
if ( err = = - 1 ) {
ret = ENOMEM ;
goto out ;
}
err = asprintf ( & valid_princ_formats [ 2 ] ,
" host/%s@%s " , my_fqdn , lp_realm ( ) ) ;
if ( err = = - 1 ) {
ret = ENOMEM ;
goto out ;
}
err = asprintf ( & valid_princ_formats [ 3 ] ,
" host/%s.%s@%s " , my_name , lp_realm ( ) , lp_realm ( ) ) ;
if ( err = = - 1 ) {
ret = ENOMEM ;
goto out ;
}
err = asprintf ( & valid_princ_formats [ 4 ] ,
" cifs/%s@%s " , my_name , lp_realm ( ) ) ;
if ( err = = - 1 ) {
ret = ENOMEM ;
goto out ;
}
err = asprintf ( & valid_princ_formats [ 5 ] ,
" cifs/%s@%s " , my_fqdn , lp_realm ( ) ) ;
if ( err = = - 1 ) {
ret = ENOMEM ;
goto out ;
}
err = asprintf ( & valid_princ_formats [ 6 ] ,
" cifs/%s.%s@%s " , my_name , lp_realm ( ) , lp_realm ( ) ) ;
if ( err = = - 1 ) {
ret = ENOMEM ;
goto out ;
}
2016-12-14 18:43:53 +03:00
ret = smb_krb5_kt_open_relative ( krbctx , NULL , false , & keytab ) ;
2012-01-20 12:31:55 +04:00
if ( ret ) {
2016-08-29 12:03:51 +03:00
DEBUG ( 1 , ( " smb_krb5_kt_open failed (%s) \n " ,
2012-01-20 12:31:55 +04:00
error_message ( ret ) ) ) ;
goto out ;
}
/*
* Iterate through the keytab . For each key , if the principal
* name case - insensitively matches one of the allowed formats ,
* copy it to the memory keytab .
*/
ret = krb5_kt_start_seq_get ( krbctx , keytab , & kt_cursor ) ;
if ( ret ) {
DEBUG ( 1 , ( __location__ " : krb5_kt_start_seq_get failed (%s) \n " ,
error_message ( ret ) ) ) ;
2017-06-24 14:41:48 +03:00
/*
* krb5_kt_start_seq_get ( ) may leaves bogus data
* in kt_cursor . And we want to use the all_zero ( )
* logic below .
*
* See bug # 10490
*/
ZERO_STRUCT ( kt_cursor ) ;
2012-01-20 12:31:55 +04:00
goto out ;
}
while ( ( krb5_kt_next_entry ( krbctx , keytab ,
& kt_entry , & kt_cursor ) = = 0 ) ) {
ret = smb_krb5_unparse_name ( talloc_tos ( ) , krbctx ,
kt_entry . principal ,
& entry_princ_s ) ;
if ( ret ) {
DEBUG ( 1 , ( __location__ " : smb_krb5_unparse_name "
" failed (%s) \n " , error_message ( ret ) ) ) ;
goto out ;
}
for ( i = 0 ; i < ARRAY_SIZE ( valid_princ_formats ) ; i + + ) {
if ( ! strequal ( entry_princ_s , valid_princ_formats [ i ] ) ) {
continue ;
}
ret = krb5_kt_add_entry ( krbctx , * mkeytab , & kt_entry ) ;
if ( ret ) {
DEBUG ( 1 , ( __location__ " : smb_krb5_unparse_name "
" failed (%s) \n " , error_message ( ret ) ) ) ;
goto out ;
}
}
/* Free the name we parsed. */
TALLOC_FREE ( entry_princ_s ) ;
/* Free the entry we just read. */
smb_krb5_kt_free_entry ( krbctx , & kt_entry ) ;
ZERO_STRUCT ( kt_entry ) ;
}
krb5_kt_end_seq_get ( krbctx , keytab , & kt_cursor ) ;
ZERO_STRUCT ( kt_cursor ) ;
out :
for ( i = 0 ; i < ARRAY_SIZE ( valid_princ_formats ) ; i + + ) {
SAFE_FREE ( valid_princ_formats [ i ] ) ;
}
TALLOC_FREE ( entry_princ_s ) ;
2016-12-31 15:45:51 +03:00
if ( ! all_zero ( ( uint8_t * ) & kt_entry , sizeof ( kt_entry ) ) ) {
smb_krb5_kt_free_entry ( krbctx , & kt_entry ) ;
2012-01-20 12:31:55 +04:00
}
2016-12-31 15:45:51 +03:00
if ( ! all_zero ( ( uint8_t * ) & kt_cursor , sizeof ( kt_cursor ) ) & & keytab ) {
krb5_kt_end_seq_get ( krbctx , keytab , & kt_cursor ) ;
2012-01-20 12:31:55 +04:00
}
if ( keytab ) {
krb5_kt_close ( krbctx , keytab ) ;
}
return ret ;
}
static krb5_error_code fill_mem_keytab_from_dedicated_keytab ( krb5_context krbctx ,
krb5_keytab * mkeytab )
{
krb5_error_code ret = 0 ;
krb5_keytab keytab = NULL ;
krb5_kt_cursor kt_cursor ;
krb5_keytab_entry kt_entry ;
2016-08-29 12:03:51 +03:00
ret = smb_krb5_kt_open ( krbctx , lp_dedicated_keytab_file ( ) ,
2012-01-20 12:31:55 +04:00
false , & keytab ) ;
if ( ret ) {
2017-09-25 05:18:34 +03:00
DEBUG ( 1 , ( " smb_krb5_kt_open of %s failed (%s) \n " ,
lp_dedicated_keytab_file ( ) ,
2012-01-20 12:31:55 +04:00
error_message ( ret ) ) ) ;
2014-11-27 07:13:23 +03:00
return ret ;
2012-01-20 12:31:55 +04:00
}
/*
2018-06-18 14:46:32 +03:00
* Copy the dedicated keyab to our in - memory keytab .
2012-01-20 12:31:55 +04:00
*/
ret = krb5_kt_start_seq_get ( krbctx , keytab , & kt_cursor ) ;
if ( ret ) {
2017-09-25 05:18:34 +03:00
DEBUG ( 1 , ( __location__ " : krb5_kt_start_seq_get on %s "
" failed (%s) \n " ,
lp_dedicated_keytab_file ( ) ,
2012-01-20 12:31:55 +04:00
error_message ( ret ) ) ) ;
goto out ;
}
while ( ( krb5_kt_next_entry ( krbctx , keytab ,
& kt_entry , & kt_cursor ) = = 0 ) ) {
ret = krb5_kt_add_entry ( krbctx , * mkeytab , & kt_entry ) ;
2014-11-27 07:13:23 +03:00
/* Free the entry we just read. */
smb_krb5_kt_free_entry ( krbctx , & kt_entry ) ;
2012-01-20 12:31:55 +04:00
if ( ret ) {
DEBUG ( 1 , ( __location__ " : smb_krb5_unparse_name "
" failed (%s) \n " , error_message ( ret ) ) ) ;
2014-11-27 07:13:23 +03:00
break ;
2012-01-20 12:31:55 +04:00
}
}
krb5_kt_end_seq_get ( krbctx , keytab , & kt_cursor ) ;
out :
2021-10-21 16:01:48 +03:00
2014-11-27 07:13:23 +03:00
krb5_kt_close ( krbctx , keytab ) ;
2012-01-20 12:31:55 +04:00
return ret ;
2010-08-19 19:25:32 +04:00
}
2010-09-01 19:58:33 +04:00
krb5_error_code gse_krb5_get_server_keytab ( krb5_context krbctx ,
2010-08-19 19:25:32 +04:00
krb5_keytab * keytab )
{
2012-01-20 14:50:20 +04:00
krb5_error_code ret = 0 ;
krb5_error_code ret1 = 0 ;
krb5_error_code ret2 = 0 ;
2010-08-19 19:25:32 +04:00
* keytab = NULL ;
2012-01-20 14:51:59 +04:00
/* create memory keytab */
ret = krb5_kt_resolve ( krbctx , SRV_MEM_KEYTAB_NAME , keytab ) ;
if ( ret ) {
DEBUG ( 1 , ( __location__ " : Failed to get memory "
" keytab! \n " ) ) ;
return ret ;
}
2010-08-19 19:25:32 +04:00
switch ( lp_kerberos_method ( ) ) {
default :
case KERBEROS_VERIFY_SECRETS :
2012-01-20 14:51:59 +04:00
ret = fill_mem_keytab_from_secrets ( krbctx , keytab ) ;
2010-08-19 19:25:32 +04:00
break ;
case KERBEROS_VERIFY_SYSTEM_KEYTAB :
2012-01-20 12:31:55 +04:00
ret = fill_mem_keytab_from_system_keytab ( krbctx , keytab ) ;
2010-08-19 19:25:32 +04:00
break ;
case KERBEROS_VERIFY_DEDICATED_KEYTAB :
/* just use whatever keytab is configured */
2012-01-20 12:31:55 +04:00
ret = fill_mem_keytab_from_dedicated_keytab ( krbctx , keytab ) ;
2010-08-19 19:25:32 +04:00
break ;
case KERBEROS_VERIFY_SECRETS_AND_KEYTAB :
2012-01-20 14:51:59 +04:00
ret1 = fill_mem_keytab_from_secrets ( krbctx , keytab ) ;
2012-01-20 14:50:20 +04:00
if ( ret1 ) {
2010-08-19 19:25:32 +04:00
DEBUG ( 3 , ( __location__ " : Warning! Unable to set mem "
" keytab from secrets! \n " ) ) ;
}
/* Now append system keytab keys too */
2012-01-20 12:31:55 +04:00
ret2 = fill_mem_keytab_from_system_keytab ( krbctx , keytab ) ;
2012-01-20 14:50:20 +04:00
if ( ret2 ) {
2010-08-19 19:25:32 +04:00
DEBUG ( 3 , ( __location__ " : Warning! Unable to set mem "
2012-01-20 14:50:20 +04:00
" keytab from system keytab! \n " ) ) ;
}
if ( ret1 = = 0 | | ret2 = = 0 ) {
ret = 0 ;
} else {
ret = ret1 ;
2010-08-19 19:25:32 +04:00
}
break ;
}
2012-01-20 14:51:59 +04:00
if ( ret ) {
krb5_kt_close ( krbctx , * keytab ) ;
* keytab = NULL ;
DEBUG ( 1 , ( " %s: Error! Unable to set mem keytab - %d \n " ,
__location__ , ret ) ) ;
}
2010-08-19 19:25:32 +04:00
return ret ;
}
# endif /* HAVE_KRB5 */