2010-09-07 23:18:53 +04:00
/*
2007-01-23 19:06:47 +03:00
Unix SMB / CIFS mplementation .
DSDB replication service
2010-09-07 23:18:53 +04:00
2007-01-23 19:06:47 +03:00
Copyright ( C ) Stefan Metzmacher 2007
2010-09-07 23:18:53 +04:00
Copyright ( C ) Kamen Mazdrashki < kamenim @ samba . org > 2010
2007-01-23 19:06:47 +03: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
2007-01-23 19:06:47 +03:00
( at your option ) any later version .
2010-09-07 23:18:53 +04:00
2007-01-23 19:06:47 +03: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 .
2010-09-07 23:18:53 +04:00
2007-01-23 19:06:47 +03: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/>.
2010-09-07 23:18:53 +04:00
2007-01-23 19:06:47 +03:00
*/
# include "includes.h"
# include "dsdb/samdb/samdb.h"
# include "auth/auth.h"
# include "smbd/service.h"
# include "lib/events/events.h"
# include "dsdb/repl/drepl_service.h"
2011-02-10 06:12:51 +03:00
# include <ldb_errors.h>
2008-10-11 23:31:42 +04:00
# include "../lib/util/dlinklist.h"
2007-01-23 19:06:47 +03:00
# include "librpc/gen_ndr/ndr_misc.h"
# include "librpc/gen_ndr/ndr_drsuapi.h"
# include "librpc/gen_ndr/ndr_drsblobs.h"
2010-08-28 21:00:39 +04:00
# include "librpc/gen_ndr/ndr_irpc.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2015-12-28 22:01:54 +03:00
# include "libds/common/roles.h"
2007-01-23 19:06:47 +03:00
2010-09-07 18:00:20 +04:00
/**
* Call - back data for _drepl_replica_sync_done_cb ( )
*/
struct drepl_replica_sync_cb_data {
struct irpc_message * msg ;
struct drsuapi_DsReplicaSync * r ;
/* number of ops left to be completed */
int ops_count ;
/* last failure error code */
WERROR werr_last_failure ;
} ;
2007-01-23 19:06:47 +03:00
static WERROR dreplsrv_init_creds ( struct dreplsrv_service * service )
{
2009-10-25 09:19:03 +03:00
service - > system_session_info = system_session ( service - > task - > lp_ctx ) ;
if ( service - > system_session_info = = NULL ) {
2015-12-03 17:24:18 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2007-01-23 19:06:47 +03:00
}
return WERR_OK ;
}
2007-12-02 19:56:09 +03:00
static WERROR dreplsrv_connect_samdb ( struct dreplsrv_service * service , struct loadparm_context * lp_ctx )
2007-01-23 19:06:47 +03:00
{
2007-04-23 04:43:47 +04:00
const struct GUID * ntds_guid ;
struct drsuapi_DsBindInfo28 * bind_info28 ;
2010-10-10 19:00:45 +04:00
service - > samdb = samdb_connect ( service , service - > task - > event_ctx , lp_ctx , service - > system_session_info , 0 ) ;
2007-01-23 19:06:47 +03:00
if ( ! service - > samdb ) {
2009-07-31 20:15:39 +04:00
return WERR_DS_UNAVAILABLE ;
2007-01-23 19:06:47 +03:00
}
2007-04-23 04:43:47 +04:00
ntds_guid = samdb_ntds_objectGUID ( service - > samdb ) ;
if ( ! ntds_guid ) {
2009-07-31 20:15:39 +04:00
return WERR_DS_UNAVAILABLE ;
2007-01-23 19:06:47 +03:00
}
2007-04-23 04:43:47 +04:00
service - > ntds_guid = * ntds_guid ;
2010-09-15 14:24:50 +04:00
if ( samdb_rodc ( service - > samdb , & service - > am_rodc ) ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( __location__ " : Failed to determine RODC status \n " ) ) ;
return WERR_DS_UNAVAILABLE ;
}
2007-04-23 04:43:47 +04:00
bind_info28 = & service - > bind_info28 ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_BASE ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2 ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1 ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2 ;
2009-09-03 06:51:42 +04:00
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION ;
2007-04-23 04:43:47 +04:00
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2 ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01 ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3 ;
2010-02-02 15:28:57 +03:00
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V5 ;
2007-04-23 04:43:47 +04:00
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2 ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6 ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8 ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5 ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6 ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3 ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7 ;
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT ;
#if 0 /* we don't support XPRESS compression yet */
bind_info28 - > supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS ;
# endif
/* TODO: fill in site_guid */
bind_info28 - > site_guid = GUID_zero ( ) ;
/* TODO: find out how this is really triggered! */
2008-07-22 17:35:23 +04:00
bind_info28 - > pid = 0 ;
2007-04-23 04:43:47 +04:00
bind_info28 - > repl_epoch = 0 ;
2007-01-23 19:06:47 +03:00
return WERR_OK ;
}
2007-04-23 04:43:47 +04:00
2010-09-03 05:29:02 +04:00
2010-09-07 18:00:20 +04:00
/**
* Callback for dreplsrv_out_operation operation completion .
*
* We just need to complete a waiting IRPC message here .
* In case pull operation has failed ,
* caller of this callback will dump
* failure information .
*
* NOTE : cb_data is allocated in IRPC msg ' s context
* and will be freed during irpc_send_reply ( ) call .
*/
static void _drepl_replica_sync_done_cb ( struct dreplsrv_service * service ,
WERROR werr ,
enum drsuapi_DsExtendedError ext_err ,
void * cb_data )
{
struct drepl_replica_sync_cb_data * data = talloc_get_type ( cb_data ,
struct drepl_replica_sync_cb_data ) ;
struct irpc_message * msg = data - > msg ;
struct drsuapi_DsReplicaSync * r = data - > r ;
/* store last bad result */
2011-02-27 00:01:20 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
2010-09-07 18:00:20 +04:00
data - > werr_last_failure = werr ;
}
/* decrement pending ops count */
data - > ops_count - - ;
if ( data - > ops_count = = 0 ) {
/* Return result to client */
r - > out . result = data - > werr_last_failure ;
/* complete IRPC message */
irpc_send_reply ( msg , NT_STATUS_OK ) ;
}
}
/**
* Helper to schedule a replication operation with a source DSA .
* If ' data ' is valid pointer , then a callback
* for the operation is passed and ' data - > msg ' is
* marked as ' deferred ' - defer_reply = true
*/
static WERROR _drepl_schedule_replication ( struct dreplsrv_service * service ,
struct dreplsrv_partition_source_dsa * dsa ,
struct drsuapi_DsReplicaObjectIdentifier * nc ,
2011-02-26 21:36:19 +03:00
uint32_t rep_options ,
2010-09-07 18:00:20 +04:00
struct drepl_replica_sync_cb_data * data ,
TALLOC_CTX * mem_ctx )
{
WERROR werr ;
2010-09-15 12:59:17 +04:00
dreplsrv_extended_callback_t fn_callback = NULL ;
2010-09-07 18:00:20 +04:00
if ( data ) {
fn_callback = _drepl_replica_sync_done_cb ;
}
/* schedule replication item */
2011-02-26 21:36:19 +03:00
werr = dreplsrv_schedule_partition_pull_source ( service , dsa , rep_options ,
2010-09-07 18:00:20 +04:00
DRSUAPI_EXOP_NONE , 0 ,
fn_callback , data ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
DEBUG ( 0 , ( " %s: failed setup of sync of partition (%s, %s, %s) - %s \n " ,
__FUNCTION__ ,
GUID_string ( mem_ctx , & nc - > guid ) ,
nc - > dn ,
dsa - > repsFrom1 - > other_info - > dns_name ,
win_errstr ( werr ) ) ) ;
return werr ;
}
/* log we've scheduled a replication item */
DEBUG ( 3 , ( " %s: forcing sync of partition (%s, %s, %s) \n " ,
__FUNCTION__ ,
GUID_string ( mem_ctx , & nc - > guid ) ,
nc - > dn ,
dsa - > repsFrom1 - > other_info - > dns_name ) ) ;
/* mark IRPC message as deferred if necessary */
if ( data ) {
data - > ops_count + + ;
data - > msg - > defer_reply = true ;
}
return WERR_OK ;
}
2009-09-09 12:04:07 +04:00
/*
DsReplicaSync messages from the DRSUAPI server are forwarded here
*/
2010-09-07 23:18:53 +04:00
static NTSTATUS drepl_replica_sync ( struct irpc_message * msg ,
2009-09-09 12:04:07 +04:00
struct drsuapi_DsReplicaSync * r )
{
2010-09-03 05:29:02 +04:00
WERROR werr ;
struct dreplsrv_partition * p ;
2010-09-07 18:00:20 +04:00
struct drepl_replica_sync_cb_data * cb_data ;
2010-09-03 05:29:02 +04:00
struct dreplsrv_partition_source_dsa * dsa ;
struct drsuapi_DsReplicaSyncRequest1 * req1 ;
struct drsuapi_DsReplicaObjectIdentifier * nc ;
2009-09-09 12:04:07 +04:00
struct dreplsrv_service * service = talloc_get_type ( msg - > private_data ,
struct dreplsrv_service ) ;
2010-09-07 22:22:47 +04:00
# define REPLICA_SYNC_FAIL(_msg, _werr) do {\
2010-11-27 22:12:25 +03:00
if ( ! W_ERROR_IS_OK ( _werr ) ) { \
2010-09-07 22:22:47 +04:00
DEBUG ( 0 , ( __location__ " : Failure - %s. werr = %s \n " , \
_msg , win_errstr ( _werr ) ) ) ; \
NDR_PRINT_IN_DEBUG ( drsuapi_DsReplicaSync , r ) ; \
} \
r - > out . result = _werr ; \
goto done ; \
} while ( 0 )
2010-09-03 05:29:02 +04:00
if ( r - > in . level ! = 1 ) {
2010-09-07 22:22:47 +04:00
REPLICA_SYNC_FAIL ( " Unsupported level " ,
WERR_DS_DRA_INVALID_PARAMETER ) ;
2010-09-03 05:29:02 +04:00
}
req1 = & r - > in . req - > req1 ;
nc = req1 - > naming_context ;
/* Check input parameters */
if ( ! nc ) {
2010-09-07 22:22:47 +04:00
REPLICA_SYNC_FAIL ( " Invalid Naming Context " ,
WERR_DS_DRA_INVALID_PARAMETER ) ;
2010-09-03 05:29:02 +04:00
}
/* Find Naming context to be synchronized */
werr = dreplsrv_partition_find_for_nc ( service ,
& nc - > guid , & nc - > sid , nc - > dn ,
& p ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2010-09-07 22:22:47 +04:00
REPLICA_SYNC_FAIL ( " Failed to find requested Naming Context " ,
werr ) ;
2010-09-03 05:29:02 +04:00
}
2010-09-07 18:00:20 +04:00
/* should we process it asynchronously? */
if ( req1 - > options & DRSUAPI_DRS_ASYNC_OP ) {
cb_data = NULL ;
} else {
cb_data = talloc_zero ( msg , struct drepl_replica_sync_cb_data ) ;
if ( ! cb_data ) {
2017-02-17 22:50:45 +03:00
REPLICA_SYNC_FAIL ( " Not enough memory " ,
2010-09-07 22:22:47 +04:00
WERR_DS_DRA_INTERNAL_ERROR ) ;
2010-09-07 18:00:20 +04:00
}
cb_data - > msg = msg ;
cb_data - > r = r ;
cb_data - > werr_last_failure = WERR_OK ;
}
2010-09-03 05:29:02 +04:00
/* collect source DSAs to sync with */
if ( req1 - > options & DRSUAPI_DRS_SYNC_ALL ) {
for ( dsa = p - > sources ; dsa ; dsa = dsa - > next ) {
/* schedule replication item */
2011-02-26 21:36:19 +03:00
werr = _drepl_schedule_replication ( service , dsa , nc ,
req1 - > options , cb_data , msg ) ;
2010-09-03 05:29:02 +04:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
2010-09-07 22:22:47 +04:00
REPLICA_SYNC_FAIL ( " _drepl_schedule_replication() failed " ,
werr ) ;
2010-09-03 05:29:02 +04:00
}
}
2009-09-09 12:04:07 +04:00
} else {
2010-09-03 05:29:02 +04:00
if ( req1 - > options & DRSUAPI_DRS_SYNC_BYNAME ) {
/* client should pass at least valid string */
if ( ! req1 - > source_dsa_dns ) {
2010-09-07 22:22:47 +04:00
REPLICA_SYNC_FAIL ( " 'source_dsa_dns' is not valid " ,
WERR_DS_DRA_INVALID_PARAMETER ) ;
2010-09-03 05:29:02 +04:00
}
werr = dreplsrv_partition_source_dsa_by_dns ( p ,
req1 - > source_dsa_dns ,
& dsa ) ;
} else {
/* client should pass at least some GUID */
if ( GUID_all_zero ( & req1 - > source_dsa_guid ) ) {
2010-09-07 22:22:47 +04:00
REPLICA_SYNC_FAIL ( " 'source_dsa_guid' is not valid " ,
WERR_DS_DRA_INVALID_PARAMETER ) ;
2010-09-03 05:29:02 +04:00
}
werr = dreplsrv_partition_source_dsa_by_guid ( p ,
& req1 - > source_dsa_guid ,
& dsa ) ;
2011-09-21 02:56:32 +04:00
if ( W_ERROR_EQUAL ( werr , WERR_DS_DRA_NO_REPLICA ) ) {
/* we don't have this source setup as
a replication partner . Create a
temporary dsa structure for this
replication */
werr = dreplsrv_partition_source_dsa_temporary ( p ,
msg ,
& req1 - > source_dsa_guid ,
& dsa ) ;
}
2010-09-03 05:29:02 +04:00
}
if ( ! W_ERROR_IS_OK ( werr ) ) {
2010-09-07 22:22:47 +04:00
REPLICA_SYNC_FAIL ( " Failed to locate source DSA for given NC " ,
2010-11-27 22:13:02 +03:00
werr ) ;
2010-09-03 05:29:02 +04:00
}
/* schedule replication item */
2011-02-26 21:36:19 +03:00
werr = _drepl_schedule_replication ( service , dsa , nc ,
req1 - > options , cb_data , msg ) ;
2010-09-03 05:29:02 +04:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
2010-09-07 22:22:47 +04:00
REPLICA_SYNC_FAIL ( " _drepl_schedule_replication() failed " ,
werr ) ;
2010-09-03 05:29:02 +04:00
}
2009-09-09 12:04:07 +04:00
}
2010-09-03 05:29:02 +04:00
/* if we got here, everything is OK */
r - > out . result = WERR_OK ;
2011-02-27 00:13:49 +03:00
/*
* schedule replication event to force
* replication as soon as possible
*/
2013-05-15 15:46:33 +04:00
dreplsrv_pendingops_schedule ( service , 0 ) ;
2010-09-03 05:29:02 +04:00
done :
2009-09-09 12:04:07 +04:00
return NT_STATUS_OK ;
}
2010-08-28 21:00:39 +04:00
/**
* Called when drplsrv should refresh its state .
* For example , when KCC change topology , dreplsrv
* should update its cache
*
* @ param partition_dn If not empty / NULL , partition to update
*/
static NTSTATUS dreplsrv_refresh ( struct irpc_message * msg ,
struct dreplsrv_refresh * r )
{
struct dreplsrv_service * s = talloc_get_type ( msg - > private_data ,
struct dreplsrv_service ) ;
2010-09-05 23:54:05 +04:00
r - > out . result = dreplsrv_refresh_partitions ( s ) ;
2010-08-28 21:00:39 +04:00
return NT_STATUS_OK ;
}
2010-09-12 04:06:39 +04:00
/**
* Called when the auth code wants us to try and replicate
* a users secrets
*/
static NTSTATUS drepl_trigger_repl_secret ( struct irpc_message * msg ,
struct drepl_trigger_repl_secret * r )
{
2010-09-15 12:59:17 +04:00
struct dreplsrv_service * service = talloc_get_type ( msg - > private_data ,
struct dreplsrv_service ) ;
drepl_repl_secret ( service , r - > in . user_dn ) ;
2010-09-12 04:06:39 +04:00
/* we are not going to be sending a reply to this request */
msg - > no_reply = true ;
2010-09-15 12:59:17 +04:00
2010-09-12 04:06:39 +04:00
return NT_STATUS_OK ;
}
2010-09-15 12:59:17 +04:00
2010-09-16 07:02:23 +04:00
/*
DsReplicaAdd messages from the DRSUAPI server are forwarded here
*/
static NTSTATUS dreplsrv_replica_add ( struct irpc_message * msg ,
struct drsuapi_DsReplicaAdd * r )
{
struct dreplsrv_service * service = talloc_get_type ( msg - > private_data ,
struct dreplsrv_service ) ;
return drepl_replica_add ( service , r ) ;
}
/*
DsReplicaDel messages from the DRSUAPI server are forwarded here
*/
static NTSTATUS dreplsrv_replica_del ( struct irpc_message * msg ,
struct drsuapi_DsReplicaDel * r )
{
struct dreplsrv_service * service = talloc_get_type ( msg - > private_data ,
struct dreplsrv_service ) ;
return drepl_replica_del ( service , r ) ;
}
/*
DsReplicaMod messages from the DRSUAPI server are forwarded here
*/
static NTSTATUS dreplsrv_replica_mod ( struct irpc_message * msg ,
struct drsuapi_DsReplicaMod * r )
{
struct dreplsrv_service * service = talloc_get_type ( msg - > private_data ,
struct dreplsrv_service ) ;
return drepl_replica_mod ( service , r ) ;
}
2007-01-23 19:06:47 +03:00
/*
startup the dsdb replicator service task
*/
static void dreplsrv_task_init ( struct task_server * task )
{
WERROR status ;
struct dreplsrv_service * service ;
2007-04-25 06:43:23 +04:00
uint32_t periodic_startup_interval ;
2007-01-23 19:06:47 +03:00
2010-07-16 08:32:42 +04:00
switch ( lpcfg_server_role ( task - > lp_ctx ) ) {
2007-01-23 19:06:47 +03:00
case ROLE_STANDALONE :
2010-09-07 23:18:53 +04:00
task_server_terminate ( task , " dreplsrv: no DSDB replication required in standalone configuration " ,
2009-09-19 05:05:55 +04:00
false ) ;
2007-01-23 19:06:47 +03:00
return ;
case ROLE_DOMAIN_MEMBER :
2010-09-07 23:18:53 +04:00
task_server_terminate ( task , " dreplsrv: no DSDB replication required in domain member configuration " ,
2009-09-19 05:05:55 +04:00
false ) ;
2007-01-23 19:06:47 +03:00
return ;
2012-06-10 16:08:20 +04:00
case ROLE_ACTIVE_DIRECTORY_DC :
2007-01-23 19:06:47 +03:00
/* Yes, we want DSDB replication */
break ;
}
task_server_set_title ( task , " task[dreplsrv] " ) ;
service = talloc_zero ( task , struct dreplsrv_service ) ;
if ( ! service ) {
2009-09-19 05:05:55 +04:00
task_server_terminate ( task , " dreplsrv_task_init: out of memory " , true ) ;
2007-01-23 19:06:47 +03:00
return ;
}
service - > task = task ;
service - > startup_time = timeval_current ( ) ;
2009-02-02 12:21:51 +03:00
task - > private_data = service ;
2007-01-23 19:06:47 +03:00
status = dreplsrv_init_creds ( service ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
task_server_terminate ( task , talloc_asprintf ( task ,
" dreplsrv: Failed to obtain server credentials: %s \n " ,
2009-09-19 05:05:55 +04:00
win_errstr ( status ) ) , true ) ;
2007-01-23 19:06:47 +03:00
return ;
}
2007-12-02 19:56:09 +03:00
status = dreplsrv_connect_samdb ( service , task - > lp_ctx ) ;
2007-01-23 19:06:47 +03:00
if ( ! W_ERROR_IS_OK ( status ) ) {
task_server_terminate ( task , talloc_asprintf ( task ,
" dreplsrv: Failed to connect to local samdb: %s \n " ,
2009-09-19 05:05:55 +04:00
win_errstr ( status ) ) , true ) ;
2007-01-23 19:06:47 +03:00
return ;
}
2007-04-23 04:43:47 +04:00
status = dreplsrv_load_partitions ( service ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
task_server_terminate ( task , talloc_asprintf ( task ,
" dreplsrv: Failed to load partitions: %s \n " ,
2009-09-19 05:05:55 +04:00
win_errstr ( status ) ) , true ) ;
2007-04-23 04:43:47 +04:00
return ;
}
2010-07-16 08:32:42 +04:00
periodic_startup_interval = lpcfg_parm_int ( task - > lp_ctx , NULL , " dreplsrv " , " periodic_startup_interval " , 15 ) ; /* in seconds */
service - > periodic . interval = lpcfg_parm_int ( task - > lp_ctx , NULL , " dreplsrv " , " periodic_interval " , 300 ) ; /* in seconds */
2007-01-23 19:06:47 +03:00
2007-04-25 06:43:23 +04:00
status = dreplsrv_periodic_schedule ( service , periodic_startup_interval ) ;
2007-01-23 19:06:47 +03:00
if ( ! W_ERROR_IS_OK ( status ) ) {
task_server_terminate ( task , talloc_asprintf ( task ,
" dreplsrv: Failed to periodic schedule: %s \n " ,
2009-09-19 05:05:55 +04:00
win_errstr ( status ) ) , true ) ;
2007-01-23 19:06:47 +03:00
return ;
}
2010-03-24 19:02:36 +03:00
/* if we are a RODC then we do not send DSReplicaSync*/
2010-09-15 14:24:50 +04:00
if ( ! service - > am_rodc ) {
2010-07-16 08:32:42 +04:00
service - > notify . interval = lpcfg_parm_int ( task - > lp_ctx , NULL , " dreplsrv " ,
2010-03-24 19:02:36 +03:00
" notify_interval " , 5 ) ; /* in seconds */
status = dreplsrv_notify_schedule ( service , service - > notify . interval ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
task_server_terminate ( task , talloc_asprintf ( task ,
" dreplsrv: Failed to setup notify schedule: %s \n " ,
win_errstr ( status ) ) , true ) ;
return ;
}
2009-09-13 12:16:13 +04:00
}
2007-01-23 19:06:47 +03:00
irpc_add_name ( task - > msg_ctx , " dreplsrv " ) ;
2009-09-09 12:04:07 +04:00
2010-08-28 21:00:39 +04:00
IRPC_REGISTER ( task - > msg_ctx , irpc , DREPLSRV_REFRESH , dreplsrv_refresh , service ) ;
2009-09-09 12:04:07 +04:00
IRPC_REGISTER ( task - > msg_ctx , drsuapi , DRSUAPI_DSREPLICASYNC , drepl_replica_sync , service ) ;
2010-09-16 07:02:23 +04:00
IRPC_REGISTER ( task - > msg_ctx , drsuapi , DRSUAPI_DSREPLICAADD , dreplsrv_replica_add , service ) ;
IRPC_REGISTER ( task - > msg_ctx , drsuapi , DRSUAPI_DSREPLICADEL , dreplsrv_replica_del , service ) ;
IRPC_REGISTER ( task - > msg_ctx , drsuapi , DRSUAPI_DSREPLICAMOD , dreplsrv_replica_mod , service ) ;
2010-08-25 01:26:28 +04:00
IRPC_REGISTER ( task - > msg_ctx , irpc , DREPL_TAKEFSMOROLE , drepl_take_FSMO_role , service ) ;
2010-09-12 04:06:39 +04:00
IRPC_REGISTER ( task - > msg_ctx , irpc , DREPL_TRIGGER_REPL_SECRET , drepl_trigger_repl_secret , service ) ;
2011-05-03 04:40:33 +04:00
imessaging_register ( task - > msg_ctx , service , MSG_DREPL_ALLOCATE_RID , dreplsrv_allocate_rid ) ;
2007-01-23 19:06:47 +03:00
}
/*
register ourselves as a available server
*/
2017-04-20 22:24:43 +03:00
NTSTATUS server_service_drepl_init ( TALLOC_CTX * ctx )
2007-01-23 19:06:47 +03:00
{
2017-05-09 23:46:45 +03:00
return register_server_service ( ctx , " drepl " , dreplsrv_task_init ) ;
2007-01-23 19:06:47 +03:00
}