2014-05-08 19:09:08 +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 <hdb.h>
# include "sdb.h"
# include "sdb_hdb.h"
# include "lib/krb5_wrap/krb5_samba.h"
2022-11-01 05:20:47 +03:00
# include "librpc/gen_ndr/security.h"
2014-05-08 19:09:08 +04:00
# include "kdc/samba_kdc.h"
2022-09-09 13:32:57 +03:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_KERBEROS
2014-05-08 19:09:08 +04:00
static void sdb_flags_to_hdb_flags ( const struct SDBFlags * s ,
HDBFlags * h )
{
2015-08-03 14:10:28 +03:00
SMB_ASSERT ( sizeof ( struct SDBFlags ) = = sizeof ( HDBFlags ) ) ;
h - > initial = s - > initial ;
h - > forwardable = s - > forwardable ;
h - > proxiable = s - > proxiable ;
h - > renewable = s - > renewable ;
h - > postdate = s - > postdate ;
h - > server = s - > server ;
h - > client = s - > client ;
h - > invalid = s - > invalid ;
h - > require_preauth = s - > require_preauth ;
h - > change_pw = s - > change_pw ;
h - > require_hwauth = s - > require_hwauth ;
h - > ok_as_delegate = s - > ok_as_delegate ;
h - > user_to_user = s - > user_to_user ;
h - > immutable = s - > immutable ;
h - > trusted_for_delegation = s - > trusted_for_delegation ;
h - > allow_kerberos4 = s - > allow_kerberos4 ;
h - > allow_digest = s - > allow_digest ;
h - > locked_out = s - > locked_out ;
2016-01-08 04:08:18 +03:00
h - > require_pwchange = s - > require_pwchange ;
h - > materialize = s - > materialize ;
h - > virtual_keys = s - > virtual_keys ;
h - > virtual = s - > virtual ;
h - > synthetic = s - > synthetic ;
h - > no_auth_data_reqd = s - > no_auth_data_reqd ;
2023-06-26 04:07:44 +03:00
h - > auth_data_reqd = s - > auth_data_reqd ;
2015-08-03 14:10:28 +03:00
h - > _unused25 = s - > _unused25 ;
h - > _unused26 = s - > _unused26 ;
h - > _unused27 = s - > _unused27 ;
h - > _unused28 = s - > _unused28 ;
h - > _unused29 = s - > _unused29 ;
2021-06-23 02:35:01 +03:00
h - > force_canonicalize = s - > force_canonicalize ;
2015-08-03 14:10:28 +03:00
h - > do_not_store = s - > do_not_store ;
2014-05-08 19:09:08 +04:00
}
static int sdb_salt_to_Salt ( const struct sdb_salt * s , Salt * h )
{
int ret ;
2023-09-27 03:58:31 +03:00
* h = ( struct Salt ) { } ;
2023-08-10 07:35:52 +03:00
2014-05-08 19:09:08 +04:00
h - > type = s - > type ;
2016-08-26 12:57:30 +03:00
ret = smb_krb5_copy_data_contents ( & h - > salt , s - > salt . data , s - > salt . length ) ;
2014-05-08 19:09:08 +04:00
if ( ret ! = 0 ) {
free_Salt ( h ) ;
return ENOMEM ;
}
return 0 ;
}
static int sdb_key_to_Key ( const struct sdb_key * s , Key * h )
{
int rc ;
2023-09-27 03:58:31 +03:00
* h = ( struct Key ) { } ;
2014-05-08 19:09:08 +04:00
h - > key . keytype = s - > key . keytype ;
2016-08-26 12:57:30 +03:00
rc = smb_krb5_copy_data_contents ( & h - > key . keyvalue ,
s - > key . keyvalue . data ,
s - > key . keyvalue . length ) ;
2014-05-08 19:09:08 +04:00
if ( rc ! = 0 ) {
goto error_nomem ;
}
if ( s - > salt ! = NULL ) {
h - > salt = malloc ( sizeof ( Salt ) ) ;
if ( h - > salt = = NULL ) {
goto error_nomem ;
}
rc = sdb_salt_to_Salt ( s - > salt ,
h - > salt ) ;
if ( rc ! = 0 ) {
goto error_nomem ;
}
}
return 0 ;
error_nomem :
free_Key ( h ) ;
return ENOMEM ;
}
static int sdb_keys_to_Keys ( const struct sdb_keys * s , Keys * h )
{
int ret , i ;
2023-09-27 03:58:31 +03:00
* h = ( struct Keys ) { } ;
2023-08-10 07:35:52 +03:00
2014-05-08 19:09:08 +04:00
if ( s - > val ! = NULL ) {
2023-08-10 07:52:13 +03:00
h - > val = malloc ( s - > len * sizeof ( Key ) ) ;
2014-05-08 19:09:08 +04:00
if ( h - > val = = NULL ) {
return ENOMEM ;
}
2023-08-10 07:52:13 +03:00
for ( i = 0 ; i < s - > len ; i + + ) {
2014-05-08 19:09:08 +04:00
ret = sdb_key_to_Key ( & s - > val [ i ] ,
& h - > val [ i ] ) ;
if ( ret ! = 0 ) {
free_Keys ( h ) ;
return ENOMEM ;
}
2023-08-10 07:52:13 +03:00
+ + h - > len ;
2014-05-08 19:09:08 +04:00
}
}
return 0 ;
}
2022-02-07 21:32:08 +03:00
static int sdb_keys_to_HistKeys ( krb5_context context ,
const struct sdb_keys * s ,
krb5_kvno kvno ,
hdb_entry * h )
{
unsigned int i ;
for ( i = 0 ; i < s - > len ; i + + ) {
Key k = { 0 , } ;
int ret ;
ret = sdb_key_to_Key ( & s - > val [ i ] , & k ) ;
if ( ret ! = 0 ) {
return ENOMEM ;
}
ret = hdb_add_history_key ( context , h , kvno , & k ) ;
free_Key ( & k ) ;
if ( ret ! = 0 ) {
return ENOMEM ;
}
}
return 0 ;
}
2014-05-08 19:09:08 +04:00
static int sdb_event_to_Event ( krb5_context context ,
const struct sdb_event * s , Event * h )
{
int ret ;
2023-09-27 03:58:31 +03:00
* h = ( struct Event ) { } ;
2023-08-10 07:35:52 +03:00
2014-05-08 19:09:08 +04:00
if ( s - > principal ! = NULL ) {
ret = krb5_copy_principal ( context ,
s - > principal ,
& h - > principal ) ;
if ( ret ! = 0 ) {
free_Event ( h ) ;
return ret ;
}
}
h - > time = s - > time ;
return 0 ;
}
2022-03-22 19:55:54 +03:00
int sdb_entry_to_hdb_entry ( krb5_context context ,
const struct sdb_entry * s ,
hdb_entry * h )
2014-05-08 19:09:08 +04:00
{
2022-03-22 18:35:58 +03:00
struct samba_kdc_entry * ske = s - > skdc_entry ;
2014-05-08 19:09:08 +04:00
unsigned int i ;
int rc ;
2023-09-27 03:58:31 +03:00
* h = ( hdb_entry ) { } ;
2022-02-17 12:59:45 +03:00
2023-09-27 03:59:32 +03:00
if ( s - > principal ! = NULL ) {
rc = krb5_copy_principal ( context ,
s - > principal ,
& h - > principal ) ;
if ( rc ! = 0 ) {
return rc ;
}
2014-05-08 19:09:08 +04:00
}
h - > kvno = s - > kvno ;
rc = sdb_keys_to_Keys ( & s - > keys , & h - > keys ) ;
if ( rc ! = 0 ) {
goto error ;
}
2022-02-07 21:32:08 +03:00
if ( h - > kvno > 1 ) {
rc = sdb_keys_to_HistKeys ( context ,
& s - > old_keys ,
h - > kvno - 1 ,
h ) ;
if ( rc ! = 0 ) {
goto error ;
}
}
if ( h - > kvno > 2 ) {
rc = sdb_keys_to_HistKeys ( context ,
& s - > older_keys ,
h - > kvno - 2 ,
h ) ;
if ( rc ! = 0 ) {
goto error ;
}
}
2014-05-08 19:09:08 +04:00
rc = sdb_event_to_Event ( context ,
& s - > created_by ,
& h - > created_by ) ;
if ( rc ! = 0 ) {
goto error ;
}
if ( s - > modified_by ) {
h - > modified_by = malloc ( sizeof ( Event ) ) ;
if ( h - > modified_by = = NULL ) {
rc = ENOMEM ;
goto error ;
}
rc = sdb_event_to_Event ( context ,
s - > modified_by ,
h - > modified_by ) ;
if ( rc ! = 0 ) {
goto error ;
}
}
if ( s - > valid_start ! = NULL ) {
h - > valid_start = malloc ( sizeof ( KerberosTime ) ) ;
if ( h - > valid_start = = NULL ) {
rc = ENOMEM ;
goto error ;
}
* h - > valid_start = * s - > valid_start ;
}
if ( s - > valid_end ! = NULL ) {
h - > valid_end = malloc ( sizeof ( KerberosTime ) ) ;
if ( h - > valid_end = = NULL ) {
rc = ENOMEM ;
goto error ;
}
* h - > valid_end = * s - > valid_end ;
}
if ( s - > pw_end ! = NULL ) {
h - > pw_end = malloc ( sizeof ( KerberosTime ) ) ;
if ( h - > pw_end = = NULL ) {
rc = ENOMEM ;
goto error ;
}
* h - > pw_end = * s - > pw_end ;
}
if ( s - > max_life ! = NULL ) {
2023-04-28 02:58:38 +03:00
h - > max_life = malloc ( sizeof ( * h - > max_life ) ) ;
2014-05-08 19:09:08 +04:00
if ( h - > max_life = = NULL ) {
rc = ENOMEM ;
goto error ;
}
* h - > max_life = * s - > max_life ;
}
if ( s - > max_renew ! = NULL ) {
2023-04-28 02:58:38 +03:00
h - > max_renew = malloc ( sizeof ( * h - > max_renew ) ) ;
2014-05-08 19:09:08 +04:00
if ( h - > max_renew = = NULL ) {
rc = ENOMEM ;
goto error ;
}
* h - > max_renew = * s - > max_renew ;
}
sdb_flags_to_hdb_flags ( & s - > flags , & h - > flags ) ;
2022-11-01 05:20:47 +03:00
if ( s - > etypes ! = NULL ) {
2014-05-08 19:09:08 +04:00
h - > etypes = malloc ( sizeof ( * h - > etypes ) ) ;
if ( h - > etypes = = NULL ) {
rc = ENOMEM ;
goto error ;
}
2016-09-25 21:32:49 +03:00
2022-11-01 05:20:47 +03:00
h - > etypes - > len = s - > etypes - > len ;
2016-09-25 21:32:49 +03:00
2014-05-08 19:09:08 +04:00
h - > etypes - > val = calloc ( h - > etypes - > len , sizeof ( int ) ) ;
if ( h - > etypes - > val = = NULL ) {
rc = ENOMEM ;
goto error ;
}
2016-09-25 21:32:49 +03:00
2014-05-08 19:09:08 +04:00
for ( i = 0 ; i < h - > etypes - > len ; i + + ) {
2022-11-01 05:20:47 +03:00
h - > etypes - > val [ i ] = s - > etypes - > val [ i ] ;
}
}
if ( s - > session_etypes ! = NULL ) {
h - > session_etypes = malloc ( sizeof ( * h - > session_etypes ) ) ;
if ( h - > session_etypes = = NULL ) {
rc = ENOMEM ;
goto error ;
}
h - > session_etypes - > len = s - > session_etypes - > len ;
h - > session_etypes - > val = calloc ( h - > session_etypes - > len , sizeof ( * h - > session_etypes - > val ) ) ;
if ( h - > session_etypes - > val = = NULL ) {
rc = ENOMEM ;
goto error ;
}
2016-09-25 21:32:49 +03:00
2022-11-01 05:20:47 +03:00
for ( i = 0 ; i < h - > session_etypes - > len ; + + i ) {
h - > session_etypes - > val [ i ] = s - > session_etypes - > val [ i ] ;
2014-05-08 19:09:08 +04:00
}
}
2016-09-25 21:32:49 +03:00
2022-03-22 18:35:58 +03:00
h - > context = ske ;
2022-03-22 19:04:22 +03:00
if ( ske ! = NULL ) {
ske - > kdc_entry = h ;
}
2014-05-08 19:09:08 +04:00
return 0 ;
error :
free_hdb_entry ( h ) ;
return rc ;
}