[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Tue Sep 28 10:35:01 UTC 2021


The branch, master has been updated
       via  3f4660900a7 selftest: test tsocket_address_inet_from_hostport_strings
       via  262148721ee selftest: add more tests for test_address_inet_from_strings
       via  c26fcef50d0 WHATSNEW: document dns forwarder change
       via  2a098030977 libcli/dns.c: dns forwarder port test changes
       via  617a5a1d357 libcli/dns: smb.conf dns forwarder port support
       via  f39a06de3be lib/tsocket: new function to parse host port strs.
       via  775939823a5 libcli/dns: dns forwarder port doc changes
       via  860d8902a9c pyldb: Make ldb.Message containment testing consistent with indexing
       via  865fe238599 pyldb: Add tests for ldb.Message containment testing
       via  22353767ca7 pyldb: Raise TypeError for an invalid ldb.Message index
       via  b018e51d272 pyldb: Add test for an invalid ldb.Message index type
       via  fb758c32e76 s4/torture/drs/python: Fix attribute existence check
       via  9d25a21d602 pyldb: Fix deleting an ldb.Control critical flag
       via  b1adaa517c1 pytest:segfault: Add test for deleting an ldb.Control critical flag
       via  d7af772de88 pyldb: Fix deleting an ldb.Message dn
       via  6a041f6a99c pytest:segfault: Add test for deleting an ldb.Message dn
      from  81e27693c62 mdssvc: Use ndr_policy_handle_empty()

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 3f4660900a71816df505c2e634eef86a86afcda3
Author: Uri Simchoni <uri at samba.org>
Date:   Thu Sep 16 20:03:59 2021 +0300

    selftest: test tsocket_address_inet_from_hostport_strings
    
    Signed-off-by: Uri Simchoni <uri at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Tue Sep 28 10:34:12 UTC 2021 on sn-devel-184

commit 262148721ee6d794f7f2d1ad1b36e00a1401ec41
Author: Uri Simchoni <uri at samba.org>
Date:   Thu Sep 16 20:03:02 2021 +0300

    selftest: add more tests for test_address_inet_from_strings
    
    Test the case of NULL address as input
    
    Signed-off-by: Uri Simchoni <uri at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c26fcef50d09d3d70c646f3151dda265d4b0eb92
Author: Uri Simchoni <uri at samba.org>
Date:   Thu Sep 16 10:11:46 2021 +0300

    WHATSNEW: document dns forwarder change
    
    Signed-off-by: Uri Simchoni <uri at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 2a098030977d7720436b7850fa731557eeb70bc2
Author: Matthew Grant <matt at mattgrant.net.nz>
Date:   Sat Sep 18 10:05:24 2021 +1200

    libcli/dns.c: dns forwarder port test changes
    
    Test harness for the dns fowarder setting in smb.conf. Adds IPv6
    forwarder as second target DNS forwarder, listening on port 54.
    
    Signed-off-by: Matthew Grant <grantma at mattgrant.net.nz>
    Reviewed-by: Uri Simchoni <uri at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 617a5a1d3579b27de0e2b0736909ca83b7b3ee15
Author: Matthew Grant <matt at mattgrant.net.nz>
Date:   Sat Sep 18 10:02:11 2021 +1200

    libcli/dns: smb.conf dns forwarder port support
    
    Call new tsocket_address_inet_from_hostport_strings() instead of
    tsocket_address_inet_from_strings() to implement setting a port to query
    for a DNS forwarder.
    
    Signed-off-by: Matthew Grant <grantma at mattgrant.net.nz>
    Reviewed-by: Uri Simchoni <uri at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f39a06de3bea9ec03a3e82c8892d9e572abd1163
Author: Matthew Grant <matt at mattgrant.net.nz>
Date:   Sun Sep 19 17:41:42 2021 +1200

    lib/tsocket: new function to parse host port strs.
    
    tsocket_address_inet_from_hostport_strings() on top of
    tsocket_address_inet_from_strings(), implementing the ability to parse a
    port number appended to an IPv6 or IPv4 address. IPv6 addresses can also
    optionally have square brackets around them, but these are needed to
    specify the port number as colon is used to delimit port from the IP
    address in the string.
    
    Note that this code just recognises and parses the strings with port
    given, or just IPv6 with square brackets.  The rest of the parsing is
    passed on to tsocket_address_inet_from strings(), and errors from there
    passed back up the stack.
    
    Signed-off-by: Matthew Grant <grantma at mattgrant.net.nz>
    Reviewed-by: Uri Simchoni <uri at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 775939823a5a956acc236c808d5aee78cbd9e132
Author: Matthew Grant <matt at mattgrant.net.nz>
Date:   Sat Sep 18 09:57:26 2021 +1200

    libcli/dns: dns forwarder port doc changes
    
    Documentation changes specifying how list entries for dns forwarder
    are to be specified with ability to add trailing target port number.
    
    Signed-off-by: Matthew Grant <grantma at mattgrant.net.nz>
    Reviewed-by: Uri Simchoni <uri at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 860d8902a9c502d4be83396598cf4a53c80fea69
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Sep 25 14:39:59 2021 +1200

    pyldb: Make ldb.Message containment testing consistent with indexing
    
    Previously, containment testing using the 'in' operator was handled by
    performing an equality comparison between the chosen object and each of
    the message's keys in turn. This behaviour was prone to errors due to
    not considering differences in case between otherwise equal elements, as
    the indexing operations do.
    
    Containment testing should now be more consistent with the indexing
    operations and with the get() method of ldb.Message.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 865fe238599a732360b77e06e592cb85d459acf8
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Sep 25 13:48:57 2021 +1200

    pyldb: Add tests for ldb.Message containment testing
    
    These tests verify that the 'in' operator on ldb.Message is consistent
    with indexing and the get() method. This means that the 'dn' element
    should always be present, lookups should be case-insensitive, and use of
    an invalid type should result in a TypeError.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 22353767ca75af9d9e8fa1e7da372dcb5eddfcb7
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Sep 25 13:39:56 2021 +1200

    pyldb: Raise TypeError for an invalid ldb.Message index
    
    Previously, a TypeError was raised and subsequently overridden by a
    KeyError.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit b018e51d2725a23b2fedd3058644b8021f6a6a06
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Sep 25 13:22:05 2021 +1200

    pyldb: Add test for an invalid ldb.Message index type
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit fb758c32e7633178f42dc2c031667b10c2ca6e90
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Sep 25 19:18:39 2021 +1200

    s4/torture/drs/python: Fix attribute existence check
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 9d25a21d6024c6c2f8e4634f45e3944d8acbf8b8
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Sep 25 11:16:09 2021 +1200

    pyldb: Fix deleting an ldb.Control critical flag
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit b1adaa517c1237a473bdcf818523f5107df3d6b0
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Sep 25 11:13:02 2021 +1200

    pytest:segfault: Add test for deleting an ldb.Control critical flag
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit d7af772de88885f46708329ff7bb5798da91d2c7
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Sep 25 11:12:16 2021 +1200

    pyldb: Fix deleting an ldb.Message dn
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 6a041f6a99c39632d5c32e9d53b06719c20bef2c
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Sep 25 10:56:25 2021 +1200

    pytest:segfault: Add test for deleting an ldb.Message dn
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14845
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 WHATSNEW.txt                                       |   9 +
 docs-xml/smbdotconf/domain/dnsforwarder.xml        |   8 +-
 lib/ldb/pyldb.c                                    |  49 ++++--
 lib/ldb/tests/python/api.py                        |  29 ++++
 lib/tsocket/tests/test_bsd_addr.c                  | 186 +++++++++++++++++++++
 lib/tsocket/tsocket.h                              |  43 +++++
 lib/tsocket/tsocket_bsd.c                          | 100 +++++++++++
 libcli/dns/dns.c                                   |   8 +-
 python/samba/tests/dns_forwarder.py                |  17 +-
 python/samba/tests/dns_forwarder_helpers/server.py |  10 +-
 python/samba/tests/segfault.py                     |  14 ++
 selftest/target/Samba4.pm                          |   4 +-
 source4/torture/drs/python/replica_sync.py         |   2 +-
 13 files changed, 449 insertions(+), 30 deletions(-)


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index b585e2e20a1..73cbe8d0392 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -29,6 +29,14 @@ certmonger paired with cepces to monitor the host certificate templates.
 Certificates are installed in /var/lib/samba/certs and private keys are
 installed in /var/lib/samba/private/certs.
 
+Ability to add ports to dns forwarder addresses in internal DNS backend
+-----------------------------------------------------------------------
+
+The internal DNS server of Samba forwards queries non-AD zones to one or more
+configured forwarders. Up until now it has been assumed that these forwarders
+listen on port 53. Starting with this version it is possible to configure the
+port using host:port notation. See smb.conf for more details. Existing setups
+are not affected, as the default port is 53.
 
 REMOVED FEATURES
 ================
@@ -50,6 +58,7 @@ smb.conf changes
   Parameter Name                          Description     Default
   --------------                          -----------     -------
   kernel share modes                      New default     No
+  dns forwarder                           Changed
 
 
 KNOWN ISSUES
diff --git a/docs-xml/smbdotconf/domain/dnsforwarder.xml b/docs-xml/smbdotconf/domain/dnsforwarder.xml
index f65740a7a24..cf8875ea5a0 100644
--- a/docs-xml/smbdotconf/domain/dnsforwarder.xml
+++ b/docs-xml/smbdotconf/domain/dnsforwarder.xml
@@ -8,10 +8,14 @@
 	</para>
 
 	<para>The DNS forwarder is only used if the internal DNS server
-		in Samba is used.
+		in Samba is used. Port numbers can be appended by separating them from
+		the address by using a colon (':').  When specifying a port, IPv6
+		addresses must be enclosed in square brackets ('[' and ']'). IPv6
+		forwarder addresses with no port specified, don't need the square
+		brackets, and default to port 53.
 	</para>
 </description>
 
 <value type="default"></value>
-<value type="example">192.168.0.1 192.168.0.2</value>
+<value type="example">192.168.0.1 192.168.0.2 ::1 [2001:db8::1] [2001:db8:1:2::1]:54 </value>
 </samba:parameter>
diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c
index f1538b37c6b..3f4b0c7a45c 100644
--- a/lib/ldb/pyldb.c
+++ b/lib/ldb/pyldb.c
@@ -182,6 +182,10 @@ static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self,
 
 static int py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
 {
+	if (value == NULL) {
+		PyErr_SetString(PyExc_AttributeError, "cannot delete critical flag");
+		return -1;
+	}
 	if (PyObject_IsTrue(value)) {
 		self->data->critical = true;
 	} else {
@@ -3429,33 +3433,41 @@ static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self,
 	return obj;
 }
 
-static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
+static int py_ldb_msg_contains(PyLdbMessageObject *self, PyObject *py_name)
 {
-	struct ldb_message_element *el;
-	const char *name;
+	struct ldb_message_element *el = NULL;
+	const char *name = NULL;
 	struct ldb_message *msg = pyldb_Message_AsMessage(self);
 	name = PyUnicode_AsUTF8(py_name);
 	if (name == NULL) {
-		PyErr_SetNone(PyExc_TypeError);
-		return NULL;
+		return -1;
 	}
-	if (!ldb_attr_cmp(name, "dn"))
-		return pyldb_Dn_FromDn(msg->dn);
-	el = ldb_msg_find_element(msg, name);
-	if (el == NULL) {
-		return NULL;
+	if (!ldb_attr_cmp(name, "dn")) {
+		return 1;
 	}
-	return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
+	el = ldb_msg_find_element(msg, name);
+	return el != NULL ? 1 : 0;
 }
 
 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
 {
-	PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
-	if (ret == NULL) {
+	struct ldb_message_element *el = NULL;
+	const char *name = NULL;
+	struct ldb_message *msg = pyldb_Message_AsMessage(self);
+	name = PyUnicode_AsUTF8(py_name);
+	if (name == NULL) {
+		return NULL;
+	}
+	if (!ldb_attr_cmp(name, "dn")) {
+		return pyldb_Dn_FromDn(msg->dn);
+	}
+	el = ldb_msg_find_element(msg, name);
+	if (el == NULL) {
 		PyErr_SetString(PyExc_KeyError, "No such element");
 		return NULL;
 	}
-	return ret;
+
+	return PyLdbMessageElement_FromMessageElement(el, msg->elements);
 }
 
 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
@@ -3665,6 +3677,10 @@ static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
 	return pyldb_Message_AsMessage(self)->num_elements;
 }
 
+static PySequenceMethods py_ldb_msg_sequence = {
+	.sq_contains = (objobjproc)py_ldb_msg_contains,
+};
+
 static PyMappingMethods py_ldb_msg_mapping = {
 	.mp_length = (lenfunc)py_ldb_msg_length,
 	.mp_subscript = (binaryfunc)py_ldb_msg_getitem,
@@ -3741,6 +3757,10 @@ static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
 {
 	struct ldb_message *msg = pyldb_Message_AsMessage(self);
+	if (value == NULL) {
+		PyErr_SetString(PyExc_AttributeError, "cannot delete dn");
+		return -1;
+	}
 	if (!pyldb_Dn_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "expected dn");
 		return -1;
@@ -3838,6 +3858,7 @@ static PyTypeObject PyLdbMessage = {
 	.tp_name = "ldb.Message",
 	.tp_methods = py_ldb_msg_methods,
 	.tp_getset = py_ldb_msg_getset,
+	.tp_as_sequence = &py_ldb_msg_sequence,
 	.tp_as_mapping = &py_ldb_msg_mapping,
 	.tp_basicsize = sizeof(PyLdbMessageObject),
 	.tp_dealloc = (destructor)py_ldb_msg_dealloc,
diff --git a/lib/ldb/tests/python/api.py b/lib/ldb/tests/python/api.py
index 16b71e2e650..bf6f7ef993d 100755
--- a/lib/ldb/tests/python/api.py
+++ b/lib/ldb/tests/python/api.py
@@ -3082,6 +3082,12 @@ class LdbMsgTests(TestCase):
     def test_notpresent(self):
         self.assertRaises(KeyError, lambda: self.msg["foo"])
 
+    def test_invalid(self):
+        try:
+            self.assertRaises(TypeError, lambda: self.msg[42])
+        except KeyError:
+            self.fail()
+
     def test_del(self):
         del self.msg["foo"]
 
@@ -3197,6 +3203,29 @@ class LdbMsgTests(TestCase):
     def test_get_unknown_text(self):
         self.assertEqual(None, self.msg.text.get("lalalala"))
 
+    def test_contains(self):
+        self.msg['foo'] = ['bar']
+        self.assertIn('foo', self.msg)
+
+        self.msg['Foo'] = ['bar']
+        self.assertIn('Foo', self.msg)
+
+    def test_contains_case(self):
+        self.msg['foo'] = ['bar']
+        self.assertIn('Foo', self.msg)
+
+        self.msg['Foo'] = ['bar']
+        self.assertIn('foo', self.msg)
+
+    def test_contains_dn(self):
+        self.assertIn('dn', self.msg)
+
+    def test_contains_dn_case(self):
+        self.assertIn('DN', self.msg)
+
+    def test_contains_invalid(self):
+        self.assertRaises(TypeError, lambda: None in self.msg)
+
     def test_msg_diff(self):
         l = ldb.Ldb()
         msgs = l.parse_ldif("dn: foo=bar\nfoo: bar\nbaz: do\n\ndn: foo=bar\nfoo: bar\nbaz: dont\n")
diff --git a/lib/tsocket/tests/test_bsd_addr.c b/lib/tsocket/tests/test_bsd_addr.c
index 9f9fa29ec2d..ac6e798b952 100644
--- a/lib/tsocket/tests/test_bsd_addr.c
+++ b/lib/tsocket/tests/test_bsd_addr.c
@@ -163,6 +163,191 @@ static void test_address_inet_from_strings(void **state)
 	assert_int_equal(rc, -1);
 	assert_int_not_equal(save_errno, 0);
 	assert_null(addr);
+
+	/*
+	 * Unspecified IP family, given NULL, verify it returns something
+	 */
+	rc = tsocket_address_inet_from_strings(mem_ctx, "ip", NULL, 1234,
+					       &addr);
+	assert_return_code(rc, errno);
+	assert_non_null(addr);
+	TALLOC_FREE(addr);
+
+	/*
+	 * IPv4, given NULL, verify it returns 0.0.0.0
+	 */
+	rc = tsocket_address_inet_from_strings(mem_ctx, "ipv4", NULL, 1234,
+					       &addr);
+	assert_return_code(rc, errno);
+	assert_non_null(addr);
+	addr_s = tsocket_address_string(addr, mem_ctx);
+	assert_non_null(addr_s);
+	assert_string_equal(addr_s, "ipv4:0.0.0.0:1234");
+	assert_true(tsocket_address_is_inet(addr, "ip"));
+	assert_true(tsocket_address_is_inet(addr, "ipv4"));
+	assert_false(tsocket_address_is_inet(addr, "ipv6"));
+	assert_int_equal(tsocket_address_inet_port(addr), 1234);
+	TALLOC_FREE(addr);
+	TALLOC_FREE(addr_s);
+
+	/*
+	 * IPv6, given NULL, verify it returns ::
+	 */
+	rc = tsocket_address_inet_from_strings(mem_ctx, "ipv6", NULL, 1234,
+					       &addr);
+	assert_return_code(rc, errno);
+	assert_non_null(addr);
+	addr_s = tsocket_address_string(addr, mem_ctx);
+	assert_non_null(addr_s);
+	assert_string_equal(addr_s, "ipv6::::1234");
+	assert_true(tsocket_address_is_inet(addr, "ip"));
+	assert_false(tsocket_address_is_inet(addr, "ipv4"));
+	assert_true(tsocket_address_is_inet(addr, "ipv6"));
+	assert_int_equal(tsocket_address_inet_port(addr), 1234);
+	TALLOC_FREE(addr);
+	TALLOC_FREE(addr_s);
+}
+
+static void test_address_inet_from_hostport_strings(void **state)
+{
+	int rc = 0;
+	int save_errno;
+	TALLOC_CTX *mem_ctx = *state;
+	struct tsocket_address *addr = NULL;
+	char *addr_s = NULL;
+
+	/*
+	 * IPv4 host:port
+	 */
+	rc = tsocket_address_inet_from_hostport_strings(
+	    mem_ctx, "ip", "1.2.3.4:5678", 1234, &addr);
+	assert_return_code(rc, errno);
+	assert_non_null(addr);
+	addr_s = tsocket_address_string(addr, mem_ctx);
+	assert_non_null(addr_s);
+	assert_string_equal(addr_s, "ipv4:1.2.3.4:5678");
+	TALLOC_FREE(addr);
+	TALLOC_FREE(addr_s);
+
+	/*
+	 * IPv4 host
+	 */
+	rc = tsocket_address_inet_from_hostport_strings(
+	    mem_ctx, "ip", "1.2.3.4", 1234, &addr);
+	assert_return_code(rc, errno);
+	assert_non_null(addr);
+	addr_s = tsocket_address_string(addr, mem_ctx);
+	assert_non_null(addr_s);
+	assert_string_equal(addr_s, "ipv4:1.2.3.4:1234");
+	TALLOC_FREE(addr);
+	TALLOC_FREE(addr_s);
+
+	/*
+	 * IPv6 [host]:port
+	 */
+	rc = tsocket_address_inet_from_hostport_strings(
+	    mem_ctx, "ip", "[2001::1]:5678", 1234, &addr);
+	assert_return_code(rc, errno);
+	assert_non_null(addr);
+	addr_s = tsocket_address_string(addr, mem_ctx);
+	assert_non_null(addr_s);
+	assert_string_equal(addr_s, "ipv6:2001::1:5678");
+	TALLOC_FREE(addr);
+	TALLOC_FREE(addr_s);
+
+	/*
+	 * IPv6 [host]
+	 */
+	rc = tsocket_address_inet_from_hostport_strings(
+	    mem_ctx, "ip", "[2001::1]", 1234, &addr);
+	assert_return_code(rc, errno);
+	assert_non_null(addr);
+	addr_s = tsocket_address_string(addr, mem_ctx);
+	assert_non_null(addr_s);
+	assert_string_equal(addr_s, "ipv6:2001::1:1234");
+	TALLOC_FREE(addr);
+	TALLOC_FREE(addr_s);
+
+	/*
+	 * IPv6 host
+	 */
+	rc = tsocket_address_inet_from_hostport_strings(
+	    mem_ctx, "ip", "2001::1", 1234, &addr);
+	assert_return_code(rc, errno);
+	assert_non_null(addr);
+	addr_s = tsocket_address_string(addr, mem_ctx);
+	assert_non_null(addr_s);
+	assert_string_equal(addr_s, "ipv6:2001::1:1234");
+	TALLOC_FREE(addr);
+	TALLOC_FREE(addr_s);
+
+	/*
+	 * Given NULL, verify it returns something
+	 */
+	rc = tsocket_address_inet_from_hostport_strings(
+	    mem_ctx, "ipv6", NULL, 1234, &addr);
+	assert_return_code(rc, errno);
+	assert_non_null(addr);
+	addr_s = tsocket_address_string(addr, mem_ctx);
+	assert_non_null(addr_s);
+	assert_string_equal(addr_s, "ipv6::::1234");
+	TALLOC_FREE(addr);
+	TALLOC_FREE(addr_s);
+
+	/*
+	 * [host]grarbage
+	 */
+	errno = 0;
+	rc = tsocket_address_inet_from_hostport_strings(
+	    mem_ctx, "ip", "[2001::1]garbage", 1234, &addr);
+	save_errno = errno;
+	assert_int_equal(rc, -1);
+	assert_int_not_equal(save_errno, 0);
+	assert_null(addr);
+
+	/*
+	 * [host]:grarbage
+	 */
+	errno = 0;
+	rc = tsocket_address_inet_from_hostport_strings(
+	    mem_ctx, "ip", "[2001::1]:garbage", 1234, &addr);
+	save_errno = errno;
+	assert_int_equal(rc, -1);
+	assert_int_not_equal(save_errno, 0);
+	assert_null(addr);
+
+	/*
+	 * host:grarbage
+	 */
+	errno = 0;
+	rc = tsocket_address_inet_from_hostport_strings(
+	    mem_ctx, "ip", "1.2.3.4:garbage", 1234, &addr);
+	save_errno = errno;
+	assert_int_equal(rc, -1);
+	assert_int_not_equal(save_errno, 0);
+	assert_null(addr);
+
+	/*
+	 * [host]:<port-too-large>
+	 */
+	errno = 0;
+	rc = tsocket_address_inet_from_hostport_strings(
+	    mem_ctx, "ip", "[2001::1]:100000", 1234, &addr);
+	save_errno = errno;
+	assert_int_equal(rc, -1);
+	assert_int_not_equal(save_errno, 0);
+	assert_null(addr);
+
+	/*
+	 * host:<port-too-large>
+	 */
+	errno = 0;
+	rc = tsocket_address_inet_from_hostport_strings(
+	    mem_ctx, "ip", "1.2.3.4:100000", 1234, &addr);
+	save_errno = errno;
+	assert_int_equal(rc, -1);
+	assert_int_not_equal(save_errno, 0);
+	assert_null(addr);
 }
 
 int main(int argc, char *argv[])
@@ -170,6 +355,7 @@ int main(int argc, char *argv[])
 	int rc;
 	const struct CMUnitTest tests[] = {
 	    cmocka_unit_test(test_address_inet_from_strings),
+	    cmocka_unit_test(test_address_inet_from_hostport_strings),
 	};
 
 	if (argc == 2) {
diff --git a/lib/tsocket/tsocket.h b/lib/tsocket/tsocket.h
index 2f1c7981346..d3cde99bf5a 100644
--- a/lib/tsocket/tsocket.h
+++ b/lib/tsocket/tsocket.h
@@ -539,6 +539,49 @@ int _tsocket_address_inet_from_strings(TALLOC_CTX *mem_ctx,
 					   __location__)
 #endif
 
+#ifdef DOXYGEN
+/**
+ * @brief Create a tsocket_address for ipv4 and ipv6 endpoint addresses.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  fam      The family can be can be "ipv4", "ipv6" or "ip". With
+ *                      "ip" it autodetects "ipv4" or "ipv6" based on the
+ *                      addr.
+ *
+ * @param[in]  host_port_addr   A valid ip address string based on the
+ *                      selected family (dns names are not allowed!). A port
+ *                      number may follow sepatated by a colon. IPv6 may be
+ *                      surrounded in square brackets, and these are required
+ *                      if appending a port number. It's valid to pass NULL,
+ *                      which gets mapped to "0.0.0.0" or "::".
+ *
+ * @param[in]  default_port  A valid port number for the default port if none
+ *                      given.
+ *
+ * @param[out] _addr    A tsocket_address pointer to store the information.
+ *
+ * @return              0 on success, -1 on error with errno set.
+ */
+int tsocket_address_inet_from_hostport_strings(TALLOC_CTX *mem_ctx,
+					       const char *fam,
+					       const char *host_port_addr,
+					       uint16_t default_port,
+					       struct tsocket_address **_addr);
+#else
+int _tsocket_address_inet_from_hostport_strings(TALLOC_CTX *mem_ctx,
+						const char *fam,
+						const char *host_port_addr,
+						uint16_t default_port,
+						struct tsocket_address **_addr,
+						const char *location);
+
+#define tsocket_address_inet_from_hostport_strings(                            \
+    mem_ctx, fam, host_port_addr, default_port, _addr)                         \
+	_tsocket_address_inet_from_hostport_strings(                           \
+	    mem_ctx, fam, host_port_addr, default_port, _addr, __location__)
+#endif
+
 /**
  * @brief Get the address of an 'inet' tsocket_address as a string.
  *
diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c
index 9485da7c8af..5650763d1e6 100644
--- a/lib/tsocket/tsocket_bsd.c
+++ b/lib/tsocket/tsocket_bsd.c
@@ -29,6 +29,7 @@
 #include "lib/util/iov_buf.h"
 #include "lib/util/blocking.h"
 #include "lib/util/util_net.h"
+#include "lib/util/samba_util.h"
 
 static int tsocket_bsd_error_from_errno(int ret,
 					int sys_errno,
@@ -441,6 +442,105 @@ done:
 	return ret;
 }
 
+int _tsocket_address_inet_from_hostport_strings(TALLOC_CTX *mem_ctx,
+						const char *fam,
+						const char *host_port_addr,
+						uint16_t default_port,
+						struct tsocket_address **_addr,
+						const char *location)
+{
+	char *pl_sq = NULL;
+	char *pr_sq = NULL;
+	char *pl_period = NULL;
+	char *port_sep = NULL;
+	char *cport = NULL;
+	char *buf = NULL;
+	uint64_t port = 0;
+	int ret;
+	char *s_addr = NULL;
+	uint16_t s_port = default_port;
+	bool conv_ret;
+	bool is_ipv6_by_squares = false;
+
+	if (host_port_addr == NULL) {
+		/* got straight to next function if host_port_addr is NULL */
+		goto get_addr;
+	}
+	buf = talloc_strdup(mem_ctx, host_port_addr);
+	if (buf == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+	pl_period = strchr_m(buf, '.');


-- 
Samba Shared Repository



More information about the samba-cvs mailing list