2011-12-05 13:49:48 +04:00
/*
2008-01-16 12:09:48 +03:00
Unix SMB / CIFS implementation .
Utility functions for the dbwrap API
Copyright ( C ) Volker Lendecke 2007
2009-07-15 18:59:07 +04:00
Copyright ( C ) Michael Adam 2009
2011-05-30 11:27:23 +04:00
Copyright ( C ) Jim McDonough < jmcd @ us . ibm . com > 2006
Major code contributions from Aleksey Fedoseev ( fedoseev @ ru . ibm . com )
2008-01-16 12:09:48 +03:00
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 2 of the License , or
( at your option ) any later version .
2011-12-05 13:49:48 +04:00
2008-01-16 12:09:48 +03:00
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 .
2011-12-05 13:49:48 +04:00
2008-01-16 12:09:48 +03:00
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2010-08-18 20:59:23 +04:00
# include "dbwrap.h"
2012-05-12 00:11:42 +04:00
# include "lib/util/util_tdb.h"
2008-01-16 12:09:48 +03:00
2012-06-12 14:58:47 +04:00
struct dbwrap_fetch_int32_state {
NTSTATUS status ;
int32_t result ;
} ;
static void dbwrap_fetch_int32_parser ( TDB_DATA key , TDB_DATA data ,
void * private_data )
{
struct dbwrap_fetch_int32_state * state =
( struct dbwrap_fetch_int32_state * ) private_data ;
if ( data . dsize ! = sizeof ( state - > result ) ) {
state - > status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
return ;
}
state - > result = IVAL ( data . dptr , 0 ) ;
state - > status = NT_STATUS_OK ;
}
2012-06-15 12:52:07 +04:00
NTSTATUS dbwrap_fetch_int32 ( struct db_context * db , TDB_DATA key ,
int32_t * result )
2008-01-16 12:09:48 +03:00
{
2012-06-12 14:58:47 +04:00
struct dbwrap_fetch_int32_state state ;
2012-06-22 17:10:00 +04:00
NTSTATUS status ;
2008-01-16 12:09:48 +03:00
2011-10-06 22:34:55 +04:00
if ( result = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2012-06-22 17:08:22 +04:00
state . status = NT_STATUS_INTERNAL_ERROR ;
2012-06-22 17:10:00 +04:00
status = dbwrap_parse_record ( db , key , dbwrap_fetch_int32_parser , & state ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2008-01-16 12:09:48 +03:00
2012-06-12 14:58:47 +04:00
if ( NT_STATUS_IS_OK ( state . status ) ) {
* result = state . result ;
2008-01-16 12:09:48 +03:00
}
2012-06-12 14:58:47 +04:00
return state . status ;
2008-01-16 12:09:48 +03:00
}
2012-06-15 12:52:07 +04:00
NTSTATUS dbwrap_fetch_int32_bystring ( struct db_context * db , const char * keystr ,
int32_t * result )
{
return dbwrap_fetch_int32 ( db , string_term_tdb_data ( keystr ) , result ) ;
}
2012-06-14 22:30:16 +04:00
NTSTATUS dbwrap_store_int32_bystring ( struct db_context * db , const char * keystr ,
int32_t v )
2008-01-16 12:09:48 +03:00
{
2017-07-26 15:56:53 +03:00
uint8_t v_store [ sizeof ( int32_t ) ] ;
TDB_DATA data = { . dptr = v_store , . dsize = sizeof ( v_store ) } ;
2008-01-16 12:09:48 +03:00
NTSTATUS status ;
2017-07-26 15:56:53 +03:00
SIVAL ( v_store , 0 , v ) ;
2008-01-16 12:09:48 +03:00
2017-07-26 15:56:53 +03:00
status = dbwrap_store ( db , string_term_tdb_data ( keystr ) , data ,
TDB_REPLACE ) ;
2011-10-06 23:24:07 +04:00
return status ;
2008-03-28 11:42:37 +03:00
}
2012-11-08 17:15:25 +04:00
struct dbwrap_fetch_uint32_state {
NTSTATUS status ;
uint32_t result ;
} ;
static void dbwrap_fetch_uint32_parser ( TDB_DATA key , TDB_DATA data ,
void * private_data )
{
struct dbwrap_fetch_uint32_state * state =
( struct dbwrap_fetch_uint32_state * ) private_data ;
if ( data . dsize ! = sizeof ( state - > result ) ) {
state - > status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
return ;
}
state - > result = IVAL ( data . dptr , 0 ) ;
state - > status = NT_STATUS_OK ;
}
2012-06-14 22:39:27 +04:00
NTSTATUS dbwrap_fetch_uint32_bystring ( struct db_context * db ,
const char * keystr , uint32_t * val )
2008-03-28 11:42:37 +03:00
{
2012-11-08 17:15:25 +04:00
struct dbwrap_fetch_uint32_state state ;
2011-08-24 15:15:48 +04:00
NTSTATUS status ;
2008-03-28 11:42:37 +03:00
2011-10-06 23:07:27 +04:00
if ( val = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2012-11-08 17:15:25 +04:00
state . status = NT_STATUS_INTERNAL_ERROR ;
status = dbwrap_parse_record ( db , string_term_tdb_data ( keystr ) ,
dbwrap_fetch_uint32_parser , & state ) ;
2011-08-24 15:15:48 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-10-06 23:07:27 +04:00
return status ;
2008-03-28 11:42:37 +03:00
}
2012-11-08 17:15:25 +04:00
if ( NT_STATUS_IS_OK ( state . status ) ) {
* val = state . result ;
2011-10-25 11:33:05 +04:00
}
2012-11-08 17:15:25 +04:00
return state . status ;
2008-03-28 11:42:37 +03:00
}
2012-06-15 11:09:57 +04:00
NTSTATUS dbwrap_store_uint32_bystring ( struct db_context * db ,
const char * keystr , uint32_t v )
2008-03-28 11:42:37 +03:00
{
2017-07-26 15:56:53 +03:00
uint8_t v_store [ sizeof ( uint32_t ) ] ;
TDB_DATA data = { . dptr = v_store , . dsize = sizeof ( v_store ) } ;
2008-03-28 11:42:37 +03:00
NTSTATUS status ;
2017-07-26 15:56:53 +03:00
SIVAL ( v_store , 0 , v ) ;
2008-03-28 11:42:37 +03:00
2017-07-26 15:56:53 +03:00
status = dbwrap_store ( db , string_term_tdb_data ( keystr ) , data ,
TDB_REPLACE ) ;
2011-10-06 23:29:04 +04:00
return status ;
2008-01-16 12:09:48 +03:00
}
2008-08-06 01:13:06 +04:00
/**
* Atomic unsigned integer change ( addition ) :
*
* if value does not exist yet in the db , use * oldval as initial old value .
* return old value in * oldval .
* store * oldval + change_val to db .
*/
2009-07-29 16:32:31 +04:00
struct dbwrap_change_uint32_atomic_context {
const char * keystr ;
uint32_t * oldval ;
uint32_t change_val ;
} ;
static NTSTATUS dbwrap_change_uint32_atomic_action ( struct db_context * db ,
void * private_data )
2008-01-16 12:09:48 +03:00
{
struct db_record * rec ;
2011-02-09 21:43:56 +03:00
uint32_t val = ( uint32_t ) - 1 ;
2009-11-21 02:08:38 +03:00
uint32_t v_store ;
2009-07-29 16:16:11 +04:00
NTSTATUS ret ;
2009-07-29 16:32:31 +04:00
struct dbwrap_change_uint32_atomic_context * state ;
2011-08-24 03:01:38 +04:00
TDB_DATA value ;
2008-01-16 12:09:48 +03:00
2009-07-29 16:32:31 +04:00
state = ( struct dbwrap_change_uint32_atomic_context * ) private_data ;
2012-06-12 13:17:58 +04:00
rec = dbwrap_fetch_locked ( db , talloc_tos ( ) ,
string_term_tdb_data ( state - > keystr ) ) ;
2009-07-29 16:25:29 +04:00
if ( ! rec ) {
2009-07-29 16:16:11 +04:00
return NT_STATUS_UNSUCCESSFUL ;
2008-01-16 12:09:48 +03:00
}
2011-08-24 03:01:38 +04:00
value = dbwrap_record_get_value ( rec ) ;
if ( value . dptr = = NULL ) {
2009-07-29 16:32:31 +04:00
val = * ( state - > oldval ) ;
2011-08-24 03:01:38 +04:00
} else if ( value . dsize = = sizeof ( val ) ) {
val = IVAL ( value . dptr , 0 ) ;
2009-07-29 16:32:31 +04:00
* ( state - > oldval ) = val ;
2008-08-06 00:38:44 +04:00
} else {
2009-07-29 16:22:37 +04:00
ret = NT_STATUS_UNSUCCESSFUL ;
goto done ;
2008-01-16 12:09:48 +03:00
}
2009-07-29 16:32:31 +04:00
val + = state - > change_val ;
2008-01-16 12:09:48 +03:00
2009-11-21 02:08:38 +03:00
SIVAL ( & v_store , 0 , val ) ;
2008-01-16 12:09:48 +03:00
2011-08-24 03:01:38 +04:00
ret = dbwrap_record_store ( rec ,
2012-05-11 23:46:23 +04:00
make_tdb_data ( ( const uint8_t * ) & v_store ,
2011-08-24 03:01:38 +04:00
sizeof ( v_store ) ) ,
TDB_REPLACE ) ;
2008-01-16 12:09:48 +03:00
2009-07-29 16:22:37 +04:00
done :
2008-01-16 12:09:48 +03:00
TALLOC_FREE ( rec ) ;
2009-07-29 16:16:11 +04:00
return ret ;
2008-01-16 12:09:48 +03:00
}
2012-06-15 11:18:17 +04:00
NTSTATUS dbwrap_change_uint32_atomic_bystring ( struct db_context * db ,
const char * keystr ,
uint32_t * oldval ,
uint32_t change_val )
2009-07-29 16:32:31 +04:00
{
NTSTATUS ret ;
struct dbwrap_change_uint32_atomic_context state ;
state . keystr = keystr ;
state . oldval = oldval ;
state . change_val = change_val ;
ret = dbwrap_change_uint32_atomic_action ( db , & state ) ;
return ret ;
}
2012-06-15 11:20:25 +04:00
NTSTATUS dbwrap_trans_change_uint32_atomic_bystring ( struct db_context * db ,
const char * keystr ,
uint32_t * oldval ,
uint32_t change_val )
2009-07-29 16:37:39 +04:00
{
NTSTATUS ret ;
struct dbwrap_change_uint32_atomic_context state ;
state . keystr = keystr ;
state . oldval = oldval ;
state . change_val = change_val ;
ret = dbwrap_trans_do ( db , dbwrap_change_uint32_atomic_action , & state ) ;
return ret ;
}
2008-08-06 01:38:56 +04:00
/**
* Atomic integer change ( addition ) :
*
* if value does not exist yet in the db , use * oldval as initial old value .
* return old value in * oldval .
* store * oldval + change_val to db .
*/
2009-07-29 17:12:39 +04:00
struct dbwrap_change_int32_atomic_context {
2012-06-15 12:50:00 +04:00
TDB_DATA key ;
2009-07-29 17:12:39 +04:00
int32_t * oldval ;
int32_t change_val ;
} ;
static NTSTATUS dbwrap_change_int32_atomic_action ( struct db_context * db ,
void * private_data )
2008-03-09 13:15:10 +03:00
{
struct db_record * rec ;
2009-07-29 17:08:06 +04:00
int32_t val = - 1 ;
2009-11-21 02:14:29 +03:00
int32_t v_store ;
2009-07-29 16:21:03 +04:00
NTSTATUS ret ;
2009-07-29 17:12:39 +04:00
struct dbwrap_change_int32_atomic_context * state ;
2011-08-24 03:01:38 +04:00
TDB_DATA value ;
2008-03-09 13:15:10 +03:00
2009-07-29 17:12:39 +04:00
state = ( struct dbwrap_change_int32_atomic_context * ) private_data ;
2012-06-15 12:50:00 +04:00
rec = dbwrap_fetch_locked ( db , talloc_tos ( ) , state - > key ) ;
2009-07-29 16:26:26 +04:00
if ( ! rec ) {
2009-07-29 16:21:03 +04:00
return NT_STATUS_UNSUCCESSFUL ;
2008-03-09 13:15:10 +03:00
}
2011-08-24 03:01:38 +04:00
value = dbwrap_record_get_value ( rec ) ;
if ( value . dptr = = NULL ) {
2009-07-29 17:12:39 +04:00
val = * ( state - > oldval ) ;
2011-08-24 03:01:38 +04:00
} else if ( value . dsize = = sizeof ( val ) ) {
val = IVAL ( value . dptr , 0 ) ;
2009-07-29 17:12:39 +04:00
* ( state - > oldval ) = val ;
2008-08-06 01:14:05 +04:00
} else {
2009-07-29 16:23:26 +04:00
ret = NT_STATUS_UNSUCCESSFUL ;
goto done ;
2008-03-09 13:15:10 +03:00
}
2009-07-29 17:12:39 +04:00
val + = state - > change_val ;
2008-03-09 13:15:10 +03:00
2009-11-21 02:14:29 +03:00
SIVAL ( & v_store , 0 , val ) ;
2008-03-09 13:15:10 +03:00
2011-08-24 03:01:38 +04:00
ret = dbwrap_record_store ( rec ,
make_tdb_data ( ( const uint8_t * ) & v_store ,
sizeof ( v_store ) ) ,
TDB_REPLACE ) ;
2008-03-09 13:15:10 +03:00
2009-07-29 16:23:26 +04:00
done :
2008-03-09 13:15:10 +03:00
TALLOC_FREE ( rec ) ;
2009-07-29 16:21:03 +04:00
return ret ;
2008-03-09 13:15:10 +03:00
}
2008-03-10 15:27:27 +03:00
2012-06-15 12:50:00 +04:00
NTSTATUS dbwrap_change_int32_atomic ( struct db_context * db ,
TDB_DATA key ,
int32_t * oldval ,
int32_t change_val )
2009-07-29 17:12:39 +04:00
{
NTSTATUS ret ;
struct dbwrap_change_int32_atomic_context state ;
2012-06-15 12:50:00 +04:00
state . key = key ;
2009-07-29 17:12:39 +04:00
state . oldval = oldval ;
state . change_val = change_val ;
ret = dbwrap_change_int32_atomic_action ( db , & state ) ;
return ret ;
}
2012-06-15 12:50:00 +04:00
NTSTATUS dbwrap_change_int32_atomic_bystring ( struct db_context * db ,
const char * keystr ,
int32_t * oldval ,
int32_t change_val )
{
return dbwrap_change_int32_atomic ( db , string_term_tdb_data ( keystr ) ,
oldval , change_val ) ;
}
2012-06-15 11:45:18 +04:00
NTSTATUS dbwrap_trans_change_int32_atomic_bystring ( struct db_context * db ,
const char * keystr ,
int32_t * oldval ,
int32_t change_val )
2009-07-29 17:14:57 +04:00
{
NTSTATUS ret ;
struct dbwrap_change_int32_atomic_context state ;
2012-06-15 12:50:00 +04:00
state . key = string_term_tdb_data ( keystr ) ;
2009-07-29 17:14:57 +04:00
state . oldval = oldval ;
state . change_val = change_val ;
ret = dbwrap_trans_do ( db , dbwrap_change_int32_atomic_action , & state ) ;
return ret ;
}
2009-07-21 14:35:48 +04:00
struct dbwrap_store_context {
TDB_DATA * key ;
TDB_DATA * dbuf ;
int flag ;
} ;
static NTSTATUS dbwrap_store_action ( struct db_context * db , void * private_data )
2008-03-10 15:27:27 +03:00
{
NTSTATUS status ;
2009-07-21 14:35:48 +04:00
struct dbwrap_store_context * store_ctx ;
2008-03-10 15:27:27 +03:00
2009-07-21 14:35:48 +04:00
store_ctx = ( struct dbwrap_store_context * ) private_data ;
2008-03-10 15:27:27 +03:00
2017-07-26 16:10:55 +03:00
status = dbwrap_store ( db , * ( store_ctx - > key ) , * ( store_ctx - > dbuf ) ,
store_ctx - > flag ) ;
2008-03-10 15:27:27 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 5 , ( " store returned %s \n " , nt_errstr ( status ) ) ) ;
}
2009-07-21 14:35:48 +04:00
return status ;
}
2008-03-10 15:27:27 +03:00
2009-07-21 14:35:48 +04:00
NTSTATUS dbwrap_trans_store ( struct db_context * db , TDB_DATA key , TDB_DATA dbuf ,
int flag )
{
NTSTATUS status ;
struct dbwrap_store_context store_ctx ;
2008-03-10 15:27:27 +03:00
2009-07-21 14:35:48 +04:00
store_ctx . key = & key ;
store_ctx . dbuf = & dbuf ;
store_ctx . flag = flag ;
2008-03-10 15:27:27 +03:00
2009-07-21 14:35:48 +04:00
status = dbwrap_trans_do ( db , dbwrap_store_action , & store_ctx ) ;
2008-03-30 15:11:22 +04:00
2008-03-28 13:53:00 +03:00
return status ;
2008-03-10 15:27:27 +03:00
}
2009-07-21 14:26:14 +04:00
static NTSTATUS dbwrap_delete_action ( struct db_context * db , void * private_data )
2008-03-10 15:27:27 +03:00
{
NTSTATUS status ;
2009-07-21 14:26:14 +04:00
TDB_DATA * key = ( TDB_DATA * ) private_data ;
2008-03-10 15:27:27 +03:00
2017-07-26 16:12:21 +03:00
status = dbwrap_delete ( db , * key ) ;
2008-03-10 15:27:27 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-02-25 18:02:36 +03:00
DBG_INFO ( " dbwrap_record_delete returned %s \n " ,
nt_errstr ( status ) ) ;
2008-03-10 15:27:27 +03:00
}
2009-07-21 14:26:14 +04:00
return status ;
}
2008-03-10 15:27:27 +03:00
2009-07-21 14:26:14 +04:00
NTSTATUS dbwrap_trans_delete ( struct db_context * db , TDB_DATA key )
{
NTSTATUS status ;
2008-03-10 15:27:27 +03:00
2009-07-21 14:26:14 +04:00
status = dbwrap_trans_do ( db , dbwrap_delete_action , & key ) ;
2008-04-08 01:36:29 +04:00
2008-03-28 13:57:54 +03:00
return status ;
2008-03-10 15:27:27 +03:00
}
2008-03-27 17:59:58 +03:00
2012-06-15 11:48:20 +04:00
NTSTATUS dbwrap_trans_store_int32_bystring ( struct db_context * db ,
const char * keystr ,
int32_t v )
2008-03-27 17:59:58 +03:00
{
2012-05-11 23:46:23 +04:00
int32_t v_store ;
2008-03-27 17:59:58 +03:00
SIVAL ( & v_store , 0 , v ) ;
2008-03-28 13:53:00 +03:00
return dbwrap_trans_store ( db , string_term_tdb_data ( keystr ) ,
2012-05-11 23:46:23 +04:00
make_tdb_data ( ( const uint8_t * ) & v_store ,
2008-03-27 17:59:58 +03:00
sizeof ( v_store ) ) ,
2008-03-28 13:53:00 +03:00
TDB_REPLACE ) ;
2008-03-27 17:59:58 +03:00
}
2008-03-28 14:02:28 +03:00
2012-06-15 11:51:21 +04:00
NTSTATUS dbwrap_trans_store_uint32_bystring ( struct db_context * db ,
const char * keystr ,
uint32_t v )
2008-03-28 22:03:30 +03:00
{
2012-05-11 23:46:23 +04:00
uint32_t v_store ;
2008-03-28 22:03:30 +03:00
SIVAL ( & v_store , 0 , v ) ;
return dbwrap_trans_store ( db , string_term_tdb_data ( keystr ) ,
2012-05-11 23:46:23 +04:00
make_tdb_data ( ( const uint8_t * ) & v_store ,
2008-03-28 22:03:30 +03:00
sizeof ( v_store ) ) ,
TDB_REPLACE ) ;
}
2008-03-28 14:02:28 +03:00
NTSTATUS dbwrap_trans_store_bystring ( struct db_context * db , const char * key ,
TDB_DATA data , int flags )
{
return dbwrap_trans_store ( db , string_term_tdb_data ( key ) , data , flags ) ;
}
NTSTATUS dbwrap_trans_delete_bystring ( struct db_context * db , const char * key )
{
return dbwrap_trans_delete ( db , string_term_tdb_data ( key ) ) ;
}
2009-07-15 16:00:42 +04:00
/**
* Wrap db action ( s ) into a transaction .
*/
NTSTATUS dbwrap_trans_do ( struct db_context * db ,
NTSTATUS ( * action ) ( struct db_context * , void * ) ,
void * private_data )
{
int res ;
NTSTATUS status ;
2011-08-24 03:01:38 +04:00
res = dbwrap_transaction_start ( db ) ;
2009-07-15 16:00:42 +04:00
if ( res ! = 0 ) {
DEBUG ( 5 , ( " transaction_start failed \n " ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
status = action ( db , private_data ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-08-24 03:01:38 +04:00
if ( dbwrap_transaction_cancel ( db ) ! = 0 ) {
2009-07-15 16:00:42 +04:00
smb_panic ( " Cancelling transaction failed " ) ;
}
return status ;
}
2011-08-24 03:01:38 +04:00
res = dbwrap_transaction_commit ( db ) ;
2009-07-15 16:00:42 +04:00
if ( res = = 0 ) {
return NT_STATUS_OK ;
}
DEBUG ( 2 , ( " transaction_commit failed \n " ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2009-07-08 18:02:19 +04:00
2011-03-16 11:13:40 +03:00
struct dbwrap_trans_traverse_action_ctx {
int ( * f ) ( struct db_record * rec , void * private_data ) ;
void * private_data ;
} ;
static NTSTATUS dbwrap_trans_traverse_action ( struct db_context * db , void * private_data )
{
struct dbwrap_trans_traverse_action_ctx * ctx =
( struct dbwrap_trans_traverse_action_ctx * ) private_data ;
2011-08-24 03:01:38 +04:00
NTSTATUS status = dbwrap_traverse ( db , ctx - > f , ctx - > private_data , NULL ) ;
2011-03-16 11:13:40 +03:00
2011-08-24 03:01:38 +04:00
return status ;
2011-03-16 11:13:40 +03:00
}
NTSTATUS dbwrap_trans_traverse ( struct db_context * db ,
int ( * f ) ( struct db_record * , void * ) ,
void * private_data )
{
struct dbwrap_trans_traverse_action_ctx ctx = {
. f = f ,
. private_data = private_data ,
} ;
return dbwrap_trans_do ( db , dbwrap_trans_traverse_action , & ctx ) ;
}
2016-02-25 02:56:14 +03:00
NTSTATUS dbwrap_purge ( struct db_context * db , TDB_DATA key )
{
NTSTATUS status ;
status = dbwrap_delete ( db , key ) ;
if ( NT_STATUS_EQUAL ( status , NT_STATUS_NOT_FOUND ) ) {
status = NT_STATUS_OK ;
}
return status ;
}
NTSTATUS dbwrap_purge_bystring ( struct db_context * db , const char * key )
{
return dbwrap_purge ( db , string_term_tdb_data ( key ) ) ;
}
2011-05-30 11:27:23 +04:00
NTSTATUS dbwrap_delete_bystring ( struct db_context * db , const char * key )
{
return dbwrap_delete ( db , string_term_tdb_data ( key ) ) ;
}
NTSTATUS dbwrap_store_bystring ( struct db_context * db , const char * key ,
TDB_DATA data , int flags )
{
return dbwrap_store ( db , string_term_tdb_data ( key ) , data , flags ) ;
}
2011-08-24 15:08:13 +04:00
NTSTATUS dbwrap_fetch_bystring ( struct db_context * db , TALLOC_CTX * mem_ctx ,
const char * key , TDB_DATA * value )
2011-05-30 11:27:23 +04:00
{
2011-08-24 15:08:13 +04:00
return dbwrap_fetch ( db , mem_ctx , string_term_tdb_data ( key ) , value ) ;
2011-05-30 11:27:23 +04:00
}
2011-03-16 11:13:40 +03:00
2009-07-08 18:02:19 +04:00
NTSTATUS dbwrap_delete_bystring_upper ( struct db_context * db , const char * key )
{
char * key_upper ;
NTSTATUS status ;
key_upper = talloc_strdup_upper ( talloc_tos ( ) , key ) ;
if ( key_upper = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = dbwrap_delete_bystring ( db , key_upper ) ;
talloc_free ( key_upper ) ;
return status ;
}
2009-07-08 18:08:41 +04:00
NTSTATUS dbwrap_store_bystring_upper ( struct db_context * db , const char * key ,
TDB_DATA data , int flags )
{
char * key_upper ;
NTSTATUS status ;
key_upper = talloc_strdup_upper ( talloc_tos ( ) , key ) ;
if ( key_upper = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = dbwrap_store_bystring ( db , key_upper , data , flags ) ;
talloc_free ( key_upper ) ;
return status ;
}
2009-07-08 18:13:07 +04:00
2011-08-24 15:08:13 +04:00
NTSTATUS dbwrap_fetch_bystring_upper ( struct db_context * db , TALLOC_CTX * mem_ctx ,
const char * key , TDB_DATA * value )
2009-07-08 18:13:07 +04:00
{
char * key_upper ;
2011-08-24 15:08:13 +04:00
NTSTATUS status ;
2009-07-08 18:13:07 +04:00
key_upper = talloc_strdup_upper ( talloc_tos ( ) , key ) ;
if ( key_upper = = NULL ) {
2011-08-24 15:08:13 +04:00
return NT_STATUS_NO_MEMORY ;
2009-07-08 18:13:07 +04:00
}
2011-08-24 15:08:13 +04:00
status = dbwrap_fetch_bystring ( db , mem_ctx , key_upper , value ) ;
2009-07-08 18:13:07 +04:00
talloc_free ( key_upper ) ;
2011-08-24 15:08:13 +04:00
return status ;
2009-07-08 18:13:07 +04:00
}
2014-11-05 16:02:38 +03:00
struct dbwrap_marshall_state {
uint8_t * buf ;
size_t bufsize ;
size_t dbsize ;
} ;
static int dbwrap_marshall_fn ( struct db_record * rec , void * private_data )
{
struct dbwrap_marshall_state * state = private_data ;
TDB_DATA key , value ;
size_t new_dbsize ;
key = dbwrap_record_get_key ( rec ) ;
value = dbwrap_record_get_value ( rec ) ;
new_dbsize = state - > dbsize ;
new_dbsize + = 8 + key . dsize ;
new_dbsize + = 8 + value . dsize ;
if ( new_dbsize < = state - > bufsize ) {
uint8_t * p = state - > buf + state - > dbsize ;
SBVAL ( p , 0 , key . dsize ) ;
p + = 8 ;
memcpy ( p , key . dptr , key . dsize ) ;
p + = key . dsize ;
SBVAL ( p , 0 , value . dsize ) ;
p + = 8 ;
memcpy ( p , value . dptr , value . dsize ) ;
}
state - > dbsize = new_dbsize ;
return 0 ;
}
size_t dbwrap_marshall ( struct db_context * db , uint8_t * buf , size_t bufsize )
{
struct dbwrap_marshall_state state ;
state . bufsize = bufsize ;
state . buf = buf ;
state . dbsize = 0 ;
dbwrap_traverse_read ( db , dbwrap_marshall_fn , & state , NULL ) ;
return state . dbsize ;
}
static ssize_t dbwrap_unmarshall_get_data ( const uint8_t * buf , size_t buflen ,
size_t ofs , TDB_DATA * pdata )
{
uint64_t space , len ;
const uint8_t * p ;
if ( ofs = = buflen ) {
return 0 ;
}
if ( ofs > buflen ) {
return - 1 ;
}
space = buflen - ofs ;
if ( space < 8 ) {
return - 1 ;
}
p = buf + ofs ;
len = BVAL ( p , 0 ) ;
p + = 8 ;
space - = 8 ;
if ( len > space ) {
return - 1 ;
}
* pdata = ( TDB_DATA ) { . dptr = discard_const_p ( uint8_t , p ) ,
. dsize = len } ;
return len + 8 ;
}
NTSTATUS dbwrap_parse_marshall_buf ( const uint8_t * buf , size_t buflen ,
bool ( * fn ) ( TDB_DATA key , TDB_DATA value ,
void * private_data ) ,
void * private_data )
{
size_t ofs = 0 ;
while ( true ) {
ssize_t len ;
TDB_DATA key , value ;
bool ok ;
len = dbwrap_unmarshall_get_data ( buf , buflen , ofs , & key ) ;
if ( len = = 0 ) {
break ;
}
if ( len = = - 1 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
ofs + = len ;
len = dbwrap_unmarshall_get_data ( buf , buflen , ofs , & value ) ;
if ( len = = 0 ) {
break ;
}
if ( len = = - 1 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
ofs + = len ;
ok = fn ( key , value , private_data ) ;
if ( ! ok ) {
break ;
}
}
return NT_STATUS_OK ;
}
struct dbwrap_unmarshall_state {
struct db_context * db ;
NTSTATUS ret ;
} ;
static bool dbwrap_unmarshall_fn ( TDB_DATA key , TDB_DATA value ,
void * private_data )
{
struct dbwrap_unmarshall_state * state = private_data ;
NTSTATUS status ;
2017-07-26 16:14:51 +03:00
status = dbwrap_store ( state - > db , key , value , 0 ) ;
2014-11-05 16:02:38 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2017-07-26 16:14:51 +03:00
DBG_DEBUG ( " dbwrap_record_store failed: %s \n " ,
nt_errstr ( status ) ) ;
2014-11-05 16:02:38 +03:00
state - > ret = status ;
return false ;
}
return true ;
}
NTSTATUS dbwrap_unmarshall ( struct db_context * db , const uint8_t * buf ,
size_t buflen )
{
struct dbwrap_unmarshall_state state = { . db = db } ;
NTSTATUS status ;
status = dbwrap_parse_marshall_buf ( buf , buflen ,
dbwrap_unmarshall_fn , & state ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return state . ret ;
}