diff options
author | Stefan Metzmacher <metze@samba.org> | 2009-01-28 18:55:13 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2009-01-29 17:40:13 +0100 |
commit | 7540d13956a8a69d25f6fbbc4f9a3417e91db1d2 (patch) | |
tree | 14e5784e6488348d2ca52b0365281bcb854e8a40 /source3 | |
parent | ba482e6b8d375449bcce52bfa383b95046d89fc1 (diff) | |
download | samba-7540d13956a8a69d25f6fbbc4f9a3417e91db1d2.tar.gz samba-7540d13956a8a69d25f6fbbc4f9a3417e91db1d2.tar.bz2 samba-7540d13956a8a69d25f6fbbc4f9a3417e91db1d2.zip |
s3:ctdbd_conn: canonicalize ips before sending them to ctdbd
This makes samba work with older ctdb versions.
metze
Diffstat (limited to 'source3')
-rw-r--r-- | source3/lib/ctdbd_conn.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c index f8dae8fbd6..88d82caab8 100644 --- a/source3/lib/ctdbd_conn.c +++ b/source3/lib/ctdbd_conn.c @@ -1177,45 +1177,75 @@ NTSTATUS ctdbd_traverse(uint32 db_id, } /* + 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; |