*/
static bool kccsrv_same_source_dsa(struct repsFromToBlob *r1, struct repsFromToBlob *r2)
{
- return GUID_compare(&r1->ctr.ctr1.source_dsa_obj_guid,
- &r2->ctr.ctr1.source_dsa_obj_guid) == 0;
+ return GUID_equal(&r1->ctr.ctr1.source_dsa_obj_guid,
+ &r2->ctr.ctr1.source_dsa_obj_guid);
}
/*
make sure we only add repsFrom entries for DCs who are masters for
the partition
*/
-static bool check_MasterNC(struct kccsrv_partition *p, struct repsFromToBlob *r,
+static bool check_MasterNC(struct kccsrv_service *service, struct dsdb_ldb_dn_list_node *p, struct repsFromToBlob *r,
struct ldb_result *res)
{
struct repsFromTo1 *r1 = &r->ctr.ctr1;
struct GUID invocation_id = r1->source_dsa_invocation_id;
unsigned int i, j;
+ TALLOC_CTX *tmp_ctx;
/* we are expecting only version 1 */
SMB_ASSERT(r->version == 1);
+ tmp_ctx = talloc_new(p);
+ if (!tmp_ctx) {
+ return false;
+ }
+
for (i=0; i<res->count; i++) {
struct ldb_message *msg = res->msgs[i];
struct ldb_message_element *el;
}
}
for (j=0; j<el->num_values; j++) {
- dn = ldb_dn_from_ldb_val(p, p->service->samdb, &el->values[j]);
+ dn = ldb_dn_from_ldb_val(tmp_ctx, service->samdb, &el->values[j]);
if (!ldb_dn_validate(dn)) {
talloc_free(dn);
continue;
}
if (ldb_dn_compare(dn, p->dn) == 0) {
- talloc_free(dn);
DEBUG(5,("%s %s match on %s in %s\n",
r1->other_info->dns_name,
el->name,
ldb_dn_get_linearized(dn),
ldb_dn_get_linearized(msg->dn)));
+ talloc_free(tmp_ctx);
return true;
}
talloc_free(dn);
}
}
+ talloc_free(tmp_ctx);
return false;
}
struct kccsrv_notify_drepl_server_state *state =
tevent_req_callback_data(subreq,
struct kccsrv_notify_drepl_server_state);
- NTSTATUS status;
- status = dcerpc_dreplsrv_refresh_r_recv(subreq, state);
+ dcerpc_dreplsrv_refresh_r_recv(subreq, state);
TALLOC_FREE(subreq);
/* we don't care about errors */
DRSUAPI_DRS_PER_SYNC |
DRSUAPI_DRS_ADD_REF |
DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING |
- DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP |
DRSUAPI_DRS_NONGC_RO_REP;
}
return DRSUAPI_DRS_INIT_SYNC |
struct repsFromToBlob *reps, uint32_t count,
struct ldb_result *res)
{
- struct kccsrv_partition *p;
+ struct dsdb_ldb_dn_list_node *p;
bool notify_dreplsrv = false;
uint32_t replica_flags = kccsrv_replica_flags(s);
/* we don't have the new one - add it
* if it is a master
*/
- if (res && !check_MasterNC(p, &reps[i], res)) {
+ if (res && !check_MasterNC(s, p, &reps[i], res)) {
/* its not a master, we don't
want to pull from it */
continue;
/* remove any stale ones */
for (i=0; i<our_count; i++) {
if (!reps_in_list(&our_reps[i], reps, count) ||
- (res && !check_MasterNC(p, &our_reps[i], res))) {
+ (res && !check_MasterNC(s, p, &our_reps[i], res))) {
DEBUG(4,(__location__ ": Removed repsFrom for %s\n",
our_reps[i].ctr.ctr1.other_info->dns_name));
memmove(&our_reps[i], &our_reps[i+1], (our_count-(i+1))*sizeof(our_reps[0]));
struct GUID ntds_guid, invocation_id;
ntds_guid = samdb_result_guid(res->msgs[i], "objectGUID");
- if (GUID_compare(&ntds_guid, &s->ntds_guid) == 0) {
+ if (GUID_equal(&ntds_guid, &s->ntds_guid)) {
/* don't replicate with ourselves */
continue;
}
return WERR_OK;
}
+/*
+ * check to see if any dns entries need scavenging
+ */
+static NTSTATUS kccsrv_dns_zone_scavenging(
+ struct kccsrv_service *s,
+ TALLOC_CTX *mem_ctx)
+{
+
+ time_t current_time = time(NULL);
+ time_t dns_scavenge_interval;
+ time_t dns_collection_interval;
+
+ NTSTATUS status;
+ char *error_string = NULL;
+
+ /*
+ * Only perform zone scavenging if it's been enabled.
+ */
+ if (!lpcfg_dns_zone_scavenging(s->task->lp_ctx)) {
+ return NT_STATUS_OK;
+ }
+
+ dns_scavenge_interval = lpcfg_parm_int(s->task->lp_ctx,
+ NULL,
+ "dnsserver",
+ "scavenging_interval",
+ 2 * 60 * 60);
+ dns_collection_interval =
+ lpcfg_parm_int(s->task->lp_ctx,
+ NULL,
+ "dnsserver",
+ "tombstone_collection_interval",
+ 24 * 60 * 60);
+ if ((current_time - s->last_dns_scavenge) > dns_scavenge_interval) {
+ s->last_dns_scavenge = current_time;
+ status = dns_tombstone_records(mem_ctx, s->samdb,
+ &error_string);
+ if (!NT_STATUS_IS_OK(status)) {
+ const char *err = NULL;
+ if (error_string != NULL) {
+ err = error_string;
+ } else {
+ err = nt_errstr(status);
+ }
+ DBG_ERR("DNS record scavenging process failed: %s",
+ err);
+ return status;
+ }
+ }
+
+ if ((current_time - s->last_dns_tombstone_collection) >
+ dns_collection_interval) {
+ s->last_dns_tombstone_collection = current_time;
+ status = dns_delete_tombstones(mem_ctx, s->samdb,
+ &error_string);
+ if (!NT_STATUS_IS_OK(status)) {
+ const char *err = NULL;
+ if (error_string != NULL) {
+ err = error_string;
+ } else {
+ err = nt_errstr(status);
+ }
+ DBG_ERR("DNS tombstone deletion failed: %s", err);
+ return status;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ check to see if any deleted objects need scavenging
+ */
+static NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx)
+{
+ time_t current_time = time(NULL);
+ time_t interval = lpcfg_parm_int(
+ s->task->lp_ctx, NULL, "kccsrv", "check_deleted_interval", 86400);
+ uint32_t tombstoneLifetime;
+ int ret;
+ unsigned int num_objects_removed = 0;
+ unsigned int num_links_removed = 0;
+ NTSTATUS status;
+ char *error_string = NULL;
+
+ if (current_time - s->last_deleted_check < interval) {
+ return NT_STATUS_OK;
+ }
+
+ ret = dsdb_tombstone_lifetime(s->samdb, &tombstoneLifetime);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(1,(__location__ ": Failed to get tombstone lifetime\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ s->last_deleted_check = current_time;
+
+ status = dsdb_garbage_collect_tombstones(mem_ctx, s->samdb,
+ s->partitions,
+ current_time, tombstoneLifetime,
+ &num_objects_removed,
+ &num_links_removed,
+ &error_string);
+
+ if (NT_STATUS_IS_OK(status)) {
+ DEBUG(5, ("garbage_collect_tombstones: Removed %u tombstone objects "
+ "and %u tombstone links successfully\n",
+ num_objects_removed, num_links_removed));
+ } else {
+ DEBUG(2, ("garbage_collect_tombstones: Failure removing tombstone "
+ "objects and links after removing %u tombstone objects "
+ "and %u tombstone links successfully: %s\n",
+ num_objects_removed, num_links_removed,
+ error_string ? error_string : nt_errstr(status)));
+ }
+ return status;
+}
+
static void kccsrv_periodic_run(struct kccsrv_service *service)
{
TALLOC_CTX *mem_ctx;
mem_ctx = talloc_new(service);
if (service->samba_kcc_code)
- status = kccsrv_samba_kcc(service, mem_ctx);
+ status = kccsrv_samba_kcc(service);
else {
status = kccsrv_simple_update(service, mem_ctx);
if (!NT_STATUS_IS_OK(status))
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("kccsrv_check_deleted failed - %s\n", nt_errstr(status)));
}
+ status = kccsrv_dns_zone_scavenging(service, mem_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("kccsrv_dns_zone_scavenging failed - %s\n",
+ nt_errstr(status));
+ }
talloc_free(mem_ctx);
}
/* Invocation of the samba_kcc python script for replication
* topology generation.
*/
-NTSTATUS kccsrv_samba_kcc(struct kccsrv_service *service,
- TALLOC_CTX *ctxp)
+NTSTATUS kccsrv_samba_kcc(struct kccsrv_service *service)
{
NTSTATUS status = NT_STATUS_OK;
const char * const *samba_kcc_command =
/* kill any existing child */
TALLOC_FREE(service->periodic.subreq);
- DEBUG(0,("Calling samba_kcc script\n"));
+ DEBUG(2, ("Calling samba_kcc script\n"));
service->periodic.subreq = samba_runcmd_send(service,
service->task->event_ctx,
timeval_current_ofs(40, 0),