2012-03-30 19:33:53 -04:00
/*
Unix SMB / CIFS implementation .
Kerberos utility functions
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2004 - 2005
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 "system/kerberos.h"
# include "auth/kerberos/kerberos.h"
# include "auth/kerberos/kerberos_srv_keytab.h"
2012-03-31 01:27:02 -04:00
static void keytab_principals_free ( krb5_context context , krb5_principal * set )
{
int i ;
for ( i = 0 ; set [ i ] ! = NULL ; i + + ) {
krb5_free_principal ( context , set [ i ] ) ;
}
}
static krb5_error_code principals_from_list ( TALLOC_CTX * parent_ctx ,
const char * samAccountName ,
const char * realm ,
const char * * SPNs , int num_SPNs ,
krb5_context context ,
krb5_principal * * principals_out ,
const char * * error_string )
2012-03-30 19:33:53 -04:00
{
unsigned int i ;
krb5_error_code ret ;
char * upper_realm ;
TALLOC_CTX * tmp_ctx ;
2012-03-31 01:27:02 -04:00
krb5_principal * principals = NULL ;
2012-03-30 19:33:53 -04:00
tmp_ctx = talloc_new ( parent_ctx ) ;
if ( ! tmp_ctx ) {
* error_string = " Cannot allocate tmp_ctx " ;
return ENOMEM ;
}
if ( ! realm ) {
2012-04-19 09:35:08 -04:00
* error_string = " Cannot make principal without a realm " ;
2012-03-31 01:27:02 -04:00
ret = EINVAL ;
goto done ;
2012-03-30 19:33:53 -04:00
}
upper_realm = strupper_talloc ( tmp_ctx , realm ) ;
if ( ! upper_realm ) {
* error_string = " Cannot allocate full upper case realm " ;
2012-03-31 01:27:02 -04:00
ret = ENOMEM ;
goto done ;
2012-03-30 19:33:53 -04:00
}
2012-03-31 01:27:02 -04:00
principals = talloc_zero_array ( tmp_ctx , krb5_principal ,
num_SPNs ? ( num_SPNs + 2 ) : 2 ) ;
2012-03-30 19:33:53 -04:00
2012-03-31 01:27:02 -04:00
for ( i = 0 ; num_SPNs & & i < num_SPNs ; i + + ) {
ret = krb5_parse_name ( context , SPNs [ i ] , & principals [ i ] ) ;
2012-03-30 19:33:53 -04:00
if ( ret ) {
2012-03-31 01:27:02 -04:00
* error_string = smb_get_krb5_error_message ( context , ret ,
parent_ctx ) ;
goto done ;
2012-03-30 19:33:53 -04:00
}
}
if ( samAccountName ) {
2012-04-26 18:11:09 -04:00
ret = smb_krb5_make_principal ( context , & principals [ i ] ,
2012-03-30 19:33:53 -04:00
upper_realm , samAccountName ,
NULL ) ;
if ( ret ) {
2012-03-31 01:27:02 -04:00
* error_string = smb_get_krb5_error_message ( context , ret ,
parent_ctx ) ;
goto done ;
2012-03-30 19:33:53 -04:00
}
}
2012-03-31 01:27:02 -04:00
done :
if ( ret ) {
keytab_principals_free ( context , principals ) ;
} else {
* principals_out = talloc_steal ( parent_ctx , principals ) ;
}
2012-03-30 19:33:53 -04:00
talloc_free ( tmp_ctx ) ;
return ret ;
}
2012-03-31 01:27:02 -04:00
static krb5_error_code salt_principal ( TALLOC_CTX * parent_ctx ,
const char * samAccountName ,
const char * realm ,
const char * saltPrincipal ,
krb5_context context ,
2012-03-30 19:33:53 -04:00
krb5_principal * salt_princ ,
const char * * error_string )
{
krb5_error_code ret ;
char * machine_username ;
char * salt_body ;
char * lower_realm ;
char * upper_realm ;
TALLOC_CTX * tmp_ctx ;
2012-03-31 01:27:02 -04:00
if ( saltPrincipal ) {
ret = krb5_parse_name ( context , saltPrincipal , salt_princ ) ;
if ( ret ) {
* error_string = smb_get_krb5_error_message (
context , ret , parent_ctx ) ;
}
return ret ;
2012-03-30 19:33:53 -04:00
}
if ( ! samAccountName ) {
( * error_string ) = " Cannot determine salt principal, no "
" saltPrincipal or samAccountName specified " ;
return EINVAL ;
}
2012-03-31 01:27:02 -04:00
if ( ! realm ) {
2012-04-19 09:35:08 -04:00
* error_string = " Cannot make principal without a realm " ;
2012-03-31 01:27:02 -04:00
return EINVAL ;
2012-03-30 19:33:53 -04:00
}
2012-03-31 01:27:02 -04:00
tmp_ctx = talloc_new ( parent_ctx ) ;
2012-03-30 19:33:53 -04:00
if ( ! tmp_ctx ) {
* error_string = " Cannot allocate tmp_ctx " ;
return ENOMEM ;
}
machine_username = talloc_strdup ( tmp_ctx , samAccountName ) ;
if ( ! machine_username ) {
* error_string = " Cannot duplicate samAccountName " ;
2012-03-31 01:27:02 -04:00
talloc_free ( tmp_ctx ) ;
2012-03-30 19:33:53 -04:00
return ENOMEM ;
}
if ( machine_username [ strlen ( machine_username ) - 1 ] = = ' $ ' ) {
machine_username [ strlen ( machine_username ) - 1 ] = ' \0 ' ;
}
lower_realm = strlower_talloc ( tmp_ctx , realm ) ;
if ( ! lower_realm ) {
* error_string = " Cannot allocate to lower case realm " ;
2012-03-31 01:27:02 -04:00
talloc_free ( tmp_ctx ) ;
2012-03-30 19:33:53 -04:00
return ENOMEM ;
}
upper_realm = strupper_talloc ( tmp_ctx , realm ) ;
if ( ! upper_realm ) {
* error_string = " Cannot allocate to upper case realm " ;
2012-03-31 01:27:02 -04:00
talloc_free ( tmp_ctx ) ;
2012-03-30 19:33:53 -04:00
return ENOMEM ;
}
2012-03-31 01:27:02 -04:00
salt_body = talloc_asprintf ( tmp_ctx , " %s.%s " ,
machine_username , lower_realm ) ;
2012-03-30 19:33:53 -04:00
if ( ! salt_body ) {
* error_string = " Cannot form salt principal body " ;
2012-03-31 01:27:02 -04:00
talloc_free ( tmp_ctx ) ;
2012-03-30 19:33:53 -04:00
return ENOMEM ;
}
2012-04-26 18:11:09 -04:00
ret = smb_krb5_make_principal ( context , salt_princ , upper_realm ,
2012-03-31 01:27:02 -04:00
" host " , salt_body , NULL ) ;
if ( ret ) {
* error_string = smb_get_krb5_error_message ( context ,
ret , parent_ctx ) ;
2012-03-30 19:33:53 -04:00
}
2012-03-31 01:27:02 -04:00
2012-03-30 19:33:53 -04:00
talloc_free ( tmp_ctx ) ;
return ret ;
}
static krb5_error_code keytab_add_keys ( TALLOC_CTX * parent_ctx ,
2012-03-31 01:27:02 -04:00
krb5_principal * principals ,
2012-03-30 19:33:53 -04:00
krb5_principal salt_princ ,
int kvno ,
const char * password_s ,
2012-03-31 01:27:02 -04:00
krb5_context context ,
2012-03-30 19:33:53 -04:00
krb5_enctype * enctypes ,
krb5_keytab keytab ,
const char * * error_string )
{
unsigned int i , p ;
krb5_error_code ret ;
krb5_data password ;
2012-03-31 01:27:02 -04:00
char * unparsed ;
2012-03-30 19:33:53 -04:00
2012-04-26 17:56:38 -04:00
password . data = discard_const_p ( char , password_s ) ;
2012-03-30 19:33:53 -04:00
password . length = strlen ( password_s ) ;
for ( i = 0 ; enctypes [ i ] ; i + + ) {
krb5_keytab_entry entry ;
ZERO_STRUCT ( entry ) ;
2012-03-31 01:27:02 -04:00
ret = create_kerberos_key_from_string_direct ( context ,
2012-03-30 19:33:53 -04:00
salt_princ , & password ,
2012-04-26 18:11:09 -04:00
KRB5_KT_KEY ( & entry ) ,
enctypes [ i ] ) ;
2012-03-30 19:33:53 -04:00
if ( ret ! = 0 ) {
return ret ;
}
entry . vno = kvno ;
for ( p = 0 ; principals [ p ] ; p + + ) {
2012-03-31 01:27:02 -04:00
unparsed = NULL ;
entry . principal = principals [ p ] ;
ret = krb5_kt_add_entry ( context , keytab , & entry ) ;
2012-03-30 19:33:53 -04:00
if ( ret ! = 0 ) {
char * k5_error_string =
2012-03-31 01:27:02 -04:00
smb_get_krb5_error_message ( context ,
ret , NULL ) ;
krb5_unparse_name ( context ,
principals [ p ] , & unparsed ) ;
2012-03-30 19:33:53 -04:00
* error_string = talloc_asprintf ( parent_ctx ,
" Failed to add enctype %d entry for "
" %s(kvno %d) to keytab: %s \n " ,
2012-03-31 01:27:02 -04:00
( int ) enctypes [ i ] , unparsed ,
2012-03-30 19:33:53 -04:00
kvno , k5_error_string ) ;
2012-03-31 01:27:02 -04:00
free ( unparsed ) ;
2012-03-30 19:33:53 -04:00
talloc_free ( k5_error_string ) ;
2012-03-31 01:27:02 -04:00
krb5_free_keyblock_contents ( context ,
2012-04-26 18:11:09 -04:00
KRB5_KT_KEY ( & entry ) ) ;
2012-03-30 19:33:53 -04:00
return ret ;
}
2012-03-31 01:27:02 -04:00
DEBUG ( 5 , ( " Added key (kvno %d) to keytab (enctype %d) \n " ,
kvno , ( int ) enctypes [ i ] ) ) ;
2012-03-30 19:33:53 -04:00
}
2012-04-26 18:11:09 -04:00
krb5_free_keyblock_contents ( context , KRB5_KT_KEY ( & entry ) ) ;
2012-03-30 19:33:53 -04:00
}
return 0 ;
}
static krb5_error_code create_keytab ( TALLOC_CTX * parent_ctx ,
2012-03-31 01:27:02 -04:00
const char * samAccountName ,
const char * realm ,
const char * saltPrincipal ,
int kvno ,
const char * new_secret ,
const char * old_secret ,
uint32_t supp_enctypes ,
krb5_principal * principals ,
krb5_context context ,
2012-03-30 19:33:53 -04:00
krb5_keytab keytab ,
bool add_old ,
const char * * error_string )
{
krb5_error_code ret ;
2012-03-31 01:27:02 -04:00
krb5_principal salt_princ = NULL ;
2012-03-30 19:33:53 -04:00
krb5_enctype * enctypes ;
2012-03-31 01:27:02 -04:00
TALLOC_CTX * mem_ctx ;
if ( ! new_secret ) {
/* There is no password here, so nothing to do */
return 0 ;
}
mem_ctx = talloc_new ( parent_ctx ) ;
2012-03-30 19:33:53 -04:00
if ( ! mem_ctx ) {
2014-06-12 10:39:02 +02:00
* error_string = talloc_strdup ( parent_ctx ,
" unable to allocate tmp_ctx for create_keytab " ) ;
2012-03-30 19:33:53 -04:00
return ENOMEM ;
}
/* The salt used to generate these entries may be different however,
* fetch that */
2012-03-31 01:27:02 -04:00
ret = salt_principal ( mem_ctx , samAccountName , realm , saltPrincipal ,
context , & salt_princ , error_string ) ;
2012-03-30 19:33:53 -04:00
if ( ret ) {
talloc_free ( mem_ctx ) ;
return ret ;
}
2012-03-31 01:27:02 -04:00
ret = ms_suptypes_to_ietf_enctypes ( mem_ctx , supp_enctypes , & enctypes ) ;
2012-03-30 19:33:53 -04:00
if ( ret ) {
* error_string = talloc_asprintf ( parent_ctx ,
" create_keytab: generating list of "
" encryption types failed (%s) \n " ,
2012-03-31 01:27:02 -04:00
smb_get_krb5_error_message ( context ,
ret , mem_ctx ) ) ;
goto done ;
2012-03-30 19:33:53 -04:00
}
ret = keytab_add_keys ( mem_ctx , principals ,
2012-03-31 01:27:02 -04:00
salt_princ , kvno , new_secret ,
context , enctypes , keytab , error_string ) ;
2012-03-30 19:33:53 -04:00
if ( ret ) {
2014-06-12 10:39:02 +02:00
talloc_steal ( parent_ctx , * error_string ) ;
2012-03-31 01:27:02 -04:00
goto done ;
2012-03-30 19:33:53 -04:00
}
2012-03-31 01:27:02 -04:00
if ( old_secret & & add_old & & kvno ! = 0 ) {
2012-03-30 19:33:53 -04:00
ret = keytab_add_keys ( mem_ctx , principals ,
salt_princ , kvno - 1 , old_secret ,
2012-03-31 01:27:02 -04:00
context , enctypes , keytab , error_string ) ;
2014-06-12 10:39:02 +02:00
if ( ret ) {
talloc_steal ( parent_ctx , * error_string ) ;
}
2012-03-30 19:33:53 -04:00
}
2012-03-31 01:27:02 -04:00
done :
krb5_free_principal ( context , salt_princ ) ;
2012-03-30 19:33:53 -04:00
talloc_free ( mem_ctx ) ;
return ret ;
}
/*
* Walk the keytab , looking for entries of this principal name ,
* with KVNO other than current kvno - 1.
*
* These entries are now stale ,
* we only keep the current and previous entries around .
*
* Inspired by the code in Samba3 for ' use kerberos keytab ' .
*/
static krb5_error_code remove_old_entries ( TALLOC_CTX * parent_ctx ,
2012-03-31 01:27:02 -04:00
int kvno ,
krb5_principal * principals ,
2012-03-30 19:33:53 -04:00
bool delete_all_kvno ,
2012-03-31 01:27:02 -04:00
krb5_context context ,
2012-03-30 19:33:53 -04:00
krb5_keytab keytab ,
bool * found_previous ,
const char * * error_string )
{
krb5_error_code ret , ret2 ;
krb5_kt_cursor cursor ;
TALLOC_CTX * mem_ctx = talloc_new ( parent_ctx ) ;
if ( ! mem_ctx ) {
return ENOMEM ;
}
* found_previous = false ;
/* for each entry in the keytab */
2012-03-31 01:27:02 -04:00
ret = krb5_kt_start_seq_get ( context , keytab , & cursor ) ;
2012-03-30 19:33:53 -04:00
switch ( ret ) {
case 0 :
break ;
2012-04-26 18:11:09 -04:00
# ifdef HEIM_ERR_OPNOTSUPP
2012-03-30 19:33:53 -04:00
case HEIM_ERR_OPNOTSUPP :
2012-04-26 18:11:09 -04:00
# endif
2012-03-30 19:33:53 -04:00
case ENOENT :
case KRB5_KT_END :
/* no point enumerating if there isn't anything here */
talloc_free ( mem_ctx ) ;
return 0 ;
default :
* error_string = talloc_asprintf ( parent_ctx ,
" failed to open keytab for read of old entries: %s \n " ,
2012-03-31 01:27:02 -04:00
smb_get_krb5_error_message ( context , ret , mem_ctx ) ) ;
2012-03-30 19:33:53 -04:00
talloc_free ( mem_ctx ) ;
return ret ;
}
while ( ! ret ) {
unsigned int i ;
bool matched = false ;
krb5_keytab_entry entry ;
2012-03-31 01:27:02 -04:00
ret = krb5_kt_next_entry ( context , keytab , & entry , & cursor ) ;
2012-03-30 19:33:53 -04:00
if ( ret ) {
break ;
}
for ( i = 0 ; principals [ i ] ; i + + ) {
/* if it matches our principal */
2012-04-26 18:11:09 -04:00
if ( smb_krb5_kt_compare ( context , & entry ,
principals [ i ] , 0 , 0 ) ) {
2012-03-30 19:33:53 -04:00
matched = true ;
break ;
}
}
if ( ! matched ) {
/* Free the entry,
* it wasn ' t the one we were looking for anyway */
2012-03-31 01:27:02 -04:00
krb5_kt_free_entry ( context , & entry ) ;
2012-03-30 19:33:53 -04:00
continue ;
}
/* delete it, if it is not kvno -1 */
if ( entry . vno ! = ( kvno - 1 ) ) {
/* Release the enumeration. We are going to
* have to start this from the top again ,
* because deletes during enumeration may not
* always be consistent .
*
* Also , the enumeration locks a FILE : keytab
*/
2012-03-31 01:27:02 -04:00
krb5_kt_end_seq_get ( context , keytab , & cursor ) ;
2012-03-30 19:33:53 -04:00
2012-03-31 01:27:02 -04:00
ret = krb5_kt_remove_entry ( context , keytab , & entry ) ;
krb5_kt_free_entry ( context , & entry ) ;
2012-03-30 19:33:53 -04:00
/* Deleted: Restart from the top */
2012-03-31 01:27:02 -04:00
ret2 = krb5_kt_start_seq_get ( context , keytab , & cursor ) ;
2012-03-30 19:33:53 -04:00
if ( ret2 ) {
2012-03-31 01:27:02 -04:00
krb5_kt_free_entry ( context , & entry ) ;
2012-03-30 19:33:53 -04:00
DEBUG ( 1 , ( " failed to restart enumeration of keytab: %s \n " ,
2012-03-31 01:27:02 -04:00
smb_get_krb5_error_message ( context ,
ret , mem_ctx ) ) ) ;
2012-03-30 19:33:53 -04:00
talloc_free ( mem_ctx ) ;
return ret2 ;
}
if ( ret ) {
break ;
}
} else {
* found_previous = true ;
}
/* Free the entry, we don't need it any more */
2012-03-31 01:27:02 -04:00
krb5_kt_free_entry ( context , & entry ) ;
2012-03-30 19:33:53 -04:00
}
2012-03-31 01:27:02 -04:00
krb5_kt_end_seq_get ( context , keytab , & cursor ) ;
2012-03-30 19:33:53 -04:00
switch ( ret ) {
case 0 :
break ;
case ENOENT :
case KRB5_KT_END :
ret = 0 ;
break ;
default :
* error_string = talloc_asprintf ( parent_ctx ,
" failed in deleting old entries for principal: %s \n " ,
2012-03-31 01:27:02 -04:00
smb_get_krb5_error_message ( context , ret , mem_ctx ) ) ;
2012-03-30 19:33:53 -04:00
}
talloc_free ( mem_ctx ) ;
return ret ;
}
krb5_error_code smb_krb5_update_keytab ( TALLOC_CTX * parent_ctx ,
2012-04-01 19:08:15 -04:00
krb5_context context ,
2012-03-31 01:27:02 -04:00
const char * keytab_name ,
const char * samAccountName ,
const char * realm ,
const char * * SPNs ,
int num_SPNs ,
const char * saltPrincipal ,
const char * new_secret ,
const char * old_secret ,
int kvno ,
uint32_t supp_enctypes ,
bool delete_all_kvno ,
2012-03-31 03:23:19 -04:00
krb5_keytab * _keytab ,
2012-03-31 01:27:02 -04:00
const char * * error_string )
2012-03-30 19:33:53 -04:00
{
2012-03-31 03:23:19 -04:00
krb5_keytab keytab ;
2012-03-30 19:33:53 -04:00
krb5_error_code ret ;
bool found_previous ;
2012-03-31 03:23:19 -04:00
TALLOC_CTX * tmp_ctx ;
2012-03-31 01:27:02 -04:00
krb5_principal * principals = NULL ;
2012-03-30 19:33:53 -04:00
2012-03-31 03:23:19 -04:00
if ( keytab_name = = NULL ) {
2012-03-30 19:33:53 -04:00
return ENOENT ;
}
2012-04-01 19:08:15 -04:00
ret = krb5_kt_resolve ( context , keytab_name , & keytab ) ;
2012-03-31 03:23:19 -04:00
if ( ret ) {
2012-04-01 19:08:15 -04:00
* error_string = smb_get_krb5_error_message ( context ,
ret , parent_ctx ) ;
2012-03-31 03:23:19 -04:00
return ret ;
2012-03-30 19:33:53 -04:00
}
DEBUG ( 5 , ( " Opened keytab %s \n " , keytab_name ) ) ;
2012-03-31 03:23:19 -04:00
tmp_ctx = talloc_new ( parent_ctx ) ;
if ( ! tmp_ctx ) {
return ENOMEM ;
}
2012-03-30 19:33:53 -04:00
/* Get the principal we will store the new keytab entries under */
2012-03-31 03:23:19 -04:00
ret = principals_from_list ( tmp_ctx ,
2012-03-31 01:27:02 -04:00
samAccountName , realm , SPNs , num_SPNs ,
2012-04-01 19:08:15 -04:00
context , & principals , error_string ) ;
2012-03-30 19:33:53 -04:00
if ( ret ! = 0 ) {
* error_string = talloc_asprintf ( parent_ctx ,
" Failed to load principals from ldb message: %s \n " ,
* error_string ) ;
2012-03-31 01:27:02 -04:00
goto done ;
2012-03-30 19:33:53 -04:00
}
2012-03-31 03:23:19 -04:00
ret = remove_old_entries ( tmp_ctx , kvno , principals , delete_all_kvno ,
2012-04-01 19:08:15 -04:00
context , keytab , & found_previous , error_string ) ;
2012-03-30 19:33:53 -04:00
if ( ret ! = 0 ) {
* error_string = talloc_asprintf ( parent_ctx ,
" Failed to remove old principals from keytab: %s \n " ,
* error_string ) ;
2012-03-31 01:27:02 -04:00
goto done ;
2012-03-30 19:33:53 -04:00
}
if ( ! delete_all_kvno ) {
/* Create a new keytab. If during the cleanout we found
* entires for kvno - 1 , then don ' t try and duplicate them .
* Otherwise , add kvno , and kvno - 1 */
2012-03-31 03:23:19 -04:00
ret = create_keytab ( tmp_ctx ,
2012-03-31 01:27:02 -04:00
samAccountName , realm , saltPrincipal ,
kvno , new_secret , old_secret ,
supp_enctypes , principals ,
2012-04-01 19:08:15 -04:00
context , keytab ,
2012-03-30 19:33:53 -04:00
found_previous ? false : true ,
error_string ) ;
2012-03-31 03:23:19 -04:00
if ( ret ) {
talloc_steal ( parent_ctx , * error_string ) ;
}
}
if ( ret = = 0 & & _keytab ! = NULL ) {
/* caller wants the keytab handle back */
* _keytab = keytab ;
2012-03-30 19:33:53 -04:00
}
2012-03-31 01:27:02 -04:00
done :
2012-04-01 19:08:15 -04:00
keytab_principals_free ( context , principals ) ;
2012-03-31 03:23:19 -04:00
if ( ret ! = 0 | | _keytab = = NULL ) {
2012-04-01 19:08:15 -04:00
krb5_kt_close ( context , keytab ) ;
2012-03-31 03:23:19 -04:00
}
talloc_free ( tmp_ctx ) ;
2012-03-30 19:33:53 -04:00
return ret ;
}
krb5_error_code smb_krb5_create_memory_keytab ( TALLOC_CTX * parent_ctx ,
2012-04-01 19:08:15 -04:00
krb5_context context ,
2012-03-31 05:19:59 -04:00
const char * new_secret ,
const char * samAccountName ,
const char * realm ,
int kvno ,
2012-03-31 03:23:19 -04:00
krb5_keytab * keytab ,
const char * * keytab_name )
2012-03-30 19:33:53 -04:00
{
krb5_error_code ret ;
TALLOC_CTX * mem_ctx = talloc_new ( parent_ctx ) ;
const char * rand_string ;
const char * error_string ;
if ( ! mem_ctx ) {
return ENOMEM ;
}
rand_string = generate_random_str ( mem_ctx , 16 ) ;
if ( ! rand_string ) {
talloc_free ( mem_ctx ) ;
return ENOMEM ;
}
2012-03-31 03:23:19 -04:00
* keytab_name = talloc_asprintf ( mem_ctx , " MEMORY:%s " , rand_string ) ;
if ( * keytab_name = = NULL ) {
2012-03-30 19:33:53 -04:00
talloc_free ( mem_ctx ) ;
return ENOMEM ;
}
2012-03-31 01:27:02 -04:00
2012-04-01 19:08:15 -04:00
ret = smb_krb5_update_keytab ( mem_ctx , context ,
2012-03-31 03:23:19 -04:00
* keytab_name , samAccountName , realm ,
2012-03-31 01:27:02 -04:00
NULL , 0 , NULL , new_secret , NULL ,
kvno , ENC_ALL_TYPES ,
2012-03-31 03:23:19 -04:00
false , keytab , & error_string ) ;
2012-03-30 19:33:53 -04:00
if ( ret = = 0 ) {
2012-03-31 03:23:19 -04:00
talloc_steal ( parent_ctx , * keytab_name ) ;
2012-03-30 19:33:53 -04:00
} else {
DEBUG ( 0 , ( " Failed to create in-memory keytab: %s \n " ,
error_string ) ) ;
2012-03-31 03:23:19 -04:00
* keytab_name = NULL ;
2012-03-30 19:33:53 -04:00
}
talloc_free ( mem_ctx ) ;
return ret ;
}