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
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 "librpc/gen_ndr/ndr_winsrepl.h"
# include "wrepl_server/wrepl_server.h"
# include "nbt_server/wins/winsdb.h"
# include "ldb/include/ldb.h"
# include "ldb/include/ldb_errors.h"
# include "system/time.h"
2006-01-09 02:32:15 +03:00
# include "smbd/service_task.h"
# include "lib/messaging/irpc.h"
# include "librpc/gen_ndr/ndr_irpc.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 ;
uint32_t i ;
int ret ;
time_t now = time ( NULL ) ;
const char * now_timestr ;
const char * action ;
const char * old_state ;
2006-01-23 19:04:27 +03:00
const char * new_state ;
2005-12-22 14:40:14 +03:00
uint32_t modify_flags ;
BOOL modify_record ;
BOOL delete_record ;
BOOL delete_tombstones ;
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
" (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 ) ;
2005-12-30 23:08:52 +03:00
ret = ldb_search ( service - > wins_db - > ldb , NULL , LDB_SCOPE_SUBTREE , filter , NULL , & res ) ;
2005-12-22 14:40:14 +03:00
if ( ret ! = LDB_SUCCESS ) return NT_STATUS_INTERNAL_DB_CORRUPTION ;
talloc_steal ( tmp_mem , res ) ;
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 ;
modify_record = False ;
delete_record = False ;
switch ( rec - > state ) {
case WREPL_STATE_ACTIVE :
old_state = " active " ;
2006-01-23 19:04:27 +03:00
new_state = " active " ;
if ( ! rec - > is_static ) {
new_state = " released " ;
rec - > state = WREPL_STATE_RELEASED ;
rec - > expire_time = service - > config . tombstone_interval + now ;
}
2005-12-22 14:40:14 +03:00
modify_flags = 0 ;
modify_record = True ;
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 ;
modify_record = True ;
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 " ;
2005-12-22 14:40:14 +03:00
delete_record = True ;
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 ) {
2006-01-23 19:04:27 +03:00
DEBUG ( 1 , ( " WINS scavenging: failed to %s name %s (owned:%s -> owned:%s): error:%u \n " ,
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 ;
uint32_t i ;
int ret ;
time_t now = time ( NULL ) ;
const char * now_timestr ;
const char * action ;
const char * old_state ;
2006-01-23 19:04:27 +03:00
const char * new_state ;
2005-12-22 14:40:14 +03:00
uint32_t modify_flags ;
BOOL modify_record ;
BOOL delete_record ;
BOOL delete_tombstones ;
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 ) ;
2005-12-30 23:08:52 +03:00
ret = ldb_search ( service - > wins_db - > ldb , NULL , LDB_SCOPE_SUBTREE , filter , NULL , & res ) ;
2005-12-22 14:40:14 +03:00
if ( ret ! = LDB_SUCCESS ) return NT_STATUS_INTERNAL_DB_CORRUPTION ;
talloc_steal ( tmp_mem , res ) ;
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 ;
modify_record = False ;
delete_record = False ;
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 ;
modify_record = True ;
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 " ;
2005-12-22 14:40:14 +03:00
delete_record = True ;
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 ) {
2006-01-23 19:04:27 +03:00
DEBUG ( 1 , ( " WINS scavenging: failed to %s name %s (replica:%s -> replica:%s): error:%u \n " ,
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 {
struct messaging_context * msg_ctx ;
struct wreplsrv_service * service ;
struct winsdb_record * rec ;
struct nbtd_proxy_wins_challenge r ;
} ;
static void verify_handler ( struct irpc_request * ireq )
{
struct verify_state * s = talloc_get_type ( ireq - > async . private ,
struct verify_state ) ;
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 ;
2006-01-09 02:32:15 +03:00
BOOL modify_record = False ;
BOOL delete_record = False ;
BOOL different = False ;
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
*/
status = irpc_call_recv ( ireq ) ;
if ( NT_STATUS_EQUAL ( NT_STATUS_OBJECT_NAME_NOT_FOUND , status ) ) {
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 + + ) {
BOOL found = False ;
for ( j = 0 ; rec - > addresses [ j ] ; j + + ) {
if ( strcmp ( s - > r . out . addrs [ i ] . addr , rec - > addresses [ j ] - > address ) = = 0 ) {
found = True ;
break ;
}
}
if ( ! found ) {
different = True ;
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 ) {
2006-01-09 02:32:15 +03:00
different = True ;
}
}
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
*/
DEBUG ( 0 , ( " 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 ;
}
modify_record = True ;
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 ;
}
2006-01-23 19:04:27 +03:00
modify_record = True ;
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 ) {
2006-01-23 19:04:27 +03:00
DEBUG ( 1 , ( " WINS scavenging: failed to %s name %s (replica:%s -> %s:%s): error:%u \n " ,
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 ;
uint32_t i ;
int ret ;
time_t now = time ( NULL ) ;
const char * now_timestr ;
2006-01-09 02:32:15 +03:00
struct irpc_request * ireq ;
struct verify_state * s ;
uint32_t * nbt_servers ;
nbt_servers = irpc_servers_byname ( service - > task - > msg_ctx , " nbt_server " ) ;
if ( ( nbt_servers = = NULL ) | | ( nbt_servers [ 0 ] = = 0 ) ) {
return NT_STATUS_INTERNAL_ERROR ;
}
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 ) ;
2005-12-30 23:08:52 +03:00
ret = ldb_search ( service - > wins_db - > ldb , NULL , LDB_SCOPE_SUBTREE , filter , NULL , & res ) ;
2005-12-22 14:40:14 +03:00
if ( ret ! = LDB_SUCCESS ) return NT_STATUS_INTERNAL_DB_CORRUPTION ;
talloc_steal ( tmp_mem , res ) ;
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
*/
2006-01-09 02:32:15 +03:00
DEBUG ( 0 , ( " ask wins server '%s' if '%s' with version_id:%llu still exists \n " ,
2005-12-22 14:40:14 +03:00
rec - > wins_owner , nbt_name_string ( rec , rec - > name ) , rec - > version ) ) ;
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
2006-01-09 02:32:15 +03:00
ireq = IRPC_CALL_SEND ( s - > msg_ctx , nbt_servers [ 0 ] ,
irpc , NBTD_PROXY_WINS_CHALLENGE ,
& s - > r , s ) ;
NT_STATUS_HAVE_NO_MEMORY ( ireq ) ;
ireq - > async . fn = verify_handler ;
ireq - > async . private = s ;
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 ;
2006-01-03 23:07:34 +03: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 ) ) {
skip_first_run = True ;
}
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 ;
}
DEBUG ( 4 , ( " wreplsrv_scavenging_run(): start \n " ) ) ;
tmp_mem = talloc_new ( service ) ;
service - > scavenging . processing = True ;
status = wreplsrv_scavenging_owned_records ( service , tmp_mem ) ;
service - > scavenging . processing = False ;
talloc_free ( tmp_mem ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
tmp_mem = talloc_new ( service ) ;
service - > scavenging . processing = True ;
status = wreplsrv_scavenging_replica_non_active_records ( service , tmp_mem ) ;
service - > scavenging . processing = False ;
talloc_free ( tmp_mem ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
tmp_mem = talloc_new ( service ) ;
service - > scavenging . processing = True ;
status = wreplsrv_scavenging_replica_active_records ( service , tmp_mem ) ;
service - > scavenging . processing = False ;
talloc_free ( tmp_mem ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
DEBUG ( 4 , ( " wreplsrv_scavenging_run(): end \n " ) ) ;
return NT_STATUS_OK ;
}