From 6b5b882073fa80c3ea7cbe52546cdc7a23a3444e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 29 Sep 2010 12:17:05 +0200 Subject: [PATCH] s3: Add "smbcontrol winbindd ip-dropped " This is supposed to improve the winbind reconnect time after an ip address has been moved away from a box. Any kind of HA scenario will benefit from this, because winbindd does not have to wait for the TCP timeout to kick in when a local IP address has been dropped and DC replies are not received anymore. --- source3/librpc/gen_ndr/messaging.h | 2 + source3/librpc/gen_ndr/ndr_messaging.c | 1 + source3/librpc/idl/messaging.idl | 1 + source3/utils/smbcontrol.c | 17 +++++++++ source3/winbindd/winbindd.c | 4 ++ source3/winbindd/winbindd_cm.c | 53 ++++++++++++++++++++++++++ source3/winbindd/winbindd_dual.c | 4 ++ source3/winbindd/winbindd_proto.h | 10 +++++ 8 files changed, 92 insertions(+) diff --git a/source3/librpc/gen_ndr/messaging.h b/source3/librpc/gen_ndr/messaging.h index 913201345a..bfb3242954 100644 --- a/source3/librpc/gen_ndr/messaging.h +++ b/source3/librpc/gen_ndr/messaging.h @@ -61,6 +61,7 @@ enum messaging_type MSG_WINBIND_FAILED_TO_GO_ONLINE=0x0407, MSG_WINBIND_VALIDATE_CACHE=0x0408, MSG_WINBIND_DUMP_DOMAIN_LIST=0x0409, + MSG_WINBIND_IP_DROPPED=0x040A, MSG_DUMP_EVENT_LIST=0x0500, MSG_DBWRAP_TDB2_CHANGES=4001, MSG_DBWRAP_G_LOCK_RETRY=4002 @@ -117,6 +118,7 @@ enum messaging_type #define MSG_WINBIND_FAILED_TO_GO_ONLINE ( 0x0407 ) #define MSG_WINBIND_VALIDATE_CACHE ( 0x0408 ) #define MSG_WINBIND_DUMP_DOMAIN_LIST ( 0x0409 ) +#define MSG_WINBIND_IP_DROPPED ( 0x040A ) #define MSG_DUMP_EVENT_LIST ( 0x0500 ) #define MSG_DBWRAP_TDB2_CHANGES ( 4001 ) #define MSG_DBWRAP_G_LOCK_RETRY ( 4002 ) diff --git a/source3/librpc/gen_ndr/ndr_messaging.c b/source3/librpc/gen_ndr/ndr_messaging.c index 02ff382197..6f84caf126 100644 --- a/source3/librpc/gen_ndr/ndr_messaging.c +++ b/source3/librpc/gen_ndr/ndr_messaging.c @@ -72,6 +72,7 @@ _PUBLIC_ void ndr_print_messaging_type(struct ndr_print *ndr, const char *name, case MSG_WINBIND_FAILED_TO_GO_ONLINE: val = "MSG_WINBIND_FAILED_TO_GO_ONLINE"; break; case MSG_WINBIND_VALIDATE_CACHE: val = "MSG_WINBIND_VALIDATE_CACHE"; break; case MSG_WINBIND_DUMP_DOMAIN_LIST: val = "MSG_WINBIND_DUMP_DOMAIN_LIST"; break; + case MSG_WINBIND_IP_DROPPED: val = "MSG_WINBIND_IP_DROPPED"; break; case MSG_DUMP_EVENT_LIST: val = "MSG_DUMP_EVENT_LIST"; break; case MSG_DBWRAP_TDB2_CHANGES: val = "MSG_DBWRAP_TDB2_CHANGES"; break; case MSG_DBWRAP_G_LOCK_RETRY: val = "MSG_DBWRAP_G_LOCK_RETRY"; break; diff --git a/source3/librpc/idl/messaging.idl b/source3/librpc/idl/messaging.idl index 08caa59508..9041d2284d 100644 --- a/source3/librpc/idl/messaging.idl +++ b/source3/librpc/idl/messaging.idl @@ -83,6 +83,7 @@ interface messaging MSG_WINBIND_FAILED_TO_GO_ONLINE = 0x0407, MSG_WINBIND_VALIDATE_CACHE = 0x0408, MSG_WINBIND_DUMP_DOMAIN_LIST = 0x0409, + MSG_WINBIND_IP_DROPPED = 0x040A, /* event messages */ MSG_DUMP_EVENT_LIST = 0x0500, diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 1c2bb5003d..b27b8cb561 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -714,6 +714,22 @@ static bool do_closeshare(struct messaging_context *msg_ctx, strlen(argv[1]) + 1); } +/* Tell winbindd an IP got dropped */ + +static bool do_ip_dropped(struct messaging_context *msg_ctx, + const struct server_id pid, + const int argc, const char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: smbcontrol ip-dropped " + "\n"); + return False; + } + + return send_message(msg_ctx, pid, MSG_WINBIND_IP_DROPPED, argv[1], + strlen(argv[1]) + 1); +} + /* force a blocking lock retry */ static bool do_lockretry(struct messaging_context *msg_ctx, @@ -1181,6 +1197,7 @@ static const struct { { "debuglevel", do_debuglevel, "Display current debuglevels" }, { "printnotify", do_printnotify, "Send a print notify message" }, { "close-share", do_closeshare, "Forcibly disconnect a share" }, + { "ip-dropped", do_ip_dropped, "Tell winbind that an IP got dropped" }, { "lockretry", do_lockretry, "Force a blocking lock retry" }, { "brl-revalidate", do_brl_revalidate, "Revalidate all brl entries" }, { "samsync", do_samsync, "Initiate SAM synchronisation" }, diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index fbaa10c5c4..ee40187fd2 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -1376,6 +1376,10 @@ int main(int argc, char **argv, char **envp) MSG_WINBIND_DUMP_DOMAIN_LIST, winbind_msg_dump_domain_list); + messaging_register(winbind_messaging_context(), NULL, + MSG_WINBIND_IP_DROPPED, + winbind_msg_ip_dropped_parent); + /* Register handler for MSG_DEBUG. */ messaging_register(winbind_messaging_context(), NULL, MSG_DEBUG, diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index e3a0b59934..ece68f1a1d 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2485,3 +2485,56 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, *cli = conn->netlogon_pipe; return NT_STATUS_OK; } + +void winbind_msg_ip_dropped(struct messaging_context *msg_ctx, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data) +{ + struct winbindd_domain *domain; + + if ((data == NULL) + || (data->data == NULL) + || (data->length == 0) + || (data->data[data->length-1] != '\0') + || !is_ipaddress((char *)data->data)) { + DEBUG(1, ("invalid msg_ip_dropped message\n")); + return; + } + for (domain = domain_list(); domain != NULL; domain = domain->next) { + char sockaddr[INET6_ADDRSTRLEN]; + if (domain->conn.cli == NULL) { + continue; + } + if (domain->conn.cli->fd == -1) { + continue; + } + client_socket_addr(domain->conn.cli->fd, sockaddr, + sizeof(sockaddr)); + if (strequal(sockaddr, (char *)data->data)) { + close(domain->conn.cli->fd); + domain->conn.cli->fd = -1; + } + } +} + +extern struct winbindd_child *children; + +void winbind_msg_ip_dropped_parent(struct messaging_context *msg_ctx, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data) +{ + struct winbindd_child *child; + + winbind_msg_ip_dropped(msg_ctx, private_data, msg_type, + server_id, data); + + + for (child = children; child != NULL; child = child->next) { + messaging_send_buf(msg_ctx, pid_to_procid(child->pid), + msg_type, data->data, data->length); + } +} diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index a5ba9e0116..efe15138bb 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -1390,6 +1390,10 @@ static bool fork_domain_child(struct winbindd_child *child) MSG_DUMP_EVENT_LIST, child_msg_dump_event_list); messaging_register(winbind_messaging_context(), NULL, MSG_DEBUG, debug_message); + messaging_register(winbind_messaging_context(), NULL, + MSG_WINBIND_IP_DROPPED, + winbind_msg_ip_dropped); + primary_domain = find_our_domain(); diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index d9421ecbf9..d666639420 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -342,6 +342,16 @@ void winbind_msg_dump_domain_list(struct messaging_context *msg_ctx, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data); +void winbind_msg_ip_dropped(struct messaging_context *msg_ctx, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data); +void winbind_msg_ip_dropped_parent(struct messaging_context *msg_ctx, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data); bool winbindd_reinit_after_fork(const char *logfilename); /* The following definitions come from winbindd/winbindd_group.c */ -- 2.34.1