2005-12-22 14:40:14 +03:00
/*
Unix SMB / CIFS implementation .
WINS Replication server
Copyright ( C ) Stefan Metzmacher 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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-12-22 14:40:14 +03:00
( 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
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-12-22 14:40:14 +03:00
*/
# include "includes.h"
# include "librpc/gen_ndr/ndr_winsrepl.h"
# include "wrepl_server/wrepl_server.h"
# include "nbt_server/wins/winsdb.h"
2011-02-10 06:12:51 +03:00
# include <ldb.h>
# include <ldb_errors.h>
2005-12-22 14:40:14 +03:00
# include "system/time.h"
2020-11-20 17:27:17 +03:00
# include "samba/service_task.h"
2006-01-09 02:32:15 +03:00
# include "lib/messaging/irpc.h"
2010-09-03 15:18:14 +04:00
# include "librpc/gen_ndr/ndr_irpc_c.h"
2006-03-16 03:23:11 +03:00
# include "librpc/gen_ndr/ndr_nbt.h"
2008-03-25 19:35:33 +03:00
# include "param/param.h"
2005-12-22 14:40:14 +03:00
2006-01-02 21:25:30 +03:00
const char * wreplsrv_owner_filter ( struct wreplsrv_service * service ,
TALLOC_CTX * mem_ctx ,
const char * wins_owner )
{
if ( strcmp ( wins_owner , service - > wins_db - > local_owner ) = = 0 ) {
return talloc_asprintf ( mem_ctx , " (|(winsOwner=%s)(winsOwner=0.0.0.0)) " ,
wins_owner ) ;
}
return talloc_asprintf ( mem_ctx , " (&(winsOwner=%s)(!(winsOwner=0.0.0.0))) " ,
wins_owner ) ;
}
2005-12-22 14:40:14 +03:00
static NTSTATUS wreplsrv_scavenging_owned_records ( struct wreplsrv_service * service , TALLOC_CTX * tmp_mem )
{
NTSTATUS status ;
struct winsdb_record * rec = NULL ;
struct ldb_result * res = NULL ;
2006-01-02 21:25:30 +03:00
const char * owner_filter ;
2005-12-22 14:40:14 +03:00
const char * filter ;
2009-11-07 23:15:17 +03:00
unsigned int i ;
2005-12-22 14:40:14 +03:00
int ret ;
time_t now = time ( NULL ) ;
const char * now_timestr ;
const char * action ;
2006-09-09 14:05:58 +04:00
const char * old_state = NULL ;
const char * new_state = NULL ;
2005-12-22 14:40:14 +03:00
uint32_t modify_flags ;
2007-10-07 01:48:28 +04:00
bool modify_record ;
bool delete_record ;
bool delete_tombstones ;
2005-12-22 14:40:14 +03:00
struct timeval tombstone_extra_time ;
2008-03-25 19:35:33 +03:00
const char * local_owner = service - > wins_db - > local_owner ;
2010-07-16 08:32:42 +04:00
bool propagate = lpcfg_parm_bool ( service - > task - > lp_ctx , NULL , " wreplsrv " , " propagate name releases " , false ) ;
2005-12-22 14:40:14 +03:00
now_timestr = ldb_timestring ( tmp_mem , now ) ;
NT_STATUS_HAVE_NO_MEMORY ( now_timestr ) ;
2008-03-25 19:35:33 +03:00
owner_filter = wreplsrv_owner_filter ( service , tmp_mem , local_owner ) ;
2006-01-02 21:25:30 +03:00
NT_STATUS_HAVE_NO_MEMORY ( owner_filter ) ;
2005-12-22 14:40:14 +03:00
filter = talloc_asprintf ( tmp_mem ,
2006-01-02 21:25:30 +03:00
" (&%s(objectClass=winsRecord) "
2006-01-23 19:04:27 +03:00
" (expireTime<=%s)) " ,
2006-01-02 21:25:30 +03:00
owner_filter , now_timestr ) ;
2005-12-22 14:40:14 +03:00
NT_STATUS_HAVE_NO_MEMORY ( filter ) ;
2008-09-23 22:30:06 +04:00
ret = ldb_search ( service - > wins_db - > ldb , tmp_mem , & res , NULL , LDB_SCOPE_SUBTREE , NULL , " %s " , filter ) ;
2005-12-22 14:40:14 +03:00
if ( ret ! = LDB_SUCCESS ) return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2006-01-02 21:25:30 +03:00
DEBUG ( 10 , ( " WINS scavenging: filter '%s' count %d \n " , filter , res - > count ) ) ;
2005-12-22 14:40:14 +03:00
tombstone_extra_time = timeval_add ( & service - > startup_time ,
service - > config . tombstone_extra_timeout ,
0 ) ;
delete_tombstones = timeval_expired ( & tombstone_extra_time ) ;
for ( i = 0 ; i < res - > count ; i + + ) {
2008-03-25 19:35:33 +03:00
bool has_replicas = false ;
2006-01-21 11:53:56 +03:00
/*
* we pass ' 0 ' as ' now ' here ,
* because we want to get the raw timestamps which are in the DB
*/
status = winsdb_record ( service - > wins_db , res - > msgs [ i ] , tmp_mem , 0 , & rec ) ;
2005-12-22 14:40:14 +03:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2006-01-08 21:25:40 +03:00
talloc_free ( res - > msgs [ i ] ) ;
2005-12-22 14:40:14 +03:00
modify_flags = 0 ;
2007-10-07 01:48:28 +04:00
modify_record = false ;
delete_record = false ;
2005-12-22 14:40:14 +03:00
switch ( rec - > state ) {
case WREPL_STATE_ACTIVE :
old_state = " active " ;
2008-03-25 18:44:46 +03:00
if ( rec - > is_static ) {
/*
* we store it again , so that it won ' t appear
* in the scavenging the next time
*/
old_state = " active(static) " ;
new_state = " active(static) " ;
modify_flags = 0 ;
modify_record = true ;
break ;
2006-01-23 19:04:27 +03:00
}
2008-03-25 19:35:33 +03:00
if ( rec - > type ! = WREPL_TYPE_SGROUP | | ! propagate ) {
new_state = " released " ;
rec - > state = WREPL_STATE_RELEASED ;
rec - > expire_time = service - > config . tombstone_interval + now ;
modify_flags = 0 ;
modify_record = true ;
break ;
}
/* check if there's any replica address */
for ( i = 0 ; rec - > addresses [ i ] ; i + + ) {
if ( strcmp ( rec - > addresses [ i ] - > wins_owner , local_owner ) ! = 0 ) {
has_replicas = true ;
rec - > addresses [ i ] - > expire_time = service - > config . renew_interval + now ;
}
}
if ( has_replicas ) {
/* if it has replica addresses propagate them */
new_state = " active(propagated) " ;
rec - > state = WREPL_STATE_ACTIVE ;
rec - > expire_time = service - > config . renew_interval + now ;
modify_flags = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP ;
modify_record = true ;
break ;
}
/*
* if it doesn ' t have replica addresses , make it a tombstone ,
* so that the released owned addresses are propagated
*/
new_state = " tombstone " ;
rec - > state = WREPL_STATE_TOMBSTONE ;
rec - > expire_time = time ( NULL ) +
service - > config . tombstone_interval +
service - > config . tombstone_timeout ;
modify_flags = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP ;
2007-10-07 01:48:28 +04:00
modify_record = true ;
2005-12-22 14:40:14 +03:00
break ;
case WREPL_STATE_RELEASED :
old_state = " released " ;
2006-01-23 19:04:27 +03:00
new_state = " tombstone " ;
2005-12-22 14:40:14 +03:00
rec - > state = WREPL_STATE_TOMBSTONE ;
rec - > expire_time = service - > config . tombstone_timeout + now ;
modify_flags = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP ;
2007-10-07 01:48:28 +04:00
modify_record = true ;
2005-12-22 14:40:14 +03:00
break ;
case WREPL_STATE_TOMBSTONE :
old_state = " tombstone " ;
2006-01-23 19:04:27 +03:00
new_state = " tombstone " ;
2005-12-22 14:40:14 +03:00
if ( ! delete_tombstones ) break ;
2006-01-23 19:04:27 +03:00
new_state = " deleted " ;
2007-10-07 01:48:28 +04:00
delete_record = true ;
2005-12-22 14:40:14 +03:00
break ;
case WREPL_STATE_RESERVED :
DEBUG ( 0 , ( " %s: corrupted record: %s \n " ,
__location__ , nbt_name_string ( rec , rec - > name ) ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( modify_record ) {
action = " modify " ;
ret = winsdb_modify ( service - > wins_db , rec , modify_flags ) ;
} else if ( delete_record ) {
action = " delete " ;
ret = winsdb_delete ( service - > wins_db , rec ) ;
} else {
action = " skip " ;
ret = NBT_RCODE_OK ;
}
if ( ret ! = NBT_RCODE_OK ) {
2008-01-14 15:57:12 +03:00
DEBUG ( 2 , ( " WINS scavenging: failed to %s name %s (owned:%s -> owned:%s): error:%u \n " ,
2006-01-23 19:04:27 +03:00
action , nbt_name_string ( rec , rec - > name ) , old_state , new_state , ret ) ) ;
2005-12-22 14:40:14 +03:00
} else {
2006-01-23 19:04:27 +03:00
DEBUG ( 4 , ( " WINS scavenging: %s name: %s (owned:%s -> owned:%s) \n " ,
action , nbt_name_string ( rec , rec - > name ) , old_state , new_state ) ) ;
2005-12-22 14:40:14 +03:00
}
talloc_free ( rec ) ;
}
return NT_STATUS_OK ;
}
static NTSTATUS wreplsrv_scavenging_replica_non_active_records ( struct wreplsrv_service * service , TALLOC_CTX * tmp_mem )
{
NTSTATUS status ;
struct winsdb_record * rec = NULL ;
struct ldb_result * res = NULL ;
2006-01-02 21:25:30 +03:00
const char * owner_filter ;
2005-12-22 14:40:14 +03:00
const char * filter ;
2009-11-07 23:15:17 +03:00
unsigned int i ;
2005-12-22 14:40:14 +03:00
int ret ;
time_t now = time ( NULL ) ;
const char * now_timestr ;
const char * action ;
2006-09-09 14:05:58 +04:00
const char * old_state = NULL ;
const char * new_state = NULL ;
2005-12-22 14:40:14 +03:00
uint32_t modify_flags ;
2007-10-07 01:48:28 +04:00
bool modify_record ;
bool delete_record ;
bool delete_tombstones ;
2005-12-22 14:40:14 +03:00
struct timeval tombstone_extra_time ;
now_timestr = ldb_timestring ( tmp_mem , now ) ;
NT_STATUS_HAVE_NO_MEMORY ( now_timestr ) ;
2006-01-02 21:25:30 +03:00
owner_filter = wreplsrv_owner_filter ( service , tmp_mem ,
service - > wins_db - > local_owner ) ;
NT_STATUS_HAVE_NO_MEMORY ( owner_filter ) ;
2005-12-22 14:40:14 +03:00
filter = talloc_asprintf ( tmp_mem ,
2006-01-02 21:25:30 +03:00
" (&(!%s)(objectClass=winsRecord) "
2006-01-23 19:04:27 +03:00
" (!(recordState=%u))(expireTime<=%s)) " ,
2006-01-02 21:25:30 +03:00
owner_filter , WREPL_STATE_ACTIVE , now_timestr ) ;
2005-12-22 14:40:14 +03:00
NT_STATUS_HAVE_NO_MEMORY ( filter ) ;
2008-09-23 22:30:06 +04:00
ret = ldb_search ( service - > wins_db - > ldb , tmp_mem , & res , NULL , LDB_SCOPE_SUBTREE , NULL , " %s " , filter ) ;
2005-12-22 14:40:14 +03:00
if ( ret ! = LDB_SUCCESS ) return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2006-01-02 21:25:30 +03:00
DEBUG ( 10 , ( " WINS scavenging: filter '%s' count %d \n " , filter , res - > count ) ) ;
2005-12-22 14:40:14 +03:00
tombstone_extra_time = timeval_add ( & service - > startup_time ,
service - > config . tombstone_extra_timeout ,
0 ) ;
delete_tombstones = timeval_expired ( & tombstone_extra_time ) ;
for ( i = 0 ; i < res - > count ; i + + ) {
2006-01-21 11:53:56 +03:00
/*
* we pass ' 0 ' as ' now ' here ,
* because we want to get the raw timestamps which are in the DB
*/
status = winsdb_record ( service - > wins_db , res - > msgs [ i ] , tmp_mem , 0 , & rec ) ;
2005-12-22 14:40:14 +03:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2006-01-08 21:25:40 +03:00
talloc_free ( res - > msgs [ i ] ) ;
2005-12-22 14:40:14 +03:00
modify_flags = 0 ;
2007-10-07 01:48:28 +04:00
modify_record = false ;
delete_record = false ;
2005-12-22 14:40:14 +03:00
switch ( rec - > state ) {
case WREPL_STATE_ACTIVE :
DEBUG ( 0 , ( " %s: corrupted record: %s \n " ,
__location__ , nbt_name_string ( rec , rec - > name ) ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
case WREPL_STATE_RELEASED :
old_state = " released " ;
2006-01-23 19:04:27 +03:00
new_state = " tombstone " ;
2005-12-22 14:40:14 +03:00
rec - > state = WREPL_STATE_TOMBSTONE ;
rec - > expire_time = service - > config . tombstone_timeout + now ;
modify_flags = 0 ;
2007-10-07 01:48:28 +04:00
modify_record = true ;
2005-12-22 14:40:14 +03:00
break ;
case WREPL_STATE_TOMBSTONE :
old_state = " tombstone " ;
2006-01-23 19:04:27 +03:00
new_state = " tombstone " ;
2005-12-22 14:40:14 +03:00
if ( ! delete_tombstones ) break ;
2006-01-23 19:04:27 +03:00
new_state = " deleted " ;
2007-10-07 01:48:28 +04:00
delete_record = true ;
2005-12-22 14:40:14 +03:00
break ;
case WREPL_STATE_RESERVED :
DEBUG ( 0 , ( " %s: corrupted record: %s \n " ,
__location__ , nbt_name_string ( rec , rec - > name ) ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( modify_record ) {
action = " modify " ;
ret = winsdb_modify ( service - > wins_db , rec , modify_flags ) ;
} else if ( delete_record ) {
action = " delete " ;
ret = winsdb_delete ( service - > wins_db , rec ) ;
} else {
action = " skip " ;
ret = NBT_RCODE_OK ;
}
if ( ret ! = NBT_RCODE_OK ) {
2008-01-14 15:57:12 +03:00
DEBUG ( 2 , ( " WINS scavenging: failed to %s name %s (replica:%s -> replica:%s): error:%u \n " ,
2006-01-23 19:04:27 +03:00
action , nbt_name_string ( rec , rec - > name ) , old_state , new_state , ret ) ) ;
2005-12-22 14:40:14 +03:00
} else {
2006-01-23 19:04:27 +03:00
DEBUG ( 4 , ( " WINS scavenging: %s name: %s (replica:%s -> replica:%s) \n " ,
action , nbt_name_string ( rec , rec - > name ) , old_state , new_state ) ) ;
2005-12-22 14:40:14 +03:00
}
talloc_free ( rec ) ;
}
return NT_STATUS_OK ;
}
2006-01-09 02:32:15 +03:00
struct verify_state {
2011-05-03 04:40:33 +04:00
struct imessaging_context * msg_ctx ;
2006-01-09 02:32:15 +03:00
struct wreplsrv_service * service ;
struct winsdb_record * rec ;
struct nbtd_proxy_wins_challenge r ;
} ;
2010-09-03 15:18:14 +04:00
static void verify_handler ( struct tevent_req * subreq )
2006-01-09 02:32:15 +03:00
{
2010-09-03 15:18:14 +04:00
struct verify_state * s =
tevent_req_callback_data ( subreq ,
struct verify_state ) ;
2006-01-09 02:32:15 +03:00
struct winsdb_record * rec = s - > rec ;
const char * action ;
const char * old_state = " active " ;
2006-01-23 19:04:27 +03:00
const char * new_state = " active " ;
const char * new_owner = " replica " ;
uint32_t modify_flags = 0 ;
2007-10-07 01:48:28 +04:00
bool modify_record = false ;
bool delete_record = false ;
bool different = false ;
2006-01-09 02:32:15 +03:00
int ret ;
NTSTATUS status ;
uint32_t i , j ;
/*
* - if the name isn ' t present anymore remove our record
* - if the name is found and not a normal group check if the addresses match ,
* - if they don ' t match remove the record
* - if they match do nothing
* - if an error happens do nothing
*/
2010-09-03 15:18:14 +04:00
status = dcerpc_nbtd_proxy_wins_challenge_r_recv ( subreq , s ) ;
TALLOC_FREE ( subreq ) ;
2006-01-09 02:32:15 +03:00
if ( NT_STATUS_EQUAL ( NT_STATUS_OBJECT_NAME_NOT_FOUND , status ) ) {
2007-10-07 01:48:28 +04:00
delete_record = true ;
2006-01-23 19:04:27 +03:00
new_state = " deleted " ;
2006-01-09 02:32:15 +03:00
} else if ( NT_STATUS_IS_OK ( status ) & & rec - > type ! = WREPL_TYPE_GROUP ) {
for ( i = 0 ; i < s - > r . out . num_addrs ; i + + ) {
2007-10-07 01:48:28 +04:00
bool found = false ;
2006-01-09 02:32:15 +03:00
for ( j = 0 ; rec - > addresses [ j ] ; j + + ) {
if ( strcmp ( s - > r . out . addrs [ i ] . addr , rec - > addresses [ j ] - > address ) = = 0 ) {
2007-10-07 01:48:28 +04:00
found = true ;
2006-01-09 02:32:15 +03:00
break ;
}
}
if ( ! found ) {
2007-10-07 01:48:28 +04:00
different = true ;
2006-01-09 02:32:15 +03:00
break ;
}
}
} else if ( NT_STATUS_IS_OK ( status ) & & rec - > type = = WREPL_TYPE_GROUP ) {
2006-01-23 15:55:22 +03:00
if ( s - > r . out . num_addrs ! = 1 | | strcmp ( s - > r . out . addrs [ 0 ] . addr , " 255.255.255.255 " ) ! = 0 ) {
2007-10-07 01:48:28 +04:00
different = true ;
2006-01-09 02:32:15 +03:00
}
}
if ( different ) {
2006-01-23 19:04:27 +03:00
/*
* if the reply from the owning wins server has different addresses
* then take the ownership of the record and make it a tombstone
* this will then hopefully replicated to the original owner of the record
* which will then propagate it ' s own record , so that the current record will
* be replicated to to us
*/
2008-01-14 15:57:12 +03:00
DEBUG ( 2 , ( " WINS scavenging: replica %s verify got different addresses from winsserver: %s: tombstoning record \n " ,
2006-01-09 02:32:15 +03:00
nbt_name_string ( rec , rec - > name ) , rec - > wins_owner ) ) ;
2006-01-23 19:04:27 +03:00
rec - > state = WREPL_STATE_TOMBSTONE ;
rec - > expire_time = time ( NULL ) + s - > service - > config . tombstone_timeout ;
for ( i = 0 ; rec - > addresses [ i ] ; i + + ) {
rec - > addresses [ i ] - > expire_time = rec - > expire_time ;
}
2007-10-07 01:48:28 +04:00
modify_record = true ;
2006-01-23 19:04:27 +03:00
modify_flags = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP ;
new_state = " tombstone " ;
new_owner = " owned " ;
2006-01-09 02:32:15 +03:00
} else if ( NT_STATUS_IS_OK ( status ) ) {
2006-01-23 19:04:27 +03:00
/* if the addresses are the same, just update the timestamps */
2006-01-09 02:32:15 +03:00
rec - > expire_time = time ( NULL ) + s - > service - > config . verify_interval ;
for ( i = 0 ; rec - > addresses [ i ] ; i + + ) {
rec - > addresses [ i ] - > expire_time = rec - > expire_time ;
}
2007-10-07 01:48:28 +04:00
modify_record = true ;
2006-01-23 19:04:27 +03:00
modify_flags = 0 ;
new_state = " active " ;
2006-01-09 02:32:15 +03:00
}
if ( modify_record ) {
action = " modify " ;
2006-01-23 19:04:27 +03:00
ret = winsdb_modify ( s - > service - > wins_db , rec , modify_flags ) ;
2006-01-09 02:32:15 +03:00
} else if ( delete_record ) {
action = " delete " ;
ret = winsdb_delete ( s - > service - > wins_db , rec ) ;
} else {
action = " skip " ;
ret = NBT_RCODE_OK ;
}
if ( ret ! = NBT_RCODE_OK ) {
2008-01-14 15:57:12 +03:00
DEBUG ( 2 , ( " WINS scavenging: failed to %s name %s (replica:%s -> %s:%s): error:%u \n " ,
2006-01-23 19:04:27 +03:00
action , nbt_name_string ( rec , rec - > name ) , old_state , new_owner , new_state , ret ) ) ;
2006-01-09 02:32:15 +03:00
} else {
2006-01-23 19:04:27 +03:00
DEBUG ( 4 , ( " WINS scavenging: %s name: %s (replica:%s -> %s:%s): %s: %s \n " ,
action , nbt_name_string ( rec , rec - > name ) , old_state , new_owner , new_state ,
rec - > wins_owner , nt_errstr ( status ) ) ) ;
2006-01-09 02:32:15 +03:00
}
talloc_free ( s ) ;
}
2005-12-22 14:40:14 +03:00
static NTSTATUS wreplsrv_scavenging_replica_active_records ( struct wreplsrv_service * service , TALLOC_CTX * tmp_mem )
{
NTSTATUS status ;
struct winsdb_record * rec = NULL ;
struct ldb_result * res = NULL ;
2006-01-02 21:25:30 +03:00
const char * owner_filter ;
2005-12-22 14:40:14 +03:00
const char * filter ;
2009-11-07 23:15:17 +03:00
unsigned int i ;
2005-12-22 14:40:14 +03:00
int ret ;
time_t now = time ( NULL ) ;
const char * now_timestr ;
2010-09-03 15:18:14 +04:00
struct tevent_req * subreq ;
2006-01-09 02:32:15 +03:00
struct verify_state * s ;
2010-09-03 15:18:14 +04:00
struct dcerpc_binding_handle * irpc_handle ;
2005-12-22 14:40:14 +03:00
now_timestr = ldb_timestring ( tmp_mem , now ) ;
NT_STATUS_HAVE_NO_MEMORY ( now_timestr ) ;
2006-01-02 21:25:30 +03:00
owner_filter = wreplsrv_owner_filter ( service , tmp_mem ,
service - > wins_db - > local_owner ) ;
NT_STATUS_HAVE_NO_MEMORY ( owner_filter ) ;
2005-12-22 14:40:14 +03:00
filter = talloc_asprintf ( tmp_mem ,
2006-01-02 21:25:30 +03:00
" (&(!%s)(objectClass=winsRecord) "
2006-01-23 19:04:27 +03:00
" (recordState=%u)(expireTime<=%s)) " ,
2006-01-02 21:25:30 +03:00
owner_filter , WREPL_STATE_ACTIVE , now_timestr ) ;
2005-12-22 14:40:14 +03:00
NT_STATUS_HAVE_NO_MEMORY ( filter ) ;
2008-09-23 22:30:06 +04:00
ret = ldb_search ( service - > wins_db - > ldb , tmp_mem , & res , NULL , LDB_SCOPE_SUBTREE , NULL , " %s " , filter ) ;
2005-12-22 14:40:14 +03:00
if ( ret ! = LDB_SUCCESS ) return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2006-01-02 21:25:30 +03:00
DEBUG ( 10 , ( " WINS scavenging: filter '%s' count %d \n " , filter , res - > count ) ) ;
2005-12-22 14:40:14 +03:00
for ( i = 0 ; i < res - > count ; i + + ) {
2006-01-21 11:53:56 +03:00
/*
* we pass ' 0 ' as ' now ' here ,
* because we want to get the raw timestamps which are in the DB
*/
status = winsdb_record ( service - > wins_db , res - > msgs [ i ] , tmp_mem , 0 , & rec ) ;
2005-12-22 14:40:14 +03:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2006-01-08 21:25:40 +03:00
talloc_free ( res - > msgs [ i ] ) ;
2005-12-22 14:40:14 +03:00
if ( rec - > state ! = WREPL_STATE_ACTIVE ) {
DEBUG ( 0 , ( " %s: corrupted record: %s \n " ,
__location__ , nbt_name_string ( rec , rec - > name ) ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
/*
2006-01-09 02:32:15 +03:00
* ask the owning wins server if the record still exists ,
* if not delete the record
*
* TODO : NOTE : this is a simpliefied version , to verify that
* a record still exist , I assume that w2k3 uses
* DCERPC calls or some WINSREPL packets for this ,
* but we use a wins name query
2005-12-22 14:40:14 +03:00
*/
2008-01-14 15:57:12 +03:00
DEBUG ( 2 , ( " ask wins server '%s' if '%s' with version_id:%llu still exists \n " ,
2006-09-09 14:05:58 +04:00
rec - > wins_owner , nbt_name_string ( rec , rec - > name ) ,
( unsigned long long ) rec - > version ) ) ;
2005-12-22 14:40:14 +03:00
2006-01-09 02:32:15 +03:00
s = talloc_zero ( tmp_mem , struct verify_state ) ;
NT_STATUS_HAVE_NO_MEMORY ( s ) ;
s - > msg_ctx = service - > task - > msg_ctx ;
s - > service = service ;
s - > rec = talloc_steal ( s , rec ) ;
2005-12-22 14:40:14 +03:00
2006-01-09 02:32:15 +03:00
s - > r . in . name = * rec - > name ;
s - > r . in . num_addrs = 1 ;
s - > r . in . addrs = talloc_array ( s , struct nbtd_proxy_wins_addr , s - > r . in . num_addrs ) ;
NT_STATUS_HAVE_NO_MEMORY ( s - > r . in . addrs ) ;
/* TODO: fix pidl to handle inline ipv4address arrays */
s - > r . in . addrs [ 0 ] . addr = rec - > wins_owner ;
2005-12-22 14:40:14 +03:00
2010-09-03 15:18:14 +04:00
irpc_handle = irpc_binding_handle_by_name ( s ,
service - > task - > msg_ctx ,
" nbt_server " ,
& ndr_table_irpc ) ;
if ( irpc_handle = = NULL ) {
return NT_STATUS_INTERNAL_ERROR ;
}
subreq = dcerpc_nbtd_proxy_wins_challenge_r_send ( s ,
service - > task - > event_ctx ,
irpc_handle ,
& s - > r ) ;
NT_STATUS_HAVE_NO_MEMORY ( subreq ) ;
2006-01-09 02:32:15 +03:00
2010-09-03 15:18:14 +04:00
tevent_req_set_callback ( subreq , verify_handler , s ) ;
2006-01-09 02:32:15 +03:00
talloc_steal ( service , s ) ;
2005-12-22 14:40:14 +03:00
}
return NT_STATUS_OK ;
}
NTSTATUS wreplsrv_scavenging_run ( struct wreplsrv_service * service )
{
NTSTATUS status ;
TALLOC_CTX * tmp_mem ;
2007-10-07 01:48:28 +04:00
bool skip_first_run = false ;
2005-12-22 14:40:14 +03:00
if ( ! timeval_expired ( & service - > scavenging . next_run ) ) {
return NT_STATUS_OK ;
}
2006-01-03 23:07:34 +03:00
if ( timeval_is_zero ( & service - > scavenging . next_run ) ) {
2007-10-07 01:48:28 +04:00
skip_first_run = true ;
2006-01-03 23:07:34 +03:00
}
2005-12-22 14:40:14 +03:00
service - > scavenging . next_run = timeval_current_ofs ( service - > config . scavenging_interval , 0 ) ;
status = wreplsrv_periodic_schedule ( service , service - > config . scavenging_interval ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
2006-01-03 23:07:34 +03:00
/*
* if it ' s the first time this functions is called ( startup )
* the next_run is zero , in this case we should not do scavenging
*/
if ( skip_first_run ) {
return NT_STATUS_OK ;
}
2005-12-22 14:40:14 +03:00
if ( service - > scavenging . processing ) {
return NT_STATUS_OK ;
}
2008-01-14 15:57:12 +03:00
DEBUG ( 2 , ( " wreplsrv_scavenging_run(): start \n " ) ) ;
2005-12-22 14:40:14 +03:00
tmp_mem = talloc_new ( service ) ;
2007-05-07 19:43:40 +04:00
NT_STATUS_HAVE_NO_MEMORY ( tmp_mem ) ;
2007-10-07 01:48:28 +04:00
service - > scavenging . processing = true ;
2005-12-22 14:40:14 +03:00
status = wreplsrv_scavenging_owned_records ( service , tmp_mem ) ;
2007-10-07 01:48:28 +04:00
service - > scavenging . processing = false ;
2005-12-22 14:40:14 +03:00
talloc_free ( tmp_mem ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
tmp_mem = talloc_new ( service ) ;
2007-05-07 19:43:40 +04:00
NT_STATUS_HAVE_NO_MEMORY ( tmp_mem ) ;
2007-10-07 01:48:28 +04:00
service - > scavenging . processing = true ;
2005-12-22 14:40:14 +03:00
status = wreplsrv_scavenging_replica_non_active_records ( service , tmp_mem ) ;
2007-10-07 01:48:28 +04:00
service - > scavenging . processing = false ;
2005-12-22 14:40:14 +03:00
talloc_free ( tmp_mem ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
tmp_mem = talloc_new ( service ) ;
2007-05-07 19:43:40 +04:00
NT_STATUS_HAVE_NO_MEMORY ( tmp_mem ) ;
2007-10-07 01:48:28 +04:00
service - > scavenging . processing = true ;
2005-12-22 14:40:14 +03:00
status = wreplsrv_scavenging_replica_active_records ( service , tmp_mem ) ;
2007-10-07 01:48:28 +04:00
service - > scavenging . processing = false ;
2005-12-22 14:40:14 +03:00
talloc_free ( tmp_mem ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
2008-01-14 15:57:12 +03:00
DEBUG ( 2 , ( " wreplsrv_scavenging_run(): end \n " ) ) ;
2005-12-22 14:40:14 +03:00
return NT_STATUS_OK ;
}