X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Fwinbindd%2Fwinbindd_cm.c;h=d76fce7a51fe1d4b1d73735165b4cd053ec079fd;hb=d94b5e95d394f180aaa296310b57a2932e3f8e2a;hp=5a6f9e2f6b951f633466e649f6003977685aff7a;hpb=2fc3e7f2ed11b1beee8dab35f05baaa4f2d19ecd;p=obnox%2Fsamba-ctdb.git diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 5a6f9e2f6b..d76fce7a51 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -1380,6 +1380,88 @@ static bool find_new_dc(TALLOC_CTX *mem_ctx, goto again; } +static char *current_dc_key(TALLOC_CTX *mem_ctx, const char *domain_name) +{ + return talloc_asprintf_strupper_m(mem_ctx, "CURRENT_DCNAME/%s", + domain_name); +} + +static void store_current_dc_in_gencache(const char *domain_name, + const char *dc_name, + struct cli_state *cli) +{ + char addr[INET6_ADDRSTRLEN]; + char *key, *value; + + if (cli == NULL) { + return; + } + if (cli->fd == -1) { + return; + } + get_peer_addr(cli->fd, addr, sizeof(addr)); + + key = current_dc_key(talloc_tos(), domain_name); + if (key == NULL) { + goto done; + } + + value = talloc_asprintf(talloc_tos(), "%s %s", addr, dc_name); + if (value == NULL) { + goto done; + } + + gencache_set(key, value, 0x7fffffff); +done: + TALLOC_FREE(value); + TALLOC_FREE(key); +} + +bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx, + const char *domain_name, + char **p_dc_name, char **p_dc_ip) +{ + char *key, *value, *p; + bool ret = false; + char *dc_name = NULL; + char *dc_ip = NULL; + + key = current_dc_key(talloc_tos(), domain_name); + if (key == NULL) { + goto done; + } + if (!gencache_get(key, &value, NULL)) { + goto done; + } + p = strchr(value, ' '); + if (p == NULL) { + goto done; + } + dc_ip = talloc_strndup(mem_ctx, value, p - value); + if (dc_ip == NULL) { + goto done; + } + dc_name = talloc_strdup(mem_ctx, p+1); + if (dc_name == NULL) { + goto done; + } + + if (p_dc_ip != NULL) { + *p_dc_ip = dc_ip; + dc_ip = NULL; + } + if (p_dc_name != NULL) { + *p_dc_name = dc_name; + dc_name = NULL; + } + ret = true; +done: + TALLOC_FREE(dc_name); + TALLOC_FREE(dc_ip); + TALLOC_FREE(key); + return ret; +} + static NTSTATUS cm_open_connection(struct winbindd_domain *domain, struct winbindd_cm_conn *new_conn) { @@ -1480,6 +1562,17 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain, set_global_winbindd_state_online(); } set_domain_online(domain); + + /* + * Much as I hate global state, this seems to be the point + * where we can be certain that we have a proper connection to + * a DC. wbinfo --dc-info needs that information, store it in + * gencache with a looong timeout. This will need revisiting + * once we start to connect to multiple DCs, wbcDcInfo is + * already prepared for that. + */ + store_current_dc_in_gencache(domain->name, domain->dcname, + new_conn->cli); } else { /* Ensure we setup the retry handler. */ set_domain_offline(domain); @@ -2461,15 +2554,42 @@ void winbind_msg_ip_dropped(struct messaging_context *msg_ctx, DATA_BLOB *data) { struct winbindd_domain *domain; + char *freeit = NULL; + char *addr; 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")); + || (data->data[data->length-1] != '\0')) { + DEBUG(1, ("invalid msg_ip_dropped message: not a valid " + "string\n")); return; } + + addr = (char *)data->data; + DEBUG(10, ("IP %s dropped\n", addr)); + + if (!is_ipaddress(addr)) { + char *slash; + /* + * Some code sends us ip addresses with the /netmask + * suffix + */ + slash = strchr(addr, '/'); + if (slash == NULL) { + DEBUG(1, ("invalid msg_ip_dropped message: %s", + addr)); + return; + } + freeit = talloc_strndup(talloc_tos(), addr, slash-addr); + if (freeit == NULL) { + DEBUG(1, ("talloc failed\n")); + return; + } + addr = freeit; + DEBUG(10, ("Stripped /netmask to IP %s\n", addr)); + } + for (domain = domain_list(); domain != NULL; domain = domain->next) { char sockaddr[INET6_ADDRSTRLEN]; if (domain->conn.cli == NULL) { @@ -2480,11 +2600,12 @@ void winbind_msg_ip_dropped(struct messaging_context *msg_ctx, } client_socket_addr(domain->conn.cli->fd, sockaddr, sizeof(sockaddr)); - if (strequal(sockaddr, (char *)data->data)) { + if (strequal(sockaddr, addr)) { close(domain->conn.cli->fd); domain->conn.cli->fd = -1; } } + TALLOC_FREE(freeit); } extern struct winbindd_child *children;