Merge ~ahasenack/ubuntu/+source/samba:focal-samba-kb5028166-2027716 into ubuntu/+source/samba:ubuntu/focal-devel

Proposed by Andreas Hasenack
Status: Merged
Approved by: git-ubuntu bot
Approved revision: not available
Merged at revision: e3f13ab02ab932d6e0acb12b10f30dfad31df166
Proposed branch: ~ahasenack/ubuntu/+source/samba:focal-samba-kb5028166-2027716
Merge into: ubuntu/+source/samba:ubuntu/focal-devel
Diff against target: 875 lines (+833/-0)
6 files modified
debian/changelog (+27/-0)
debian/patches/secure-channel-faulty-kb5028166.patch (+215/-0)
debian/patches/series (+1/-0)
debian/tests/control (+4/-0)
debian/tests/samba-ad-dc-provisioning-internal-dns (+408/-0)
debian/tests/util (+178/-0)
Reviewer Review Type Date Requested Status
git-ubuntu bot Approve
Lucas Kanashiro (community) Approve
Canonical Server Reporter Pending
Review via email: mp+447460@code.launchpad.net

Description of the change

PPA: https://launchpad.net/~ahasenack/+archive/ubuntu/samba-kb5028166/

Bug fix for #2027716. SRU template is filled in, including a test case.

I split the patch in two commits: one that introduces the upstream patch, pristine, and another that removes the hunks that changed the upstream test suite. We don't run that test suite, and I think a smaller patch is easier to review, specially when comparing to the other ubuntu releases which needed a small backport change.

I tried to make incremental changes to this branch when compared to lunar, so it's easier to review. But range-diff is still a bit noisy, specially because focal did not have d/t/util.

The DEP8 test needed even more tweaking for focal, and I tried to keep the differences as additional commits.

DEP8 is green. It doesn't exercise this bug in particular, but does exercise a domain join with linux<->linux, which is a good regression test.

To post a comment you must log in.
Revision history for this message
Lucas Kanashiro (lucaskanashiro) wrote :

Thanks for this MP Andreas! I found no issue in the packaging changes, but the autopgktest execution against the package in your PPA has a failure in ppc64el:

  - samba/2:4.15.13+dfsg-0ubuntu0.20.04.4~ppa1
    + ✅ samba on focal for amd64 @ 20.07.23 17:52:59
    + ✅ samba on focal for arm64 @ 20.07.23 18:34:00
    + ✅ samba on focal for armhf @ 20.07.23 17:56:16
    + ❌ samba on focal for ppc64el @ 20.07.23 18:08:37
      • Status: FAIL
      • Log: https://autopkgtest.ubuntu.com/results/autopkgtest-focal-ahasenack-samba-kb5028166/focal/ppc64el/s/samba/20230720_180837_9f4b6@/log.gz
      • 2064s PASS 🟩
      • 2064s PASS 🟩
      • 2064s PASS 🟩
      • 2064s PASS 🟩
      • 2064s PASS 🟩
      • 2064s PASS 🟩
      • 2064s FAIL 🟥
    + ❌ samba on focal for ppc64el @ 20.07.23 20:21:15
      • Status: FAIL
      • Log: https://autopkgtest.ubuntu.com/results/autopkgtest-focal-ahasenack-samba-kb5028166/focal/ppc64el/s/samba/20230720_202115_59d84@/log.gz
      • 1929s PASS 🟩
      • 1929s PASS 🟩
      • 1929s PASS 🟩
      • 1929s PASS 🟩
      • 1929s PASS 🟩
      • 1929s PASS 🟩
      • 1929s FAIL 🟥
    + ✅ samba on focal for s390x @ 21.07.23 17:35:21

I just re-triggered the test to make sure it is failing again:

* Running:
  # time pkg release arch ppa trigger
  - 530 samba focal ppc64el ahasenack/samba-kb5028166 samba/2:4.15.13+dfsg-0ubuntu0.20.04.4~ppa1

Waiting for the results now.

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Thanks. I don't know why it failed, all of the previous, complicated, checks, passed, even kerberos ones, and it failed close to the end:

1927s ## wbinfo kerberos authentication check for user "<email address hidden>" inside member server
1927s plaintext kerberos password authentication for [<email address hidden>] failed (requesting cctype: FILE)
1927s Could not authenticate user [<email address hidden>%Passw0rd] with Kerberos (ccache: FILE)
1927s ## Something failed, gathering logs

Let's see what the new run brings.

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

It failed again, let me see if I can get a ppc64el machine to poke around it...

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Ok, so when wbinfo --krb5auth fails in the DEP8 test, the winbind service logs this error on ppc64el:

[2023/07/26 18:21:42.215411, 0] ../../source3/winbindd/winbindd_cred_cache.c:836(store_memory_creds)
failed to mlock memory: Cannot allocate memory (12)

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

In that situation, if I restart winbind, and then try again, then it works :/

This is a lxd container inside a 2Gb VM. Maybe ppc64el needs more memory...? I remember having to adjust some packages to use a bigger VM in the dep8 infrastructure.

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Tests passed on ppc64el this time, and kept passing in all other arches as well:

