mirror of
https://github.com/samba-team/samba.git
synced 2025-03-09 08:58:35 +03:00
s3:winbind: Get rid of the winbind dc-connect child
The new code uses PING_DC to tell the child to try to go online. Pair-Programmed-With: Andreas Schneider <asn@samba.org> Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> Signed-off-by: Andreas Schneider <asn@samba.org> Signed-off-by: Isaac Boukris <iboukris@samba.org> Signed-off-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
parent
9f63240503
commit
17c86a2c5a
@ -122,8 +122,7 @@ interface messaging
|
||||
MSG_WINBIND_ONLINE = 0x0403,
|
||||
MSG_WINBIND_OFFLINE = 0x0404,
|
||||
MSG_WINBIND_ONLINESTATUS = 0x0405,
|
||||
MSG_WINBIND_TRY_TO_GO_ONLINE = 0x0406,
|
||||
MSG_WINBIND_FAILED_TO_GO_ONLINE = 0x0407,
|
||||
|
||||
MSG_WINBIND_VALIDATE_CACHE = 0x0408,
|
||||
MSG_WINBIND_DUMP_DOMAIN_LIST = 0x0409,
|
||||
MSG_WINBIND_IP_DROPPED = 0x040A,
|
||||
|
@ -1383,6 +1383,8 @@ static void winbindd_register_handlers(struct messaging_context *msg_ctx,
|
||||
{
|
||||
bool scan_trusts = true;
|
||||
NTSTATUS status;
|
||||
struct tevent_timer *te = NULL;
|
||||
|
||||
/* Setup signal handlers */
|
||||
|
||||
if (!winbindd_setup_sig_term_handler(true))
|
||||
@ -1486,6 +1488,16 @@ static void winbindd_register_handlers(struct messaging_context *msg_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
te = tevent_add_timer(global_event_context(),
|
||||
NULL,
|
||||
timeval_zero(),
|
||||
winbindd_ping_offline_domains,
|
||||
NULL);
|
||||
if (te == NULL) {
|
||||
DBG_ERR("Failed to schedule winbindd_ping_offline_domains()\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
status = wb_irpc_register();
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
|
@ -158,8 +158,8 @@ struct winbindd_domain {
|
||||
void *private_data;
|
||||
|
||||
/* A working DC */
|
||||
pid_t dc_probe_pid; /* Child we're using to detect the DC. */
|
||||
char *dcname;
|
||||
const char *ping_dcname;
|
||||
struct sockaddr_storage dcaddr;
|
||||
|
||||
/* Sequence number stuff */
|
||||
@ -179,10 +179,7 @@ struct winbindd_domain {
|
||||
struct tevent_queue *queue;
|
||||
struct dcerpc_binding_handle *binding_handle;
|
||||
|
||||
/* Callback we use to try put us back online. */
|
||||
|
||||
uint32_t check_online_timeout;
|
||||
struct tevent_timer *check_online_event;
|
||||
struct tevent_req *check_online_event;
|
||||
|
||||
/* Linked list info */
|
||||
|
||||
|
@ -87,6 +87,7 @@
|
||||
#include "lib/gencache.h"
|
||||
#include "lib/util/string_wrappers.h"
|
||||
#include "lib/global_contexts.h"
|
||||
#include "librpc/gen_ndr/ndr_winbind_c.h"
|
||||
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_WINBIND
|
||||
@ -106,256 +107,6 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
|
||||
struct dc_name_ip **dcs, int *num_dcs,
|
||||
uint32_t request_flags);
|
||||
|
||||
/****************************************************************
|
||||
Child failed to find DC's. Reschedule check.
|
||||
****************************************************************/
|
||||
|
||||
static void msg_failed_to_go_online(struct messaging_context *msg,
|
||||
void *private_data,
|
||||
uint32_t msg_type,
|
||||
struct server_id server_id,
|
||||
DATA_BLOB *data)
|
||||
{
|
||||
struct winbindd_domain *domain;
|
||||
const char *domainname = (const char *)data->data;
|
||||
|
||||
if (data->data == NULL || data->length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname));
|
||||
|
||||
for (domain = domain_list(); domain; domain = domain->next) {
|
||||
if (domain->internal) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strequal(domain->name, domainname)) {
|
||||
if (domain->online) {
|
||||
/* We're already online, ignore. */
|
||||
DEBUG(5,("msg_fail_to_go_online: domain %s "
|
||||
"already online.\n", domainname));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Reschedule the online check. */
|
||||
set_domain_offline(domain);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
Actually cause a reconnect from a message.
|
||||
****************************************************************/
|
||||
|
||||
static void msg_try_to_go_online(struct messaging_context *msg,
|
||||
void *private_data,
|
||||
uint32_t msg_type,
|
||||
struct server_id server_id,
|
||||
DATA_BLOB *data)
|
||||
{
|
||||
struct winbindd_domain *domain;
|
||||
const char *domainname = (const char *)data->data;
|
||||
|
||||
if (data->data == NULL || data->length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname));
|
||||
|
||||
for (domain = domain_list(); domain; domain = domain->next) {
|
||||
if (domain->internal) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strequal(domain->name, domainname)) {
|
||||
|
||||
if (domain->online) {
|
||||
/* We're already online, ignore. */
|
||||
DEBUG(5,("msg_try_to_go_online: domain %s "
|
||||
"already online.\n", domainname));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* This call takes care of setting the online
|
||||
flag to true if we connected, or re-adding
|
||||
the offline handler if false. Bypasses online
|
||||
check so always does network calls. */
|
||||
|
||||
init_dc_connection_network(domain, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
Fork a child to try and contact a DC. Do this as contacting a
|
||||
DC requires blocking lookups and we don't want to block our
|
||||
parent.
|
||||
****************************************************************/
|
||||
|
||||
static bool fork_child_dc_connect(struct winbindd_domain *domain)
|
||||
{
|
||||
struct dc_name_ip *dcs = NULL;
|
||||
int num_dcs = 0;
|
||||
TALLOC_CTX *mem_ctx = NULL;
|
||||
pid_t parent_pid = getpid();
|
||||
char *lfile = NULL;
|
||||
NTSTATUS status;
|
||||
bool ok;
|
||||
|
||||
if (domain->dc_probe_pid != (pid_t)-1) {
|
||||
/*
|
||||
* We might already have a DC probe
|
||||
* child working, check.
|
||||
*/
|
||||
if (process_exists_by_pid(domain->dc_probe_pid)) {
|
||||
DEBUG(10,("fork_child_dc_connect: pid %u already "
|
||||
"checking for DC's.\n",
|
||||
(unsigned int)domain->dc_probe_pid));
|
||||
return true;
|
||||
}
|
||||
domain->dc_probe_pid = (pid_t)-1;
|
||||
}
|
||||
|
||||
domain->dc_probe_pid = fork();
|
||||
|
||||
if (domain->dc_probe_pid == (pid_t)-1) {
|
||||
DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (domain->dc_probe_pid != (pid_t)0) {
|
||||
/* Parent */
|
||||
messaging_register(global_messaging_context(), NULL,
|
||||
MSG_WINBIND_TRY_TO_GO_ONLINE,
|
||||
msg_try_to_go_online);
|
||||
messaging_register(global_messaging_context(), NULL,
|
||||
MSG_WINBIND_FAILED_TO_GO_ONLINE,
|
||||
msg_failed_to_go_online);
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Child. */
|
||||
|
||||
/* Leave messages blocked - we will never process one. */
|
||||
|
||||
if (!override_logfile) {
|
||||
if (asprintf(&lfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) == -1) {
|
||||
DBG_ERR("fork_child_dc_connect: "
|
||||
"out of memory in asprintf().\n");
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
status = winbindd_reinit_after_fork(NULL, lfile);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
|
||||
nt_errstr(status)));
|
||||
messaging_send_buf(global_messaging_context(),
|
||||
pid_to_procid(parent_pid),
|
||||
MSG_WINBIND_FAILED_TO_GO_ONLINE,
|
||||
(const uint8_t *)domain->name,
|
||||
strlen(domain->name)+1);
|
||||
_exit(1);
|
||||
}
|
||||
SAFE_FREE(lfile);
|
||||
|
||||
setproctitle("dc-connect child");
|
||||
|
||||
mem_ctx = talloc_init("fork_child_dc_connect");
|
||||
if (!mem_ctx) {
|
||||
DEBUG(0,("talloc_init failed.\n"));
|
||||
messaging_send_buf(global_messaging_context(),
|
||||
pid_to_procid(parent_pid),
|
||||
MSG_WINBIND_FAILED_TO_GO_ONLINE,
|
||||
(const uint8_t *)domain->name,
|
||||
strlen(domain->name)+1);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
ok = get_dcs(mem_ctx, domain, &dcs, &num_dcs, 0);
|
||||
TALLOC_FREE(mem_ctx);
|
||||
if (!ok || (num_dcs == 0)) {
|
||||
/* Still offline ? Can't find DC's. */
|
||||
messaging_send_buf(global_messaging_context(),
|
||||
pid_to_procid(parent_pid),
|
||||
MSG_WINBIND_FAILED_TO_GO_ONLINE,
|
||||
(const uint8_t *)domain->name,
|
||||
strlen(domain->name)+1);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
/* We got a DC. Send a message to our parent to get it to
|
||||
try and do the same. */
|
||||
|
||||
messaging_send_buf(global_messaging_context(),
|
||||
pid_to_procid(parent_pid),
|
||||
MSG_WINBIND_TRY_TO_GO_ONLINE,
|
||||
(const uint8_t *)domain->name,
|
||||
strlen(domain->name)+1);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
Handler triggered if we're offline to try and detect a DC.
|
||||
****************************************************************/
|
||||
|
||||
static void check_domain_online_handler(struct tevent_context *ctx,
|
||||
struct tevent_timer *te,
|
||||
struct timeval now,
|
||||
void *private_data)
|
||||
{
|
||||
struct winbindd_domain *domain =
|
||||
(struct winbindd_domain *)private_data;
|
||||
|
||||
DEBUG(10,("check_domain_online_handler: called for domain "
|
||||
"%s (online = %s)\n", domain->name,
|
||||
domain->online ? "True" : "False" ));
|
||||
|
||||
TALLOC_FREE(domain->check_online_event);
|
||||
|
||||
/* Are we still in "startup" mode ? */
|
||||
|
||||
if (domain->startup && (time_mono(NULL) > domain->startup_time + 30)) {
|
||||
/* No longer in "startup" mode. */
|
||||
DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
|
||||
domain->name ));
|
||||
domain->startup = False;
|
||||
}
|
||||
|
||||
/* We've been told to stay offline, so stay
|
||||
that way. */
|
||||
|
||||
if (get_global_winbindd_state_offline()) {
|
||||
DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
|
||||
domain->name ));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fork a child to test if it can contact a DC.
|
||||
If it can then send ourselves a message to
|
||||
cause a reconnect. */
|
||||
|
||||
fork_child_dc_connect(domain);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
If we're still offline setup the timeout check.
|
||||
****************************************************************/
|
||||
|
||||
static void calc_new_online_timeout_check(struct winbindd_domain *domain)
|
||||
{
|
||||
int wbr = lp_winbind_reconnect_delay();
|
||||
|
||||
if (domain->startup) {
|
||||
domain->check_online_timeout = 10;
|
||||
} else if (domain->check_online_timeout < wbr) {
|
||||
domain->check_online_timeout = wbr;
|
||||
}
|
||||
}
|
||||
|
||||
void winbind_msg_domain_offline(struct messaging_context *msg_ctx,
|
||||
void *private_data,
|
||||
uint32_t msg_type,
|
||||
@ -367,13 +118,15 @@ void winbind_msg_domain_offline(struct messaging_context *msg_ctx,
|
||||
|
||||
domain = find_domain_from_name_noinit(domain_name);
|
||||
if (domain == NULL) {
|
||||
DBG_DEBUG("Domain %s not found!\n", domain_name);
|
||||
return;
|
||||
}
|
||||
|
||||
domain->online = false;
|
||||
DBG_DEBUG("Domain %s was %s, change to offline now.\n",
|
||||
domain_name,
|
||||
domain->online ? "online" : "offline");
|
||||
|
||||
DEBUG(10, ("Domain %s is marked as offline now.\n",
|
||||
domain_name));
|
||||
domain->online = false;
|
||||
}
|
||||
|
||||
void winbind_msg_domain_online(struct messaging_context *msg_ctx,
|
||||
@ -390,10 +143,13 @@ void winbind_msg_domain_online(struct messaging_context *msg_ctx,
|
||||
return;
|
||||
}
|
||||
|
||||
domain->online = true;
|
||||
SMB_ASSERT(wb_child_domain() == NULL);
|
||||
|
||||
DEBUG(10, ("Domain %s is marked as online now.\n",
|
||||
domain_name));
|
||||
DBG_DEBUG("Domain %s was %s, marking as online now!\n",
|
||||
domain_name,
|
||||
domain->online ? "online" : "offline");
|
||||
|
||||
domain->online = true;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
@ -408,8 +164,6 @@ void set_domain_offline(struct winbindd_domain *domain)
|
||||
DEBUG(10,("set_domain_offline: called for domain %s\n",
|
||||
domain->name ));
|
||||
|
||||
TALLOC_FREE(domain->check_online_event);
|
||||
|
||||
if (domain->internal) {
|
||||
DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
|
||||
domain->name ));
|
||||
@ -423,35 +177,6 @@ void set_domain_offline(struct winbindd_domain *domain)
|
||||
|
||||
domain->initialized = True;
|
||||
|
||||
/* We only add the timeout handler that checks and
|
||||
allows us to go back online when we've not
|
||||
been told to remain offline. */
|
||||
|
||||
if (get_global_winbindd_state_offline()) {
|
||||
DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
|
||||
domain->name ));
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we're in startup mode, check again in 10 seconds, not in
|
||||
lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */
|
||||
|
||||
calc_new_online_timeout_check(domain);
|
||||
|
||||
domain->check_online_event = tevent_add_timer(global_event_context(),
|
||||
NULL,
|
||||
timeval_current_ofs(domain->check_online_timeout,0),
|
||||
check_domain_online_handler,
|
||||
domain);
|
||||
|
||||
/* The above *has* to succeed for winbindd to work. */
|
||||
if (!domain->check_online_event) {
|
||||
smb_panic("set_domain_offline: failed to add online handler");
|
||||
}
|
||||
|
||||
DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
|
||||
domain->name ));
|
||||
|
||||
/* Send a message to the parent that the domain is offline. */
|
||||
if (parent_pid > 1 && !domain->internal) {
|
||||
messaging_send_buf(global_messaging_context(),
|
||||
@ -463,7 +188,6 @@ void set_domain_offline(struct winbindd_domain *domain)
|
||||
|
||||
/* Send an offline message to the idmap child when our
|
||||
primary domain goes offline */
|
||||
|
||||
if ( domain->primary ) {
|
||||
pid_t idmap_pid = idmap_child_pid();
|
||||
|
||||
@ -526,16 +250,6 @@ static void set_domain_online(struct winbindd_domain *domain)
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure we have no online timeout checks. */
|
||||
domain->check_online_timeout = 0;
|
||||
TALLOC_FREE(domain->check_online_event);
|
||||
|
||||
/* Ensure we ignore any pending child messages. */
|
||||
messaging_deregister(global_messaging_context(),
|
||||
MSG_WINBIND_TRY_TO_GO_ONLINE, NULL);
|
||||
messaging_deregister(global_messaging_context(),
|
||||
MSG_WINBIND_FAILED_TO_GO_ONLINE, NULL);
|
||||
|
||||
domain->online = True;
|
||||
|
||||
/* Send a message to the parent that the domain is online. */
|
||||
@ -571,7 +285,9 @@ static void set_domain_online(struct winbindd_domain *domain)
|
||||
|
||||
void set_domain_online_request(struct winbindd_domain *domain)
|
||||
{
|
||||
struct timeval tev;
|
||||
NTSTATUS status;
|
||||
|
||||
SMB_ASSERT(wb_child_domain() || idmap_child());
|
||||
|
||||
DEBUG(10,("set_domain_online_request: called for domain %s\n",
|
||||
domain->name ));
|
||||
@ -588,42 +304,17 @@ void set_domain_online_request(struct winbindd_domain *domain)
|
||||
return;
|
||||
}
|
||||
|
||||
/* We've been told it's safe to go online and
|
||||
try and connect to a DC. But I don't believe it
|
||||
because network manager seems to lie.
|
||||
Wait at least 5 seconds. Heuristics suck... */
|
||||
|
||||
|
||||
GetTimeOfDay(&tev);
|
||||
|
||||
/* Go into "startup" mode again. */
|
||||
domain->startup_time = time_mono(NULL);
|
||||
domain->startup = True;
|
||||
|
||||
tev.tv_sec += 5;
|
||||
|
||||
if (!domain->check_online_event) {
|
||||
/* If we've come from being globally offline we
|
||||
don't have a check online event handler set.
|
||||
We need to add one now we're trying to go
|
||||
back online. */
|
||||
|
||||
DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
|
||||
domain->name ));
|
||||
}
|
||||
|
||||
TALLOC_FREE(domain->check_online_event);
|
||||
|
||||
domain->check_online_event = tevent_add_timer(global_event_context(),
|
||||
NULL,
|
||||
tev,
|
||||
check_domain_online_handler,
|
||||
domain);
|
||||
|
||||
/* The above *has* to succeed for winbindd to work. */
|
||||
if (!domain->check_online_event) {
|
||||
smb_panic("set_domain_online_request: failed to add online handler");
|
||||
}
|
||||
/*
|
||||
* This call takes care of setting the online flag to true if we
|
||||
* connected, or tell the parent to ping us back if false. Bypasses
|
||||
* online check so always does network calls.
|
||||
*/
|
||||
status = init_dc_connection_network(domain, true);
|
||||
DBG_DEBUG("init_dc_connection_network(), returned %s, called for "
|
||||
"domain %s (online = %s)\n",
|
||||
nt_errstr(status),
|
||||
domain->name,
|
||||
domain->online ? "true" : "false");
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
@ -2242,10 +1933,7 @@ NTSTATUS init_dc_connection(struct winbindd_domain *domain, bool need_rw_dc)
|
||||
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||
}
|
||||
|
||||
if (domain->initialized && !domain->online) {
|
||||
/* We check for online status elsewhere. */
|
||||
return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
|
||||
}
|
||||
SMB_ASSERT(wb_child_domain() || idmap_child());
|
||||
|
||||
return init_dc_connection_network(domain, need_rw_dc);
|
||||
}
|
||||
|
@ -1026,7 +1026,7 @@ void winbind_msg_offline(struct messaging_context *msg_ctx,
|
||||
continue;
|
||||
}
|
||||
DEBUG(5,("winbind_msg_offline: marking %s offline.\n", domain->name));
|
||||
set_domain_offline(domain);
|
||||
domain->online = false;
|
||||
}
|
||||
|
||||
forall_domain_children(winbind_msg_on_offline_fn, &state);
|
||||
@ -1044,7 +1044,6 @@ void winbind_msg_online(struct messaging_context *msg_ctx,
|
||||
.msg_ctx = msg_ctx,
|
||||
.msg_type = MSG_WINBIND_ONLINE,
|
||||
};
|
||||
struct winbindd_domain *domain;
|
||||
|
||||
DEBUG(10,("winbind_msg_online: got online message.\n"));
|
||||
|
||||
@ -1059,32 +1058,7 @@ void winbind_msg_online(struct messaging_context *msg_ctx,
|
||||
smb_nscd_flush_user_cache();
|
||||
smb_nscd_flush_group_cache();
|
||||
|
||||
/* Set all our domains as online. */
|
||||
for (domain = domain_list(); domain; domain = domain->next) {
|
||||
if (domain->internal) {
|
||||
continue;
|
||||
}
|
||||
DEBUG(5,("winbind_msg_online: requesting %s to go online.\n", domain->name));
|
||||
|
||||
winbindd_flush_negative_conn_cache(domain);
|
||||
set_domain_online_request(domain);
|
||||
|
||||
/* Send an online message to the idmap child when our
|
||||
primary domain comes back online */
|
||||
|
||||
if ( domain->primary ) {
|
||||
pid_t idmap_pid = idmap_child_pid();
|
||||
|
||||
if (idmap_pid != 0) {
|
||||
messaging_send_buf(msg_ctx,
|
||||
pid_to_procid(idmap_pid),
|
||||
MSG_WINBIND_ONLINE,
|
||||
(const uint8_t *)domain->name,
|
||||
strlen(domain->name)+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell all our child domains to go online online. */
|
||||
forall_domain_children(winbind_msg_on_offline_fn, &state);
|
||||
}
|
||||
|
||||
@ -1832,8 +1806,7 @@ static bool fork_domain_child(struct winbindd_child *child)
|
||||
}
|
||||
|
||||
/*
|
||||
* We are in idmap child, make sure that we set the
|
||||
* check_online_event to bring primary domain online.
|
||||
* We are in idmap child, bring primary domain online.
|
||||
*/
|
||||
if (is_idmap_child(child)) {
|
||||
set_domain_online_request(primary_domain);
|
||||
|
@ -153,7 +153,6 @@ void ndr_print_winbindd_domain(struct ndr_print *ndr,
|
||||
for (i=0; i<lp_winbind_max_domain_connections(); i++) {
|
||||
ndr_print_winbindd_child(ndr, "children", &r->children[i]);
|
||||
}
|
||||
ndr_print_uint32(ndr, "check_online_timeout", r->check_online_timeout);
|
||||
ndr_print_ptr(ndr, "check_online_event", r->check_online_event);
|
||||
ndr->depth--;
|
||||
}
|
||||
|
@ -479,6 +479,10 @@ bool add_trusted_domain_from_auth(uint16_t validation_level,
|
||||
bool domain_is_forest_root(const struct winbindd_domain *domain);
|
||||
void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te,
|
||||
struct timeval now, void *private_data);
|
||||
void winbindd_ping_offline_domains(struct tevent_context *ev,
|
||||
struct tevent_timer *te,
|
||||
struct timeval now,
|
||||
void *private_data);
|
||||
enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain,
|
||||
struct winbindd_cli_state *state);
|
||||
bool init_domain_list(void);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "lib/util/smb_strtox.h"
|
||||
#include "lib/util/string_wrappers.h"
|
||||
#include "lib/global_contexts.h"
|
||||
#include "librpc/gen_ndr/ndr_winbind_c.h"
|
||||
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_WINBIND
|
||||
@ -251,8 +252,6 @@ static NTSTATUS add_trusted_domain(const char *domain_name,
|
||||
domain->last_seq_check = 0;
|
||||
domain->initialized = false;
|
||||
domain->online = is_internal_domain(sid);
|
||||
domain->check_online_timeout = 0;
|
||||
domain->dc_probe_pid = (pid_t)-1;
|
||||
domain->domain_flags = trust_flags;
|
||||
domain->domain_type = trust_type;
|
||||
domain->domain_trust_attribs = trust_attribs;
|
||||
@ -798,6 +797,93 @@ void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te,
|
||||
return;
|
||||
}
|
||||
|
||||
static void wbd_ping_dc_done(struct tevent_req *subreq);
|
||||
|
||||
void winbindd_ping_offline_domains(struct tevent_context *ev,
|
||||
struct tevent_timer *te,
|
||||
struct timeval now,
|
||||
void *private_data)
|
||||
{
|
||||
struct winbindd_domain *domain = NULL;
|
||||
|
||||
TALLOC_FREE(te);
|
||||
|
||||
for (domain = domain_list(); domain != NULL; domain = domain->next) {
|
||||
DBG_DEBUG("Domain %s is %s\n",
|
||||
domain->name,
|
||||
domain->online ? "online" : "offline");
|
||||
|
||||
if (get_global_winbindd_state_offline()) {
|
||||
DBG_DEBUG("We are globally offline, do nothing.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (domain->online ||
|
||||
domain->check_online_event != NULL ||
|
||||
domain->secure_channel_type == SEC_CHAN_NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
winbindd_flush_negative_conn_cache(domain);
|
||||
|
||||
domain->check_online_event =
|
||||
dcerpc_wbint_PingDc_send(domain,
|
||||
ev,
|
||||
dom_child_handle(domain),
|
||||
&domain->ping_dcname);
|
||||
if (domain->check_online_event == NULL) {
|
||||
DBG_WARNING("Failed to schedule ping, no-memory\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(domain->check_online_event,
|
||||
wbd_ping_dc_done, domain);
|
||||
}
|
||||
|
||||
te = tevent_add_timer(ev,
|
||||
NULL,
|
||||
timeval_current_ofs(lp_winbind_reconnect_delay(),
|
||||
0),
|
||||
winbindd_ping_offline_domains,
|
||||
NULL);
|
||||
if (te == NULL) {
|
||||
DBG_ERR("Failed to schedule winbindd_ping_offline_domains()\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void wbd_ping_dc_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct winbindd_domain *domain =
|
||||
tevent_req_callback_data(subreq,
|
||||
struct winbindd_domain);
|
||||
NTSTATUS status, result;
|
||||
|
||||
SMB_ASSERT(subreq == domain->check_online_event);
|
||||
domain->check_online_event = NULL;
|
||||
|
||||
status = dcerpc_wbint_PingDc_recv(subreq, domain, &result);
|
||||
TALLOC_FREE(subreq);
|
||||
if (any_nt_status_not_ok(status, result, &status)) {
|
||||
DBG_WARNING("dcerpc_wbint_PingDc_recv failed for domain: "
|
||||
"%s - %s\n",
|
||||
domain->name,
|
||||
nt_errstr(status));
|
||||
return;
|
||||
}
|
||||
|
||||
DBG_DEBUG("dcerpc_wbint_PingDc_recv() succeeded, "
|
||||
"domain: %s, dc-name: %s\n",
|
||||
domain->name,
|
||||
domain->ping_dcname);
|
||||
|
||||
talloc_free(discard_const(domain->ping_dcname));
|
||||
domain->ping_dcname = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain,
|
||||
struct winbindd_cli_state *state)
|
||||
{
|
||||
@ -941,14 +1027,6 @@ static bool add_trusted_domains_dc(void)
|
||||
nt_errstr(status));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Even in the parent winbindd we'll need to
|
||||
talk to the DC, so try and see if we can
|
||||
contact it. Theoretically this isn't necessary
|
||||
as the init_dc_connection() in init_child_recv()
|
||||
will do this, but we can start detecting the DC
|
||||
early here. */
|
||||
set_domain_online_request(domain);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1014,16 +1092,6 @@ static bool add_trusted_domains_dc(void)
|
||||
}
|
||||
domain->domain_type = domains[i]->trust_type;
|
||||
domain->domain_trust_attribs = domains[i]->trust_attributes;
|
||||
|
||||
if (sec_chan_type != SEC_CHAN_NULL) {
|
||||
/* Even in the parent winbindd we'll need to
|
||||
talk to the DC, so try and see if we can
|
||||
contact it. Theoretically this isn't necessary
|
||||
as the init_dc_connection() in init_child_recv()
|
||||
will do this, but we can start detecting the DC
|
||||
early here. */
|
||||
set_domain_online_request(domain);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_domains; i++) {
|
||||
@ -1308,14 +1376,6 @@ bool init_domain_list(void)
|
||||
"domain to winbindd's internal list\n");
|
||||
return false;
|
||||
}
|
||||
/* Even in the parent winbindd we'll need to
|
||||
talk to the DC, so try and see if we can
|
||||
contact it. Theoretically this isn't necessary
|
||||
as the init_dc_connection() in init_child_recv()
|
||||
will do this, but we can start detecting the DC
|
||||
early here. */
|
||||
set_domain_online_request(domain);
|
||||
|
||||
}
|
||||
|
||||
status = imessaging_register(winbind_imessaging_context(), NULL,
|
||||
|
Loading…
x
Reference in New Issue
Block a user