mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
s4:dsdb: add forest trust scanner service
See MS-ADTS 3.1.1.6.4 PDC Forest Trust Update It basically connects to all forest trusts and searches for crossRef objects with SYSTEM_FLAG_CR_NTDS_DOMAIN under CN=Partitions,CN=Configuration. With this information it add/removes FOREST_TRUST_SCANNER_INFO records into the msDS-TrustForestTrustInfo of the local trustedDomain object. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
parent
af0b912215
commit
f5b112b436
122
source4/dsdb/ft_scanner/ft_scanner_periodic.c
Normal file
122
source4/dsdb/ft_scanner/ft_scanner_periodic.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
Unix SMB/CIFS Implementation.
|
||||
forest trust scanner service
|
||||
|
||||
Copyright (C) Stefan Metzmacher 2025
|
||||
|
||||
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 "dsdb/samdb/samdb.h"
|
||||
#include "samba/service.h"
|
||||
#include "dsdb/ft_scanner/ft_scanner_service.h"
|
||||
#include "dsdb/ft_scanner/ft_scanner_service_proto.h"
|
||||
#include <ldb_errors.h>
|
||||
|
||||
static void ft_scanner_periodic_run(struct ft_scanner_service *service);
|
||||
|
||||
static void ft_scanner_periodic_handler_te(struct tevent_context *ev,
|
||||
struct tevent_timer *te,
|
||||
struct timeval t,
|
||||
void *ptr)
|
||||
{
|
||||
struct ft_scanner_service *service =
|
||||
talloc_get_type_abort(ptr,
|
||||
struct ft_scanner_service);
|
||||
NTSTATUS status;
|
||||
|
||||
service->periodic.te = NULL;
|
||||
|
||||
ft_scanner_periodic_run(service);
|
||||
|
||||
status = ft_scanner_periodic_schedule(service,
|
||||
service->periodic.interval);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
task_server_terminate(service->task, nt_errstr(status), false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS ft_scanner_periodic_schedule(struct ft_scanner_service *service,
|
||||
uint32_t next_interval)
|
||||
{
|
||||
TALLOC_CTX *frame = NULL;
|
||||
struct tevent_timer *new_te = NULL;
|
||||
struct timeval next_time;
|
||||
|
||||
/* prevent looping */
|
||||
if (next_interval == 0) next_interval = 1;
|
||||
|
||||
next_time = timeval_current_ofs(next_interval, 50);
|
||||
|
||||
if (service->periodic.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->periodic.next_event) > 0) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset the next scheduled timestamp */
|
||||
service->periodic.next_event = next_time;
|
||||
|
||||
new_te = tevent_add_timer(service->task->event_ctx, service,
|
||||
service->periodic.next_event,
|
||||
ft_scanner_periodic_handler_te, service);
|
||||
if (new_te == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
frame = talloc_stackframe();
|
||||
D_DEBUG("ft_scanner_periodic_schedule(%u) %sscheduled for: %s\n",
|
||||
next_interval,
|
||||
(service->periodic.te?"re":""),
|
||||
nt_time_string(frame, timeval_to_nttime(&next_time)));
|
||||
TALLOC_FREE(frame);
|
||||
|
||||
TALLOC_FREE(service->periodic.te);
|
||||
service->periodic.te = new_te;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static void ft_scanner_periodic_run(struct ft_scanner_service *service)
|
||||
{
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
NTSTATUS status;
|
||||
bool is_pdc;
|
||||
|
||||
is_pdc = samdb_is_pdc(service->l_samdb);
|
||||
if (!is_pdc) {
|
||||
DBG_DEBUG("NO-OP: we are not the current PDC\n");
|
||||
TALLOC_FREE(frame);
|
||||
return;
|
||||
}
|
||||
|
||||
DBG_DEBUG("Running ft_scanner_check_trusts()\n");
|
||||
status = ft_scanner_check_trusts(service);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DBG_WARNING("ft_scanner_check_trusts() => %s\n",
|
||||
nt_errstr(status));
|
||||
TALLOC_FREE(frame);
|
||||
return;
|
||||
}
|
||||
DBG_DEBUG("ft_scanner_check_trusts() => %s\n",
|
||||
nt_errstr(status));
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
}
|
157
source4/dsdb/ft_scanner/ft_scanner_service.c
Normal file
157
source4/dsdb/ft_scanner/ft_scanner_service.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
Unix SMB/CIFS Implementation.
|
||||
forest trust scanner service
|
||||
|
||||
Copyright (C) Stefan Metzmacher 2025
|
||||
|
||||
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 "dsdb/samdb/samdb.h"
|
||||
#include "auth/auth.h"
|
||||
#include "samba/service.h"
|
||||
#include "dsdb/ft_scanner/ft_scanner_service.h"
|
||||
#include "dsdb/ft_scanner/ft_scanner_service_proto.h"
|
||||
#include <ldb_errors.h>
|
||||
#include "lib/messaging/irpc.h"
|
||||
#include "librpc/gen_ndr/ndr_irpc.h"
|
||||
#include "param/param.h"
|
||||
#include "libds/common/roles.h"
|
||||
|
||||
static NTSTATUS ft_scanner_connect_samdb(struct ft_scanner_service *service)
|
||||
{
|
||||
struct auth_session_info *session_info = NULL;
|
||||
|
||||
session_info = system_session(service->task->lp_ctx);
|
||||
if (session_info == NULL) {
|
||||
return NT_STATUS_DS_INIT_FAILURE;
|
||||
}
|
||||
|
||||
service->l_samdb = samdb_connect(service,
|
||||
service->task->event_ctx,
|
||||
service->task->lp_ctx,
|
||||
session_info,
|
||||
NULL,
|
||||
0);
|
||||
if (service->l_samdb == NULL) {
|
||||
return NT_STATUS_DS_UNAVAILABLE;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
startup the forest trust scanner service task
|
||||
*/
|
||||
static NTSTATUS ft_scanner_task_init(struct task_server *task)
|
||||
{
|
||||
struct ft_scanner_service *service = NULL;
|
||||
uint32_t periodic_startup_interval;
|
||||
NTSTATUS status;
|
||||
bool am_rodc;
|
||||
int ret;
|
||||
|
||||
switch (lpcfg_server_role(task->lp_ctx)) {
|
||||
case ROLE_STANDALONE:
|
||||
task_server_terminate(task,
|
||||
"ft_scanner: no forest trust scanning "
|
||||
"required in standalone configuration",
|
||||
false);
|
||||
return NT_STATUS_INVALID_DOMAIN_ROLE;
|
||||
case ROLE_DOMAIN_MEMBER:
|
||||
task_server_terminate(task,
|
||||
"ft_scanner: no forest trust scanning "
|
||||
"required in domain member configuration",
|
||||
false);
|
||||
return NT_STATUS_INVALID_DOMAIN_ROLE;
|
||||
case ROLE_ACTIVE_DIRECTORY_DC:
|
||||
/* Yes, we want forest trust scanning */
|
||||
break;
|
||||
}
|
||||
|
||||
task_server_set_title(task, "task[ft_scanner]");
|
||||
|
||||
service = talloc_zero(task, struct ft_scanner_service);
|
||||
if (!service) {
|
||||
task_server_terminate(task, "ft_scanner_task_init: out of memory", true);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
service->task = task;
|
||||
service->startup_time = timeval_current();
|
||||
task->private_data = service;
|
||||
|
||||
status = ft_scanner_connect_samdb(service);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
task_server_terminate(task, talloc_asprintf(task,
|
||||
"ft_scanner: Failed to connect to local samdb: %s\n",
|
||||
nt_errstr(status)), true);
|
||||
return status;
|
||||
}
|
||||
|
||||
ret = samdb_rodc(service->l_samdb, &am_rodc);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
status = NT_STATUS_LDAP(ret);
|
||||
task_server_terminate(task, talloc_asprintf(task,
|
||||
"ft_scanner: Failed to get rodc state: %s\n",
|
||||
nt_errstr(status)), true);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (am_rodc) {
|
||||
task_server_terminate(task,
|
||||
"ft_scanner: no forest trust scanning "
|
||||
"required on RODC configuration",
|
||||
false);
|
||||
return NT_STATUS_INVALID_DOMAIN_ROLE;
|
||||
}
|
||||
|
||||
periodic_startup_interval = lpcfg_parm_int(task->lp_ctx,
|
||||
NULL,
|
||||
"ft_scanner",
|
||||
"periodic_startup_interval",
|
||||
15); /* in seconds */
|
||||
service->periodic.interval = lpcfg_parm_int(task->lp_ctx,
|
||||
NULL,
|
||||
"ft_scanner",
|
||||
"periodic_interval",
|
||||
900); /* in seconds */
|
||||
service->periodic.interval = MAX(service->periodic.interval, 60);
|
||||
|
||||
status = ft_scanner_periodic_schedule(service, periodic_startup_interval);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
task_server_terminate(task, talloc_asprintf(task,
|
||||
"ft_scanner: Failed to periodic schedule: %s\n",
|
||||
nt_errstr(status)), true);
|
||||
return status;
|
||||
}
|
||||
|
||||
irpc_add_name(task->msg_ctx, "ft_scanner");
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
register ourselves as a available server
|
||||
*/
|
||||
NTSTATUS server_service_ft_scanner_init(TALLOC_CTX *ctx)
|
||||
{
|
||||
static const struct service_details details = {
|
||||
.inhibit_fork_on_accept = true,
|
||||
.inhibit_pre_fork = true,
|
||||
.task_init = ft_scanner_task_init,
|
||||
.post_fork = NULL,
|
||||
};
|
||||
return register_server_service(ctx, "ft_scanner", &details);
|
||||
}
|
57
source4/dsdb/ft_scanner/ft_scanner_service.h
Normal file
57
source4/dsdb/ft_scanner/ft_scanner_service.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
Unix SMB/CIFS Implementation.
|
||||
forest trust scanner service
|
||||
|
||||
Copyright (C) Stefan Metzmacher 2025
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef _DSDB_FT_SCANNER_FT_SCANNER_SERVICE_H_
|
||||
#define _DSDB_FT_SCANNER_FT_SCANNER_SERVICE_H_
|
||||
|
||||
struct ft_scanner_service {
|
||||
/* the whole ft_scanner service is in one task */
|
||||
struct task_server *task;
|
||||
|
||||
/* the time the service was started */
|
||||
struct timeval startup_time;
|
||||
|
||||
/*
|
||||
* a connection to the local samdb
|
||||
*/
|
||||
struct ldb_context *l_samdb;
|
||||
|
||||
/* some stuff for periodic processing */
|
||||
struct {
|
||||
/*
|
||||
* the interval between to periodic runs
|
||||
*/
|
||||
uint32_t interval;
|
||||
|
||||
/*
|
||||
* the timestamp for the next event,
|
||||
* this is the timestamp passed to event_add_timed()
|
||||
*/
|
||||
struct timeval next_event;
|
||||
|
||||
/*
|
||||
* here we have a reference to the timed event the
|
||||
* schedules the periodic stuff
|
||||
*/
|
||||
struct tevent_timer *te;
|
||||
} periodic;
|
||||
};
|
||||
|
||||
#endif /* _DSDB_FT_SCANNER_FT_SCANNER_SERVICE_H_ */
|
1329
source4/dsdb/ft_scanner/ft_scanner_tdos.c
Normal file
1329
source4/dsdb/ft_scanner/ft_scanner_tdos.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -69,6 +69,20 @@ bld.SAMBA_MODULE('service_dns_update',
|
||||
enabled=bld.AD_DC_BUILD_IS_ENABLED()
|
||||
)
|
||||
|
||||
bld.SAMBA_MODULE('service_ft_scanner',
|
||||
source='''
|
||||
ft_scanner/ft_scanner_service.c
|
||||
ft_scanner/ft_scanner_periodic.c
|
||||
ft_scanner/ft_scanner_tdos.c
|
||||
''',
|
||||
autoproto='ft_scanner/ft_scanner_service_proto.h',
|
||||
subsystem='service',
|
||||
init_function='server_service_ft_scanner_init',
|
||||
deps='samdb process_model',
|
||||
internal_module=False,
|
||||
enabled=bld.AD_DC_BUILD_IS_ENABLED()
|
||||
)
|
||||
|
||||
pyldb_util = bld.pyembed_libname('pyldb-util')
|
||||
pyrpc_util = bld.pyembed_libname('pyrpc_util')
|
||||
pyparam_util = bld.pyembed_libname('pyparam_util')
|
||||
|
Loading…
x
Reference in New Issue
Block a user