2021-04-11 22:43:51 +03:00
/*
2003-08-13 05:53:07 +04:00
Unix SMB / CIFS implementation .
2005-09-16 07:52:42 +04:00
2003-08-13 05:53:07 +04:00
tdb utility functions
2005-09-16 07:52:42 +04:00
2006-10-21 03:32:23 +04:00
Copyright ( C ) Andrew Tridgell 1992 - 2006
2012-04-16 08:18:49 +04:00
Copyright ( C ) Volker Lendecke 2007 - 2011
2003-08-13 05:53:07 +04: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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2003-08-13 05:53:07 +04:00
( at your option ) any later version .
2021-04-11 22:43:51 +03:00
2003-08-13 05:53:07 +04: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 .
2021-04-11 22:43:51 +03:00
2003-08-13 05:53:07 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-08-13 05:53:07 +04:00
*/
2017-01-08 22:52:47 +03:00
# include "replace.h"
# include <talloc.h>
# include "libcli/util/ntstatus.h"
# include "lib/util/memory.h"
# include "lib/util/byteorder.h"
2012-06-22 09:37:36 +04:00
# include "system/filesys.h"
2012-06-19 07:13:10 +04:00
# include "../lib/tdb/include/tdb.h"
2008-10-11 23:31:42 +04:00
# include "../lib/util/util_tdb.h"
2003-08-13 05:53:07 +04:00
/* these are little tdb utility functions that are meant to make
dealing with a tdb database a little less cumbersome in Samba */
/***************************************************************
Make a TDB_DATA and keep the const warning in one place
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-10-12 18:53:17 +04:00
TDB_DATA make_tdb_data ( const uint8_t * dptr , size_t dsize )
2003-08-13 05:53:07 +04:00
{
TDB_DATA ret ;
2008-10-12 18:53:17 +04:00
ret . dptr = discard_const_p ( uint8_t , dptr ) ;
2003-08-13 05:53:07 +04:00
ret . dsize = dsize ;
return ret ;
}
2009-12-03 20:43:49 +03:00
bool tdb_data_equal ( TDB_DATA t1 , TDB_DATA t2 )
{
if ( t1 . dsize ! = t2 . dsize ) {
return false ;
}
return ( memcmp ( t1 . dptr , t2 . dptr , t1 . dsize ) = = 0 ) ;
}
2011-12-06 16:46:08 +04:00
bool tdb_data_is_empty ( TDB_DATA d )
{
2011-11-07 12:59:37 +04:00
return ( d . dsize = = 0 ) | | ( d . dptr = = NULL ) ;
}
2008-10-12 18:53:17 +04:00
TDB_DATA string_tdb_data ( const char * string )
{
2008-10-12 19:34:43 +04:00
return make_tdb_data ( ( const uint8_t * ) string , string ? strlen ( string ) : 0 ) ;
2008-10-12 18:53:17 +04:00
}
TDB_DATA string_term_tdb_data ( const char * string )
{
2008-10-12 19:34:43 +04:00
return make_tdb_data ( ( const uint8_t * ) string , string ? strlen ( string ) + 1 : 0 ) ;
2008-10-12 18:53:17 +04:00
}
2013-01-10 14:09:09 +04:00
TDB_DATA tdb_data_talloc_copy ( TALLOC_CTX * mem_ctx , TDB_DATA data ) {
TDB_DATA ret = {
. dptr = ( uint8_t * ) talloc_size ( mem_ctx , data . dsize + 1 ) ,
. dsize = data . dsize
} ;
if ( ret . dptr = = NULL ) {
ret . dsize = 0 ;
} else {
memcpy ( ret . dptr , data . dptr , data . dsize ) ;
ret . dptr [ ret . dsize ] = ' \0 ' ;
}
return ret ;
}
2003-08-13 05:53:07 +04:00
/****************************************************************************
2011-06-20 13:10:33 +04:00
Lock a chain by string . Return non - zero if lock failed .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-16 07:52:42 +04:00
int tdb_lock_bystring ( struct tdb_context * tdb , const char * keyval )
2003-08-13 05:53:07 +04:00
{
2008-10-12 18:53:17 +04:00
TDB_DATA key = string_term_tdb_data ( keyval ) ;
2021-04-11 22:43:51 +03:00
2005-03-13 04:40:45 +03:00
return tdb_chainlock ( tdb , key ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Unlock a chain by string .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-16 07:52:42 +04:00
void tdb_unlock_bystring ( struct tdb_context * tdb , const char * keyval )
2003-08-13 05:53:07 +04:00
{
2008-10-12 18:53:17 +04:00
TDB_DATA key = string_term_tdb_data ( keyval ) ;
2003-08-13 05:53:07 +04:00
tdb_chainunlock ( tdb , key ) ;
}
/****************************************************************************
2011-06-20 13:10:33 +04:00
Read lock a chain by string . Return non - zero if lock failed .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-16 07:52:42 +04:00
int tdb_read_lock_bystring ( struct tdb_context * tdb , const char * keyval )
2003-08-13 05:53:07 +04:00
{
2008-10-12 18:53:17 +04:00
TDB_DATA key = string_term_tdb_data ( keyval ) ;
2021-04-11 22:43:51 +03:00
2005-03-13 04:40:45 +03:00
return tdb_chainlock_read ( tdb , key ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Read unlock a chain by string .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-16 07:52:42 +04:00
void tdb_read_unlock_bystring ( struct tdb_context * tdb , const char * keyval )
2003-08-13 05:53:07 +04:00
{
2008-10-12 18:53:17 +04:00
TDB_DATA key = string_term_tdb_data ( keyval ) ;
2021-04-11 22:43:51 +03:00
2003-08-13 05:53:07 +04:00
tdb_chainunlock_read ( tdb , key ) ;
}
/****************************************************************************
2004-05-25 20:24:13 +04:00
Fetch a int32_t value by a arbitrary blob key , return - 1 if not found .
Output is int32_t in native byte order .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2021-04-12 11:37:11 +03:00
static int fetch_int32_parser ( TDB_DATA key , TDB_DATA data , void * private_data )
2003-08-13 05:53:07 +04:00
{
2021-04-12 11:37:11 +03:00
if ( data . dsize = = sizeof ( int32_t ) ) {
* ( ( int32_t * ) private_data ) = PULL_LE_I32 ( data . dptr , 0 ) ;
2003-08-13 05:53:07 +04:00
}
2021-04-12 11:37:11 +03:00
return 0 ;
}
2003-08-13 05:53:07 +04:00
2021-04-12 11:37:11 +03:00
static int32_t tdb_fetch_int32_byblob ( struct tdb_context * tdb , TDB_DATA key )
{
2021-12-10 17:06:03 +03:00
int32_t v = - 1 ;
int32_t ret = tdb_parse_record ( tdb , key , fetch_int32_parser , & v ) ;
if ( ret = = - 1 ) {
return ret ;
}
2021-04-12 11:37:11 +03:00
return v ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
2004-05-25 20:24:13 +04:00
Fetch a int32_t value by string key , return - 1 if not found .
Output is int32_t in native byte order .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-16 07:52:42 +04:00
int32_t tdb_fetch_int32 ( struct tdb_context * tdb , const char * keystr )
2003-08-13 05:53:07 +04:00
{
2008-10-12 18:53:17 +04:00
return tdb_fetch_int32_byblob ( tdb , string_term_tdb_data ( keystr ) ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
2011-06-20 13:10:31 +04:00
Store a int32_t value by an arbitrary blob key , return 0 on success , - ve on failure .
2004-05-25 20:24:13 +04:00
Input is int32_t in native byte order . Output in tdb is in little - endian .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-08-03 18:08:48 +03:00
static int tdb_store_int32_byblob ( struct tdb_context * tdb , TDB_DATA key ,
int32_t v )
2003-08-13 05:53:07 +04:00
{
TDB_DATA data ;
2004-05-25 20:24:13 +04:00
int32_t v_store ;
2003-08-13 05:53:07 +04:00
SIVAL ( & v_store , 0 , v ) ;
2007-09-08 17:27:14 +04:00
data . dptr = ( unsigned char * ) & v_store ;
2004-05-25 20:50:09 +04:00
data . dsize = sizeof ( int32_t ) ;
2003-08-13 05:53:07 +04:00
return tdb_store ( tdb , key , data , TDB_REPLACE ) ;
}
/****************************************************************************
2011-06-20 13:10:31 +04:00
Store a int32_t value by string key , return 0 on success , - ve on failure .
2004-05-25 20:24:13 +04:00
Input is int32_t in native byte order . Output in tdb is in little - endian .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-16 07:52:42 +04:00
int tdb_store_int32 ( struct tdb_context * tdb , const char * keystr , int32_t v )
2003-08-13 05:53:07 +04:00
{
2008-10-12 18:53:17 +04:00
return tdb_store_int32_byblob ( tdb , string_term_tdb_data ( keystr ) , v ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
2009-05-12 04:29:16 +04:00
Fetch a uint32_t value by a arbitrary blob key , return false if not found .
2004-05-25 20:24:13 +04:00
Output is uint32_t in native byte order .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2021-04-12 11:29:02 +03:00
static int fetch_uint32_parser ( TDB_DATA key , TDB_DATA data , void * private_data )
2003-08-13 05:53:07 +04:00
{
2021-04-12 11:29:02 +03:00
if ( data . dsize ! = sizeof ( uint32_t ) ) {
return - 1 ;
2003-08-13 05:53:07 +04:00
}
2021-04-12 11:29:02 +03:00
* ( ( uint32_t * ) private_data ) = PULL_LE_U32 ( data . dptr , 0 ) ;
return 0 ;
}
2003-08-13 05:53:07 +04:00
2021-04-12 11:29:02 +03:00
static bool tdb_fetch_uint32_byblob ( struct tdb_context * tdb , TDB_DATA key ,
uint32_t * value )
{
int ret = tdb_parse_record ( tdb , key , fetch_uint32_parser , value ) ;
2021-05-11 12:31:33 +03:00
if ( ret = = - 1 ) {
return false ;
}
return true ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
2009-05-12 04:29:16 +04:00
Fetch a uint32_t value by string key , return false if not found .
2004-05-25 20:24:13 +04:00
Output is uint32_t in native byte order .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-08-27 21:21:16 +04:00
bool tdb_fetch_uint32 ( struct tdb_context * tdb , const char * keystr , uint32_t * value )
2003-08-13 05:53:07 +04:00
{
2008-10-12 18:53:17 +04:00
return tdb_fetch_uint32_byblob ( tdb , string_term_tdb_data ( keystr ) , value ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
2011-06-20 13:10:31 +04:00
Store a uint32_t value by an arbitrary blob key , return true on success , false on failure .
2004-05-25 20:24:13 +04:00
Input is uint32_t in native byte order . Output in tdb is in little - endian .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-08-03 18:08:48 +03:00
static bool tdb_store_uint32_byblob ( struct tdb_context * tdb , TDB_DATA key ,
uint32_t value )
2003-08-13 05:53:07 +04:00
{
TDB_DATA data ;
2004-05-25 20:24:13 +04:00
uint32_t v_store ;
2007-08-27 21:21:16 +04:00
bool ret = true ;
2003-08-13 05:53:07 +04:00
SIVAL ( & v_store , 0 , value ) ;
2007-09-08 17:27:14 +04:00
data . dptr = ( unsigned char * ) & v_store ;
2004-05-25 20:50:09 +04:00
data . dsize = sizeof ( uint32_t ) ;
2003-08-13 05:53:07 +04:00
2011-06-20 13:10:31 +04:00
if ( tdb_store ( tdb , key , data , TDB_REPLACE ) ! = 0 )
2007-08-27 21:21:16 +04:00
ret = false ;
2003-08-13 05:53:07 +04:00
return ret ;
}
/****************************************************************************
2011-06-20 13:10:31 +04:00
Store a uint32_t value by string key , return true on success , false on failure .
2004-05-25 20:24:13 +04:00
Input is uint32_t in native byte order . Output in tdb is in little - endian .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-08-27 21:21:16 +04:00
bool tdb_store_uint32 ( struct tdb_context * tdb , const char * keystr , uint32_t value )
2003-08-13 05:53:07 +04:00
{
2008-10-12 18:53:17 +04:00
return tdb_store_uint32_byblob ( tdb , string_term_tdb_data ( keystr ) , value ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
2011-06-20 13:10:31 +04:00
Store a buffer by a null terminated string key . Return 0 on success , - ve
2003-08-13 05:53:07 +04:00
on failure .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-16 07:52:42 +04:00
int tdb_store_bystring ( struct tdb_context * tdb , const char * keystr , TDB_DATA data , int flags )
2003-08-13 05:53:07 +04:00
{
2008-10-12 18:53:17 +04:00
TDB_DATA key = string_term_tdb_data ( keystr ) ;
2021-04-11 22:43:51 +03:00
2003-08-13 05:53:07 +04:00
return tdb_store ( tdb , key , data , flags ) ;
}
/****************************************************************************
Fetch a buffer using a null terminated string key . Don ' t forget to call
free ( ) on the result dptr .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-16 07:52:42 +04:00
TDB_DATA tdb_fetch_bystring ( struct tdb_context * tdb , const char * keystr )
2003-08-13 05:53:07 +04:00
{
2008-10-12 18:53:17 +04:00
TDB_DATA key = string_term_tdb_data ( keystr ) ;
2003-08-13 05:53:07 +04:00
2012-06-19 07:13:10 +04:00
return tdb_fetch ( tdb , key ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
2021-04-11 22:43:51 +03:00
Delete an entry using a null terminated string key .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-16 07:52:42 +04:00
int tdb_delete_bystring ( struct tdb_context * tdb , const char * keystr )
2003-08-13 05:53:07 +04:00
{
2008-10-12 18:53:17 +04:00
TDB_DATA key = string_term_tdb_data ( keystr ) ;
2003-08-13 05:53:07 +04:00
return tdb_delete ( tdb , key ) ;
}
/****************************************************************************
2021-04-11 22:43:51 +03:00
Atomic integer change . Returns old value . To create , set initial value in * oldval .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-16 07:52:42 +04:00
int32_t tdb_change_int32_atomic ( struct tdb_context * tdb , const char * keystr , int32_t * oldval , int32_t change_val )
2003-08-13 05:53:07 +04:00
{
2004-05-25 20:24:13 +04:00
int32_t val ;
int32_t ret = - 1 ;
2003-08-13 05:53:07 +04:00
2011-06-20 13:10:33 +04:00
if ( tdb_lock_bystring ( tdb , keystr ) ! = 0 )
2003-08-13 05:53:07 +04:00
return - 1 ;
if ( ( val = tdb_fetch_int32 ( tdb , keystr ) ) = = - 1 ) {
/* The lookup failed */
if ( tdb_error ( tdb ) ! = TDB_ERR_NOEXIST ) {
2003-12-10 06:02:12 +03:00
/* but not because it didn't exist */
2003-08-13 05:53:07 +04:00
goto err_out ;
}
2021-04-11 22:43:51 +03:00
2003-08-13 05:53:07 +04:00
/* Start with 'old' value */
val = * oldval ;
} else {
/* It worked, set return value (oldval) to tdb data */
* oldval = val ;
}
/* Increment value for storage and return next time */
val + = change_val ;
2021-04-11 22:43:51 +03:00
2011-06-20 13:10:31 +04:00
if ( tdb_store_int32 ( tdb , keystr , val ) ! = 0 )
2003-08-13 05:53:07 +04:00
goto err_out ;
ret = 0 ;
err_out :
tdb_unlock_bystring ( tdb , keystr ) ;
return ret ;
}
/****************************************************************************
2021-04-11 22:43:51 +03:00
Atomic unsigned integer change . Returns old value . To create , set initial value in * oldval .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-08-27 21:21:16 +04:00
bool tdb_change_uint32_atomic ( struct tdb_context * tdb , const char * keystr , uint32_t * oldval , uint32_t change_val )
2003-08-13 05:53:07 +04:00
{
2004-05-25 20:24:13 +04:00
uint32_t val ;
2007-08-27 21:21:16 +04:00
bool ret = false ;
2003-08-13 05:53:07 +04:00
2011-06-20 13:10:33 +04:00
if ( tdb_lock_bystring ( tdb , keystr ) ! = 0 )
2007-08-27 21:21:16 +04:00
return false ;
2003-08-13 05:53:07 +04:00
if ( ! tdb_fetch_uint32 ( tdb , keystr , & val ) ) {
/* It failed */
2021-04-11 22:43:51 +03:00
if ( tdb_error ( tdb ) ! = TDB_ERR_NOEXIST ) {
2003-12-10 06:02:12 +03:00
/* and not because it didn't exist */
2003-08-13 05:53:07 +04:00
goto err_out ;
}
/* Start with 'old' value */
val = * oldval ;
} else {
/* it worked, set return value (oldval) to tdb data */
* oldval = val ;
}
/* get a new value to store */
val + = change_val ;
2021-04-11 22:43:51 +03:00
2003-08-13 05:53:07 +04:00
if ( ! tdb_store_uint32 ( tdb , keystr , val ) )
goto err_out ;
2007-08-27 21:21:16 +04:00
ret = true ;
2003-08-13 05:53:07 +04:00
err_out :
tdb_unlock_bystring ( tdb , keystr ) ;
return ret ;
}
2012-04-16 08:18:49 +04:00
/****************************************************************************
Return an NTSTATUS from a TDB_ERROR
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS map_nt_error_from_tdb ( enum TDB_ERROR err )
{
2019-06-13 21:26:18 +03:00
NTSTATUS result ;
2012-04-16 08:18:49 +04:00
switch ( err ) {
case TDB_SUCCESS :
result = NT_STATUS_OK ;
break ;
case TDB_ERR_CORRUPT :
result = NT_STATUS_INTERNAL_DB_CORRUPTION ;
break ;
case TDB_ERR_IO :
result = NT_STATUS_UNEXPECTED_IO_ERROR ;
break ;
case TDB_ERR_OOM :
result = NT_STATUS_NO_MEMORY ;
break ;
case TDB_ERR_EXISTS :
result = NT_STATUS_OBJECT_NAME_COLLISION ;
break ;
case TDB_ERR_LOCK :
/*
* TDB_ERR_LOCK is very broad , we could for example
* distinguish between fcntl locks and invalid lock
* sequences . So NT_STATUS_FILE_LOCK_CONFLICT is a
* compromise .
*/
result = NT_STATUS_FILE_LOCK_CONFLICT ;
break ;
case TDB_ERR_NOLOCK :
case TDB_ERR_LOCK_TIMEOUT :
/*
* These two ones in the enum are not actually used
*/
result = NT_STATUS_FILE_LOCK_CONFLICT ;
break ;
case TDB_ERR_NOEXIST :
result = NT_STATUS_NOT_FOUND ;
break ;
case TDB_ERR_EINVAL :
result = NT_STATUS_INVALID_PARAMETER ;
break ;
case TDB_ERR_RDONLY :
result = NT_STATUS_ACCESS_DENIED ;
break ;
case TDB_ERR_NESTING :
result = NT_STATUS_INTERNAL_ERROR ;
break ;
2019-06-13 21:26:18 +03:00
default :
result = NT_STATUS_INTERNAL_ERROR ;
break ;
2012-04-16 08:18:49 +04:00
} ;
return result ;
}
2014-09-14 15:10:58 +04:00
int map_unix_error_from_tdb ( enum TDB_ERROR err )
{
int result = EINVAL ;
switch ( err ) {
case TDB_SUCCESS :
result = 0 ;
break ;
case TDB_ERR_CORRUPT :
result = EILSEQ ;
break ;
case TDB_ERR_IO :
result = EIO ;
break ;
case TDB_ERR_OOM :
result = ENOMEM ;
break ;
case TDB_ERR_EXISTS :
result = EEXIST ;
break ;
case TDB_ERR_LOCK :
/*
* TDB_ERR_LOCK is very broad , we could for example
* distinguish between fcntl locks and invalid lock
* sequences . EWOULDBLOCK is wrong , but there is no real
* generic lock error code in errno . h
*/
result = EWOULDBLOCK ;
break ;
case TDB_ERR_NOLOCK :
case TDB_ERR_LOCK_TIMEOUT :
/*
* These two ones in the enum are not actually used
*/
result = ENOLCK ;
break ;
case TDB_ERR_NOEXIST :
result = ENOENT ;
break ;
case TDB_ERR_EINVAL :
result = EINVAL ;
break ;
case TDB_ERR_RDONLY :
result = EROFS ;
break ;
case TDB_ERR_NESTING :
/*
* Well , this db is already busy . . .
*/
result = EBUSY ;
break ;
} ;
return result ;
}
2014-10-21 14:39:53 +04:00
struct tdb_fetch_talloc_state {
TALLOC_CTX * mem_ctx ;
uint8_t * buf ;
} ;
static int tdb_fetch_talloc_parser ( TDB_DATA key , TDB_DATA data ,
void * private_data )
{
struct tdb_fetch_talloc_state * state = private_data ;
state - > buf = talloc_memdup ( state - > mem_ctx , data . dptr , data . dsize ) ;
return 0 ;
}
int tdb_fetch_talloc ( struct tdb_context * tdb , TDB_DATA key ,
TALLOC_CTX * mem_ctx , uint8_t * * buf )
{
struct tdb_fetch_talloc_state state = { . mem_ctx = mem_ctx } ;
int ret ;
ret = tdb_parse_record ( tdb , key , tdb_fetch_talloc_parser , & state ) ;
if ( ret = = - 1 ) {
enum TDB_ERROR err = tdb_error ( tdb ) ;
return map_unix_error_from_tdb ( err ) ;
}
if ( state . buf = = NULL ) {
return ENOMEM ;
}
* buf = state . buf ;
return 0 ;
}