2014-05-07 18:52:42 +04:00
/*
Unix SMB / CIFS implementation .
Database Glue between Samba and the KDC
Copyright ( C ) Guenther Deschner < gd @ samba . org > 2014
Copyright ( C ) Andreas Schneider < asn @ samba . org > 2014
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 "sdb.h"
2022-03-22 19:04:22 +03:00
# include "samba_kdc.h"
2014-05-07 18:52:42 +04:00
# include "lib/krb5_wrap/krb5_samba.h"
2022-09-09 13:32:57 +03:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_KERBEROS
2022-02-11 23:04:44 +03:00
void sdb_key_free ( struct sdb_key * k )
2014-05-07 18:52:42 +04:00
{
if ( k = = NULL ) {
return ;
}
2022-02-11 22:56:17 +03:00
/*
* Passing NULL as the Kerberos context is intentional here , as
* both Heimdal and MIT libraries don ' t use the context when
* clearing the keyblocks .
*/
krb5_free_keyblock_contents ( NULL , & k - > key ) ;
2014-05-07 18:52:42 +04:00
if ( k - > salt ) {
2016-08-26 12:51:52 +03:00
smb_krb5_free_data_contents ( NULL , & k - > salt - > salt ) ;
2022-02-11 23:13:24 +03:00
SAFE_FREE ( k - > salt ) ;
2014-05-07 18:52:42 +04:00
}
ZERO_STRUCTP ( k ) ;
}
2022-02-11 23:04:44 +03:00
void sdb_keys_free ( struct sdb_keys * keys )
2014-05-07 18:52:42 +04:00
{
unsigned int i ;
2022-02-11 23:04:44 +03:00
if ( keys = = NULL ) {
return ;
}
for ( i = 0 ; i < keys - > len ; i + + ) {
sdb_key_free ( & keys - > val [ i ] ) ;
}
SAFE_FREE ( keys - > val ) ;
ZERO_STRUCTP ( keys ) ;
}
2022-03-22 19:59:19 +03:00
void sdb_entry_free ( struct sdb_entry * s )
2022-02-11 23:04:44 +03:00
{
2022-03-22 19:04:22 +03:00
if ( s - > skdc_entry ! = NULL ) {
s - > skdc_entry - > db_entry = NULL ;
TALLOC_FREE ( s - > skdc_entry ) ;
}
2014-05-07 18:52:42 +04:00
/*
* Passing NULL as the Kerberos context is intentional here , as both
* Heimdal and MIT libraries don ' t use the context when clearing the
* principals .
*/
krb5_free_principal ( NULL , s - > principal ) ;
2022-02-11 23:04:44 +03:00
sdb_keys_free ( & s - > keys ) ;
2022-03-23 02:41:13 +03:00
sdb_keys_free ( & s - > old_keys ) ;
sdb_keys_free ( & s - > older_keys ) ;
2014-05-07 18:52:42 +04:00
krb5_free_principal ( NULL , s - > created_by . principal ) ;
if ( s - > modified_by ) {
krb5_free_principal ( NULL , s - > modified_by - > principal ) ;
}
SAFE_FREE ( s - > valid_start ) ;
SAFE_FREE ( s - > valid_end ) ;
SAFE_FREE ( s - > pw_end ) ;
ZERO_STRUCTP ( s ) ;
}
struct SDBFlags int2SDBFlags ( unsigned n )
{
struct SDBFlags flags ;
memset ( & flags , 0 , sizeof ( flags ) ) ;
flags . initial = ( n > > 0 ) & 1 ;
flags . forwardable = ( n > > 1 ) & 1 ;
flags . proxiable = ( n > > 2 ) & 1 ;
flags . renewable = ( n > > 3 ) & 1 ;
flags . postdate = ( n > > 4 ) & 1 ;
flags . server = ( n > > 5 ) & 1 ;
flags . client = ( n > > 6 ) & 1 ;
flags . invalid = ( n > > 7 ) & 1 ;
flags . require_preauth = ( n > > 8 ) & 1 ;
flags . change_pw = ( n > > 9 ) & 1 ;
flags . require_hwauth = ( n > > 10 ) & 1 ;
flags . ok_as_delegate = ( n > > 11 ) & 1 ;
flags . user_to_user = ( n > > 12 ) & 1 ;
flags . immutable = ( n > > 13 ) & 1 ;
flags . trusted_for_delegation = ( n > > 14 ) & 1 ;
flags . allow_kerberos4 = ( n > > 15 ) & 1 ;
flags . allow_digest = ( n > > 16 ) & 1 ;
flags . locked_out = ( n > > 17 ) & 1 ;
flags . do_not_store = ( n > > 31 ) & 1 ;
return flags ;
}
2022-11-01 05:20:47 +03:00
/* Set the etypes of an sdb_entry based on its available current keys. */
krb5_error_code sdb_entry_set_etypes ( struct sdb_entry * s )
{
if ( s - > keys . val ! = NULL ) {
unsigned i ;
s - > etypes = malloc ( sizeof ( * s - > etypes ) ) ;
if ( s - > etypes = = NULL ) {
return ENOMEM ;
}
s - > etypes - > len = s - > keys . len ;
s - > etypes - > val = calloc ( s - > etypes - > len , sizeof ( * s - > etypes - > val ) ) ;
if ( s - > etypes - > val = = NULL ) {
return ENOMEM ;
}
for ( i = 0 ; i < s - > etypes - > len ; i + + ) {
const struct sdb_key * k = & s - > keys . val [ i ] ;
s - > etypes - > val [ i ] = KRB5_KEY_TYPE ( & ( k - > key ) ) ;
}
}
return 0 ;
}
/*
* Set the session etypes of a server sdb_entry based on its etypes , forcing in
* strong etypes as desired .
*/
krb5_error_code sdb_entry_set_session_etypes ( struct sdb_entry * s ,
2022-03-24 17:44:40 +03:00
bool add_aes256 ,
bool add_aes128 ,
bool add_rc4 )
2022-11-01 05:20:47 +03:00
{
2022-03-24 17:44:40 +03:00
unsigned len = 0 ;
if ( add_aes256 ) {
/* Reserve space for AES256 */
len + = 1 ;
}
if ( add_aes128 ) {
/* Reserve space for AES128 */
len + = 1 ;
}
if ( add_rc4 ) {
/* Reserve space for RC4. */
len + = 1 ;
}
if ( len ! = 0 ) {
2022-11-01 05:20:47 +03:00
unsigned j = 0 ;
s - > session_etypes = malloc ( sizeof ( * s - > session_etypes ) ) ;
if ( s - > session_etypes = = NULL ) {
return ENOMEM ;
}
/* session_etypes must be sorted in order of strength, with preferred etype first. */
s - > session_etypes - > val = calloc ( len , sizeof ( * s - > session_etypes - > val ) ) ;
if ( s - > session_etypes - > val = = NULL ) {
2022-03-24 17:44:40 +03:00
SAFE_FREE ( s - > session_etypes ) ;
2022-11-01 05:20:47 +03:00
return ENOMEM ;
}
2022-03-24 17:44:40 +03:00
if ( add_aes256 ) {
/* Add AES256 */
2022-11-01 05:20:47 +03:00
s - > session_etypes - > val [ j + + ] = ENCTYPE_AES256_CTS_HMAC_SHA1_96 ;
2022-03-24 17:44:40 +03:00
}
if ( add_aes128 ) {
/* Add AES128. */
2022-11-01 05:20:47 +03:00
s - > session_etypes - > val [ j + + ] = ENCTYPE_AES128_CTS_HMAC_SHA1_96 ;
}
2022-03-24 17:44:40 +03:00
if ( add_rc4 ) {
2022-11-01 05:20:47 +03:00
/* Add RC4. */
s - > session_etypes - > val [ j + + ] = ENCTYPE_ARCFOUR_HMAC ;
}
s - > session_etypes - > len = j ;
}
return 0 ;
}