2014-10-11 03:36:54 +04:00
/*
Unix SMB / CIFS implementation .
Map lease keys to file ids
Copyright ( C ) Volker Lendecke 2013
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/filesys.h"
# include "locking/leases_db.h"
# include "dbwrap/dbwrap.h"
# include "dbwrap/dbwrap_open.h"
# include "util_tdb.h"
# include "ndr.h"
# include "librpc/gen_ndr/ndr_leases_db.h"
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_LOCKING
/* the leases database handle */
static struct db_context * leases_db ;
bool leases_db_init ( bool read_only )
{
2015-01-12 18:49:54 +03:00
char * db_path ;
2014-10-11 03:36:54 +04:00
if ( leases_db ) {
return true ;
}
2018-08-16 11:51:44 +03:00
db_path = lock_path ( talloc_tos ( ) , " leases.tdb " ) ;
2015-01-12 18:49:54 +03:00
if ( db_path = = NULL ) {
return false ;
}
2019-06-17 17:36:01 +03:00
leases_db = db_open ( NULL , db_path ,
SMBD_VOLATILE_TDB_HASH_SIZE ,
SMBD_VOLATILE_TDB_FLAGS |
TDB_SEQNUM ,
2014-10-11 03:36:54 +04:00
read_only ? O_RDONLY : O_RDWR | O_CREAT , 0644 ,
2019-09-15 12:58:43 +03:00
DBWRAP_LOCK_ORDER_4 , DBWRAP_FLAG_NONE ) ;
2015-01-12 18:49:54 +03:00
TALLOC_FREE ( db_path ) ;
2014-10-11 03:36:54 +04:00
if ( leases_db = = NULL ) {
DEBUG ( 1 , ( " ERROR: Failed to initialise leases database \n " ) ) ;
return false ;
}
return true ;
}
2018-09-13 22:05:05 +03:00
struct leases_db_key_buf {
uint8_t buf [ 32 ] ;
} ;
static TDB_DATA leases_db_key ( struct leases_db_key_buf * buf ,
const struct GUID * client_guid ,
const struct smb2_lease_key * lease_key )
2014-10-11 03:36:54 +04:00
{
struct leases_db_key db_key = {
. client_guid = * client_guid ,
. lease_key = * lease_key } ;
2018-09-13 22:05:05 +03:00
DATA_BLOB blob = { . data = buf - > buf , . length = sizeof ( buf - > buf ) } ;
2014-10-11 03:36:54 +04:00
enum ndr_err_code ndr_err ;
if ( DEBUGLEVEL > = 10 ) {
2018-09-13 22:05:05 +03:00
DBG_DEBUG ( " \n " ) ;
2014-10-11 03:36:54 +04:00
NDR_PRINT_DEBUG ( leases_db_key , & db_key ) ;
}
2018-09-13 22:05:05 +03:00
ndr_err = ndr_push_struct_into_fixed_blob (
& blob , & db_key , ( ndr_push_flags_fn_t ) ndr_push_leases_db_key ) ;
SMB_ASSERT ( NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) ;
2014-10-11 03:36:54 +04:00
2018-09-13 22:05:05 +03:00
return ( TDB_DATA ) { . dptr = buf - > buf , . dsize = sizeof ( buf - > buf ) } ;
2014-10-11 03:36:54 +04:00
}
2019-04-08 16:18:31 +03:00
struct leases_db_do_locked_state {
void ( * fn ) ( struct leases_db_value * value ,
bool * modified ,
void * private_data ) ;
void * private_data ;
NTSTATUS status ;
} ;
2019-10-23 12:34:47 +03:00
static void leases_db_do_locked_fn (
struct db_record * rec ,
TDB_DATA db_value ,
void * private_data )
2019-04-08 16:18:31 +03:00
{
struct leases_db_do_locked_state * state = private_data ;
DATA_BLOB blob = { . data = db_value . dptr , . length = db_value . dsize } ;
struct leases_db_value * value = NULL ;
enum ndr_err_code ndr_err ;
bool modified = false ;
value = talloc_zero ( talloc_tos ( ) , struct leases_db_value ) ;
if ( value = = NULL ) {
state - > status = NT_STATUS_NO_MEMORY ;
goto done ;
}
if ( blob . length ! = 0 ) {
ndr_err = ndr_pull_struct_blob_all (
& blob ,
value ,
value ,
( ndr_pull_flags_fn_t ) ndr_pull_leases_db_value ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2020-07-06 15:03:39 +03:00
DBG_ERR ( " ndr_pull_struct_blob_failed: %s \n " ,
2019-04-08 16:18:31 +03:00
ndr_errstr ( ndr_err ) ) ;
state - > status = ndr_map_error2ntstatus ( ndr_err ) ;
goto done ;
}
}
state - > fn ( value , & modified , state - > private_data ) ;
if ( ! modified ) {
goto done ;
}
if ( value - > num_files = = 0 ) {
state - > status = dbwrap_record_delete ( rec ) ;
if ( ! NT_STATUS_IS_OK ( state - > status ) ) {
2020-07-06 15:03:39 +03:00
DBG_ERR ( " dbwrap_record_delete returned %s \n " ,
2019-04-08 16:18:31 +03:00
nt_errstr ( state - > status ) ) ;
}
goto done ;
}
ndr_err = ndr_push_struct_blob (
& blob ,
value ,
value ,
( ndr_push_flags_fn_t ) ndr_push_leases_db_value ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2020-07-06 15:03:39 +03:00
DBG_ERR ( " ndr_push_struct_blob_failed: %s \n " ,
2019-04-08 16:18:31 +03:00
ndr_errstr ( ndr_err ) ) ;
state - > status = ndr_map_error2ntstatus ( ndr_err ) ;
goto done ;
}
if ( DEBUGLEVEL > = 10 ) {
DBG_DEBUG ( " \n " ) ;
NDR_PRINT_DEBUG ( leases_db_value , value ) ;
}
db_value = make_tdb_data ( blob . data , blob . length ) ;
state - > status = dbwrap_record_store ( rec , db_value , 0 ) ;
if ( ! NT_STATUS_IS_OK ( state - > status ) ) {
2020-07-06 15:03:39 +03:00
DBG_ERR ( " dbwrap_record_store returned %s \n " ,
2019-04-08 16:18:31 +03:00
nt_errstr ( state - > status ) ) ;
}
done :
TALLOC_FREE ( value ) ;
}
static NTSTATUS leases_db_do_locked (
const struct GUID * client_guid ,
const struct smb2_lease_key * lease_key ,
void ( * fn ) ( struct leases_db_value * value ,
bool * modified ,
void * private_data ) ,
void * private_data )
{
struct leases_db_key_buf keybuf ;
TDB_DATA db_key = leases_db_key ( & keybuf , client_guid , lease_key ) ;
struct leases_db_do_locked_state state = {
. fn = fn , . private_data = private_data ,
} ;
NTSTATUS status ;
if ( ! leases_db_init ( false ) ) {
return NT_STATUS_INTERNAL_ERROR ;
}
status = dbwrap_do_locked (
leases_db , db_key , leases_db_do_locked_fn , & state ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return state . status ;
}
2019-04-08 16:33:30 +03:00
struct leases_db_add_state {
const struct file_id * id ;
2018-09-11 17:13:24 +03:00
uint32_t current_state ;
uint16_t lease_version ;
uint16_t epoch ;
2019-04-08 16:33:30 +03:00
const char * servicepath ;
const char * base_name ;
const char * stream_name ;
2014-10-11 03:36:54 +04:00
NTSTATUS status ;
2019-04-08 16:33:30 +03:00
} ;
2014-10-11 03:36:54 +04:00
2019-04-08 16:33:30 +03:00
static void leases_db_add_fn (
struct leases_db_value * value , bool * modified , void * private_data )
{
struct leases_db_add_state * state = private_data ;
struct leases_db_file * tmp = NULL ;
uint32_t i ;
2014-10-11 03:36:54 +04:00
2019-04-08 16:33:30 +03:00
/* id must be unique. */
for ( i = 0 ; i < value - > num_files ; i + + ) {
if ( file_id_equal ( state - > id , & value - > files [ i ] . id ) ) {
state - > status = NT_STATUS_OBJECT_NAME_COLLISION ;
return ;
2014-10-11 03:36:54 +04:00
}
}
2018-09-11 17:13:24 +03:00
if ( value - > num_files = = 0 ) {
/* new record */
value - > current_state = state - > current_state ;
value - > lease_version = state - > lease_version ;
value - > epoch = state - > epoch ;
}
2019-04-08 16:33:30 +03:00
tmp = talloc_realloc (
value ,
value - > files ,
struct leases_db_file ,
value - > num_files + 1 ) ;
if ( tmp = = NULL ) {
state - > status = NT_STATUS_NO_MEMORY ;
return ;
2014-10-11 03:36:54 +04:00
}
2019-04-08 16:33:30 +03:00
value - > files = tmp ;
2014-10-11 03:36:54 +04:00
2019-04-08 16:33:30 +03:00
value - > files [ value - > num_files ] = ( struct leases_db_file ) {
. id = * state - > id ,
. servicepath = state - > servicepath ,
. base_name = state - > base_name ,
. stream_name = state - > stream_name ,
} ;
value - > num_files + = 1 ;
2014-10-11 03:36:54 +04:00
2019-04-08 16:33:30 +03:00
* modified = true ;
}
2014-10-11 03:36:54 +04:00
2019-04-08 16:33:30 +03:00
NTSTATUS leases_db_add ( const struct GUID * client_guid ,
const struct smb2_lease_key * lease_key ,
const struct file_id * id ,
2018-09-11 17:13:24 +03:00
uint32_t current_state ,
uint16_t lease_version ,
uint16_t epoch ,
2019-04-08 16:33:30 +03:00
const char * servicepath ,
const char * base_name ,
const char * stream_name )
{
struct leases_db_add_state state = {
. id = id ,
2018-09-11 17:13:24 +03:00
. current_state = current_state ,
. lease_version = lease_version ,
. epoch = epoch ,
2019-04-08 16:33:30 +03:00
. servicepath = servicepath ,
. base_name = base_name ,
. stream_name = stream_name ,
} ;
NTSTATUS status ;
2014-10-11 03:36:54 +04:00
2019-04-08 16:33:30 +03:00
status = leases_db_do_locked (
client_guid , lease_key , leases_db_add_fn , & state ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_DEBUG ( " leases_db_do_locked failed: %s \n " ,
nt_errstr ( status ) ) ;
return status ;
2014-10-11 03:36:54 +04:00
}
2019-04-08 16:33:30 +03:00
return state . status ;
2014-10-11 03:36:54 +04:00
}
2019-04-08 16:38:01 +03:00
struct leases_db_del_state {
const struct file_id * id ;
2014-10-11 03:36:54 +04:00
NTSTATUS status ;
2019-04-08 16:38:01 +03:00
} ;
2014-10-11 03:36:54 +04:00
2019-04-08 16:38:01 +03:00
static void leases_db_del_fn (
struct leases_db_value * value , bool * modified , void * private_data )
{
struct leases_db_del_state * state = private_data ;
uint32_t i ;
2014-10-11 03:36:54 +04:00
2014-12-05 23:47:52 +03:00
for ( i = 0 ; i < value - > num_files ; i + + ) {
2019-04-08 16:38:01 +03:00
if ( file_id_equal ( state - > id , & value - > files [ i ] . id ) ) {
2014-10-11 03:36:54 +04:00
break ;
}
}
2014-12-05 23:47:52 +03:00
if ( i = = value - > num_files ) {
2019-04-08 16:38:01 +03:00
state - > status = NT_STATUS_NOT_FOUND ;
return ;
2014-10-11 03:36:54 +04:00
}
2014-12-05 23:47:52 +03:00
value - > files [ i ] = value - > files [ value - > num_files - 1 ] ;
value - > num_files - = 1 ;
2014-10-11 03:36:54 +04:00
2019-04-08 16:38:01 +03:00
* modified = true ;
}
2014-10-11 03:36:54 +04:00
2019-04-08 16:38:01 +03:00
NTSTATUS leases_db_del ( const struct GUID * client_guid ,
const struct smb2_lease_key * lease_key ,
const struct file_id * id )
{
struct leases_db_del_state state = { . id = id } ;
NTSTATUS status ;
2014-10-11 03:36:54 +04:00
2019-04-08 16:38:01 +03:00
status = leases_db_do_locked (
client_guid , lease_key , leases_db_del_fn , & state ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_DEBUG ( " leases_db_do_locked failed: %s \n " ,
nt_errstr ( status ) ) ;
return status ;
2014-10-11 03:36:54 +04:00
}
2019-04-08 16:38:01 +03:00
return state . status ;
2014-10-11 03:36:54 +04:00
}
struct leases_db_fetch_state {
2014-12-05 23:47:52 +03:00
void ( * parser ) ( uint32_t num_files ,
const struct leases_db_file * files ,
void * private_data ) ;
2014-10-11 03:36:54 +04:00
void * private_data ;
NTSTATUS status ;
} ;
static void leases_db_parser ( TDB_DATA key , TDB_DATA data , void * private_data )
{
struct leases_db_fetch_state * state =
( struct leases_db_fetch_state * ) private_data ;
DATA_BLOB blob = { . data = data . dptr , . length = data . dsize } ;
enum ndr_err_code ndr_err ;
struct leases_db_value * value ;
value = talloc ( talloc_tos ( ) , struct leases_db_value ) ;
if ( value = = NULL ) {
state - > status = NT_STATUS_NO_MEMORY ;
return ;
}
ndr_err = ndr_pull_struct_blob_all (
& blob , value , value ,
( ndr_pull_flags_fn_t ) ndr_pull_leases_db_value ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 10 , ( " %s: ndr_pull_struct_blob_failed: %s \n " ,
__func__ , ndr_errstr ( ndr_err ) ) ) ;
TALLOC_FREE ( value ) ;
state - > status = ndr_map_error2ntstatus ( ndr_err ) ;
return ;
}
if ( DEBUGLEVEL > = 10 ) {
DEBUG ( 10 , ( " %s: \n " , __func__ ) ) ;
NDR_PRINT_DEBUG ( leases_db_value , value ) ;
}
2014-12-05 23:47:52 +03:00
state - > parser ( value - > num_files ,
value - > files ,
2014-10-11 03:36:54 +04:00
state - > private_data ) ;
TALLOC_FREE ( value ) ;
state - > status = NT_STATUS_OK ;
}
NTSTATUS leases_db_parse ( const struct GUID * client_guid ,
const struct smb2_lease_key * lease_key ,
2014-12-05 23:47:52 +03:00
void ( * parser ) ( uint32_t num_files ,
const struct leases_db_file * files ,
2014-10-11 03:36:54 +04:00
void * private_data ) ,
void * private_data )
{
2018-09-13 22:05:05 +03:00
struct leases_db_key_buf keybuf ;
TDB_DATA db_key = leases_db_key ( & keybuf , client_guid , lease_key ) ;
2014-10-11 03:36:54 +04:00
struct leases_db_fetch_state state ;
NTSTATUS status ;
if ( ! leases_db_init ( true ) ) {
return NT_STATUS_INTERNAL_ERROR ;
}
state = ( struct leases_db_fetch_state ) {
. parser = parser ,
. private_data = private_data ,
. status = NT_STATUS_OK
} ;
status = dbwrap_parse_record ( leases_db , db_key , leases_db_parser ,
& state ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return state . status ;
}
2014-12-04 21:13:47 +03:00
2019-04-08 16:18:31 +03:00
struct leases_db_rename_state {
const struct file_id * id ;
const char * servicename_new ;
const char * filename_new ;
const char * stream_name_new ;
NTSTATUS status ;
} ;
static void leases_db_rename_fn (
struct leases_db_value * value , bool * modified , void * private_data )
{
struct leases_db_rename_state * state = private_data ;
struct leases_db_file * file = NULL ;
uint32_t i ;
/* id must exist. */
for ( i = 0 ; i < value - > num_files ; i + + ) {
if ( file_id_equal ( state - > id , & value - > files [ i ] . id ) ) {
break ;
}
}
if ( i = = value - > num_files ) {
state - > status = NT_STATUS_NOT_FOUND ;
return ;
}
file = & value - > files [ i ] ;
file - > servicepath = state - > servicename_new ;
file - > base_name = state - > filename_new ;
file - > stream_name = state - > stream_name_new ;
* modified = true ;
}
2014-12-04 21:13:47 +03:00
NTSTATUS leases_db_rename ( const struct GUID * client_guid ,
const struct smb2_lease_key * lease_key ,
const struct file_id * id ,
2014-12-05 23:56:03 +03:00
const char * servicename_new ,
2014-12-04 21:13:47 +03:00
const char * filename_new ,
const char * stream_name_new )
{
2019-04-08 16:18:31 +03:00
struct leases_db_rename_state state = {
. id = id ,
. servicename_new = servicename_new ,
. filename_new = filename_new ,
. stream_name_new = stream_name_new ,
} ;
2014-12-04 21:13:47 +03:00
NTSTATUS status ;
2019-04-08 16:18:31 +03:00
status = leases_db_do_locked (
client_guid , lease_key , leases_db_rename_fn , & state ) ;
2014-12-04 21:13:47 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2019-04-08 16:18:31 +03:00
DBG_DEBUG ( " leases_db_do_locked failed: %s \n " ,
nt_errstr ( status ) ) ;
2014-12-04 21:13:47 +03:00
return status ;
}
2019-04-08 16:18:31 +03:00
return state . status ;
2014-12-04 21:13:47 +03:00
}
2014-12-05 23:57:24 +03:00
2018-09-11 17:23:38 +03:00
struct leases_db_set_state {
uint32_t current_state ;
bool breaking ;
uint32_t breaking_to_requested ;
uint32_t breaking_to_required ;
uint16_t lease_version ;
uint16_t epoch ;
} ;
static void leases_db_set_fn (
struct leases_db_value * value , bool * modified , void * private_data )
{
struct leases_db_set_state * state = private_data ;
if ( value - > num_files = = 0 ) {
DBG_WARNING ( " leases_db_set on new entry \n " ) ;
return ;
}
value - > current_state = state - > current_state ;
value - > breaking = state - > breaking ;
value - > breaking_to_requested = state - > breaking_to_requested ;
value - > breaking_to_required = state - > breaking_to_required ;
value - > lease_version = state - > lease_version ;
value - > epoch = state - > epoch ;
* modified = true ;
}
NTSTATUS leases_db_set ( const struct GUID * client_guid ,
const struct smb2_lease_key * lease_key ,
uint32_t current_state ,
bool breaking ,
uint32_t breaking_to_requested ,
uint32_t breaking_to_required ,
uint16_t lease_version ,
uint16_t epoch )
{
struct leases_db_set_state state = {
. current_state = current_state ,
. breaking = breaking ,
. breaking_to_requested = breaking_to_requested ,
. breaking_to_required = breaking_to_required ,
. lease_version = lease_version ,
. epoch = epoch ,
} ;
NTSTATUS status ;
status = leases_db_do_locked (
client_guid , lease_key , leases_db_set_fn , & state ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_DEBUG ( " leases_db_do_locked failed: %s \n " ,
nt_errstr ( status ) ) ;
return status ;
}
return NT_STATUS_OK ;
}
struct leases_db_get_state {
const struct file_id * file_id ;
uint32_t * current_state ;
bool * breaking ;
uint32_t * breaking_to_requested ;
uint32_t * breaking_to_required ;
uint16_t * lease_version ;
uint16_t * epoch ;
NTSTATUS status ;
} ;
static void leases_db_get_fn ( TDB_DATA key , TDB_DATA data , void * private_data )
{
struct leases_db_get_state * state = private_data ;
DATA_BLOB blob = { . data = data . dptr , . length = data . dsize } ;
enum ndr_err_code ndr_err ;
struct leases_db_value * value ;
uint32_t i ;
value = talloc ( talloc_tos ( ) , struct leases_db_value ) ;
if ( value = = NULL ) {
state - > status = NT_STATUS_NO_MEMORY ;
return ;
}
ndr_err = ndr_pull_struct_blob_all (
& blob , value , value ,
( ndr_pull_flags_fn_t ) ndr_pull_leases_db_value ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2020-07-02 15:10:05 +03:00
DBG_ERR ( " ndr_pull_struct_blob_failed: %s \n " ,
ndr_errstr ( ndr_err ) ) ;
2018-09-11 17:23:38 +03:00
TALLOC_FREE ( value ) ;
state - > status = ndr_map_error2ntstatus ( ndr_err ) ;
return ;
}
if ( DEBUGLEVEL > = 10 ) {
DBG_DEBUG ( " \n " ) ;
NDR_PRINT_DEBUG ( leases_db_value , value ) ;
}
/* id must exist. */
for ( i = 0 ; i < value - > num_files ; i + + ) {
if ( file_id_equal ( state - > file_id , & value - > files [ i ] . id ) ) {
break ;
}
}
if ( i = = value - > num_files ) {
state - > status = NT_STATUS_NOT_FOUND ;
TALLOC_FREE ( value ) ;
return ;
}
if ( state - > current_state ! = NULL ) {
* state - > current_state = value - > current_state ;
} ;
if ( state - > breaking ! = NULL ) {
* state - > breaking = value - > breaking ;
} ;
if ( state - > breaking_to_requested ! = NULL ) {
* state - > breaking_to_requested = value - > breaking_to_requested ;
} ;
if ( state - > breaking_to_required ! = NULL ) {
* state - > breaking_to_required = value - > breaking_to_required ;
} ;
if ( state - > lease_version ! = NULL ) {
* state - > lease_version = value - > lease_version ;
} ;
if ( state - > epoch ! = NULL ) {
* state - > epoch = value - > epoch ;
} ;
TALLOC_FREE ( value ) ;
state - > status = NT_STATUS_OK ;
}
NTSTATUS leases_db_get ( const struct GUID * client_guid ,
const struct smb2_lease_key * lease_key ,
const struct file_id * file_id ,
uint32_t * current_state ,
bool * breaking ,
uint32_t * breaking_to_requested ,
uint32_t * breaking_to_required ,
uint16_t * lease_version ,
uint16_t * epoch )
{
struct leases_db_get_state state = {
. file_id = file_id ,
. current_state = current_state ,
. breaking = breaking ,
. breaking_to_requested = breaking_to_requested ,
. breaking_to_required = breaking_to_required ,
. lease_version = lease_version ,
. epoch = epoch ,
} ;
struct leases_db_key_buf keybuf ;
TDB_DATA db_key = leases_db_key ( & keybuf , client_guid , lease_key ) ;
NTSTATUS status ;
if ( ! leases_db_init ( true ) ) {
return NT_STATUS_INTERNAL_ERROR ;
}
status = dbwrap_parse_record (
leases_db , db_key , leases_db_get_fn , & state ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return state . status ;
2019-08-13 23:07:47 +03:00
}
struct leases_db_get_current_state_state {
int seqnum ;
uint32_t current_state ;
NTSTATUS status ;
} ;
/*
* This function is an optimization that
* relies on the fact that the
* smb2_lease_state current_state
* ( which is a uint32_t size )
* from struct leases_db_value is the first
* entry in the ndr - encoded struct leases_db_value .
* Read it without having to ndr decode all
* the values in struct leases_db_value .
*/
static void leases_db_get_current_state_fn (
TDB_DATA key , TDB_DATA data , void * private_data )
{
struct leases_db_get_current_state_state * state = private_data ;
struct ndr_pull ndr ;
enum ndr_err_code ndr_err ;
if ( data . dsize < sizeof ( uint32_t ) ) {
state - > status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
return ;
}
state - > seqnum = dbwrap_get_seqnum ( leases_db ) ;
ndr = ( struct ndr_pull ) {
. data = data . dptr , . data_size = data . dsize ,
} ;
ndr_err = ndr_pull_uint32 ( & ndr , NDR_SCALARS , & state - > current_state ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
state - > status = ndr_map_error2ntstatus ( ndr_err ) ;
}
}
2018-09-11 17:23:38 +03:00
2019-08-13 23:07:47 +03:00
NTSTATUS leases_db_get_current_state (
const struct GUID * client_guid ,
const struct smb2_lease_key * lease_key ,
int * database_seqnum ,
uint32_t * current_state )
{
struct leases_db_get_current_state_state state = { 0 } ;
struct leases_db_key_buf keybuf ;
TDB_DATA db_key = { 0 } ;
NTSTATUS status ;
if ( ! leases_db_init ( true ) ) {
return NT_STATUS_INTERNAL_ERROR ;
}
state . seqnum = dbwrap_get_seqnum ( leases_db ) ;
if ( * database_seqnum = = state . seqnum ) {
return NT_STATUS_OK ;
}
db_key = leases_db_key ( & keybuf , client_guid , lease_key ) ;
status = dbwrap_parse_record (
leases_db , db_key , leases_db_get_current_state_fn , & state ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
* database_seqnum = state . seqnum ;
* current_state = state . current_state ;
return NT_STATUS_OK ;
2018-09-11 17:23:38 +03:00
}
2014-12-05 23:57:24 +03:00
NTSTATUS leases_db_copy_file_ids ( TALLOC_CTX * mem_ctx ,
uint32_t num_files ,
const struct leases_db_file * files ,
struct file_id * * pp_ids )
{
uint32_t i ;
struct file_id * ids = talloc_array ( mem_ctx ,
struct file_id ,
num_files ) ;
if ( ids = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < num_files ; i + + ) {
ids [ i ] = files [ i ] . id ;
}
* pp_ids = ids ;
return NT_STATUS_OK ;
}