diff options
-rw-r--r-- | source3/include/proto.h | 10 | ||||
-rw-r--r-- | source3/lib/util_sock.c | 157 | ||||
-rw-r--r-- | source3/nmbd/nmbd.c | 12 | ||||
-rw-r--r-- | source3/nmbd/nmbd_subnetdb.c | 63 | ||||
-rw-r--r-- | source3/rpc_server/rpc_sock_helper.c | 17 | ||||
-rw-r--r-- | source3/smbd/server.c | 13 | ||||
-rw-r--r-- | source3/utils/nmblookup.c | 16 | ||||
-rw-r--r-- | source3/utils/smbfilter.c | 6 |
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); } |