From: Stefan Metzmacher Date: Wed, 28 Jan 2009 17:55:13 +0000 (+0100) Subject: s3:ctdbd_conn: canonicalize ips before sending them to ctdbd X-Git-Url: http://git.samba.org/?p=metze%2Fsamba%2Fwip.git;a=commitdiff_plain;h=7540d13956a8a69d25f6fbbc4f9a3417e91db1d2 s3:ctdbd_conn: canonicalize ips before sending them to ctdbd This makes samba work with older ctdb versions. metze --- diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c index f8dae8fbd6ce..88d82caab83f 100644 --- a/source3/lib/ctdbd_conn.c +++ b/source3/lib/ctdbd_conn.c @@ -1176,46 +1176,76 @@ NTSTATUS ctdbd_traverse(uint32 db_id, return status; } +/* + This is used to canonicalize a ctdb_sock_addr structure. +*/ +static void smbd_ctdb_canonicalize_ip(const struct sockaddr_storage *in, + struct sockaddr_storage *out) +{ + memcpy(out, in, sizeof (*out)); + +#ifdef HAVE_IPV6 + if (in->ss_family == AF_INET6) { + const char prefix[12] = { 0,0,0,0,0,0,0,0,0,0,0xff,0xff }; + const struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)in; + struct sockaddr_in *out4 = (struct sockaddr_in *)out; + if (memcmp(&in6->sin6_addr, prefix, 12) == 0) { + memset(out, 0, sizeof(*out)); +#ifdef HAVE_SOCK_SIN_LEN + out4->sin_len = sizeof(*out); +#endif + out4->sin_family = AF_INET; + out4->sin_port = in6->sin6_port; + memcpy(&out4->sin_addr, &in6->sin6_addr.s6_addr32[3], 4); + } + } +#endif +} + /* * Register us as a server for a particular tcp connection */ NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn, - const struct sockaddr_storage *server, - const struct sockaddr_storage *client, + const struct sockaddr_storage *_server, + const struct sockaddr_storage *_client, void (*release_ip_handler)(const char *ip_addr, void *private_data), void *private_data) { - struct sockaddr *sock = (struct sockaddr *)client; /* * we still use ctdb_control_tcp for ipv4 * because we want to work against older ctdb * versions at runtime */ struct ctdb_control_tcp p4; -#ifdef HAVE_IPV6 +#ifdef HAVE_STRUCT_CTDB_CONTROL_TCP_ADDR struct ctdb_control_tcp_addr p; #endif TDB_DATA data; NTSTATUS status; + struct sockaddr_storage client; + struct sockaddr_storage server; /* * Only one connection so far */ SMB_ASSERT(conn->release_ip_handler == NULL); - switch (sock->sa_family) { + smbd_ctdb_canonicalize_ip(_client, &client); + smbd_ctdb_canonicalize_ip(_server, &server); + + switch (client.ss_family) { case AF_INET: - p4.dest = *(struct sockaddr_in *)server; - p4.src = *(struct sockaddr_in *)client; + p4.dest = *(struct sockaddr_in *)&server; + p4.src = *(struct sockaddr_in *)&client; data.dptr = (uint8_t *)&p4; data.dsize = sizeof(p4); break; -#ifdef HAVE_IPV6 +#ifdef HAVE_STRUCT_CTDB_CONTROL_TCP_ADDR case AF_INET6: - p.dest.ip6 = *(struct sockaddr_in6 *)server; - p.src.ip6 = *(struct sockaddr_in6 *)client; + p.dest.ip6 = *(struct sockaddr_in6 *)&server; + p.src.ip6 = *(struct sockaddr_in6 *)&client; data.dptr = (uint8_t *)&p; data.dsize = sizeof(p); break;