2009-09-13 18:16:13 +10:00
/*
Unix SMB / CIFS mplementation .
DSDB replication service periodic notification handling
Copyright ( C ) Andrew Tridgell 2009
based on drepl_periodic
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 3 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 , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "lib/events/events.h"
# include "dsdb/samdb/samdb.h"
# include "auth/auth.h"
# include "smbd/service.h"
# include "dsdb/repl/drepl_service.h"
2011-02-10 14:12:51 +11:00
# include <ldb_errors.h>
2009-09-13 18:16:13 +10:00
# include "../lib/util/dlinklist.h"
# include "librpc/gen_ndr/ndr_misc.h"
# include "librpc/gen_ndr/ndr_drsuapi.h"
# include "librpc/gen_ndr/ndr_drsblobs.h"
# include "libcli/composite/composite.h"
2010-01-11 20:00:07 +01:00
# include "../lib/util/tevent_ntstatus.h"
2009-09-13 18:16:13 +10:00
struct dreplsrv_op_notify_state {
2010-03-08 16:23:17 +01:00
struct tevent_context * ev ;
2009-09-13 18:16:13 +10:00
struct dreplsrv_notify_operation * op ;
2010-02-27 09:43:21 +01:00
void * ndr_struct_ptr ;
2009-09-13 18:16:13 +10:00
} ;
2010-01-13 16:00:20 +01:00
static void dreplsrv_op_notify_connect_done ( struct tevent_req * subreq ) ;
2009-09-13 18:16:13 +10:00
/*
2010-01-13 16:00:20 +01:00
start the ReplicaSync async call
2009-09-13 18:16:13 +10:00
*/
2010-01-13 16:00:20 +01:00
static struct tevent_req * dreplsrv_op_notify_send ( TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct dreplsrv_notify_operation * op )
2009-09-13 18:16:13 +10:00
{
2010-01-13 16:00:20 +01:00
struct tevent_req * req ;
struct dreplsrv_op_notify_state * state ;
struct tevent_req * subreq ;
2009-09-13 18:16:13 +10:00
2010-01-13 16:00:20 +01:00
req = tevent_req_create ( mem_ctx , & state ,
struct dreplsrv_op_notify_state ) ;
if ( req = = NULL ) {
return NULL ;
2010-01-11 20:00:07 +01:00
}
2010-03-08 16:23:17 +01:00
state - > ev = ev ;
2010-01-13 16:00:20 +01:00
state - > op = op ;
2009-09-13 18:16:13 +10:00
2010-01-13 16:00:20 +01:00
subreq = dreplsrv_out_drsuapi_send ( state ,
ev ,
op - > source_dsa - > conn ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , dreplsrv_op_notify_connect_done , req ) ;
return req ;
}
static void dreplsrv_op_notify_replica_sync_trigger ( struct tevent_req * req ) ;
static void dreplsrv_op_notify_connect_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data ( subreq ,
struct tevent_req ) ;
NTSTATUS status ;
status = dreplsrv_out_drsuapi_recv ( subreq ) ;
TALLOC_FREE ( subreq ) ;
if ( tevent_req_nterror ( req , status ) ) {
2009-09-13 18:16:13 +10:00
return ;
}
2010-01-13 16:00:20 +01:00
dreplsrv_op_notify_replica_sync_trigger ( req ) ;
2009-09-13 18:16:13 +10:00
}
2010-03-08 16:23:17 +01:00
static void dreplsrv_op_notify_replica_sync_done ( struct tevent_req * subreq ) ;
2010-01-13 16:00:20 +01:00
2010-01-11 20:00:07 +01:00
static void dreplsrv_op_notify_replica_sync_trigger ( struct tevent_req * req )
2009-09-13 18:16:13 +10:00
{
2010-01-11 20:00:07 +01:00
struct dreplsrv_op_notify_state * state =
tevent_req_data ( req ,
struct dreplsrv_op_notify_state ) ;
struct dreplsrv_partition * partition = state - > op - > source_dsa - > partition ;
struct dreplsrv_drsuapi_connection * drsuapi = state - > op - > source_dsa - > conn - > drsuapi ;
2009-09-13 18:16:13 +10:00
struct drsuapi_DsReplicaSync * r ;
2010-03-08 16:23:17 +01:00
struct tevent_req * subreq ;
2009-09-13 18:16:13 +10:00
2010-01-11 20:00:07 +01:00
r = talloc_zero ( state , struct drsuapi_DsReplicaSync ) ;
if ( tevent_req_nomem ( r , req ) ) {
return ;
}
2010-02-13 04:57:28 +02:00
r - > in . req = talloc_zero ( r , union drsuapi_DsReplicaSyncRequest ) ;
if ( tevent_req_nomem ( r , req ) ) {
return ;
}
2009-09-13 18:16:13 +10:00
r - > in . bind_handle = & drsuapi - > bind_handle ;
r - > in . level = 1 ;
2010-02-13 04:57:28 +02:00
r - > in . req - > req1 . naming_context = & partition - > nc ;
r - > in . req - > req1 . source_dsa_guid = state - > op - > service - > ntds_guid ;
r - > in . req - > req1 . options =
2010-01-14 14:37:22 +11:00
DRSUAPI_DRS_ASYNC_OP |
DRSUAPI_DRS_UPDATE_NOTIFICATION |
DRSUAPI_DRS_WRIT_REP ;
2009-09-13 18:16:13 +10:00
2010-01-21 09:20:44 -02:00
if ( state - > op - > is_urgent ) {
2010-02-13 04:57:28 +02:00
r - > in . req - > req1 . options | = DRSUAPI_DRS_SYNC_URGENT ;
2010-01-21 09:20:44 -02:00
}
2010-02-27 09:43:21 +01:00
state - > ndr_struct_ptr = r ;
2010-04-27 12:17:08 +10:00
if ( DEBUGLVL ( 10 ) ) {
NDR_PRINT_IN_DEBUG ( drsuapi_DsReplicaSync , r ) ;
}
2010-03-08 16:23:17 +01:00
subreq = dcerpc_drsuapi_DsReplicaSync_r_send ( state ,
state - > ev ,
drsuapi - > drsuapi_handle ,
r ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
2010-01-11 20:00:07 +01:00
return ;
}
2010-03-08 16:23:17 +01:00
tevent_req_set_callback ( subreq , dreplsrv_op_notify_replica_sync_done , req ) ;
2009-09-13 18:16:13 +10:00
}
2010-03-08 16:23:17 +01:00
static void dreplsrv_op_notify_replica_sync_done ( struct tevent_req * subreq )
2009-09-13 18:16:13 +10:00
{
2010-03-08 16:23:17 +01:00
struct tevent_req * req =
tevent_req_callback_data ( subreq ,
struct tevent_req ) ;
2010-02-27 09:43:21 +01:00
struct dreplsrv_op_notify_state * state =
tevent_req_data ( req ,
struct dreplsrv_op_notify_state ) ;
struct drsuapi_DsReplicaSync * r = talloc_get_type ( state - > ndr_struct_ptr ,
2010-01-13 16:00:20 +01:00
struct drsuapi_DsReplicaSync ) ;
2010-01-11 20:00:07 +01:00
NTSTATUS status ;
2009-09-13 18:16:13 +10:00
2010-02-27 09:43:21 +01:00
state - > ndr_struct_ptr = NULL ;
2010-03-08 16:23:17 +01:00
status = dcerpc_drsuapi_DsReplicaSync_r_recv ( subreq , r ) ;
TALLOC_FREE ( subreq ) ;
2010-01-11 20:00:07 +01:00
if ( tevent_req_nterror ( req , status ) ) {
return ;
}
2009-09-13 18:16:13 +10:00
2010-01-13 16:00:20 +01:00
if ( ! W_ERROR_IS_OK ( r - > out . result ) ) {
status = werror_to_ntstatus ( r - > out . result ) ;
tevent_req_nterror ( req , status ) ;
return ;
2010-01-11 20:00:07 +01:00
}
2010-01-13 16:00:20 +01:00
tevent_req_done ( req ) ;
2010-01-11 20:00:07 +01:00
}
2009-09-13 18:16:13 +10:00
2010-01-11 20:00:07 +01:00
static NTSTATUS dreplsrv_op_notify_recv ( struct tevent_req * req )
{
return tevent_req_simple_recv_ntstatus ( req ) ;
2009-09-13 18:16:13 +10:00
}
/*
called when a notify operation has completed
*/
2010-01-11 20:00:07 +01:00
static void dreplsrv_notify_op_callback ( struct tevent_req * subreq )
2009-09-13 18:16:13 +10:00
{
2010-01-11 20:00:07 +01:00
struct dreplsrv_notify_operation * op =
tevent_req_callback_data ( subreq ,
struct dreplsrv_notify_operation ) ;
2009-09-13 18:16:13 +10:00
NTSTATUS status ;
struct dreplsrv_service * s = op - > service ;
2010-11-17 23:13:32 +11:00
WERROR werr ;
2009-09-13 18:16:13 +10:00
2010-01-11 20:00:07 +01:00
status = dreplsrv_op_notify_recv ( subreq ) ;
2010-11-17 23:13:32 +11:00
werr = ntstatus_to_werror ( status ) ;
2010-01-11 20:00:07 +01:00
TALLOC_FREE ( subreq ) ;
2009-09-13 18:16:13 +10:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-11-17 23:13:32 +11:00
DEBUG ( 4 , ( " dreplsrv_notify: Failed to send DsReplicaSync to %s for %s - %s : %s \n " ,
2009-09-13 18:16:13 +10:00
op - > source_dsa - > repsFrom1 - > other_info - > dns_name ,
2009-09-19 14:27:29 -07:00
ldb_dn_get_linearized ( op - > source_dsa - > partition - > dn ) ,
2010-04-27 12:17:08 +10:00
nt_errstr ( status ) , win_errstr ( werr ) ) ) ;
2009-09-13 18:16:13 +10:00
} else {
2012-10-15 22:15:17 -07:00
DEBUG ( 2 , ( " dreplsrv_notify: DsReplicaSync successfuly sent to %s \n " ,
2009-09-13 18:16:13 +10:00
op - > source_dsa - > repsFrom1 - > other_info - > dns_name ) ) ;
op - > source_dsa - > notify_uSN = op - > uSN ;
}
2010-11-17 23:13:32 +11:00
drepl_reps_update ( s , " repsTo " , op - > source_dsa - > partition - > dn ,
& op - > source_dsa - > repsFrom1 - > source_dsa_obj_guid ,
werr ) ;
2009-09-13 18:16:13 +10:00
talloc_free ( op ) ;
s - > ops . n_current = NULL ;
2010-11-17 23:12:10 +11:00
dreplsrv_run_pending_ops ( s ) ;
2009-09-13 18:16:13 +10:00
}
/*
run any pending replica sync calls
*/
void dreplsrv_notify_run_ops ( struct dreplsrv_service * s )
{
struct dreplsrv_notify_operation * op ;
2010-01-11 20:00:07 +01:00
struct tevent_req * subreq ;
2009-09-13 18:16:13 +10:00
if ( s - > ops . n_current | | s - > ops . current ) {
/* if there's still one running, we're done */
return ;
}
if ( ! s - > ops . notifies ) {
/* if there're no pending operations, we're done */
return ;
}
op = s - > ops . notifies ;
s - > ops . n_current = op ;
DLIST_REMOVE ( s - > ops . notifies , op ) ;
2010-01-11 20:00:07 +01:00
subreq = dreplsrv_op_notify_send ( op , s - > task - > event_ctx , op ) ;
if ( ! subreq ) {
DEBUG ( 0 , ( " dreplsrv_notify_run_ops: dreplsrv_op_notify_send[%s][%s] - no memory \n " ,
op - > source_dsa - > repsFrom1 - > other_info - > dns_name ,
ldb_dn_get_linearized ( op - > source_dsa - > partition - > dn ) ) ) ;
2009-09-13 18:16:13 +10:00
return ;
}
2010-01-11 20:00:07 +01:00
tevent_req_set_callback ( subreq , dreplsrv_notify_op_callback , op ) ;
2010-04-26 21:47:29 +10:00
DEBUG ( 4 , ( " started DsReplicaSync for %s to %s \n " ,
ldb_dn_get_linearized ( op - > source_dsa - > partition - > dn ) ,
op - > source_dsa - > repsFrom1 - > other_info - > dns_name ) ) ;
2009-09-13 18:16:13 +10:00
}
/*
find a source_dsa for a given guid
*/
2010-11-08 17:14:09 +11:00
static struct dreplsrv_partition_source_dsa * dreplsrv_find_notify_dsa ( struct dreplsrv_partition * p ,
2009-09-13 18:16:13 +10:00
struct GUID * guid )
{
struct dreplsrv_partition_source_dsa * s ;
2010-11-08 17:14:09 +11:00
/* first check the sources list */
2009-09-13 18:16:13 +10:00
for ( s = p - > sources ; s ; s = s - > next ) {
2014-06-05 10:04:43 +00:00
if ( GUID_equal ( & s - > repsFrom1 - > source_dsa_obj_guid , guid ) ) {
2009-09-13 18:16:13 +10:00
return s ;
}
}
2010-11-08 17:14:09 +11:00
/* then the notifies list */
for ( s = p - > notifies ; s ; s = s - > next ) {
2014-06-05 10:04:43 +00:00
if ( GUID_equal ( & s - > repsFrom1 - > source_dsa_obj_guid , guid ) ) {
2010-11-08 17:14:09 +11:00
return s ;
}
}
2009-09-13 18:16:13 +10:00
return NULL ;
}
/*
schedule a replicaSync message
*/
static WERROR dreplsrv_schedule_notify_sync ( struct dreplsrv_service * service ,
struct dreplsrv_partition * p ,
struct repsFromToBlob * reps ,
TALLOC_CTX * mem_ctx ,
2010-01-21 09:20:44 -02:00
uint64_t uSN ,
2010-10-01 19:07:01 -07:00
bool is_urgent ,
uint32_t replica_flags )
2009-09-13 18:16:13 +10:00
{
struct dreplsrv_notify_operation * op ;
struct dreplsrv_partition_source_dsa * s ;
2010-11-08 17:14:09 +11:00
s = dreplsrv_find_notify_dsa ( p , & reps - > ctr . ctr1 . source_dsa_obj_guid ) ;
2009-09-13 18:16:13 +10:00
if ( s = = NULL ) {
DEBUG ( 0 , ( __location__ " : Unable to find source_dsa for %s \n " ,
GUID_string ( mem_ctx , & reps - > ctr . ctr1 . source_dsa_obj_guid ) ) ) ;
return WERR_DS_UNAVAILABLE ;
}
s4:dsdb/drepl_notify: reuse dreplsrv_notify_operation structures
Otherwise we'll requeue the same notify events on and on.
(gdb) p *((struct dreplsrv_service *) 0x1b52190)->ops.notifies
$8 = {prev = 0xe4cb30, next = 0x1a25440, service = 0x1b52190, uSN = 123905,
source_dsa = 0x164c100, is_urgent = false, replica_flags = 29}
(gdb) p *((struct dreplsrv_service *) 0x1b52190)->ops.notifies->next
$9 = {prev = 0x80e000, next = 0x1b7bf70, service = 0x1b52190, uSN = 123589,
source_dsa = 0x1a2d930, is_urgent = false, replica_flags = 29}
(gdb) p *((struct dreplsrv_service *) 0x1b52190)->ops.notifies->next->next
$10 = {prev = 0x1a25440, next = 0x1d0c310, service = 0x1b52190, uSN = 1587,
source_dsa = 0x13d3210, is_urgent = false, replica_flags = 29}
(gdb) p *((struct dreplsrv_service *) 0x1b52190)->ops.notifies->next->next->next
$11 = {prev = 0x1b7bf70, next = 0x1ba1420, service = 0x1b52190, uSN = 123905,
source_dsa = 0x164c100, is_urgent = false, replica_flags = 29}
(gdb) p *((struct dreplsrv_service *)
0x1b52190)->ops.notifies->next->next->next->next
$12 = {prev = 0x1d0c310, next = 0x1c43510, service = 0x1b52190, uSN = 123589,
source_dsa = 0x1a2d930, is_urgent = false, replica_flags = 29}
(gdb) p *((struct dreplsrv_service *)
0x1b52190)->ops.notifies->next->next->next->next->next
$13 = {prev = 0x1ba1420, next = 0xed97b0, service = 0x1b52190, uSN = 1587,
source_dsa = 0x13d3210, is_urgent = false, replica_flags = 29}
(gdb) p *((struct dreplsrv_service *)
0x1b52190)->ops.notifies->next->next->next->next->next->next
$14 = {prev = 0x1c43510, next = 0xe4ce80, service = 0x1b52190, uSN = 123905,
source_dsa = 0x164c100, is_urgent = false, replica_flags = 29}
We can reuse this operations, while they're not yet started.
metze
Autobuild-User: Stefan Metzmacher <metze@samba.org>
Autobuild-Date: Fri Nov 5 07:15:04 UTC 2010 on sn-devel-104
2010-11-04 18:07:18 +01:00
/* first try to find an existing notify operation */
for ( op = service - > ops . notifies ; op ; op = op - > next ) {
if ( op - > source_dsa ! = s ) {
continue ;
}
if ( op - > is_urgent ! = is_urgent ) {
continue ;
}
if ( op - > replica_flags ! = replica_flags ) {
continue ;
}
if ( op - > uSN < uSN ) {
op - > uSN = uSN ;
}
/* reuse the notify operation, as it's not yet started */
return WERR_OK ;
}
2009-09-13 18:16:13 +10:00
op = talloc_zero ( mem_ctx , struct dreplsrv_notify_operation ) ;
W_ERROR_HAVE_NO_MEMORY ( op ) ;
2010-10-01 19:07:01 -07:00
op - > service = service ;
op - > source_dsa = s ;
op - > uSN = uSN ;
op - > is_urgent = is_urgent ;
op - > replica_flags = replica_flags ;
2010-11-17 23:12:10 +11:00
op - > schedule_time = time ( NULL ) ;
2009-09-13 18:16:13 +10:00
2016-02-05 11:32:18 +01:00
DLIST_ADD_END ( service - > ops . notifies , op ) ;
2009-09-13 18:16:13 +10:00
talloc_steal ( service , op ) ;
return WERR_OK ;
}
/*
see if a partition has a hugher uSN than what is in the repsTo and
if so then send a DsReplicaSync
*/
static WERROR dreplsrv_notify_check ( struct dreplsrv_service * s ,
struct dreplsrv_partition * p ,
TALLOC_CTX * mem_ctx )
{
2009-09-14 03:43:26 -07:00
uint32_t count = 0 ;
2009-09-13 18:16:13 +10:00
struct repsFromToBlob * reps ;
WERROR werr ;
2010-01-21 09:20:44 -02:00
uint64_t uSNHighest ;
uint64_t uSNUrgent ;
2009-11-06 20:14:41 +01:00
uint32_t i ;
int ret ;
2009-09-13 18:16:13 +10:00
werr = dsdb_loadreps ( s - > samdb , mem_ctx , p - > dn , " repsTo " , & reps , & count ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
DEBUG ( 0 , ( __location__ " : Failed to load repsTo for %s \n " ,
ldb_dn_get_linearized ( p - > dn ) ) ) ;
return werr ;
}
2010-01-21 09:20:44 -02:00
/* loads the partition uSNHighest and uSNUrgent */
ret = dsdb_load_partition_usn ( s - > samdb , p - > dn , & uSNHighest , & uSNUrgent ) ;
if ( ret ! = LDB_SUCCESS | | uSNHighest = = 0 ) {
2009-09-13 18:16:13 +10:00
/* nothing to do */
return WERR_OK ;
}
/* see if any of our partners need some of our objects */
for ( i = 0 ; i < count ; i + + ) {
struct dreplsrv_partition_source_dsa * sdsa ;
2010-10-01 19:07:01 -07:00
uint32_t replica_flags ;
2010-11-08 17:14:09 +11:00
sdsa = dreplsrv_find_notify_dsa ( p , & reps [ i ] . ctr . ctr1 . source_dsa_obj_guid ) ;
2010-10-01 19:07:01 -07:00
replica_flags = reps [ i ] . ctr . ctr1 . replica_flags ;
2009-09-13 18:16:13 +10:00
if ( sdsa = = NULL ) continue ;
2010-01-21 09:20:44 -02:00
if ( sdsa - > notify_uSN < uSNHighest ) {
2009-09-13 18:16:13 +10:00
/* we need to tell this partner to replicate
with us */
2010-04-26 21:47:29 +10:00
bool is_urgent = sdsa - > notify_uSN < uSNUrgent ;
2010-01-21 09:20:44 -02:00
/* check if urgent replication is needed */
2010-04-26 21:47:29 +10:00
werr = dreplsrv_schedule_notify_sync ( s , p , & reps [ i ] , mem_ctx ,
2010-10-01 19:07:01 -07:00
uSNHighest , is_urgent , replica_flags ) ;
2009-09-13 18:16:13 +10:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
DEBUG ( 0 , ( __location__ " : Failed to setup notify to %s for %s \n " ,
reps [ i ] . ctr . ctr1 . other_info - > dns_name ,
ldb_dn_get_linearized ( p - > dn ) ) ) ;
return werr ;
}
2010-04-26 21:47:29 +10:00
DEBUG ( 4 , ( " queued DsReplicaSync for %s to %s (urgent=%s) uSN=%llu:%llu \n " ,
ldb_dn_get_linearized ( p - > dn ) ,
reps [ i ] . ctr . ctr1 . other_info - > dns_name ,
is_urgent ? " true " : " false " ,
( unsigned long long ) sdsa - > notify_uSN ,
( unsigned long long ) uSNHighest ) ) ;
2009-09-13 18:16:13 +10:00
}
}
return WERR_OK ;
}
/*
see if any of the partitions have changed , and if so then send a
DsReplicaSync to all the replica partners in the repsTo object
*/
static WERROR dreplsrv_notify_check_all ( struct dreplsrv_service * s , TALLOC_CTX * mem_ctx )
{
WERROR status ;
struct dreplsrv_partition * p ;
for ( p = s - > partitions ; p ; p = p - > next ) {
status = dreplsrv_notify_check ( s , p , mem_ctx ) ;
W_ERROR_NOT_OK_RETURN ( status ) ;
}
return WERR_OK ;
}
static void dreplsrv_notify_run ( struct dreplsrv_service * service ) ;
static void dreplsrv_notify_handler_te ( struct tevent_context * ev , struct tevent_timer * te ,
struct timeval t , void * ptr )
{
struct dreplsrv_service * service = talloc_get_type ( ptr , struct dreplsrv_service ) ;
WERROR status ;
service - > notify . te = NULL ;
dreplsrv_notify_run ( service ) ;
status = dreplsrv_notify_schedule ( service , service - > notify . interval ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
2009-09-18 18:05:55 -07:00
task_server_terminate ( service - > task , win_errstr ( status ) , false ) ;
2009-09-13 18:16:13 +10:00
return ;
}
}
WERROR dreplsrv_notify_schedule ( struct dreplsrv_service * service , uint32_t next_interval )
{
TALLOC_CTX * tmp_mem ;
struct tevent_timer * new_te ;
struct timeval next_time ;
/* prevent looping */
if ( next_interval = = 0 ) next_interval = 1 ;
next_time = timeval_current_ofs ( next_interval , 50 ) ;
if ( service - > notify . te ) {
/*
* if the timestamp of the new event is higher ,
* as current next we don ' t need to reschedule
*/
if ( timeval_compare ( & next_time , & service - > notify . next_event ) > 0 ) {
return WERR_OK ;
}
}
/* reset the next scheduled timestamp */
service - > notify . next_event = next_time ;
2010-05-25 15:26:00 -04:00
new_te = tevent_add_timer ( service - > task - > event_ctx , service ,
2009-09-13 18:16:13 +10:00
service - > notify . next_event ,
dreplsrv_notify_handler_te , service ) ;
W_ERROR_HAVE_NO_MEMORY ( new_te ) ;
tmp_mem = talloc_new ( service ) ;
2009-12-19 23:32:48 +11:00
DEBUG ( 4 , ( " dreplsrv_notify_schedule(%u) %sscheduled for: %s \n " ,
2009-09-13 18:16:13 +10:00
next_interval ,
( service - > notify . te ? " re " : " " ) ,
nt_time_string ( tmp_mem , timeval_to_nttime ( & next_time ) ) ) ) ;
talloc_free ( tmp_mem ) ;
talloc_free ( service - > notify . te ) ;
service - > notify . te = new_te ;
return WERR_OK ;
}
static void dreplsrv_notify_run ( struct dreplsrv_service * service )
{
TALLOC_CTX * mem_ctx ;
mem_ctx = talloc_new ( service ) ;
dreplsrv_notify_check_all ( service , mem_ctx ) ;
talloc_free ( mem_ctx ) ;
dreplsrv_run_pending_ops ( service ) ;
}