Results: (from http://autopkgtest.ubuntu.com/results/autopkgtest-focal-ahasenack-samba-kb5028166/?format=plain)
  samba @ amd64:
    26.07.23 22:31:46 Log 🗒️ ✅ Triggers: samba/2:4.15.13+dfsg-0ubuntu0.20.04.4~ppa2
  samba @ arm64:
    27.07.23 00:06:46 Log 🗒️ ✅ Triggers: samba/2:4.15.13+dfsg-0ubuntu0.20.04.4~ppa2
  samba @ armhf:
    26.07.23 22:15:14 Log 🗒️ ✅ Triggers: samba/2:4.15.13+dfsg-0ubuntu0.20.04.4~ppa2
  samba @ ppc64el:
    26.07.23 22:35:14 Log 🗒️ ✅ Triggers: samba/2:4.15.13+dfsg-0ubuntu0.20.04.4~ppa2
  samba @ s390x:
    26.07.23 22:33:21 Log 🗒️ ✅ Triggers: samba/2:4.15.13+dfsg-0ubuntu0.20.04.4~ppa2

Revision history for this message
Lucas Kanashiro (lucaskanashiro) wrote :

Thanks Andreas!

review: Approve
Revision history for this message
git-ubuntu bot (git-ubuntu-bot) wrote :

Approvers: ahasenack, lucaskanashiro
Uploaders: ahasenack, lucaskanashiro
MP auto-approved

review: Approve
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Thanks, uploaded with rich history:

Uploading samba_4.15.13+dfsg-0ubuntu0.20.04.4.dsc
Uploading samba_4.15.13+dfsg-0ubuntu0.20.04.4.debian.tar.xz
Uploading samba_4.15.13+dfsg-0ubuntu0.20.04.4_source.buildinfo
Uploading samba_4.15.13+dfsg-0ubuntu0.20.04.4_source.changes

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 3ea7797..373ec2d 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,30 @@
6+samba (2:4.15.13+dfsg-0ubuntu0.20.04.4) focal; urgency=medium
7+
8+ * d/p/secure-channel-faulty-kb5028166.patch: fix domain membership
9+ after Windows KB5028166 update (LP: #2027716)
10+ * Cherry pick samba AD DC provisioning DEP8 test from later Ubuntu
11+ releases (LP: #1977746, LP: #2011745):
12+ - d/t/control, d/t/util,d/t/samba-ad-dc-provisioning-internal-dns:
13+ samba AD DC provisioning and domain join tests with internal DNS
14+ + d/t/control: adjust package dependencies
15+ + d/t/samba-ad-dc-provisioning-internal-dns: handle the case where
16+ libnss-winbind does not automatically add winbind to
17+ /etc/nsswitch.conf (that is done only in Lunar and later)
18+ + d/t/samba-ad-dc-provisioning-internal-dns: use case insensitive
19+ match when inspecting kerberos tickets, as the hostname may be
20+ capitalized
21+ + d/t/samba-ad-dc-provisioning-internal-dns: Adjust regexp for
22+ slightly different resolvectl output
23+ + d/t/util: several lxc command output parsing changes, needed for
24+ this older version of the lxd snap
25+ + d/t/samba-ad-dc-provisioning-internal-dns: more dependencies for
26+ the winbind and sssd domain join tests, which don't get
27+ installed automatically for us by this version of realmd
28+ + d/t/util: increase the RLIMIT_MEMLOCK limit for lxd containers,
29+ as the default of 64kb is too low for at least ppc64el on focal
30+
31+ -- Andreas Hasenack <andreas@canonical.com> Sun, 23 Jul 2023 17:19:48 -0300
32+
33 samba (2:4.15.13+dfsg-0ubuntu0.20.04.3) focal-security; urgency=medium
34
35 * SECURITY UPDATE: Out-Of-Bounds read in winbind AUTH_CRAP
36diff --git a/debian/patches/secure-channel-faulty-kb5028166.patch b/debian/patches/secure-channel-faulty-kb5028166.patch
37new file mode 100644
38index 0000000..c1367f7
39--- /dev/null
40+++ b/debian/patches/secure-channel-faulty-kb5028166.patch
41@@ -0,0 +1,215 @@
42+From 2150e7f3dc409b415ca8b6a541729a49932c5073 Mon Sep 17 00:00:00 2001
43+From: Stefan Metzmacher <metze@samba.org>
44+Date: Sat, 15 Jul 2023 17:20:32 +0200
45+Subject: [PATCH 1/4] netlogon.idl: add support for netr_LogonGetCapabilities
46+ response level 2
47+
48+We don't have any documentation about this yet, but tests against
49+a Windows Server 2022 patched with KB5028166 revealed that
50+the response for query_level=2 is exactly the same as
51+for querey_level=1.
52+
53+Until we know the reason for query_level=2 we won't
54+use it as client nor support it in the server, but
55+we want ndrdump to work.
56+
57+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15418
58+
59+Signed-off-by: Stefan Metzmacher <metze@samba.org>
60+Reviewed-by: Andrew Bartlett <abartlet@samba.org>
61+(cherry picked from commit 5f87888ed53320538cf773d64868390d8641a40e)
62+---
63+ librpc/idl/netlogon.idl | 1 +
64+ 1 file changed, 1 insertion(+)
65+
66+Ubuntu patch note: removed the parts that changed the upstream test suite
67+
68+Origin: backport, https://bugzilla.samba.org/attachment.cgi?id=17987
69+Bug: https://bugzilla.samba.org/show_bug.cgi?id=15418
70+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/samba/+bug/2027716
71+Last-Update: 2023-07-17
72+
73+diff --git a/librpc/idl/netlogon.idl b/librpc/idl/netlogon.idl
74+index d956a661fff7..b51767136d3c 100644
75+--- a/librpc/idl/netlogon.idl
76++++ b/librpc/idl/netlogon.idl
77+@@ -1241,6 +1241,7 @@ interface netlogon
78+ /* Function 0x15 */
79+ typedef [switch_type(uint32)] union {
80+ [case(1)] netr_NegotiateFlags server_capabilities;
81++ [case(2)] netr_NegotiateFlags server_capabilities;
82+ } netr_Capabilities;
83+
84+ NTSTATUS netr_LogonGetCapabilities(
85+--
86+2.34.1
87+
88+
89+From fa71e7b4b027dc8224fda7125f1faaefa4e71eae Mon Sep 17 00:00:00 2001
90+From: Stefan Metzmacher <metze@samba.org>
91+Date: Sat, 15 Jul 2023 16:11:48 +0200
92+Subject: [PATCH 3/4] s4:rpc_server:netlogon: generate FAULT_INVALID_TAG for
93+ invalid netr_LogonGetCapabilities levels
94+
95+This is important as Windows clients with KB5028166 seem to
96+call netr_LogonGetCapabilities with query_level=2 after
97+a call with query_level=1.
98+
99+An unpatched Windows Server returns DCERPC_NCA_S_FAULT_INVALID_TAG
100+for query_level values other than 1.
101+While Samba tries to return NT_STATUS_NOT_SUPPORTED, but
102+later fails to marshall the response, which results
103+in DCERPC_FAULT_BAD_STUB_DATA instead.
104+
105+Because we don't have any documentation for level 2 yet,
106+we just try to behave like an unpatched server and
107+generate DCERPC_NCA_S_FAULT_INVALID_TAG instead of
108+DCERPC_FAULT_BAD_STUB_DATA.
109+Which allows patched Windows clients to keep working
110+against a Samba DC.
111+
112+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15418
113+
114+Signed-off-by: Stefan Metzmacher <metze@samba.org>
115+Reviewed-by: Andrew Bartlett <abartlet@samba.org>
116+(cherry picked from commit d5f1097b6220676d56ed5fc6707acf667b704518)
117+---
118+ .../knownfail.d/netr_LogonGetCapabilities | 2 --
119+ source4/rpc_server/netlogon/dcerpc_netlogon.c | 28 ++++++++++++++++---
120+ 2 files changed, 24 insertions(+), 6 deletions(-)
121+
122+diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
123+index 6a3e044eb9da..26be4f567513 100644
124+--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
125++++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
126+@@ -2399,6 +2399,30 @@ static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_c
127+ struct netlogon_creds_CredentialState *creds;
128+ NTSTATUS status;
129+
130++ switch (r->in.query_level) {
131++ case 1:
132++ break;
133++ case 2:
134++ /*
135++ * Until we know the details behind KB5028166
136++ * just return DCERPC_NCA_S_FAULT_INVALID_TAG
137++ * like an unpatched Windows Server.
138++ */
139++ FALL_THROUGH;
140++ default:
141++ /*
142++ * There would not be a way to marshall the
143++ * the response. Which would mean our final
144++ * ndr_push would fail an we would return
145++ * an RPC-level fault with DCERPC_FAULT_BAD_STUB_DATA.
146++ *
147++ * But it's important to match a Windows server
148++ * especially before KB5028166, see also our bug #15418
149++ * Otherwise Windows client would stop talking to us.
150++ */
151++ DCESRV_FAULT(DCERPC_NCA_S_FAULT_INVALID_TAG);
152++ }
153++
154+ status = dcesrv_netr_creds_server_step_check(dce_call,
155+ mem_ctx,
156+ r->in.computer_name,
157+@@ -2410,10 +2434,6 @@ static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_c
158+ }
159+ NT_STATUS_NOT_OK_RETURN(status);
160+
161+- if (r->in.query_level != 1) {
162+- return NT_STATUS_NOT_SUPPORTED;
163+- }
164+-
165+ r->out.capabilities->server_capabilities = creds->negotiate_flags;
166+
167+ return NT_STATUS_OK;
168+--
169+2.34.1
170+
171+
172+From 05f110e1a4d4b38bfbaaa3a92fda7a9127b3b456 Mon Sep 17 00:00:00 2001
173+From: Stefan Metzmacher <metze@samba.org>
174+Date: Sat, 15 Jul 2023 16:11:48 +0200
175+Subject: [PATCH 4/4] s3:rpc_server:netlogon: generate FAULT_INVALID_TAG for
176+ invalid netr_LogonGetCapabilities levels
177+
178+This is important as Windows clients with KB5028166 seem to
179+call netr_LogonGetCapabilities with query_level=2 after
180+a call with query_level=1.
181+
182+An unpatched Windows Server returns DCERPC_NCA_S_FAULT_INVALID_TAG
183+for query_level values other than 1.
184+While Samba tries to return NT_STATUS_NOT_SUPPORTED, but
185+later fails to marshall the response, which results
186+in DCERPC_FAULT_BAD_STUB_DATA instead.
187+
188+Because we don't have any documentation for level 2 yet,
189+we just try to behave like an unpatched server and
190+generate DCERPC_NCA_S_FAULT_INVALID_TAG instead of
191+DCERPC_FAULT_BAD_STUB_DATA.
192+Which allows patched Windows clients to keep working
193+against a Samba DC.
194+
195+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15418
196+
197+Signed-off-by: Stefan Metzmacher <metze@samba.org>
198+Reviewed-by: Andrew Bartlett <abartlet@samba.org>
199+
200+Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
201+Autobuild-Date(master): Mon Jul 17 07:35:09 UTC 2023 on atb-devel-224
202+
203+(cherry picked from commit dfeabce44fbb78083fbbb2aa634fc4172cf83db9)
204+---
205+ .../knownfail.d/netr_LogonGetCapabilities | 1 -
206+ source3/rpc_server/netlogon/srv_netlog_nt.c | 29 ++++++++++++++++---
207+ 2 files changed, 25 insertions(+), 5 deletions(-)
208+ delete mode 100644 selftest/knownfail.d/netr_LogonGetCapabilities
209+
210+diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
211+index 5906464a9f3..35433ec6781 100644
212+--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
213++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
214+@@ -2421,6 +2421,31 @@ NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
215+ struct netlogon_creds_CredentialState *creds;
216+ NTSTATUS status;
217+
218++ switch (r->in.query_level) {
219++ case 1:
220++ break;
221++ case 2:
222++ /*
223++ * Until we know the details behind KB5028166
224++ * just return DCERPC_NCA_S_FAULT_INVALID_TAG
225++ * like an unpatched Windows Server.
226++ */
227++ FALL_THROUGH;
228++ default:
229++ /*
230++ * There would not be a way to marshall the
231++ * the response. Which would mean our final
232++ * ndr_push would fail an we would return
233++ * an RPC-level fault with DCERPC_FAULT_BAD_STUB_DATA.
234++ *
235++ * But it's important to match a Windows server
236++ * especially before KB5028166, see also our bug #15418
237++ * Otherwise Windows client would stop talking to us.
238++ */
239++ p->fault_state = DCERPC_NCA_S_FAULT_INVALID_TAG;
240++ return NT_STATUS_NOT_SUPPORTED;
241++ }
242++
243+ become_root();
244+ status = netr_creds_server_step_check(p, p->mem_ctx,
245+ r->in.computer_name,
246+@@ -2432,10 +2457,6 @@ NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
247+ return status;
248+ }
249+
250+- if (r->in.query_level != 1) {
251+- return NT_STATUS_NOT_SUPPORTED;
252+- }
253+-
254+ r->out.capabilities->server_capabilities = creds->negotiate_flags;
255+
256+ return NT_STATUS_OK;
257diff --git a/debian/patches/series b/debian/patches/series
258index 54984e0..be2f88c 100644
259--- a/debian/patches/series
260+++ b/debian/patches/series
261@@ -66,3 +66,4 @@ CVE-2023-34968-09.patch
262 CVE-2023-34968-10.patch
263 CVE-2023-34968-11.patch
264 CVE-2023-34968-12.patch
265+secure-channel-faulty-kb5028166.patch
266diff --git a/debian/tests/control b/debian/tests/control
267index efc23b7..5e1cd04 100644
268--- a/debian/tests/control
269+++ b/debian/tests/control
270@@ -20,3 +20,7 @@ Restrictions: needs-root, allow-stderr, isolation-container
271 Tests: reinstall-samba-common-bin
272 Depends: samba-common, samba-common-bin
273 Restrictions: needs-root, needs-reboot, isolation-machine, allow-stderr
274+
275+Tests: samba-ad-dc-provisioning-internal-dns
276+Depends: samba, samba-dsdb-modules, samba-vfs-modules, winbind, smbclient, krb5-user, bind9-dnsutils, lxd | snapd, lsb-release, dctrl-tools
277+Restrictions: needs-root, isolation-machine, allow-stderr, breaks-testbed
278diff --git a/debian/tests/samba-ad-dc-provisioning-internal-dns b/debian/tests/samba-ad-dc-provisioning-internal-dns
279new file mode 100755
280index 0000000..f84372c
281--- /dev/null
282+++ b/debian/tests/samba-ad-dc-provisioning-internal-dns
283@@ -0,0 +1,408 @@
284+#!/bin/bash
285+
286+set -e
287+set -o pipefail
288+
289+source debian/tests/util
290+
291+declare -r domain="EXAMPLE"
292+declare -r realm="EXAMPLE.FAKE"
293+declare -r adminpass="Passw0rd"
294+declare -r test_user="test_user_${RANDOM}"
295+declare -r test_pw="test_user_secret_${RANDOM}"
296+declare -A user_pass
297+user_pass[Administrator]="${adminpass}"
298+user_pass[${test_user}]="${test_pw}"
299+declare -A join_method_deps
300+# Minimum set of deps: let realmd install the extra dependencies
301+# as needed, depending on the join method.
302+# sssd-dbus is needed by the sssctl tool, and is not installed automatically
303+# via deps in focal
304+join_method_deps[realmd_sssd]="realmd krb5-user smbclient sssd-dbus"
305+# libnss-winbind needs to be explicitly listed because realmd only started
306+# installing it in version 0.17.0, that's >= focal
307+join_method_deps[realmd_winbind]="realmd krb5-user smbclient libnss-winbind"
308+
309+
310+cleanup() {
311+ rc=$?
312+ set +e # so we don't exit midcleanup
313+ if [ ${rc} -ne 0 ]; then
314+ echo "## Something failed, gathering logs"
315+ echo
316+ echo "## smb.conf"
317+ cat /etc/samba/smb.conf
318+ echo
319+ echo "## resolv.conf"
320+ cat /etc/resolv.conf
321+ echo
322+ echo "## resolvectl status"
323+ resolvectl status
324+ echo "## journal for samba-ad-dc.service"
325+ journalctl -u samba-ad-dc.service --lines 500
326+ echo
327+ for log in /var/log/samba/log.*; do
328+ # skip compressed logrotated files
329+ if [ "${log%.gz}" != "${log}" ]; then
330+ continue
331+ fi
332+ [ -s "${log}" ] || continue
333+ echo "## $(basename ${log}):"
334+ tail -n 500 "${log}"
335+ echo
336+ done
337+ echo "## syslog"
338+ tail -n 500 /var/log/syslog
339+ fi
340+}
341+
342+trap cleanup EXIT
343+
344+assert_testparm() {
345+ local parameter="${1}"
346+ local expected_value="${2}"
347+ local current_value=""
348+ local -i retval=0
349+
350+ echo -n "Asserting ${parameter} is ${expected_value}: "
351+ current_value=$(testparm -s --parameter-name "${parameter}" 2>/dev/null) || {
352+ retval=$?
353+ echo "FAIL"
354+ return ${retval}
355+ }
356+ if [ "${current_value}" = "${expected_value}" ]; then
357+ echo "OK"
358+ return 0
359+ else
360+ echo "FAIL"
361+ return 1
362+ fi
363+}
364+
365+basic_config_tests() {
366+ echo "## Basic config tests"
367+ testparm -s > /dev/null
368+ assert_testparm "realm" "${realm}"
369+ assert_testparm "workgroup" "${domain}"
370+ assert_testparm "server role" "active directory domain controller"
371+ echo
372+}
373+
374+dns_tests() {
375+ echo "## DNS tests"
376+ echo "Obtaining administrator kerberos ticket"
377+ echo "${adminpass}" | timeout --verbose 30 kinit Administrator
378+ echo
379+ echo "Querying server info"
380+ samba-tool dns serverinfo "$(hostname)"
381+ echo
382+ echo "Checking we got a service ticket of type host/"
383+ klist | grep -i "host/$(hostname)"
384+ echo
385+ echo "Checking specific DNS records"
386+ for srv in _ldap._tcp _kerberos._tcp _kerberos._udp _kpasswd._udp; do
387+ echo -n "${srv}.${realm,,}: "
388+ dig @localhost +short -t SRV ${srv}.${realm,,}
389+ echo
390+ done
391+ echo
392+ echo -n "Checking that our hostname \"$(hostname)\" is in DNS: "
393+ myip=$(dig @localhost +short -t A "$(hostname).${realm,,}")
394+ echo "${myip}"
395+ echo
396+}
397+
398+user_creation_tests() {
399+ echo "## User creation tests"
400+ samba-tool domain passwordsettings set --complexity=off
401+ echo "Creating user \"${test_user}\" with password ${test_pw}"
402+ samba-tool user add "${test_user}" "${test_pw}"
403+ echo
404+ echo "Attempting to obtain kerberos ticket for user \"${test_user}\""
405+ # just in case it ends up waiting at a prompt, we use "timeout"
406+ echo "${test_pw}" | timeout --verbose 30 kinit "${test_user}"
407+ echo "Ticket obtained"
408+ klist
409+ echo
410+}
411+
412+smbclient_tests() {
413+ echo "## smbclient tests"
414+ kdestroy || :
415+ echo
416+ echo "Obtaining a TGT for ${test_user}"
417+ echo "${test_pw}" | timeout --verbose 30 kinit "${test_user}"
418+ klist | grep krbtgt
419+ echo
420+ echo "Attempting password-less authentication with smbclient"
421+ echo
422+ echo "Listing shares"
423+ smbclient -L "$(hostname)" --use-kerberos=required -k
424+ echo
425+ echo "Listing the sysvol share"
426+ smbclient "//$(hostname)/sysvol" --use-kerberos=required -k -c "ls"
427+ echo
428+ echo "Listing policies"
429+ # lowercase the ${realm}
430+ smbclient "//$(hostname)/sysvol" --use-kerberos=required -k -c "ls ${realm,,}/Policies/*"
431+ echo
432+ echo "Checking that we have a ticket for the cifs service after all these commands"
433+ klist | grep cifs/
434+ echo
435+}
436+
437+server_join_tests() {
438+ local member_server
439+ # the join methods are the keys of the join_method_deps dict
440+ local -a methods=("${!join_method_deps[@]}")
441+ local member_server="member-server"
442+
443+ echo "## Server join tests"
444+ echo "## Initializing lxd"
445+ setup_lxd "${realm,,}"
446+
447+ for method in "${methods[@]}"; do
448+ echo "## Setting up member server to join a domain using method ${method}"
449+ setup_member_server "${member_server}" "${method}"
450+ echo "## Joining domain with method ${method}"
451+ join_domain "${member_server}" "${method}"
452+ echo
453+ echo "## Verifying join with method ${method}"
454+ verify_join "${member_server}" "${method}"
455+ echo
456+ echo "## Leaving domain with method ${method}"
457+ leave_domain "${member_server}" "${method}"
458+ echo
459+ echo "## Destroying member server"
460+ lxc delete --force "${member_server}"
461+ done
462+}
463+
464+setup_member_server() {
465+ local container_name="${1}"
466+ local method="${2}"
467+ local release
468+
469+ release="$(lsb_release -cs)"
470+ if [ -z "${join_method_deps[${method}]}" ]; then
471+ echo "## INTERNAL ERROR, invalid join method: ${method}"
472+ return 1
473+ fi
474+ echo "## Got test dependencies: ${join_method_deps[${method}]}"
475+ # can't use cloud-init here to install packages, because we first need to
476+ # sync the apt config from the host to the container
477+ echo "## Launching ${release} container"
478+ lxc launch "ubuntu-daily:${release}" "${container_name}" -q
479+ wait_container_ready "${container_name}"
480+ send_apt_config "${container_name}"
481+ copy_local_apt_files "${container_name}"
482+ echo "## Installing dependencies in test container"
483+ install_packages_in_container "${container_name}" ${join_method_deps[${method}]}
484+}
485+
486+join_domain_realmd_winbind() {
487+ local server="${1}"
488+ local discover_cmd="realm discover -v --membership-software=samba --client-software=winbind ${realm,,}"
489+ local join_cmd="realm join -v --membership-software=samba --client-software=winbind ${realm,,}"
490+
491+ echo "## Domain information"
492+ lxc exec "${server}" -- ${discover_cmd}
493+ echo
494+ echo "## Running join command: ${join_cmd}"
495+ echo "${adminpass}" | lxc exec "${server}" -- ${join_cmd}
496+ # LP: #1980246
497+ # So far, only lunar and later automatically add winbind to /etc/nsswitch.conf.
498+ lxc exec "${server}" -- sed -r -i \
499+ -e '/^(passwd|group):.*[[:space:]]winbind\b/b' \
500+ -e 's/^(passwd|group):.*/& winbind/' \
501+ /etc/nsswitch.conf
502+}
503+
504+verify_join_realmd_winbind() {
505+ local server="${1}"
506+ local member_domain
507+
508+ echo -n "## Verifying member server joined domain name: "
509+ member_domain=$(lxc exec "${server}" -- wbinfo --own-domain)
510+ echo "${member_domain}"
511+ if [ "${member_domain}" != "${domain}" ]; then
512+ echo "ERROR: expected member server domain to match the joined domain:"
513+ echo "member server domain: ${member_domain}"
514+ echo "AD domain: ${domain}"
515+ return 1
516+ fi
517+ echo
518+ # we just want to see the output, not parse it
519+ echo "## Domain status in member server"
520+ lxc exec "${server}" -- wbinfo --domain-info "${member_domain}"
521+ echo
522+ echo "## User status in member server"
523+ for u in "${!user_pass[@]}"; do
524+ echo "## User \"${u}@${realm}\" information:"
525+ lxc exec "${server}" -- wbinfo --user-info "${u}@${realm}"
526+ echo
527+ echo "## id ${u}@${realm}"
528+ lxc exec "${server}" -- id ${u}@${realm}
529+ echo
530+ echo "## kinit authentication check for user \"${u}@${realm}\" inside member server"
531+ echo "${user_pass[${u}]}" | lxc exec "${server}" -- timeout --verbose 30 kinit "${u}@${realm}"
532+ lxc exec "${server}" -- klist
533+ echo
534+ echo "## Listing shares with the obtained kerberos ticket"
535+ lxc exec "${server}" -- smbclient -L "$(hostname)" --use-kerberos=required -k
536+ lxc exec "${server}" -- kdestroy
537+ echo
538+ echo "## wbinfo authentication check for user \"${u}@${realm}\" inside member server"
539+ # non-interactive format for username is user%password
540+ lxc exec "${server}" -- wbinfo --authenticate="${u}@${realm}%${user_pass[${u}]}"
541+ echo
542+ echo "## wbinfo kerberos authentication check for user \"${u}@${realm}\" inside member server"
543+ lxc exec "${server}" -- wbinfo --krb5auth="${u}@${realm}%${user_pass[${u}]}"
544+ echo
545+ echo "## Listing shares with the obtained kerberos ticket"
546+ lxc exec "${server}" -- smbclient -L "$(hostname)" --use-kerberos=required -k
547+ lxc exec "${server}" -- kdestroy
548+ done
549+}
550+
551+leave_domain_realmd_winbind() {
552+ local server="${1}"
553+ local leave_cmd="realm leave -v --remove --client-software=winbind"
554+
555+ echo "## Running leave command: ${leave_cmd}"
556+ echo "${adminpass}" | lxc exec "${server}" -- ${leave_cmd}
557+}
558+
559+join_domain_realmd_sssd() {
560+ local server="${1}"
561+ local discover_cmd="realm discover -v --membership-software=adcli --client-software=sssd ${realm,,}"
562+ local join_cmd="realm join -v --membership-software=adcli --client-software=sssd ${realm,,}"
563+
564+ echo "## Domain information"
565+ lxc exec "${server}" -- ${discover_cmd}
566+ echo
567+ echo "## Running join command: ${join_cmd}"
568+ echo "${adminpass}" | lxc exec "${server}" -- ${join_cmd}
569+ echo
570+}
571+
572+verify_join_realmd_sssd() {
573+ local server="${1}"
574+ local samba_domain
575+
576+ echo -n "## Verifying member server joined domain name: "
577+ samba_domain=$(lxc exec "${server}" -- sssctl domain-list)
578+ echo "${samba_domain}"
579+ if [ "${samba_domain}" != "${realm,,}" ]; then
580+ echo "ERROR: expected member server domain to match the joined domain:"
581+ echo "member server domain: ${samba_domain}"
582+ echo "AD domain: ${realm,,}"
583+ return 1
584+ fi
585+ echo
586+ # we just want to see the output, not parse it
587+ echo "## Domain status in member server"
588+ lxc exec "${server}" -- sssctl domain-status "${realm}"
589+ echo
590+ echo "## User status in member server"
591+ for u in "${!user_pass[@]}"; do
592+ echo "## User \"${u}@${realm}\" information:"
593+ lxc exec "${server}" -- sssctl user-checks "${u}@${realm}"
594+ echo
595+ echo "## id ${u}@${realm}"
596+ lxc exec "${server}" -- id "${u}@${realm}"
597+ echo
598+ echo "## kinit authentication check for user \"${u}@${realm}\" inside member server"
599+ echo "${user_pass[${u}]}" | lxc exec "${server}" -- timeout --verbose 30 kinit "${u}@${realm}"
600+ lxc exec "${server}" -- klist
601+ echo
602+ echo "## Listing shares with the obtained kerberos ticket"
603+ lxc exec "${server}" -- smbclient -L "$(hostname)" --use-kerberos=required -k
604+ lxc exec "${server}" -- kdestroy
605+ done
606+}
607+
608+leave_domain_realmd_sssd() {
609+ local server="${1}"
610+ local leave_cmd="realm leave -v --remove --client-software=sssd"
611+
612+ echo "## Running leave command: ${leave_cmd}"
613+ echo "${adminpass}" | lxc exec "${server}" -- ${leave_cmd}
614+}
615+
616+join_domain() {
617+ local server="${1}"
618+ local m="${2}"
619+
620+ join_domain_${m} "${server}"
621+}
622+
623+verify_join() {
624+ local server="${1}"
625+ local m="${2}"
626+
627+ verify_join_${m} "${server}"
628+}
629+
630+leave_domain() {
631+ local server="${1}"
632+ local m="${2}"
633+
634+ leave_domain_${m} "${server}"
635+}
636+
637+systemctl stop smbd nmbd winbind
638+systemctl disable smbd nmbd winbind
639+systemctl mask smbd nmbd winbind
640+
641+systemctl unmask samba-ad-dc
642+systemctl enable samba-ad-dc
643+
644+if [ -f /etc/samba/smb.conf ]; then
645+ mv /etc/samba/smb.conf{,.orig}
646+fi
647+
648+# make sure we are starting fresh, as previous tests might left things around
649+
650+rm -rf /var/lib/samba/* /var/cache/samba/* /run/samba/*
651+kdestroy || :
652+
653+samba-tool domain provision \
654+ --domain="${domain}" \
655+ --realm="${realm}" \
656+ --adminpass="${adminpass}" \
657+ --server-role=dc \
658+ --use-rfc2307 \
659+ --dns-backend=SAMBA_INTERNAL
660+
661+current_dns=$(resolvectl status | grep -E "^[[:blank:]]*Current DNS Server:" | awk '{print $4}')
662+
663+if [ -n "${current_dns}" ]; then
664+ echo "## Setting dns forwarder to ${current_dns} in smb.conf"
665+ sed -r -i "s,dns forwarder = .*,dns forwarder = ${current_dns}," \
666+ /etc/samba/smb.conf
667+ unlink /etc/resolv.conf
668+ echo "nameserver 127.0.0.1" > /etc/resolv.conf
669+ # lowercase substitution
670+ echo "search ${realm,,}" >> /etc/resolv.conf
671+ systemctl stop systemd-resolved
672+ systemctl disable systemd-resolved
673+else
674+ echo "## Warning, couldn't detect the current DNS server to use as forwarder in smb.conf"
675+ echo "## resolvectl status:"
676+ resolvectl status
677+ echo "## Continuing, and hoping for the best"
678+fi
679+
680+cp -f /var/lib/samba/private/krb5.conf /etc/krb5.conf
681+
682+systemctl start samba-ad-dc
683+
684+# give it some time, it's a lot of services to start
685+sleep 5s
686+
687+basic_config_tests
688+dns_tests
689+user_creation_tests
690+smbclient_tests
691+server_join_tests
692diff --git a/debian/tests/util b/debian/tests/util
693new file mode 100644
694index 0000000..66ed247
695--- /dev/null
696+++ b/debian/tests/util
697@@ -0,0 +1,178 @@
698+#!/bin/sh
699+
700+# $1: share name
701+# $2: comma separated list of vfs_objects to use, if any
702+add_share() {
703+ local share="$1"
704+ local vfs="$2"
705+ if ! testparm -s 2>&1 | grep -E "^\[${share}\]"; then
706+ echo "Adding [${share}] share"
707+ cat >> /etc/samba/smb.conf <<EOFEOF
708+[${share}]
709+ read only = no
710+ guest ok = no
711+ path = /${share}
712+EOFEOF
713+ if [ -n "${vfs}" ]; then
714+ echo "vfs objects = ${vfs}" >> /etc/samba/smb.conf
715+ fi
716+ systemctl reload smbd.service
717+ else
718+ echo "Share [${share}] already exists, continuing"
719+ fi
720+}
721+
722+# $1: username
723+# $2: password
724+add_user() {
725+ local username="$1"
726+ local password="$2"
727+
728+ echo "Creating a local and samba user called ${username}"
729+ useradd -m "${username}"
730+ echo "Setting samba password for the ${username} user"
731+ (echo "${password}"; echo "${password}") | smbpasswd -s -a ${username}
732+}
733+
734+# $1: share name
735+populate_share() {
736+ local sharename="$1"
737+ local usergroup="$2"
738+ local sharepath="/${sharename}"
739+
740+ mkdir -p "${sharepath}"
741+ dd if=/dev/urandom bs=4096 count=1000 2>/dev/null | base64 > "${sharepath}/data"
742+ cd "${sharepath}"
743+ md5sum data > data.md5
744+ chown -R "${usergroup}:${usergroup}" "${sharepath}"
745+}
746+
747+
748+# $1: kernel version in the form major.minor.patch
749+check_kernel_version() {
750+ local k_ver=$1
751+ local k_major=$(echo ${k_ver} | cut -d . -f 1)
752+ local k_minor=$(echo ${k_ver} | cut -d . -f 2)
753+
754+ # uring is supported starting with kernel 5.1.x
755+ if [ ${k_major} -eq 5 ] && [ ${k_minor} -ge 1 ]; then
756+ return 0
757+ elif [ ${k_major} -ge 6 ]; then
758+ return 0
759+ else
760+ return 1
761+ fi
762+}
763+
764+wait_container_ready() {
765+ local container="${1}"
766+ local -i limit=120 # seconds
767+ local -i i=0
768+ local -i result=0
769+ local ip
770+ local output
771+
772+ while /bin/true; do
773+ ip=$(lxc list "${container}" -c 4 --format=csv | tail -1 | awk '{print $1}')
774+ if [ -n "${ip}" ]; then
775+ break
776+ fi
777+ i=$((i+1))
778+ if [ ${i} -ge ${limit} ]; then
779+ return 1
780+ fi
781+ sleep 1s
782+ echo -n "."
783+ done
784+ while ! nc -z "${ip}" 22; do
785+ echo -n "."
786+ i=$((i+1))
787+ if [ ${i} -ge ${limit} ]; then
788+ return 1
789+ fi
790+ sleep 1s
791+ done
792+ # cloud-init might still be doing things...
793+ # this call blocks, so wrap it in its own little timeout
794+ output=$(lxc exec "${container}" -- timeout --verbose $((limit-i)) cloud-init status --wait) || {
795+ result=$?
796+ echo "cloud-init status --wait failed on container ${container}"
797+ echo "${output}"
798+ return ${result}
799+ }
800+ echo
801+}
802+
803+install_lxd() {
804+ if ! command -v lxd > /dev/null 2>&1; then
805+ # the test depends has "lxd | snapd", so if we don't have lxd, we must
806+ # install the snap
807+ snap list lxd > /dev/null 2>&1 || {
808+ echo "Installing the LXD snap..."
809+ snap install lxd
810+ }
811+ fi
812+}
813+
814+setup_lxd() {
815+ local dns_domain="${1}"
816+ local nic
817+ local dns_ip
818+
819+ install_lxd
820+ # Stop samba while lxd is setup, to avoid conflicts on lxdbr0:53
821+ systemctl stop samba-ad-dc
822+ lxd init --auto
823+ lxd waitready --timeout 600
824+ # sample csv output. Columns are NAME,TYPE,MANAGED,DESCRIPTION,USED_BY
825+ #enp1s0,physical,NO,,0
826+ #lxdbr0,bridge,YES,,1
827+ nic=$(lxc network list --format=csv | grep -E "bridge,YES,,1" | cut -d , -f 1)
828+ dns_ip=$(lxc network info "${nic}" | grep -w inet | awk '{print $2}')
829+ # port=0 effectively disables dnsmasq's DNS, so it doesn't conflict with samba's DNS
830+ lxc network set "${nic:-lxdbr0}" ipv6.address=none dns.domain="${dns_domain}" raw.dnsmasq="$(echo -e port=0\\ndhcp-option=option:dns-server,${dns_ip})"
831+ if [ -n "${http_proxy}" ]; then
832+ lxc config set core.proxy_http "${http_proxy}"
833+ fi
834+ if [ -n "${https_proxy}" ]; then
835+ lxc config set core.proxy_https "${https_proxy}"
836+ fi
837+ if [ -n "${noproxy}" ]; then
838+ lxc config set core.proxy_ignore_hosts "${noproxy}"
839+ fi
840+ # the default of 64k is too low for, at least, ppc64el on focal
841+ lxc profile set default limits.kernel.memlock 262144
842+ systemctl start samba-ad-dc
843+ # give it some time, it's a lot of services to start
844+ sleep 5s
845+}
846+
847+# Copy the local apt package archive over to the lxd container.
848+copy_local_apt_files() {
849+ local container_name="${1:-docker}"
850+
851+ for local_source in $(apt-get indextargets | grep-dctrl -F URI -e '^file:/' -sURI | awk '{print $2}'); do
852+ local_source=${local_source#file:}
853+ local_dir=$(dirname "${local_source}")
854+ lxc exec "${container_name}" -- mkdir -p "${local_dir}"
855+ tar -cC "${local_dir}" . | lxc exec "${container_name}" -- tar -xC "${local_dir}"
856+ done
857+}
858+
859+send_apt_config() {
860+ echo "Copying over /etc/apt to container ${1}"
861+ lxc exec "${1}" -- rm -rf /etc/apt
862+ lxc exec "${1}" -- mkdir -p /etc/apt
863+ tar -cC /etc/apt . | lxc exec "${1}" -- tar -xC /etc/apt
864+}
865+
866+install_packages_in_container() {
867+ local container="${1}"
868+ shift
869+ local packages="${*}"
870+
871+ echo "### Installing dependencies in member server container: ${packages}"
872+ lxc exec "${container}" --env DEBIAN_FRONTEND=noninteractive -- apt-get update -q
873+ lxc exec "${container}" --env DEBIAN_FRONTEND=noninteractive -- apt-get dist-upgrade -q -y
874+ lxc exec "${container}" --env DEBIAN_FRONTEND=noninteractive -- apt-get install -q -y ${packages}
875+}

Subscribers

People subscribed via source and target branches