diff --git a/source/auth/auth_server.c b/source/auth/auth_server.c
index f200ad9..6220fb3 100644
--- a/source/auth/auth_server.c
+++ b/source/auth/auth_server.c
@@ -18,6 +18,8 @@
along with this program. If not, see .
*/
+#error "THIS CODE IS NOT CONVERTED TO THE NEW IP CONVENTIONS"
+
#include "includes.h"
/****************************************************************************
@@ -28,7 +30,7 @@ static struct smbcli_state *server_cryptkey(TALLOC_CTX *mem_ctx, bool unicode, i
{
struct smbcli_state *cli = NULL;
fstring desthost;
- struct in_addr dest_ip;
+ const char *dest_ip;
const char *p;
char *pserver;
bool connected_ok = false;
diff --git a/source/auth/gensec/gensec_gssapi.c b/source/auth/gensec/gensec_gssapi.c
index cc0d404..d241fac 100644
--- a/source/auth/gensec/gensec_gssapi.c
+++ b/source/auth/gensec/gensec_gssapi.c
@@ -37,6 +37,7 @@
#include "auth/gensec/gensec_proto.h"
#include "param/param.h"
#include "auth/session_proto.h"
+#include "lib/util/util_ip.h"
enum gensec_gssapi_sasl_state
{
diff --git a/source/auth/gensec/gensec_krb5.c b/source/auth/gensec/gensec_krb5.c
index 47df2cc..5d9555a 100644
--- a/source/auth/gensec/gensec_krb5.c
+++ b/source/auth/gensec/gensec_krb5.c
@@ -39,6 +39,7 @@
#include "auth/gensec/gensec_proto.h"
#include "param/param.h"
#include "auth/session_proto.h"
+#include "lib/util/util_ip.h"
enum GENSEC_KRB5_STATE {
GENSEC_KRB5_SERVER_START,
diff --git a/source/auth/gensec/socket.c b/source/auth/gensec/socket.c
index 27449bf..57c3510 100644
--- a/source/auth/gensec/socket.c
+++ b/source/auth/gensec/socket.c
@@ -486,10 +486,9 @@ NTSTATUS gensec_socket_init(struct gensec_security *gensec_security,
}
-static NTSTATUS gensec_socket_set_option(struct socket_context *sock, const char *option, const char *val)
+static NTSTATUS gensec_socket_set_option(struct socket_context *sock, const char *option)
{
- set_socket_options(socket_get_fd(sock), option);
- return NT_STATUS_OK;
+ return socket_set_option(sock, option);
}
static char *gensec_socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx)
diff --git a/source/auth/kerberos/krb5_init_context.c b/source/auth/kerberos/krb5_init_context.c
index a455fda..ade052e 100644
--- a/source/auth/kerberos/krb5_init_context.c
+++ b/source/auth/kerberos/krb5_init_context.c
@@ -238,11 +238,9 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
case PF_INET:
name = "ipv4";
break;
-#ifdef HAVE_IPV6
case PF_INET6:
name = "ipv6";
break;
-#endif
default:
talloc_free(smb_krb5);
return EINVAL;
diff --git a/source/cldap_server/cldap_server.c b/source/cldap_server/cldap_server.c
index 58e9e2d..f56c5ae 100644
--- a/source/cldap_server/cldap_server.c
+++ b/source/cldap_server/cldap_server.c
@@ -89,26 +89,17 @@ static NTSTATUS cldapd_add_socket(struct cldapd_server *cldapd, struct loadparm_
{
struct cldap_socket *cldapsock;
struct socket_address *socket_address;
- NTSTATUS status;
-
- /* listen for unicasts on the CLDAP port (389) */
- cldapsock = cldap_socket_init(cldapd, cldapd->task->event_ctx, lp_iconv_convenience(cldapd->task->lp_ctx));
- NT_STATUS_HAVE_NO_MEMORY(cldapsock);
- socket_address = socket_address_from_strings(cldapsock, cldapsock->sock->backend_name,
+ socket_address = socket_address_from_strings(cldapd, "ip",
address, lp_cldap_port(lp_ctx));
if (!socket_address) {
- talloc_free(cldapsock);
- return NT_STATUS_NO_MEMORY;
+ return NT_STATUS_INVALID_ADDRESS;
}
- status = socket_listen(cldapsock->sock, socket_address, 0, 0);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("Failed to bind to %s:%d - %s\n",
- address, lp_cldap_port(lp_ctx), nt_errstr(status)));
- talloc_free(cldapsock);
- return status;
- }
+ /* listen for unicasts on the CLDAP port (389) */
+ cldapsock = cldap_socket_init(cldapd, cldapd->task->event_ctx,
+ lp_iconv_convenience(cldapd->task->lp_ctx), socket_address);
+ NT_STATUS_HAVE_NO_MEMORY(cldapsock);
talloc_free(socket_address);
@@ -133,7 +124,7 @@ static NTSTATUS cldapd_startup_interfaces(struct cldapd_server *cldapd, struct l
/* if we are allowing incoming packets from any address, then
we need to bind to the wildcard address */
if (!lp_bind_interfaces_only(lp_ctx)) {
- status = cldapd_add_socket(cldapd, lp_ctx, "0.0.0.0");
+ status = cldapd_add_socket(cldapd, lp_ctx, "::");
NT_STATUS_NOT_OK_RETURN(status);
} else {
int i;
diff --git a/source/client/smbmount.c b/source/client/smbmount.c
index 9ab6c37..f3c55b7 100644
--- a/source/client/smbmount.c
+++ b/source/client/smbmount.c
@@ -33,7 +33,7 @@ static pstring mpoint;
static pstring service;
static pstring options;
-static struct in_addr dest_ip;
+static const char *dest_ip;
static bool have_ip;
static int smb_port = 0;
static bool got_user;
@@ -116,7 +116,7 @@ static struct smbcli_state *do_connection(const char *the_service, bool unicode,
struct smbcli_state *c;
struct nmb_name called, calling;
char *server_n;
- struct in_addr ip;
+ const char *ip = NULL;
pstring server;
char *share;
@@ -140,7 +140,6 @@ static struct smbcli_state *do_connection(const char *the_service, bool unicode,
choose_called_name(&called, server, 0x20);
again:
- zero_ip(&ip);
if (have_ip) ip = dest_ip;
/* have to open a new connection */
@@ -787,11 +786,7 @@ static void parse_mount_smb(int argc, char **argv)
} else if(!strcmp(opts, "debug")) {
DEBUGLEVEL = val;
} else if(!strcmp(opts, "ip")) {
- dest_ip = interpret_addr2(opteq+1);
- if (is_zero_ip(dest_ip)) {
- fprintf(stderr,"Can't resolve address %s\n", opteq+1);
- exit(1);
- }
+ dest_ip = opteq+1;
have_ip = true;
} else if(!strcmp(opts, "workgroup")) {
pstrcpy(workgroup,opteq+1);
diff --git a/source/kdc/kdc.c b/source/kdc/kdc.c
index 84d9d45..3720acf 100644
--- a/source/kdc/kdc.c
+++ b/source/kdc/kdc.c
@@ -443,10 +443,6 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address,
talloc_steal(kdc_socket, kdc_socket->sock);
- kdc_socket->fde = event_add_fd(kdc->task->event_ctx, kdc,
- socket_get_fd(kdc_socket->sock), EVENT_FD_READ,
- kdc_socket_handler, kdc_socket);
-
kdc_address = socket_address_from_strings(kdc_socket, kdc_socket->sock->backend_name,
address, kdc_port);
NT_STATUS_HAVE_NO_MEMORY(kdc_address);
@@ -459,16 +455,16 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address,
return status;
}
+ kdc_socket->fde = event_add_fd(kdc->task->event_ctx, kdc,
+ socket_get_fd(kdc_socket->sock), EVENT_FD_READ,
+ kdc_socket_handler, kdc_socket);
+
kpasswd_socket->kdc = kdc;
kpasswd_socket->send_queue = NULL;
kpasswd_socket->process = kpasswdd_process;
talloc_steal(kpasswd_socket, kpasswd_socket->sock);
- kpasswd_socket->fde = event_add_fd(kdc->task->event_ctx, kdc,
- socket_get_fd(kpasswd_socket->sock), EVENT_FD_READ,
- kdc_socket_handler, kpasswd_socket);
-
kpasswd_address = socket_address_from_strings(kpasswd_socket, kpasswd_socket->sock->backend_name,
address, kpasswd_port);
NT_STATUS_HAVE_NO_MEMORY(kpasswd_address);
@@ -481,6 +477,10 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address,
return status;
}
+ kpasswd_socket->fde = event_add_fd(kdc->task->event_ctx, kdc,
+ socket_get_fd(kpasswd_socket->sock), EVENT_FD_READ,
+ kdc_socket_handler, kpasswd_socket);
+
/* within the kdc task we want to be a single process, so
ask for the single process model ops and pass these to the
stream_setup_socket() call. */
@@ -529,23 +529,26 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address,
static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc, struct loadparm_context *lp_ctx,
struct interface *ifaces)
{
- int num_interfaces;
TALLOC_CTX *tmp_ctx = talloc_new(kdc);
NTSTATUS status;
- int i;
- num_interfaces = iface_count(ifaces);
-
- for (i=0; i
#endif
-#ifdef HAVE_NETINET_IN_H
-#include
-#endif
#ifdef HAVE_ARPA_INET_H
#include
#endif
+#ifdef HAVE_NETINET_IN_H
+#include
+#endif
+
#ifdef HAVE_NETDB_H
#include
#endif
diff --git a/source/lib/socket/access.c b/source/lib/socket/access.c
index 42c42db..3d6b874 100644
--- a/source/lib/socket/access.c
+++ b/source/lib/socket/access.c
@@ -34,40 +34,42 @@
#include "system/network.h"
#include "lib/socket/socket.h"
#include "system/locale.h"
+#include "lib/util/util_ip.h"
#define FAIL (-1)
-#define ALLONES ((uint32_t)0xFFFFFFFF)
/* masked_match - match address against netnumber/netmask */
-static bool masked_match(TALLOC_CTX *mem_ctx, const char *tok, const char *slash, const char *s)
+static bool masked_match(TALLOC_CTX *mem_ctx, const char *tok, const char *slash,
+ const char *s)
{
- uint32_t net;
- uint32_t mask;
- uint32_t addr;
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ const char *net;
+ const char *mask;
+ const char *addr;
char *tok_cpy;
+ bool ret;
- if ((addr = interpret_addr(s)) == INADDR_NONE)
- return false;
+ addr = interpret_addr_str(tmp_ctx, s);
+ if (addr == NULL) goto failed;
+
+ tok_cpy = talloc_strdup(tmp_ctx, tok);
+ if (tok_cpy == NULL) goto failed;
- tok_cpy = talloc_strdup(mem_ctx, tok);
tok_cpy[PTR_DIFF(slash,tok)] = '\0';
- net = interpret_addr(tok_cpy);
- talloc_free(tok_cpy);
-
- if (strlen(slash + 1) > 2) {
- mask = interpret_addr(slash + 1);
- } else {
- mask = (uint32_t)((ALLONES >> atoi(slash + 1)) ^ ALLONES);
- /* convert to network byte order */
- mask = htonl(mask);
- }
-
- if (net == INADDR_NONE || mask == INADDR_NONE) {
- DEBUG(0,("access: bad net/mask access control: %s\n", tok));
- return false;
- }
-
- return (addr & mask) == (net & mask);
+ net = interpret_addr_str(tmp_ctx, tok_cpy);
+ if (net == NULL) goto failed;
+
+ mask = ip_netmask(tmp_ctx, net, slash + 1);
+ if (mask == NULL) goto failed;
+
+ ret = ip_same_net(addr, net, mask);
+ talloc_free(tmp_ctx);
+
+ return ret;
+
+failed:
+ talloc_free(tmp_ctx);
+ return false;
}
/* string_match - match string against token */
@@ -286,7 +288,7 @@ static bool only_ipaddrs_in_list(const char** list)
continue;
}
- if (!is_ipaddress(*list)) {
+ if (!is_ipv4address(*list)) {
/*
* if we failed, make sure that it was not because the token
* was a network/netmask pair. Only network/netmask pairs
diff --git a/source/lib/socket/connect_multi.c b/source/lib/socket/connect_multi.c
index 2f736a4..dfc7b61 100644
--- a/source/lib/socket/connect_multi.c
+++ b/source/lib/socket/connect_multi.c
@@ -27,6 +27,8 @@
#include "libcli/composite/composite.h"
#include "libcli/resolve/resolve.h"
#include "param/param.h"
+#include "system/network.h"
+#include "lib/util/util_ip.h"
#define MULTI_PORT_DELAY 2000 /* microseconds */
diff --git a/source/lib/socket/interface.c b/source/lib/socket/interface.c
index c327f02..cb8054d 100644
--- a/source/lib/socket/interface.c
+++ b/source/lib/socket/interface.c
@@ -23,38 +23,35 @@
#include "system/network.h"
#include "lib/socket/netif.h"
#include "lib/util/dlinklist.h"
+#include "lib/util/util_ip.h"
#include "param/param.h"
/** used for network interfaces */
struct interface {
struct interface *next, *prev;
- struct in_addr ip;
- struct in_addr nmask;
const char *ip_s;
- const char *bcast_s;
const char *nmask_s;
+ const char *bcast_s;
};
-#define ALLONES ((uint32_t)0xFFFFFFFF)
-/*
- address construction based on a patch from fred@datalync.com
-*/
-#define MKBCADDR(_IP, _NM) ((_IP & _NM) | (_NM ^ ALLONES))
-#define MKNETADDR(_IP, _NM) (_IP & _NM)
/****************************************************************************
Try and find an interface that matches an ip. If we cannot, return NULL
**************************************************************************/
static struct interface *iface_find(struct interface *interfaces,
- struct in_addr ip, bool CheckMask)
+ const char *ip, bool CheckMask)
{
struct interface *i;
+
if (is_zero_ip(ip)) return interfaces;
- for (i=interfaces;i;i=i->next)
+ for (i=interfaces;i;i=i->next) {
if (CheckMask) {
- if (same_net(i->ip,ip,i->nmask)) return i;
- } else if (i->ip.s_addr == ip.s_addr) return i;
+ if (ip_same_net(i->ip_s, ip, i->nmask_s)) return i;
+ } else if (strcmp(i->ip_s, ip) == 0) {
+ return i;
+ }
+ }
return NULL;
}
@@ -63,13 +60,15 @@ static struct interface *iface_find(struct interface *interfaces,
/****************************************************************************
add an interface to the linked list of interfaces
****************************************************************************/
-static void add_interface(TALLOC_CTX *mem_ctx, struct in_addr ip, struct in_addr nmask, struct interface **interfaces)
+static void add_interface(TALLOC_CTX *mem_ctx,
+ const char *ip_s, const char *netmask,
+ struct interface **interfaces)
{
struct interface *iface;
- struct in_addr bcast;
+ struct in_addr ip, nmask, bcast;
- if (iface_find(*interfaces, ip, false)) {
- DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip)));
+ if (iface_find(*interfaces, ip_s, false)) {
+ DEBUG(3,("not adding duplicate interface for IP '%s'\n", ip_s));
return;
}
@@ -79,22 +78,29 @@ static void add_interface(TALLOC_CTX *mem_ctx, struct in_addr ip, struct in_addr
ZERO_STRUCTPN(iface);
- iface->ip = ip;
- iface->nmask = nmask;
- bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
+ iface->ip_s = talloc_strdup(iface, ip_s);
+ iface->nmask_s = talloc_strdup(iface, netmask);
+ if (iface->ip_s == NULL ||
+ iface->nmask_s == NULL) {
+ return;
+ }
- /* keep string versions too, to avoid people tripping over the implied
- static in inet_ntoa() */
- iface->ip_s = talloc_strdup(iface, inet_ntoa(iface->ip));
- iface->nmask_s = talloc_strdup(iface, inet_ntoa(iface->nmask));
-
- if (nmask.s_addr != ~0) {
- iface->bcast_s = talloc_strdup(iface, inet_ntoa(bcast));
+ /* IPv4 addresses have broadcasts too */
+ if (inet_pton(AF_INET, iface->ip_s, &ip) > 0 &&
+ inet_pton(AF_INET, iface->nmask_s, &nmask) > 0) {
+ char buf[INET6_ADDRSTRLEN+1];
+ bcast.s_addr = (ip.s_addr & nmask.s_addr) |
+ (nmask.s_addr ^ 0xFFFFFFFF);
+ if (inet_ntop(AF_INET, &bcast, buf, sizeof(buf)) > 0) {
+ iface->bcast_s = talloc_strdup(iface, buf);
+ }
}
+
DLIST_ADD_END(*interfaces, iface, struct interface *);
- DEBUG(2,("added interface ip=%s nmask=%s\n", iface->ip_s, iface->nmask_s));
+ DEBUG(2,("added interface ip=%s nmask=%s count=%u\n",
+ iface->ip_s, iface->nmask_s, iface_count(*interfaces)));
}
@@ -116,77 +122,79 @@ static void interpret_interface(TALLOC_CTX *mem_ctx,
int total_probed,
struct interface **local_interfaces)
{
- struct in_addr ip, nmask;
char *p;
- char *address;
+ char *address, *ip, *nmask;
int i, added=0;
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
- ip.s_addr = 0;
- nmask.s_addr = 0;
-
/* first check if it is an interface name */
for (i=0;i 2) {
- nmask.s_addr = interpret_addr2(p).s_addr;
- } else {
- nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
+ ip = interpret_addr_str(tmp_ctx, address);
+ if (ip == NULL) {
+ DEBUG(0,("Can't resolve IP for '%s'\n", address));
+ talloc_free(tmp_ctx);
+ return;
}
- /* maybe the first component was a broadcast address */
- if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) ||
- ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) {
- for (i=0;iip_s;
}
@@ -315,21 +318,9 @@ const char *iface_best_ip(struct interface *ifaces, const char *dest)
*/
bool iface_is_local(struct interface *ifaces, const char *dest)
{
- struct in_addr ip;
-
- ip.s_addr = interpret_addr(dest);
- if (iface_find(ifaces, ip, true)) {
+ if (iface_find(ifaces, dest, true)) {
return true;
}
return false;
}
-/**
- return true if a IP matches a IP/netmask pair
-*/
-bool iface_same_net(const char *ip1, const char *ip2, const char *netmask)
-{
- return same_net(interpret_addr2(ip1),
- interpret_addr2(ip2),
- interpret_addr2(netmask));
-}
diff --git a/source/lib/socket/netif.c b/source/lib/socket/netif.c
index bf410af..04efdac 100644
--- a/source/lib/socket/netif.c
+++ b/source/lib/socket/netif.c
@@ -24,42 +24,41 @@
thing. We have several possible implementations below, and autoconf
tries each of them to see what works
- Note that this file does _not_ include includes.h. That is so this code
- can be called directly from the autoconf tests. That also means
- this code cannot use any of the normal Samba debug stuff or defines.
- This is standalone code.
-
*/
#include "includes.h"
#include "system/network.h"
#include "netif.h"
+#include "lib/util/util_ip.h"
/****************************************************************************
Try the "standard" getifaddrs/freeifaddrs interfaces.
Also gets IPv6 interfaces.
****************************************************************************/
+
/****************************************************************************
Get the netmask address for a local interface.
****************************************************************************/
-static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
+static struct iface_struct *_get_interfaces(TALLOC_CTX *mem_ctx, int *num_interfaces)
{
struct ifaddrs *iflist = NULL;
struct ifaddrs *ifptr = NULL;
int total = 0;
+ struct iface_struct *ifaces = NULL;
+
+ *num_interfaces = 0;
if (getifaddrs(&iflist) < 0) {
- return -1;
+ return NULL;
}
- /* Loop through interfaces, looking for given IP address */
+ /* Loop through interfaces, looking for IP addresses */
for (ifptr = iflist, total = 0;
- ifptr != NULL && total < max_interfaces;
- ifptr = ifptr->ifa_next) {
-
- memset(&ifaces[total], '\0', sizeof(ifaces[total]));
+ ifptr != NULL;
+ ifptr = ifptr->ifa_next) {
+ struct iface_struct *ifaces2 = NULL;
if (!ifptr->ifa_addr || !ifptr->ifa_netmask) {
continue;
@@ -70,22 +69,33 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
continue;
}
- /* We don't support IPv6 *yet* */
- if (ifptr->ifa_addr->sa_family != AF_INET) {
- continue;
+ ifaces2 = talloc_realloc(mem_ctx, ifaces, struct iface_struct,
+ total+1);
+ if (ifaces2 == NULL) {
+ goto oom;
}
+ ifaces = ifaces2;
+
+ ifaces[total].ip_s = ip_sockaddr_string(ifaces, ifptr->ifa_addr, NULL);
+ if (ifaces[total].ip_s == NULL) goto oom;
- ifaces[total].ip = ((struct sockaddr_in *)ifptr->ifa_addr)->sin_addr;
- ifaces[total].netmask = ((struct sockaddr_in *)ifptr->ifa_netmask)->sin_addr;
+ ifaces[total].netmask_s = ip_sockaddr_string(ifaces, ifptr->ifa_netmask, NULL);
+ if (ifaces[total].netmask_s == NULL) goto oom;
+
+ ifaces[total].name = talloc_strdup(ifaces, ifptr->ifa_name);
+ if (ifaces[total].name == NULL) goto oom;
- strlcpy(ifaces[total].name, ifptr->ifa_name,
- sizeof(ifaces[total].name));
total++;
+ *num_interfaces = total;
}
freeifaddrs(iflist);
+ return ifaces;
- return total;
+oom:
+ DEBUG(0,("Failed to allocate memory in interfaces code\n"));
+ talloc_free(ifaces);
+ return NULL;
}
static int iface_comp(struct iface_struct *i1, struct iface_struct *i2)
@@ -93,34 +103,37 @@ static int iface_comp(struct iface_struct *i1, struct iface_struct *i2)
int r;
r = strcmp(i1->name, i2->name);
if (r) return r;
- r = ntohl(i1->ip.s_addr) - ntohl(i2->ip.s_addr);
+ r = strcmp(i1->ip_s, i2->ip_s);
if (r) return r;
- r = ntohl(i1->netmask.s_addr) - ntohl(i2->netmask.s_addr);
+ r = strcmp(i1->netmask_s, i2->netmask_s);
return r;
}
-/* this wrapper is used to remove duplicates from the interface list generated
- above */
-int get_interfaces(struct iface_struct *ifaces, int max_interfaces)
+/* this wrapper is used to remove duplicates from the interface
+ list generated above */
+struct iface_struct *get_interfaces(TALLOC_CTX *mem_ctx, int *num_interfaces)
{
- int total, i, j;
+ int i, j;
+ struct iface_struct *ret;
- total = _get_interfaces(ifaces, max_interfaces);
- if (total <= 0) return total;
+ ret = _get_interfaces(mem_ctx, num_interfaces);
+ if (ret == NULL || *num_interfaces <= 1) {
+ return ret;
+ }
/* now we need to remove duplicates */
- qsort(ifaces, total, sizeof(ifaces[0]), QSORT_CAST iface_comp);
+ qsort(ret, *num_interfaces, sizeof(ret[0]), QSORT_CAST iface_comp);
- for (i=1;iflags |= SOCKET_FLAG_TESTNONBLOCK;
}
- /* we don't do a connect() on dgram sockets, so need to set
- non-blocking at socket create time */
- if (!(flags & SOCKET_FLAG_BLOCK) && type == SOCKET_TYPE_DGRAM) {
- set_blocking(socket_get_fd(*new_sock), false);
- }
-
talloc_set_destructor(*new_sock, socket_destructor);
return NT_STATUS_OK;
@@ -296,7 +292,7 @@ _PUBLIC_ NTSTATUS socket_pending(struct socket_context *sock, size_t *npending)
}
-_PUBLIC_ NTSTATUS socket_set_option(struct socket_context *sock, const char *option, const char *val)
+_PUBLIC_ NTSTATUS socket_set_option(struct socket_context *sock, const char *option)
{
if (sock == NULL) {
return NT_STATUS_CONNECTION_DISCONNECTED;
@@ -305,7 +301,7 @@ _PUBLIC_ NTSTATUS socket_set_option(struct socket_context *sock, const char *opt
return NT_STATUS_NOT_IMPLEMENTED;
}
- return sock->ops->fn_set_option(sock, option, val);
+ return sock->ops->fn_set_option(sock, option);
}
_PUBLIC_ char *socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx)
@@ -380,12 +376,13 @@ _PUBLIC_ struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx,
return NULL;
}
- addr->family = family;
addr->addr = talloc_strdup(addr, host);
+
if (!addr->addr) {
talloc_free(addr);
return NULL;
}
+ addr->family = family;
addr->port = port;
addr->sockaddr = NULL;
addr->sockaddrlen = 0;
@@ -405,7 +402,6 @@ _PUBLIC_ struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx
if (!addr) {
return NULL;
}
- addr->family = NULL;
addr->addr = NULL;
addr->port = 0;
addr->sockaddr = (struct sockaddr *)talloc_memdup(addr, sockaddr, sockaddrlen);
@@ -419,20 +415,18 @@ _PUBLIC_ struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx
_PUBLIC_ const struct socket_ops *socket_getops_byname(const char *family, enum socket_type type)
{
+ extern const struct socket_ops *socket_ip_ops(enum socket_type);
extern const struct socket_ops *socket_ipv4_ops(enum socket_type);
- extern const struct socket_ops *socket_ipv6_ops(enum socket_type);
extern const struct socket_ops *socket_unixdom_ops(enum socket_type);
- if (strcmp("ip", family) == 0 ||
- strcmp("ipv4", family) == 0) {
+ if (strcmp("ipv4", family) == 0) {
return socket_ipv4_ops(type);
}
-#if HAVE_IPV6
- if (strcmp("ipv6", family) == 0) {
- return socket_ipv6_ops(type);
+ if (strcmp("ip", family) == 0 ||
+ strcmp("ipv6", family) == 0) {
+ return socket_ip_ops(type);
}
-#endif
if (strcmp("unix", family) == 0) {
return socket_unixdom_ops(type);
diff --git a/source/lib/socket/socket.h b/source/lib/socket/socket.h
index 4baa0cf..34436f8 100644
--- a/source/lib/socket/socket.h
+++ b/source/lib/socket/socket.h
@@ -75,7 +75,7 @@ struct socket_ops {
void (*fn_close)(struct socket_context *sock);
- NTSTATUS (*fn_set_option)(struct socket_context *sock, const char *option, const char *val);
+ NTSTATUS (*fn_set_option)(struct socket_context *sock, const char *option);
char *(*fn_get_peer_name)(struct socket_context *sock, TALLOC_CTX *mem_ctx);
struct socket_address *(*fn_get_peer_addr)(struct socket_context *sock, TALLOC_CTX *mem_ctx);
@@ -122,8 +122,8 @@ struct socket_context {
const struct socket_ops *ops;
const char *backend_name;
- /* specific to the ip backend */
- int family;
+ /* private to IP backend */
+ char *options;
};
struct resolve_context;
@@ -154,14 +154,14 @@ NTSTATUS socket_sendto(struct socket_context *sock,
const DATA_BLOB *blob, size_t *sendlen,
const struct socket_address *dest_addr);
NTSTATUS socket_pending(struct socket_context *sock, size_t *npending);
-NTSTATUS socket_set_option(struct socket_context *sock, const char *option, const char *val);
+NTSTATUS socket_set_option(struct socket_context *sock, const char *option);
char *socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx);
struct socket_address *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx);
struct socket_address *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx);
int socket_get_fd(struct socket_context *sock);
NTSTATUS socket_dup(struct socket_context *sock);
struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx,
- const char *type,
+ const char *family,
const char *host,
int port);
struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx,
diff --git a/source/lib/socket/socket_ip.c b/source/lib/socket/socket_ip.c
index bca0aab..6ce6602 100644
--- a/source/lib/socket/socket_ip.c
+++ b/source/lib/socket/socket_ip.c
@@ -25,36 +25,25 @@
#include "system/filesys.h"
#include "lib/socket/socket.h"
#include "system/network.h"
+#include "lib/util/util_ip.h"
-static NTSTATUS ipv4_init(struct socket_context *sock)
+static NTSTATUS ip_init(struct socket_context *sock)
{
- int type;
-
- switch (sock->type) {
- case SOCKET_TYPE_STREAM:
- type = SOCK_STREAM;
- break;
- case SOCKET_TYPE_DGRAM:
- type = SOCK_DGRAM;
- break;
- default:
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- sock->fd = socket(PF_INET, type, 0);
- if (sock->fd == -1) {
- return map_nt_error_from_unix(errno);
- }
-
- sock->backend_name = "ipv4";
- sock->family = AF_INET;
+ sock->fd = -1;
+ sock->backend_name = "ip";
+ sock->options = NULL;
+
+ /* we don't create the socket yet, as we don't yet know
+ the family */
return NT_STATUS_OK;
}
static void ip_close(struct socket_context *sock)
{
- close(sock->fd);
+ if (sock->fd != -1) {
+ close(sock->fd);
+ }
}
static NTSTATUS ip_connect_complete(struct socket_context *sock, uint32_t flags)
@@ -85,35 +74,68 @@ static NTSTATUS ip_connect_complete(struct socket_context *sock, uint32_t flags)
}
-static NTSTATUS ipv4_connect(struct socket_context *sock,
- const struct socket_address *my_address,
- const struct socket_address *srv_address,
- uint32_t flags)
+/*
+ late creation of socket - only called once we know the family
+ */
+static NTSTATUS ip_create_socket(struct socket_context *sock, int family)
+{
+ int type;
+
+ if (sock->fd != -1) {
+ return NT_STATUS_OK;
+ }
+
+ switch (sock->type) {
+ case SOCKET_TYPE_STREAM:
+ type = SOCK_STREAM;
+ break;
+ case SOCKET_TYPE_DGRAM:
+ type = SOCK_DGRAM;
+ break;
+ default:
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ sock->fd = socket(family, type, 0);
+ if (sock->fd == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+
+ /* any delayed socket options */
+ if (sock->options) {
+ set_socket_options(sock->fd, sock->options);
+ talloc_free(sock->options);
+ sock->options = NULL;
+ }
+
+ /* we don't do a connect() on dgram sockets, so need to set
+ non-blocking at socket create time */
+ if (!(sock->flags & SOCKET_FLAG_BLOCK) && sock->type == SOCKET_TYPE_DGRAM) {
+ set_blocking(sock->fd, false);
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS ip_connect(struct socket_context *sock,
+ const struct socket_address *my_address,
+ const struct socket_address *srv_address,
+ uint32_t flags)
{
- struct sockaddr_in srv_addr;
- struct in_addr my_ip;
- struct in_addr srv_ip;
int ret;
if (my_address && my_address->sockaddr) {
+ NT_STATUS_NOT_OK_RETURN(ip_create_socket(sock, my_address->sockaddr->sa_family));
ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
if (ret == -1) {
return map_nt_error_from_unix(errno);
}
} else if (my_address) {
- my_ip = interpret_addr2(my_address->addr);
-
- if (my_ip.s_addr != 0 || my_address->port != 0) {
- struct sockaddr_in my_addr;
- ZERO_STRUCT(my_addr);
-#ifdef HAVE_SOCK_SIN_LEN
- my_addr.sin_len = sizeof(my_addr);
-#endif
- my_addr.sin_addr.s_addr = my_ip.s_addr;
- my_addr.sin_port = htons(my_address->port);
- my_addr.sin_family = PF_INET;
-
- ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
+ struct sockaddr sa;
+
+ if (ip_sockaddr(my_address->addr, my_address->port, &sa)) {
+ NT_STATUS_NOT_OK_RETURN(ip_create_socket(sock, sa.sa_family));
+ ret = bind(sock->fd, &sa, ip_sockaddrlen(&sa));
if (ret == -1) {
return map_nt_error_from_unix(errno);
}
@@ -121,27 +143,22 @@ static NTSTATUS ipv4_connect(struct socket_context *sock,
}
if (srv_address->sockaddr) {
+ NT_STATUS_NOT_OK_RETURN(ip_create_socket(sock, srv_address->sockaddr->sa_family));
ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen);
if (ret == -1) {
return map_nt_error_from_unix(errno);
}
} else {
- srv_ip = interpret_addr2(srv_address->addr);
- if (!srv_ip.s_addr) {
+ struct sockaddr sa;
+
+ SMB_ASSERT(srv_address->port != 0);
+
+ if (!ip_sockaddr(srv_address->addr, srv_address->port, &sa)) {
return NT_STATUS_BAD_NETWORK_NAME;
}
- SMB_ASSERT(srv_address->port != 0);
-
- ZERO_STRUCT(srv_addr);
-#ifdef HAVE_SOCK_SIN_LEN
- srv_addr.sin_len = sizeof(srv_addr);
-#endif
- srv_addr.sin_addr.s_addr= srv_ip.s_addr;
- srv_addr.sin_port = htons(srv_address->port);
- srv_addr.sin_family = PF_INET;
-
- ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr));
+ NT_STATUS_NOT_OK_RETURN(ip_create_socket(sock, sa.sa_family));
+ ret = connect(sock->fd, &sa, ip_sockaddrlen(&sa));
if (ret == -1) {
return map_nt_error_from_unix(errno);
}
@@ -155,30 +172,26 @@ static NTSTATUS ipv4_connect(struct socket_context *sock,
note that for simplicity of the API, socket_listen() is also
use for DGRAM sockets, but in reality only a bind() is done
*/
-static NTSTATUS ipv4_listen(struct socket_context *sock,
- const struct socket_address *my_address,
- int queue_size, uint32_t flags)
+static NTSTATUS ip_listen(struct socket_context *sock,
+ const struct socket_address *my_address,
+ int queue_size, uint32_t flags)
{
- struct sockaddr_in my_addr;
- struct in_addr ip_addr;
int ret;
- socket_set_option(sock, "SO_REUSEADDR=1", NULL);
+ socket_set_option(sock, "SO_REUSEADDR=1");
if (my_address->sockaddr) {
+ NT_STATUS_NOT_OK_RETURN(ip_create_socket(sock, my_address->sockaddr->sa_family));
ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
} else {
- ip_addr = interpret_addr2(my_address->addr);
-
- ZERO_STRUCT(my_addr);
-#ifdef HAVE_SOCK_SIN_LEN
- my_addr.sin_len = sizeof(my_addr);
-#endif
- my_addr.sin_addr.s_addr = ip_addr.s_addr;
- my_addr.sin_port = htons(my_address->port);
- my_addr.sin_family = PF_INET;
-
- ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
+ struct sockaddr sa;
+
+ if (!ip_sockaddr(my_address->addr, my_address->port, &sa)) {
+ return NT_STATUS_BAD_NETWORK_NAME;
+ }
+
+ NT_STATUS_NOT_OK_RETURN(ip_create_socket(sock, sa.sa_family));
+ ret = bind(sock->fd, &sa, ip_sockaddrlen(&sa));
}
if (ret == -1) {
@@ -199,12 +212,12 @@ static NTSTATUS ipv4_listen(struct socket_context *sock,
}
}
- sock->state= SOCKET_STATE_SERVER_LISTEN;
+ sock->state = SOCKET_STATE_SERVER_LISTEN;
return NT_STATUS_OK;
}
-static NTSTATUS ipv4_accept(struct socket_context *sock, struct socket_context **new_sock)
+static NTSTATUS ip_accept(struct socket_context *sock, struct socket_context **new_sock)
{
struct sockaddr_in cli_addr;
socklen_t cli_addr_len = sizeof(cli_addr);
@@ -273,35 +286,24 @@ static NTSTATUS ip_recv(struct socket_context *sock, void *buf,
}
-static NTSTATUS ipv4_recvfrom(struct socket_context *sock, void *buf,
- size_t wantlen, size_t *nread,
- TALLOC_CTX *addr_ctx, struct socket_address **_src)
+static NTSTATUS ip_recvfrom(struct socket_context *sock, void *buf,
+ size_t wantlen, size_t *nread,
+ TALLOC_CTX *addr_ctx, struct socket_address **_src)
{
ssize_t gotlen;
- struct sockaddr_in *from_addr;
- socklen_t from_len = sizeof(*from_addr);
+ struct sockaddr from_addr;
+ socklen_t from_len = sizeof(from_addr);
struct socket_address *src;
- char addrstring[INET_ADDRSTRLEN];
src = talloc(addr_ctx, struct socket_address);
if (!src) {
return NT_STATUS_NO_MEMORY;
}
- src->family = sock->backend_name;
-
- from_addr = talloc(src, struct sockaddr_in);
- if (!from_addr) {
- talloc_free(src);
- return NT_STATUS_NO_MEMORY;
- }
-
- src->sockaddr = (struct sockaddr *)from_addr;
-
*nread = 0;
gotlen = recvfrom(sock->fd, buf, wantlen, 0,
- src->sockaddr, &from_len);
+ &from_addr, &from_len);
if (gotlen == 0) {
talloc_free(src);
return NT_STATUS_END_OF_FILE;
@@ -311,18 +313,12 @@ static NTSTATUS ipv4_recvfrom(struct socket_context *sock, void *buf,
}
src->sockaddrlen = from_len;
-
- if (inet_ntop(AF_INET, &from_addr->sin_addr, addrstring,
- sizeof(addrstring)) == NULL) {
- talloc_free(src);
- return NT_STATUS_INTERNAL_ERROR;
- }
- src->addr = talloc_strdup(src, addrstring);
+ src->sockaddr = (struct sockaddr *)talloc_memdup(src, &from_addr, from_len);
+ src->addr = ip_sockaddr_string(src, &from_addr, &src->port);
if (src->addr == NULL) {
talloc_free(src);
- return NT_STATUS_NO_MEMORY;
+ return NT_STATUS_INTERNAL_ERROR;
}
- src->port = ntohs(from_addr->sin_port);
*nread = gotlen;
*_src = src;
@@ -330,7 +326,7 @@ static NTSTATUS ipv4_recvfrom(struct socket_context *sock, void *buf,
}
static NTSTATUS ip_send(struct socket_context *sock,
- const DATA_BLOB *blob, size_t *sendlen)
+ const DATA_BLOB *blob, size_t *sendlen)
{
ssize_t len;
@@ -346,37 +342,28 @@ static NTSTATUS ip_send(struct socket_context *sock,
return NT_STATUS_OK;
}
-static NTSTATUS ipv4_sendto(struct socket_context *sock,
+static NTSTATUS ip_sendto(struct socket_context *sock,
const DATA_BLOB *blob, size_t *sendlen,
const struct socket_address *dest_addr)
{
ssize_t len;
if (dest_addr->sockaddr) {
+ NT_STATUS_NOT_OK_RETURN(ip_create_socket(sock, dest_addr->sockaddr->sa_family));
len = sendto(sock->fd, blob->data, blob->length, 0,
dest_addr->sockaddr, dest_addr->sockaddrlen);
} else {
- struct sockaddr_in srv_addr;
- struct in_addr addr;
+ struct sockaddr sa;
SMB_ASSERT(dest_addr->port != 0);
-
- ZERO_STRUCT(srv_addr);
-#ifdef HAVE_SOCK_SIN_LEN
- srv_addr.sin_len = sizeof(srv_addr);
-#endif
- addr = interpret_addr2(dest_addr->addr);
- if (addr.s_addr == 0) {
+
+ if (!ip_sockaddr(dest_addr->addr, dest_addr->port, &sa)) {
return NT_STATUS_HOST_UNREACHABLE;
}
- srv_addr.sin_addr.s_addr = addr.s_addr;
- srv_addr.sin_port = htons(dest_addr->port);
- srv_addr.sin_family = PF_INET;
*sendlen = 0;
- len = sendto(sock->fd, blob->data, blob->length, 0,
- (struct sockaddr *)&srv_addr, sizeof(srv_addr));
+ len = sendto(sock->fd, blob->data, blob->length, 0, &sa, ip_sockaddrlen(&sa));
}
if (len == -1) {
return map_nt_error_from_unix(errno);
@@ -387,123 +374,110 @@ static NTSTATUS ipv4_sendto(struct socket_context *sock,
return NT_STATUS_OK;
}
-static NTSTATUS ipv4_set_option(struct socket_context *sock, const char *option, const char *val)
+static NTSTATUS ip_set_option(struct socket_context *sock, const char *option)
{
- set_socket_options(sock->fd, option);
+ if (sock->fd == -1) {
+ if (sock->options == NULL) {
+ sock->options = talloc_strdup(sock, option);
+ } else {
+ sock->options = talloc_asprintf_append(sock->options, " %s", option);
+ }
+ if (sock->options == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ } else {
+ set_socket_options(sock->fd, option);
+ }
return NT_STATUS_OK;
}
-static char *ipv4_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx)
+static char *ip_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx)
{
- struct sockaddr_in peer_addr;
+ struct sockaddr peer_addr;
socklen_t len = sizeof(peer_addr);
- struct hostent *he;
- int ret;
+ char hostname[NI_MAXHOST];
- ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len);
- if (ret == -1) {
+ if (getpeername(sock->fd, &peer_addr, &len) != 0) {
return NULL;
}
- he = gethostbyaddr((char *)&peer_addr.sin_addr, sizeof(peer_addr.sin_addr), AF_INET);
- if (he == NULL) {
+ if (getnameinfo(&peer_addr, len, hostname, sizeof(hostname), NULL, 0, 0) != 0) {
return NULL;
}
- return talloc_strdup(mem_ctx, he->h_name);
+ return talloc_strdup(mem_ctx, hostname);
}
-static struct socket_address *ipv4_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
+static struct socket_address *ip_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
{
- struct sockaddr_in *peer_addr;
- socklen_t len = sizeof(*peer_addr);
+ struct sockaddr peer_addr;
+ socklen_t len = sizeof(peer_addr);
struct socket_address *peer;
- char addrstring[INET_ADDRSTRLEN];
- int ret;
-
- peer = talloc(mem_ctx, struct socket_address);
- if (!peer) {
+
+ if (getpeername(sock->fd, &peer_addr, &len) != 0) {
return NULL;
}
- peer->family = sock->backend_name;
- peer_addr = talloc(peer, struct sockaddr_in);
- if (!peer_addr) {
- talloc_free(peer);
+ peer = talloc_zero(mem_ctx, struct socket_address);
+ if (!peer) {
return NULL;
}
- peer->sockaddr = (struct sockaddr *)peer_addr;
-
- ret = getpeername(sock->fd, peer->sockaddr, &len);
- if (ret == -1) {
+ peer->addr = ip_sockaddr_string(peer, &peer_addr, &peer->port);
+ if (peer->addr == NULL) {
talloc_free(peer);
return NULL;
}
-
+
peer->sockaddrlen = len;
-
- if (inet_ntop(AF_INET, &peer_addr->sin_addr, addrstring,
- sizeof(addrstring)) == NULL) {
+ peer->sockaddr = (struct sockaddr *)talloc_memdup(peer, &peer_addr, len);
+ if (peer->sockaddr == NULL) {
talloc_free(peer);
return NULL;
}
- peer->addr = talloc_strdup(peer, addrstring);
- if (!peer->addr) {
- talloc_free(peer);
- return NULL;
- }
- peer->port = ntohs(peer_addr->sin_port);
return peer;
}
-static struct socket_address *ipv4_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
+static struct socket_address *ip_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
{
- struct sockaddr_in *local_addr;
- socklen_t len = sizeof(*local_addr);
+ struct sockaddr local_addr;
+ socklen_t len = sizeof(local_addr);
struct socket_address *local;
- char addrstring[INET_ADDRSTRLEN];
- int ret;
-
- local = talloc(mem_ctx, struct socket_address);
- if (!local) {
+
+ if (getsockname(sock->fd, &local_addr, &len) != 0) {
return NULL;
}
- local->family = sock->backend_name;
- local_addr = talloc(local, struct sockaddr_in);
- if (!local_addr) {
- talloc_free(local);
+ local = talloc_zero(mem_ctx, struct socket_address);
+ if (!local) {
return NULL;
}
- local->sockaddr = (struct sockaddr *)local_addr;
-
- ret = getsockname(sock->fd, local->sockaddr, &len);
- if (ret == -1) {
+ local->addr = ip_sockaddr_string(local, &local_addr, &local->port);
+ if (local->addr == NULL) {
talloc_free(local);
return NULL;
}
-
+
local->sockaddrlen = len;
-
- if (inet_ntop(AF_INET, &local_addr->sin_addr, addrstring,
- sizeof(addrstring)) == NULL) {
+ local->sockaddr = (struct sockaddr *)talloc_memdup(local, &local_addr, len);
+ if (local->sockaddr == NULL) {
talloc_free(local);
return NULL;
}
- local->addr = talloc_strdup(local, addrstring);
- if (!local->addr) {
- talloc_free(local);
- return NULL;
- }
- local->port = ntohs(local_addr->sin_port);
return local;
}
+
static int ip_get_fd(struct socket_context *sock)
{
+ if (sock->fd == -1) {
+ if (!NT_STATUS_IS_OK(ip_create_socket(sock, AF_INET6)) &&
+ !NT_STATUS_IS_OK(ip_create_socket(sock, AF_INET))) {
+ return -1;
+ }
+ }
return sock->fd;
}
@@ -517,469 +491,71 @@ static NTSTATUS ip_pending(struct socket_context *sock, size_t *npending)
return map_nt_error_from_unix(errno);
}
-static const struct socket_ops ipv4_ops = {
- .name = "ipv4",
- .fn_init = ipv4_init,
- .fn_connect = ipv4_connect,
+static const struct socket_ops ip_ops = {
+ .name = "ip",
+ .fn_init = ip_init,
+ .fn_connect = ip_connect,
.fn_connect_complete = ip_connect_complete,
- .fn_listen = ipv4_listen,
- .fn_accept = ipv4_accept,
+ .fn_listen = ip_listen,
+ .fn_accept = ip_accept,
.fn_recv = ip_recv,
- .fn_recvfrom = ipv4_recvfrom,
+ .fn_recvfrom = ip_recvfrom,
.fn_send = ip_send,
- .fn_sendto = ipv4_sendto,
+ .fn_sendto = ip_sendto,
.fn_pending = ip_pending,
.fn_close = ip_close,
- .fn_set_option = ipv4_set_option,
+ .fn_set_option = ip_set_option,
- .fn_get_peer_name = ipv4_get_peer_name,
- .fn_get_peer_addr = ipv4_get_peer_addr,
- .fn_get_my_addr = ipv4_get_my_addr,
+ .fn_get_peer_name = ip_get_peer_name,
+ .fn_get_peer_addr = ip_get_peer_addr,
+ .fn_get_my_addr = ip_get_my_addr,
.fn_get_fd = ip_get_fd
};
-_PUBLIC_ const struct socket_ops *socket_ipv4_ops(enum socket_type type)
-{
- return &ipv4_ops;
-}
-
-#if HAVE_IPV6
-
-static struct in6_addr interpret_addr6(const char *name)
-{
- struct hostent *he;
-
- if (name == NULL) return in6addr_any;
-
- if (strcasecmp(name, "localhost") == 0) {
- name = "::1";
- }
-
- he = gethostbyname2(name, PF_INET6);
-
- if (he == NULL) return in6addr_any;
-
- return *((struct in6_addr *)he->h_addr);
-}
-
-static NTSTATUS ipv6_init(struct socket_context *sock)
-{
- int type;
-
- switch (sock->type) {
- case SOCKET_TYPE_STREAM:
- type = SOCK_STREAM;
- break;
- case SOCKET_TYPE_DGRAM:
- type = SOCK_DGRAM;
- break;
- default:
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- sock->fd = socket(PF_INET6, type, 0);
- if (sock->fd == -1) {
- return map_nt_error_from_unix(errno);
- }
-
- sock->backend_name = "ipv6";
- sock->family = AF_INET6;
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS ipv6_tcp_connect(struct socket_context *sock,
- const struct socket_address *my_address,
- const struct socket_address *srv_address,
- uint32_t flags)
+_PUBLIC_ const struct socket_ops *socket_ip_ops(enum socket_type type)
{
- int ret;
-
- if (my_address && my_address->sockaddr) {
- ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
- if (ret == -1) {
- return map_nt_error_from_unix(errno);
- }
- } else if (my_address) {
- struct in6_addr my_ip;
- my_ip = interpret_addr6(my_address->addr);
-
- if (memcmp(&my_ip, &in6addr_any, sizeof(my_ip)) || my_address->port != 0) {
- struct sockaddr_in6 my_addr;
- ZERO_STRUCT(my_addr);
- my_addr.sin6_addr = my_ip;
- my_addr.sin6_port = htons(my_address->port);
- my_addr.sin6_family = PF_INET6;
-
- ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
- if (ret == -1) {
- return map_nt_error_from_unix(errno);
- }
- }
- }
-
- if (srv_address->sockaddr) {
- ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen);
- } else {
- struct in6_addr srv_ip;
- struct sockaddr_in6 srv_addr;
- srv_ip = interpret_addr6(srv_address->addr);
- if (memcmp(&srv_ip, &in6addr_any, sizeof(srv_ip)) == 0) {
- return NT_STATUS_BAD_NETWORK_NAME;
- }
-
- ZERO_STRUCT(srv_addr);
- srv_addr.sin6_addr = srv_ip;
- srv_addr.sin6_port = htons(srv_address->port);
- srv_addr.sin6_family = PF_INET6;
-
- ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr));
- }
- if (ret == -1) {
- return map_nt_error_from_unix(errno);
- }
-
- return ip_connect_complete(sock, flags);
+ return &ip_ops;
}
-static NTSTATUS ipv6_listen(struct socket_context *sock,
- const struct socket_address *my_address,
- int queue_size, uint32_t flags)
-{
- struct sockaddr_in6 my_addr;
- struct in6_addr ip_addr;
- int ret;
-
- socket_set_option(sock, "SO_REUSEADDR=1", NULL);
-
- if (my_address->sockaddr) {
- ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
- } else {
- ip_addr = interpret_addr6(my_address->addr);
-
- ZERO_STRUCT(my_addr);
- my_addr.sin6_addr = ip_addr;
- my_addr.sin6_port = htons(my_address->port);
- my_addr.sin6_family = PF_INET6;
-
- ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
- }
-
- if (ret == -1) {
- return map_nt_error_from_unix(errno);
- }
-
- if (sock->type == SOCKET_TYPE_STREAM) {
- ret = listen(sock->fd, queue_size);
- if (ret == -1) {
- return map_nt_error_from_unix(errno);
- }
- }
-
- if (!(flags & SOCKET_FLAG_BLOCK)) {
- ret = set_blocking(sock->fd, false);
- if (ret == -1) {
- return map_nt_error_from_unix(errno);
- }
- }
-
- sock->state= SOCKET_STATE_SERVER_LISTEN;
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS ipv6_tcp_accept(struct socket_context *sock, struct socket_context **new_sock)
-{
- struct sockaddr_in cli_addr;
- socklen_t cli_addr_len = sizeof(cli_addr);
- int new_fd;
-
- if (sock->type != SOCKET_TYPE_STREAM) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len);
- if (new_fd == -1) {
- return map_nt_error_from_unix(errno);
- }
-
- if (!(sock->flags & SOCKET_FLAG_BLOCK)) {
- int ret = set_blocking(new_fd, false);
- if (ret == -1) {
- close(new_fd);
- return map_nt_error_from_unix(errno);
- }
- }
-
- /* TODO: we could add a 'accept_check' hook here
- * which get the black/white lists via socket_set_accept_filter()
- * or something like that
- * --metze
- */
-
- (*new_sock) = talloc(NULL, struct socket_context);
- if (!(*new_sock)) {
- close(new_fd);
- return NT_STATUS_NO_MEMORY;
- }
-
- /* copy the socket_context */
- (*new_sock)->type = sock->type;
- (*new_sock)->state = SOCKET_STATE_SERVER_CONNECTED;
- (*new_sock)->flags = sock->flags;
-
- (*new_sock)->fd = new_fd;
-
- (*new_sock)->private_data = NULL;
- (*new_sock)->ops = sock->ops;
- (*new_sock)->backend_name = sock->backend_name;
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS ipv6_recvfrom(struct socket_context *sock, void *buf,
- size_t wantlen, size_t *nread,
- TALLOC_CTX *addr_ctx, struct socket_address **_src)
-{
- ssize_t gotlen;
- struct sockaddr_in6 *from_addr;
- socklen_t from_len = sizeof(*from_addr);
- struct socket_address *src;
- char addrstring[INET6_ADDRSTRLEN];
-
- src = talloc(addr_ctx, struct socket_address);
- if (!src) {
- return NT_STATUS_NO_MEMORY;
- }
-
- src->family = sock->backend_name;
-
- from_addr = talloc(src, struct sockaddr_in6);
- if (!from_addr) {
- talloc_free(src);
- return NT_STATUS_NO_MEMORY;
- }
-
- src->sockaddr = (struct sockaddr *)from_addr;
-
- *nread = 0;
-
- gotlen = recvfrom(sock->fd, buf, wantlen, 0,
- src->sockaddr, &from_len);
- if (gotlen == 0) {
- talloc_free(src);
- return NT_STATUS_END_OF_FILE;
- } else if (gotlen == -1) {
- talloc_free(src);
- return map_nt_error_from_unix(errno);
- }
-
- src->sockaddrlen = from_len;
-
- if (inet_ntop(AF_INET6, &from_addr->sin6_addr, addrstring, sizeof(addrstring)) == NULL) {
- DEBUG(0, ("Unable to convert address to string: %s\n", strerror(errno)));
- talloc_free(src);
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- src->addr = talloc_strdup(src, addrstring);
- if (src->addr == NULL) {
- talloc_free(src);
- return NT_STATUS_NO_MEMORY;
- }
- src->port = ntohs(from_addr->sin6_port);
-
- *nread = gotlen;
- *_src = src;
- return NT_STATUS_OK;
-}
-
-static NTSTATUS ipv6_sendto(struct socket_context *sock,
- const DATA_BLOB *blob, size_t *sendlen,
- const struct socket_address *dest_addr)
-{
- ssize_t len;
-
- if (dest_addr->sockaddr) {
- len = sendto(sock->fd, blob->data, blob->length, 0,
- dest_addr->sockaddr, dest_addr->sockaddrlen);
- } else {
- struct sockaddr_in6 srv_addr;
- struct in6_addr addr;
-
- ZERO_STRUCT(srv_addr);
- addr = interpret_addr6(dest_addr->addr);
- if (addr.s6_addr == 0) {
- return NT_STATUS_HOST_UNREACHABLE;
- }
- srv_addr.sin6_addr = addr;
- srv_addr.sin6_port = htons(dest_addr->port);
- srv_addr.sin6_family = PF_INET6;
-
- *sendlen = 0;
-
- len = sendto(sock->fd, blob->data, blob->length, 0,
- (struct sockaddr *)&srv_addr, sizeof(srv_addr));
- }
- if (len == -1) {
- return map_nt_error_from_unix(errno);
- }
-
- *sendlen = len;
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS ipv6_set_option(struct socket_context *sock, const char *option, const char *val)
-{
- set_socket_options(sock->fd, option);
- return NT_STATUS_OK;
-}
-
-static char *ipv6_tcp_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx)
-{
- struct sockaddr_in6 peer_addr;
- socklen_t len = sizeof(peer_addr);
- struct hostent *he;
- int ret;
-
- ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len);
- if (ret == -1) {
- return NULL;
- }
-
- he = gethostbyaddr((char *)&peer_addr.sin6_addr, sizeof(peer_addr.sin6_addr), AF_INET6);
- if (he == NULL) {
- return NULL;
- }
-
- return talloc_strdup(mem_ctx, he->h_name);
-}
-
-static struct socket_address *ipv6_tcp_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
-{
- struct sockaddr_in6 *peer_addr;
- socklen_t len = sizeof(*peer_addr);
- struct socket_address *peer;
- int ret;
- char addr[128];
- const char *addr_ret;
-
- peer = talloc(mem_ctx, struct socket_address);
- if (!peer) {
- return NULL;
- }
-
- peer->family = sock->backend_name;
- peer_addr = talloc(peer, struct sockaddr_in6);
- if (!peer_addr) {
- talloc_free(peer);
- return NULL;
- }
-
- peer->sockaddr = (struct sockaddr *)peer_addr;
-
- ret = getpeername(sock->fd, peer->sockaddr, &len);
- if (ret == -1) {
- talloc_free(peer);
- return NULL;
- }
-
- peer->sockaddrlen = len;
-
- addr_ret = inet_ntop(AF_INET6, &peer_addr->sin6_addr, addr, sizeof(addr));
- if (addr_ret == NULL) {
- talloc_free(peer);
- return NULL;
- }
-
- peer->addr = talloc_strdup(peer, addr_ret);
- if (peer->addr == NULL) {
- talloc_free(peer);
- return NULL;
- }
-
- peer->port = ntohs(peer_addr->sin6_port);
-
- return peer;
-}
-
-static struct socket_address *ipv6_tcp_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
+/*
+ this is the only function that needs to be different for sockets forced to ipv4
+ */
+static NTSTATUS ipv4_init(struct socket_context *sock)
{
- struct sockaddr_in6 *local_addr;
- socklen_t len = sizeof(*local_addr);
- struct socket_address *local;
- int ret;
- char addrstring[INET6_ADDRSTRLEN];
-
- local = talloc(mem_ctx, struct socket_address);
- if (!local) {
- return NULL;
- }
-
- local->family = sock->backend_name;
- local_addr = talloc(local, struct sockaddr_in6);
- if (!local_addr) {
- talloc_free(local);
- return NULL;
- }
+ NT_STATUS_NOT_OK_RETURN(ip_init(sock));
- local->sockaddr = (struct sockaddr *)local_addr;
-
- ret = getsockname(sock->fd, local->sockaddr, &len);
- if (ret == -1) {
- talloc_free(local);
- return NULL;
- }
-
- local->sockaddrlen = len;
-
- if (inet_ntop(AF_INET6, &local_addr->sin6_addr, addrstring,
- sizeof(addrstring)) == NULL) {
- DEBUG(0, ("Unable to convert address to string: %s\n",
- strerror(errno)));
- talloc_free(local);
- return NULL;
- }
+ sock->backend_name = "ipv4";
- local->addr = talloc_strdup(mem_ctx, addrstring);
- if (!local->addr) {
- talloc_free(local);
- return NULL;
- }
- local->port = ntohs(local_addr->sin6_port);
-
- return local;
+ return ip_create_socket(sock, AF_INET);
}
-static const struct socket_ops ipv6_tcp_ops = {
- .name = "ipv6",
- .fn_init = ipv6_init,
- .fn_connect = ipv6_tcp_connect,
+static const struct socket_ops ipv4_ops = {
+ .name = "ipv4",
+ .fn_init = ipv4_init,
+ .fn_connect = ip_connect,
.fn_connect_complete = ip_connect_complete,
- .fn_listen = ipv6_listen,
- .fn_accept = ipv6_tcp_accept,
+ .fn_listen = ip_listen,
+ .fn_accept = ip_accept,
.fn_recv = ip_recv,
- .fn_recvfrom = ipv6_recvfrom,
+ .fn_recvfrom = ip_recvfrom,
.fn_send = ip_send,
- .fn_sendto = ipv6_sendto,
+ .fn_sendto = ip_sendto,
.fn_pending = ip_pending,
.fn_close = ip_close,
- .fn_set_option = ipv6_set_option,
+ .fn_set_option = ip_set_option,
- .fn_get_peer_name = ipv6_tcp_get_peer_name,
- .fn_get_peer_addr = ipv6_tcp_get_peer_addr,
- .fn_get_my_addr = ipv6_tcp_get_my_addr,
+ .fn_get_peer_name = ip_get_peer_name,
+ .fn_get_peer_addr = ip_get_peer_addr,
+ .fn_get_my_addr = ip_get_my_addr,
.fn_get_fd = ip_get_fd
};
-_PUBLIC_ const struct socket_ops *socket_ipv6_ops(enum socket_type type)
+_PUBLIC_ const struct socket_ops *socket_ipv4_ops(enum socket_type type)
{
- return &ipv6_tcp_ops;
+ return &ipv4_ops;
}
-#endif
diff --git a/source/lib/socket/socket_unix.c b/source/lib/socket/socket_unix.c
index af7d2bb..f49991d 100644
--- a/source/lib/socket/socket_unix.c
+++ b/source/lib/socket/socket_unix.c
@@ -58,6 +58,12 @@ static NTSTATUS unixdom_init(struct socket_context *sock)
sock->backend_name = "unix";
+ /* we don't do a connect() on dgram sockets, so need to set
+ non-blocking at socket create time */
+ if (!(sock->flags & SOCKET_FLAG_BLOCK) && sock->type == SOCKET_TYPE_DGRAM) {
+ set_blocking(sock->fd, false);
+ }
+
return NT_STATUS_OK;
}
@@ -288,8 +294,7 @@ static NTSTATUS unixdom_sendto(struct socket_context *sock,
}
-static NTSTATUS unixdom_set_option(struct socket_context *sock,
- const char *option, const char *val)
+static NTSTATUS unixdom_set_option(struct socket_context *sock, const char *option)
{
return NT_STATUS_OK;
}
@@ -311,7 +316,6 @@ static struct socket_address *unixdom_get_peer_addr(struct socket_context *sock,
return NULL;
}
- peer->family = sock->backend_name;
peer_addr = talloc(peer, struct sockaddr_in);
if (!peer_addr) {
talloc_free(peer);
@@ -350,7 +354,6 @@ static struct socket_address *unixdom_get_my_addr(struct socket_context *sock, T
return NULL;
}
- local->family = sock->backend_name;
local_addr = talloc(local, struct sockaddr_in);
if (!local_addr) {
talloc_free(local);
diff --git a/source/lib/socket_wrapper/socket_wrapper.c b/source/lib/socket_wrapper/socket_wrapper.c
index 86d9f7a..867cda8 100644
--- a/source/lib/socket_wrapper/socket_wrapper.c
+++ b/source/lib/socket_wrapper/socket_wrapper.c
@@ -160,11 +160,9 @@ static void set_port(int family, int prt, struct sockaddr *addr)
case AF_INET:
((struct sockaddr_in *)addr)->sin_port = htons(prt);
break;
-#ifdef HAVE_IPV6
case AF_INET6:
((struct sockaddr_in6 *)addr)->sin6_port = htons(prt);
break;
-#endif
}
}
@@ -173,10 +171,8 @@ static size_t socket_length(int family)
switch (family) {
case AF_INET:
return sizeof(struct sockaddr_in);
-#ifdef HAVE_IPV6
case AF_INET6:
return sizeof(struct sockaddr_in6);
-#endif
}
return 0;
}
@@ -283,7 +279,6 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, sock
*len = sizeof(*in2);
break;
}
-#ifdef HAVE_IPV6
case SOCKET_TYPE_CHAR_TCP_V6:
case SOCKET_TYPE_CHAR_UDP_V6: {
struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)in;
@@ -301,7 +296,6 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, sock
*len = sizeof(*in2);
break;
}
-#endif
default:
errno = EINVAL;
return -1;
@@ -363,7 +357,6 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
if (bcast) *bcast = is_bcast;
break;
}
-#ifdef HAVE_IPV6
case AF_INET6: {
const struct sockaddr_in6 *in =
(const struct sockaddr_in6 *)inaddr;
@@ -384,7 +377,6 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
break;
}
-#endif
default:
errno = ENETUNREACH;
return -1;
@@ -470,7 +462,6 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
}
break;
}
-#ifdef HAVE_IPV6
case AF_INET6: {
const struct sockaddr_in6 *in =
(const struct sockaddr_in6 *)inaddr;
@@ -491,7 +482,6 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
break;
}
-#endif
default:
errno = ENETUNREACH;
return -1;
@@ -542,9 +532,7 @@ static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr
switch (in_addr->sa_family) {
case AF_INET:
-#ifdef HAVE_IPV6
case AF_INET6:
-#endif
switch (si->type) {
case SOCK_STREAM:
case SOCK_DGRAM:
@@ -583,9 +571,7 @@ static int sockaddr_convert_from_un(const struct socket_info *si,
switch (family) {
case AF_INET:
-#ifdef HAVE_IPV6
case AF_INET6:
-#endif
switch (si->type) {
case SOCK_STREAM:
case SOCK_DGRAM:
@@ -1207,9 +1193,7 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol)
switch (family) {
case AF_INET:
-#ifdef HAVE_IPV6
case AF_INET6:
-#endif
break;
case AF_UNIX:
return real_socket(family, type, protocol);
@@ -1414,7 +1398,6 @@ static int swrap_auto_bind(struct socket_info *si)
si->myname = sockaddr_dup(&in, si->myname_len);
break;
}
-#ifdef HAVE_IPV6
case AF_INET6: {
struct sockaddr_in6 in6;
@@ -1437,7 +1420,6 @@ static int swrap_auto_bind(struct socket_info *si)
si->myname = sockaddr_dup(&in6, si->myname_len);
break;
}
-#endif
default:
errno = ESOCKTNOSUPPORT;
return -1;
diff --git a/source/lib/tdr/tdr.c b/source/lib/tdr/tdr.c
index 2ad0991..5b8be39 100644
--- a/source/lib/tdr/tdr.c
+++ b/source/lib/tdr/tdr.c
@@ -217,8 +217,13 @@ NTSTATUS tdr_pull_ipv4address(struct tdr_pull *tdr, TALLOC_CTX *ctx,
*/
NTSTATUS tdr_push_ipv4address(struct tdr_push *tdr, const char **address)
{
- uint32_t addr = htonl(interpret_addr(*address));
- TDR_CHECK(tdr_push_uint32(tdr, &addr));
+ struct in_addr addr;
+ uint32_t h_addr;
+ if (inet_pton(AF_INET, *address, &addr) <= 0) {
+ return NT_STATUS_INVALID_ADDRESS;
+ }
+ h_addr = htonl(addr.s_addr);
+ TDR_CHECK(tdr_push_uint32(tdr, &h_addr));
return NT_STATUS_OK;
}
diff --git a/source/lib/tls/tls.c b/source/lib/tls/tls.c
index b298fb1..d896e0d 100644
--- a/source/lib/tls/tls.c
+++ b/source/lib/tls/tls.c
@@ -599,7 +599,7 @@ failed:
return new_sock;
}
-static NTSTATUS tls_socket_set_option(struct socket_context *sock, const char *option, const char *val)
+static NTSTATUS tls_socket_set_option(struct socket_context *sock, const char *option)
{
set_socket_options(socket_get_fd(sock), option);
return NT_STATUS_OK;
diff --git a/source/lib/util/config.mk b/source/lib/util/config.mk
index 5a4b831..ca66fde 100644
--- a/source/lib/util/config.mk
+++ b/source/lib/util/config.mk
@@ -13,6 +13,7 @@ LIBSAMBA-UTIL_OBJ_FILES = $(addprefix lib/util/, \
time.o \
genrand.o \
dprintf.o \
+ util_ip.o \
util_str.o \
util_strlist.o \
util_file.o \
diff --git a/source/lib/util/fault.c b/source/lib/util/fault.c
index cb51cbd..40d0534 100644
--- a/source/lib/util/fault.c
+++ b/source/lib/util/fault.c
@@ -160,7 +160,7 @@ _NORETURN_ static void fault_report(int sig)
if (counter) _exit(1);
DEBUG(0,("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"));
- DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),SAMBA_VERSION_STRING));
+ DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)\n",sig,(int)getpid(), "SAMBA_VERSION_STRING" ));
DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n"));
DEBUG(0,("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"));
diff --git a/source/lib/util/util.c b/source/lib/util/util.c
index b5bb753..bc75b83 100644
--- a/source/lib/util/util.c
+++ b/source/lib/util/util.c
@@ -216,106 +216,6 @@ _PUBLIC_ char *get_myname(void)
return hostname;
}
-/**
- Return true if a string could be a pure IP address.
-**/
-
-_PUBLIC_ bool is_ipaddress(const char *str)
-{
- bool pure_address = true;
- int i;
-
- if (str == NULL) return false;
-
- for (i=0; pure_address && str[i]; i++)
- if (!(isdigit((int)str[i]) || str[i] == '.'))
- pure_address = false;
-
- /* Check that a pure number is not misinterpreted as an IP */
- pure_address = pure_address && (strchr(str, '.') != NULL);
-
- return pure_address;
-}
-
-/**
- Interpret an internet address or name into an IP address in 4 byte form.
-**/
-_PUBLIC_ uint32_t interpret_addr(const char *str)
-{
- struct hostent *hp;
- uint32_t res;
-
- if (str == NULL || *str == 0 ||
- strcmp(str,"0.0.0.0") == 0) {
- return 0;
- }
- if (strcmp(str,"255.255.255.255") == 0) {
- return 0xFFFFFFFF;
- }
- /* recognise 'localhost' as a special name. This fixes problems with
- some hosts that don't have localhost in /etc/hosts */
- if (strcasecmp(str,"localhost") == 0) {
- str = "127.0.0.1";
- }
-
- /* if it's in the form of an IP address then get the lib to interpret it */
- if (is_ipaddress(str)) {
- res = inet_addr(str);
- } else {
- /* otherwise assume it's a network name of some sort and use
- sys_gethostbyname */
- if ((hp = sys_gethostbyname(str)) == 0) {
- DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
- return 0;
- }
-
- if(hp->h_addr == NULL) {
- DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str));
- return 0;
- }
- memcpy((char *)&res,(char *)hp->h_addr, 4);
- }
-
- if (res == (uint32_t)-1)
- return(0);
-
- return(res);
-}
-
-/**
- A convenient addition to interpret_addr().
-**/
-_PUBLIC_ struct in_addr interpret_addr2(const char *str)
-{
- struct in_addr ret;
- uint32_t a = interpret_addr(str);
- ret.s_addr = a;
- return ret;
-}
-
-/**
- Check if an IP is the 0.0.0.0.
-**/
-
-_PUBLIC_ bool is_zero_ip(struct in_addr ip)
-{
- return ip.s_addr == 0;
-}
-
-/**
- Are two IPs on the same subnet?
-**/
-
-_PUBLIC_ bool same_net(struct in_addr ip1, struct in_addr ip2, struct in_addr mask)
-{
- uint32_t net1,net2,nmask;
-
- nmask = ntohl(mask.s_addr);
- net1 = ntohl(ip1.s_addr);
- net2 = ntohl(ip2.s_addr);
-
- return((net1 & nmask) == (net2 & nmask));
-}
/**
diff --git a/source/lib/util/util.h b/source/lib/util/util.h
index ffe83c1..fc269dc 100644
--- a/source/lib/util/util.h
+++ b/source/lib/util/util.h
@@ -615,31 +615,6 @@ _PUBLIC_ void msleep(unsigned int t);
_PUBLIC_ char* get_myname(void);
/**
- Return true if a string could be a pure IP address.
-**/
-_PUBLIC_ bool is_ipaddress(const char *str);
-
-/**
- Interpret an internet address or name into an IP address in 4 byte form.
-**/
-_PUBLIC_ uint32_t interpret_addr(const char *str);
-
-/**
- A convenient addition to interpret_addr().
-**/
-_PUBLIC_ struct in_addr interpret_addr2(const char *str);
-
-/**
- Check if an IP is the 0.0.0.0.
-**/
-_PUBLIC_ bool is_zero_ip(struct in_addr ip);
-
-/**
- Are two IPs on the same subnet?
-**/
-_PUBLIC_ bool same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
-
-/**
Check if a process exists. Does this work on all unixes?
**/
_PUBLIC_ bool process_exists(pid_t pid);
diff --git a/source/libcli/cldap/cldap.c b/source/libcli/cldap/cldap.c
index d991028..76ef877 100644
--- a/source/libcli/cldap/cldap.c
+++ b/source/libcli/cldap/cldap.c
@@ -242,7 +242,8 @@ static void cldap_socket_handler(struct event_context *ev, struct fd_event *fde,
*/
struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx,
struct event_context *event_ctx,
- struct smb_iconv_convenience *iconv_convenience)
+ struct smb_iconv_convenience *iconv_convenience,
+ struct socket_address *socket_address)
{
struct cldap_socket *cldap;
NTSTATUS status;
@@ -265,9 +266,18 @@ struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx,
talloc_steal(cldap, cldap->sock);
+ if (socket_address) {
+ status = socket_listen(cldap->sock, socket_address, 0, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to bind cldap to %s:%d - %s\n",
+ socket_address->addr, socket_address->port, nt_errstr(status)));
+ goto failed;
+ }
+ }
+
cldap->fde = event_add_fd(cldap->event_ctx, cldap,
- socket_get_fd(cldap->sock), 0,
- cldap_socket_handler, cldap);
+ socket_get_fd(cldap->sock), 0,
+ cldap_socket_handler, cldap);
cldap->send_queue = NULL;
cldap->incoming.handler = NULL;
diff --git a/source/libcli/cldap/cldap.h b/source/libcli/cldap/cldap.h
index eb0191d..616e2bf 100644
--- a/source/libcli/cldap/cldap.h
+++ b/source/libcli/cldap/cldap.h
@@ -113,7 +113,8 @@ struct cldap_search {
struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx,
struct event_context *event_ctx,
- struct smb_iconv_convenience *iconv_convenience);
+ struct smb_iconv_convenience *iconv_convenience,
+ struct socket_address *address);
NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap,
void (*handler)(struct cldap_socket *, struct ldap_message *,
struct socket_address *),
diff --git a/source/libcli/dgram/dgramsocket.c b/source/libcli/dgram/dgramsocket.c
index 130d8ae..db71b2f 100644
--- a/source/libcli/dgram/dgramsocket.c
+++ b/source/libcli/dgram/dgramsocket.c
@@ -174,10 +174,10 @@ struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx,
}
if (dgmsock->event_ctx == NULL) goto failed;
- status = socket_create("ip", SOCKET_TYPE_DGRAM, &dgmsock->sock, 0);
+ status = socket_create("ipv4", SOCKET_TYPE_DGRAM, &dgmsock->sock, 0);
if (!NT_STATUS_IS_OK(status)) goto failed;
- socket_set_option(dgmsock->sock, "SO_BROADCAST", "1");
+ socket_set_option(dgmsock->sock, "SO_BROADCAST=1");
talloc_steal(dgmsock, dgmsock->sock);
diff --git a/source/libcli/nbt/nbtname.c b/source/libcli/nbt/nbtname.c
index 0d9073c..9d58ab2 100644
--- a/source/libcli/nbt/nbtname.c
+++ b/source/libcli/nbt/nbtname.c
@@ -28,6 +28,8 @@
#include "librpc/gen_ndr/ndr_misc.h"
#include "system/locale.h"
#include "param/param.h"
+#include "system/network.h"
+#include "lib/util/util_ip.h"
/* don't allow an unlimited number of name components */
#define MAX_COMPONENTS 10
diff --git a/source/libcli/nbt/nbtsocket.c b/source/libcli/nbt/nbtsocket.c
index 7471279..3b8de54 100644
--- a/source/libcli/nbt/nbtsocket.c
+++ b/source/libcli/nbt/nbtsocket.c
@@ -325,10 +325,10 @@ _PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx,
}
if (nbtsock->event_ctx == NULL) goto failed;
- status = socket_create("ip", SOCKET_TYPE_DGRAM, &nbtsock->sock, 0);
+ status = socket_create("ipv4", SOCKET_TYPE_DGRAM, &nbtsock->sock, 0);
if (!NT_STATUS_IS_OK(status)) goto failed;
- socket_set_option(nbtsock->sock, "SO_BROADCAST", "1");
+ socket_set_option(nbtsock->sock, "SO_BROADCAST=1");
talloc_steal(nbtsock, nbtsock->sock);
diff --git a/source/libcli/raw/clisocket.c b/source/libcli/raw/clisocket.c
index 1dcf2d1..c91b729 100644
--- a/source/libcli/raw/clisocket.c
+++ b/source/libcli/raw/clisocket.c
@@ -110,7 +110,7 @@ static void smbcli_sock_connect_recv_conn(struct composite_context *ctx)
if (!composite_is_ok(state->ctx)) return;
state->ctx->status =
- socket_set_option(sock, state->socket_options, NULL);
+ socket_set_option(sock, state->socket_options);
if (!composite_is_ok(state->ctx)) return;
@@ -183,7 +183,7 @@ _PUBLIC_ void smbcli_sock_dead(struct smbcli_socket *sock)
****************************************************************************/
void smbcli_sock_set_options(struct smbcli_socket *sock, const char *options)
{
- socket_set_option(sock->sock, options, NULL);
+ socket_set_option(sock->sock, options);
}
/****************************************************************************
diff --git a/source/libcli/raw/rawfile.c b/source/libcli/raw/rawfile.c
index 3c5c1b7..8b17a34 100644
--- a/source/libcli/raw/rawfile.c
+++ b/source/libcli/raw/rawfile.c
@@ -1,3 +1,26 @@
+/* server to server copy? */
+
+/*
+ wan accelerators: pre-ack writes
+ unlink, rmdir: go back to 1 cmd? or chaining?
+ compounding: change to win32 api?
+ reconnect session?
+ will regain oplocks on open handles? how? notify when oplock available?
+ looking at header compression
+ HMAC SHA-256 for signing - 128 bytes plus fixed seed
+ VC count gone
+
+ netsh enable/disable ctcp
+
+ */
+
+/*
+ likewise: lac AD admin tools, .NET, mono, will be released
+ tested with S4 ?
+ likewisesoftware.com/community
+
+ */
+
/*
Unix SMB/CIFS implementation.
client file operations
diff --git a/source/libcli/raw/trans2.h b/source/libcli/raw/trans2.h
index 5b7987a..389bdcc 100644
--- a/source/libcli/raw/trans2.h
+++ b/source/libcli/raw/trans2.h
@@ -75,6 +75,7 @@ Found 4 aliased levels
#define SMB_QFS_UNIX_INFO 0x200
#define SMB_QFS_POSIX_INFO 0x201
#define SMB_QFS_POSIX_WHOAMI 0x202
+#define SMB_QFS_PROXY_INFORMATION 0x203 /* WAFS sam@liddicott.com */
#define SMB_QFS_VOLUME_INFORMATION 1001
#define SMB_QFS_SIZE_INFORMATION 1003
#define SMB_QFS_DEVICE_INFORMATION 1004
diff --git a/source/libcli/resolve/host.c b/source/libcli/resolve/host.c
index 4b8f3f9..7119f9a 100644
--- a/source/libcli/resolve/host.c
+++ b/source/libcli/resolve/host.c
@@ -35,6 +35,7 @@
#include "libcli/composite/composite.h"
#include "librpc/gen_ndr/ndr_nbt.h"
#include "libcli/resolve/resolve.h"
+#include "lib/util/util_ip.h"
struct host_state {
struct nbt_name name;
@@ -66,17 +67,15 @@ static int host_destructor(struct host_state *state)
static void run_child(struct composite_context *c, int fd)
{
struct host_state *state = talloc_get_type(c->private_data, struct host_state);
- struct in_addr ip;
- const char *address;
+ char *address;
/* this is the blocking call we are going to lots of trouble
to avoid in the parent */
- ip = interpret_addr2(state->name.name);
-
- address = inet_ntoa(ip);
+ address = interpret_addr_str(state, state->name.name);
if (address != NULL) {
write(fd, address, strlen(address)+1);
}
+ talloc_free(address);
close(fd);
}
@@ -105,13 +104,7 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde,
return;
}
- /* enusre the address looks good */
address[ret] = 0;
- if (strcmp(address, "0.0.0.0") == 0 ||
- inet_addr(address) == INADDR_NONE) {
- composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
- return;
- }
state->reply_addr = talloc_strdup(state, address);
if (composite_nomem(state->reply_addr, c)) return;
diff --git a/source/libcli/resolve/resolve.c b/source/libcli/resolve/resolve.c
index 33ace09..1149ab4 100644
--- a/source/libcli/resolve/resolve.c
+++ b/source/libcli/resolve/resolve.c
@@ -28,6 +28,7 @@
#include "param/param.h"
#include "system/network.h"
#include "util/dlinklist.h"
+#include "lib/util/util_ip.h"
struct resolve_state {
struct resolve_context *ctx;
@@ -163,8 +164,7 @@ struct composite_context *resolve_name_send(struct resolve_context *ctx,
if (is_ipaddress(state->name.name) ||
strcasecmp(state->name.name, "localhost") == 0) {
- struct in_addr ip = interpret_addr2(state->name.name);
- state->reply_addr = talloc_strdup(state, inet_ntoa(ip));
+ state->reply_addr = interpret_addr_str(state, state->name.name);
if (composite_nomem(state->reply_addr, c)) return c;
composite_done(c);
return c;
diff --git a/source/libcli/resolve/testsuite.c b/source/libcli/resolve/testsuite.c
index 73a8c84..f59344f 100644
--- a/source/libcli/resolve/testsuite.c
+++ b/source/libcli/resolve/testsuite.c
@@ -24,6 +24,7 @@
#include "libcli/resolve/resolve.h"
#include "torture/torture.h"
#include "system/network.h"
+#include "lib/util/util_ip.h"
static bool test_async_resolve(struct torture_context *tctx)
{
@@ -69,8 +70,13 @@ static bool test_sync_resolve(struct torture_context *tctx)
torture_comment(tctx, "Testing sync resolve of '%s' for %d seconds\n",
host, timelimit);
while (timeval_elapsed(&tv) < timelimit) {
- inet_ntoa(interpret_addr2(host));
+ char *addr = interpret_addr_str(tctx, host);
+ if (addr == NULL) {
+ torture_comment(tctx, "Failed to resolve '%s'\n", host);
+ return false;
+ }
count++;
+ talloc_free(host);
}
torture_comment(tctx, "sync rate of %.1f resolves/sec\n",
diff --git a/source/libcli/smb_composite/connect.c b/source/libcli/smb_composite/connect.c
index c44c62f..03efacd 100644
--- a/source/libcli/smb_composite/connect.c
+++ b/source/libcli/smb_composite/connect.c
@@ -30,6 +30,8 @@
#include "auth/credentials/credentials.h"
#include "librpc/gen_ndr/ndr_nbt.h"
#include "param/param.h"
+#include "system/network.h"
+#include "lib/util/util_ip.h"
/* the stages of this call */
enum connect_stage {CONNECT_RESOLVE,
diff --git a/source/libcli/wrepl/winsrepl.c b/source/libcli/wrepl/winsrepl.c
index 3e7793c..12144ce 100644
--- a/source/libcli/wrepl/winsrepl.c
+++ b/source/libcli/wrepl/winsrepl.c
@@ -181,7 +181,7 @@ struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx,
wrepl_socket->iconv_convenience = iconv_convenience;
- status = socket_create("ip", SOCKET_TYPE_STREAM, &wrepl_socket->sock, 0);
+ status = socket_create("ipv4", SOCKET_TYPE_STREAM, &wrepl_socket->sock, 0);
if (!NT_STATUS_IS_OK(status)) goto failed;
talloc_steal(wrepl_socket, wrepl_socket->sock);
diff --git a/source/libnet/libnet_become_dc.c b/source/libnet/libnet_become_dc.c
index e8a5329..3d0540d 100644
--- a/source/libnet/libnet_become_dc.c
+++ b/source/libnet/libnet_become_dc.c
@@ -748,7 +748,7 @@ static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
s->cldap.io.in.version = 6;
s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx,
- lp_iconv_convenience(s->libnet->lp_ctx));
+ lp_iconv_convenience(s->libnet->lp_ctx), NULL);
if (composite_nomem(s->cldap.sock, c)) return;
req = cldap_netlogon_send(s->cldap.sock, &s->cldap.io);
diff --git a/source/libnet/libnet_site.c b/source/libnet/libnet_site.c
index dabd23a..ea46df4 100644
--- a/source/libnet/libnet_site.c
+++ b/source/libnet/libnet_site.c
@@ -55,7 +55,7 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_JoinSite *r)
search.in.acct_control = -1;
search.in.version = 6;
- cldap = cldap_socket_init(tmp_ctx, NULL, lp_iconv_convenience(global_loadparm));
+ cldap = cldap_socket_init(tmp_ctx, NULL, lp_iconv_convenience(global_loadparm), NULL);
status = cldap_netlogon(cldap, tmp_ctx, &search);
if (!NT_STATUS_IS_OK(status)) {
/*
diff --git a/source/libnet/libnet_unbecome_dc.c b/source/libnet/libnet_unbecome_dc.c
index 6f06585..25a71b6 100644
--- a/source/libnet/libnet_unbecome_dc.c
+++ b/source/libnet/libnet_unbecome_dc.c
@@ -268,7 +268,7 @@ static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s)
s->cldap.io.in.version = 6;
s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx,
- lp_iconv_convenience(s->libnet->lp_ctx));
+ lp_iconv_convenience(s->libnet->lp_ctx), NULL);
if (composite_nomem(s->cldap.sock, c)) return;
req = cldap_netlogon_send(s->cldap.sock, &s->cldap.io);
diff --git a/source/librpc/ndr/ndr_basic.c b/source/librpc/ndr/ndr_basic.c
index 1d2b47c..be178c7 100644
--- a/source/librpc/ndr/ndr_basic.c
+++ b/source/librpc/ndr/ndr_basic.c
@@ -22,6 +22,7 @@
#include "includes.h"
#include "system/network.h"
#include "librpc/ndr/libndr.h"
+#include "lib/util/util_ip.h"
#define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))
#define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))
@@ -582,7 +583,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_ipv4address(struct ndr_pull *ndr, int ndr_fl
_PUBLIC_ enum ndr_err_code ndr_push_ipv4address(struct ndr_push *ndr, int ndr_flags, const char *address)
{
uint32_t addr;
- if (!is_ipaddress(address)) {
+ if (!is_ipv4address(address)) {
return ndr_push_error(ndr, NDR_ERR_IPV4ADDRESS,
"Invalid IPv4 address: '%s'",
address);
diff --git a/source/librpc/rpc/binding.c b/source/librpc/rpc/binding.c
index ae88dce..2697654 100644
--- a/source/librpc/rpc/binding.c
+++ b/source/librpc/rpc/binding.c
@@ -27,6 +27,8 @@
#include "librpc/gen_ndr/ndr_epmapper_c.h"
#include "librpc/gen_ndr/ndr_dcerpc.h"
#include "librpc/gen_ndr/ndr_misc.h"
+#include "system/network.h"
+#include "lib/util/util_ip.h"
#define MAX_PROTSEQ 10
diff --git a/source/librpc/rpc/dcerpc_sock.c b/source/librpc/rpc/dcerpc_sock.c
index 7480bea..4cae7ee 100644
--- a/source/librpc/rpc/dcerpc_sock.c
+++ b/source/librpc/rpc/dcerpc_sock.c
@@ -361,10 +361,7 @@ struct pipe_tcp_state {
};
-#if 0 /* disabled till we can resolve names to ipv6 addresses */
-static void continue_ipv6_open_socket(struct composite_context *ctx);
-#endif
-static void continue_ipv4_open_socket(struct composite_context *ctx);
+static void continue_ip_open_socket(struct composite_context *ctx);
static void continue_ip_resolve_name(struct composite_context *ctx);
static void continue_ip_resolve_name(struct composite_context *ctx)
@@ -373,62 +370,27 @@ static void continue_ip_resolve_name(struct composite_context *ctx)
struct composite_context);
struct pipe_tcp_state *s = talloc_get_type(c->private_data,
struct pipe_tcp_state);
- struct composite_context *sock_ipv4_req;
+ struct composite_context *sock_ip_req;
c->status = resolve_name_recv(ctx, s, &s->address);
if (!composite_is_ok(c)) return;
/* prepare server address using host ip:port and transport name */
- s->srvaddr = socket_address_from_strings(s->conn, "ipv4", s->address, s->port);
+ s->srvaddr = socket_address_from_strings(s->conn, "ip", s->address, s->port);
if (composite_nomem(s->srvaddr, c)) return;
- /* resolve_nbt_name gives only ipv4 ... - send socket open request */
- sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn,
+ sock_ip_req = dcerpc_pipe_open_socket_send(c, s->conn,
s->resolve_ctx,
s->srvaddr, s->target_hostname,
NCACN_IP_TCP);
- composite_continue(c, sock_ipv4_req, continue_ipv4_open_socket, c);
+ composite_continue(c, sock_ip_req, continue_ip_open_socket, c);
}
/*
Stage 2 of dcerpc_pipe_open_tcp_send: receive result of pipe open request
- on IPv6 and send the request on IPv4 unless IPv6 transport succeeded.
+ on IP transport.
*/
-#if 0 /* disabled till we can resolve names to ipv6 addresses */
-static void continue_ipv6_open_socket(struct composite_context *ctx)
-{
- struct composite_context *c = talloc_get_type(ctx->async.private_data,
- struct composite_context);
- struct pipe_tcp_state *s = talloc_get_type(c->private_data,
- struct pipe_tcp_state);
- struct composite_context *sock_ipv4_req;
-
- /* receive result of socket open request */
- c->status = dcerpc_pipe_open_socket_recv(ctx);
- if (NT_STATUS_IS_OK(c->status)) {
- composite_done(c);
- return;
- }
-
- talloc_free(s->srvaddr);
-
- /* prepare server address using host:ip and transport name */
- s->srvaddr = socket_address_from_strings(s->conn, "ipv4", s->address, s->port);
- if (composite_nomem(s->srvaddr, c)) return;
-
- /* try IPv4 if IPv6 fails */
- sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn,
- s->srvaddr, s->target_hostname,
- NCACN_IP_TCP);
- composite_continue(c, sock_ipv4_req, continue_ipv4_open_socket, c);
-}
-#endif
-
-/*
- Stage 2 of dcerpc_pipe_open_tcp_send: receive result of pipe open request
- on IPv4 transport.
-*/
-static void continue_ipv4_open_socket(struct composite_context *ctx)
+static void continue_ip_open_socket(struct composite_context *ctx)
{
struct composite_context *c = talloc_get_type(ctx->async.private_data,
struct composite_context);
diff --git a/source/librpc/tests/binding_string.c b/source/librpc/tests/binding_string.c
index 01cdfae..e442a2e 100644
--- a/source/librpc/tests/binding_string.c
+++ b/source/librpc/tests/binding_string.c
@@ -24,6 +24,8 @@
#include "librpc/rpc/dcerpc.h"
#include "librpc/rpc/dcerpc_proto.h"
#include "torture/torture.h"
+#include "system/network.h"
+#include "lib/util/util_ip.h"
static bool test_BindingString(struct torture_context *tctx,
const void *test_data)
diff --git a/source/nbt_server/interfaces.c b/source/nbt_server/interfaces.c
index e594750..7d8011c 100644
--- a/source/nbt_server/interfaces.c
+++ b/source/nbt_server/interfaces.c
@@ -29,6 +29,7 @@
#include "system/network.h"
#include "lib/socket/netif.h"
#include "param/param.h"
+#include "lib/util/util_ip.h"
/*
@@ -236,8 +237,8 @@ NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_con
if (num_interfaces > 0) {
primary_address = iface_n_ip(ifaces, 0);
} else {
- primary_address = inet_ntoa(interpret_addr2(
- lp_netbios_name(lp_ctx)));
+ primary_address = interpret_addr_str(tmp_ctx,
+ lp_netbios_name(lp_ctx));
}
primary_address = talloc_strdup(tmp_ctx, primary_address);
NT_STATUS_HAVE_NO_MEMORY(primary_address);
@@ -290,7 +291,7 @@ const char **nbtd_address_list(struct nbtd_interface *iface, TALLOC_CTX *mem_ctx
bool is_loopback = false;
if (iface->ip_address) {
- is_loopback = iface_same_net(iface->ip_address, "127.0.0.1", "255.0.0.0");
+ is_loopback = ip_same_net(iface->ip_address, "127.0.0.1", "255.0.0.0");
ret = str_list_add(ret, iface->ip_address);
}
@@ -300,7 +301,7 @@ const char **nbtd_address_list(struct nbtd_interface *iface, TALLOC_CTX *mem_ctx
if (!iface2->ip_address) continue;
if (!is_loopback) {
- if (iface_same_net(iface2->ip_address, "127.0.0.1", "255.0.0.0")) {
+ if (ip_same_net(iface2->ip_address, "127.0.0.1", "255.0.0.0")) {
continue;
}
}
@@ -324,7 +325,7 @@ struct nbtd_interface *nbtd_find_request_iface(struct nbtd_server *nbtd_server,
/* try to find a exact match */
for (cur=nbtd_server->interfaces;cur;cur=cur->next) {
- if (iface_same_net(address, cur->ip_address, cur->netmask)) {
+ if (ip_same_net(address, cur->ip_address, cur->netmask)) {
return cur;
}
}
diff --git a/source/nbt_server/wins/winsserver.c b/source/nbt_server/wins/winsserver.c
index f8901ce..ae73fb7 100644
--- a/source/nbt_server/wins/winsserver.c
+++ b/source/nbt_server/wins/winsserver.c
@@ -34,6 +34,7 @@
#include "lib/ldb/include/ldb.h"
#include "param/param.h"
#include "libcli/resolve/resolve.h"
+#include "lib/util/util_ip.h"
/*
work out the ttl we will use given a client requested ttl
@@ -594,9 +595,16 @@ static int nbtd_wins_randomize1Clist_sort(void *p1,/* (const char **) */
const char *a2 = (const char *)*(const char **)p2;
uint32_t match_bits1;
uint32_t match_bits2;
+ struct in_addr src_v4, a1_v4, a2_v4;
- match_bits1 = ipv4_match_bits(interpret_addr2(a1), interpret_addr2(src->addr));
- match_bits2 = ipv4_match_bits(interpret_addr2(a2), interpret_addr2(src->addr));
+ if (!interpret_addr_v4(src->addr, &src_v4) ||
+ !interpret_addr_v4(a1, &a1_v4) ||
+ !interpret_addr_v4(a2, &a2_v4)) {
+ return -1;
+ }
+
+ match_bits1 = ipv4_match_bits(a1_v4, src_v4);
+ match_bits2 = ipv4_match_bits(a2_v4, src_v4);
return match_bits2 - match_bits1;
}
@@ -634,7 +642,7 @@ static void nbtd_wins_randomize1Clist(struct loadparm_context *lp_ctx,
bool same;
/* if the current one is in the same subnet, use it */
- same = iface_same_net(addresses[idx], src->addr, mask);
+ same = ip_same_net(addresses[idx], src->addr, mask);
if (same) {
sidx = idx;
break;
diff --git a/source/ntvfs/posix/pvfs_fsinfo.c b/source/ntvfs/posix/pvfs_fsinfo.c
index 9a836fa..effe6fd 100644
--- a/source/ntvfs/posix/pvfs_fsinfo.c
+++ b/source/ntvfs/posix/pvfs_fsinfo.c
@@ -200,6 +200,15 @@ NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs,
fs->objectid_information.out.guid = *pvfs->base_fs_uuid;
return NT_STATUS_OK;
+ case RAW_QFS_UNIX_INFO:
+ /* we don't actually support the new unix extensions used
+ by cifsfs yet
+ */
+ fs->unix_info.out.major_version = 1;
+ fs->unix_info.out.minor_version = 0;
+ fs->unix_info.out.capability = 0;
+ return NT_STATUS_OK;
+
default:
break;
}
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 812162e..a3103a7 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -2331,7 +2331,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
lp_do_global_parameter(lp_ctx, "modules dir", dyn_MODULESDIR);
lp_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR);
- lp_do_global_parameter(lp_ctx, "socket address", "0.0.0.0");
+ lp_do_global_parameter(lp_ctx, "socket address", "::");
lp_do_global_parameter_var(lp_ctx, "server string",
"Samba %s", SAMBA_VERSION_STRING);
diff --git a/source/rpc_server/netlogon/dcerpc_netlogon.c b/source/rpc_server/netlogon/dcerpc_netlogon.c
index d9ae92c..e5c73ac 100644
--- a/source/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source/rpc_server/netlogon/dcerpc_netlogon.c
@@ -1030,7 +1030,7 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA
lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
lp_realm(dce_call->conn->dce_ctx->lp_ctx));
W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
- r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
+ r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\::");
W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
diff --git a/source/rpc_server/service_rpc.c b/source/rpc_server/service_rpc.c
index 27f3fe4..54c9605 100644
--- a/source/rpc_server/service_rpc.c
+++ b/source/rpc_server/service_rpc.c
@@ -356,7 +356,7 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct
status = stream_setup_socket(event_ctx, dce_ctx->lp_ctx,
model_ops, &dcesrv_stream_ops,
- "ipv4", address, &port,
+ "ip", address, &port,
lp_socket_options(dce_ctx->lp_ctx),
dcesrv_sock);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source/smb_server/smb_server.c b/source/smb_server/smb_server.c
index 367557d..bfb53aa 100644
--- a/source/smb_server/smb_server.c
+++ b/source/smb_server/smb_server.c
@@ -188,7 +188,7 @@ _PUBLIC_ NTSTATUS smbsrv_add_socket(struct event_context *event_context,
if (port == 0) continue;
status = stream_setup_socket(event_context, lp_ctx,
model_ops, &smb_stream_ops,
- "ipv4", address, &port,
+ "ip", address, &port,
lp_socket_options(lp_ctx),
NULL);
NT_STATUS_NOT_OK_RETURN(status);
@@ -238,9 +238,7 @@ static void smbsrv_task_init(struct task_server *task)
if (!NT_STATUS_IS_OK(status)) goto failed;
}
} else {
- /* Just bind to lp_socket_address() (usually 0.0.0.0) */
- status = smbsrv_add_socket(task->event_ctx, task->lp_ctx, task->model_ops,
- lp_socket_address(task->lp_ctx));
+ status = smbsrv_add_socket(task->event_ctx, task->lp_ctx, task->model_ops, "::");
if (!NT_STATUS_IS_OK(status)) goto failed;
}
diff --git a/source/smbd/service_stream.c b/source/smbd/service_stream.c
index 9f744ef..d1ead4d 100644
--- a/source/smbd/service_stream.c
+++ b/source/smbd/service_stream.c
@@ -267,11 +267,11 @@ NTSTATUS stream_setup_socket(struct event_context *event_context,
stream_socket->lp_ctx = talloc_reference(stream_socket, lp_ctx);
/* ready to listen */
- status = socket_set_option(stream_socket->sock, "SO_KEEPALIVE", NULL);
+ status = socket_set_option(stream_socket->sock, "SO_KEEPALIVE");
NT_STATUS_NOT_OK_RETURN(status);
if (socket_options != NULL) {
- status = socket_set_option(stream_socket->sock, socket_options, NULL);
+ status = socket_set_option(stream_socket->sock, socket_options);
NT_STATUS_NOT_OK_RETURN(status);
}
diff --git a/source/torture/ldap/cldap.c b/source/torture/ldap/cldap.c
index dbe9d2f..274949c 100644
--- a/source/torture/ldap/cldap.c
+++ b/source/torture/ldap/cldap.c
@@ -38,7 +38,7 @@
*/
static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
{
- struct cldap_socket *cldap = cldap_socket_init(tctx, NULL, lp_iconv_convenience(tctx->lp_ctx));
+ struct cldap_socket *cldap = cldap_socket_init(tctx, NULL, lp_iconv_convenience(tctx->lp_ctx), NULL);
NTSTATUS status;
struct cldap_netlogon search, empty_search;
union nbt_cldap_netlogon n1;
@@ -244,7 +244,7 @@ static void cldap_dump_results(struct cldap_search *search)
*/
static bool test_cldap_generic(struct torture_context *tctx, const char *dest)
{
- struct cldap_socket *cldap = cldap_socket_init(tctx, NULL, lp_iconv_convenience(tctx->lp_ctx));
+ struct cldap_socket *cldap = cldap_socket_init(tctx, NULL, lp_iconv_convenience(tctx->lp_ctx), NULL);
NTSTATUS status;
struct cldap_search search;
const char *attrs1[] = { "currentTime", "highestCommittedUSN", NULL };
diff --git a/source/torture/ldap/cldapbench.c b/source/torture/ldap/cldapbench.c
index 51586ac..ee77403 100644
--- a/source/torture/ldap/cldapbench.c
+++ b/source/torture/ldap/cldapbench.c
@@ -51,7 +51,7 @@ static void request_handler(struct cldap_request *req)
*/
static bool bench_cldap(struct torture_context *tctx, const char *address)
{
- struct cldap_socket *cldap = cldap_socket_init(tctx, NULL, lp_iconv_convenience(tctx->lp_ctx));
+ struct cldap_socket *cldap = cldap_socket_init(tctx, NULL, lp_iconv_convenience(tctx->lp_ctx), NULL);
int num_sent=0;
struct timeval tv = timeval_current();
bool ret = true;
diff --git a/source/torture/rpc/dssync.c b/source/torture/rpc/dssync.c
index b28e429..5388314 100644
--- a/source/torture/rpc/dssync.c
+++ b/source/torture/rpc/dssync.c
@@ -255,7 +255,7 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx)
struct drsuapi_DsNameString names[1];
bool ret = true;
- struct cldap_socket *cldap = cldap_socket_init(ctx, NULL, lp_iconv_convenience(tctx->lp_ctx));
+ struct cldap_socket *cldap = cldap_socket_init(ctx, NULL, lp_iconv_convenience(tctx->lp_ctx), NULL);
struct cldap_netlogon search;
r.in.bind_handle = &ctx->admin.drsuapi.bind_handle;
diff --git a/source/web_server/web_server.c b/source/web_server/web_server.c
index ac83a33..cd32fac 100644
--- a/source/web_server/web_server.c
+++ b/source/web_server/web_server.c
@@ -263,7 +263,7 @@ static void websrv_task_init(struct task_server *task)
status = stream_setup_socket(task->event_ctx,
task->lp_ctx, model_ops,
&web_stream_ops,
- "ipv4", address,
+ "ip", address,
&port, lp_socket_options(task->lp_ctx),
task);
if (!NT_STATUS_IS_OK(status)) goto failed;
@@ -273,7 +273,7 @@ static void websrv_task_init(struct task_server *task)
} else {
status = stream_setup_socket(task->event_ctx, task->lp_ctx,
model_ops, &web_stream_ops,
- "ipv4", lp_socket_address(task->lp_ctx),
+ "ip", lp_socket_address(task->lp_ctx),
&port, lp_socket_options(task->lp_ctx), task);
if (!NT_STATUS_IS_OK(status)) goto failed;
}
diff --git a/source/wrepl_server/wrepl_in_connection.c b/source/wrepl_server/wrepl_in_connection.c
index 34d94d7..f2a5a3d 100644
--- a/source/wrepl_server/wrepl_in_connection.c
+++ b/source/wrepl_server/wrepl_in_connection.c
@@ -297,7 +297,7 @@ NTSTATUS wreplsrv_setup_sockets(struct wreplsrv_service *service, struct loadpar
status = stream_setup_socket(task->event_ctx,
task->lp_ctx, model_ops,
&wreplsrv_stream_ops,
- "ipv4", address, &port,
+ "ip", address, &port,
lp_socket_options(task->lp_ctx),
service);
if (!NT_STATUS_IS_OK(status)) {
@@ -310,7 +310,7 @@ NTSTATUS wreplsrv_setup_sockets(struct wreplsrv_service *service, struct loadpar
address = lp_socket_address(lp_ctx);
status = stream_setup_socket(task->event_ctx, task->lp_ctx,
model_ops, &wreplsrv_stream_ops,
- "ipv4", address, &port, lp_socket_options(task->lp_ctx),
+ "ip", address, &port, lp_socket_options(task->lp_ctx),
service);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("stream_setup_socket(address=%s,port=%u) failed - %s\n",