[PATCH] Update masked_match in source4 to support IPv6 addresses (resend)

Jeremy Allison jra at samba.org
Thu Nov 10 19:09:02 UTC 2016


On Thu, Nov 10, 2016 at 01:02:30PM -0600, Heath Kehoe wrote:
> We have an AD environment backed entirely by Samba4. We have a
> remote location where I spun up a Samba4 instance and made it a DC.
> The remote subnet is connected to our "main" subnet via VPN, with
> both IPv4 and IPv6.
> 
> I set up an AD Site for the remote location and assigned the
> appropriate subnets (both v4 and v6) to it. However, a Windows
> client at the remote location never associated with the correct site,
> in that 'nltest /dsgetsite' always returned the default site. Also,
> that client would sometimes use a DC at the main site; and worse,
> clients at the main site sometimes bound to the DC at the remote
> site's DC causing long login times.
> 
> So I tracked down what Samba was doing to match a client to a site.
> I found samdb_client_site_name() which in turn uses
> socket_allow_access() which led to masked_match() in
> source4/lib/socket/access.c that clearly only worked with IPv4
> addresses. Since we are using IPv6, clients failed to be matched
> to any site.
> 
> So I ported the masked_match() that appears in source3 (which had
> already been updated to support IPv6) over to source4, which resolves
> (for us) the problem with sites.

Oh good catch. I think the correct fix for this is to
move the source3/ masked match to lib/util/access.c
and make both source3 and source4 link against it though.

If I create this patch can you test it for me ?

Jeremy.

> Couple of notes
> 
>  * I didn't copy all of the 'if' noise that's in front of the
>    masked_match invocation in source3/lib/access.c to the
>    corresponding invocation in source4/lib/socket/access.c, because
>    the first thing masked_match does is call interpret_string_addr
>    which itself will validate the input.
> 
>  * I had to add 'netif' to deps in source4/lib/socket/wscript_build
>    to get make_netmask()
> 

> From 6fa1e442e14d231b31f700304cd1b2e94ef2e5a5 Mon Sep 17 00:00:00 2001
> From: Heath Kehoe <heath at digitalartefacts.com>
> Date: Thu, 10 Nov 2016 11:33:49 -0600
> Subject: [PATCH] Update masked_match in source4 to support IPv6
> 
> Port masked_match from source3/lib/access.c to source4/lib/socket/access.c in order to add support for IPv6 addresses.
> 
> Signed-off-by: Heath Kehoe <heath at digitalartefacts.com>
> ---
>  source4/lib/socket/access.c      | 76 ++++++++++++++++++++++++++--------------
>  source4/lib/socket/wscript_build |  2 +-
>  2 files changed, 51 insertions(+), 27 deletions(-)
> 
> diff --git a/source4/lib/socket/access.c b/source4/lib/socket/access.c
> index adc8105..2328ec1 100644
> --- a/source4/lib/socket/access.c
> +++ b/source4/lib/socket/access.c
> @@ -32,43 +32,67 @@
>  
>  #include "includes.h"
>  #include "system/network.h"
> +#include "lib/socket/interfaces.h"
>  #include "lib/socket/socket.h"
>  #include "system/locale.h"
>  #include "lib/util/util_net.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)
>  {
> -	uint32_t net;
> -	uint32_t mask;
> -	uint32_t addr;
> -	char *tok_cpy;
> +	struct sockaddr_storage ss_mask;
> +	struct sockaddr_storage ss_tok;
> +	struct sockaddr_storage ss_host;
> +	char *tok_copy = NULL;
>  
> -	if ((addr = interpret_addr(s)) == INADDR_NONE)
> -		return false;
> -
> -	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));
> +	if (!interpret_string_addr(&ss_host, s, 0)) {
>  		return false;
>  	}
> -	
> -	return (addr & mask) == (net & mask);
> +
> +	if (*tok == '[') {
> +		/* IPv6 address - remove braces. */
> +		tok_copy = talloc_strdup(mem_ctx, tok+1);
> +		if (!tok_copy) {
> +			return false;
> +		}
> +		/* Remove the terminating ']' */
> +		tok_copy[PTR_DIFF(slash,tok)-1] = '\0';
> +	} else {
> +		tok_copy = talloc_strdup(mem_ctx, tok);
> +		if (!tok_copy) {
> +			return false;
> +		}
> +		/* Remove the terminating '/' */
> +		tok_copy[PTR_DIFF(slash,tok)] = '\0';
> +	}
> +
> +	if (!interpret_string_addr(&ss_tok, tok_copy, 0)) {
> +		talloc_free(tok_copy);
> +		return false;
> +	}
> +
> +	talloc_free(tok_copy);
> +
> +	if (strlen(slash + 1) > 2) {
> +		if (!interpret_string_addr(&ss_mask, slash+1, 0)) {
> +			return false;
> +		}
> +	} else {
> +		char *endp = NULL;
> +		unsigned long val = strtoul(slash+1, &endp, 0);
> +		if (slash+1 == endp || (endp && *endp != '\0')) {
> +			return false;
> +		}
> +		if (!make_netmask(&ss_mask, &ss_tok, val)) {
> +			return false;
> +		}
> +	}
> +
> +	return same_net((struct sockaddr *)(void *)&ss_host,
> +			(struct sockaddr *)(void *)&ss_tok,
> +			(struct sockaddr *)(void *)&ss_mask);
>  }
>  
>  /* string_match - match string against token */
> @@ -116,7 +140,7 @@ static bool string_match(TALLOC_CTX *mem_ctx, const char *tok,const char *s, cha
>  		if (strncmp(tok, s, tok_len) == 0)
>  			return true;
>  	} else if ((cut = strchr(tok, '/')) != 0) {	/* netnumber/netmask */
> -		if (isdigit((int)s[0]) && masked_match(mem_ctx, tok, cut, s))
> +		if (masked_match(mem_ctx, tok, cut, s))
>  			return true;
>  	} else if (strchr(tok, '*') != 0) {
>  		*invalid_char = '*';
> diff --git a/source4/lib/socket/wscript_build b/source4/lib/socket/wscript_build
> index 1cb89c6..225e605 100644
> --- a/source4/lib/socket/wscript_build
> +++ b/source4/lib/socket/wscript_build
> @@ -24,6 +24,6 @@ bld.SAMBA_MODULE('socket_unix',
>  bld.SAMBA_SUBSYSTEM('samba_socket',
>      source='socket.c access.c connect_multi.c connect.c',
>      public_deps='talloc LIBTSOCKET',
> -    deps='cli_composite LIBCLI_RESOLVE socket_ip socket_unix'
> +    deps='cli_composite LIBCLI_RESOLVE socket_ip socket_unix netif'
>      )
>  
> -- 
> 2.10.2
> 




More information about the samba-technical mailing list