summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h10
-rw-r--r--source3/lib/util_sock.c157
-rw-r--r--source3/nmbd/nmbd.c12
-rw-r--r--source3/nmbd/nmbd_subnetdb.c63
-rw-r--r--source3/rpc_server/rpc_sock_helper.c17
-rw-r--r--source3/smbd/server.c13
-rw-r--r--source3/utils/nmblookup.c16
-rw-r--r--source3/utils/smbfilter.c6
8 files changed, 142 insertions, 152 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 1d5ebecb03c..dd262529212 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -515,11 +515,11 @@ NTSTATUS receive_smb_raw(int fd,
unsigned int timeout,
size_t maxlen,
size_t *p_len);
-int open_socket_in(int type,
- uint16_t port,
- int dlevel,
- const struct sockaddr_storage *psock,
- bool rebind);
+int open_socket_in(
+ int type,
+ const struct sockaddr_storage *paddr,
+ uint16_t port,
+ bool rebind);
NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
int timeout, int *pfd);
struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index 97415011097..2dbb572a974 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -234,67 +234,59 @@ NTSTATUS receive_smb_raw(int fd, char *buffer, size_t buflen, unsigned int timeo
return NT_STATUS_OK;
}
-/****************************************************************************
- Open a socket of the specified type, port, and address for incoming data.
-****************************************************************************/
-
-int open_socket_in(int type,
- uint16_t port,
- int dlevel,
- const struct sockaddr_storage *psock,
- bool rebind)
+/*
+ * Open a socket of the specified type, port, and address for incoming data.
+ *
+ * Return sock or -errno
+ */
+
+int open_socket_in(
+ int type,
+ const struct sockaddr_storage *paddr,
+ uint16_t port,
+ bool rebind)
{
- struct sockaddr_storage sock;
- int res;
- socklen_t slen = sizeof(struct sockaddr_in);
-
- sock = *psock;
+ struct samba_sockaddr addr = {
+ .sa_socklen = sizeof(struct sockaddr_storage),
+ .u.ss = *paddr,
+ };
+ int ret, sock = -1;
+ int val = rebind ? 1 : 0;
+ bool ok;
-#if defined(HAVE_IPV6)
- if (sock.ss_family == AF_INET6) {
- ((struct sockaddr_in6 *)&sock)->sin6_port = htons(port);
- slen = sizeof(struct sockaddr_in6);
+ ok = samba_sockaddr_set_port(&addr, port);
+ if (!ok) {
+ ret = -EINVAL;
+ DBG_DEBUG("samba_sockaddr_set_port failed\n");
+ goto fail;
}
-#endif
- if (sock.ss_family == AF_INET) {
- ((struct sockaddr_in *)&sock)->sin_port = htons(port);
+
+ sock = socket(addr.u.ss.ss_family, type, 0 );
+ if (sock == -1) {
+ ret = -errno;
+ DBG_DEBUG("socket() failed: %s\n", strerror(errno));
+ goto fail;
}
- res = socket(sock.ss_family, type, 0 );
- if( res == -1 ) {
- if( DEBUGLVL(0) ) {
- dbgtext( "open_socket_in(): socket() call failed: " );
- dbgtext( "%s\n", strerror( errno ) );
- }
- return -1;
+ ret = setsockopt(
+ sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
+ if (ret == -1) {
+ ret = -errno;
+ DBG_DEBUG("setsockopt(SO_REUSEADDR) failed: %s\n",
+ strerror(errno));
+ goto fail;
}
- /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
- {
- int val = rebind ? 1 : 0;
- if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,
- (char *)&val,sizeof(val)) == -1 ) {
- if( DEBUGLVL( dlevel ) ) {
- dbgtext( "open_socket_in(): setsockopt: " );
- dbgtext( "SO_REUSEADDR = %s ",
- val?"true":"false" );
- dbgtext( "on port %d failed ", port );
- dbgtext( "with error = %s\n", strerror(errno) );
- }
- }
#ifdef SO_REUSEPORT
- if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,
- (char *)&val,sizeof(val)) == -1 ) {
- if( DEBUGLVL( dlevel ) ) {
- dbgtext( "open_socket_in(): setsockopt: ");
- dbgtext( "SO_REUSEPORT = %s ",
- val?"true":"false");
- dbgtext( "on port %d failed ", port);
- dbgtext( "with error = %s\n", strerror(errno));
- }
- }
-#endif /* SO_REUSEPORT */
+ ret = setsockopt(
+ sock, SOL_SOCKET, SO_REUSEPORT, (char *)&val, sizeof(val));
+ if (ret == -1) {
+ ret = -errno;
+ DBG_DEBUG("setsockopt(SO_REUSEPORT) failed: %s\n",
+ strerror(errno));
+ goto fail;
}
+#endif /* SO_REUSEPORT */
#ifdef HAVE_IPV6
/*
@@ -305,41 +297,50 @@ int open_socket_in(int type,
* and makes sure %I never resolves to a '::ffff:192.168.0.1'
* string.
*/
- if (sock.ss_family == AF_INET6) {
- int val = 1;
- int ret;
+ if (addr.u.ss.ss_family == AF_INET6) {
+
+ val = 1;
- ret = setsockopt(res, IPPROTO_IPV6, IPV6_V6ONLY,
- (const void *)&val, sizeof(val));
+ ret = setsockopt(
+ sock,
+ IPPROTO_IPV6,
+ IPV6_V6ONLY,
+ (const void *)&val,
+ sizeof(val));
if (ret == -1) {
- if(DEBUGLVL(0)) {
- dbgtext("open_socket_in(): IPV6_ONLY failed: ");
- dbgtext("%s\n", strerror(errno));
- }
- close(res);
- return -1;
+ ret = -errno;
+ DBG_DEBUG("setsockopt(IPV6_V6ONLY) failed: %s\n",
+ strerror(errno));
+ goto fail;
}
}
#endif
/* now we've got a socket - we need to bind it */
- if (bind(res, (struct sockaddr *)&sock, slen) == -1 ) {
- if( DEBUGLVL(dlevel) && (port == NMB_PORT ||
- port == NBT_SMB_PORT ||
- port == TCP_SMB_PORT) ) {
- char addr[INET6_ADDRSTRLEN];
- print_sockaddr(addr, sizeof(addr),
- &sock);
- dbgtext( "bind failed on port %d ", port);
- dbgtext( "socket_addr = %s.\n", addr);
- dbgtext( "Error = %s\n", strerror(errno));
- }
- close(res);
- return -1;
+ ret = bind(sock, &addr.u.sa, addr.sa_socklen);
+ if (ret == -1) {
+ char addrstr[INET6_ADDRSTRLEN];
+
+ ret = -errno;
+
+ print_sockaddr(addrstr, sizeof(addrstr), &addr.u.ss);
+ DBG_DEBUG("bind for %s port %"PRIu16" failed: %s\n",
+ addrstr,
+ port,
+ strerror(-ret));
+ goto fail;
}
- DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
- return( res );
+ DBG_DEBUG("bind succeeded on port %"PRIu16"\n", port);
+
+ return sock;
+
+fail:
+ if (sock != -1) {
+ close(sock);
+ sock = -1;
+ }
+ return ret;
}
struct open_socket_out_state {
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index 1f7e81a5473..dce746a8339 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -733,22 +733,18 @@ static bool open_sockets(bool isdaemon, int port)
}
if (isdaemon) {
- ClientNMB = open_socket_in(SOCK_DGRAM, port,
- 0, &ss,
- true);
+ ClientNMB = open_socket_in(SOCK_DGRAM, &ss, port, true);
} else {
ClientNMB = 0;
}
- if (ClientNMB == -1) {
+ if (ClientNMB < 0) {
return false;
}
- ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
- 3, &ss,
- true);
+ ClientDGRAM = open_socket_in(SOCK_DGRAM, &ss, DGRAM_PORT, true);
- if (ClientDGRAM == -1) {
+ if (ClientDGRAM < 0) {
if (ClientNMB != 0) {
close(ClientNMB);
}
diff --git a/source3/nmbd/nmbd_subnetdb.c b/source3/nmbd/nmbd_subnetdb.c
index 5c9e4c7eb26..38c6db69b3d 100644
--- a/source3/nmbd/nmbd_subnetdb.c
+++ b/source3/nmbd/nmbd_subnetdb.c
@@ -107,56 +107,55 @@ static struct subnet_record *make_subnet(const char *name, enum subnet_type type
* Fail the subnet creation if this fails.
*/
- nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,
- 0, &ss, true);
- if (nmb_sock == -1) {
- DEBUG(0, ("nmbd_subnetdb:make_subnet()\n"));
- DEBUGADD(0,(" Failed to open nmb socket on interface %s ",
- inet_ntoa(myip)));
- DEBUGADD(0,("for port %d. ", global_nmb_port));
- DEBUGADD(0,("Error was %s\n", strerror(errno)));
+ nmb_sock = open_socket_in(
+ SOCK_DGRAM, &ss, global_nmb_port, true);
+ if (nmb_sock < 0) {
+ DBG_ERR("Failed to open nmb socket on interface %s "
+ "for port %d: %s\n",
+ inet_ntoa(myip),
+ global_nmb_port,
+ strerror(-nmb_sock));
goto failed;
}
set_socket_options(nmb_sock,"SO_BROADCAST");
set_blocking(nmb_sock, false);
if (bind_bcast) {
- nmb_bcast = open_socket_in(SOCK_DGRAM, global_nmb_port,
- 0, &ss_bcast, true);
- if (nmb_bcast == -1) {
- DEBUG(0, ("nmbd_subnetdb:make_subnet()\n"));
- DEBUGADD(0,(" Failed to open nmb bcast socket on interface %s ",
- inet_ntoa(bcast_ip)));
- DEBUGADD(0,("for port %d. ", global_nmb_port));
- DEBUGADD(0,("Error was %s\n", strerror(errno)));
+ nmb_bcast = open_socket_in(
+ SOCK_DGRAM, &ss_bcast, global_nmb_port, true);
+ if (nmb_bcast < 0) {
+ DBG_ERR("Failed to open nmb bcast socket on "
+ "interface %s for port %d: %s\n",
+ inet_ntoa(myip),
+ global_nmb_port,
+ strerror(-nmb_bcast));
goto failed;
}
set_socket_options(nmb_bcast, "SO_BROADCAST");
set_blocking(nmb_bcast, false);
}
- dgram_sock = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
- 3, &ss, true);
- if (dgram_sock == -1) {
- DEBUG(0, ("nmbd_subnetdb:make_subnet()\n"));
- DEBUGADD(0,(" Failed to open dgram socket on interface %s ",
- inet_ntoa(myip)));
- DEBUGADD(0,("for port %d. ", DGRAM_PORT));
- DEBUGADD(0,("Error was %s\n", strerror(errno)));
+ dgram_sock = open_socket_in(SOCK_DGRAM, &ss, DGRAM_PORT, true);
+ if (dgram_sock < 0) {
+ DBG_ERR("Failed to open dgram socket on "
+ "interface %s for port %d: %s\n",
+ inet_ntoa(myip),
+ DGRAM_PORT,
+ strerror(-dgram_sock));
goto failed;
}
set_socket_options(dgram_sock, "SO_BROADCAST");
set_blocking(dgram_sock, false);
if (bind_bcast) {
- dgram_bcast = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
- 3, &ss_bcast, true);
- if (dgram_bcast == -1) {
- DEBUG(0, ("nmbd_subnetdb:make_subnet()\n"));
- DEBUGADD(0,(" Failed to open dgram bcast socket on interface %s ",
- inet_ntoa(bcast_ip)));
- DEBUGADD(0,("for port %d. ", DGRAM_PORT));
- DEBUGADD(0,("Error was %s\n", strerror(errno)));
+ dgram_bcast = open_socket_in(
+ SOCK_DGRAM, &ss_bcast, DGRAM_PORT, true);
+ if (dgram_bcast < 0) {
+ DBG_ERR("Failed to open dgram bcast socket on "
+ "interface %s for port %d: %s\n",
+ inet_ntoa(myip),
+ DGRAM_PORT,
+ strerror(-dgram_sock));
goto failed;
}
set_socket_options(dgram_bcast, "SO_BROADCAST");
diff --git a/source3/rpc_server/rpc_sock_helper.c b/source3/rpc_server/rpc_sock_helper.c
index 5756a891544..7308338b71f 100644
--- a/source3/rpc_server/rpc_sock_helper.c
+++ b/source3/rpc_server/rpc_sock_helper.c
@@ -120,26 +120,19 @@ static NTSTATUS dcesrv_create_ncacn_ip_tcp_socket(
uint16_t i;
for (i = lp_rpc_low_port(); i <= lp_rpc_high_port(); i++) {
- fd = open_socket_in(SOCK_STREAM,
- i,
- 0,
- ifss,
- false);
+ fd = open_socket_in(SOCK_STREAM, ifss, i, false);
if (fd >= 0) {
*port = i;
break;
}
}
} else {
- fd = open_socket_in(SOCK_STREAM,
- *port,
- 0,
- ifss,
- true);
+ fd = open_socket_in(SOCK_STREAM, ifss, *port, true);
}
- if (fd == -1) {
+
+ if (fd < 0) {
DBG_ERR("Failed to create socket on port %u!\n", *port);
- return NT_STATUS_UNSUCCESSFUL;
+ return map_nt_error_from_unix(-fd);
}
/* ready to listen */
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 8dd3068bf08..3ca71f4e718 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -1073,14 +1073,11 @@ static bool smbd_open_one_socket(struct smbd_parent_context *parent,
}
s->parent = parent;
- s->fd = open_socket_in(SOCK_STREAM,
- port,
- parent->sockets == NULL ? 0 : 2,
- ifss,
- true);
- if (s->fd == -1) {
- DEBUG(0,("smbd_open_one_socket: open_socket_in: "
- "%s\n", strerror(errno)));
+
+ s->fd = open_socket_in(SOCK_STREAM, ifss, port, true);
+ if (s->fd < 0) {
+ int err = -(s->fd);
+ DBG_ERR("open_socket_in failed: %s\n", strerror(err));
TALLOC_FREE(s);
/*
* We ignore an error here, as we've done before
diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c
index e9e16109e88..f718e47a98f 100644
--- a/source3/utils/nmblookup.c
+++ b/source3/utils/nmblookup.c
@@ -50,12 +50,16 @@ static bool open_sockets(void)
"from string %s", sock_addr));
return false;
}
- ServerFD = open_socket_in( SOCK_DGRAM,
- (RootPort ? 137 : 0),
- (RootPort ? 0 : 3),
- &ss, true );
-
- if (ServerFD == -1) {
+ ServerFD = open_socket_in(
+ SOCK_DGRAM, &ss, (RootPort ? 137 : 0), true);
+ if (ServerFD < 0) {
+ if (RootPort) {
+ DBG_ERR("open_socket_in failed: %s\n",
+ strerror(-ServerFD));
+ } else {
+ DBG_NOTICE("open_socket_in failed: %s\n",
+ strerror(-ServerFD));
+ }
return false;
}
diff --git a/source3/utils/smbfilter.c b/source3/utils/smbfilter.c
index 35fb7521384..3fbd63975c9 100644
--- a/source3/utils/smbfilter.c
+++ b/source3/utils/smbfilter.c
@@ -284,10 +284,10 @@ static void start_filter(char *desthost)
/* start listening on port 445 locally */
zero_sockaddr(&my_ss);
- s = open_socket_in(SOCK_STREAM, TCP_SMB_PORT, 0, &my_ss, True);
+ s = open_socket_in(SOCK_STREAM, &my_ss, TCP_SMB_PORT, true);
- if (s == -1) {
- d_printf("bind failed\n");
+ if (s < 0) {
+ d_printf("bind failed: %s\n", strerror(-s));
exit(1);
}