The branch, master has been updated via 09e9dd576da torture: Test the "server addresses" parameter via f9a3a6b434f testprogs: Fix testit_expect_failure_grep() via 55feb593012 testprogs: Add testit_grep_count() helper via e24481251dd srvsvc: Only list shares in "server addresses" via 23167a4dd7b smbd: Implement "server addresses" for tree connect via 9321a533cdc lib: Add lp_allow_local_address() via d9c4f94e4fd smbd: Add "server addresses" parameter via 12edd038cfa smbd: Some whitespace fixes from 4a68d43b7b0 third_party: Update nss_wrapper to version 1.1.13
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 09e9dd576dad5a38287b2241a965f769f1264292 Author: Volker Lendecke <v...@samba.org> Date: Mon Nov 7 20:34:57 2022 +0100 torture: Test the "server addresses" parameter Thanks to Metze for the hint that all file servers already listen on 2 addressess -- V4 and V6 :-) Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Volker Lendecke <v...@samba.org> Autobuild-Date(master): Thu Nov 10 08:23:14 UTC 2022 on sn-devel-184 commit f9a3a6b434f6b82303241a57beae3e1762a2c41d Author: Volker Lendecke <v...@samba.org> Date: Wed Nov 9 14:09:34 2022 +0100 testprogs: Fix testit_expect_failure_grep() Callers expect success (i.e. retval==0) if grep failed with non-zero error status. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 55feb593012fc5b24e795a00081666fca740429c Author: Volker Lendecke <v...@samba.org> Date: Wed Nov 9 14:04:23 2022 +0100 testprogs: Add testit_grep_count() helper Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit e24481251ddc64abfd51b9bd101833814defd8c4 Author: Volker Lendecke <v...@samba.org> Date: Fri Oct 21 17:02:07 2022 +0200 srvsvc: Only list shares in "server addresses" Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 23167a4dd7be30123f66826999db559a4bc0db7d Author: Volker Lendecke <v...@samba.org> Date: Fri Oct 21 16:58:36 2022 +0200 smbd: Implement "server addresses" for tree connect Only allow share connections if the server address matches Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 9321a533cdc3cbb81afa03bcf3cd5030b8b317ea Author: Volker Lendecke <v...@samba.org> Date: Fri Oct 21 16:45:35 2022 +0200 lib: Add lp_allow_local_address() Helper function for listing and accessing shares Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit d9c4f94e4fde22a91c230d2ddb2eb3b9c56f88b0 Author: Volker Lendecke <v...@samba.org> Date: Fri Oct 21 17:01:21 2022 +0200 smbd: Add "server addresses" parameter This is a per-share parameter to limit share visibility and accessibility to specific server IP addresses. This can be used to limit the visibility and accessibility of shares on different subnets offered by the server. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 12edd038cfa1326c517cb51e6b4c7bdf75f471fa Author: Volker Lendecke <v...@samba.org> Date: Fri Oct 21 09:17:42 2022 +0200 smbd: Some whitespace fixes Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> ----------------------------------------------------------------------- Summary of changes: docs-xml/smbdotconf/browse/server_addresses.xml | 12 +++++ selftest/target/Samba3.pm | 4 ++ source3/include/proto.h | 2 + source3/lib/util_sock.c | 1 + source3/param/service.c | 69 +++++++++++++++++++++++++ source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 10 +++- source3/script/tests/test_server_addresses.sh | 32 ++++++++++++ source3/selftest/tests.py | 5 ++ source3/smbd/smb2_service.c | 35 +++++++++++-- testprogs/blackbox/subunit.sh | 31 ++++++++++- 10 files changed, 193 insertions(+), 8 deletions(-) create mode 100644 docs-xml/smbdotconf/browse/server_addresses.xml create mode 100755 source3/script/tests/test_server_addresses.sh Changeset truncated at 500 lines: diff --git a/docs-xml/smbdotconf/browse/server_addresses.xml b/docs-xml/smbdotconf/browse/server_addresses.xml new file mode 100644 index 00000000000..e1dd6d60f8e --- /dev/null +++ b/docs-xml/smbdotconf/browse/server_addresses.xml @@ -0,0 +1,12 @@ +<samba:parameter name="server addresses" + context="S" + type="cmdlist" + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> +<description> + <para>This is a per-share parameter to limit share visibility and + accessibility to specific server IP addresses. Multi-homed servers + can offer a different set of shares per interface.</para> + <para>An empty list means to offer a share on all interfaces.</para> +</description> +<value type="default"/> +</samba:parameter> diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 800df1f81bd..4db74e4d86e 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -3457,6 +3457,10 @@ sub provision($$) [full_audit_fail_bad_name] copy = tmp full_audit:failure = badname + +[only_ipv6] + copy = tmpguest + server addresses = $server_ipv6 "; close(CONF); diff --git a/source3/include/proto.h b/source3/include/proto.h index f632cf37c08..8582830d558 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -765,6 +765,8 @@ void unbecome_root(void); /* The following definitions come from lib/smbd_shim.c */ int find_service(TALLOC_CTX *ctx, const char *service_in, char **p_service_out); +bool lp_allow_local_address( + int snum, const struct tsocket_address *local_address); void send_stat_cache_delete_message(struct messaging_context *msg_ctx, const char *name); NTSTATUS can_delete_directory_fsp(files_struct *fsp); diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 85dc3efbe15..391b46f801e 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -30,6 +30,7 @@ #include "../lib/tsocket/tsocket.h" #include "lib/util/sys_rw.h" #include "lib/util/sys_rw_data.h" +#include "source3/lib/util_tsock.h" /**************************************************************************** Determine if a file descriptor is in fact a socket. diff --git a/source3/param/service.c b/source3/param/service.c index 880e79fb284..b06a2fbc734 100644 --- a/source3/param/service.c +++ b/source3/param/service.c @@ -264,3 +264,72 @@ int find_service(TALLOC_CTX *ctx, const char *service_in, char **p_service_out) return (iService); } + +bool lp_allow_local_address( + int snum, const struct tsocket_address *local_address) +{ + bool is_inet = tsocket_address_is_inet(local_address, "ip"); + const char **server_addresses = lp_server_addresses(snum); + char *local = NULL; + ssize_t i; + + if (!is_inet) { + return false; + } + + if (server_addresses == NULL) { + return true; + } + + local = tsocket_address_inet_addr_string(local_address, talloc_tos()); + if (local == NULL) { + return false; + } + + for (i=0; server_addresses[i] != NULL; i++) { + struct tsocket_address *server_addr = NULL; + char *server_addr_string = NULL; + bool equal; + int ret; + + /* + * Go through struct tsocket_address to normalize the + * string representation + */ + + ret = tsocket_address_inet_from_strings( + talloc_tos(), + "ip", + server_addresses[i], + 0, + &server_addr); + if (ret == -1) { + DBG_WARNING("tsocket_address_inet_from_strings " + "failed for %s: %s, ignoring\n", + server_addresses[i], + strerror(errno)); + continue; + } + + server_addr_string = tsocket_address_inet_addr_string( + server_addr, talloc_tos()); + TALLOC_FREE(server_addr); + if (server_addr_string == NULL) { + DBG_ERR("tsocket_address_inet_addr_string failed " + "for %s, ignoring\n", + server_addresses[i]); + continue; + } + + equal = strequal(local, server_addr_string); + TALLOC_FREE(server_addr_string); + + if (equal) { + TALLOC_FREE(local); + return true; + } + } + + TALLOC_FREE(local); + return false; +} diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c index 07bfb759147..4fcb7681d84 100644 --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c @@ -44,6 +44,8 @@ #include "serverid.h" #include "lib/global_contexts.h" #include "source3/lib/substitute.h" +#include "lib/tsocket/tsocket.h" +#include "librpc/rpc/dcesrv_core.h" extern const struct generic_mapping file_generic_mapping; @@ -615,6 +617,9 @@ static WERROR init_srv_share_info_ctr(struct pipes_struct *p, struct dcesrv_call_state *dce_call = p->dce_call; struct auth_session_info *session_info = dcesrv_call_session_info(dce_call); + struct dcesrv_connection *dcesrv_conn = dce_call->conn; + const struct tsocket_address *local_address = + dcesrv_connection_get_local_address(dcesrv_conn); const struct loadparm_substitution *lp_sub = loadparm_s3_global_substitution(); uint32_t num_entries = 0; @@ -655,8 +660,9 @@ static WERROR init_srv_share_info_ctr(struct pipes_struct *p, /* Count the number of entries. */ for (snum = 0; snum < num_services; snum++) { if (lp_browseable(snum) && lp_snum_ok(snum) && - is_enumeration_allowed(p, snum) && - (all_shares || !is_hidden_share(snum)) ) { + lp_allow_local_address(snum, local_address) && + is_enumeration_allowed(p, snum) && + (all_shares || !is_hidden_share(snum))) { DEBUG(10, ("counting service %s\n", lp_servicename(talloc_tos(), lp_sub, snum) ? lp_servicename(talloc_tos(), lp_sub, snum) : "(null)")); allowed[snum] = true; diff --git a/source3/script/tests/test_server_addresses.sh b/source3/script/tests/test_server_addresses.sh new file mode 100755 index 00000000000..891c2f25fb5 --- /dev/null +++ b/source3/script/tests/test_server_addresses.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# +# Blackbox test for the server addresses parameter +# + +incdir=$(dirname $0)/../../../testprogs/blackbox +. $incdir/subunit.sh + +failed=0 + +testit_grep_count \ + "[only_ipv6] invisible over ipv4" "netname: only_ipv6" 0 \ + bin/rpcclient "$SERVER_IP" -U% -c netshareenumall || + failed=$(expr "$failed" + 1) + +testit_grep_count \ + "[only_ipv6] visible over ipv6" "netname: only_ipv6" 1 \ + bin/rpcclient "$SERVER_IPV6" -U% -c netshareenumall || + failed=$(expr "$failed" + 1) + +testit_expect_failure_grep \ + "[only_ipv6] inaccessible over ipv4" \ + "tree connect failed: NT_STATUS_BAD_NETWORK_NAME" \ + bin/smbclient //"$SERVER_IP"/only_ipv6 -U% -c quit || + failed=$(expr "$failed" + 1) + +testit \ + "[only_ipv6] accessible over ipv6" \ + bin/smbclient //"$SERVER_IPV6"/only_ipv6 -U% -c quit || + failed=$(expr "$failed" + 1) + +testok $0 $failed diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 2155866923f..182283d9c9d 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -802,6 +802,11 @@ for env in ["fileserver:local"]: plantestsuite("samba3.blackbox.smbstatus", env, [os.path.join(samba3srcdir, "script/tests/test_smbstatus.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$USERID', '$LOCAL_PATH', '$PREFIX', smbclient3, smbstatus, configuration, "SMB3"]) plantestsuite("samba3.blackbox.net_registry_import", env, [os.path.join(samba3srcdir, "script/tests/test_net_registry_import.sh"), '$SERVER', '$LOCAL_PATH', '$USERNAME', '$PASSWORD']) +plantestsuite("samba3.blackbox.server_addresses", + "simpleserver", + [os.path.join(samba3srcdir, + "script/tests/test_server_addresses.sh")]) + # TODO encrypted against member, with member creds, and with DC creds plantestsuite("samba3.blackbox.net.misc NT1", "ad_dc_smb1_done:local", [os.path.join(samba3srcdir, "script/tests/test_net_misc.sh"), diff --git a/source3/smbd/smb2_service.c b/source3/smbd/smb2_service.c index 5affea6b3e4..6b821e6da70 100644 --- a/source3/smbd/smb2_service.c +++ b/source3/smbd/smb2_service.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. service (connection) opening and closing Copyright (C) Andrew Tridgell 1992-1998 @@ -177,17 +177,41 @@ bool chdir_current_service(connection_struct *conn) } /**************************************************************************** - do some basic sainity checks on the share. + do some basic sainity checks on the share. This function modifies dev, ecode. ****************************************************************************/ -static NTSTATUS share_sanity_checks(const struct tsocket_address *remote_address, +static NTSTATUS share_sanity_checks(const struct tsocket_address *local_address, + const struct tsocket_address *remote_address, const char *rhost, int snum, fstring dev) { char *raddr; + if (!lp_allow_local_address(snum, local_address)) { + char *laddr = NULL; + + laddr = tsocket_address_inet_addr_string( + local_address, talloc_tos()); + if (laddr == NULL) { + return NT_STATUS_NO_MEMORY; + } + + raddr = tsocket_address_inet_addr_string( + remote_address, laddr); + if (raddr == NULL) { + TALLOC_FREE(laddr); + return NT_STATUS_NO_MEMORY; + } + + DBG_ERR("Denied connection from %s (%s) to \\\\%s\\%s\n", + rhost, raddr, laddr, lp_const_servicename(snum)); + TALLOC_FREE(laddr); + + return NT_STATUS_BAD_NETWORK_NAME; + } + raddr = tsocket_address_inet_addr_string(remote_address, talloc_tos()); if (raddr == NULL) { @@ -236,7 +260,7 @@ static NTSTATUS share_sanity_checks(const struct tsocket_address *remote_address } /* - * Go through lookup_name etc to find the force'd group. + * Go through lookup_name etc to find the force'd group. * * Create a new token from src_token, replacing the primary group sid with the * one found. @@ -527,7 +551,8 @@ NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn, fstrcpy(dev, pdev); - status = share_sanity_checks(sconn->remote_address, + status = share_sanity_checks(sconn->local_address, + sconn->remote_address, sconn->remote_hostname, snum, dev); diff --git a/testprogs/blackbox/subunit.sh b/testprogs/blackbox/subunit.sh index 75a9b5ec7e3..08bbeefd1e2 100755 --- a/testprogs/blackbox/subunit.sh +++ b/testprogs/blackbox/subunit.sh @@ -121,6 +121,35 @@ testit_grep() return $status } +# This returns 0 if the command gave success and the grep value was found +# num times all other cases return != 0 +testit_grep_count() +{ + name="$1" + shift + grep="$1" + shift + num="$1" + shift + cmdline="$@" + subunit_start_test "$name" + output=$($cmdline 2>&1) + status=$? + if [ x$status != x0 ]; then + printf '%s' "$output" | subunit_fail_test "$name" + return $status + fi + found=$(printf '%s' "$output" | grep -c "$grep") + if [ x"$found" = x"$num" ]; then + subunit_pass_test "$name" + else + printf 'GREP: "%s" found "%d" times, expected "%d" in output:\n%s'\ + "$grep" "$found" "$num" "$output" | + subunit_fail_test "$name" + fi + return $status +} + testit_expect_failure() { name="$1" @@ -160,7 +189,7 @@ testit_expect_failure_grep() else printf 'GREP: "%s" not found in output:\n%s' "$grep" "$output" | subunit_fail_test "$name" fi - return $status + return 0 } testok() -- Samba Shared Repository