2005-02-12 14:33:42 +03:00
/*
Unix SMB / CIFS implementation .
WINS database routines
Copyright ( C ) Andrew Tridgell 2005
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 .
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 , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
# include "nbt_server/nbt_server.h"
2005-02-19 02:53:52 +03:00
# include "nbt_server/wins/winsdb.h"
2005-02-12 14:33:42 +03:00
# include "lib/ldb/include/ldb.h"
2005-09-24 19:42:15 +04:00
# include "lib/ldb/include/ldb_errors.h"
2005-02-12 14:33:42 +03:00
# include "db_wrap.h"
2005-02-14 08:00:22 +03:00
# include "system/time.h"
2005-02-12 14:33:42 +03:00
2005-02-16 18:19:49 +03:00
/*
2005-10-14 16:47:57 +04:00
return the new maxVersion and save it
2005-02-16 18:19:49 +03:00
*/
2005-10-14 16:47:57 +04:00
static uint64_t winsdb_allocate_version ( struct wins_server * winssrv )
2005-02-16 18:19:49 +03:00
{
2005-10-14 16:47:57 +04:00
int ret ;
2005-02-27 14:35:47 +03:00
struct ldb_context * ldb = winssrv - > wins_db ;
2005-10-14 16:47:57 +04:00
struct ldb_dn * dn ;
struct ldb_message * * res = NULL ;
struct ldb_message * msg = NULL ;
TALLOC_CTX * tmp_ctx = talloc_new ( winssrv ) ;
uint64_t maxVersion = 0 ;
2005-02-16 18:19:49 +03:00
2005-10-14 16:47:57 +04:00
dn = ldb_dn_explode ( tmp_ctx , " CN=VERSION " ) ;
if ( ! dn ) goto failed ;
2005-02-16 18:19:49 +03:00
2005-10-12 10:10:23 +04:00
ret | = ldb_msg_add_string ( msg , " objectClass " , " winsEntry " ) ;
ret | = ldb_msg_add_fmt ( msg , " minVersion " , " %llu " , winssrv - > min_version ) ;
ret | = ldb_msg_add_fmt ( msg , " maxVersion " , " %llu " , winssrv - > max_version ) ;
2005-02-16 18:19:49 +03:00
if ( ret ! = 0 ) goto failed ;
2005-10-14 16:47:57 +04:00
if ( ret = = 1 ) {
maxVersion = ldb_msg_find_uint64 ( res [ 0 ] , " maxVersion " , 0 ) ;
2005-02-16 18:19:49 +03:00
}
2005-10-14 16:47:57 +04:00
maxVersion + + ;
msg = ldb_msg_new ( tmp_ctx ) ;
if ( ! msg ) goto failed ;
msg - > dn = dn ;
ret = ldb_msg_add_empty ( ldb , msg , " maxVersion " , LDB_FLAG_MOD_REPLACE ) ;
if ( ret ! = 0 ) goto failed ;
ret = ldb_msg_add_fmt ( ldb , msg , " maxVersion " , " %llu " , maxVersion ) ;
if ( ret ! = 0 ) goto failed ;
2005-02-16 18:19:49 +03:00
ret = ldb_modify ( ldb , msg ) ;
if ( ret ! = 0 ) ret = ldb_add ( ldb , msg ) ;
if ( ret ! = 0 ) goto failed ;
2005-10-14 16:47:57 +04:00
talloc_free ( tmp_ctx ) ;
return maxVersion ;
2005-02-16 18:19:49 +03:00
failed :
2005-10-14 16:47:57 +04:00
talloc_free ( tmp_ctx ) ;
return 0 ;
2005-02-16 18:19:49 +03:00
}
/*
2005-10-14 16:51:36 +04:00
return a DN for a nbt_name
2005-02-16 18:19:49 +03:00
*/
2005-10-14 16:51:36 +04:00
static struct ldb_dn * winsdb_dn ( TALLOC_CTX * mem_ctx , struct nbt_name * name )
2005-02-16 18:19:49 +03:00
{
2005-10-14 16:51:36 +04:00
struct ldb_dn * dn ;
2005-10-14 16:55:59 +04:00
dn = ldb_dn_string_compose ( mem_ctx , NULL , " type=0x%02X " , name - > type ) ;
2005-10-14 16:51:36 +04:00
if ( dn & & name - > name & & * name - > name ) {
dn = ldb_dn_string_compose ( mem_ctx , dn , " name=%s " , name - > name ) ;
}
if ( dn & & name - > scope & & * name - > scope ) {
dn = ldb_dn_string_compose ( mem_ctx , dn , " scope=%s " , name - > scope ) ;
2005-02-16 18:19:49 +03:00
}
2005-10-14 16:51:36 +04:00
return dn ;
2005-02-16 18:19:49 +03:00
}
2005-10-14 16:55:59 +04:00
static NTSTATUS winsdb_nbt_name ( TALLOC_CTX * mem_ctx , struct ldb_dn * dn , struct nbt_name * * _name )
2005-10-14 16:54:26 +04:00
{
2005-10-14 16:55:59 +04:00
NTSTATUS status ;
2005-10-14 16:54:26 +04:00
struct nbt_name * name ;
uint32_t cur = 0 ;
name = talloc ( mem_ctx , struct nbt_name ) ;
2005-10-14 16:55:59 +04:00
if ( ! name ) {
status = NT_STATUS_NO_MEMORY ;
goto failed ;
}
2005-10-14 16:54:26 +04:00
if ( dn - > comp_num > 3 ) {
2005-10-14 16:55:59 +04:00
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
2005-10-14 16:54:26 +04:00
goto failed ;
}
if ( dn - > comp_num > cur & & strcasecmp ( " scope " , dn - > components [ cur ] . name ) = = 0 ) {
name - > scope = talloc_steal ( name , dn - > components [ cur ] . value . data ) ;
cur + + ;
} else {
name - > scope = NULL ;
}
if ( dn - > comp_num > cur & & strcasecmp ( " name " , dn - > components [ cur ] . name ) = = 0 ) {
name - > name = talloc_steal ( name , dn - > components [ cur ] . value . data ) ;
cur + + ;
} else {
name - > name = talloc_strdup ( name , " " ) ;
2005-10-14 16:55:59 +04:00
if ( ! name - > name ) {
status = NT_STATUS_NO_MEMORY ;
goto failed ;
}
2005-10-14 16:54:26 +04:00
}
if ( dn - > comp_num > cur & & strcasecmp ( " type " , dn - > components [ cur ] . name ) = = 0 ) {
2005-10-14 16:55:59 +04:00
name - > type = strtoul ( ( char * ) dn - > components [ cur ] . value . data , NULL , 0 ) ;
2005-10-14 16:54:26 +04:00
cur + + ;
} else {
2005-10-14 16:55:59 +04:00
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
2005-10-14 16:54:26 +04:00
goto failed ;
}
2005-10-14 16:55:59 +04:00
* _name = name ;
return NT_STATUS_OK ;
2005-10-14 16:54:26 +04:00
failed :
talloc_free ( name ) ;
2005-10-14 16:55:59 +04:00
return status ;
2005-10-14 16:54:26 +04:00
}
2005-02-16 18:19:49 +03:00
/*
2005-10-14 16:51:36 +04:00
decode the winsdb_addr ( " address " ) attribute :
" 172.31.1.1 " or
2005-10-14 16:55:59 +04:00
" 172.31.1.1;winsOwner:172.31.9.202;expireTime:20050923032330.0Z; "
2005-10-14 16:51:36 +04:00
are valid records
2005-02-16 18:19:49 +03:00
*/
2005-09-24 19:42:15 +04:00
static BOOL winsdb_remove_version ( struct wins_server * winssrv , uint64_t version )
2005-02-16 18:19:49 +03:00
{
if ( version = = winssrv - > min_version ) {
winssrv - > min_version + + ;
2005-09-24 19:42:15 +04:00
return winsdb_save_version ( winssrv ) ;
2005-02-16 18:19:49 +03:00
}
2005-09-24 19:42:15 +04:00
return True ;
2005-02-16 18:19:49 +03:00
}
2005-07-24 16:18:11 +04:00
/*
2005-10-14 16:51:36 +04:00
encode the winsdb_addr ( " address " ) attribute like this :
" 172.31.1.1;winsOwner:172.31.9.202;expireTime:20050923032330.0Z "
2005-07-24 16:18:11 +04:00
*/
2005-10-14 16:51:36 +04:00
static int ldb_msg_add_winsdb_addr ( struct ldb_context * ldb , struct ldb_message * msg ,
const char * attr_name , struct winsdb_addr * addr )
2005-07-24 16:18:11 +04:00
{
2005-10-14 16:51:36 +04:00
struct ldb_val val ;
const char * str ;
2005-09-16 07:18:49 +04:00
dn = ldb_dn_string_compose ( mem_ctx , NULL , " type=%02x " , name - > type ) ;
2005-10-14 16:51:36 +04:00
addresses [ len ] - > address = talloc_strdup ( addresses [ len ] , address ) ;
if ( ! addresses [ len ] - > address ) {
talloc_free ( addresses ) ;
return NULL ;
2005-07-24 16:18:11 +04:00
}
2005-10-14 16:51:36 +04:00
addresses [ len ] - > wins_owner = talloc_strdup ( addresses [ len ] , wins_owner ) ;
if ( ! addresses [ len ] - > wins_owner ) {
talloc_free ( addresses ) ;
return NULL ;
2005-07-24 16:18:11 +04:00
}
2005-10-14 16:51:36 +04:00
addresses [ len ] - > expire_time = expire_time ;
addresses [ len + 1 ] = NULL ;
return addresses ;
}
void winsdb_addr_list_remove ( struct winsdb_addr * * addresses , const char * address )
{
size_t i ;
for ( i = 0 ; addresses [ i ] ; i + + ) {
if ( strcmp ( addresses [ i ] - > address , address ) = = 0 ) {
break ;
}
}
if ( ! addresses [ i ] ) return ;
for ( ; addresses [ i ] ; i + + ) {
addresses [ i ] = addresses [ i + 1 ] ;
}
return ;
}
struct winsdb_addr * winsdb_addr_list_check ( struct winsdb_addr * * addresses , const char * address )
{
size_t i ;
for ( i = 0 ; addresses [ i ] ; i + + ) {
if ( strcmp ( addresses [ i ] - > address , address ) = = 0 ) {
return addresses [ i ] ;
}
}
return NULL ;
}
size_t winsdb_addr_list_length ( struct winsdb_addr * * addresses )
{
size_t i ;
for ( i = 0 ; addresses [ i ] ; i + + ) ;
return i ;
}
const char * * winsdb_addr_string_list ( TALLOC_CTX * mem_ctx , struct winsdb_addr * * addresses )
{
size_t len = winsdb_addr_list_length ( addresses ) ;
const char * * str_list ;
size_t i ;
str_list = talloc_array ( mem_ctx , const char * , len + 1 ) ;
if ( ! str_list ) return NULL ;
for ( i = 0 ; i < len ; i + + ) {
str_list [ i ] = talloc_strdup ( str_list , addresses [ i ] - > address ) ;
if ( ! str_list [ i ] ) {
talloc_free ( str_list ) ;
return NULL ;
}
}
str_list [ len ] = NULL ;
return str_list ;
2005-07-24 16:18:11 +04:00
}
2005-10-14 16:50:11 +04:00
/*
decode the winsdb_addr ( " address " ) attribute :
" 172.31.1.1 " or
" 172.31.1.1;winsOwner:172.31.9.202;expireTime:20050923032330.0Z "
are valid records
*/
static struct winsdb_addr * winsdb_addr_decode ( struct winsdb_record * rec , TALLOC_CTX * mem_ctx , struct ldb_val * val )
2005-10-14 16:49:36 +04:00
{
2005-10-14 16:55:59 +04:00
NTSTATUS status ;
2005-10-14 16:49:55 +04:00
struct winsdb_addr * addr ;
2005-10-14 16:50:11 +04:00
char * address ;
char * wins_owner ;
char * expire_time ;
char * p ;
2005-10-14 16:49:55 +04:00
addr = talloc ( mem_ctx , struct winsdb_addr ) ;
2005-10-14 16:55:59 +04:00
if ( ! addr ) {
status = NT_STATUS_NO_MEMORY ;
goto failed ;
}
2005-10-14 16:49:55 +04:00
2005-10-14 16:50:11 +04:00
address = ( char * ) val - > data ;
p = strchr ( address , ' ; ' ) ;
if ( ! p ) {
/* support old entries, with only the address */
addr - > address = talloc_steal ( addr , val - > data ) ;
addr - > wins_owner = rec - > wins_owner ;
addr - > expire_time = rec - > expire_time ;
2005-10-14 16:55:59 +04:00
* _addr = addr ;
return NT_STATUS_OK ;
2005-10-14 16:50:11 +04:00
}
* p = ' \0 ' ; p + + ;
addr - > address = talloc_strdup ( addr , address ) ;
if ( ! addr - > address ) {
2005-10-14 16:55:59 +04:00
status = NT_STATUS_NO_MEMORY ;
goto failed ;
2005-10-14 16:50:11 +04:00
}
if ( strncmp ( " winsOwner: " , p , 10 ) ! = 0 ) {
2005-10-14 16:55:59 +04:00
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto failed ;
2005-10-14 16:50:11 +04:00
}
wins_owner = p + 10 ;
p = strchr ( wins_owner , ' ; ' ) ;
if ( ! p ) {
2005-10-14 16:55:59 +04:00
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto failed ;
2005-10-14 16:50:11 +04:00
}
* p = ' \0 ' ; p + + ;
addr - > wins_owner = talloc_strdup ( addr , wins_owner ) ;
if ( ! addr - > wins_owner ) {
2005-10-14 16:55:59 +04:00
status = NT_STATUS_NO_MEMORY ;
goto failed ;
2005-10-14 16:50:11 +04:00
}
if ( strncmp ( " expireTime: " , p , 11 ) ! = 0 ) {
2005-10-14 16:55:59 +04:00
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto failed ;
2005-10-14 16:50:11 +04:00
}
expire_time = p + 11 ;
2005-10-14 16:55:59 +04:00
p = strchr ( expire_time , ' ; ' ) ;
if ( ! p ) {
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto failed ;
}
2005-10-14 16:50:11 +04:00
2005-10-14 16:55:59 +04:00
* p = ' \0 ' ; p + + ;
2005-10-14 16:50:11 +04:00
addr - > expire_time = ldap_string_to_time ( expire_time ) ;
2005-10-14 16:49:55 +04:00
2005-10-14 16:55:59 +04:00
* _addr = addr ;
return NT_STATUS_OK ;
failed :
talloc_free ( addr ) ;
return status ;
2005-10-14 16:49:36 +04:00
}
2005-10-14 16:50:11 +04:00
/*
encode the winsdb_addr ( " address " ) attribute like this :
2005-10-14 16:55:59 +04:00
" 172.31.1.1;winsOwner:172.31.9.202;expireTime:20050923032330.0Z; "
2005-10-14 16:50:11 +04:00
*/
2005-10-14 16:49:36 +04:00
static int ldb_msg_add_winsdb_addr ( struct ldb_context * ldb , struct ldb_message * msg ,
2005-10-14 16:49:55 +04:00
const char * attr_name , struct winsdb_addr * addr )
2005-10-14 16:49:36 +04:00
{
struct ldb_val val ;
2005-10-14 16:50:11 +04:00
const char * str ;
2005-10-14 16:55:59 +04:00
str = talloc_asprintf ( msg , " %s;winsOwner:%s;expireTime:%s; " ,
2005-10-14 16:50:11 +04:00
addr - > address , addr - > wins_owner ,
ldap_timestring ( msg , addr - > expire_time ) ) ;
if ( ! str ) return - 1 ;
2005-10-14 16:49:36 +04:00
2005-10-14 16:50:11 +04:00
val . data = discard_const_p ( uint8_t , str ) ;
val . length = strlen ( str ) ;
2005-10-14 16:49:36 +04:00
return ldb_msg_add_value ( ldb , msg , attr_name , & val ) ;
}
2005-10-14 16:49:55 +04:00
struct winsdb_addr * * winsdb_addr_list_make ( TALLOC_CTX * mem_ctx )
{
struct winsdb_addr * * addresses ;
addresses = talloc_array ( mem_ctx , struct winsdb_addr * , 1 ) ;
if ( ! addresses ) return NULL ;
addresses [ 0 ] = NULL ;
return addresses ;
}
2005-10-14 16:50:11 +04:00
struct winsdb_addr * * winsdb_addr_list_add ( struct winsdb_addr * * addresses , const char * address ,
const char * wins_owner , time_t expire_time )
2005-10-14 16:49:55 +04:00
{
size_t len = winsdb_addr_list_length ( addresses ) ;
addresses = talloc_realloc ( addresses , addresses , struct winsdb_addr * , len + 2 ) ;
if ( ! addresses ) return NULL ;
addresses [ len ] = talloc ( addresses , struct winsdb_addr ) ;
if ( ! addresses [ len ] ) {
talloc_free ( addresses ) ;
return NULL ;
}
addresses [ len ] - > address = talloc_strdup ( addresses [ len ] , address ) ;
if ( ! addresses [ len ] - > address ) {
talloc_free ( addresses ) ;
2005-10-14 16:50:11 +04:00
return NULL ;
2005-10-14 16:49:55 +04:00
}
2005-10-14 16:50:11 +04:00
addresses [ len ] - > wins_owner = talloc_strdup ( addresses [ len ] , wins_owner ) ;
if ( ! addresses [ len ] - > wins_owner ) {
talloc_free ( addresses ) ;
return NULL ;
}
addresses [ len ] - > expire_time = expire_time ;
2005-10-14 16:49:55 +04:00
addresses [ len + 1 ] = NULL ;
return addresses ;
}
void winsdb_addr_list_remove ( struct winsdb_addr * * addresses , const char * address )
{
size_t i ;
for ( i = 0 ; addresses [ i ] ; i + + ) {
if ( strcmp ( addresses [ i ] - > address , address ) = = 0 ) {
break ;
}
}
if ( ! addresses [ i ] ) return ;
for ( ; addresses [ i ] ; i + + ) {
addresses [ i ] = addresses [ i + 1 ] ;
}
return ;
}
struct winsdb_addr * winsdb_addr_list_check ( struct winsdb_addr * * addresses , const char * address )
{
size_t i ;
for ( i = 0 ; addresses [ i ] ; i + + ) {
if ( strcmp ( addresses [ i ] - > address , address ) = = 0 ) {
return addresses [ i ] ;
}
}
return NULL ;
}
size_t winsdb_addr_list_length ( struct winsdb_addr * * addresses )
{
size_t i ;
for ( i = 0 ; addresses [ i ] ; i + + ) ;
return i ;
}
const char * * winsdb_addr_string_list ( TALLOC_CTX * mem_ctx , struct winsdb_addr * * addresses )
{
size_t len = winsdb_addr_list_length ( addresses ) ;
const char * * str_list ;
size_t i ;
str_list = talloc_array ( mem_ctx , const char * , len + 1 ) ;
if ( ! str_list ) return NULL ;
for ( i = 0 ; i < len ; i + + ) {
str_list [ i ] = talloc_strdup ( str_list , addresses [ i ] - > address ) ;
if ( ! str_list [ i ] ) {
talloc_free ( str_list ) ;
return NULL ;
}
}
str_list [ len ] = NULL ;
return str_list ;
}
2005-02-12 14:33:42 +03:00
/*
load a WINS entry from the database
*/
2005-10-14 16:55:59 +04:00
NTSTATUS winsdb_lookup ( struct ldb_context * wins_db ,
struct nbt_name * name ,
TALLOC_CTX * mem_ctx ,
struct winsdb_record * * _rec )
2005-02-12 14:33:42 +03:00
{
2005-10-14 16:55:59 +04:00
NTSTATUS status ;
2005-02-12 14:33:42 +03:00
struct ldb_message * * res = NULL ;
int ret ;
struct winsdb_record * rec ;
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
/* find the record in the WINS database */
2005-10-14 16:55:59 +04:00
ret = ldb_search ( wins_db , winsdb_dn ( tmp_ctx , name ) , LDB_SCOPE_BASE ,
2005-09-16 07:18:49 +04:00
NULL , NULL , & res ) ;
2005-02-12 14:33:42 +03:00
if ( res ! = NULL ) {
talloc_steal ( tmp_ctx , res ) ;
}
2005-10-14 16:55:59 +04:00
if ( ret = = 0 ) {
status = NT_STATUS_OBJECT_NAME_NOT_FOUND ;
goto failed ;
} else if ( ret ! = 1 ) {
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto failed ;
}
2005-02-12 14:33:42 +03:00
2005-10-14 16:55:59 +04:00
status = winsdb_record ( res [ 0 ] , name , tmp_ctx , & rec ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) goto failed ;
2005-10-14 16:53:50 +04:00
/* see if it has already expired */
if ( rec - > state = = WINS_REC_ACTIVE & &
rec - > expire_time < = time ( NULL ) ) {
DEBUG ( 5 , ( " WINS: expiring name %s (expired at %s) \n " ,
nbt_name_string ( tmp_ctx , rec - > name ) , timestring ( tmp_ctx , rec - > expire_time ) ) ) ;
rec - > state = WINS_REC_RELEASED ;
}
talloc_steal ( mem_ctx , rec ) ;
talloc_free ( tmp_ctx ) ;
2005-10-14 16:55:59 +04:00
* _rec = rec ;
return NT_STATUS_OK ;
2005-10-14 16:53:50 +04:00
failed :
talloc_free ( tmp_ctx ) ;
2005-10-14 16:55:59 +04:00
return status ;
2005-10-14 16:53:50 +04:00
}
2005-10-14 16:55:59 +04:00
NTSTATUS winsdb_record ( struct ldb_message * msg , struct nbt_name * name , TALLOC_CTX * mem_ctx , struct winsdb_record * * _rec )
2005-10-14 16:53:50 +04:00
{
2005-10-14 16:55:59 +04:00
NTSTATUS status ;
2005-10-14 16:53:50 +04:00
struct winsdb_record * rec ;
struct ldb_message_element * el ;
uint32_t i ;
rec = talloc ( mem_ctx , struct winsdb_record ) ;
2005-10-14 16:55:59 +04:00
if ( rec = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
goto failed ;
}
if ( ! name ) {
status = winsdb_nbt_name ( rec , msg - > dn , & name ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) goto failed ;
}
2005-02-12 14:33:42 +03:00
/* parse it into a more convenient winsdb_record structure */
rec - > name = name ;
rec - > state = ldb_msg_find_int ( res [ 0 ] , " active " , WINS_REC_RELEASED ) ;
rec - > nb_flags = ldb_msg_find_int ( res [ 0 ] , " nbFlags " , 0 ) ;
2005-10-12 10:30:47 +04:00
rec - > expire_time = ldb_string_to_time ( ldb_msg_find_string ( res [ 0 ] , " expires " , NULL ) ) ;
2005-02-12 14:33:42 +03:00
rec - > registered_by = ldb_msg_find_string ( res [ 0 ] , " registeredBy " , NULL ) ;
2005-02-16 18:19:49 +03:00
rec - > version = ldb_msg_find_uint64 ( res [ 0 ] , " version " , 0 ) ;
2005-10-14 16:50:11 +04:00
talloc_steal ( rec , rec - > wins_owner ) ;
2005-02-12 14:33:42 +03:00
talloc_steal ( rec , rec - > registered_by ) ;
2005-10-14 16:50:11 +04:00
if ( ! rec - > wins_owner ) rec - > wins_owner = WINSDB_OWNER_LOCAL ;
2005-10-14 16:53:50 +04:00
el = ldb_msg_find_element ( msg , " address " ) ;
2005-10-14 16:55:59 +04:00
if ( el = = NULL ) {
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto failed ;
}
2005-02-12 14:33:42 +03:00
2005-10-14 16:49:55 +04:00
rec - > addresses = talloc_array ( rec , struct winsdb_addr * , el - > num_values + 1 ) ;
2005-10-14 16:55:59 +04:00
if ( rec - > addresses = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
goto failed ;
}
2005-02-12 14:33:42 +03:00
for ( i = 0 ; i < el - > num_values ; i + + ) {
2005-10-14 16:55:59 +04:00
status = winsdb_addr_decode ( rec , & el - > values [ i ] , rec - > addresses , & rec - > addresses [ i ] ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) goto failed ;
2005-02-12 14:33:42 +03:00
}
rec - > addresses [ i ] = NULL ;
2005-10-14 16:55:59 +04:00
* _rec = rec ;
return NT_STATUS_OK ;
2005-02-12 14:33:42 +03:00
failed :
2005-10-14 16:55:59 +04:00
if ( NT_STATUS_EQUAL ( NT_STATUS_INTERNAL_DB_CORRUPTION , status ) ) {
DEBUG ( 1 , ( " winsdb_record: corrupted record: %s \n " , ldb_dn_linearize ( rec , msg - > dn ) ) ) ;
}
2005-10-14 16:53:50 +04:00
talloc_free ( rec ) ;
2005-10-14 16:55:59 +04:00
return status ;
2005-02-12 14:33:42 +03:00
}
/*
form a ldb_message from a winsdb_record
*/
2005-10-14 16:53:50 +04:00
struct ldb_message * winsdb_message ( struct ldb_context * ldb ,
struct winsdb_record * rec , TALLOC_CTX * mem_ctx )
2005-02-12 14:33:42 +03:00
{
int i , ret = 0 ;
struct ldb_message * msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) goto failed ;
2005-09-16 07:18:49 +04:00
msg - > dn = winsdb_dn ( msg , rec - > name ) ;
2005-02-12 14:33:42 +03:00
if ( msg - > dn = = NULL ) goto failed ;
2005-10-12 10:10:23 +04:00
ret | = ldb_msg_add_fmt ( msg , " objectClass " , " wins " ) ;
ret | = ldb_msg_add_fmt ( msg , " active " , " %u " , rec - > state ) ;
ret | = ldb_msg_add_fmt ( msg , " nbFlags " , " 0x%04x " , rec - > nb_flags ) ;
ret | = ldb_msg_add_string ( msg , " registeredBy " , rec - > registered_by ) ;
ret | = ldb_msg_add_string ( msg , " expires " ,
2005-10-12 10:30:47 +04:00
ldb_timestring ( msg , rec - > expire_time ) ) ;
2005-10-12 10:10:23 +04:00
ret | = ldb_msg_add_fmt ( msg , " version " , " %llu " , rec - > version ) ;
2005-02-12 14:33:42 +03:00
for ( i = 0 ; rec - > addresses [ i ] ; i + + ) {
2005-10-12 10:10:23 +04:00
ret | = ldb_msg_add_string ( msg , " address " , rec - > addresses [ i ] ) ;
2005-02-12 14:33:42 +03:00
}
if ( ret ! = 0 ) goto failed ;
return msg ;
failed :
talloc_free ( msg ) ;
return NULL ;
}
/*
save a WINS record into the database
*/
uint8_t winsdb_add ( struct wins_server * winssrv , struct winsdb_record * rec )
{
2005-02-27 14:35:47 +03:00
struct ldb_context * ldb = winssrv - > wins_db ;
2005-02-12 14:33:42 +03:00
struct ldb_message * msg ;
TALLOC_CTX * tmp_ctx = talloc_new ( winssrv ) ;
2005-09-24 19:42:15 +04:00
int trans = - 1 ;
int ret = 0 ;
trans = ldb_transaction_start ( ldb ) ;
if ( trans ! = LDB_SUCCESS ) goto failed ;
2005-02-12 14:33:42 +03:00
2005-02-16 18:19:49 +03:00
rec - > version = winsdb_allocate_version ( winssrv ) ;
if ( rec - > version = = 0 ) goto failed ;
2005-10-14 16:53:50 +04:00
msg = winsdb_message ( winssrv - > wins_db , rec , tmp_ctx ) ;
2005-02-12 14:33:42 +03:00
if ( msg = = NULL ) goto failed ;
ret = ldb_add ( ldb , msg ) ;
if ( ret ! = 0 ) goto failed ;
2005-09-24 19:42:15 +04:00
trans = ldb_transaction_commit ( ldb ) ;
if ( trans ! = LDB_SUCCESS ) goto failed ;
2005-02-12 14:33:42 +03:00
talloc_free ( tmp_ctx ) ;
return NBT_RCODE_OK ;
failed :
2005-09-24 19:42:15 +04:00
if ( trans = = LDB_SUCCESS ) ldb_transaction_cancel ( ldb ) ;
2005-02-12 14:33:42 +03:00
talloc_free ( tmp_ctx ) ;
return NBT_RCODE_SVR ;
}
/*
modify a WINS record in the database
*/
uint8_t winsdb_modify ( struct wins_server * winssrv , struct winsdb_record * rec )
{
2005-02-27 14:35:47 +03:00
struct ldb_context * ldb = winssrv - > wins_db ;
2005-02-12 14:33:42 +03:00
struct ldb_message * msg ;
TALLOC_CTX * tmp_ctx = talloc_new ( winssrv ) ;
2005-09-24 19:42:15 +04:00
int trans ;
2005-02-12 14:33:42 +03:00
int ret ;
int i ;
2005-09-24 19:42:15 +04:00
trans = ldb_transaction_start ( ldb ) ;
if ( trans ! = LDB_SUCCESS ) goto failed ;
2005-02-16 18:19:49 +03:00
rec - > version = winsdb_allocate_version ( winssrv ) ;
if ( rec - > version = = 0 ) goto failed ;
2005-10-14 16:50:11 +04:00
rec - > wins_owner = WINSDB_OWNER_LOCAL ;
2005-02-16 18:19:49 +03:00
2005-10-14 16:53:50 +04:00
msg = winsdb_message ( winssrv - > wins_db , rec , tmp_ctx ) ;
2005-02-12 14:33:42 +03:00
if ( msg = = NULL ) goto failed ;
for ( i = 0 ; i < msg - > num_elements ; i + + ) {
msg - > elements [ i ] . flags = LDB_FLAG_MOD_REPLACE ;
}
ret = ldb_modify ( ldb , msg ) ;
if ( ret ! = 0 ) goto failed ;
2005-09-24 19:42:15 +04:00
trans = ldb_transaction_commit ( ldb ) ;
if ( trans ! = LDB_SUCCESS ) goto failed ;
2005-02-12 14:33:42 +03:00
talloc_free ( tmp_ctx ) ;
return NBT_RCODE_OK ;
failed :
2005-09-24 19:42:15 +04:00
if ( trans = = LDB_SUCCESS ) ldb_transaction_cancel ( ldb ) ;
2005-02-12 14:33:42 +03:00
talloc_free ( tmp_ctx ) ;
return NBT_RCODE_SVR ;
}
2005-02-14 08:00:22 +03:00
/*
delete a WINS record from the database
*/
2005-02-16 18:19:49 +03:00
uint8_t winsdb_delete ( struct wins_server * winssrv , struct winsdb_record * rec )
2005-02-14 08:00:22 +03:00
{
2005-02-27 14:35:47 +03:00
struct ldb_context * ldb = winssrv - > wins_db ;
2005-02-14 08:00:22 +03:00
TALLOC_CTX * tmp_ctx = talloc_new ( winssrv ) ;
2005-08-18 19:02:01 +04:00
const struct ldb_dn * dn ;
2005-09-24 19:42:15 +04:00
int trans ;
int ret ;
trans = ldb_transaction_start ( ldb ) ;
if ( trans ! = LDB_SUCCESS ) goto failed ;
2005-02-14 08:00:22 +03:00
2005-09-24 19:42:15 +04:00
if ( ! winsdb_remove_version ( winssrv , rec - > version ) )
goto failed ;
2005-02-16 18:19:49 +03:00
2005-09-16 07:18:49 +04:00
dn = winsdb_dn ( tmp_ctx , rec - > name ) ;
2005-02-14 08:00:22 +03:00
if ( dn = = NULL ) goto failed ;
ret = ldb_delete ( ldb , dn ) ;
if ( ret ! = 0 ) goto failed ;
2005-09-24 19:42:15 +04:00
trans = ldb_transaction_commit ( ldb ) ;
if ( trans ! = LDB_SUCCESS ) goto failed ;
2005-02-14 08:00:22 +03:00
talloc_free ( tmp_ctx ) ;
return NBT_RCODE_OK ;
failed :
2005-09-24 19:42:15 +04:00
if ( trans = = LDB_SUCCESS ) ldb_transaction_cancel ( ldb ) ;
2005-02-14 08:00:22 +03:00
talloc_free ( tmp_ctx ) ;
return NBT_RCODE_SVR ;
}
2005-10-14 16:47:57 +04:00
struct ldb_context * winsdb_connect ( TALLOC_CTX * mem_ctx )
2005-02-12 14:33:42 +03:00
{
2005-10-14 16:47:57 +04:00
return ldb_wrap_connect ( mem_ctx , lp_wins_url ( ) , 0 , NULL ) ;
2005-02-12 14:33:42 +03:00
}