1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-03 12:58:35 +03:00

s3:ctdbd_conn: canonicalize ips before sending them to ctdbd

This makes samba work with older ctdb versions.

metze
This commit is contained in:
Stefan Metzmacher 2009-01-28 18:55:13 +01:00
parent ba482e6b8d
commit 7540d13956

View File

@ -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;