/[smeserver]/rpms/samba/sme10/samba-4.10-redhat.patch
ViewVC logotype

Annotation of /rpms/samba/sme10/samba-4.10-redhat.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Wed Aug 9 04:48:46 2023 UTC (15 months, 3 weeks ago) by jpp
Branch: MAIN
CVS Tags: samba-4_10_16-24_el7_9, samba-4_10_16-24_1_el7_sme, HEAD
Initial import

1 jpp 1.1 From 9aa816f5017bd38cbb9af2af5a7c385647e4f76d Mon Sep 17 00:00:00 2001
2     From: Alexander Bokovoy <ab@samba.org>
3     Date: Tue, 7 Jan 2020 19:25:53 +0200
4     Subject: [PATCH 001/142] s3-rpcserver: fix security level check for
5     DsRGetForestTrustInformation
6     MIME-Version: 1.0
7     Content-Type: text/plain; charset=UTF-8
8     Content-Transfer-Encoding: 8bit
9    
10     Harmonize _netr_DsRGetForestTrustInformation with source4/ logic which
11     didn't change since DCE RPC channel refactoring.
12    
13     With the current code we return RPC faul as can be seen in the logs:
14    
15     2019/12/11 17:12:55.463081, 1, pid=20939, effective(1284200000, 1284200000), real(1284200000, 0), class=rpc_parse] ../librpc/ndr/ndr.c:471(ndr_print_function_debug)
16     netr_DsRGetForestTrustInformation: struct netr_DsRGetForestTrustInformation
17     in: struct netr_DsRGetForestTrustInformation
18     server_name : *
19     server_name : '\\some-dc.example.com'
20     trusted_domain_name : NULL
21     flags : 0x00000000 (0)
22     [2019/12/11 17:12:55.463122, 4, pid=20939, effective(1284200000, 1284200000), real(1284200000, 0), class=rpc_srv] ../source3/rpc_server/srv_pipe.c:1561(api_rpcTNP)
23     api_rpcTNP: fault(5) return.
24    
25     This is due to this check in processing a request:
26     if (!(p->pipe_bound && (p->auth.auth_type != DCERPC_AUTH_TYPE_NONE)
27     && (p->auth.auth_level != DCERPC_AUTH_LEVEL_NONE))) {
28     p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
29     return WERR_ACCESS_DENIED;
30     }
31    
32     and since we get AuthZ response,
33    
34     Successful AuthZ: [netlogon,ncacn_np] user [EXAMPLE]\[admin] [S-1-5-21-1234567-890123456-500] at [Wed, 11 Dec 2019 17:12:55.461164 UTC]
35     Remote host [ipv4:Y.Y.Y.Y:59017] local host [ipv4:X.X.X.X:445]
36     [2019/12/11 17:12:55.461584, 4, pid=20939, effective(0, 0), real(0, 0)] ../lib/audit_logging/audit_logging.c:141(audit_log_json)
37     JSON Authorization: {"timestamp": "2019-12-11T17:12:55.461491+0000",
38     "type": "Authorization", "Authorization": {"version": {"major": 1, "minor": 1},
39     "localAddress": "ipv4:X.X.X.X:445", "remoteAddress": "ipv4:Y.Y.Y.Y:59017",
40     "serviceDescription": "netlogon", "authType": "ncacn_np",
41     "domain": "EXAMPLE", "account": "admin", "sid": "S-1-5-21-1234567-890123456-500",
42     "sessionId": "c5a2386f-f2cc-4241-9a9e-d104cf5859d5", "logonServer": "SOME-DC",
43     "transportProtection": "SMB", "accountFlags": "0x00000010"}}
44    
45     this means we are actually getting anonymous DCE/RPC access to netlogon
46     on top of authenticated SMB connection. In such case we have exactly
47     auth_type set to DCERPC_AUTH_TYPE_NONE and auth_level set to
48     DCERPC_AUTH_LEVEL_NONE in the pipe->auth. Thus, returning an error.
49    
50     Update the code to follow the same security level check as in s4 variant
51     of the call.
52    
53     Signed-off-by: Alexander Bokovoy <ab@samba.org>
54     Reviewed-by: Guenther Deschner <gd@samba.org>
55    
56     Autobuild-User(master): Günther Deschner <gd@samba.org>
57     Autobuild-Date(master): Mon Jan 13 15:05:28 UTC 2020 on sn-devel-184
58    
59     (cherry picked from commit c6d880a115095c336b8b74f45854a99abb1bbb87)
60     ---
61     source3/rpc_server/netlogon/srv_netlog_nt.c | 6 +++---
62     1 file changed, 3 insertions(+), 3 deletions(-)
63    
64     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
65     index d799ba4feef..87613b99fde 100644
66     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
67     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
68     @@ -2425,10 +2425,10 @@ WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p,
69     {
70     NTSTATUS status;
71     struct lsa_ForestTrustInformation *info, **info_ptr;
72     + enum security_user_level security_level;
73    
74     - if (!(p->pipe_bound && (p->auth.auth_type != DCERPC_AUTH_TYPE_NONE)
75     - && (p->auth.auth_level != DCERPC_AUTH_LEVEL_NONE))) {
76     - p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
77     + security_level = security_session_user_level(p->session_info, NULL);
78     + if (security_level < SECURITY_USER) {
79     return WERR_ACCESS_DENIED;
80     }
81    
82     --
83     2.39.0
84    
85    
86     From e71fddb9ad5275a222d96bdcee06571a9a8c73c8 Mon Sep 17 00:00:00 2001
87     From: Isaac Boukris <iboukris@gmail.com>
88     Date: Wed, 27 May 2020 16:50:45 +0200
89     Subject: [PATCH 002/142] Add a test to check dNSHostName with netbios aliases
90    
91     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
92    
93     Signed-off-by: Isaac Boukris <iboukris@samba.org>
94     Reviewed-by: Andreas Schneider <asn@samba.org>
95     ---
96     selftest/knownfail.d/nb_alias_dnshostname | 2 ++
97     testprogs/blackbox/test_net_ads.sh | 14 ++++++++++++++
98     2 files changed, 16 insertions(+)
99     create mode 100644 selftest/knownfail.d/nb_alias_dnshostname
100    
101     diff --git a/selftest/knownfail.d/nb_alias_dnshostname b/selftest/knownfail.d/nb_alias_dnshostname
102     new file mode 100644
103     index 00000000000..3c14e9931b9
104     --- /dev/null
105     +++ b/selftest/knownfail.d/nb_alias_dnshostname
106     @@ -0,0 +1,2 @@
107     +^samba4.blackbox.net_ads.nb_alias check dNSHostName
108     +^samba4.blackbox.net_ads.nb_alias check main SPN
109     diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh
110     index 95c0cf76f90..6073ea972f9 100755
111     --- a/testprogs/blackbox/test_net_ads.sh
112     +++ b/testprogs/blackbox/test_net_ads.sh
113     @@ -220,6 +220,20 @@ testit_grep "dns alias addl" $dns_alias2 $VALGRIND $net_tool ads search -P samac
114     ##Goodbye...
115     testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
116    
117     +# netbios aliases tests
118     +testit "join nb_alias" $VALGRIND $net_tool --option=netbiosaliases=nb_alias1,nb_alias2 ads join -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
119     +
120     +testit "testjoin nb_alias" $VALGRIND $net_tool ads testjoin || failed=`expr $failed + 1`
121     +
122     +testit_grep "nb_alias check dNSHostName" $fqdn $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ dNSHostName || failed=`expr $failed + 1`
123     +testit_grep "nb_alias check main SPN" ${uc_netbios}.${lc_realm} $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1`
124     +
125     +testit_grep "nb_alias1 SPN" nb_alias1 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1`
126     +testit_grep "nb_alias2 SPN" nb_alias2 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1`
127     +
128     +##Goodbye...
129     +testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
130     +
131     #
132     # Test createcomputer option of 'net ads join'
133     #
134     --
135     2.39.0
136    
137    
138     From e80e373485818eb7faebf5c9aae10d82fbc4e2e2 Mon Sep 17 00:00:00 2001
139     From: Isaac Boukris <iboukris@gmail.com>
140     Date: Wed, 27 May 2020 15:52:46 +0200
141     Subject: [PATCH 003/142] Fix accidental overwrite of dnsHostName by the last
142     netbios alias
143    
144     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
145    
146     Signed-off-by: Isaac Boukris <iboukris@samba.org>
147     Reviewed-by: Andreas Schneider <asn@samba.org>
148     ---
149     selftest/knownfail.d/nb_alias_dnshostname | 2 --
150     source3/libnet/libnet_join.c | 5 +++--
151     2 files changed, 3 insertions(+), 4 deletions(-)
152     delete mode 100644 selftest/knownfail.d/nb_alias_dnshostname
153    
154     diff --git a/selftest/knownfail.d/nb_alias_dnshostname b/selftest/knownfail.d/nb_alias_dnshostname
155     deleted file mode 100644
156     index 3c14e9931b9..00000000000
157     --- a/selftest/knownfail.d/nb_alias_dnshostname
158     +++ /dev/null
159     @@ -1,2 +0,0 @@
160     -^samba4.blackbox.net_ads.nb_alias check dNSHostName
161     -^samba4.blackbox.net_ads.nb_alias check main SPN
162     diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
163     index 9d4f656ffec..a31011b0ff8 100644
164     --- a/source3/libnet/libnet_join.c
165     +++ b/source3/libnet/libnet_join.c
166     @@ -507,6 +507,7 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
167     ADS_STATUS status;
168     ADS_MODLIST mods;
169     fstring my_fqdn;
170     + fstring my_alias;
171     const char **spn_array = NULL;
172     size_t num_spns = 0;
173     char *spn = NULL;
174     @@ -587,11 +588,11 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
175     /*
176     * Add HOST/netbiosname.domainname
177     */
178     - fstr_sprintf(my_fqdn, "%s.%s",
179     + fstr_sprintf(my_alias, "%s.%s",
180     *netbios_aliases,
181     lp_dnsdomain());
182    
183     - spn = talloc_asprintf(frame, "HOST/%s", my_fqdn);
184     + spn = talloc_asprintf(frame, "HOST/%s", my_alias);
185     if (spn == NULL) {
186     status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
187     goto done;
188     --
189     2.39.0
190    
191    
192     From 7ca5f9b2956ec41777837a7e14800a4345505ed6 Mon Sep 17 00:00:00 2001
193     From: Isaac Boukris <iboukris@gmail.com>
194     Date: Thu, 24 Oct 2019 19:04:51 +0300
195     Subject: [PATCH 004/142] Refactor ads_keytab_add_entry() to make it iterable
196    
197     so we can more easily add msDS-AdditionalDnsHostName entries.
198    
199     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
200    
201     Signed-off-by: Isaac Boukris <iboukris@samba.org>
202     Reviewed-by: Andreas Schneider <asn@samba.org>
203     ---
204     source3/libads/kerberos_keytab.c | 197 +++++++++++++++++--------------
205     1 file changed, 107 insertions(+), 90 deletions(-)
206    
207     diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c
208     index 97d5535041c..0f450a09df5 100644
209     --- a/source3/libads/kerberos_keytab.c
210     +++ b/source3/libads/kerberos_keytab.c
211     @@ -228,18 +228,16 @@ out:
212     return ok;
213     }
214    
215     -/**********************************************************************
216     - Adds a single service principal, i.e. 'host' to the system keytab
217     -***********************************************************************/
218     -
219     -int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
220     +static int add_kt_entry_etypes(krb5_context context, TALLOC_CTX *tmpctx,
221     + ADS_STRUCT *ads, const char *salt_princ_s,
222     + krb5_keytab keytab, krb5_kvno kvno,
223     + const char *srvPrinc, const char *my_fqdn,
224     + krb5_data *password, bool update_ads)
225     {
226     krb5_error_code ret = 0;
227     - krb5_context context = NULL;
228     - krb5_keytab keytab = NULL;
229     - krb5_data password;
230     - krb5_kvno kvno;
231     - krb5_enctype enctypes[6] = {
232     + char *princ_s = NULL;
233     + char *short_princ_s = NULL;
234     + krb5_enctype enctypes[6] = {
235     ENCTYPE_DES_CBC_CRC,
236     ENCTYPE_DES_CBC_MD5,
237     #ifdef HAVE_ENCTYPE_AES128_CTS_HMAC_SHA1_96
238     @@ -251,65 +249,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
239     ENCTYPE_ARCFOUR_HMAC,
240     0
241     };
242     - char *princ_s = NULL;
243     - char *short_princ_s = NULL;
244     - char *salt_princ_s = NULL;
245     - char *password_s = NULL;
246     - char *my_fqdn;
247     - TALLOC_CTX *tmpctx = NULL;
248     - int i;
249     -
250     - ret = smb_krb5_init_context_common(&context);
251     - if (ret) {
252     - DBG_ERR("kerberos init context failed (%s)\n",
253     - error_message(ret));
254     - return -1;
255     - }
256     -
257     - ret = ads_keytab_open(context, &keytab);
258     - if (ret != 0) {
259     - goto out;
260     - }
261     -
262     - /* retrieve the password */
263     - if (!secrets_init()) {
264     - DEBUG(1, (__location__ ": secrets_init failed\n"));
265     - ret = -1;
266     - goto out;
267     - }
268     - password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
269     - if (!password_s) {
270     - DEBUG(1, (__location__ ": failed to fetch machine password\n"));
271     - ret = -1;
272     - goto out;
273     - }
274     - ZERO_STRUCT(password);
275     - password.data = password_s;
276     - password.length = strlen(password_s);
277     -
278     - /* we need the dNSHostName value here */
279     - tmpctx = talloc_init(__location__);
280     - if (!tmpctx) {
281     - DEBUG(0, (__location__ ": talloc_init() failed!\n"));
282     - ret = -1;
283     - goto out;
284     - }
285     -
286     - my_fqdn = ads_get_dnshostname(ads, tmpctx, lp_netbios_name());
287     - if (!my_fqdn) {
288     - DEBUG(0, (__location__ ": unable to determine machine "
289     - "account's dns name in AD!\n"));
290     - ret = -1;
291     - goto out;
292     - }
293     -
294     - /* make sure we have a single instance of a the computer account */
295     - if (!ads_has_samaccountname(ads, tmpctx, lp_netbios_name())) {
296     - DEBUG(0, (__location__ ": unable to determine machine "
297     - "account's short name in AD!\n"));
298     - ret = -1;
299     - goto out;
300     - }
301     + size_t i;
302    
303     /* Construct our principal */
304     if (strchr_m(srvPrinc, '@')) {
305     @@ -358,22 +298,6 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
306     }
307     }
308    
309     - kvno = (krb5_kvno)ads_get_machine_kvno(ads, lp_netbios_name());
310     - if (kvno == -1) {
311     - /* -1 indicates failure, everything else is OK */
312     - DEBUG(1, (__location__ ": ads_get_machine_kvno failed to "
313     - "determine the system's kvno.\n"));
314     - ret = -1;
315     - goto out;
316     - }
317     -
318     - salt_princ_s = kerberos_secrets_fetch_salt_princ();
319     - if (salt_princ_s == NULL) {
320     - DBG_WARNING("kerberos_secrets_fetch_salt_princ() failed\n");
321     - ret = -1;
322     - goto out;
323     - }
324     -
325     for (i = 0; enctypes[i]; i++) {
326    
327     /* add the fqdn principal to the keytab */
328     @@ -383,11 +307,11 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
329     princ_s,
330     salt_princ_s,
331     enctypes[i],
332     - &password,
333     + password,
334     false,
335     false);
336     if (ret) {
337     - DEBUG(1, (__location__ ": Failed to add entry to keytab\n"));
338     + DBG_WARNING("Failed to add entry to keytab\n");
339     goto out;
340     }
341    
342     @@ -399,16 +323,109 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
343     short_princ_s,
344     salt_princ_s,
345     enctypes[i],
346     - &password,
347     + password,
348     false,
349     false);
350     if (ret) {
351     - DEBUG(1, (__location__
352     - ": Failed to add short entry to keytab\n"));
353     + DBG_WARNING("Failed to add short entry to keytab\n");
354     goto out;
355     }
356     }
357     }
358     +out:
359     + return ret;
360     +}
361     +
362     +/**********************************************************************
363     + Adds a single service principal, i.e. 'host' to the system keytab
364     +***********************************************************************/
365     +
366     +int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
367     +{
368     + krb5_error_code ret = 0;
369     + krb5_context context = NULL;
370     + krb5_keytab keytab = NULL;
371     + krb5_data password;
372     + krb5_kvno kvno;
373     + char *salt_princ_s = NULL;
374     + char *password_s = NULL;
375     + char *my_fqdn;
376     + TALLOC_CTX *tmpctx = NULL;
377     +
378     + ret = smb_krb5_init_context_common(&context);
379     + if (ret) {
380     + DBG_ERR("kerberos init context failed (%s)\n",
381     + error_message(ret));
382     + return -1;
383     + }
384     +
385     + ret = ads_keytab_open(context, &keytab);
386     + if (ret != 0) {
387     + goto out;
388     + }
389     +
390     + /* retrieve the password */
391     + if (!secrets_init()) {
392     + DBG_WARNING("secrets_init failed\n");
393     + ret = -1;
394     + goto out;
395     + }
396     + password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
397     + if (!password_s) {
398     + DBG_WARNING("failed to fetch machine password\n");
399     + ret = -1;
400     + goto out;
401     + }
402     + ZERO_STRUCT(password);
403     + password.data = password_s;
404     + password.length = strlen(password_s);
405     +
406     + /* we need the dNSHostName value here */
407     + tmpctx = talloc_init(__location__);
408     + if (!tmpctx) {
409     + DBG_ERR("talloc_init() failed!\n");
410     + ret = -1;
411     + goto out;
412     + }
413     +
414     + my_fqdn = ads_get_dnshostname(ads, tmpctx, lp_netbios_name());
415     + if (!my_fqdn) {
416     + DBG_ERR("unable to determine machine account's dns name in "
417     + "AD!\n");
418     + ret = -1;
419     + goto out;
420     + }
421     +
422     + /* make sure we have a single instance of a the computer account */
423     + if (!ads_has_samaccountname(ads, tmpctx, lp_netbios_name())) {
424     + DBG_ERR("unable to determine machine account's short name in "
425     + "AD!\n");
426     + ret = -1;
427     + goto out;
428     + }
429     +
430     + kvno = (krb5_kvno)ads_get_machine_kvno(ads, lp_netbios_name());
431     + if (kvno == -1) {
432     + /* -1 indicates failure, everything else is OK */
433     + DBG_WARNING("ads_get_machine_kvno failed to determine the "
434     + "system's kvno.\n");
435     + ret = -1;
436     + goto out;
437     + }
438     +
439     + salt_princ_s = kerberos_secrets_fetch_salt_princ();
440     + if (salt_princ_s == NULL) {
441     + DBG_WARNING("kerberos_secrets_fetch_salt_princ() failed\n");
442     + ret = -1;
443     + goto out;
444     + }
445     +
446     + ret = add_kt_entry_etypes(context, tmpctx, ads, salt_princ_s, keytab,
447     + kvno, srvPrinc, my_fqdn, &password,
448     + update_ads);
449     + if (ret != 0) {
450     + goto out;
451     + }
452    
453     out:
454     SAFE_FREE(salt_princ_s);
455     --
456     2.39.0
457    
458    
459     From 087d6dd4c4f25860643ab5920a1b2c0c70e5551b Mon Sep 17 00:00:00 2001
460     From: Isaac Boukris <iboukris@gmail.com>
461     Date: Wed, 27 May 2020 17:55:12 +0200
462     Subject: [PATCH 005/142] Add a test for msDS-AdditionalDnsHostName entries in
463     keytab
464    
465     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
466    
467     Signed-off-by: Isaac Boukris <iboukris@samba.org>
468     Reviewed-by: Andreas Schneider <asn@samba.org>
469     ---
470     selftest/knownfail.d/dns_alias_keytab | 2 ++
471     testprogs/blackbox/test_net_ads.sh | 9 +++++++++
472     2 files changed, 11 insertions(+)
473     create mode 100644 selftest/knownfail.d/dns_alias_keytab
474    
475     diff --git a/selftest/knownfail.d/dns_alias_keytab b/selftest/knownfail.d/dns_alias_keytab
476     new file mode 100644
477     index 00000000000..216592e1210
478     --- /dev/null
479     +++ b/selftest/knownfail.d/dns_alias_keytab
480     @@ -0,0 +1,2 @@
481     +^samba4.blackbox.net_ads.dns alias1 check keytab
482     +^samba4.blackbox.net_ads.dns alias2 check keytab
483     diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh
484     index 6073ea972f9..a40b477a173 100755
485     --- a/testprogs/blackbox/test_net_ads.sh
486     +++ b/testprogs/blackbox/test_net_ads.sh
487     @@ -217,6 +217,15 @@ testit_grep "dns alias SPN" $dns_alias2 $VALGRIND $net_tool ads search -P samacc
488     testit_grep "dns alias addl" $dns_alias1 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ msDS-AdditionalDnsHostName || failed=`expr $failed + 1`
489     testit_grep "dns alias addl" $dns_alias2 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ msDS-AdditionalDnsHostName || failed=`expr $failed + 1`
490    
491     +dedicated_keytab_file="$PREFIX_ABS/test_dns_aliases_dedicated_krb5.keytab"
492     +
493     +testit "dns alias create_keytab" $VALGRIND $net_tool ads keytab create --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
494     +
495     +testit_grep "dns alias1 check keytab" "host/${dns_alias1}@$REALM" $net_tool ads keytab list --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
496     +testit_grep "dns alias2 check keytab" "host/${dns_alias2}@$REALM" $net_tool ads keytab list --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
497     +
498     +rm -f $dedicated_keytab_file
499     +
500     ##Goodbye...
501     testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
502    
503     --
504     2.39.0
505    
506    
507     From 1ae32dddad89cdb75ae2c8fb3e7378ce6f5ad6af Mon Sep 17 00:00:00 2001
508     From: Isaac Boukris <iboukris@gmail.com>
509     Date: Wed, 27 May 2020 15:36:28 +0200
510     Subject: [PATCH 006/142] Add msDS-AdditionalDnsHostName entries to the keytab
511    
512     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
513    
514     Signed-off-by: Isaac Boukris <iboukris@samba.org>
515     Reviewed-by: Andreas Schneider <asn@samba.org>
516     ---
517     selftest/knownfail.d/dns_alias_keytab | 2 --
518     source3/libads/ads_proto.h | 5 +++
519     source3/libads/kerberos_keytab.c | 21 +++++++++++++
520     source3/libads/ldap.c | 45 +++++++++++++++++++++++++++
521     4 files changed, 71 insertions(+), 2 deletions(-)
522     delete mode 100644 selftest/knownfail.d/dns_alias_keytab
523    
524     diff --git a/selftest/knownfail.d/dns_alias_keytab b/selftest/knownfail.d/dns_alias_keytab
525     deleted file mode 100644
526     index 216592e1210..00000000000
527     --- a/selftest/knownfail.d/dns_alias_keytab
528     +++ /dev/null
529     @@ -1,2 +0,0 @@
530     -^samba4.blackbox.net_ads.dns alias1 check keytab
531     -^samba4.blackbox.net_ads.dns alias2 check keytab
532     diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h
533     index 495ef5d3325..cd9c1082681 100644
534     --- a/source3/libads/ads_proto.h
535     +++ b/source3/libads/ads_proto.h
536     @@ -137,6 +137,11 @@ ADS_STATUS ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
537     enum ads_extended_dn_flags flags,
538     struct dom_sid *sid);
539     char* ads_get_dnshostname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name );
540     +ADS_STATUS ads_get_additional_dns_hostnames(TALLOC_CTX *mem_ctx,
541     + ADS_STRUCT *ads,
542     + const char *machine_name,
543     + char ***hostnames_array,
544     + size_t *num_hostnames);
545     char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name );
546     bool ads_has_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name );
547     ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name,
548     diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c
549     index 0f450a09df5..818ec884a03 100644
550     --- a/source3/libads/kerberos_keytab.c
551     +++ b/source3/libads/kerberos_keytab.c
552     @@ -351,6 +351,8 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
553     char *password_s = NULL;
554     char *my_fqdn;
555     TALLOC_CTX *tmpctx = NULL;
556     + char **hostnames_array = NULL;
557     + size_t num_hostnames = 0;
558    
559     ret = smb_krb5_init_context_common(&context);
560     if (ret) {
561     @@ -427,6 +429,25 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
562     goto out;
563     }
564    
565     + if (ADS_ERR_OK(ads_get_additional_dns_hostnames(tmpctx, ads,
566     + lp_netbios_name(),
567     + &hostnames_array,
568     + &num_hostnames))) {
569     + size_t i;
570     +
571     + for (i = 0; i < num_hostnames; i++) {
572     +
573     + ret = add_kt_entry_etypes(context, tmpctx, ads,
574     + salt_princ_s, keytab,
575     + kvno, srvPrinc,
576     + hostnames_array[i],
577     + &password, update_ads);
578     + if (ret != 0) {
579     + goto out;
580     + }
581     + }
582     + }
583     +
584     out:
585     SAFE_FREE(salt_princ_s);
586     TALLOC_FREE(tmpctx);
587     diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
588     index db2b72ab1b5..02a628ee0e6 100644
589     --- a/source3/libads/ldap.c
590     +++ b/source3/libads/ldap.c
591     @@ -1377,6 +1377,7 @@ char *ads_parent_dn(const char *dn)
592     "unicodePwd",
593    
594     /* Additional attributes Samba checks */
595     + "msDS-AdditionalDnsHostName",
596     "msDS-SupportedEncryptionTypes",
597     "nTSecurityDescriptor",
598    
599     @@ -3663,6 +3664,50 @@ out:
600     /********************************************************************
601     ********************************************************************/
602    
603     +ADS_STATUS ads_get_additional_dns_hostnames(TALLOC_CTX *mem_ctx,
604     + ADS_STRUCT *ads,
605     + const char *machine_name,
606     + char ***hostnames_array,
607     + size_t *num_hostnames)
608     +{
609     + ADS_STATUS status;
610     + LDAPMessage *res = NULL;
611     + int count;
612     +
613     + status = ads_find_machine_acct(ads,
614     + &res,
615     + machine_name);
616     + if (!ADS_ERR_OK(status)) {
617     + DEBUG(1,("Host Account for %s not found... skipping operation.\n",
618     + machine_name));
619     + return status;
620     + }
621     +
622     + count = ads_count_replies(ads, res);
623     + if (count != 1) {
624     + status = ADS_ERROR(LDAP_NO_SUCH_OBJECT);
625     + goto done;
626     + }
627     +
628     + *hostnames_array = ads_pull_strings(ads, mem_ctx, res,
629     + "msDS-AdditionalDnsHostName",
630     + num_hostnames);
631     + if (*hostnames_array == NULL) {
632     + DEBUG(1, ("Host account for %s does not have msDS-AdditionalDnsHostName.\n",
633     + machine_name));
634     + status = ADS_ERROR(LDAP_NO_SUCH_OBJECT);
635     + goto done;
636     + }
637     +
638     +done:
639     + ads_msgfree(ads, res);
640     +
641     + return status;
642     +}
643     +
644     +/********************************************************************
645     +********************************************************************/
646     +
647     char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name )
648     {
649     LDAPMessage *res = NULL;
650     --
651     2.39.0
652    
653    
654     From 939b9265a533393189ef3c513e77b2cb009a51d5 Mon Sep 17 00:00:00 2001
655     From: Isaac Boukris <iboukris@gmail.com>
656     Date: Wed, 27 May 2020 15:54:12 +0200
657     Subject: [PATCH 007/142] Add net-ads-join dnshostname=fqdn option
658    
659     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
660    
661     Signed-off-by: Isaac Boukris <iboukris@samba.org>
662     Reviewed-by: Andreas Schneider <asn@samba.org>
663    
664     Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
665     Autobuild-Date(master): Fri May 29 13:33:28 UTC 2020 on sn-devel-184
666     ---
667     docs-xml/manpages/net.8.xml | 7 ++++++-
668     source3/libnet/libnet_join.c | 7 ++++++-
669     source3/librpc/idl/libnet_join.idl | 1 +
670     source3/utils/net_ads.c | 9 ++++++++-
671     testprogs/blackbox/test_net_ads.sh | 15 +++++++++++++++
672     5 files changed, 36 insertions(+), 3 deletions(-)
673    
674     diff --git a/docs-xml/manpages/net.8.xml b/docs-xml/manpages/net.8.xml
675     index 37dfa2af694..69e18df8b6c 100644
676     --- a/docs-xml/manpages/net.8.xml
677     +++ b/docs-xml/manpages/net.8.xml
678     @@ -454,7 +454,7 @@ The remote server must be specified with the -S option.
679    
680     <refsect2>
681     <title>[RPC|ADS] JOIN [TYPE] [--no-dns-updates] [-U username[%password]]
682     -[createupn=UPN] [createcomputer=OU] [machinepass=PASS]
683     +[dnshostname=FQDN] [createupn=UPN] [createcomputer=OU] [machinepass=PASS]
684     [osName=string osVer=string] [options]</title>
685    
686     <para>
687     @@ -469,6 +469,11 @@ be created.</para>
688     joining the domain.
689     </para>
690    
691     +<para>
692     +[FQDN] (ADS only) set the dnsHosName attribute during the join.
693     +The default format is netbiosname.dnsdomain.
694     +</para>
695     +
696     <para>
697     [UPN] (ADS only) set the principalname attribute during the join. The default
698     format is host/netbiosname@REALM.
699     diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
700     index a31011b0ff8..de558be4f91 100644
701     --- a/source3/libnet/libnet_join.c
702     +++ b/source3/libnet/libnet_join.c
703     @@ -546,7 +546,12 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
704     goto done;
705     }
706    
707     - fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name, lp_dnsdomain());
708     + if (r->in.dnshostname != NULL) {
709     + fstr_sprintf(my_fqdn, "%s", r->in.dnshostname);
710     + } else {
711     + fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name,
712     + lp_dnsdomain());
713     + }
714    
715     if (!strlower_m(my_fqdn)) {
716     status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
717     diff --git a/source3/librpc/idl/libnet_join.idl b/source3/librpc/idl/libnet_join.idl
718     index e45034d40da..03d919863b5 100644
719     --- a/source3/librpc/idl/libnet_join.idl
720     +++ b/source3/librpc/idl/libnet_join.idl
721     @@ -37,6 +37,7 @@ interface libnetjoin
722     [in] string os_servicepack,
723     [in] boolean8 create_upn,
724     [in] string upn,
725     + [in] string dnshostname,
726     [in] boolean8 modify_config,
727     [in,unique] ads_struct *ads,
728     [in] boolean8 debug,
729     diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
730     index 07a22098fb1..3cf8fbbf7c8 100644
731     --- a/source3/utils/net_ads.c
732     +++ b/source3/utils/net_ads.c
733     @@ -1710,6 +1710,8 @@ static int net_ads_join_usage(struct net_context *c, int argc, const char **argv
734     {
735     d_printf(_("net ads join [--no-dns-updates] [options]\n"
736     "Valid options:\n"));
737     + d_printf(_(" dnshostname=FQDN Set the dnsHostName attribute during the join.\n"
738     + " The default is in the form netbiosname.dnsdomain\n"));
739     d_printf(_(" createupn[=UPN] Set the userPrincipalName attribute during the join.\n"
740     " The default UPN is in the form host/netbiosname@REALM.\n"));
741     d_printf(_(" createcomputer=OU Precreate the computer account in a specific OU.\n"
742     @@ -1830,6 +1832,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
743     const char *domain = lp_realm();
744     WERROR werr = WERR_NERR_SETUPNOTJOINED;
745     bool createupn = false;
746     + const char *dnshostname = NULL;
747     const char *machineupn = NULL;
748     const char *machine_password = NULL;
749     const char *create_in_ou = NULL;
750     @@ -1870,7 +1873,10 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
751     /* process additional command line args */
752    
753     for ( i=0; i<argc; i++ ) {
754     - if ( !strncasecmp_m(argv[i], "createupn", strlen("createupn")) ) {
755     + if ( !strncasecmp_m(argv[i], "dnshostname", strlen("dnshostname")) ) {
756     + dnshostname = get_string_param(argv[i]);
757     + }
758     + else if ( !strncasecmp_m(argv[i], "createupn", strlen("createupn")) ) {
759     createupn = true;
760     machineupn = get_string_param(argv[i]);
761     }
762     @@ -1938,6 +1944,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
763     r->in.domain_name_type = domain_name_type;
764     r->in.create_upn = createupn;
765     r->in.upn = machineupn;
766     + r->in.dnshostname = dnshostname;
767     r->in.account_ou = create_in_ou;
768     r->in.os_name = os_name;
769     r->in.os_version = os_version;
770     diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh
771     index a40b477a173..85257f445d8 100755
772     --- a/testprogs/blackbox/test_net_ads.sh
773     +++ b/testprogs/blackbox/test_net_ads.sh
774     @@ -277,6 +277,21 @@ rm -f $dedicated_keytab_file
775    
776     testit "leave+createupn" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
777    
778     +#
779     +# Test dnshostname option of 'net ads join'
780     +#
781     +testit "join+dnshostname" $VALGRIND $net_tool ads join -U$DC_USERNAME%$DC_PASSWORD dnshostname="alt.hostname.$HOSTNAME" || failed=`expr $failed + 1`
782     +
783     +testit_grep "check dnshostname opt" "dNSHostName: alt.hostname.$HOSTNAME" $ldbsearch -U$DC_USERNAME%$DC_PASSWORD -H ldap://$SERVER.$REALM -s base -b "CN=$HOSTNAME,CN=Computers,$base_dn" || failed=`expr $failed + 1`
784     +
785     +testit "create_keytab+dnshostname" $VALGRIND $net_tool ads keytab create --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
786     +
787     +testit_grep "check dnshostname+keytab" "host/alt.hostname.$HOSTNAME@$REALM" $net_tool ads keytab list --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
788     +
789     +rm -f $dedicated_keytab_file
790     +
791     +testit "leave+dnshostname" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
792     +
793     rm -rf $BASEDIR/$WORKDIR
794    
795     exit $failed
796     --
797     2.39.0
798    
799    
800     From 25a6679a5260dafde7a7d2aed9bfe43eaf083b1c Mon Sep 17 00:00:00 2001
801     From: Stefan Metzmacher <metze@samba.org>
802     Date: Wed, 16 Sep 2020 16:04:57 +0200
803     Subject: [PATCH 008/142] CVE-2020-1472(ZeroLogon): libcli/auth: add
804     netlogon_creds_random_challenge()
805    
806     It's good to have just a single isolated function that will generate
807     random challenges, in future we can add some logic in order to
808     avoid weak values, which are likely to be rejected by a server.
809    
810     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
811    
812     Signed-off-by: Stefan Metzmacher <metze@samba.org>
813     ---
814     libcli/auth/credentials.c | 8 ++++++++
815     libcli/auth/proto.h | 2 ++
816     2 files changed, 10 insertions(+)
817    
818     diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c
819     index b6c8ba281ba..dbbef9e7a3c 100644
820     --- a/libcli/auth/credentials.c
821     +++ b/libcli/auth/credentials.c
822     @@ -26,9 +26,17 @@
823     #include "libcli/auth/libcli_auth.h"
824     #include "../libcli/security/dom_sid.h"
825    
826     +
827     +void netlogon_creds_random_challenge(struct netr_Credential *challenge)
828     +{
829     + ZERO_STRUCTP(challenge);
830     + generate_random_buffer(challenge->data, sizeof(challenge->data));
831     +}
832     +
833     static void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *creds,
834     const struct netr_Credential *in,
835     struct netr_Credential *out)
836     +
837     {
838     if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
839     AES_KEY key;
840     diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h
841     index 82febe74440..82797d453ed 100644
842     --- a/libcli/auth/proto.h
843     +++ b/libcli/auth/proto.h
844     @@ -11,6 +11,8 @@
845    
846     /* The following definitions come from /home/jeremy/src/samba/git/master/source3/../source4/../libcli/auth/credentials.c */
847    
848     +void netlogon_creds_random_challenge(struct netr_Credential *challenge);
849     +
850     void netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key);
851     void netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key);
852     void netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass);
853     --
854     2.39.0
855    
856    
857     From 1e8ad7efe35d8b79fef387ff709d6a499565c39a Mon Sep 17 00:00:00 2001
858     From: Stefan Metzmacher <metze@samba.org>
859     Date: Wed, 16 Sep 2020 16:07:30 +0200
860     Subject: [PATCH 009/142] CVE-2020-1472(ZeroLogon): s4:torture/rpc: make use of
861     netlogon_creds_random_challenge()
862    
863     This will avoid getting flakey tests once our server starts to
864     reject weak challenges.
865    
866     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
867    
868     Signed-off-by: Stefan Metzmacher <metze@samba.org>
869     ---
870     source4/torture/rpc/lsa.c | 2 +-
871     source4/torture/rpc/netlogon.c | 34 ++++++++++++----------------------
872     2 files changed, 13 insertions(+), 23 deletions(-)
873    
874     diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c
875     index 21cc16afbaf..7bdc0cf679a 100644
876     --- a/source4/torture/rpc/lsa.c
877     +++ b/source4/torture/rpc/lsa.c
878     @@ -2847,7 +2847,7 @@ static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
879     r.in.credentials = &credentials1;
880     r.out.return_credentials = &credentials2;
881    
882     - generate_random_buffer(credentials1.data, sizeof(credentials1.data));
883     + netlogon_creds_random_challenge(&credentials1);
884    
885     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
886     "ServerReqChallenge failed");
887     diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
888     index 026d86d50e4..e11014922f8 100644
889     --- a/source4/torture/rpc/netlogon.c
890     +++ b/source4/torture/rpc/netlogon.c
891     @@ -160,7 +160,7 @@ bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
892     r.in.credentials = &credentials1;
893     r.out.return_credentials = &credentials2;
894    
895     - generate_random_buffer(credentials1.data, sizeof(credentials1.data));
896     + netlogon_creds_random_challenge(&credentials1);
897    
898     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
899     "ServerReqChallenge failed");
900     @@ -229,7 +229,7 @@ bool test_SetupCredentials2ex(struct dcerpc_pipe *p, struct torture_context *tct
901     r.in.credentials = &credentials1;
902     r.out.return_credentials = &credentials2;
903    
904     - generate_random_buffer(credentials1.data, sizeof(credentials1.data));
905     + netlogon_creds_random_challenge(&credentials1);
906    
907     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
908     "ServerReqChallenge failed");
909     @@ -318,7 +318,7 @@ bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
910     r.in.credentials = &credentials1;
911     r.out.return_credentials = &credentials2;
912    
913     - generate_random_buffer(credentials1.data, sizeof(credentials1.data));
914     + netlogon_creds_random_challenge(&credentials1);
915    
916     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
917     "ServerReqChallenge failed");
918     @@ -390,7 +390,7 @@ bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
919     r.in.credentials = &credentials1;
920     r.out.return_credentials = &credentials2;
921    
922     - generate_random_buffer(credentials1.data, sizeof(credentials1.data));
923     + netlogon_creds_random_challenge(&credentials1);
924    
925     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
926     "ServerReqChallenge failed");
927     @@ -1278,7 +1278,7 @@ static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
928     r.in.credentials = &credentials1;
929     r.out.return_credentials = &credentials2;
930    
931     - generate_random_buffer(credentials1.data, sizeof(credentials1.data));
932     + netlogon_creds_random_challenge(&credentials1);
933    
934     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
935     "ServerReqChallenge failed on b1");
936     @@ -1367,7 +1367,7 @@ static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
937     r.in.credentials = &credentials1;
938     r.out.return_credentials = &credentials2;
939    
940     - generate_random_buffer(credentials1.data, sizeof(credentials1.data));
941     + netlogon_creds_random_challenge(&credentials1);
942    
943     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
944     "ServerReqChallenge failed on b1");
945     @@ -1456,7 +1456,7 @@ static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
946     r.in.credentials = &credentials1;
947     r.out.return_credentials = &credentials2;
948    
949     - generate_random_buffer(credentials1.data, sizeof(credentials1.data));
950     + netlogon_creds_random_challenge(&credentials1);
951    
952     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
953     "ServerReqChallenge failed on b1");
954     @@ -1546,7 +1546,7 @@ static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx,
955     r.in.credentials = &credentials1;
956     r.out.return_credentials = &credentials2;
957    
958     - generate_random_buffer(credentials1.data, sizeof(credentials1.data));
959     + netlogon_creds_random_challenge(&credentials1);
960    
961     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
962     "ServerReqChallenge failed on b1");
963     @@ -1638,8 +1638,7 @@ static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
964     r.in.credentials = &credentials1_random;
965     r.out.return_credentials = &credentials_discard;
966    
967     - generate_random_buffer(credentials1_random.data,
968     - sizeof(credentials1_random.data));
969     + netlogon_creds_random_challenge(&credentials1_random);
970    
971     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
972     "ServerReqChallenge failed on b1");
973     @@ -1651,7 +1650,7 @@ static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
974     r.in.credentials = &credentials1;
975     r.out.return_credentials = &credentials2;
976    
977     - generate_random_buffer(credentials1.data, sizeof(credentials1.data));
978     + netlogon_creds_random_challenge(&credentials1);
979    
980     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
981     "ServerReqChallenge failed on b1");
982     @@ -1662,16 +1661,7 @@ static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
983     r.in.credentials = &credentials1_random;
984     r.out.return_credentials = &credentials_discard;
985    
986     - generate_random_buffer(credentials1_random.data,
987     - sizeof(credentials1_random.data));
988     -
989     - r.in.server_name = NULL;
990     - r.in.computer_name = "CHALTEST3";
991     - r.in.credentials = &credentials1_random;
992     - r.out.return_credentials = &credentials_discard;
993     -
994     - generate_random_buffer(credentials1_random.data,
995     - sizeof(credentials1_random.data));
996     + netlogon_creds_random_challenge(&credentials1_random);
997    
998     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
999     "ServerReqChallenge failed on b1");
1000     @@ -1747,7 +1737,7 @@ static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
1001     r.in.credentials = &credentials1;
1002     r.out.return_credentials = &credentials2;
1003    
1004     - generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1005     + netlogon_creds_random_challenge(&credentials1);
1006    
1007     torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
1008     "ServerReqChallenge");
1009     --
1010     2.39.0
1011    
1012    
1013     From 74ee204ad4647d0d7a2097124652cbcd43406c7d Mon Sep 17 00:00:00 2001
1014     From: Stefan Metzmacher <metze@samba.org>
1015     Date: Wed, 16 Sep 2020 16:08:38 +0200
1016     Subject: [PATCH 010/142] CVE-2020-1472(ZeroLogon): libcli/auth: make use of
1017     netlogon_creds_random_challenge() in netlogon_creds_cli.c
1018    
1019     This will avoid getting rejected by the server if we generate
1020     a weak challenge.
1021    
1022     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1023    
1024     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1025     ---
1026     libcli/auth/netlogon_creds_cli.c | 3 +--
1027     1 file changed, 1 insertion(+), 2 deletions(-)
1028    
1029     diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
1030     index 817d2cd041a..0f6ca11ff96 100644
1031     --- a/libcli/auth/netlogon_creds_cli.c
1032     +++ b/libcli/auth/netlogon_creds_cli.c
1033     @@ -1177,8 +1177,7 @@ static void netlogon_creds_cli_auth_challenge_start(struct tevent_req *req)
1034    
1035     TALLOC_FREE(state->creds);
1036    
1037     - generate_random_buffer(state->client_challenge.data,
1038     - sizeof(state->client_challenge.data));
1039     + netlogon_creds_random_challenge(&state->client_challenge);
1040    
1041     subreq = dcerpc_netr_ServerReqChallenge_send(state, state->ev,
1042     state->binding_handle,
1043     --
1044     2.39.0
1045    
1046    
1047     From 10196846d019d0e2ccef51f32ddd39fc17ca60aa Mon Sep 17 00:00:00 2001
1048     From: Stefan Metzmacher <metze@samba.org>
1049     Date: Wed, 16 Sep 2020 16:10:53 +0200
1050     Subject: [PATCH 011/142] CVE-2020-1472(ZeroLogon): s3:rpc_server:netlogon:
1051     make use of netlogon_creds_random_challenge()
1052    
1053     This is not strictly needed, but makes things more clear.
1054    
1055     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1056    
1057     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1058     ---
1059     source3/rpc_server/netlogon/srv_netlog_nt.c | 3 +--
1060     1 file changed, 1 insertion(+), 2 deletions(-)
1061    
1062     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
1063     index 87613b99fde..86b2f343e82 100644
1064     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
1065     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
1066     @@ -840,8 +840,7 @@ NTSTATUS _netr_ServerReqChallenge(struct pipes_struct *p,
1067    
1068     pipe_state->client_challenge = *r->in.credentials;
1069    
1070     - generate_random_buffer(pipe_state->server_challenge.data,
1071     - sizeof(pipe_state->server_challenge.data));
1072     + netlogon_creds_random_challenge(&pipe_state->server_challenge);
1073    
1074     *r->out.return_credentials = pipe_state->server_challenge;
1075    
1076     --
1077     2.39.0
1078    
1079    
1080     From 215aca6d11b900ee3cf11568d27bce77e0567653 Mon Sep 17 00:00:00 2001
1081     From: Stefan Metzmacher <metze@samba.org>
1082     Date: Wed, 16 Sep 2020 16:10:53 +0200
1083     Subject: [PATCH 012/142] CVE-2020-1472(ZeroLogon): s4:rpc_server:netlogon:
1084     make use of netlogon_creds_random_challenge()
1085    
1086     This is not strictly needed, but makes things more clear.
1087    
1088     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1089    
1090     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1091     ---
1092     source4/rpc_server/netlogon/dcerpc_netlogon.c | 3 +--
1093     1 file changed, 1 insertion(+), 2 deletions(-)
1094    
1095     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
1096     index 023adfd99e9..de260d8051d 100644
1097     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
1098     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
1099     @@ -90,8 +90,7 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal
1100    
1101     pipe_state->client_challenge = *r->in.credentials;
1102    
1103     - generate_random_buffer(pipe_state->server_challenge.data,
1104     - sizeof(pipe_state->server_challenge.data));
1105     + netlogon_creds_random_challenge(&pipe_state->server_challenge);
1106    
1107     *r->out.return_credentials = pipe_state->server_challenge;
1108    
1109     --
1110     2.39.0
1111    
1112    
1113     From 4551bf623426e8c543b287807d447feb69bb0f09 Mon Sep 17 00:00:00 2001
1114     From: Stefan Metzmacher <metze@samba.org>
1115     Date: Wed, 16 Sep 2020 16:15:26 +0200
1116     Subject: [PATCH 013/142] CVE-2020-1472(ZeroLogon): libcli/auth: add
1117     netlogon_creds_is_random_challenge() to avoid weak values
1118    
1119     This is the check Windows is using, so we won't generate challenges,
1120     which are rejected by Windows DCs (and future Samba DCs).
1121    
1122     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1123    
1124     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1125     ---
1126     libcli/auth/credentials.c | 23 ++++++++++++++++++++++-
1127     libcli/auth/proto.h | 1 +
1128     2 files changed, 23 insertions(+), 1 deletion(-)
1129    
1130     diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c
1131     index dbbef9e7a3c..64b424c099f 100644
1132     --- a/libcli/auth/credentials.c
1133     +++ b/libcli/auth/credentials.c
1134     @@ -27,10 +27,31 @@
1135     #include "../libcli/security/dom_sid.h"
1136    
1137    
1138     +bool netlogon_creds_is_random_challenge(const struct netr_Credential *challenge)
1139     +{
1140     + /*
1141     + * If none of the first 5 bytes of the client challenge is unique, the
1142     + * server MUST fail session-key negotiation without further processing
1143     + * of the following steps.
1144     + */
1145     +
1146     + if (challenge->data[1] == challenge->data[0] &&
1147     + challenge->data[2] == challenge->data[0] &&
1148     + challenge->data[3] == challenge->data[0] &&
1149     + challenge->data[4] == challenge->data[0])
1150     + {
1151     + return false;
1152     + }
1153     +
1154     + return true;
1155     +}
1156     +
1157     void netlogon_creds_random_challenge(struct netr_Credential *challenge)
1158     {
1159     ZERO_STRUCTP(challenge);
1160     - generate_random_buffer(challenge->data, sizeof(challenge->data));
1161     + while (!netlogon_creds_is_random_challenge(challenge)) {
1162     + generate_random_buffer(challenge->data, sizeof(challenge->data));
1163     + }
1164     }
1165    
1166     static void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *creds,
1167     diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h
1168     index 82797d453ed..ad768682b9f 100644
1169     --- a/libcli/auth/proto.h
1170     +++ b/libcli/auth/proto.h
1171     @@ -11,6 +11,7 @@
1172    
1173     /* The following definitions come from /home/jeremy/src/samba/git/master/source3/../source4/../libcli/auth/credentials.c */
1174    
1175     +bool netlogon_creds_is_random_challenge(const struct netr_Credential *challenge);
1176     void netlogon_creds_random_challenge(struct netr_Credential *challenge);
1177    
1178     void netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key);
1179     --
1180     2.39.0
1181    
1182    
1183     From f7e09421ace8fe60c0110770d909800d21ae6c8e Mon Sep 17 00:00:00 2001
1184     From: Stefan Metzmacher <metze@samba.org>
1185     Date: Wed, 16 Sep 2020 16:17:29 +0200
1186     Subject: [PATCH 014/142] CVE-2020-1472(ZeroLogon): libcli/auth: reject weak
1187     client challenges in netlogon_creds_server_init()
1188    
1189     This implements the note from MS-NRPC 3.1.4.1 Session-Key Negotiation:
1190    
1191     7. If none of the first 5 bytes of the client challenge is unique, the
1192     server MUST fail session-key negotiation without further processing of
1193     the following steps.
1194    
1195     It lets ./zerologon_tester.py from
1196     https://github.com/SecuraBV/CVE-2020-1472.git
1197     report: "Attack failed. Target is probably patched."
1198    
1199     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1200    
1201     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1202    
1203     [dbagnall@samba.org, abartlet@samba.org: wscript_build backport
1204     differs because 4.10 has no gnutls dependency]
1205     ---
1206     libcli/auth/credentials.c | 16 ++++++++++++++++
1207     libcli/auth/wscript_build | 2 +-
1208     2 files changed, 17 insertions(+), 1 deletion(-)
1209    
1210     diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c
1211     index 64b424c099f..e2bc82809b7 100644
1212     --- a/libcli/auth/credentials.c
1213     +++ b/libcli/auth/credentials.c
1214     @@ -25,6 +25,7 @@
1215     #include "../lib/crypto/crypto.h"
1216     #include "libcli/auth/libcli_auth.h"
1217     #include "../libcli/security/dom_sid.h"
1218     +#include "lib/util/util_str_escape.h"
1219    
1220    
1221     bool netlogon_creds_is_random_challenge(const struct netr_Credential *challenge)
1222     @@ -451,6 +452,7 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me
1223     {
1224    
1225     struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState);
1226     + bool ok;
1227    
1228     if (!creds) {
1229     return NULL;
1230     @@ -463,6 +465,20 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me
1231     dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data));
1232     dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash));
1233    
1234     + ok = netlogon_creds_is_random_challenge(client_challenge);
1235     + if (!ok) {
1236     + DBG_WARNING("CVE-2020-1472(ZeroLogon): "
1237     + "non-random client challenge rejected for "
1238     + "client_account[%s] client_computer_name[%s]\n",
1239     + log_escape(mem_ctx, client_account),
1240     + log_escape(mem_ctx, client_computer_name));
1241     + dump_data(DBGLVL_WARNING,
1242     + client_challenge->data,
1243     + sizeof(client_challenge->data));
1244     + talloc_free(creds);
1245     + return NULL;
1246     + }
1247     +
1248     creds->computer_name = talloc_strdup(creds, client_computer_name);
1249     if (!creds->computer_name) {
1250     talloc_free(creds);
1251     diff --git a/libcli/auth/wscript_build b/libcli/auth/wscript_build
1252     index d319d9b879e..394505d166d 100644
1253     --- a/libcli/auth/wscript_build
1254     +++ b/libcli/auth/wscript_build
1255     @@ -18,7 +18,7 @@ bld.SAMBA_SUBSYSTEM('NTLM_CHECK',
1256    
1257     bld.SAMBA_SUBSYSTEM('LIBCLI_AUTH',
1258     source='credentials.c session.c smbencrypt.c smbdes.c',
1259     - public_deps='MSRPC_PARSE',
1260     + public_deps='MSRPC_PARSE util_str_escape',
1261     public_headers='credentials.h:domain_credentials.h'
1262     )
1263    
1264     --
1265     2.39.0
1266    
1267    
1268     From 6bc86fb69bf50c89a334fd2dcbce6999a2360fb7 Mon Sep 17 00:00:00 2001
1269     From: Stefan Metzmacher <metze@samba.org>
1270     Date: Wed, 16 Sep 2020 19:20:25 +0200
1271     Subject: [PATCH 015/142] CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon:
1272     protect netr_ServerPasswordSet2 against unencrypted passwords
1273    
1274     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1275    
1276     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1277     ---
1278     source4/rpc_server/netlogon/dcerpc_netlogon.c | 60 ++++++++++++++++++-
1279     1 file changed, 59 insertions(+), 1 deletion(-)
1280    
1281     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
1282     index de260d8051d..acbf077c6c7 100644
1283     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
1284     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
1285     @@ -722,7 +722,10 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
1286     struct NL_PASSWORD_VERSION version = {};
1287     const uint32_t *new_version = NULL;
1288     NTSTATUS nt_status;
1289     - DATA_BLOB new_password;
1290     + DATA_BLOB new_password = data_blob_null;
1291     + size_t confounder_len;
1292     + DATA_BLOB dec_blob = data_blob_null;
1293     + DATA_BLOB enc_blob = data_blob_null;
1294     int ret;
1295     struct samr_CryptPassword password_buf;
1296    
1297     @@ -780,6 +783,61 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
1298     return NT_STATUS_WRONG_PASSWORD;
1299     }
1300    
1301     + /*
1302     + * Make sure the length field was encrypted,
1303     + * otherwise we are under attack.
1304     + */
1305     + if (new_password.length == r->in.new_password->length) {
1306     + DBG_WARNING("Length[%zu] field not encrypted\n",
1307     + new_password.length);
1308     + return NT_STATUS_WRONG_PASSWORD;
1309     + }
1310     +
1311     + /*
1312     + * We don't allow empty passwords for machine accounts.
1313     + */
1314     + if (new_password.length < 2) {
1315     + DBG_WARNING("Empty password Length[%zu]\n",
1316     + new_password.length);
1317     + return NT_STATUS_WRONG_PASSWORD;
1318     + }
1319     +
1320     + /*
1321     + * Make sure the confounder part of CryptPassword
1322     + * buffer was encrypted, otherwise we are under attack.
1323     + */
1324     + confounder_len = 512 - new_password.length;
1325     + enc_blob = data_blob_const(r->in.new_password->data, confounder_len);
1326     + dec_blob = data_blob_const(password_buf.data, confounder_len);
1327     + if (data_blob_cmp(&dec_blob, &enc_blob) == 0) {
1328     + DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n",
1329     + confounder_len);
1330     + return NT_STATUS_WRONG_PASSWORD;
1331     + }
1332     +
1333     + /*
1334     + * Check that the password part was actually encrypted,
1335     + * otherwise we are under attack.
1336     + */
1337     + enc_blob = data_blob_const(r->in.new_password->data + confounder_len,
1338     + new_password.length);
1339     + dec_blob = data_blob_const(password_buf.data + confounder_len,
1340     + new_password.length);
1341     + if (data_blob_cmp(&dec_blob, &enc_blob) == 0) {
1342     + DBG_WARNING("Password buffer not encrypted Length[%zu]\n",
1343     + new_password.length);
1344     + return NT_STATUS_WRONG_PASSWORD;
1345     + }
1346     +
1347     + /*
1348     + * don't allow zero buffers
1349     + */
1350     + if (all_zero(new_password.data, new_password.length)) {
1351     + DBG_WARNING("Password zero buffer Length[%zu]\n",
1352     + new_password.length);
1353     + return NT_STATUS_WRONG_PASSWORD;
1354     + }
1355     +
1356     /* fetch the old password hashes (at least one of both has to exist) */
1357    
1358     ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
1359     --
1360     2.39.0
1361    
1362    
1363     From 1f8dec1cbb37f3406d999425590f8a923586ccac Mon Sep 17 00:00:00 2001
1364     From: Jeremy Allison <jra@samba.org>
1365     Date: Wed, 16 Sep 2020 12:53:50 -0700
1366     Subject: [PATCH 016/142] CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon:
1367     protect netr_ServerPasswordSet2 against unencrypted passwords
1368    
1369     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1370    
1371     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
1372    
1373     Signed-off-by: Jeremy Allison <jra@samba.org>
1374     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1375     ---
1376     source3/rpc_server/netlogon/srv_netlog_nt.c | 98 +++++++++++++++++++--
1377     1 file changed, 92 insertions(+), 6 deletions(-)
1378    
1379     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
1380     index 86b2f343e82..fd9127b386f 100644
1381     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
1382     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
1383     @@ -1326,9 +1326,14 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
1384     {
1385     NTSTATUS status;
1386     struct netlogon_creds_CredentialState *creds = NULL;
1387     - DATA_BLOB plaintext;
1388     + DATA_BLOB plaintext = data_blob_null;
1389     + DATA_BLOB new_password = data_blob_null;
1390     + size_t confounder_len;
1391     + DATA_BLOB dec_blob = data_blob_null;
1392     + DATA_BLOB enc_blob = data_blob_null;
1393     struct samr_CryptPassword password_buf;
1394     struct _samr_Credentials_t cr = { CRED_TYPE_PLAIN_TEXT, {0}};
1395     + bool ok;
1396    
1397     become_root();
1398     status = netr_creds_server_step_check(p, p->mem_ctx,
1399     @@ -1364,18 +1369,99 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
1400     netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1401     }
1402    
1403     - if (!decode_pw_buffer(p->mem_ctx,
1404     - password_buf.data,
1405     - (char**) &plaintext.data,
1406     - &plaintext.length,
1407     - CH_UTF16)) {
1408     + if (!extract_pw_from_buffer(p->mem_ctx, password_buf.data, &new_password)) {
1409     DEBUG(2,("_netr_ServerPasswordSet2: unable to extract password "
1410     "from a buffer. Rejecting auth request as a wrong password\n"));
1411     TALLOC_FREE(creds);
1412     return NT_STATUS_WRONG_PASSWORD;
1413     }
1414    
1415     + /*
1416     + * Make sure the length field was encrypted,
1417     + * otherwise we are under attack.
1418     + */
1419     + if (new_password.length == r->in.new_password->length) {
1420     + DBG_WARNING("Length[%zu] field not encrypted\n",
1421     + new_password.length);
1422     + TALLOC_FREE(creds);
1423     + return NT_STATUS_WRONG_PASSWORD;
1424     + }
1425     +
1426     + /*
1427     + * We don't allow empty passwords for machine accounts.
1428     + */
1429     + if (new_password.length < 2) {
1430     + DBG_WARNING("Empty password Length[%zu]\n",
1431     + new_password.length);
1432     + TALLOC_FREE(creds);
1433     + return NT_STATUS_WRONG_PASSWORD;
1434     + }
1435     +
1436     + /*
1437     + * Make sure the confounder part of CryptPassword
1438     + * buffer was encrypted, otherwise we are under attack.
1439     + */
1440     + confounder_len = 512 - new_password.length;
1441     + enc_blob = data_blob_const(r->in.new_password->data, confounder_len);
1442     + dec_blob = data_blob_const(password_buf.data, confounder_len);
1443     + if (data_blob_cmp(&dec_blob, &enc_blob) == 0) {
1444     + DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n",
1445     + confounder_len);
1446     + TALLOC_FREE(creds);
1447     + return NT_STATUS_WRONG_PASSWORD;
1448     + }
1449     +
1450     + /*
1451     + * Check that the password part was actually encrypted,
1452     + * otherwise we are under attack.
1453     + */
1454     + enc_blob = data_blob_const(r->in.new_password->data + confounder_len,
1455     + new_password.length);
1456     + dec_blob = data_blob_const(password_buf.data + confounder_len,
1457     + new_password.length);
1458     + if (data_blob_cmp(&dec_blob, &enc_blob) == 0) {
1459     + DBG_WARNING("Password buffer not encrypted Length[%zu]\n",
1460     + new_password.length);
1461     + TALLOC_FREE(creds);
1462     + return NT_STATUS_WRONG_PASSWORD;
1463     + }
1464     +
1465     + /*
1466     + * don't allow zero buffers
1467     + */
1468     + if (all_zero(new_password.data, new_password.length)) {
1469     + DBG_WARNING("Password zero buffer Length[%zu]\n",
1470     + new_password.length);
1471     + TALLOC_FREE(creds);
1472     + return NT_STATUS_WRONG_PASSWORD;
1473     + }
1474     +
1475     + /* Convert from UTF16 -> plaintext. */
1476     + ok = convert_string_talloc(p->mem_ctx,
1477     + CH_UTF16,
1478     + CH_UNIX,
1479     + new_password.data,
1480     + new_password.length,
1481     + (void *)&plaintext.data,
1482     + &plaintext.length);
1483     + if (!ok) {
1484     + DBG_WARNING("unable to extract password from a buffer. "
1485     + "Rejecting auth request as a wrong password\n");
1486     + TALLOC_FREE(creds);
1487     + return NT_STATUS_WRONG_PASSWORD;
1488     + }
1489     +
1490     + /*
1491     + * We don't allow empty passwords for machine accounts.
1492     + */
1493     +
1494     cr.creds.password = (const char*) plaintext.data;
1495     + if (strlen(cr.creds.password) == 0) {
1496     + DBG_WARNING("Empty plaintext password\n");
1497     + TALLOC_FREE(creds);
1498     + return NT_STATUS_WRONG_PASSWORD;
1499     + }
1500     +
1501     status = netr_set_machine_account_password(p->mem_ctx,
1502     p->session_info,
1503     p->msg_ctx,
1504     --
1505     2.39.0
1506    
1507    
1508     From 2ad269be74481789ded62a3dcb538709c6d6e291 Mon Sep 17 00:00:00 2001
1509     From: Stefan Metzmacher <metze@samba.org>
1510     Date: Wed, 16 Sep 2020 10:18:45 +0200
1511     Subject: [PATCH 017/142] CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon:
1512     refactor dcesrv_netr_creds_server_step_check()
1513    
1514     We should debug more details about the failing request.
1515    
1516     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1517    
1518     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1519     ---
1520     source4/rpc_server/netlogon/dcerpc_netlogon.c | 45 ++++++++++++++-----
1521     1 file changed, 33 insertions(+), 12 deletions(-)
1522    
1523     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
1524     index acbf077c6c7..b4326a4ecaa 100644
1525     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
1526     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
1527     @@ -623,26 +623,47 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
1528     NTSTATUS nt_status;
1529     int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx);
1530     bool schannel_global_required = (schannel == true);
1531     + struct netlogon_creds_CredentialState *creds = NULL;
1532     + enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1533     + uint16_t opnum = dce_call->pkt.u.request.opnum;
1534     + const char *opname = "<unknown>";
1535    
1536     - if (schannel_global_required) {
1537     - enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1538     -
1539     - dcesrv_call_auth_info(dce_call, &auth_type, NULL);
1540     -
1541     - if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1542     - DBG_ERR("[%s] is not using schannel\n",
1543     - computer_name);
1544     - return NT_STATUS_ACCESS_DENIED;
1545     - }
1546     + if (opnum < ndr_table_netlogon.num_calls) {
1547     + opname = ndr_table_netlogon.calls[opnum].name;
1548     }
1549    
1550     + dcesrv_call_auth_info(dce_call, &auth_type, NULL);
1551     +
1552     nt_status = schannel_check_creds_state(mem_ctx,
1553     dce_call->conn->dce_ctx->lp_ctx,
1554     computer_name,
1555     received_authenticator,
1556     return_authenticator,
1557     - creds_out);
1558     - return nt_status;
1559     + &creds);
1560     + if (!NT_STATUS_IS_OK(nt_status)) {
1561     + ZERO_STRUCTP(return_authenticator);
1562     + return nt_status;
1563     + }
1564     +
1565     + if (schannel_global_required) {
1566     + if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1567     + *creds_out = creds;
1568     + return NT_STATUS_OK;
1569     + }
1570     +
1571     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
1572     + "%s request (opnum[%u]) without schannel from "
1573     + "client_account[%s] client_computer_name[%s]\n",
1574     + opname, opnum,
1575     + log_escape(mem_ctx, creds->account_name),
1576     + log_escape(mem_ctx, creds->computer_name));
1577     + TALLOC_FREE(creds);
1578     + ZERO_STRUCTP(return_authenticator);
1579     + return NT_STATUS_ACCESS_DENIED;
1580     + }
1581     +
1582     + *creds_out = creds;
1583     + return NT_STATUS_OK;
1584     }
1585    
1586     /*
1587     --
1588     2.39.0
1589    
1590    
1591     From 57941290adb9a2fd4be9aa4a70f879a684b38dfd Mon Sep 17 00:00:00 2001
1592     From: Stefan Metzmacher <metze@samba.org>
1593     Date: Wed, 16 Sep 2020 10:56:53 +0200
1594     Subject: [PATCH 018/142] CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon:
1595     support "server require schannel:WORKSTATION$ = no"
1596    
1597     This allows to add expections for individual workstations, when using "server schannel = yes".
1598     "server schannel = auto" is very insecure and will be removed soon.
1599    
1600     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1601    
1602     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1603     ---
1604     source4/rpc_server/netlogon/dcerpc_netlogon.c | 9 ++++++++-
1605     1 file changed, 8 insertions(+), 1 deletion(-)
1606    
1607     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
1608     index b4326a4ecaa..e7bafb31e83 100644
1609     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
1610     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
1611     @@ -623,6 +623,7 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
1612     NTSTATUS nt_status;
1613     int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx);
1614     bool schannel_global_required = (schannel == true);
1615     + bool schannel_required = schannel_global_required;
1616     struct netlogon_creds_CredentialState *creds = NULL;
1617     enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1618     uint16_t opnum = dce_call->pkt.u.request.opnum;
1619     @@ -645,7 +646,13 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
1620     return nt_status;
1621     }
1622    
1623     - if (schannel_global_required) {
1624     + schannel_required = lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx,
1625     + NULL,
1626     + "server require schannel",
1627     + creds->account_name,
1628     + schannel_global_required);
1629     +
1630     + if (schannel_required) {
1631     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1632     *creds_out = creds;
1633     return NT_STATUS_OK;
1634     --
1635     2.39.0
1636    
1637    
1638     From 779b37e825fe406892ff77be18c098d314cd387d Mon Sep 17 00:00:00 2001
1639     From: Stefan Metzmacher <metze@samba.org>
1640     Date: Thu, 17 Sep 2020 13:37:26 +0200
1641     Subject: [PATCH 019/142] CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: log
1642     warnings about unsecure configurations
1643     MIME-Version: 1.0
1644     Content-Type: text/plain; charset=UTF-8
1645     Content-Transfer-Encoding: 8bit
1646    
1647     This should give admins wawrnings until they have a secure
1648     configuration.
1649    
1650     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1651    
1652     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1653     Reviewed-by: Ralph Boehme <slow@samba.org>
1654     Reviewed-by: Günther Deschner <gd@samba.org>
1655     ---
1656     source4/rpc_server/netlogon/dcerpc_netlogon.c | 66 ++++++++++++++++++-
1657     1 file changed, 63 insertions(+), 3 deletions(-)
1658    
1659     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
1660     index e7bafb31e83..7668a9eb923 100644
1661     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
1662     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
1663     @@ -624,10 +624,12 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
1664     int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx);
1665     bool schannel_global_required = (schannel == true);
1666     bool schannel_required = schannel_global_required;
1667     + const char *explicit_opt = NULL;
1668     struct netlogon_creds_CredentialState *creds = NULL;
1669     enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1670     uint16_t opnum = dce_call->pkt.u.request.opnum;
1671     const char *opname = "<unknown>";
1672     + static bool warned_global_once = false;
1673    
1674     if (opnum < ndr_table_netlogon.num_calls) {
1675     opname = ndr_table_netlogon.calls[opnum].name;
1676     @@ -646,11 +648,18 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
1677     return nt_status;
1678     }
1679    
1680     - schannel_required = lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx,
1681     + /*
1682     + * We don't use lpcfg_parm_bool(), as we
1683     + * need the explicit_opt pointer in order to
1684     + * adjust the debug messages.
1685     + */
1686     + explicit_opt = lpcfg_get_parametric(dce_call->conn->dce_ctx->lp_ctx,
1687     NULL,
1688     "server require schannel",
1689     - creds->account_name,
1690     - schannel_global_required);
1691     + creds->account_name);
1692     + if (explicit_opt != NULL) {
1693     + schannel_required = lp_bool(explicit_opt);
1694     + }
1695    
1696     if (schannel_required) {
1697     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1698     @@ -664,11 +673,62 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
1699     opname, opnum,
1700     log_escape(mem_ctx, creds->account_name),
1701     log_escape(mem_ctx, creds->computer_name));
1702     + DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
1703     + "'server require schannel:%s = no' is needed! \n",
1704     + log_escape(mem_ctx, creds->account_name));
1705     TALLOC_FREE(creds);
1706     ZERO_STRUCTP(return_authenticator);
1707     return NT_STATUS_ACCESS_DENIED;
1708     }
1709    
1710     + if (!schannel_global_required && !warned_global_once) {
1711     + /*
1712     + * We want admins to notice their misconfiguration!
1713     + */
1714     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
1715     + "Please configure 'server schannel = yes', "
1716     + "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n");
1717     + warned_global_once = true;
1718     + }
1719     +
1720     + if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1721     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
1722     + "%s request (opnum[%u]) WITH schannel from "
1723     + "client_account[%s] client_computer_name[%s]\n",
1724     + opname, opnum,
1725     + log_escape(mem_ctx, creds->account_name),
1726     + log_escape(mem_ctx, creds->computer_name));
1727     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
1728     + "Option 'server require schannel:%s = no' not needed!?\n",
1729     + log_escape(mem_ctx, creds->account_name));
1730     +
1731     + *creds_out = creds;
1732     + return NT_STATUS_OK;
1733     + }
1734     +
1735     +
1736     + if (explicit_opt != NULL) {
1737     + DBG_INFO("CVE-2020-1472(ZeroLogon): "
1738     + "%s request (opnum[%u]) without schannel from "
1739     + "client_account[%s] client_computer_name[%s]\n",
1740     + opname, opnum,
1741     + log_escape(mem_ctx, creds->account_name),
1742     + log_escape(mem_ctx, creds->computer_name));
1743     + DBG_INFO("CVE-2020-1472(ZeroLogon): "
1744     + "Option 'server require schannel:%s = no' still needed!\n",
1745     + log_escape(mem_ctx, creds->account_name));
1746     + } else {
1747     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
1748     + "%s request (opnum[%u]) without schannel from "
1749     + "client_account[%s] client_computer_name[%s]\n",
1750     + opname, opnum,
1751     + log_escape(mem_ctx, creds->account_name),
1752     + log_escape(mem_ctx, creds->computer_name));
1753     + DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
1754     + "'server require schannel:%s = no' might be needed!\n",
1755     + log_escape(mem_ctx, creds->account_name));
1756     + }
1757     +
1758     *creds_out = creds;
1759     return NT_STATUS_OK;
1760     }
1761     --
1762     2.39.0
1763    
1764    
1765     From 60b83fbda31c53c592a02f0ed43356a912021021 Mon Sep 17 00:00:00 2001
1766     From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
1767     Date: Thu, 17 Sep 2020 14:57:22 +0200
1768     Subject: [PATCH 020/142] CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon:
1769     refactor dcesrv_netr_creds_server_step_check()
1770     MIME-Version: 1.0
1771     Content-Type: text/plain; charset=UTF-8
1772     Content-Transfer-Encoding: 8bit
1773    
1774     We should debug more details about the failing request.
1775    
1776     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1777    
1778     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
1779    
1780     Signed-off-by: Günther Deschner <gd@samba.org>
1781     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1782     ---
1783     source3/rpc_server/netlogon/srv_netlog_nt.c | 43 +++++++++++++++++----
1784     1 file changed, 35 insertions(+), 8 deletions(-)
1785    
1786     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
1787     index fd9127b386f..8541571b459 100644
1788     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
1789     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
1790     @@ -48,6 +48,7 @@
1791     #include "../lib/tsocket/tsocket.h"
1792     #include "lib/param/param.h"
1793     #include "libsmb/dsgetdcname.h"
1794     +#include "lib/util/util_str_escape.h"
1795    
1796     extern userdom_struct current_user_info;
1797    
1798     @@ -1073,19 +1074,21 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
1799     NTSTATUS status;
1800     bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
1801     struct loadparm_context *lp_ctx;
1802     + struct netlogon_creds_CredentialState *creds = NULL;
1803     + enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1804     + uint16_t opnum = p->opnum;
1805     + const char *opname = "<unknown>";
1806    
1807     if (creds_out != NULL) {
1808     *creds_out = NULL;
1809     }
1810    
1811     - if (schannel_global_required) {
1812     - if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1813     - DBG_ERR("[%s] is not using schannel\n",
1814     - computer_name);
1815     - return NT_STATUS_ACCESS_DENIED;
1816     - }
1817     + if (opnum < ndr_table_netlogon.num_calls) {
1818     + opname = ndr_table_netlogon.calls[opnum].name;
1819     }
1820    
1821     + auth_type = p->auth.auth_type;
1822     +
1823     lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers());
1824     if (lp_ctx == NULL) {
1825     DEBUG(0, ("loadparm_init_s3 failed\n"));
1826     @@ -1094,9 +1097,33 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
1827    
1828     status = schannel_check_creds_state(mem_ctx, lp_ctx,
1829     computer_name, received_authenticator,
1830     - return_authenticator, creds_out);
1831     + return_authenticator, &creds);
1832     talloc_unlink(mem_ctx, lp_ctx);
1833     - return status;
1834     +
1835     + if (!NT_STATUS_IS_OK(status)) {
1836     + ZERO_STRUCTP(return_authenticator);
1837     + return status;
1838     + }
1839     +
1840     + if (schannel_global_required) {
1841     + if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1842     + *creds_out = creds;
1843     + return NT_STATUS_OK;
1844     + }
1845     +
1846     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
1847     + "%s request (opnum[%u]) without schannel from "
1848     + "client_account[%s] client_computer_name[%s]\n",
1849     + opname, opnum,
1850     + log_escape(mem_ctx, creds->account_name),
1851     + log_escape(mem_ctx, creds->computer_name));
1852     + TALLOC_FREE(creds);
1853     + ZERO_STRUCTP(return_authenticator);
1854     + return NT_STATUS_ACCESS_DENIED;
1855     + }
1856     +
1857     + *creds_out = creds;
1858     + return NT_STATUS_OK;
1859     }
1860    
1861    
1862     --
1863     2.39.0
1864    
1865    
1866     From c0a188b2696edb8f3ae9f7f56a820b11358bad98 Mon Sep 17 00:00:00 2001
1867     From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
1868     Date: Thu, 17 Sep 2020 14:23:16 +0200
1869     Subject: [PATCH 021/142] CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon:
1870     support "server require schannel:WORKSTATION$ = no"
1871     MIME-Version: 1.0
1872     Content-Type: text/plain; charset=UTF-8
1873     Content-Transfer-Encoding: 8bit
1874    
1875     This allows to add expections for individual workstations, when using "server schannel = yes".
1876     "server schannel = auto" is very insecure and will be removed soon.
1877    
1878     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1879    
1880     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
1881    
1882     Signed-off-by: Günther Deschner <gd@samba.org>
1883     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1884     ---
1885     source3/rpc_server/netlogon/srv_netlog_nt.c | 7 ++++++-
1886     1 file changed, 6 insertions(+), 1 deletion(-)
1887    
1888     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
1889     index 8541571b459..f9b10103bd5 100644
1890     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
1891     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
1892     @@ -1073,6 +1073,7 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
1893     {
1894     NTSTATUS status;
1895     bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
1896     + bool schannel_required = schannel_global_required;
1897     struct loadparm_context *lp_ctx;
1898     struct netlogon_creds_CredentialState *creds = NULL;
1899     enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1900     @@ -1105,7 +1106,11 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
1901     return status;
1902     }
1903    
1904     - if (schannel_global_required) {
1905     + schannel_required = lp_parm_bool(GLOBAL_SECTION_SNUM,
1906     + "server require schannel",
1907     + creds->account_name,
1908     + schannel_global_required);
1909     + if (schannel_required) {
1910     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1911     *creds_out = creds;
1912     return NT_STATUS_OK;
1913     --
1914     2.39.0
1915    
1916    
1917     From c9550b81b55316cf5d667502885fc248a5999fb5 Mon Sep 17 00:00:00 2001
1918     From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
1919     Date: Thu, 17 Sep 2020 14:42:52 +0200
1920     Subject: [PATCH 022/142] CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: log
1921     warnings about unsecure configurations
1922     MIME-Version: 1.0
1923     Content-Type: text/plain; charset=UTF-8
1924     Content-Transfer-Encoding: 8bit
1925    
1926     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
1927    
1928     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
1929    
1930     Signed-off-by: Günther Deschner <gd@samba.org>
1931     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1932     ---
1933     source3/rpc_server/netlogon/srv_netlog_nt.c | 70 +++++++++++++++++++--
1934     1 file changed, 66 insertions(+), 4 deletions(-)
1935    
1936     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
1937     index f9b10103bd5..7f6704adbda 100644
1938     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
1939     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
1940     @@ -1074,11 +1074,13 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
1941     NTSTATUS status;
1942     bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
1943     bool schannel_required = schannel_global_required;
1944     + const char *explicit_opt = NULL;
1945     struct loadparm_context *lp_ctx;
1946     struct netlogon_creds_CredentialState *creds = NULL;
1947     enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1948     uint16_t opnum = p->opnum;
1949     const char *opname = "<unknown>";
1950     + static bool warned_global_once = false;
1951    
1952     if (creds_out != NULL) {
1953     *creds_out = NULL;
1954     @@ -1106,10 +1108,20 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
1955     return status;
1956     }
1957    
1958     - schannel_required = lp_parm_bool(GLOBAL_SECTION_SNUM,
1959     - "server require schannel",
1960     - creds->account_name,
1961     - schannel_global_required);
1962     + /*
1963     + * We don't use lp_parm_bool(), as we
1964     + * need the explicit_opt pointer in order to
1965     + * adjust the debug messages.
1966     + */
1967     +
1968     + explicit_opt = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1969     + "server require schannel",
1970     + creds->account_name,
1971     + NULL);
1972     + if (explicit_opt != NULL) {
1973     + schannel_required = lp_bool(explicit_opt);
1974     + }
1975     +
1976     if (schannel_required) {
1977     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1978     *creds_out = creds;
1979     @@ -1122,11 +1134,61 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
1980     opname, opnum,
1981     log_escape(mem_ctx, creds->account_name),
1982     log_escape(mem_ctx, creds->computer_name));
1983     + DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
1984     + "'server require schannel:%s = no' is needed! \n",
1985     + log_escape(mem_ctx, creds->account_name));
1986     TALLOC_FREE(creds);
1987     ZERO_STRUCTP(return_authenticator);
1988     return NT_STATUS_ACCESS_DENIED;
1989     }
1990    
1991     + if (!schannel_global_required && !warned_global_once) {
1992     + /*
1993     + * We want admins to notice their misconfiguration!
1994     + */
1995     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
1996     + "Please configure 'server schannel = yes', "
1997     + "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n");
1998     + warned_global_once = true;
1999     + }
2000     +
2001     + if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
2002     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
2003     + "%s request (opnum[%u]) WITH schannel from "
2004     + "client_account[%s] client_computer_name[%s]\n",
2005     + opname, opnum,
2006     + log_escape(mem_ctx, creds->account_name),
2007     + log_escape(mem_ctx, creds->computer_name));
2008     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
2009     + "Option 'server require schannel:%s = no' not needed!?\n",
2010     + log_escape(mem_ctx, creds->account_name));
2011     +
2012     + *creds_out = creds;
2013     + return NT_STATUS_OK;
2014     + }
2015     +
2016     + if (explicit_opt != NULL) {
2017     + DBG_INFO("CVE-2020-1472(ZeroLogon): "
2018     + "%s request (opnum[%u]) without schannel from "
2019     + "client_account[%s] client_computer_name[%s]\n",
2020     + opname, opnum,
2021     + log_escape(mem_ctx, creds->account_name),
2022     + log_escape(mem_ctx, creds->computer_name));
2023     + DBG_INFO("CVE-2020-1472(ZeroLogon): "
2024     + "Option 'server require schannel:%s = no' still needed!\n",
2025     + log_escape(mem_ctx, creds->account_name));
2026     + } else {
2027     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
2028     + "%s request (opnum[%u]) without schannel from "
2029     + "client_account[%s] client_computer_name[%s]\n",
2030     + opname, opnum,
2031     + log_escape(mem_ctx, creds->account_name),
2032     + log_escape(mem_ctx, creds->computer_name));
2033     + DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
2034     + "'server require schannel:%s = no' might be needed!\n",
2035     + log_escape(mem_ctx, creds->account_name));
2036     + }
2037     +
2038     *creds_out = creds;
2039     return NT_STATUS_OK;
2040     }
2041     --
2042     2.39.0
2043    
2044    
2045     From 63f03e2e29e81f890a5d88c726cced6d3e7bbf5d Mon Sep 17 00:00:00 2001
2046     From: Stefan Metzmacher <metze@samba.org>
2047     Date: Thu, 17 Sep 2020 17:27:54 +0200
2048     Subject: [PATCH 023/142] CVE-2020-1472(ZeroLogon): docs-xml: document 'server
2049     require schannel:COMPUTERACCOUNT'
2050    
2051     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
2052    
2053     Signed-off-by: Stefan Metzmacher <metze@samba.org>
2054     ---
2055     .../smbdotconf/security/serverschannel.xml | 69 +++++++++++++++----
2056     1 file changed, 54 insertions(+), 15 deletions(-)
2057    
2058     diff --git a/docs-xml/smbdotconf/security/serverschannel.xml b/docs-xml/smbdotconf/security/serverschannel.xml
2059     index 489492d79b1..b682d086f76 100644
2060     --- a/docs-xml/smbdotconf/security/serverschannel.xml
2061     +++ b/docs-xml/smbdotconf/security/serverschannel.xml
2062     @@ -7,26 +7,65 @@
2063     <description>
2064    
2065     <para>
2066     - This option is deprecated with Samba 4.8 and will be removed in future.
2067     - At the same time the default changed to yes, which will be the
2068     - hardcoded behavior in future. If you have the need for the behavior of "auto"
2069     - to be kept, please file a bug at https://bugzilla.samba.org.
2070     + This option is deprecated and will be removed in future,
2071     + as it is a security problem if not set to "yes" (which will be
2072     + the hardcoded behavior in future).
2073     </para>
2074    
2075     <para>
2076     - This controls whether the server offers or even demands the use of the netlogon schannel.
2077     - <smbconfoption name="server schannel">no</smbconfoption> does not offer the schannel, <smbconfoption
2078     - name="server schannel">auto</smbconfoption> offers the schannel but does not enforce it, and <smbconfoption
2079     - name="server schannel">yes</smbconfoption> denies access if the client is not able to speak netlogon schannel.
2080     - This is only the case for Windows NT4 before SP4.
2081     - </para>
2082     -
2083     + Samba will complain in the log files at log level 0,
2084     + about the security problem if the option is not set to "yes".
2085     + </para>
2086     <para>
2087     - Please note that with this set to <literal>no</literal>, you will have to apply the WindowsXP
2088     - <filename>WinXP_SignOrSeal.reg</filename> registry patch found in the docs/registry subdirectory of the Samba distribution tarball.
2089     - </para>
2090     + See CVE-2020-1472(ZeroLogon) https://bugzilla.samba.org/show_bug.cgi?id=14497
2091     + </para>
2092     +
2093     + <para>If you still have legacy domain members use the <smbconfoption name="server require schannel:COMPUTERACCOUNT"/> option.
2094     + </para>
2095     +
2096     + <para>This option yields precedence to the <smbconfoption name="server require schannel:COMPUTERACCOUNT"/> option.</para>
2097     +
2098     </description>
2099    
2100     <value type="default">yes</value>
2101     -<value type="example">auto</value>
2102     +</samba:parameter>
2103     +
2104     +<samba:parameter name="server require schannel:COMPUTERACCOUNT"
2105     + context="G"
2106     + type="string"
2107     + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
2108     +<description>
2109     +
2110     + <para>If you still have legacy domain members, which required "server schannel = auto" before,
2111     + it is possible to specify explicit expection per computer account
2112     + by using 'server require schannel:COMPUTERACCOUNT = no' as option.
2113     + Note that COMPUTERACCOUNT has to be the sAMAccountName value of
2114     + the computer account (including the trailing '$' sign).
2115     + </para>
2116     +
2117     + <para>
2118     + Samba will complain in the log files at log level 0,
2119     + about the security problem if the option is not set to "no",
2120     + but the related computer is actually using the netlogon
2121     + secure channel (schannel) feature.
2122     + </para>
2123     +
2124     + <para>
2125     + Samba will warn in the log files at log level 5,
2126     + if a setting is still needed for the specified computer account.
2127     + </para>
2128     +
2129     + <para>
2130     + See CVE-2020-1472(ZeroLogon) https://bugzilla.samba.org/show_bug.cgi?id=14497
2131     + </para>
2132     +
2133     + <para>This option takes precedence to the <smbconfoption name="server schannel"/> option.</para>
2134     +
2135     + <programlisting>
2136     + server require schannel:LEGACYCOMPUTER1$ = no
2137     + server require schannel:NASBOX$ = no
2138     + server require schannel:LEGACYCOMPUTER2$ = no
2139     + </programlisting>
2140     +</description>
2141     +
2142     </samba:parameter>
2143     --
2144     2.39.0
2145    
2146    
2147     From 8a40da45b7f4e7a9110daf010383c4fce30bd9b6 Mon Sep 17 00:00:00 2001
2148     From: Gary Lockyer <gary@catalyst.net.nz>
2149     Date: Fri, 18 Sep 2020 12:39:54 +1200
2150     Subject: [PATCH 024/142] CVE-2020-1472(ZeroLogon): s4 torture rpc: Test empty
2151     machine acct pwd
2152    
2153     Ensure that an empty machine account password can't be set by
2154     netr_ServerPasswordSet2
2155    
2156     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
2157    
2158     Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
2159     ---
2160     source4/torture/rpc/netlogon.c | 64 +++++++++++++++-------------------
2161     1 file changed, 29 insertions(+), 35 deletions(-)
2162    
2163     diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
2164     index e11014922f8..0ba45f0c1da 100644
2165     --- a/source4/torture/rpc/netlogon.c
2166     +++ b/source4/torture/rpc/netlogon.c
2167     @@ -719,45 +719,39 @@ static bool test_SetPassword2_with_flags(struct torture_context *tctx,
2168    
2169     cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
2170    
2171     - if (!torture_setting_bool(tctx, "dangerous", false)) {
2172     - torture_comment(tctx,
2173     - "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
2174     + /*
2175     + * As a consequence of CVE-2020-1472(ZeroLogon)
2176     + * Samba explicitly disallows the setting of an empty machine account
2177     + * password.
2178     + *
2179     + * Note that this may fail against Windows, and leave a machine account
2180     + * with an empty password.
2181     + */
2182     + password = "";
2183     + encode_pw_buffer(password_buf.data, password, STR_UNICODE);
2184     + if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
2185     + netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
2186     } else {
2187     - /* by changing the machine password to ""
2188     - * we check if the server uses password restrictions
2189     - * for ServerPasswordSet2
2190     - * (win2k3 accepts "")
2191     - */
2192     - password = "";
2193     - encode_pw_buffer(password_buf.data, password, STR_UNICODE);
2194     - if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
2195     - netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
2196     - } else {
2197     - netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
2198     - }
2199     - memcpy(new_password.data, password_buf.data, 512);
2200     - new_password.length = IVAL(password_buf.data, 512);
2201     -
2202     - torture_comment(tctx,
2203     - "Testing ServerPasswordSet2 on machine account\n");
2204     - torture_comment(tctx,
2205     - "Changing machine account password to '%s'\n", password);
2206     -
2207     - netlogon_creds_client_authenticator(creds, &credential);
2208     -
2209     - torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
2210     - "ServerPasswordSet2 failed");
2211     - torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
2212     + netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
2213     + }
2214     + memcpy(new_password.data, password_buf.data, 512);
2215     + new_password.length = IVAL(password_buf.data, 512);
2216    
2217     - if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2218     - torture_comment(tctx, "Credential chaining failed\n");
2219     - }
2220     + torture_comment(tctx,
2221     + "Testing ServerPasswordSet2 on machine account\n");
2222     + torture_comment(tctx,
2223     + "Changing machine account password to '%s'\n", password);
2224    
2225     - cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
2226     - }
2227     + netlogon_creds_client_authenticator(creds, &credential);
2228    
2229     - torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
2230     - "ServerPasswordSet failed to actually change the password");
2231     + torture_assert_ntstatus_ok(
2232     + tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
2233     + "ServerPasswordSet2 failed");
2234     + torture_assert_ntstatus_equal(
2235     + tctx,
2236     + r.out.result,
2237     + NT_STATUS_WRONG_PASSWORD,
2238     + "ServerPasswordSet2 did not return NT_STATUS_WRONG_PASSWORD");
2239    
2240     /* now try a random password */
2241     password = generate_random_password(tctx, 8, 255);
2242     --
2243     2.39.0
2244    
2245    
2246     From 341a448cb69557410fa79dbb8a3d4adbab79d5b6 Mon Sep 17 00:00:00 2001
2247     From: Gary Lockyer <gary@catalyst.net.nz>
2248     Date: Fri, 18 Sep 2020 15:57:34 +1200
2249     Subject: [PATCH 025/142] CVE-2020-1472(ZeroLogon): s4 torture rpc: repeated
2250     bytes in client challenge
2251    
2252     Ensure that client challenges with the first 5 bytes identical are
2253     rejected.
2254    
2255     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
2256    
2257     Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
2258    
2259     [abartlet@samba.org: backported from master as test order was flipped]
2260     ---
2261     source4/torture/rpc/netlogon.c | 335 +++++++++++++++++++++++++++++++++
2262     1 file changed, 335 insertions(+)
2263    
2264     diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
2265     index 0ba45f0c1da..97c16688bc9 100644
2266     --- a/source4/torture/rpc/netlogon.c
2267     +++ b/source4/torture/rpc/netlogon.c
2268     @@ -480,6 +480,325 @@ bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1,
2269     return true;
2270     }
2271    
2272     +static bool test_ServerReqChallenge(
2273     + struct torture_context *tctx,
2274     + struct dcerpc_pipe *p,
2275     + struct cli_credentials *credentials)
2276     +{
2277     + struct netr_ServerReqChallenge r;
2278     + struct netr_Credential credentials1, credentials2, credentials3;
2279     + const char *machine_name;
2280     + struct dcerpc_binding_handle *b = p->binding_handle;
2281     + struct netr_ServerAuthenticate2 a;
2282     + uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2283     + uint32_t out_negotiate_flags = 0;
2284     + const struct samr_Password *mach_password = NULL;
2285     + enum netr_SchannelType sec_chan_type = 0;
2286     + struct netlogon_creds_CredentialState *creds = NULL;
2287     + const char *account_name = NULL;
2288     +
2289     + machine_name = cli_credentials_get_workstation(credentials);
2290     + mach_password = cli_credentials_get_nt_hash(credentials, tctx);
2291     + account_name = cli_credentials_get_username(credentials);
2292     + sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
2293     +
2294     + torture_comment(tctx, "Testing ServerReqChallenge\n");
2295     +
2296     + r.in.server_name = NULL;
2297     + r.in.computer_name = machine_name;
2298     + r.in.credentials = &credentials1;
2299     + r.out.return_credentials = &credentials2;
2300     +
2301     + netlogon_creds_random_challenge(&credentials1);
2302     +
2303     + torture_assert_ntstatus_ok(
2304     + tctx,
2305     + dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2306     + "ServerReqChallenge failed");
2307     + torture_assert_ntstatus_ok(
2308     + tctx,
2309     + r.out.result,
2310     + "ServerReqChallenge failed");
2311     + a.in.server_name = NULL;
2312     + a.in.account_name = account_name;
2313     + a.in.secure_channel_type = sec_chan_type;
2314     + a.in.computer_name = machine_name;
2315     + a.in.negotiate_flags = &in_negotiate_flags;
2316     + a.out.negotiate_flags = &out_negotiate_flags;
2317     + a.in.credentials = &credentials3;
2318     + a.out.return_credentials = &credentials3;
2319     +
2320     + creds = netlogon_creds_client_init(tctx, a.in.account_name,
2321     + a.in.computer_name,
2322     + a.in.secure_channel_type,
2323     + &credentials1, &credentials2,
2324     + mach_password, &credentials3,
2325     + in_negotiate_flags);
2326     +
2327     + torture_assert(tctx, creds != NULL, "memory allocation");
2328     +
2329     + torture_comment(tctx, "Testing ServerAuthenticate2\n");
2330     +
2331     + torture_assert_ntstatus_ok(
2332     + tctx,
2333     + dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
2334     + "ServerAuthenticate2 failed");
2335     + torture_assert_ntstatus_equal(
2336     + tctx,
2337     + a.out.result,
2338     + NT_STATUS_OK,
2339     + "ServerAuthenticate2 unexpected");
2340     +
2341     + return true;
2342     +}
2343     +
2344     +static bool test_ServerReqChallenge_zero_challenge(
2345     + struct torture_context *tctx,
2346     + struct dcerpc_pipe *p,
2347     + struct cli_credentials *credentials)
2348     +{
2349     + struct netr_ServerReqChallenge r;
2350     + struct netr_Credential credentials1, credentials2, credentials3;
2351     + const char *machine_name;
2352     + struct dcerpc_binding_handle *b = p->binding_handle;
2353     + struct netr_ServerAuthenticate2 a;
2354     + uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2355     + uint32_t out_negotiate_flags = 0;
2356     + const struct samr_Password *mach_password = NULL;
2357     + enum netr_SchannelType sec_chan_type = 0;
2358     + struct netlogon_creds_CredentialState *creds = NULL;
2359     + const char *account_name = NULL;
2360     +
2361     + machine_name = cli_credentials_get_workstation(credentials);
2362     + mach_password = cli_credentials_get_nt_hash(credentials, tctx);
2363     + account_name = cli_credentials_get_username(credentials);
2364     + sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
2365     +
2366     + torture_comment(tctx, "Testing ServerReqChallenge\n");
2367     +
2368     + r.in.server_name = NULL;
2369     + r.in.computer_name = machine_name;
2370     + r.in.credentials = &credentials1;
2371     + r.out.return_credentials = &credentials2;
2372     +
2373     + /*
2374     + * Set the client challenge to zero, this should fail
2375     + * CVE-2020-1472(ZeroLogon)
2376     + * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
2377     + */
2378     + ZERO_STRUCT(credentials1);
2379     +
2380     + torture_assert_ntstatus_ok(
2381     + tctx,
2382     + dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2383     + "ServerReqChallenge failed");
2384     + torture_assert_ntstatus_ok(
2385     + tctx,
2386     + r.out.result,
2387     + "ServerReqChallenge failed");
2388     + a.in.server_name = NULL;
2389     + a.in.account_name = account_name;
2390     + a.in.secure_channel_type = sec_chan_type;
2391     + a.in.computer_name = machine_name;
2392     + a.in.negotiate_flags = &in_negotiate_flags;
2393     + a.out.negotiate_flags = &out_negotiate_flags;
2394     + a.in.credentials = &credentials3;
2395     + a.out.return_credentials = &credentials3;
2396     +
2397     + creds = netlogon_creds_client_init(tctx, a.in.account_name,
2398     + a.in.computer_name,
2399     + a.in.secure_channel_type,
2400     + &credentials1, &credentials2,
2401     + mach_password, &credentials3,
2402     + in_negotiate_flags);
2403     +
2404     + torture_assert(tctx, creds != NULL, "memory allocation");
2405     +
2406     + torture_comment(tctx, "Testing ServerAuthenticate2\n");
2407     +
2408     + torture_assert_ntstatus_ok(
2409     + tctx,
2410     + dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
2411     + "ServerAuthenticate2 failed");
2412     + torture_assert_ntstatus_equal(
2413     + tctx,
2414     + a.out.result,
2415     + NT_STATUS_ACCESS_DENIED,
2416     + "ServerAuthenticate2 unexpected");
2417     +
2418     + return true;
2419     +}
2420     +
2421     +static bool test_ServerReqChallenge_5_repeats(
2422     + struct torture_context *tctx,
2423     + struct dcerpc_pipe *p,
2424     + struct cli_credentials *credentials)
2425     +{
2426     + struct netr_ServerReqChallenge r;
2427     + struct netr_Credential credentials1, credentials2, credentials3;
2428     + const char *machine_name;
2429     + struct dcerpc_binding_handle *b = p->binding_handle;
2430     + struct netr_ServerAuthenticate2 a;
2431     + uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2432     + uint32_t out_negotiate_flags = 0;
2433     + const struct samr_Password *mach_password = NULL;
2434     + enum netr_SchannelType sec_chan_type = 0;
2435     + struct netlogon_creds_CredentialState *creds = NULL;
2436     + const char *account_name = NULL;
2437     +
2438     + machine_name = cli_credentials_get_workstation(credentials);
2439     + mach_password = cli_credentials_get_nt_hash(credentials, tctx);
2440     + account_name = cli_credentials_get_username(credentials);
2441     + sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
2442     +
2443     + torture_comment(tctx, "Testing ServerReqChallenge\n");
2444     +
2445     + r.in.server_name = NULL;
2446     + r.in.computer_name = machine_name;
2447     + r.in.credentials = &credentials1;
2448     + r.out.return_credentials = &credentials2;
2449     +
2450     + /*
2451     + * Set the first 5 bytes of the client challenge to the same value,
2452     + * this should fail CVE-2020-1472(ZeroLogon)
2453     + * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
2454     + */
2455     + credentials1.data[0] = 'A';
2456     + credentials1.data[1] = 'A';
2457     + credentials1.data[2] = 'A';
2458     + credentials1.data[3] = 'A';
2459     + credentials1.data[4] = 'A';
2460     + credentials1.data[5] = 'B';
2461     + credentials1.data[6] = 'C';
2462     + credentials1.data[7] = 'D';
2463     +
2464     + torture_assert_ntstatus_ok(
2465     + tctx,
2466     + dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2467     + "ServerReqChallenge failed");
2468     + torture_assert_ntstatus_ok(
2469     + tctx,
2470     + r.out.result,
2471     + "ServerReqChallenge failed");
2472     + a.in.server_name = NULL;
2473     + a.in.account_name = account_name;
2474     + a.in.secure_channel_type = sec_chan_type;
2475     + a.in.computer_name = machine_name;
2476     + a.in.negotiate_flags = &in_negotiate_flags;
2477     + a.out.negotiate_flags = &out_negotiate_flags;
2478     + a.in.credentials = &credentials3;
2479     + a.out.return_credentials = &credentials3;
2480     +
2481     + creds = netlogon_creds_client_init(tctx, a.in.account_name,
2482     + a.in.computer_name,
2483     + a.in.secure_channel_type,
2484     + &credentials1, &credentials2,
2485     + mach_password, &credentials3,
2486     + in_negotiate_flags);
2487     +
2488     + torture_assert(tctx, creds != NULL, "memory allocation");
2489     +
2490     + torture_comment(tctx, "Testing ServerAuthenticate2\n");
2491     +
2492     + torture_assert_ntstatus_ok(
2493     + tctx,
2494     + dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
2495     + "ServerAuthenticate2 failed");
2496     + torture_assert_ntstatus_equal(
2497     + tctx,
2498     + a.out.result,
2499     + NT_STATUS_ACCESS_DENIED,
2500     + "ServerAuthenticate2 unexpected");
2501     +
2502     + return true;
2503     +}
2504     +
2505     +static bool test_ServerReqChallenge_4_repeats(
2506     + struct torture_context *tctx,
2507     + struct dcerpc_pipe *p,
2508     + struct cli_credentials *credentials)
2509     +{
2510     + struct netr_ServerReqChallenge r;
2511     + struct netr_Credential credentials1, credentials2, credentials3;
2512     + const char *machine_name;
2513     + struct dcerpc_binding_handle *b = p->binding_handle;
2514     + struct netr_ServerAuthenticate2 a;
2515     + uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2516     + uint32_t out_negotiate_flags = 0;
2517     + const struct samr_Password *mach_password = NULL;
2518     + enum netr_SchannelType sec_chan_type = 0;
2519     + struct netlogon_creds_CredentialState *creds = NULL;
2520     + const char *account_name = NULL;
2521     +
2522     + machine_name = cli_credentials_get_workstation(credentials);
2523     + mach_password = cli_credentials_get_nt_hash(credentials, tctx);
2524     + account_name = cli_credentials_get_username(credentials);
2525     + sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
2526     +
2527     + torture_comment(tctx, "Testing ServerReqChallenge\n");
2528     +
2529     + r.in.server_name = NULL;
2530     + r.in.computer_name = machine_name;
2531     + r.in.credentials = &credentials1;
2532     + r.out.return_credentials = &credentials2;
2533     +
2534     + /*
2535     + * Set the first 4 bytes of the client challenge to the same
2536     + * value, this should pass as 5 bytes identical are needed to
2537     + * fail for CVE-2020-1472(ZeroLogon)
2538     + *
2539     + * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
2540     + */
2541     + credentials1.data[0] = 'A';
2542     + credentials1.data[1] = 'A';
2543     + credentials1.data[2] = 'A';
2544     + credentials1.data[3] = 'A';
2545     + credentials1.data[4] = 'B';
2546     + credentials1.data[5] = 'C';
2547     + credentials1.data[6] = 'D';
2548     + credentials1.data[7] = 'E';
2549     +
2550     + torture_assert_ntstatus_ok(
2551     + tctx,
2552     + dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2553     + "ServerReqChallenge failed");
2554     + torture_assert_ntstatus_ok(
2555     + tctx,
2556     + r.out.result,
2557     + "ServerReqChallenge failed");
2558     + a.in.server_name = NULL;
2559     + a.in.account_name = account_name;
2560     + a.in.secure_channel_type = sec_chan_type;
2561     + a.in.computer_name = machine_name;
2562     + a.in.negotiate_flags = &in_negotiate_flags;
2563     + a.out.negotiate_flags = &out_negotiate_flags;
2564     + a.in.credentials = &credentials3;
2565     + a.out.return_credentials = &credentials3;
2566     +
2567     + creds = netlogon_creds_client_init(tctx, a.in.account_name,
2568     + a.in.computer_name,
2569     + a.in.secure_channel_type,
2570     + &credentials1, &credentials2,
2571     + mach_password, &credentials3,
2572     + in_negotiate_flags);
2573     +
2574     + torture_assert(tctx, creds != NULL, "memory allocation");
2575     +
2576     + torture_comment(tctx, "Testing ServerAuthenticate2\n");
2577     +
2578     + torture_assert_ntstatus_ok(
2579     + tctx,
2580     + dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
2581     + "ServerAuthenticate2 failed");
2582     + torture_assert_ntstatus_equal(
2583     + tctx,
2584     + a.out.result,
2585     + NT_STATUS_OK,
2586     + "ServerAuthenticate2 unexpected");
2587     +
2588     + return true;
2589     +}
2590     +
2591     /*
2592     try a change password for our machine account
2593     */
2594     @@ -4949,6 +5268,22 @@ struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
2595     torture_rpc_tcase_add_test(tcase, "lsa_over_netlogon", test_lsa_over_netlogon);
2596     torture_rpc_tcase_add_test_creds(tcase, "SetupCredentialsDowngrade", test_SetupCredentialsDowngrade);
2597    
2598     + torture_rpc_tcase_add_test_creds(
2599     + tcase,
2600     + "ServerReqChallenge",
2601     + test_ServerReqChallenge);
2602     + torture_rpc_tcase_add_test_creds(
2603     + tcase,
2604     + "ServerReqChallenge_zero_challenge",
2605     + test_ServerReqChallenge_zero_challenge);
2606     + torture_rpc_tcase_add_test_creds(
2607     + tcase,
2608     + "ServerReqChallenge_5_repeats",
2609     + test_ServerReqChallenge_5_repeats);
2610     + torture_rpc_tcase_add_test_creds(
2611     + tcase,
2612     + "ServerReqChallenge_4_repeats",
2613     + test_ServerReqChallenge_4_repeats);
2614     return suite;
2615     }
2616    
2617     --
2618     2.39.0
2619    
2620    
2621     From 268303632f79d7395b452172c06b25ad68fe35fb Mon Sep 17 00:00:00 2001
2622     From: Jeremy Allison <jra@samba.org>
2623     Date: Fri, 10 Jul 2020 15:09:33 -0700
2624     Subject: [PATCH 026/142] s4: torture: Add smb2.notify.handle-permissions test.
2625    
2626     Add knownfail entry.
2627    
2628     CVE-2020-14318
2629    
2630     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14434
2631    
2632     Signed-off-by: Jeremy Allison <jra@samba.org>
2633     (cherry picked from commit f100bd2f2e4f047942002a992c99104227a17f81)
2634     ---
2635     .../smb2_notify_handle_permissions | 2 +
2636     source4/torture/smb2/notify.c | 80 +++++++++++++++++++
2637     2 files changed, 82 insertions(+)
2638     create mode 100644 selftest/knownfail.d/smb2_notify_handle_permissions
2639    
2640     diff --git a/selftest/knownfail.d/smb2_notify_handle_permissions b/selftest/knownfail.d/smb2_notify_handle_permissions
2641     new file mode 100644
2642     index 00000000000..c0ec8fc8153
2643     --- /dev/null
2644     +++ b/selftest/knownfail.d/smb2_notify_handle_permissions
2645     @@ -0,0 +1,2 @@
2646     +^samba3.smb2.notify.handle-permissions
2647     +
2648     diff --git a/source4/torture/smb2/notify.c b/source4/torture/smb2/notify.c
2649     index ebb4f8a4f8e..b017491c8fb 100644
2650     --- a/source4/torture/smb2/notify.c
2651     +++ b/source4/torture/smb2/notify.c
2652     @@ -2569,6 +2569,83 @@ done:
2653     return ok;
2654     }
2655    
2656     +/*
2657     + Test asking for a change notify on a handle without permissions.
2658     +*/
2659     +
2660     +#define BASEDIR_HPERM BASEDIR "_HPERM"
2661     +
2662     +static bool torture_smb2_notify_handle_permissions(
2663     + struct torture_context *torture,
2664     + struct smb2_tree *tree)
2665     +{
2666     + bool ret = true;
2667     + NTSTATUS status;
2668     + union smb_notify notify;
2669     + union smb_open io;
2670     + struct smb2_handle h1 = {{0}};
2671     + struct smb2_request *req;
2672     +
2673     + smb2_deltree(tree, BASEDIR_HPERM);
2674     + smb2_util_rmdir(tree, BASEDIR_HPERM);
2675     +
2676     + torture_comment(torture,
2677     + "TESTING CHANGE NOTIFY "
2678     + "ON A HANDLE WITHOUT PERMISSIONS\n");
2679     +
2680     + /*
2681     + get a handle on the directory
2682     + */
2683     + ZERO_STRUCT(io.smb2);
2684     + io.generic.level = RAW_OPEN_SMB2;
2685     + io.smb2.in.create_flags = 0;
2686     + io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
2687     + io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2688     + io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2689     + io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
2690     + NTCREATEX_SHARE_ACCESS_WRITE;
2691     + io.smb2.in.alloc_size = 0;
2692     + io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2693     + io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2694     + io.smb2.in.security_flags = 0;
2695     + io.smb2.in.fname = BASEDIR_HPERM;
2696     +
2697     + status = smb2_create(tree, torture, &io.smb2);
2698     + CHECK_STATUS(status, NT_STATUS_OK);
2699     + h1 = io.smb2.out.file.handle;
2700     +
2701     + /* ask for a change notify,
2702     + on file or directory name changes */
2703     + ZERO_STRUCT(notify.smb2);
2704     + notify.smb2.level = RAW_NOTIFY_SMB2;
2705     + notify.smb2.in.buffer_size = 1000;
2706     + notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
2707     + notify.smb2.in.file.handle = h1;
2708     + notify.smb2.in.recursive = true;
2709     +
2710     + req = smb2_notify_send(tree, &notify.smb2);
2711     + torture_assert_goto(torture,
2712     + req != NULL,
2713     + ret,
2714     + done,
2715     + "smb2_notify_send failed\n");
2716     +
2717     + /*
2718     + * Cancel it, we don't really want to wait.
2719     + */
2720     + smb2_cancel(req);
2721     + status = smb2_notify_recv(req, torture, &notify.smb2);
2722     + /* Handle h1 doesn't have permissions for ChangeNotify. */
2723     + CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
2724     +
2725     +done:
2726     + if (!smb2_util_handle_empty(h1)) {
2727     + smb2_util_close(tree, h1);
2728     + }
2729     + smb2_deltree(tree, BASEDIR_HPERM);
2730     + return ret;
2731     +}
2732     +
2733     /*
2734     basic testing of SMB2 change notify
2735     */
2736     @@ -2602,6 +2679,9 @@ struct torture_suite *torture_smb2_notify_init(TALLOC_CTX *ctx)
2737     torture_smb2_notify_rmdir3);
2738     torture_suite_add_2smb2_test(suite, "rmdir4",
2739     torture_smb2_notify_rmdir4);
2740     + torture_suite_add_1smb2_test(suite,
2741     + "handle-permissions",
2742     + torture_smb2_notify_handle_permissions);
2743    
2744     suite->description = talloc_strdup(suite, "SMB2-NOTIFY tests");
2745    
2746     --
2747     2.39.0
2748    
2749    
2750     From 448d4e99f8883a07589264cfca474c3dff8b5942 Mon Sep 17 00:00:00 2001
2751     From: Jeremy Allison <jra@samba.org>
2752     Date: Tue, 7 Jul 2020 18:25:23 -0700
2753     Subject: [PATCH 027/142] s3: smbd: Ensure change notifies can't get set unless
2754     the directory handle is open for SEC_DIR_LIST.
2755    
2756     Remove knownfail entry.
2757    
2758     CVE-2020-14318
2759    
2760     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14434
2761    
2762     Signed-off-by: Jeremy Allison <jra@samba.org>
2763     (cherry picked from commit f43ecce46a89c6380317fbb5f2ae38f48d3d42c8)
2764     ---
2765     selftest/knownfail.d/smb2_notify_handle_permissions | 2 --
2766     source3/smbd/notify.c | 8 ++++++++
2767     2 files changed, 8 insertions(+), 2 deletions(-)
2768     delete mode 100644 selftest/knownfail.d/smb2_notify_handle_permissions
2769    
2770     diff --git a/selftest/knownfail.d/smb2_notify_handle_permissions b/selftest/knownfail.d/smb2_notify_handle_permissions
2771     deleted file mode 100644
2772     index c0ec8fc8153..00000000000
2773     --- a/selftest/knownfail.d/smb2_notify_handle_permissions
2774     +++ /dev/null
2775     @@ -1,2 +0,0 @@
2776     -^samba3.smb2.notify.handle-permissions
2777     -
2778     diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
2779     index 44c0b09432e..d23c03bce41 100644
2780     --- a/source3/smbd/notify.c
2781     +++ b/source3/smbd/notify.c
2782     @@ -283,6 +283,14 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
2783     char fullpath[len+1];
2784     NTSTATUS status = NT_STATUS_NOT_IMPLEMENTED;
2785    
2786     + /*
2787     + * Setting a changenotify needs READ/LIST access
2788     + * on the directory handle.
2789     + */
2790     + if (!(fsp->access_mask & SEC_DIR_LIST)) {
2791     + return NT_STATUS_ACCESS_DENIED;
2792     + }
2793     +
2794     if (fsp->notify != NULL) {
2795     DEBUG(1, ("change_notify_create: fsp->notify != NULL, "
2796     "fname = %s\n", fsp->fsp_name->base_name));
2797     --
2798     2.39.0
2799    
2800    
2801     From 041c86926999594f13b884522b1d9fcc65f92a52 Mon Sep 17 00:00:00 2001
2802     From: Volker Lendecke <vl@samba.org>
2803     Date: Thu, 9 Jul 2020 21:49:25 +0200
2804     Subject: [PATCH 028/142] CVE-2020-14323 winbind: Fix invalid lookupsids DoS
2805    
2806     A lookupsids request without extra_data will lead to "state->domain==NULL",
2807     which makes winbindd_lookupsids_recv trying to dereference it.
2808    
2809     Reported by Bas Alberts of the GitHub Security Lab Team as GHSL-2020-134
2810    
2811     Bug: https://bugzilla.samba.org/show_bug.cgi?id=14436
2812     Signed-off-by: Volker Lendecke <vl@samba.org>
2813     (cherry picked from commit f17967ad73e9c1d2bd6e0b7c181f08079d2a8214)
2814     ---
2815     source3/winbindd/winbindd_lookupsids.c | 2 +-
2816     1 file changed, 1 insertion(+), 1 deletion(-)
2817    
2818     diff --git a/source3/winbindd/winbindd_lookupsids.c b/source3/winbindd/winbindd_lookupsids.c
2819     index d28b5fa9f01..a289fd86f0f 100644
2820     --- a/source3/winbindd/winbindd_lookupsids.c
2821     +++ b/source3/winbindd/winbindd_lookupsids.c
2822     @@ -47,7 +47,7 @@ struct tevent_req *winbindd_lookupsids_send(TALLOC_CTX *mem_ctx,
2823     DEBUG(3, ("lookupsids\n"));
2824    
2825     if (request->extra_len == 0) {
2826     - tevent_req_done(req);
2827     + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2828     return tevent_req_post(req, ev);
2829     }
2830     if (request->extra_data.data[request->extra_len-1] != '\0') {
2831     --
2832     2.39.0
2833    
2834    
2835     From e6e77a3a503f9223ecbc2d32a1d24e20f834659f Mon Sep 17 00:00:00 2001
2836     From: Volker Lendecke <vl@samba.org>
2837     Date: Thu, 9 Jul 2020 21:48:57 +0200
2838     Subject: [PATCH 029/142] CVE-2020-14323 torture4: Add a simple test for
2839     invalid lookup_sids winbind call
2840    
2841     We can't add this test before the fix, add it to knownfail and have the fix
2842     remove the knownfail entry again. As this crashes winbind, many tests after
2843     this one will fail.
2844    
2845     Reported by Bas Alberts of the GitHub Security Lab Team as GHSL-2020-134
2846    
2847     Bug: https://bugzilla.samba.org/show_bug.cgi?id=14436
2848     Signed-off-by: Volker Lendecke <vl@samba.org>
2849     (cherry picked from commit d0ca2a63aaedf123205337aaa211426175ffcebf)
2850     ---
2851     source4/torture/winbind/struct_based.c | 27 ++++++++++++++++++++++++++
2852     1 file changed, 27 insertions(+)
2853    
2854     diff --git a/source4/torture/winbind/struct_based.c b/source4/torture/winbind/struct_based.c
2855     index 9745b621ca9..71f248c0d61 100644
2856     --- a/source4/torture/winbind/struct_based.c
2857     +++ b/source4/torture/winbind/struct_based.c
2858     @@ -1110,6 +1110,29 @@ static bool torture_winbind_struct_lookup_name_sid(struct torture_context *tortu
2859     return true;
2860     }
2861    
2862     +static bool torture_winbind_struct_lookup_sids_invalid(
2863     + struct torture_context *torture)
2864     +{
2865     + struct winbindd_request req = {0};
2866     + struct winbindd_response rep = {0};
2867     + bool strict = torture_setting_bool(torture, "strict mode", false);
2868     + bool ok;
2869     +
2870     + torture_comment(torture,
2871     + "Running WINBINDD_LOOKUP_SIDS (struct based)\n");
2872     +
2873     + ok = true;
2874     + DO_STRUCT_REQ_REP_EXT(WINBINDD_LOOKUPSIDS, &req, &rep,
2875     + NSS_STATUS_NOTFOUND,
2876     + strict,
2877     + ok=false,
2878     + talloc_asprintf(
2879     + torture,
2880     + "invalid lookupsids succeeded"));
2881     +
2882     + return ok;
2883     +}
2884     +
2885     struct torture_suite *torture_winbind_struct_init(TALLOC_CTX *ctx)
2886     {
2887     struct torture_suite *suite = torture_suite_create(ctx, "struct");
2888     @@ -1132,6 +1155,10 @@ struct torture_suite *torture_winbind_struct_init(TALLOC_CTX *ctx)
2889     torture_suite_add_simple_test(suite, "getpwent", torture_winbind_struct_getpwent);
2890     torture_suite_add_simple_test(suite, "endpwent", torture_winbind_struct_endpwent);
2891     torture_suite_add_simple_test(suite, "lookup_name_sid", torture_winbind_struct_lookup_name_sid);
2892     + torture_suite_add_simple_test(
2893     + suite,
2894     + "lookup_sids_invalid",
2895     + torture_winbind_struct_lookup_sids_invalid);
2896    
2897     suite->description = talloc_strdup(suite, "WINBIND - struct based protocol tests");
2898    
2899     --
2900     2.39.0
2901    
2902    
2903     From 2b4763940d1826a2b4e5eaa1e2df338004cd9af0 Mon Sep 17 00:00:00 2001
2904     From: Laurent Menase <laurent.menase@hpe.com>
2905     Date: Wed, 20 May 2020 12:31:53 +0200
2906     Subject: [PATCH 030/142] winbind: Fix a memleak
2907    
2908     Bug: https://bugzilla.samba.org/show_bug.cgi?id=14388
2909     Signed-off-by: Laurent Menase <laurent.menase@hpe.com>
2910     Reviewed-by: Volker Lendecke <vl@samba.org>
2911     Reviewed-by: Noel Power <noel.power@suse.com>
2912    
2913     Autobuild-User(master): Volker Lendecke <vl@samba.org>
2914     Autobuild-Date(master): Mon Sep 14 13:33:13 UTC 2020 on sn-devel-184
2915    
2916     (cherry picked from commit 8f868b0ea0b4795668f7bc0b028cd85686b249fb)
2917     ---
2918     source3/winbindd/winbindd_ads.c | 1 +
2919     1 file changed, 1 insertion(+)
2920    
2921     diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
2922     index 556b4523866..325ba1abd82 100644
2923     --- a/source3/winbindd/winbindd_ads.c
2924     +++ b/source3/winbindd/winbindd_ads.c
2925     @@ -405,6 +405,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
2926     DBG_NOTICE("ads query_user_list gave %d entries\n", count);
2927    
2928     done:
2929     + ads_msgfree(ads, res);
2930     return status;
2931     }
2932    
2933     --
2934     2.39.0
2935    
2936    
2937     From accc423a4eb9170ab0dbe4b2ba90ce83790e7a16 Mon Sep 17 00:00:00 2001
2938     From: Andreas Schneider <asn@samba.org>
2939     Date: Mon, 17 Aug 2020 13:39:58 +0200
2940     Subject: [PATCH 031/142] s3:tests: Add test for 'valid users = DOMAIN\%U'
2941    
2942     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14467
2943    
2944     Signed-off-by: Andreas Schneider <asn@samba.org>
2945     Reviewed-by: Ralph Boehme <slow@samba.org>
2946     (cherry picked from commit 53b6dd951249052772e1ffcf651b7efd0963b931)
2947     (cherry picked from commit 20d3cf455c631c6cea6d471333779cc15d0e8d8a)
2948     ---
2949     selftest/knownfail.d/samba3.substiutions | 1 +
2950     selftest/target/Samba3.pm | 4 ++++
2951     source3/script/tests/test_substitutions.sh | 5 +++++
2952     3 files changed, 10 insertions(+)
2953     create mode 100644 selftest/knownfail.d/samba3.substiutions
2954    
2955     diff --git a/selftest/knownfail.d/samba3.substiutions b/selftest/knownfail.d/samba3.substiutions
2956     new file mode 100644
2957     index 00000000000..f116d3b2fcf
2958     --- /dev/null
2959     +++ b/selftest/knownfail.d/samba3.substiutions
2960     @@ -0,0 +1 @@
2961     +^samba3.substitutions.Test.login.to.share.with.substitution.for.valid.users
2962     diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
2963     index 75960dbc790..9e4da0e6a08 100755
2964     --- a/selftest/target/Samba3.pm
2965     +++ b/selftest/target/Samba3.pm
2966     @@ -423,6 +423,10 @@ sub setup_ad_member
2967     path = $share_dir/D_%D/u_%u/g_%g
2968     writeable = yes
2969    
2970     +[sub_valid_users]
2971     + path = $share_dir
2972     + valid users = ADDOMAIN/%U
2973     +
2974     ";
2975    
2976     my $ret = $self->provision($prefix, $dcvars->{DOMAIN},
2977     diff --git a/source3/script/tests/test_substitutions.sh b/source3/script/tests/test_substitutions.sh
2978     index 1a46f11c85d..c813a8f9def 100755
2979     --- a/source3/script/tests/test_substitutions.sh
2980     +++ b/source3/script/tests/test_substitutions.sh
2981     @@ -34,4 +34,9 @@ SMB_UNC="//$SERVER/sub_dug2"
2982     test_smbclient "Test login to share with substitution (Dug)" \
2983     "ls" "$SMB_UNC" "-U$USERNAME%$PASSWORD" || failed=$(expr $failed + 1)
2984    
2985     +SMB_UNC="//$SERVER/sub_valid_users"
2986     +
2987     +test_smbclient "Test login to share with substitution for valid users" \
2988     + "ls" "$SMB_UNC" "-U$USERNAME%$PASSWORD" || failed=$(expr $failed + 1)
2989     +
2990     exit $failed
2991     --
2992     2.39.0
2993    
2994    
2995     From 1c594e3734e3ffd2dfc615897ac95792878f2df4 Mon Sep 17 00:00:00 2001
2996     From: Andreas Schneider <asn@samba.org>
2997     Date: Mon, 17 Aug 2020 14:12:48 +0200
2998     Subject: [PATCH 032/142] s3:smbd: Fix %U substitutions if it contains a domain
2999     name
3000    
3001     'valid users = DOMAIN\%U' worked with Samba 3.6 and broke in a newer
3002     version.
3003    
3004     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14467
3005    
3006     Signed-off-by: Andreas Schneider <asn@samba.org>
3007     Reviewed-by: Ralph Boehme <slow@samba.org>
3008     (cherry picked from commit 5de7c91e6d4e98f438157a7675c8582cabdd828d)
3009     (cherry picked from commit 60ddb7b20071b00f0cd7f1cb818022220eb0c279)
3010     ---
3011     selftest/knownfail.d/samba3.substiutions | 1 -
3012     source3/smbd/share_access.c | 18 +++++++++++++++++-
3013     2 files changed, 17 insertions(+), 2 deletions(-)
3014     delete mode 100644 selftest/knownfail.d/samba3.substiutions
3015    
3016     diff --git a/selftest/knownfail.d/samba3.substiutions b/selftest/knownfail.d/samba3.substiutions
3017     deleted file mode 100644
3018     index f116d3b2fcf..00000000000
3019     --- a/selftest/knownfail.d/samba3.substiutions
3020     +++ /dev/null
3021     @@ -1 +0,0 @@
3022     -^samba3.substitutions.Test.login.to.share.with.substitution.for.valid.users
3023     diff --git a/source3/smbd/share_access.c b/source3/smbd/share_access.c
3024     index 3cbf7f318a2..0705e197975 100644
3025     --- a/source3/smbd/share_access.c
3026     +++ b/source3/smbd/share_access.c
3027     @@ -79,7 +79,23 @@ static bool token_contains_name(TALLOC_CTX *mem_ctx,
3028     enum lsa_SidType type;
3029    
3030     if (username != NULL) {
3031     - name = talloc_sub_basic(mem_ctx, username, domain, name);
3032     + size_t domain_len = strlen(domain);
3033     +
3034     + /* Check if username starts with domain name */
3035     + if (domain_len > 0) {
3036     + const char *sep = lp_winbind_separator();
3037     + int cmp = strncasecmp_m(username, domain, domain_len);
3038     + if (cmp == 0 && sep[0] == username[domain_len]) {
3039     + /* Move after the winbind separator */
3040     + domain_len += 1;
3041     + } else {
3042     + domain_len = 0;
3043     + }
3044     + }
3045     + name = talloc_sub_basic(mem_ctx,
3046     + username + domain_len,
3047     + domain,
3048     + name);
3049     }
3050     if (sharename != NULL) {
3051     name = talloc_string_sub(mem_ctx, name, "%S", sharename);
3052     --
3053     2.39.0
3054    
3055    
3056     From d93ddae23e1b378f771134e93d1b15e61e2278af Mon Sep 17 00:00:00 2001
3057     From: Andreas Schneider <asn@samba.org>
3058     Date: Thu, 9 Jul 2020 11:48:26 +0200
3059     Subject: [PATCH 033/142] docs: Fix documentation for require_membership_of of
3060     pam_winbind
3061    
3062     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14358
3063    
3064     Signed-off-by: Andreas Schneider <asn@samba.org>
3065     Reviewed-by: Alexander Bokovoy <ab@samba.org>
3066     (cherry picked from commit 4c74db6978c682f8ba4e74a6ee8157cfcbb54971)
3067     ---
3068     docs-xml/manpages/pam_winbind.8.xml | 8 +++++---
3069     1 file changed, 5 insertions(+), 3 deletions(-)
3070    
3071     diff --git a/docs-xml/manpages/pam_winbind.8.xml b/docs-xml/manpages/pam_winbind.8.xml
3072     index a9a227f1647..a61fb2d58e5 100644
3073     --- a/docs-xml/manpages/pam_winbind.8.xml
3074     +++ b/docs-xml/manpages/pam_winbind.8.xml
3075     @@ -84,9 +84,11 @@
3076     If this option is set, pam_winbind will only succeed if the user is a member of the given SID or NAME. A SID
3077     can be either a group-SID, an alias-SID or even an user-SID. It is also possible to give a NAME instead of the
3078     SID. That name must have the form: <parameter>MYDOMAIN\mygroup</parameter> or
3079     - <parameter>MYDOMAIN\myuser</parameter>. pam_winbind will, in that case, lookup the SID internally. Note that
3080     - NAME may not contain any spaces. It is thus recommended to only use SIDs. You can verify the list of SIDs a
3081     - user is a member of with <command>wbinfo --user-sids=SID</command>.
3082     + <parameter>MYDOMAIN\myuser</parameter> (where '\' character corresponds to the value of
3083     + <parameter>winbind separator</parameter> parameter). It is also possible to use a UPN in the form
3084     + <parameter>user@REALM</parameter> or <parameter>group@REALM</parameter>. pam_winbind will, in that case, lookup
3085     + the SID internally. Note that NAME may not contain any spaces. It is thus recommended to only use SIDs. You can
3086     + verify the list of SIDs a user is a member of with <command>wbinfo --user-sids=SID</command>.
3087     </para>
3088    
3089     <para>
3090     --
3091     2.39.0
3092    
3093    
3094     From c9aea952eb3f8d83701abd6db4d48c8d93a8517a Mon Sep 17 00:00:00 2001
3095     From: Andreas Schneider <asn@samba.org>
3096     Date: Fri, 17 Jul 2020 12:14:16 +0200
3097     Subject: [PATCH 034/142] docs: Fix documentation for require_membership_of of
3098     pam_winbind.conf
3099    
3100     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14358
3101    
3102     Signed-off-by: Andreas Schneider <asn@samba.org>
3103     Reviewed-by: Isaac Boukris <iboukris@samba.org>
3104     (cherry picked from commit 71b7140fd0a33e7e8c5bf37c2897cea8224b3f01)
3105     ---
3106     docs-xml/manpages/pam_winbind.conf.5.xml | 9 ++++++---
3107     1 file changed, 6 insertions(+), 3 deletions(-)
3108    
3109     diff --git a/docs-xml/manpages/pam_winbind.conf.5.xml b/docs-xml/manpages/pam_winbind.conf.5.xml
3110     index fcac1ee7036..d81a0bd6eba 100644
3111     --- a/docs-xml/manpages/pam_winbind.conf.5.xml
3112     +++ b/docs-xml/manpages/pam_winbind.conf.5.xml
3113     @@ -69,9 +69,12 @@
3114     If this option is set, pam_winbind will only succeed if the user is a member of the given SID or NAME. A SID
3115     can be either a group-SID, an alias-SID or even an user-SID. It is also possible to give a NAME instead of the
3116     SID. That name must have the form: <parameter>MYDOMAIN\mygroup</parameter> or
3117     - <parameter>MYDOMAIN\myuser</parameter>. pam_winbind will, in that case, lookup the SID internally. Note that
3118     - NAME may not contain any spaces. It is thus recommended to only use SIDs. You can verify the list of SIDs a
3119     - user is a member of with <command>wbinfo --user-sids=SID</command>. This setting is empty by default.
3120     + <parameter>MYDOMAIN\myuser</parameter> (where '\' character corresponds to the value of
3121     + <parameter>winbind separator</parameter> parameter). It is also possible to use a UPN in the form
3122     + <parameter>user@REALM</parameter> or <parameter>group@REALM</parameter>. pam_winbind will, in that case, lookup
3123     + the SID internally. Note that NAME may not contain any spaces. It is thus recommended to only use SIDs. You can
3124     + verify the list of SIDs a user is a member of with <command>wbinfo --user-sids=SID</command>.
3125     + This setting is empty by default.
3126     </para>
3127     <para>This option only operates during password authentication, and will not restrict access if a password is not required for any reason (such as SSH key-based login).</para>
3128     </listitem>
3129     --
3130     2.39.0
3131    
3132    
3133     From b04be6ffd3a1c9eda1f1dc78d60ad7b3a9b7471d Mon Sep 17 00:00:00 2001
3134     From: Isaac Boukris <iboukris@gmail.com>
3135     Date: Thu, 11 Jun 2020 21:05:07 +0300
3136     Subject: [PATCH 035/142] Fix a typo in recent net man page changes
3137    
3138     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14406
3139    
3140     Signed-off-by: Isaac Boukris <iboukris@samba.org>
3141     Reviewed-by: Andreas Schneider <asn@samba.org>
3142     (cherry picked from commit 4e51e832176a99f2a841c7a0d78fb0424f02956e)
3143     ---
3144     docs-xml/manpages/net.8.xml | 2 +-
3145     1 file changed, 1 insertion(+), 1 deletion(-)
3146    
3147     diff --git a/docs-xml/manpages/net.8.xml b/docs-xml/manpages/net.8.xml
3148     index 69e18df8b6c..9b1d4458acc 100644
3149     --- a/docs-xml/manpages/net.8.xml
3150     +++ b/docs-xml/manpages/net.8.xml
3151     @@ -470,7 +470,7 @@ joining the domain.
3152     </para>
3153    
3154     <para>
3155     -[FQDN] (ADS only) set the dnsHosName attribute during the join.
3156     +[FQDN] (ADS only) set the dnsHostName attribute during the join.
3157     The default format is netbiosname.dnsdomain.
3158     </para>
3159    
3160     --
3161     2.39.0
3162    
3163    
3164     From a5a7dac759c2570861732c68efefb62371a29565 Mon Sep 17 00:00:00 2001
3165     From: Isaac Boukris <iboukris@gmail.com>
3166     Date: Tue, 16 Jun 2020 22:01:49 +0300
3167     Subject: [PATCH 036/142] selftest: add tests for binary
3168     msDS-AdditionalDnsHostName
3169    
3170     Like the short names added implicitly by Windows DC.
3171    
3172     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14406
3173    
3174     Signed-off-by: Isaac Boukris <iboukris@samba.org>
3175     Reviewed-by: Andreas Schneider <asn@samba.org>
3176     (cherry picked from commit 4605d7aec5caf494a23f2c9800d6689f710ffbce)
3177     ---
3178     selftest/knownfail.d/binary_addl_hostname | 3 +++
3179     testprogs/blackbox/test_net_ads.sh | 22 ++++++++++++++++++++++
3180     2 files changed, 25 insertions(+)
3181     create mode 100644 selftest/knownfail.d/binary_addl_hostname
3182    
3183     diff --git a/selftest/knownfail.d/binary_addl_hostname b/selftest/knownfail.d/binary_addl_hostname
3184     new file mode 100644
3185     index 00000000000..559db1df507
3186     --- /dev/null
3187     +++ b/selftest/knownfail.d/binary_addl_hostname
3188     @@ -0,0 +1,3 @@
3189     +^samba4.blackbox.net_ads.dns alias1 check keytab
3190     +^samba4.blackbox.net_ads.dns alias2 check keytab
3191     +^samba4.blackbox.net_ads.addl short check keytab
3192     diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh
3193     index 85257f445d8..eef4a31a6a7 100755
3194     --- a/testprogs/blackbox/test_net_ads.sh
3195     +++ b/testprogs/blackbox/test_net_ads.sh
3196     @@ -41,6 +41,11 @@ if [ -x "$BINDIR/ldbdel" ]; then
3197     ldbdel="$BINDIR/ldbdel"
3198     fi
3199    
3200     +ldbmodify="ldbmodify"
3201     +if [ -x "$BINDIR/ldbmodify" ]; then
3202     + ldbmodify="$BINDIR/ldbmodify"
3203     +fi
3204     +
3205     # Load test functions
3206     . `dirname $0`/subunit.sh
3207    
3208     @@ -217,12 +222,29 @@ testit_grep "dns alias SPN" $dns_alias2 $VALGRIND $net_tool ads search -P samacc
3209     testit_grep "dns alias addl" $dns_alias1 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ msDS-AdditionalDnsHostName || failed=`expr $failed + 1`
3210     testit_grep "dns alias addl" $dns_alias2 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ msDS-AdditionalDnsHostName || failed=`expr $failed + 1`
3211    
3212     +# Test binary msDS-AdditionalDnsHostName like ones added by Windows DC
3213     +short_alias_file="$PREFIX_ABS/short_alias_file"
3214     +printf 'short_alias\0$' > $short_alias_file
3215     +cat > $PREFIX_ABS/tmpldbmodify <<EOF
3216     +dn: CN=$HOSTNAME,$computers_dn
3217     +changetype: modify
3218     +add: msDS-AdditionalDnsHostName
3219     +msDS-AdditionalDnsHostName:< file://$short_alias_file
3220     +EOF
3221     +
3222     +testit "add binary msDS-AdditionalDnsHostName" $VALGRIND $ldbmodify -k yes -U$DC_USERNAME%$DC_PASSWORD -H ldap://$SERVER.$REALM $PREFIX_ABS/tmpldbmodify || failed=`expr $failed + 1`
3223     +
3224     +testit_grep "addl short alias" short_alias $ldbsearch --show-binary -U$DC_USERNAME%$DC_PASSWORD -H ldap://$SERVER.$REALM -s base -b "CN=$HOSTNAME,CN=Computers,$base_dn" msDS-AdditionalDnsHostName || failed=`expr $failed + 1`
3225     +
3226     +rm -f $PREFIX_ABS/tmpldbmodify $short_alias_file
3227     +
3228     dedicated_keytab_file="$PREFIX_ABS/test_dns_aliases_dedicated_krb5.keytab"
3229    
3230     testit "dns alias create_keytab" $VALGRIND $net_tool ads keytab create --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
3231    
3232     testit_grep "dns alias1 check keytab" "host/${dns_alias1}@$REALM" $net_tool ads keytab list --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
3233     testit_grep "dns alias2 check keytab" "host/${dns_alias2}@$REALM" $net_tool ads keytab list --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
3234     +testit_grep "addl short check keytab" "host/short_alias@$REALM" $net_tool ads keytab list --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
3235    
3236     rm -f $dedicated_keytab_file
3237    
3238     --
3239     2.39.0
3240    
3241    
3242     From 2769976aaa13474d2b5ee7b58ee17d5824dfa5a2 Mon Sep 17 00:00:00 2001
3243     From: Isaac Boukris <iboukris@gmail.com>
3244     Date: Thu, 11 Jun 2020 16:51:27 +0300
3245     Subject: [PATCH 037/142] Properly handle msDS-AdditionalDnsHostName returned
3246     from Windows DC
3247    
3248     Windows DC adds short names for each specified msDS-AdditionalDnsHostName
3249     attribute, but these have a suffix of "\0$" and thus fail with
3250     ldap_get_values(), use ldap_get_values_len() instead.
3251    
3252     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14406
3253    
3254     Signed-off-by: Isaac Boukris <iboukris@samba.org>
3255     Reviewed-by: Andreas Schneider <asn@samba.org>
3256    
3257     Autobuild-User(master): Isaac Boukris <iboukris@samba.org>
3258     Autobuild-Date(master): Thu Jun 18 16:43:47 UTC 2020 on sn-devel-184
3259    
3260     (cherry picked from commit 9a447fb7e0701bf8b2fd922aed44d89f40420251)
3261     ---
3262     selftest/knownfail.d/binary_addl_hostname | 3 --
3263     source3/libads/ldap.c | 38 +++++++++++++++++++++--
3264     2 files changed, 35 insertions(+), 6 deletions(-)
3265     delete mode 100644 selftest/knownfail.d/binary_addl_hostname
3266    
3267     diff --git a/selftest/knownfail.d/binary_addl_hostname b/selftest/knownfail.d/binary_addl_hostname
3268     deleted file mode 100644
3269     index 559db1df507..00000000000
3270     --- a/selftest/knownfail.d/binary_addl_hostname
3271     +++ /dev/null
3272     @@ -1,3 +0,0 @@
3273     -^samba4.blackbox.net_ads.dns alias1 check keytab
3274     -^samba4.blackbox.net_ads.dns alias2 check keytab
3275     -^samba4.blackbox.net_ads.addl short check keytab
3276     diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
3277     index 02a628ee0e6..2684bba63ec 100644
3278     --- a/source3/libads/ldap.c
3279     +++ b/source3/libads/ldap.c
3280     @@ -3664,6 +3664,40 @@ out:
3281     /********************************************************************
3282     ********************************************************************/
3283    
3284     +static char **get_addl_hosts(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
3285     + LDAPMessage *msg, size_t *num_values)
3286     +{
3287     + const char *field = "msDS-AdditionalDnsHostName";
3288     + struct berval **values = NULL;
3289     + char **ret = NULL;
3290     + size_t i, converted_size;
3291     +
3292     + values = ldap_get_values_len(ads->ldap.ld, msg, field);
3293     + if (values == NULL) {
3294     + return NULL;
3295     + }
3296     +
3297     + *num_values = ldap_count_values_len(values);
3298     +
3299     + ret = talloc_array(mem_ctx, char *, *num_values + 1);
3300     + if (ret == NULL) {
3301     + ldap_value_free_len(values);
3302     + return NULL;
3303     + }
3304     +
3305     + for (i = 0; i < *num_values; i++) {
3306     + if (!pull_utf8_talloc(mem_ctx, &ret[i], values[i]->bv_val,
3307     + &converted_size)) {
3308     + ldap_value_free_len(values);
3309     + return NULL;
3310     + }
3311     + }
3312     + ret[i] = NULL;
3313     +
3314     + ldap_value_free_len(values);
3315     + return ret;
3316     +}
3317     +
3318     ADS_STATUS ads_get_additional_dns_hostnames(TALLOC_CTX *mem_ctx,
3319     ADS_STRUCT *ads,
3320     const char *machine_name,
3321     @@ -3689,9 +3723,7 @@ ADS_STATUS ads_get_additional_dns_hostnames(TALLOC_CTX *mem_ctx,
3322     goto done;
3323     }
3324    
3325     - *hostnames_array = ads_pull_strings(ads, mem_ctx, res,
3326     - "msDS-AdditionalDnsHostName",
3327     - num_hostnames);
3328     + *hostnames_array = get_addl_hosts(ads, mem_ctx, res, num_hostnames);
3329     if (*hostnames_array == NULL) {
3330     DEBUG(1, ("Host account for %s does not have msDS-AdditionalDnsHostName.\n",
3331     machine_name));
3332     --
3333     2.39.0
3334    
3335    
3336     From 9727953d482a3849d4ac1f40486bc567f6b77067 Mon Sep 17 00:00:00 2001
3337     From: Isaac Boukris <iboukris@gmail.com>
3338     Date: Sat, 20 Jun 2020 17:17:33 +0200
3339     Subject: [PATCH 038/142] Fix usage of ldap_get_values_len for
3340     msDS-AdditionalDnsHostName
3341    
3342     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14406
3343    
3344     Signed-off-by: Isaac Boukris <iboukris@samba.org>
3345     Reviewed-by: Andreas Schneider <asn@samba.org>
3346    
3347     Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
3348     Autobuild-Date(master): Mon Jun 22 09:59:04 UTC 2020 on sn-devel-184
3349    
3350     (cherry picked from commit f9dd67355ba35539d7ae1774d5135fd05d747b3f)
3351     ---
3352     source3/libads/ldap.c | 8 ++++++--
3353     1 file changed, 6 insertions(+), 2 deletions(-)
3354    
3355     diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
3356     index 2684bba63ec..d1ce9cee2f0 100644
3357     --- a/source3/libads/ldap.c
3358     +++ b/source3/libads/ldap.c
3359     @@ -3686,8 +3686,12 @@ static char **get_addl_hosts(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
3360     }
3361    
3362     for (i = 0; i < *num_values; i++) {
3363     - if (!pull_utf8_talloc(mem_ctx, &ret[i], values[i]->bv_val,
3364     - &converted_size)) {
3365     + ret[i] = NULL;
3366     + if (!convert_string_talloc(mem_ctx, CH_UTF8, CH_UNIX,
3367     + values[i]->bv_val,
3368     + strnlen(values[i]->bv_val,
3369     + values[i]->bv_len),
3370     + &ret[i], &converted_size)) {
3371     ldap_value_free_len(values);
3372     return NULL;
3373     }
3374     --
3375     2.39.0
3376    
3377    
3378     From ec4cfe786d8c3cb67bb0e9224ae1822902c672d3 Mon Sep 17 00:00:00 2001
3379     From: Isaac Boukris <iboukris@gmail.com>
3380     Date: Tue, 15 Dec 2020 15:17:04 +0100
3381     Subject: [PATCH 039/142] HACK:s3:winbind: Rely on the domain child for online
3382     check
3383    
3384     ---
3385     source3/winbindd/winbindd_cm.c | 9 +++++++++
3386     source3/winbindd/winbindd_dual.c | 3 +++
3387     2 files changed, 12 insertions(+)
3388    
3389     diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
3390     index 4bd03ed8b7a..502331f7260 100644
3391     --- a/source3/winbindd/winbindd_cm.c
3392     +++ b/source3/winbindd/winbindd_cm.c
3393     @@ -89,6 +89,8 @@
3394     #undef DBGC_CLASS
3395     #define DBGC_CLASS DBGC_WINBIND
3396    
3397     +extern bool wb_idmap_child;
3398     +
3399     struct dc_name_ip {
3400     fstring name;
3401     struct sockaddr_storage ss;
3402     @@ -176,6 +178,13 @@ static void msg_try_to_go_online(struct messaging_context *msg,
3403     continue;
3404     }
3405    
3406     + if (wb_child_domain() == NULL && !wb_idmap_child) {
3407     + DEBUG(5,("msg_try_to_go_online: domain %s "
3408     + "NOT CONNECTING IN MAIN PROCESS.\n", domainname));
3409     + domain->online = true;
3410     + continue;
3411     + }
3412     +
3413     /* This call takes care of setting the online
3414     flag to true if we connected, or re-adding
3415     the offline handler if false. Bypasses online
3416     diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
3417     index 6e3277e5529..35b76a367aa 100644
3418     --- a/source3/winbindd/winbindd_dual.c
3419     +++ b/source3/winbindd/winbindd_dual.c
3420     @@ -1612,6 +1612,8 @@ static void child_handler(struct tevent_context *ev, struct tevent_fd *fde,
3421     }
3422     }
3423    
3424     +bool wb_idmap_child;
3425     +
3426     static bool fork_domain_child(struct winbindd_child *child)
3427     {
3428     int fdpair[2];
3429     @@ -1715,6 +1717,7 @@ static bool fork_domain_child(struct winbindd_child *child)
3430     setproctitle("domain child [%s]", child_domain->name);
3431     } else if (child == idmap_child()) {
3432     setproctitle("idmap child");
3433     + wb_idmap_child = true;
3434     }
3435    
3436     /* Handle online/offline messages. */
3437     --
3438     2.39.0
3439    
3440    
3441     From 958bed1a1e5c9f334a1859bef14f4fe1657c3e49 Mon Sep 17 00:00:00 2001
3442     From: Andreas Schneider <asn@samba.org>
3443     Date: Wed, 9 Sep 2020 16:00:52 +0200
3444     Subject: [PATCH 040/142] s3:smbd: Use fsp al the talloc memory context
3445    
3446     Somehow the lck pointer gets freed before we call TALLOC_FREE().
3447    
3448     Signed-off-by: Andreas Schneider <asn@samba.org>
3449     Reviewed-by: Guenther Deschner <gd@samba.org>
3450     Reviewed-by: Alexander Bokovoy <ab@samba.org>
3451     ---
3452     source3/smbd/open.c | 2 +-
3453     1 file changed, 1 insertion(+), 1 deletion(-)
3454    
3455     diff --git a/source3/smbd/open.c b/source3/smbd/open.c
3456     index de557f53a20..9a24e331ab1 100644
3457     --- a/source3/smbd/open.c
3458     +++ b/source3/smbd/open.c
3459     @@ -4239,7 +4239,7 @@ static NTSTATUS open_directory(connection_struct *conn,
3460     return NT_STATUS_ACCESS_DENIED;
3461     }
3462    
3463     - lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
3464     + lck = get_share_mode_lock(fsp, fsp->file_id,
3465     conn->connectpath, smb_dname,
3466     &mtimespec);
3467    
3468     --
3469     2.39.0
3470    
3471    
3472     From 2591ae5d6a1dbd71391801b7bdf20bd37c8e8375 Mon Sep 17 00:00:00 2001
3473     From: Andreas Schneider <asn@samba.org>
3474     Date: Wed, 3 Feb 2021 12:58:31 +0100
3475     Subject: [PATCH 041/142] Revert "s3:smbd: Use fsp al the talloc memory
3476     context"
3477    
3478     This reverts commit 958bed1a1e5c9f334a1859bef14f4fe1657c3e49.
3479     ---
3480     source3/smbd/open.c | 2 +-
3481     1 file changed, 1 insertion(+), 1 deletion(-)
3482    
3483     diff --git a/source3/smbd/open.c b/source3/smbd/open.c
3484     index 9a24e331ab1..de557f53a20 100644
3485     --- a/source3/smbd/open.c
3486     +++ b/source3/smbd/open.c
3487     @@ -4239,7 +4239,7 @@ static NTSTATUS open_directory(connection_struct *conn,
3488     return NT_STATUS_ACCESS_DENIED;
3489     }
3490    
3491     - lck = get_share_mode_lock(fsp, fsp->file_id,
3492     + lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
3493     conn->connectpath, smb_dname,
3494     &mtimespec);
3495    
3496     --
3497     2.39.0
3498    
3499    
3500     From 2438619ec7ef18816f6b92c87a094851223d2bb1 Mon Sep 17 00:00:00 2001
3501     From: Khem Raj <raj.khem@gmail.com>
3502     Date: Wed, 22 Jul 2020 22:42:09 -0700
3503     Subject: [PATCH 042/142] nsswitch/nsstest.c: Avoid nss function conflicts with
3504     glibc nss.h
3505    
3506     glibc 2.32 will define these varibles [1] which results in conflicts
3507     with these static function names, therefore prefix these function names
3508     with samba_ to avoid it
3509    
3510     [1] https://sourceware.org/git/?p=glibc.git;a=commit;h=499a92df8b9fc64a054cf3b7f728f8967fc1da7d
3511    
3512     Signed-off-by: Khem Raj <raj.khem@gmail.com>
3513     Reviewed-by: Volker Lendecke <vl@samba.org>
3514     Reviewed-by: Noel Power <npower@samba.org>
3515    
3516     Autobuild-User(master): Noel Power <npower@samba.org>
3517     Autobuild-Date(master): Tue Jul 28 10:52:00 UTC 2020 on sn-devel-184
3518    
3519     (cherry picked from commit 6e496aa3635557b59792e469f7c7f8eccd822322)
3520     ---
3521     nsswitch/nsstest.c | 16 ++++++++--------
3522     1 file changed, 8 insertions(+), 8 deletions(-)
3523    
3524     diff --git a/nsswitch/nsstest.c b/nsswitch/nsstest.c
3525     index 6d92806cffc..46f96795f39 100644
3526     --- a/nsswitch/nsstest.c
3527     +++ b/nsswitch/nsstest.c
3528     @@ -137,7 +137,7 @@ static struct passwd *nss_getpwuid(uid_t uid)
3529     return &pwd;
3530     }
3531    
3532     -static void nss_setpwent(void)
3533     +static void samba_nss_setpwent(void)
3534     {
3535     NSS_STATUS (*_nss_setpwent)(void) =
3536     (NSS_STATUS(*)(void))find_fn("setpwent");
3537     @@ -152,7 +152,7 @@ static void nss_setpwent(void)
3538     }
3539     }
3540    
3541     -static void nss_endpwent(void)
3542     +static void samba_nss_endpwent(void)
3543     {
3544     NSS_STATUS (*_nss_endpwent)(void) =
3545     (NSS_STATUS (*)(void))find_fn("endpwent");
3546     @@ -284,7 +284,7 @@ again:
3547     return &grp;
3548     }
3549    
3550     -static void nss_setgrent(void)
3551     +static void samba_nss_setgrent(void)
3552     {
3553     NSS_STATUS (*_nss_setgrent)(void) =
3554     (NSS_STATUS (*)(void))find_fn("setgrent");
3555     @@ -299,7 +299,7 @@ static void nss_setgrent(void)
3556     }
3557     }
3558    
3559     -static void nss_endgrent(void)
3560     +static void samba_nss_endgrent(void)
3561     {
3562     NSS_STATUS (*_nss_endgrent)(void) =
3563     (NSS_STATUS (*)(void))find_fn("endgrent");
3564     @@ -396,7 +396,7 @@ static void nss_test_users(void)
3565     {
3566     struct passwd *pwd;
3567    
3568     - nss_setpwent();
3569     + samba_nss_setpwent();
3570     /* loop over all users */
3571     while ((pwd = nss_getpwent())) {
3572     printf("Testing user %s\n", pwd->pw_name);
3573     @@ -418,14 +418,14 @@ static void nss_test_users(void)
3574     printf("initgroups: "); nss_test_initgroups(pwd->pw_name, pwd->pw_gid);
3575     printf("\n");
3576     }
3577     - nss_endpwent();
3578     + samba_nss_endpwent();
3579     }
3580    
3581     static void nss_test_groups(void)
3582     {
3583     struct group *grp;
3584    
3585     - nss_setgrent();
3586     + samba_nss_setgrent();
3587     /* loop over all groups */
3588     while ((grp = nss_getgrent())) {
3589     printf("Testing group %s\n", grp->gr_name);
3590     @@ -446,7 +446,7 @@ static void nss_test_groups(void)
3591     printf("getgrgid: "); print_group(grp);
3592     printf("\n");
3593     }
3594     - nss_endgrent();
3595     + samba_nss_endgrent();
3596     }
3597    
3598     static void nss_test_errors(void)
3599     --
3600     2.39.0
3601    
3602    
3603     From d5410b038bb3b1d31783c0d825dc933497f6eeaa Mon Sep 17 00:00:00 2001
3604     From: Andreas Schneider <asn@samba.org>
3605     Date: Wed, 3 Feb 2021 10:30:08 +0100
3606     Subject: [PATCH 043/142] lib:util: Add basic memcache unit test
3607    
3608     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14625
3609    
3610     Signed-off-by: Andreas Schneider <asn@samba.org>
3611     Reviewed-by: Ralph Boehme <slow@samba.org>
3612     (cherry picked from commit bebbf621d6052f797c5cf19a2a9bbc13e699d3f0)
3613     ---
3614     lib/util/tests/test_memcache.c | 122 +++++++++++++++++++++++++++++++++
3615     lib/util/wscript_build | 6 ++
3616     selftest/tests.py | 2 +
3617     3 files changed, 130 insertions(+)
3618     create mode 100644 lib/util/tests/test_memcache.c
3619    
3620     diff --git a/lib/util/tests/test_memcache.c b/lib/util/tests/test_memcache.c
3621     new file mode 100644
3622     index 00000000000..8ea5e5b042e
3623     --- /dev/null
3624     +++ b/lib/util/tests/test_memcache.c
3625     @@ -0,0 +1,122 @@
3626     +/*
3627     + * Unix SMB/CIFS implementation.
3628     + *
3629     + * Copyright (C) 2021 Andreas Schneider <asn@samba.org>
3630     + *
3631     + * This program is free software; you can redistribute it and/or modify
3632     + * it under the terms of the GNU General Public License as published by
3633     + * the Free Software Foundation; either version 3 of the License, or
3634     + * (at your option) any later version.
3635     + *
3636     + * This program is distributed in the hope that it will be useful,
3637     + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3638     + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3639     + * GNU General Public License for more details.
3640     + *
3641     + * You should have received a copy of the GNU General Public License
3642     + * along with this program. If not, see <http://www.gnu.org/licenses/>.
3643     + */
3644     +
3645     +#include <stdarg.h>
3646     +#include <stddef.h>
3647     +#include <stdint.h>
3648     +#include <setjmp.h>
3649     +#include <cmocka.h>
3650     +
3651     +#include "lib/replace/replace.h"
3652     +#include "lib/util/talloc_stack.h"
3653     +#include "lib/util/memcache.h"
3654     +
3655     +static int setup_talloc_context(void **state)
3656     +{
3657     + TALLOC_CTX *frame = talloc_stackframe();
3658     +
3659     + *state = frame;
3660     + return 0;
3661     +}
3662     +
3663     +static int teardown_talloc_context(void **state)
3664     +{
3665     + TALLOC_CTX *frame = *state;
3666     + TALLOC_FREE(frame);
3667     + return 0;
3668     +}
3669     +
3670     +static void torture_memcache_init(void **state)
3671     +{
3672     + TALLOC_CTX *mem_ctx = *state;
3673     + struct memcache *cache = NULL;
3674     +
3675     + cache = memcache_init(mem_ctx, 0);
3676     + assert_non_null(cache);
3677     +
3678     + TALLOC_FREE(cache);
3679     +
3680     + cache = memcache_init(mem_ctx, 10);
3681     + assert_non_null(cache);
3682     +
3683     + TALLOC_FREE(cache);
3684     +}
3685     +
3686     +static void torture_memcache_add_lookup_delete(void **state)
3687     +{
3688     + TALLOC_CTX *mem_ctx = *state;
3689     + struct memcache *cache = NULL;
3690     + DATA_BLOB key1, key2;
3691     + char *path1 = NULL, *path2 = NULL;
3692     +
3693     + cache = memcache_init(mem_ctx, 0);
3694     + assert_non_null(cache);
3695     +
3696     + key1 = data_blob_const("key1", 4);
3697     + path1 = talloc_strdup(mem_ctx, "/tmp/one");
3698     + assert_non_null(path1);
3699     +
3700     + key2 = data_blob_const("key2", 4);
3701     + path2 = talloc_strdup(mem_ctx, "/tmp/two");
3702     + assert_non_null(path1);
3703     +
3704     + memcache_add_talloc(cache, GETWD_CACHE, key1, &path1);
3705     + assert_null(path1);
3706     +
3707     + memcache_add_talloc(cache, GETWD_CACHE, key2, &path2);
3708     + assert_null(path2);
3709     +
3710     + path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1);
3711     + assert_non_null(path1);
3712     + assert_string_equal(path1, "/tmp/one");
3713     +
3714     + path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2);
3715     + assert_non_null(path2);
3716     + assert_string_equal(path2, "/tmp/two");
3717     +
3718     + memcache_delete(cache, GETWD_CACHE, key1);
3719     + path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1);
3720     + assert_null(path1);
3721     +
3722     + memcache_flush(cache, GETWD_CACHE);
3723     + path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2);
3724     + assert_null(path2);
3725     +
3726     + TALLOC_FREE(cache);
3727     +}
3728     +
3729     +int main(int argc, char *argv[])
3730     +{
3731     + int rc;
3732     + const struct CMUnitTest tests[] = {
3733     + cmocka_unit_test(torture_memcache_init),
3734     + cmocka_unit_test(torture_memcache_add_lookup_delete),
3735     + };
3736     +
3737     + if (argc == 2) {
3738     + cmocka_set_test_filter(argv[1]);
3739     + }
3740     + cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
3741     +
3742     + rc = cmocka_run_group_tests(tests,
3743     + setup_talloc_context,
3744     + teardown_talloc_context);
3745     +
3746     + return rc;
3747     +}
3748     diff --git a/lib/util/wscript_build b/lib/util/wscript_build
3749     index fd3027eff77..229dbd5ef6a 100644
3750     --- a/lib/util/wscript_build
3751     +++ b/lib/util/wscript_build
3752     @@ -256,3 +256,9 @@ else:
3753     deps='cmocka replace talloc samba-util',
3754     local_include=False,
3755     install=False)
3756     +
3757     + bld.SAMBA_BINARY('test_memcache',
3758     + source='tests/test_memcache.c',
3759     + deps='cmocka replace talloc samba-util',
3760     + local_include=False,
3761     + install=False)
3762     diff --git a/selftest/tests.py b/selftest/tests.py
3763     index e7639c4da27..e3f7d9acb4a 100644
3764     --- a/selftest/tests.py
3765     +++ b/selftest/tests.py
3766     @@ -254,6 +254,8 @@ plantestsuite("samba.unittests.ms_fnmatch", "none",
3767     [os.path.join(bindir(), "default/lib/util/test_ms_fnmatch")])
3768     plantestsuite("samba.unittests.util_paths", "none",
3769     [os.path.join(bindir(), "default/lib/util/test_util_paths")])
3770     +plantestsuite("samba.unittests.memcache", "none",
3771     + [os.path.join(bindir(), "default/lib/util/test_memcache")])
3772     plantestsuite("samba.unittests.ntlm_check", "none",
3773     [os.path.join(bindir(), "default/libcli/auth/test_ntlm_check")])
3774     plantestsuite("samba.unittests.test_registry_regfio", "none",
3775     --
3776     2.39.0
3777    
3778    
3779     From 7f6661b3c60319073d7fd58906b9a3728f421fed Mon Sep 17 00:00:00 2001
3780     From: Andreas Schneider <asn@samba.org>
3781     Date: Wed, 3 Feb 2021 10:37:12 +0100
3782     Subject: [PATCH 044/142] lib:util: Add cache oversize test for memcache
3783    
3784     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14625
3785    
3786     Signed-off-by: Andreas Schneider <asn@samba.org>
3787     Reviewed-by: Ralph Boehme <slow@samba.org>
3788     (cherry picked from commit 00543ab3b29e3fbfe8314e51919629803e14ede6)
3789     ---
3790     lib/util/tests/test_memcache.c | 39 ++++++++++++++++++++++++++++++++++
3791     selftest/knownfail.d/memcache | 1 +
3792     2 files changed, 40 insertions(+)
3793     create mode 100644 selftest/knownfail.d/memcache
3794    
3795     diff --git a/lib/util/tests/test_memcache.c b/lib/util/tests/test_memcache.c
3796     index 8ea5e5b042e..8a3997817c1 100644
3797     --- a/lib/util/tests/test_memcache.c
3798     +++ b/lib/util/tests/test_memcache.c
3799     @@ -98,6 +98,44 @@ static void torture_memcache_add_lookup_delete(void **state)
3800     path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2);
3801     assert_null(path2);
3802    
3803     + TALLOC_FREE(path1);
3804     + TALLOC_FREE(path2);
3805     + TALLOC_FREE(cache);
3806     +}
3807     +
3808     +static void torture_memcache_add_oversize(void **state)
3809     +{
3810     + TALLOC_CTX *mem_ctx = *state;
3811     + struct memcache *cache = NULL;
3812     + DATA_BLOB key1, key2;
3813     + char *path1 = NULL, *path2 = NULL;
3814     +
3815     + cache = memcache_init(mem_ctx, 10);
3816     + assert_non_null(cache);
3817     +
3818     + key1 = data_blob_const("key1", 4);
3819     + path1 = talloc_strdup(mem_ctx, "/tmp/one");
3820     + assert_non_null(path1);
3821     +
3822     + key2 = data_blob_const("key2", 4);
3823     + path2 = talloc_strdup(mem_ctx, "/tmp/two");
3824     + assert_non_null(path1);
3825     +
3826     + memcache_add_talloc(cache, GETWD_CACHE, key1, &path1);
3827     + assert_null(path1);
3828     +
3829     + memcache_add_talloc(cache, GETWD_CACHE, key2, &path2);
3830     + assert_null(path2);
3831     +
3832     + path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1);
3833     + assert_null(path1);
3834     +
3835     + path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2);
3836     + assert_non_null(path2);
3837     + assert_string_equal(path2, "/tmp/two");
3838     +
3839     + TALLOC_FREE(path1);
3840     + TALLOC_FREE(path2);
3841     TALLOC_FREE(cache);
3842     }
3843    
3844     @@ -107,6 +145,7 @@ int main(int argc, char *argv[])
3845     const struct CMUnitTest tests[] = {
3846     cmocka_unit_test(torture_memcache_init),
3847     cmocka_unit_test(torture_memcache_add_lookup_delete),
3848     + cmocka_unit_test(torture_memcache_add_oversize),
3849     };
3850    
3851     if (argc == 2) {
3852     diff --git a/selftest/knownfail.d/memcache b/selftest/knownfail.d/memcache
3853     new file mode 100644
3854     index 00000000000..0a74ace3003
3855     --- /dev/null
3856     +++ b/selftest/knownfail.d/memcache
3857     @@ -0,0 +1 @@
3858     +^samba.unittests.memcache.torture_memcache_add_oversize
3859     --
3860     2.39.0
3861    
3862    
3863     From 53c7f00510556aea15b640254934e514c1d88c25 Mon Sep 17 00:00:00 2001
3864     From: Andreas Schneider <asn@samba.org>
3865     Date: Tue, 2 Feb 2021 18:10:38 +0100
3866     Subject: [PATCH 045/142] lib:util: Avoid free'ing our own pointer
3867     MIME-Version: 1.0
3868     Content-Type: text/plain; charset=UTF-8
3869     Content-Transfer-Encoding: 8bit
3870    
3871     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14625
3872    
3873     Signed-off-by: Andreas Schneider <asn@samba.org>
3874     Reviewed-by: Ralph Boehme <slow@samba.org>
3875    
3876     Autobuild-User(master): Ralph Böhme <slow@samba.org>
3877     Autobuild-Date(master): Wed Feb 3 10:57:01 UTC 2021 on sn-devel-184
3878    
3879     (cherry picked from commit 0bdbe50fac680be3fe21043246b8c75005611351)
3880     ---
3881     lib/util/memcache.c | 19 +++++++++++++++----
3882     selftest/knownfail.d/memcache | 1 -
3883     2 files changed, 15 insertions(+), 5 deletions(-)
3884     delete mode 100644 selftest/knownfail.d/memcache
3885    
3886     diff --git a/lib/util/memcache.c b/lib/util/memcache.c
3887     index 1e616bd0e9a..7b0b27eaddb 100644
3888     --- a/lib/util/memcache.c
3889     +++ b/lib/util/memcache.c
3890     @@ -223,14 +223,25 @@ static void memcache_delete_element(struct memcache *cache,
3891     TALLOC_FREE(e);
3892     }
3893    
3894     -static void memcache_trim(struct memcache *cache)
3895     +static void memcache_trim(struct memcache *cache, struct memcache_element *e)
3896     {
3897     + struct memcache_element *tail = NULL;
3898     +
3899     if (cache->max_size == 0) {
3900     return;
3901     }
3902    
3903     - while ((cache->size > cache->max_size) && DLIST_TAIL(cache->mru)) {
3904     - memcache_delete_element(cache, DLIST_TAIL(cache->mru));
3905     + for (tail = DLIST_TAIL(cache->mru);
3906     + (cache->size > cache->max_size) && (tail != NULL);
3907     + tail = DLIST_TAIL(cache->mru))
3908     + {
3909     + if (tail == e) {
3910     + tail = DLIST_PREV(tail);
3911     + if (tail == NULL) {
3912     + break;
3913     + }
3914     + }
3915     + memcache_delete_element(cache, tail);
3916     }
3917     }
3918    
3919     @@ -351,7 +362,7 @@ void memcache_add(struct memcache *cache, enum memcache_number n,
3920     memcpy(&mtv, cache_value.data, sizeof(mtv));
3921     cache->size += mtv.len;
3922     }
3923     - memcache_trim(cache);
3924     + memcache_trim(cache, e);
3925     }
3926    
3927     void memcache_add_talloc(struct memcache *cache, enum memcache_number n,
3928     diff --git a/selftest/knownfail.d/memcache b/selftest/knownfail.d/memcache
3929     deleted file mode 100644
3930     index 0a74ace3003..00000000000
3931     --- a/selftest/knownfail.d/memcache
3932     +++ /dev/null
3933     @@ -1 +0,0 @@
3934     -^samba.unittests.memcache.torture_memcache_add_oversize
3935     --
3936     2.39.0
3937    
3938    
3939     From 138662453fb421609b4fa30487a53a50c085895f Mon Sep 17 00:00:00 2001
3940     From: Jeremy Allison <jra@samba.org>
3941     Date: Thu, 5 Nov 2020 15:48:08 -0800
3942     Subject: [PATCH 046/142] s3: spoolss: Make parameters in call to
3943     user_ok_token() match all other uses.
3944    
3945     We already have p->session_info->unix_info->unix_name, we don't
3946     need to go through a legacy call to uidtoname(p->session_info->unix_token->uid).
3947    
3948     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14568
3949    
3950     Signed-off-by: Jeremy Allison <jra@samba.org>
3951     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
3952    
3953     Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
3954     Autobuild-Date(master): Mon Nov 9 04:10:45 UTC 2020 on sn-devel-184
3955    
3956     (cherry picked from commit e5e1759057a767f517bf480a2172a36623df2799)
3957     ---
3958     source3/rpc_server/spoolss/srv_spoolss_nt.c | 3 ++-
3959     1 file changed, 2 insertions(+), 1 deletion(-)
3960    
3961     diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
3962     index f32b465afb6..c0f1803c2fa 100644
3963     --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
3964     +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
3965     @@ -1869,7 +1869,8 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
3966     return WERR_ACCESS_DENIED;
3967     }
3968    
3969     - if (!user_ok_token(uidtoname(p->session_info->unix_token->uid), NULL,
3970     + if (!user_ok_token(p->session_info->unix_info->unix_name,
3971     + p->session_info->info->domain_name,
3972     p->session_info->security_token, snum) ||
3973     !W_ERROR_IS_OK(print_access_check(p->session_info,
3974     p->msg_ctx,
3975     --
3976     2.39.0
3977    
3978    
3979     From 9550eb620ff23fb9f9414c9de596789aae64aef1 Mon Sep 17 00:00:00 2001
3980     From: Andreas Schneider <asn@samba.org>
3981     Date: Wed, 11 Nov 2020 13:42:06 +0100
3982     Subject: [PATCH 047/142] s3:smbd: Fix possible null pointer dereference in
3983     token_contains_name()
3984    
3985     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14572
3986    
3987     Signed-off-by: Andreas Schneider <asn@samba.org>
3988     Reviewed-by: Alexander Bokovoy <ab@samba.org>
3989    
3990     Autobuild-User(master): Alexander Bokovoy <ab@samba.org>
3991     Autobuild-Date(master): Thu Nov 12 15:13:47 UTC 2020 on sn-devel-184
3992    
3993     (cherry picked from commit 8036bf9717f83e83c3e4a9cf00fded42e9a5de15)
3994     ---
3995     source3/smbd/share_access.c | 2 +-
3996     1 file changed, 1 insertion(+), 1 deletion(-)
3997    
3998     diff --git a/source3/smbd/share_access.c b/source3/smbd/share_access.c
3999     index 0705e197975..64276c79fbe 100644
4000     --- a/source3/smbd/share_access.c
4001     +++ b/source3/smbd/share_access.c
4002     @@ -79,7 +79,7 @@ static bool token_contains_name(TALLOC_CTX *mem_ctx,
4003     enum lsa_SidType type;
4004    
4005     if (username != NULL) {
4006     - size_t domain_len = strlen(domain);
4007     + size_t domain_len = domain != NULL ? strlen(domain) : 0;
4008    
4009     /* Check if username starts with domain name */
4010     if (domain_len > 0) {
4011     --
4012     2.39.0
4013    
4014    
4015     From 49a19805c6837df04dce449841d011fc67e0a7df Mon Sep 17 00:00:00 2001
4016     From: Volker Lendecke <vl@samba.org>
4017     Date: Sat, 20 Feb 2021 15:50:12 +0100
4018     Subject: [PATCH 048/142] passdb: Simplify sids_to_unixids()
4019    
4020     Best reviewed with "git show -b", there's a "continue" statement that
4021     changes subsequent indentation.
4022    
4023     Decouple lookup status of ids from ID_TYPE_NOT_SPECIFIED
4024    
4025     Bug: https://bugzilla.samba.org/show_bug.cgi?id=14571
4026    
4027     Signed-off-by: Volker Lendecke <vl@samba.org>
4028     Reviewed-by: Jeremy Allison <jra@samba.org>
4029     ---
4030     source3/passdb/lookup_sid.c | 123 +++++++++++++++++++++++++++++-------
4031     1 file changed, 101 insertions(+), 22 deletions(-)
4032    
4033     diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
4034     index 1bb15ccb8b4..186ba17fda6 100644
4035     --- a/source3/passdb/lookup_sid.c
4036     +++ b/source3/passdb/lookup_sid.c
4037     @@ -29,6 +29,7 @@
4038     #include "../libcli/security/security.h"
4039     #include "lib/winbind_util.h"
4040     #include "../librpc/gen_ndr/idmap.h"
4041     +#include "lib/util/bitmap.h"
4042    
4043     static bool lookup_unix_user_name(const char *name, struct dom_sid *sid)
4044     {
4045     @@ -1247,7 +1248,9 @@ bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
4046     {
4047     struct wbcDomainSid *wbc_sids = NULL;
4048     struct wbcUnixId *wbc_ids = NULL;
4049     + struct bitmap *found = NULL;
4050     uint32_t i, num_not_cached;
4051     + uint32_t wbc_ids_size = 0;
4052     wbcErr err;
4053     bool ret = false;
4054    
4055     @@ -1255,6 +1258,20 @@ bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
4056     if (wbc_sids == NULL) {
4057     return false;
4058     }
4059     + found = bitmap_talloc(wbc_sids, num_sids);
4060     + if (found == NULL) {
4061     + goto fail;
4062     + }
4063     +
4064     + /*
4065     + * We go through the requested SID array three times.
4066     + * First time to look for global_sid_Unix_Users
4067     + * and global_sid_Unix_Groups SIDS, and to look
4068     + * for mappings cached in the idmap_cache.
4069     + *
4070     + * Use bitmap_set() to mark an ids[] array entry as
4071     + * being mapped.
4072     + */
4073    
4074     num_not_cached = 0;
4075    
4076     @@ -1266,17 +1283,20 @@ bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
4077     &sids[i], &rid)) {
4078     ids[i].type = ID_TYPE_UID;
4079     ids[i].id = rid;
4080     + bitmap_set(found, i);
4081     continue;
4082     }
4083     if (sid_peek_check_rid(&global_sid_Unix_Groups,
4084     &sids[i], &rid)) {
4085     ids[i].type = ID_TYPE_GID;
4086     ids[i].id = rid;
4087     + bitmap_set(found, i);
4088     continue;
4089     }
4090     if (idmap_cache_find_sid2unixid(&sids[i], &ids[i], &expired)
4091     && !expired)
4092     {
4093     + bitmap_set(found, i);
4094     continue;
4095     }
4096     ids[i].type = ID_TYPE_NOT_SPECIFIED;
4097     @@ -1287,62 +1307,121 @@ bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
4098     if (num_not_cached == 0) {
4099     goto done;
4100     }
4101     - wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, num_not_cached);
4102     +
4103     + /*
4104     + * For the ones that we couldn't map in the loop above, query winbindd
4105     + * via wbcSidsToUnixIds().
4106     + */
4107     +
4108     + wbc_ids_size = num_not_cached;
4109     + wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, wbc_ids_size);
4110     if (wbc_ids == NULL) {
4111     goto fail;
4112     }
4113     - for (i=0; i<num_not_cached; i++) {
4114     + for (i=0; i<wbc_ids_size; i++) {
4115     wbc_ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
4116     + wbc_ids[i].id.gid = (uint32_t)-1;
4117     }
4118     - err = wbcSidsToUnixIds(wbc_sids, num_not_cached, wbc_ids);
4119     + err = wbcSidsToUnixIds(wbc_sids, wbc_ids_size, wbc_ids);
4120     if (!WBC_ERROR_IS_OK(err)) {
4121     DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
4122     wbcErrorString(err)));
4123     }
4124    
4125     + /*
4126     + * Second time through the SID array, replace
4127     + * the ids[] entries that wbcSidsToUnixIds() was able to
4128     + * map.
4129     + *
4130     + * Use bitmap_set() to mark an ids[] array entry as
4131     + * being mapped.
4132     + */
4133     +
4134     num_not_cached = 0;
4135    
4136     for (i=0; i<num_sids; i++) {
4137     - if (ids[i].type == ID_TYPE_NOT_SPECIFIED) {
4138     - switch (wbc_ids[num_not_cached].type) {
4139     - case WBC_ID_TYPE_UID:
4140     - ids[i].type = ID_TYPE_UID;
4141     - ids[i].id = wbc_ids[num_not_cached].id.uid;
4142     - break;
4143     - case WBC_ID_TYPE_GID:
4144     - ids[i].type = ID_TYPE_GID;
4145     - ids[i].id = wbc_ids[num_not_cached].id.gid;
4146     - break;
4147     - default:
4148     - /* The types match, and wbcUnixId -> id is a union anyway */
4149     - ids[i].type = (enum id_type)wbc_ids[num_not_cached].type;
4150     - ids[i].id = wbc_ids[num_not_cached].id.gid;
4151     - break;
4152     - }
4153     - num_not_cached += 1;
4154     + if (bitmap_query(found, i)) {
4155     + continue;
4156     }
4157     +
4158     + SMB_ASSERT(num_not_cached < wbc_ids_size);
4159     +
4160     + switch (wbc_ids[num_not_cached].type) {
4161     + case WBC_ID_TYPE_UID:
4162     + ids[i].type = ID_TYPE_UID;
4163     + ids[i].id = wbc_ids[num_not_cached].id.uid;
4164     + bitmap_set(found, i);
4165     + break;
4166     + case WBC_ID_TYPE_GID:
4167     + ids[i].type = ID_TYPE_GID;
4168     + ids[i].id = wbc_ids[num_not_cached].id.gid;
4169     + bitmap_set(found, i);
4170     + break;
4171     + case WBC_ID_TYPE_BOTH:
4172     + ids[i].type = ID_TYPE_BOTH;
4173     + ids[i].id = wbc_ids[num_not_cached].id.uid;
4174     + bitmap_set(found, i);
4175     + break;
4176     + case WBC_ID_TYPE_NOT_SPECIFIED:
4177     + /*
4178     + * wbcSidsToUnixIds() wasn't able to map this
4179     + * so we still need to check legacy_sid_to_XXX()
4180     + * below. Don't mark the bitmap entry
4181     + * as being found so the final loop knows
4182     + * to try and map this entry.
4183     + */
4184     + ids[i].type = ID_TYPE_NOT_SPECIFIED;
4185     + ids[i].id = (uint32_t)-1;
4186     + break;
4187     + default:
4188     + /*
4189     + * A successful return from wbcSidsToUnixIds()
4190     + * cannot return anything other than the values
4191     + * checked for above. Ensure this is so.
4192     + */
4193     + smb_panic(__location__);
4194     + break;
4195     + }
4196     + num_not_cached += 1;
4197     }
4198    
4199     + /*
4200     + * Third and final time through the SID array,
4201     + * try legacy_sid_to_gid()/legacy_sid_to_uid()
4202     + * for entries we haven't already been able to
4203     + * map.
4204     + *
4205     + * Use bitmap_set() to mark an ids[] array entry as
4206     + * being mapped.
4207     + */
4208     +
4209     for (i=0; i<num_sids; i++) {
4210     - if (ids[i].type != ID_TYPE_NOT_SPECIFIED) {
4211     + if (bitmap_query(found, i)) {
4212     continue;
4213     }
4214     if (legacy_sid_to_gid(&sids[i], &ids[i].id)) {
4215     ids[i].type = ID_TYPE_GID;
4216     + bitmap_set(found, i);
4217     continue;
4218     }
4219     if (legacy_sid_to_uid(&sids[i], &ids[i].id)) {
4220     ids[i].type = ID_TYPE_UID;
4221     + bitmap_set(found, i);
4222     continue;
4223     }
4224     }
4225     done:
4226     + /*
4227     + * Pass through the return array for consistency.
4228     + * Any ids[].id mapped to (uint32_t)-1 must be returned
4229     + * as ID_TYPE_NOT_SPECIFIED.
4230     + */
4231     for (i=0; i<num_sids; i++) {
4232     switch(ids[i].type) {
4233     case WBC_ID_TYPE_GID:
4234     case WBC_ID_TYPE_UID:
4235     case WBC_ID_TYPE_BOTH:
4236     - if (ids[i].id == -1) {
4237     + if (ids[i].id == (uint32_t)-1) {
4238     ids[i].type = ID_TYPE_NOT_SPECIFIED;
4239     }
4240     break;
4241     --
4242     2.39.0
4243    
4244    
4245     From 8b39b14dcaf104a2f3172917ef926a3fec5db891 Mon Sep 17 00:00:00 2001
4246     From: Stefan Metzmacher <metze@samba.org>
4247     Date: Thu, 24 Nov 2016 09:12:59 +0100
4248     Subject: [PATCH 049/142] CVE-2016-2124: s4:libcli/sesssetup: don't fallback to
4249     non spnego authentication if we require kerberos
4250    
4251     We should not send NTLM[v2] data on the wire if the user asked for kerberos
4252     only.
4253    
4254     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12444
4255    
4256     Signed-off-by: Stefan Metzmacher <metze@samba.org>
4257     ---
4258     source4/libcli/smb_composite/sesssetup.c | 14 ++++++++++++++
4259     1 file changed, 14 insertions(+)
4260    
4261     diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c
4262     index 6ee4929e8d7..a0a1f4baa56 100644
4263     --- a/source4/libcli/smb_composite/sesssetup.c
4264     +++ b/source4/libcli/smb_composite/sesssetup.c
4265     @@ -620,6 +620,8 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se
4266     struct composite_context *c;
4267     struct sesssetup_state *state;
4268     NTSTATUS status;
4269     + enum credentials_use_kerberos krb5_state =
4270     + cli_credentials_get_kerberos_state(io->in.credentials);
4271    
4272     c = composite_create(session, session->transport->ev);
4273     if (c == NULL) return NULL;
4274     @@ -635,6 +637,10 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se
4275    
4276     /* no session setup at all in earliest protocol varients */
4277     if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) {
4278     + if (krb5_state == CRED_MUST_USE_KERBEROS) {
4279     + composite_error(c, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
4280     + return c;
4281     + }
4282     ZERO_STRUCT(io->out);
4283     composite_done(c);
4284     return c;
4285     @@ -642,9 +648,17 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se
4286    
4287     /* see what session setup interface we will use */
4288     if (session->transport->negotiate.protocol < PROTOCOL_NT1) {
4289     + if (krb5_state == CRED_MUST_USE_KERBEROS) {
4290     + composite_error(c, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
4291     + return c;
4292     + }
4293     status = session_setup_old(c, session, io, &state->req);
4294     } else if (!session->transport->options.use_spnego ||
4295     !(io->in.capabilities & CAP_EXTENDED_SECURITY)) {
4296     + if (krb5_state == CRED_MUST_USE_KERBEROS) {
4297     + composite_error(c, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
4298     + return c;
4299     + }
4300     status = session_setup_nt1(c, session, io, &state->req);
4301     } else {
4302     struct tevent_req *subreq = NULL;
4303     --
4304     2.39.0
4305    
4306    
4307     From 41cc796909aeade44c4f1e88923936ba4444278e Mon Sep 17 00:00:00 2001
4308     From: Stefan Metzmacher <metze@samba.org>
4309     Date: Thu, 27 Oct 2016 10:40:28 +0200
4310     Subject: [PATCH 050/142] CVE-2016-2124: s3:libsmb: don't fallback to non
4311     spnego authentication if we require kerberos
4312    
4313     We should not send NTLM[v2] nor plaintext data on the wire if the user
4314     asked for kerberos only.
4315    
4316     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12444
4317    
4318     Signed-off-by: Stefan Metzmacher <metze@samba.org>
4319     ---
4320     source3/libsmb/cliconnect.c | 7 +++++++
4321     1 file changed, 7 insertions(+)
4322    
4323     diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
4324     index 9bba2665663..9a69d4b7217 100644
4325     --- a/source3/libsmb/cliconnect.c
4326     +++ b/source3/libsmb/cliconnect.c
4327     @@ -1455,6 +1455,13 @@ struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
4328     return req;
4329     }
4330    
4331     + if (krb5_state == CRED_MUST_USE_KERBEROS) {
4332     + DBG_WARNING("Kerberos authentication requested, but "
4333     + "the server does not support SPNEGO authentication\n");
4334     + tevent_req_nterror(req, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
4335     + return tevent_req_post(req, ev);
4336     + }
4337     +
4338     if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
4339     /*
4340     * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
4341     --
4342     2.39.0
4343    
4344    
4345     From 3c1688714ea93cdb7c3088b8a5e5da3025e43b42 Mon Sep 17 00:00:00 2001
4346     From: Ralph Boehme <slow@samba.org>
4347     Date: Sat, 18 Jan 2020 08:06:45 +0100
4348     Subject: [PATCH 051/142] s3/auth: use set_current_user_info() in
4349     auth3_generate_session_info_pac()
4350    
4351     This delays reloading config slightly, but I don't see how could affect
4352     observable behaviour other then log messages coming from the functions in
4353     between the different locations for lp_load_with_shares() like
4354     make_session_info_krb5() are sent to a different logfile if "log file" uses %U.
4355    
4356     Signed-off-by: Ralph Boehme <slow@samba.org>
4357     Reviewed-by: Andreas Schneider <asn@samba.org>
4358     (cherry picked from commit dc4b1e39ce1f2201a2d6ae2d4cffef2448f69a62)
4359    
4360     [scabrero@samba.org Prerequisite for CVE-2020-25717 backport]
4361     ---
4362     source3/auth/auth_generic.c | 14 ++++++++------
4363     1 file changed, 8 insertions(+), 6 deletions(-)
4364    
4365     diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
4366     index 167d4e00367..0e9c423efef 100644
4367     --- a/source3/auth/auth_generic.c
4368     +++ b/source3/auth/auth_generic.c
4369     @@ -159,12 +159,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
4370     }
4371     }
4372    
4373     - /* setup the string used by %U */
4374     - sub_set_smb_name(username);
4375     -
4376     - /* reload services so that the new %U is taken into account */
4377     - lp_load_with_shares(get_dyn_CONFIGFILE());
4378     -
4379     status = make_session_info_krb5(mem_ctx,
4380     ntuser, ntdomain, username, pw,
4381     info3_copy, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
4382     @@ -176,6 +170,14 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
4383     goto done;
4384     }
4385    
4386     + /* setup the string used by %U */
4387     + set_current_user_info((*session_info)->unix_info->sanitized_username,
4388     + (*session_info)->unix_info->unix_name,
4389     + (*session_info)->info->domain_name);
4390     +
4391     + /* reload services so that the new %U is taken into account */
4392     + lp_load_with_shares(get_dyn_CONFIGFILE());
4393     +
4394     DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
4395     ntuser, ntdomain, rhost));
4396    
4397     --
4398     2.39.0
4399    
4400    
4401     From cf43f0a90b3025077479d37ad905fe730695e739 Mon Sep 17 00:00:00 2001
4402     From: Samuel Cabrero <scabrero@suse.de>
4403     Date: Thu, 4 Nov 2021 11:51:08 +0100
4404     Subject: [PATCH 052/142] selftest: Fix ktest usermap file
4405    
4406     The user was not mapped:
4407    
4408     user_in_list: checking user |KTEST/administrator| against |KTEST\Administrator|
4409     The user 'KTEST/administrator' has no mapping. Skip it next time.
4410    
4411     Signed-off-by: Samuel Cabrero <scabrero@samba.org>
4412    
4413     [scabrero@samba.org Once smb_getpswnam() fallbacks are removed the user
4414     has to be mapped]
4415     ---
4416     selftest/target/Samba3.pm | 2 +-
4417     1 file changed, 1 insertion(+), 1 deletion(-)
4418    
4419     diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
4420     index 9e4da0e6a08..2eb5003112e 100755
4421     --- a/selftest/target/Samba3.pm
4422     +++ b/selftest/target/Samba3.pm
4423     @@ -1124,7 +1124,7 @@ sub setup_ktest
4424    
4425     open(USERMAP, ">$prefix/lib/username.map") or die("Unable to open $prefix/lib/username.map");
4426     print USERMAP "
4427     -$ret->{USERNAME} = KTEST\\Administrator
4428     +$ret->{USERNAME} = KTEST/Administrator
4429     ";
4430     close(USERMAP);
4431    
4432     --
4433     2.39.0
4434    
4435    
4436     From 703f43ea7817fa0ab423134a4c40bf9c37f90274 Mon Sep 17 00:00:00 2001
4437     From: Stefan Metzmacher <metze@samba.org>
4438     Date: Tue, 5 Oct 2021 16:42:00 +0200
4439     Subject: [PATCH 053/142] selftest/Samba3: replace (winbindd => "yes",
4440     skip_wait => 1) with (winbindd => "offline")
4441    
4442     This is much more flexible and concentrates the logic in a single place.
4443    
4444     We'll use winbindd => "offline" in other places soon.
4445    
4446     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14870
4447     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881
4448    
4449     Signed-off-by: Stefan Metzmacher <metze@samba.org>
4450     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
4451     (cherry picked from commit 4dc3c68c9a28f71888e3d6dd3b1f0bcdb8fa45de)
4452     (cherry picked from commit 89b9cb8b786c3e4eb8691b5363390b68d8228a2d)
4453    
4454     [scabrero@samba.org Backported to 4.10]
4455     ---
4456     selftest/target/Samba3.pm | 10 +++++++---
4457     1 file changed, 7 insertions(+), 3 deletions(-)
4458    
4459     diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
4460     index 2eb5003112e..bbbefea44b7 100755
4461     --- a/selftest/target/Samba3.pm
4462     +++ b/selftest/target/Samba3.pm
4463     @@ -1333,7 +1333,7 @@ sub check_or_start($$$$$) {
4464    
4465     $ENV{ENVNAME} = "$ENV{ENVNAME}.winbindd";
4466    
4467     - if ($winbindd ne "yes") {
4468     + if ($winbindd ne "yes" and $winbindd ne "offline") {
4469     $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
4470     my $signame = shift;
4471     print("Skip winbindd received signal $signame");
4472     @@ -2564,13 +2564,17 @@ sub wait_for_start($$$$$)
4473     }
4474     }
4475    
4476     - if ($winbindd eq "yes") {
4477     + if ($winbindd eq "yes" or $winbindd eq "offline") {
4478     print "checking for winbindd\n";
4479     my $count = 0;
4480     $cmd = "SELFTEST_WINBINDD_SOCKET_DIR='$envvars->{SELFTEST_WINBINDD_SOCKET_DIR}' ";
4481     $cmd .= "NSS_WRAPPER_PASSWD='$envvars->{NSS_WRAPPER_PASSWD}' ";
4482     $cmd .= "NSS_WRAPPER_GROUP='$envvars->{NSS_WRAPPER_GROUP}' ";
4483     - $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping-dc";
4484     + if ($winbindd eq "yes") {
4485     + $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping-dc";
4486     + } elsif ($winbindd eq "offline") {
4487     + $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping";
4488     + }
4489    
4490     do {
4491     if ($ret != 0) {
4492     --
4493     2.39.0
4494    
4495    
4496     From eadbcf608a98c8ff90b2d5d91b61fc8100d2cc71 Mon Sep 17 00:00:00 2001
4497     From: Stefan Metzmacher <metze@samba.org>
4498     Date: Fri, 22 Oct 2021 16:20:36 +0200
4499     Subject: [PATCH 054/142] CVE-2020-25719 CVE-2020-25717: selftest: remove
4500     "gensec:require_pac" settings
4501    
4502     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
4503     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
4504    
4505     Signed-off-by: Stefan Metzmacher <metze@samba.org>
4506     ---
4507     selftest/selftest.pl | 2 --
4508     selftest/target/Samba4.pm | 2 --
4509     2 files changed, 4 deletions(-)
4510    
4511     diff --git a/selftest/selftest.pl b/selftest/selftest.pl
4512     index f2968139cfd..8c273951ab3 100755
4513     --- a/selftest/selftest.pl
4514     +++ b/selftest/selftest.pl
4515     @@ -637,8 +637,6 @@ sub write_clientconf($$$)
4516     client lanman auth = Yes
4517     log level = 1
4518     torture:basedir = $clientdir
4519     -#We don't want to pass our self-tests if the PAC code is wrong
4520     - gensec:require_pac = true
4521     #We don't want to run 'speed' tests for very long
4522     torture:timelimit = 1
4523     winbind separator = /
4524     diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
4525     index a7a6c4c9587..0f644661176 100755
4526     --- a/selftest/target/Samba4.pm
4527     +++ b/selftest/target/Samba4.pm
4528     @@ -777,8 +777,6 @@ sub provision_raw_step1($$)
4529     notify:inotify = false
4530     ldb:nosync = true
4531     ldap server require strong auth = yes
4532     -#We don't want to pass our self-tests if the PAC code is wrong
4533     - gensec:require_pac = true
4534     log file = $ctx->{logdir}/log.\%m
4535     log level = $ctx->{server_loglevel}
4536     lanman auth = Yes
4537     --
4538     2.39.0
4539    
4540    
4541     From 628493ea5f0cda3851ab13a41b8018daa228132b Mon Sep 17 00:00:00 2001
4542     From: Stefan Metzmacher <metze@samba.org>
4543     Date: Mon, 4 Oct 2021 17:29:34 +0200
4544     Subject: [PATCH 055/142] CVE-2020-25717: s3:winbindd: make sure we default to
4545     r->out.authoritative = true
4546    
4547     We need to make sure that temporary failures don't trigger a fallback
4548     to the local SAM that silently ignores the domain name part for users.
4549    
4550     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
4551    
4552     Signed-off-by: Stefan Metzmacher <metze@samba.org>
4553    
4554     [scabrero@samba.org Backported for 4.10 due to no logon_id for
4555     log_authentication() neither is_allowed_domain()]
4556     ---
4557     source3/winbindd/winbindd_dual_srv.c | 7 +++++++
4558     source3/winbindd/winbindd_irpc.c | 7 +++++++
4559     source3/winbindd/winbindd_pam.c | 13 ++++++++++---
4560     source3/winbindd/winbindd_pam_auth_crap.c | 9 ++++++++-
4561     source3/winbindd/winbindd_util.c | 7 +++++++
4562     5 files changed, 39 insertions(+), 4 deletions(-)
4563    
4564     diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
4565     index ab14f5d51a0..0842241e02e 100644
4566     --- a/source3/winbindd/winbindd_dual_srv.c
4567     +++ b/source3/winbindd/winbindd_dual_srv.c
4568     @@ -928,6 +928,13 @@ NTSTATUS _winbind_SamLogon(struct pipes_struct *p,
4569     union netr_Validation *validation = NULL;
4570     bool interactive = false;
4571    
4572     + /*
4573     + * Make sure we start with authoritative=true,
4574     + * it will only set to false if we don't know the
4575     + * domain.
4576     + */
4577     + r->out.authoritative = true;
4578     +
4579     domain = wb_child_domain();
4580     if (domain == NULL) {
4581     return NT_STATUS_REQUEST_NOT_ACCEPTED;
4582     diff --git a/source3/winbindd/winbindd_irpc.c b/source3/winbindd/winbindd_irpc.c
4583     index 8cbb0b93086..45615c2dc47 100644
4584     --- a/source3/winbindd/winbindd_irpc.c
4585     +++ b/source3/winbindd/winbindd_irpc.c
4586     @@ -143,6 +143,13 @@ static NTSTATUS wb_irpc_SamLogon(struct irpc_message *msg,
4587     const char *target_domain_name = NULL;
4588     const char *account_name = NULL;
4589    
4590     + /*
4591     + * Make sure we start with authoritative=true,
4592     + * it will only set to false if we don't know the
4593     + * domain.
4594     + */
4595     + req->out.authoritative = true;
4596     +
4597     switch (req->in.logon_level) {
4598     case NetlogonInteractiveInformation:
4599     case NetlogonServiceInformation:
4600     diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
4601     index 35018fbe284..deed81d0a79 100644
4602     --- a/source3/winbindd/winbindd_pam.c
4603     +++ b/source3/winbindd/winbindd_pam.c
4604     @@ -1703,7 +1703,7 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(
4605     unsigned char local_nt_response[24];
4606     fstring name_namespace, name_domain, name_user;
4607     NTSTATUS result;
4608     - uint8_t authoritative = 0;
4609     + uint8_t authoritative = 1;
4610     uint32_t flags = 0;
4611     uint16_t validation_level;
4612     union netr_Validation *validation = NULL;
4613     @@ -2238,6 +2238,13 @@ done:
4614     result = NT_STATUS_NO_LOGON_SERVERS;
4615     }
4616    
4617     + /*
4618     + * Here we don't alter
4619     + * state->response->data.auth.authoritative based
4620     + * on the servers response
4621     + * as we don't want a fallback to the local sam
4622     + * for interactive PAM logons
4623     + */
4624     set_auth_errors(state->response, result);
4625    
4626     DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n",
4627     @@ -2420,7 +2427,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
4628     const char *name_user = NULL;
4629     const char *name_domain = NULL;
4630     const char *workstation;
4631     - uint8_t authoritative = 0;
4632     + uint8_t authoritative = 1;
4633     uint32_t flags = 0;
4634     uint16_t validation_level;
4635     union netr_Validation *validation = NULL;
4636     @@ -2482,7 +2489,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
4637     &validation_level,
4638     &validation);
4639     if (!NT_STATUS_IS_OK(result)) {
4640     - state->response->data.auth.authoritative = authoritative;
4641     goto done;
4642     }
4643    
4644     @@ -2526,6 +2532,7 @@ done:
4645     }
4646    
4647     set_auth_errors(state->response, result);
4648     + state->response->data.auth.authoritative = authoritative;
4649    
4650     return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
4651     }
4652     diff --git a/source3/winbindd/winbindd_pam_auth_crap.c b/source3/winbindd/winbindd_pam_auth_crap.c
4653     index b7912db43df..40cab81b5ea 100644
4654     --- a/source3/winbindd/winbindd_pam_auth_crap.c
4655     +++ b/source3/winbindd/winbindd_pam_auth_crap.c
4656     @@ -24,6 +24,7 @@
4657    
4658     struct winbindd_pam_auth_crap_state {
4659     struct winbindd_response *response;
4660     + bool authoritative;
4661     uint32_t flags;
4662     };
4663    
4664     @@ -45,7 +46,7 @@ struct tevent_req *winbindd_pam_auth_crap_send(
4665     if (req == NULL) {
4666     return NULL;
4667     }
4668     -
4669     + state->authoritative = true;
4670     state->flags = request->flags;
4671    
4672     if (state->flags & WBFLAG_PAM_AUTH_PAC) {
4673     @@ -124,6 +125,11 @@ struct tevent_req *winbindd_pam_auth_crap_send(
4674    
4675     domain = find_auth_domain(request->flags, auth_domain);
4676     if (domain == NULL) {
4677     + /*
4678     + * We don't know the domain so
4679     + * we're not authoritative
4680     + */
4681     + state->authoritative = false;
4682     tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
4683     return tevent_req_post(req, ev);
4684     }
4685     @@ -184,6 +190,7 @@ NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req,
4686    
4687     if (tevent_req_is_nterror(req, &status)) {
4688     set_auth_errors(response, status);
4689     + response->data.auth.authoritative = state->authoritative;
4690     return status;
4691     }
4692    
4693     diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
4694     index 3245c70bb8e..315eb366a52 100644
4695     --- a/source3/winbindd/winbindd_util.c
4696     +++ b/source3/winbindd/winbindd_util.c
4697     @@ -2062,6 +2062,13 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain)
4698    
4699     void set_auth_errors(struct winbindd_response *resp, NTSTATUS result)
4700     {
4701     + /*
4702     + * Make sure we start with authoritative=true,
4703     + * it will only set to false if we don't know the
4704     + * domain.
4705     + */
4706     + resp->data.auth.authoritative = true;
4707     +
4708     resp->data.auth.nt_status = NT_STATUS_V(result);
4709     fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result));
4710    
4711     --
4712     2.39.0
4713    
4714    
4715     From fc3b3940208c2f03ea3aeb4b6f7e609fa9f90648 Mon Sep 17 00:00:00 2001
4716     From: Stefan Metzmacher <metze@samba.org>
4717     Date: Mon, 4 Oct 2021 17:29:34 +0200
4718     Subject: [PATCH 056/142] CVE-2020-25717: s4:auth/ntlm: make sure
4719     auth_check_password() defaults to r->out.authoritative = true
4720    
4721     We need to make sure that temporary failures don't trigger a fallback
4722     to the local SAM that silently ignores the domain name part for users.
4723    
4724     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
4725    
4726     Signed-off-by: Stefan Metzmacher <metze@samba.org>
4727     ---
4728     source4/auth/ntlm/auth.c | 5 +++++
4729     1 file changed, 5 insertions(+)
4730    
4731     diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
4732     index 3a3fa7eaa59..f754bd5cd44 100644
4733     --- a/source4/auth/ntlm/auth.c
4734     +++ b/source4/auth/ntlm/auth.c
4735     @@ -169,6 +169,11 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
4736     /*TODO: create a new event context here! */
4737     ev = auth_ctx->event_ctx;
4738    
4739     + /*
4740     + * We are authoritative by default
4741     + */
4742     + *pauthoritative = 1;
4743     +
4744     subreq = auth_check_password_send(mem_ctx,
4745     ev,
4746     auth_ctx,
4747     --
4748     2.39.0
4749    
4750    
4751     From ecd3a8af56dcd1aad43999a253175aa04b298eef Mon Sep 17 00:00:00 2001
4752     From: Stefan Metzmacher <metze@samba.org>
4753     Date: Tue, 26 Oct 2021 17:42:41 +0200
4754     Subject: [PATCH 057/142] CVE-2020-25717: s4:torture: start with authoritative
4755     = 1
4756    
4757     This is not strictly needed, but makes it easier to audit
4758     that we don't miss important places.
4759    
4760     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
4761    
4762     Signed-off-by: Stefan Metzmacher <metze@samba.org>
4763     ---
4764     source4/torture/rpc/samlogon.c | 4 ++--
4765     source4/torture/rpc/schannel.c | 2 +-
4766     2 files changed, 3 insertions(+), 3 deletions(-)
4767    
4768     diff --git a/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c
4769     index e689dfd5e98..957cb410712 100644
4770     --- a/source4/torture/rpc/samlogon.c
4771     +++ b/source4/torture/rpc/samlogon.c
4772     @@ -1385,7 +1385,7 @@ static bool test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4773    
4774     union netr_LogonLevel logon;
4775     union netr_Validation validation;
4776     - uint8_t authoritative = 0;
4777     + uint8_t authoritative = 1;
4778     uint32_t flags = 0;
4779    
4780     ZERO_STRUCT(logon);
4781     @@ -1498,7 +1498,7 @@ bool test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4782    
4783     union netr_LogonLevel logon;
4784     union netr_Validation validation;
4785     - uint8_t authoritative = 0;
4786     + uint8_t authoritative = 1;
4787     struct dcerpc_binding_handle *b = p->binding_handle;
4788    
4789     ZERO_STRUCT(a);
4790     diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c
4791     index c237c82bbe7..72d0bf28fdd 100644
4792     --- a/source4/torture/rpc/schannel.c
4793     +++ b/source4/torture/rpc/schannel.c
4794     @@ -50,7 +50,7 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
4795     struct netr_NetworkInfo ninfo;
4796     union netr_LogonLevel logon;
4797     union netr_Validation validation;
4798     - uint8_t authoritative = 0;
4799     + uint8_t authoritative = 1;
4800     uint32_t _flags = 0;
4801     DATA_BLOB names_blob, chal, lm_resp, nt_resp;
4802     int i;
4803     --
4804     2.39.0
4805    
4806    
4807     From 3feb493c3dd5383712a41729ed6f770695acb8b7 Mon Sep 17 00:00:00 2001
4808     From: Stefan Metzmacher <metze@samba.org>
4809     Date: Tue, 26 Oct 2021 17:42:41 +0200
4810     Subject: [PATCH 058/142] CVE-2020-25717: s4:smb_server: start with
4811     authoritative = 1
4812    
4813     This is not strictly needed, but makes it easier to audit
4814     that we don't miss important places.
4815    
4816     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
4817    
4818     Signed-off-by: Stefan Metzmacher <metze@samba.org>
4819     ---
4820     source4/smb_server/smb/sesssetup.c | 4 ++--
4821     1 file changed, 2 insertions(+), 2 deletions(-)
4822    
4823     diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c
4824     index 13f13934412..5e817eecd4b 100644
4825     --- a/source4/smb_server/smb/sesssetup.c
4826     +++ b/source4/smb_server/smb/sesssetup.c
4827     @@ -102,7 +102,7 @@ static void sesssetup_old_send(struct tevent_req *subreq)
4828     struct auth_session_info *session_info;
4829     struct smbsrv_session *smb_sess;
4830     NTSTATUS status;
4831     - uint8_t authoritative = 0;
4832     + uint8_t authoritative = 1;
4833     uint32_t flags;
4834    
4835     status = auth_check_password_recv(subreq, req, &user_info_dc,
4836     @@ -243,7 +243,7 @@ static void sesssetup_nt1_send(struct tevent_req *subreq)
4837     struct auth_user_info_dc *user_info_dc = NULL;
4838     struct auth_session_info *session_info;
4839     struct smbsrv_session *smb_sess;
4840     - uint8_t authoritative = 0;
4841     + uint8_t authoritative = 1;
4842     uint32_t flags;
4843     NTSTATUS status;
4844    
4845     --
4846     2.39.0
4847    
4848    
4849     From e1a1787d1d3b64adc743eab4f626068b438d0e5c Mon Sep 17 00:00:00 2001
4850     From: Stefan Metzmacher <metze@samba.org>
4851     Date: Tue, 26 Oct 2021 17:42:41 +0200
4852     Subject: [PATCH 059/142] CVE-2020-25717: s4:auth_simple: start with
4853     authoritative = 1
4854    
4855     This is not strictly needed, but makes it easier to audit
4856     that we don't miss important places.
4857    
4858     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
4859    
4860     Signed-off-by: Stefan Metzmacher <metze@samba.org>
4861     ---
4862     source4/auth/ntlm/auth_simple.c | 2 +-
4863     1 file changed, 1 insertion(+), 1 deletion(-)
4864    
4865     diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c
4866     index fcd9050979d..da8f094a838 100644
4867     --- a/source4/auth/ntlm/auth_simple.c
4868     +++ b/source4/auth/ntlm/auth_simple.c
4869     @@ -150,7 +150,7 @@ static void authenticate_ldap_simple_bind_done(struct tevent_req *subreq)
4870     const struct tsocket_address *local_address = user_info->local_host;
4871     const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
4872     struct auth_user_info_dc *user_info_dc = NULL;
4873     - uint8_t authoritative = 0;
4874     + uint8_t authoritative = 1;
4875     uint32_t flags = 0;
4876     NTSTATUS nt_status;
4877    
4878     --
4879     2.39.0
4880    
4881    
4882     From e09409714301455ba7bbed1d80a9c90c05257aaf Mon Sep 17 00:00:00 2001
4883     From: Stefan Metzmacher <metze@samba.org>
4884     Date: Tue, 26 Oct 2021 17:42:41 +0200
4885     Subject: [PATCH 060/142] CVE-2020-25717: s3:ntlm_auth: start with
4886     authoritative = 1
4887    
4888     This is not strictly needed, but makes it easier to audit
4889     that we don't miss important places.
4890    
4891     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
4892    
4893     Signed-off-by: Stefan Metzmacher <metze@samba.org>
4894     ---
4895     source3/utils/ntlm_auth.c | 4 ++--
4896     source3/utils/ntlm_auth_diagnostics.c | 10 +++++-----
4897     2 files changed, 7 insertions(+), 7 deletions(-)
4898    
4899     diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
4900     index 36c32e4a3dc..3f70732a837 100644
4901     --- a/source3/utils/ntlm_auth.c
4902     +++ b/source3/utils/ntlm_auth.c
4903     @@ -1766,7 +1766,7 @@ static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mod
4904     TALLOC_FREE(mem_ctx);
4905    
4906     } else {
4907     - uint8_t authoritative = 0;
4908     + uint8_t authoritative = 1;
4909    
4910     if (!domain) {
4911     domain = smb_xstrdup(get_winbind_domain());
4912     @@ -2235,7 +2235,7 @@ static bool check_auth_crap(void)
4913     char *hex_lm_key;
4914     char *hex_user_session_key;
4915     char *error_string;
4916     - uint8_t authoritative = 0;
4917     + uint8_t authoritative = 1;
4918    
4919     setbuf(stdout, NULL);
4920    
4921     diff --git a/source3/utils/ntlm_auth_diagnostics.c b/source3/utils/ntlm_auth_diagnostics.c
4922     index 41591a8de33..fc0fc19bacb 100644
4923     --- a/source3/utils/ntlm_auth_diagnostics.c
4924     +++ b/source3/utils/ntlm_auth_diagnostics.c
4925     @@ -54,7 +54,7 @@ static bool test_lm_ntlm_broken(enum ntlm_break break_which)
4926     DATA_BLOB lm_response = data_blob(NULL, 24);
4927     DATA_BLOB nt_response = data_blob(NULL, 24);
4928     DATA_BLOB session_key = data_blob(NULL, 16);
4929     - uint8_t authoritative = 0;
4930     + uint8_t authoritative = 1;
4931     uchar lm_key[8];
4932     uchar user_session_key[16];
4933     uchar lm_hash[16];
4934     @@ -177,7 +177,7 @@ static bool test_ntlm_in_lm(void)
4935     NTSTATUS nt_status;
4936     uint32_t flags = 0;
4937     DATA_BLOB nt_response = data_blob(NULL, 24);
4938     - uint8_t authoritative = 0;
4939     + uint8_t authoritative = 1;
4940     uchar lm_key[8];
4941     uchar lm_hash[16];
4942     uchar user_session_key[16];
4943     @@ -245,7 +245,7 @@ static bool test_ntlm_in_both(void)
4944     uint32_t flags = 0;
4945     DATA_BLOB nt_response = data_blob(NULL, 24);
4946     DATA_BLOB session_key = data_blob(NULL, 16);
4947     - uint8_t authoritative = 0;
4948     + uint8_t authoritative = 1;
4949     uint8_t lm_key[8];
4950     uint8_t lm_hash[16];
4951     uint8_t user_session_key[16];
4952     @@ -322,7 +322,7 @@ static bool test_lmv2_ntlmv2_broken(enum ntlm_break break_which)
4953     DATA_BLOB lmv2_response = data_blob_null;
4954     DATA_BLOB ntlmv2_session_key = data_blob_null;
4955     DATA_BLOB names_blob = NTLMv2_generate_names_blob(NULL, get_winbind_netbios_name(), get_winbind_domain());
4956     - uint8_t authoritative = 0;
4957     + uint8_t authoritative = 1;
4958     uchar user_session_key[16];
4959     DATA_BLOB chall = get_challenge();
4960     char *error_string;
4961     @@ -452,7 +452,7 @@ static bool test_plaintext(enum ntlm_break break_which)
4962     char *password;
4963     smb_ucs2_t *nt_response_ucs2;
4964     size_t converted_size;
4965     - uint8_t authoritative = 0;
4966     + uint8_t authoritative = 1;
4967     uchar user_session_key[16];
4968     uchar lm_key[16];
4969     static const uchar zeros[8] = { 0, };
4970     --
4971     2.39.0
4972    
4973    
4974     From 26570ee2e981cc5d44eeeed020a051a4771470fe Mon Sep 17 00:00:00 2001
4975     From: Stefan Metzmacher <metze@samba.org>
4976     Date: Tue, 26 Oct 2021 17:42:41 +0200
4977     Subject: [PATCH 061/142] CVE-2020-25717: s3:torture: start with authoritative
4978     = 1
4979    
4980     This is not strictly needed, but makes it easier to audit
4981     that we don't miss important places.
4982    
4983     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
4984    
4985     Signed-off-by: Stefan Metzmacher <metze@samba.org>
4986    
4987     [scabrero@samba.org Backported to 4.10 due to missing commit
4988     a5548af018643f2e78c482e33ef0e6073db149e4 to check return value
4989     of SMBOWFencrypt()]
4990     ---
4991     source3/torture/pdbtest.c | 2 +-
4992     1 file changed, 1 insertion(+), 1 deletion(-)
4993    
4994     diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c
4995     index 64bc45e6a7c..48190e78bf8 100644
4996     --- a/source3/torture/pdbtest.c
4997     +++ b/source3/torture/pdbtest.c
4998     @@ -277,7 +277,7 @@ static bool test_auth(TALLOC_CTX *mem_ctx, struct samu *pdb_entry)
4999     struct netr_SamInfo6 *info6_wbc = NULL;
5000     NTSTATUS status;
5001     bool ok;
5002     - uint8_t authoritative = 0;
5003     + uint8_t authoritative = 1;
5004    
5005     SMBOWFencrypt(pdb_get_nt_passwd(pdb_entry), challenge_8,
5006     local_nt_response);
5007     --
5008     2.39.0
5009    
5010    
5011     From 36af26aac042ce48ae912d0ab7ce398280d81c93 Mon Sep 17 00:00:00 2001
5012     From: Stefan Metzmacher <metze@samba.org>
5013     Date: Tue, 26 Oct 2021 17:42:41 +0200
5014     Subject: [PATCH 062/142] CVE-2020-25717: s3:rpcclient: start with
5015     authoritative = 1
5016    
5017     This is not strictly needed, but makes it easier to audit
5018     that we don't miss important places.
5019    
5020     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
5021    
5022     Signed-off-by: Stefan Metzmacher <metze@samba.org>
5023     ---
5024     source3/rpcclient/cmd_netlogon.c | 2 +-
5025     1 file changed, 1 insertion(+), 1 deletion(-)
5026    
5027     diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c
5028     index 631740562c6..30fa1ed7816 100644
5029     --- a/source3/rpcclient/cmd_netlogon.c
5030     +++ b/source3/rpcclient/cmd_netlogon.c
5031     @@ -496,7 +496,7 @@ static NTSTATUS cmd_netlogon_sam_logon(struct rpc_pipe_client *cli,
5032     uint32_t logon_param = 0;
5033     const char *workstation = NULL;
5034     struct netr_SamInfo3 *info3 = NULL;
5035     - uint8_t authoritative = 0;
5036     + uint8_t authoritative = 1;
5037     uint32_t flags = 0;
5038     uint16_t validation_level;
5039     union netr_Validation *validation = NULL;
5040     --
5041     2.39.0
5042    
5043    
5044     From 8eec50d65a10baa4e282c4a833c3cb202cd33255 Mon Sep 17 00:00:00 2001
5045     From: Stefan Metzmacher <metze@samba.org>
5046     Date: Tue, 26 Oct 2021 17:42:41 +0200
5047     Subject: [PATCH 063/142] CVE-2020-25717: s3:auth: start with authoritative = 1
5048    
5049     This is not strictly needed, but makes it easier to audit
5050     that we don't miss important places.
5051    
5052     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
5053    
5054     Signed-off-by: Stefan Metzmacher <metze@samba.org>
5055    
5056     [scabrero@samba.org Backported to 4.10 due to missing commits
5057     7f75dec865256049e99f7fcf46317cd2d53e95d1 and
5058     434030ba711e677fdd167a255d05c1cd4db943b7]
5059     ---
5060     source3/auth/auth_generic.c | 2 +-
5061     source3/auth/auth_samba4.c | 2 +-
5062     2 files changed, 2 insertions(+), 2 deletions(-)
5063    
5064     diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
5065     index 0e9c423efef..4ef2270cb34 100644
5066     --- a/source3/auth/auth_generic.c
5067     +++ b/source3/auth/auth_generic.c
5068     @@ -415,7 +415,7 @@ NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
5069     {
5070     NTSTATUS nt_status;
5071     void *server_info;
5072     - uint8_t authoritative = 0;
5073     + uint8_t authoritative = 1;
5074    
5075     if (auth_context->check_ntlm_password_send != NULL) {
5076     struct tevent_context *ev = NULL;
5077     diff --git a/source3/auth/auth_samba4.c b/source3/auth/auth_samba4.c
5078     index a71c75631d7..bf7ccb4348c 100644
5079     --- a/source3/auth/auth_samba4.c
5080     +++ b/source3/auth/auth_samba4.c
5081     @@ -118,7 +118,7 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context,
5082     NTSTATUS nt_status;
5083     struct auth_user_info_dc *user_info_dc;
5084     struct auth4_context *auth4_context;
5085     - uint8_t authoritative = 0;
5086     + uint8_t authoritative = 1;
5087    
5088     nt_status = make_auth4_context_s4(auth_context, mem_ctx, &auth4_context);
5089     if (!NT_STATUS_IS_OK(nt_status)) {
5090     --
5091     2.39.0
5092    
5093    
5094     From 46bc67c24c83940ef56cfa5dbbdb8544c290f200 Mon Sep 17 00:00:00 2001
5095     From: Stefan Metzmacher <metze@samba.org>
5096     Date: Tue, 26 Oct 2021 17:42:41 +0200
5097     Subject: [PATCH 064/142] CVE-2020-25717: auth/ntlmssp: start with
5098     authoritative = 1
5099    
5100     This is not strictly needed, but makes it easier to audit
5101     that we don't miss important places.
5102    
5103     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
5104    
5105     Signed-off-by: Stefan Metzmacher <metze@samba.org>
5106     ---
5107     auth/ntlmssp/ntlmssp_server.c | 2 +-
5108     1 file changed, 1 insertion(+), 1 deletion(-)
5109    
5110     diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c
5111     index 140e89daeb1..eebada670be 100644
5112     --- a/auth/ntlmssp/ntlmssp_server.c
5113     +++ b/auth/ntlmssp/ntlmssp_server.c
5114     @@ -830,7 +830,7 @@ static void ntlmssp_server_auth_done(struct tevent_req *subreq)
5115     struct gensec_security *gensec_security = state->gensec_security;
5116     struct gensec_ntlmssp_context *gensec_ntlmssp = state->gensec_ntlmssp;
5117     struct auth4_context *auth_context = gensec_security->auth_context;
5118     - uint8_t authoritative = 0;
5119     + uint8_t authoritative = 1;
5120     NTSTATUS status;
5121    
5122     status = auth_context->check_ntlm_password_recv(subreq,
5123     --
5124     2.39.0
5125    
5126    
5127     From 986642f066c3fdf187a8799898196a23cb9d532c Mon Sep 17 00:00:00 2001
5128     From: Samuel Cabrero <scabrero@samba.org>
5129     Date: Tue, 28 Sep 2021 10:43:40 +0200
5130     Subject: [PATCH 065/142] CVE-2020-25717: loadparm: Add new parameter "min
5131     domain uid"
5132    
5133     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
5134     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
5135    
5136     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
5137    
5138     Signed-off-by: Samuel Cabrero <scabrero@samba.org>
5139     Signed-off-by: Stefan Metzmacher <metze@samba.org>
5140    
5141     [abartlet@samba.org Backported from master/4.15 due to
5142     conflicts with other new parameters]
5143     ---
5144     docs-xml/smbdotconf/security/mindomainuid.xml | 17 +++++++++++++++++
5145     docs-xml/smbdotconf/winbind/idmapconfig.xml | 4 ++++
5146     lib/param/loadparm.c | 4 ++++
5147     source3/param/loadparm.c | 2 ++
5148     4 files changed, 27 insertions(+)
5149     create mode 100644 docs-xml/smbdotconf/security/mindomainuid.xml
5150    
5151     diff --git a/docs-xml/smbdotconf/security/mindomainuid.xml b/docs-xml/smbdotconf/security/mindomainuid.xml
5152     new file mode 100644
5153     index 00000000000..46ae795d730
5154     --- /dev/null
5155     +++ b/docs-xml/smbdotconf/security/mindomainuid.xml
5156     @@ -0,0 +1,17 @@
5157     +<samba:parameter name="min domain uid"
5158     + type="integer"
5159     + context="G"
5160     + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
5161     +<description>
5162     + <para>
5163     + The integer parameter specifies the minimum uid allowed when mapping a
5164     + local account to a domain account.
5165     + </para>
5166     +
5167     + <para>
5168     + Note that this option interacts with the configured <emphasis>idmap ranges</emphasis>!
5169     + </para>
5170     +</description>
5171     +
5172     +<value type="default">1000</value>
5173     +</samba:parameter>
5174     diff --git a/docs-xml/smbdotconf/winbind/idmapconfig.xml b/docs-xml/smbdotconf/winbind/idmapconfig.xml
5175     index 1374040fb29..f70f11df757 100644
5176     --- a/docs-xml/smbdotconf/winbind/idmapconfig.xml
5177     +++ b/docs-xml/smbdotconf/winbind/idmapconfig.xml
5178     @@ -80,6 +80,9 @@
5179     authoritative for a unix ID to SID mapping, so it must be set
5180     for each individually configured domain and for the default
5181     configuration. The configured ranges must be mutually disjoint.
5182     + </para>
5183     + <para>
5184     + Note that the low value interacts with the <smbconfoption name="min domain uid"/> option!
5185     </para></listitem>
5186     </varlistentry>
5187    
5188     @@ -115,4 +118,5 @@
5189     </programlisting>
5190    
5191     </description>
5192     +<related>min domain uid</related>
5193     </samba:parameter>
5194     diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
5195     index 4c3dfff24f3..4aa91f4d404 100644
5196     --- a/lib/param/loadparm.c
5197     +++ b/lib/param/loadparm.c
5198     @@ -3015,6 +3015,10 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
5199     lpcfg_do_global_parameter(
5200     lp_ctx, "ldap max search request size", "256000");
5201    
5202     + lpcfg_do_global_parameter(lp_ctx,
5203     + "min domain uid",
5204     + "1000");
5205     +
5206     for (i = 0; parm_table[i].label; i++) {
5207     if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
5208     lp_ctx->flags[i] |= FLAG_DEFAULT;
5209     diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
5210     index 0db44e92d19..57d1d909099 100644
5211     --- a/source3/param/loadparm.c
5212     +++ b/source3/param/loadparm.c
5213     @@ -963,6 +963,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
5214     Globals.ldap_max_authenticated_request_size = 16777216;
5215     Globals.ldap_max_search_request_size = 256000;
5216    
5217     + Globals.min_domain_uid = 1000;
5218     +
5219     /* Now put back the settings that were set with lp_set_cmdline() */
5220     apply_lp_set_cmdline();
5221     }
5222     --
5223     2.39.0
5224    
5225    
5226     From 16fa6601a3517c723e90dfb8b1a086df2616e668 Mon Sep 17 00:00:00 2001
5227     From: Stefan Metzmacher <metze@samba.org>
5228     Date: Fri, 8 Oct 2021 19:57:18 +0200
5229     Subject: [PATCH 066/142] CVE-2020-25717: s3:auth: let
5230     auth3_generate_session_info_pac() forward the low level errors
5231    
5232     Mapping everything to ACCESS_DENIED makes it hard to debug problems,
5233     which may happen because of our more restrictive behaviour in future.
5234    
5235     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
5236     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
5237    
5238     Signed-off-by: Stefan Metzmacher <metze@samba.org>
5239     ---
5240     source3/auth/auth_generic.c | 2 +-
5241     1 file changed, 1 insertion(+), 1 deletion(-)
5242    
5243     diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
5244     index 4ef2270cb34..26a38f92b30 100644
5245     --- a/source3/auth/auth_generic.c
5246     +++ b/source3/auth/auth_generic.c
5247     @@ -166,7 +166,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
5248     if (!NT_STATUS_IS_OK(status)) {
5249     DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
5250     nt_errstr(status)));
5251     - status = NT_STATUS_ACCESS_DENIED;
5252     + status = nt_status_squash(status);
5253     goto done;
5254     }
5255    
5256     --
5257     2.39.0
5258    
5259    
5260     From 10a4bdbe4a16fec1bd9b212736a9d26500e0981e Mon Sep 17 00:00:00 2001
5261     From: Samuel Cabrero <scabrero@samba.org>
5262     Date: Tue, 28 Sep 2021 10:45:11 +0200
5263     Subject: [PATCH 067/142] CVE-2020-25717: s3:auth: Check minimum domain uid
5264    
5265     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
5266     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
5267    
5268     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
5269    
5270     Signed-off-by: Samuel Cabrero <scabrero@samba.org>
5271     Signed-off-by: Stefan Metzmacher <metze@samba.org>
5272     ---
5273     source3/auth/auth_util.c | 16 ++++++++++++++++
5274     1 file changed, 16 insertions(+)
5275    
5276     diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
5277     index 8ff20c33759..8801d3f0f0b 100644
5278     --- a/source3/auth/auth_util.c
5279     +++ b/source3/auth/auth_util.c
5280     @@ -2078,6 +2078,22 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
5281     }
5282     }
5283     goto out;
5284     + } else if ((lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
5285     + !is_myname(domain) && pwd->pw_uid < lp_min_domain_uid()) {
5286     + /*
5287     + * !is_myname(domain) because when smbd starts tries to setup
5288     + * the guest user info, calling this function with nobody
5289     + * username. Nobody is usually uid 65535 but it can be changed
5290     + * to a regular user with 'guest account' parameter
5291     + */
5292     + nt_status = NT_STATUS_INVALID_TOKEN;
5293     + DBG_NOTICE("Username '%s%s%s' is invalid on this system, "
5294     + "it does not meet 'min domain uid' "
5295     + "restriction (%u < %u): %s\n",
5296     + nt_domain, lp_winbind_separator(), nt_username,
5297     + pwd->pw_uid, lp_min_domain_uid(),
5298     + nt_errstr(nt_status));
5299     + goto out;
5300     }
5301    
5302     result = make_server_info(tmp_ctx);
5303     --
5304     2.39.0
5305    
5306    
5307     From 58bea3837cfbeba5cd5c56060a42117fffedbda4 Mon Sep 17 00:00:00 2001
5308     From: Stefan Metzmacher <metze@samba.org>
5309     Date: Fri, 8 Oct 2021 17:40:30 +0200
5310     Subject: [PATCH 068/142] CVE-2020-25717: s3:auth: we should not try to
5311     autocreate the guest account
5312    
5313     We should avoid autocreation of users as much as possible.
5314    
5315     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
5316     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
5317    
5318     Signed-off-by: Stefan Metzmacher <metze@samba.org>
5319     ---
5320     source3/auth/user_krb5.c | 2 +-
5321     1 file changed, 1 insertion(+), 1 deletion(-)
5322    
5323     diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c
5324     index 8998f9c8f8a..074e8c7eb71 100644
5325     --- a/source3/auth/user_krb5.c
5326     +++ b/source3/auth/user_krb5.c
5327     @@ -155,7 +155,7 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
5328     if (!fuser) {
5329     return NT_STATUS_NO_MEMORY;
5330     }
5331     - pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true);
5332     + pw = smb_getpwnam(mem_ctx, fuser, &unixuser, false);
5333     }
5334    
5335     /* extra sanity check that the guest account is valid */
5336     --
5337     2.39.0
5338    
5339    
5340     From e78afbcff415d78cb29b65204fefeb0355d6651e Mon Sep 17 00:00:00 2001
5341     From: Stefan Metzmacher <metze@samba.org>
5342     Date: Fri, 8 Oct 2021 18:08:20 +0200
5343     Subject: [PATCH 069/142] CVE-2020-25717: s3:auth: no longer let
5344     check_account() autocreate local users
5345    
5346     So far we autocreated local user accounts based on just the
5347     account_name (just ignoring any domain part).
5348    
5349     This only happens via a possible 'add user script',
5350     which is not typically defined on domain members
5351     and on NT4 DCs local users already exist in the
5352     local passdb anyway.
5353    
5354     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
5355     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
5356    
5357     Signed-off-by: Stefan Metzmacher <metze@samba.org>
5358     ---
5359     source3/auth/auth_util.c | 2 +-
5360     1 file changed, 1 insertion(+), 1 deletion(-)
5361    
5362     diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
5363     index 8801d3f0f0b..6ee500493e6 100644
5364     --- a/source3/auth/auth_util.c
5365     +++ b/source3/auth/auth_util.c
5366     @@ -1873,7 +1873,7 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
5367     return NT_STATUS_NO_MEMORY;
5368     }
5369    
5370     - passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
5371     + passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
5372     if (!passwd) {
5373     DEBUG(3, ("Failed to find authenticated user %s via "
5374     "getpwnam(), denying access.\n", dom_user));
5375     --
5376     2.39.0
5377    
5378    
5379     From a3ffab81c235aae479262cca73cf4361f76f7f9d Mon Sep 17 00:00:00 2001
5380     From: Ralph Boehme <slow@samba.org>
5381     Date: Fri, 8 Oct 2021 12:33:16 +0200
5382     Subject: [PATCH 070/142] CVE-2020-25717: s3:auth: remove fallbacks in
5383     smb_getpwnam()
5384    
5385     So far we tried getpwnam("DOMAIN\account") first and
5386     always did a fallback to getpwnam("account") completely
5387     ignoring the domain part, this just causes problems
5388     as we mix "DOMAIN1\account", "DOMAIN2\account",
5389     and "account"!
5390    
5391     As we require a running winbindd for domain member setups
5392     we should no longer do a fallback to just "account" for
5393     users served by winbindd!
5394    
5395     For users of the local SAM don't use this code path,
5396     as check_sam_security() doesn't call check_account().
5397    
5398     The only case where smb_getpwnam("account") happens is
5399     when map_username() via ("username map [script]") mapped
5400     "DOMAIN\account" to something without '\', but that is
5401     explicitly desired by the admin.
5402    
5403     Note: use 'git show -w'
5404    
5405     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
5406     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
5407    
5408     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
5409    
5410     Signed-off-by: Ralph Boehme <slow@samba.org>
5411     Signed-off-by: Stefan Metzmacher <metze@samba.org>
5412     ---
5413     source3/auth/auth_util.c | 77 ++++++++++++++++++++++------------------
5414     1 file changed, 42 insertions(+), 35 deletions(-)
5415    
5416     diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
5417     index 6ee500493e6..161e05c2106 100644
5418     --- a/source3/auth/auth_util.c
5419     +++ b/source3/auth/auth_util.c
5420     @@ -1908,7 +1908,7 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
5421     {
5422     struct passwd *pw = NULL;
5423     char *p = NULL;
5424     - char *username = NULL;
5425     + const char *username = NULL;
5426    
5427     /* we only save a copy of the username it has been mangled
5428     by winbindd use default domain */
5429     @@ -1927,48 +1927,55 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
5430     /* code for a DOMAIN\user string */
5431    
5432     if ( p ) {
5433     - pw = Get_Pwnam_alloc( mem_ctx, domuser );
5434     - if ( pw ) {
5435     - /* make sure we get the case of the username correct */
5436     - /* work around 'winbind use default domain = yes' */
5437     -
5438     - if ( lp_winbind_use_default_domain() &&
5439     - !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
5440     - char *domain;
5441     -
5442     - /* split the domain and username into 2 strings */
5443     - *p = '\0';
5444     - domain = username;
5445     -
5446     - *p_save_username = talloc_asprintf(mem_ctx,
5447     - "%s%c%s",
5448     - domain,
5449     - *lp_winbind_separator(),
5450     - pw->pw_name);
5451     - if (!*p_save_username) {
5452     - TALLOC_FREE(pw);
5453     - return NULL;
5454     - }
5455     - } else {
5456     - *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
5457     - }
5458     + const char *domain = NULL;
5459    
5460     - /* whew -- done! */
5461     - return pw;
5462     + /* split the domain and username into 2 strings */
5463     + *p = '\0';
5464     + domain = username;
5465     + p++;
5466     + username = p;
5467     +
5468     + if (strequal(domain, get_global_sam_name())) {
5469     + /*
5470     + * This typically don't happen
5471     + * as check_sam_Security()
5472     + * don't call make_server_info_info3()
5473     + * and thus check_account().
5474     + *
5475     + * But we better keep this.
5476     + */
5477     + goto username_only;
5478     }
5479    
5480     - /* setup for lookup of just the username */
5481     - /* remember that p and username are overlapping memory */
5482     -
5483     - p++;
5484     - username = talloc_strdup(mem_ctx, p);
5485     - if (!username) {
5486     + pw = Get_Pwnam_alloc( mem_ctx, domuser );
5487     + if (pw == NULL) {
5488     return NULL;
5489     }
5490     + /* make sure we get the case of the username correct */
5491     + /* work around 'winbind use default domain = yes' */
5492     +
5493     + if ( lp_winbind_use_default_domain() &&
5494     + !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
5495     + *p_save_username = talloc_asprintf(mem_ctx,
5496     + "%s%c%s",
5497     + domain,
5498     + *lp_winbind_separator(),
5499     + pw->pw_name);
5500     + if (!*p_save_username) {
5501     + TALLOC_FREE(pw);
5502     + return NULL;
5503     + }
5504     + } else {
5505     + *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
5506     + }
5507     +
5508     + /* whew -- done! */
5509     + return pw;
5510     +
5511     }
5512    
5513     /* just lookup a plain username */
5514     -
5515     +username_only:
5516     pw = Get_Pwnam_alloc(mem_ctx, username);
5517    
5518     /* Create local user if requested but only if winbindd
5519     --
5520     2.39.0
5521    
5522    
5523     From 9a1bb168388205f5a2bfa459a5da63c5046eaa7a Mon Sep 17 00:00:00 2001
5524     From: Stefan Metzmacher <metze@samba.org>
5525     Date: Mon, 4 Oct 2021 18:03:55 +0200
5526     Subject: [PATCH 071/142] CVE-2020-25717: s3:auth: don't let create_local_token
5527     depend on !winbind_ping()
5528    
5529     We always require a running winbindd on a domain member, so
5530     we should better fail a request instead of silently alter
5531     the behaviour, which results in a different unix token, just
5532     because winbindd might be restarted.
5533    
5534     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
5535     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
5536    
5537     Signed-off-by: Stefan Metzmacher <metze@samba.org>
5538     ---
5539     source3/auth/auth_util.c | 10 ++++------
5540     1 file changed, 4 insertions(+), 6 deletions(-)
5541    
5542     diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
5543     index 161e05c2106..c0e5cfd7fa8 100644
5544     --- a/source3/auth/auth_util.c
5545     +++ b/source3/auth/auth_util.c
5546     @@ -551,13 +551,11 @@ NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
5547     }
5548    
5549     /*
5550     - * If winbind is not around, we can not make much use of the SIDs the
5551     - * domain controller provided us with. Likewise if the user name was
5552     - * mapped to some local unix user.
5553     + * If the user name was mapped to some local unix user,
5554     + * we can not make much use of the SIDs the
5555     + * domain controller provided us with.
5556     */
5557     -
5558     - if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
5559     - (server_info->nss_token)) {
5560     + if (server_info->nss_token) {
5561     char *found_username = NULL;
5562     status = create_token_from_username(session_info,
5563     server_info->unix_name,
5564     --
5565     2.39.0
5566    
5567    
5568     From bbe5c6693ba6954dab5bfef9f8c3778164cd879e Mon Sep 17 00:00:00 2001
5569     From: Alexander Bokovoy <ab@samba.org>
5570     Date: Wed, 11 Nov 2020 18:50:45 +0200
5571     Subject: [PATCH 072/142] CVE-2020-25717: Add FreeIPA domain controller role
5572    
5573     As we want to reduce use of 'classic domain controller' role but FreeIPA
5574     relies on it internally, add a separate role to mark FreeIPA domain
5575     controller role.
5576    
5577     It means that role won't result in ROLE_STANDALONE.
5578    
5579     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
5580     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
5581    
5582     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
5583    
5584     Signed-off-by: Alexander Bokovoy <ab@samba.org>
5585     Signed-off-by: Stefan Metzmacher <metze@samba.org>
5586    
5587     [abartlet@samba.org Backported due to conflict with DEBUG
5588     statements and IPA branding changes in comments]
5589     ---
5590     docs-xml/smbdotconf/security/serverrole.xml | 7 ++++
5591     lib/param/loadparm_server_role.c | 2 ++
5592     lib/param/param_table.c | 1 +
5593     lib/param/util.c | 1 +
5594     libcli/netlogon/netlogon.c | 2 +-
5595     libds/common/roles.h | 1 +
5596     source3/auth/auth.c | 3 ++
5597     source3/auth/auth_sam.c | 2 ++
5598     source3/include/smb_macros.h | 2 +-
5599     source3/lib/netapi/joindomain.c | 1 +
5600     source3/param/loadparm.c | 4 ++-
5601     source3/passdb/lookup_sid.c | 1 -
5602     source3/passdb/machine_account_secrets.c | 7 ++--
5603     source3/registry/reg_backend_prod_options.c | 1 +
5604     source3/rpc_server/dssetup/srv_dssetup_nt.c | 1 +
5605     source3/smbd/server.c | 2 +-
5606     source3/winbindd/winbindd_misc.c | 2 +-
5607     source3/winbindd/winbindd_util.c | 40 ++++++++++++++++-----
5608     source4/auth/ntlm/auth.c | 1 +
5609     source4/kdc/kdc-heimdal.c | 1 +
5610     source4/rpc_server/samr/dcesrv_samr.c | 2 ++
5611     21 files changed, 65 insertions(+), 19 deletions(-)
5612    
5613     diff --git a/docs-xml/smbdotconf/security/serverrole.xml b/docs-xml/smbdotconf/security/serverrole.xml
5614     index 9511c61c96d..b8b83a127b5 100644
5615     --- a/docs-xml/smbdotconf/security/serverrole.xml
5616     +++ b/docs-xml/smbdotconf/security/serverrole.xml
5617     @@ -78,6 +78,13 @@
5618     url="http://wiki.samba.org/index.php/Samba4/HOWTO">Samba4
5619     HOWTO</ulink></para>
5620    
5621     + <para><anchor id="IPA-DC"/><emphasis>SERVER ROLE = IPA DOMAIN CONTROLLER</emphasis></para>
5622     +
5623     + <para>This mode of operation runs Samba in a hybrid mode for IPA
5624     + domain controller, providing forest trust to Active Directory.
5625     + This role requires special configuration performed by IPA installers
5626     + and should not be used manually by any administrator.
5627     + </para>
5628     </description>
5629    
5630     <related>security</related>
5631     diff --git a/lib/param/loadparm_server_role.c b/lib/param/loadparm_server_role.c
5632     index 7a6bc770723..a78d1ab9cf3 100644
5633     --- a/lib/param/loadparm_server_role.c
5634     +++ b/lib/param/loadparm_server_role.c
5635     @@ -42,6 +42,7 @@ static const struct srv_role_tab {
5636     { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
5637     { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
5638     { ROLE_ACTIVE_DIRECTORY_DC, "ROLE_ACTIVE_DIRECTORY_DC" },
5639     + { ROLE_IPA_DC, "ROLE_IPA_DC"},
5640     { 0, NULL }
5641     };
5642    
5643     @@ -140,6 +141,7 @@ bool lp_is_security_and_server_role_valid(int server_role, int security)
5644     case ROLE_DOMAIN_PDC:
5645     case ROLE_DOMAIN_BDC:
5646     case ROLE_ACTIVE_DIRECTORY_DC:
5647     + case ROLE_IPA_DC:
5648     if (security == SEC_USER) {
5649     valid = true;
5650     }
5651     diff --git a/lib/param/param_table.c b/lib/param/param_table.c
5652     index f9d3b55adf2..aed205d1944 100644
5653     --- a/lib/param/param_table.c
5654     +++ b/lib/param/param_table.c
5655     @@ -100,6 +100,7 @@ static const struct enum_list enum_server_role[] = {
5656     {ROLE_ACTIVE_DIRECTORY_DC, "active directory domain controller"},
5657     {ROLE_ACTIVE_DIRECTORY_DC, "domain controller"},
5658     {ROLE_ACTIVE_DIRECTORY_DC, "dc"},
5659     + {ROLE_IPA_DC, "IPA primary domain controller"},
5660     {-1, NULL}
5661     };
5662    
5663     diff --git a/lib/param/util.c b/lib/param/util.c
5664     index cd8e74b9d8f..9a0fc102de8 100644
5665     --- a/lib/param/util.c
5666     +++ b/lib/param/util.c
5667     @@ -255,6 +255,7 @@ const char *lpcfg_sam_name(struct loadparm_context *lp_ctx)
5668     case ROLE_DOMAIN_BDC:
5669     case ROLE_DOMAIN_PDC:
5670     case ROLE_ACTIVE_DIRECTORY_DC:
5671     + case ROLE_IPA_DC:
5672     return lpcfg_workgroup(lp_ctx);
5673     default:
5674     return lpcfg_netbios_name(lp_ctx);
5675     diff --git a/libcli/netlogon/netlogon.c b/libcli/netlogon/netlogon.c
5676     index 58a331d70ad..838bdf84c87 100644
5677     --- a/libcli/netlogon/netlogon.c
5678     +++ b/libcli/netlogon/netlogon.c
5679     @@ -93,7 +93,7 @@ NTSTATUS pull_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
5680     if (ndr->offset < ndr->data_size) {
5681     TALLOC_FREE(ndr);
5682     /*
5683     - * We need to handle a bug in FreeIPA (at least <= 4.1.2).
5684     + * We need to handle a bug in IPA (at least <= 4.1.2).
5685     *
5686     * They include the ip address information without setting
5687     * NETLOGON_NT_VERSION_5EX_WITH_IP, while using
5688     diff --git a/libds/common/roles.h b/libds/common/roles.h
5689     index 4772c8d7d3f..03ba1915b21 100644
5690     --- a/libds/common/roles.h
5691     +++ b/libds/common/roles.h
5692     @@ -33,6 +33,7 @@ enum server_role {
5693    
5694     /* not in samr.idl */
5695     ROLE_ACTIVE_DIRECTORY_DC = 4,
5696     + ROLE_IPA_DC = 5,
5697    
5698     /* To determine the role automatically, this is not a valid role */
5699     ROLE_AUTO = 100
5700     diff --git a/source3/auth/auth.c b/source3/auth/auth.c
5701     index 0a96d591808..c5bfe9ac626 100644
5702     --- a/source3/auth/auth.c
5703     +++ b/source3/auth/auth.c
5704     @@ -529,6 +529,7 @@ NTSTATUS make_auth3_context_for_ntlm(TALLOC_CTX *mem_ctx,
5705     break;
5706     case ROLE_DOMAIN_BDC:
5707     case ROLE_DOMAIN_PDC:
5708     + case ROLE_IPA_DC:
5709     DEBUG(5,("Making default auth method list for DC\n"));
5710     methods = "anonymous sam winbind sam_ignoredomain";
5711     break;
5712     @@ -557,6 +558,7 @@ NTSTATUS make_auth3_context_for_netlogon(TALLOC_CTX *mem_ctx,
5713     switch (lp_server_role()) {
5714     case ROLE_DOMAIN_BDC:
5715     case ROLE_DOMAIN_PDC:
5716     + case ROLE_IPA_DC:
5717     methods = "sam_netlogon3 winbind";
5718     break;
5719    
5720     @@ -578,6 +580,7 @@ NTSTATUS make_auth3_context_for_winbind(TALLOC_CTX *mem_ctx,
5721     case ROLE_DOMAIN_MEMBER:
5722     case ROLE_DOMAIN_BDC:
5723     case ROLE_DOMAIN_PDC:
5724     + case ROLE_IPA_DC:
5725     methods = "sam";
5726     break;
5727     case ROLE_ACTIVE_DIRECTORY_DC:
5728     diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
5729     index f9764d87e3c..d0b29083d46 100644
5730     --- a/source3/auth/auth_sam.c
5731     +++ b/source3/auth/auth_sam.c
5732     @@ -139,6 +139,7 @@ static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context,
5733     break;
5734     case ROLE_DOMAIN_PDC:
5735     case ROLE_DOMAIN_BDC:
5736     + case ROLE_IPA_DC:
5737     if ( !is_local_name && !is_my_domain ) {
5738     DEBUG(6,("check_samstrict_security: %s is not one of my local names or domain name (DC)\n",
5739     effective_domain));
5740     @@ -209,6 +210,7 @@ static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context,
5741     switch (lp_server_role()) {
5742     case ROLE_DOMAIN_PDC:
5743     case ROLE_DOMAIN_BDC:
5744     + case ROLE_IPA_DC:
5745     break;
5746     default:
5747     DBG_ERR("Invalid server role\n");
5748     diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
5749     index 06d24744960..346401510c2 100644
5750     --- a/source3/include/smb_macros.h
5751     +++ b/source3/include/smb_macros.h
5752     @@ -213,7 +213,7 @@ copy an IP address from one buffer to another
5753     Check to see if we are a DC for this domain
5754     *****************************************************************************/
5755    
5756     -#define IS_DC (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC || lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC)
5757     +#define IS_DC (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC || lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC || lp_server_role() == ROLE_IPA_DC)
5758     #define IS_AD_DC (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC)
5759    
5760     /*
5761     diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c
5762     index 8d0752f4531..0344c0e0416 100644
5763     --- a/source3/lib/netapi/joindomain.c
5764     +++ b/source3/lib/netapi/joindomain.c
5765     @@ -369,6 +369,7 @@ WERROR NetGetJoinInformation_l(struct libnetapi_ctx *ctx,
5766     case ROLE_DOMAIN_MEMBER:
5767     case ROLE_DOMAIN_PDC:
5768     case ROLE_DOMAIN_BDC:
5769     + case ROLE_IPA_DC:
5770     *r->out.name_type = NetSetupDomainName;
5771     break;
5772     case ROLE_STANDALONE:
5773     diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
5774     index 57d1d909099..98e05d13d59 100644
5775     --- a/source3/param/loadparm.c
5776     +++ b/source3/param/loadparm.c
5777     @@ -4321,6 +4321,7 @@ int lp_default_server_announce(void)
5778     default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5779     break;
5780     case ROLE_DOMAIN_PDC:
5781     + case ROLE_IPA_DC:
5782     default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5783     break;
5784     case ROLE_DOMAIN_BDC:
5785     @@ -4346,7 +4347,8 @@ int lp_default_server_announce(void)
5786     bool lp_domain_master(void)
5787     {
5788     if (Globals._domain_master == Auto)
5789     - return (lp_server_role() == ROLE_DOMAIN_PDC);
5790     + return (lp_server_role() == ROLE_DOMAIN_PDC ||
5791     + lp_server_role() == ROLE_IPA_DC);
5792    
5793     return (bool)Globals._domain_master;
5794     }
5795     diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
5796     index 186ba17fda6..839da5cfbf4 100644
5797     --- a/source3/passdb/lookup_sid.c
5798     +++ b/source3/passdb/lookup_sid.c
5799     @@ -117,7 +117,6 @@ bool lookup_name(TALLOC_CTX *mem_ctx,
5800     if (((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) &&
5801     strequal(domain, get_global_sam_name()))
5802     {
5803     -
5804     /* It's our own domain, lookup the name in passdb */
5805     if (lookup_global_sam_name(name, flags, &rid, &type)) {
5806     sid_compose(&sid, get_global_sam_sid(), rid);
5807     diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c
5808     index dfc21f295a1..b60cf56c490 100644
5809     --- a/source3/passdb/machine_account_secrets.c
5810     +++ b/source3/passdb/machine_account_secrets.c
5811     @@ -198,7 +198,8 @@ bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
5812     dyn_guid = (struct GUID *)secrets_fetch(key, &size);
5813    
5814     if (!dyn_guid) {
5815     - if (lp_server_role() == ROLE_DOMAIN_PDC) {
5816     + if (lp_server_role() == ROLE_DOMAIN_PDC ||
5817     + lp_server_role() == ROLE_IPA_DC) {
5818     new_guid = GUID_random();
5819     if (!secrets_store_domain_guid(domain, &new_guid))
5820     return False;
5821     @@ -314,9 +315,7 @@ static const char *trust_keystr(const char *domain)
5822    
5823     enum netr_SchannelType get_default_sec_channel(void)
5824     {
5825     - if (lp_server_role() == ROLE_DOMAIN_BDC ||
5826     - lp_server_role() == ROLE_DOMAIN_PDC ||
5827     - lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
5828     + if (IS_DC) {
5829     return SEC_CHAN_BDC;
5830     } else {
5831     return SEC_CHAN_WKSTA;
5832     diff --git a/source3/registry/reg_backend_prod_options.c b/source3/registry/reg_backend_prod_options.c
5833     index 655c587ac40..7bd3f324c37 100644
5834     --- a/source3/registry/reg_backend_prod_options.c
5835     +++ b/source3/registry/reg_backend_prod_options.c
5836     @@ -40,6 +40,7 @@ static int prod_options_fetch_values(const char *key, struct regval_ctr *regvals
5837     switch (lp_server_role()) {
5838     case ROLE_DOMAIN_PDC:
5839     case ROLE_DOMAIN_BDC:
5840     + case ROLE_IPA_DC:
5841     value_ascii = "LanmanNT";
5842     break;
5843     case ROLE_STANDALONE:
5844     diff --git a/source3/rpc_server/dssetup/srv_dssetup_nt.c b/source3/rpc_server/dssetup/srv_dssetup_nt.c
5845     index 7e3efa8504e..aa896e15ac4 100644
5846     --- a/source3/rpc_server/dssetup/srv_dssetup_nt.c
5847     +++ b/source3/rpc_server/dssetup/srv_dssetup_nt.c
5848     @@ -62,6 +62,7 @@ static WERROR fill_dsrole_dominfo_basic(TALLOC_CTX *ctx,
5849     basic->domain = get_global_sam_name();
5850     break;
5851     case ROLE_DOMAIN_PDC:
5852     + case ROLE_IPA_DC:
5853     basic->role = DS_ROLE_PRIMARY_DC;
5854     basic->domain = get_global_sam_name();
5855     break;
5856     diff --git a/source3/smbd/server.c b/source3/smbd/server.c
5857     index 7d96a5762ec..d263507b22f 100644
5858     --- a/source3/smbd/server.c
5859     +++ b/source3/smbd/server.c
5860     @@ -1969,7 +1969,7 @@ extern void build_options(bool screen);
5861     exit_daemon("smbd can not open secrets.tdb", EACCES);
5862     }
5863    
5864     - if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
5865     + if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC || lp_server_role() == ROLE_IPA_DC) {
5866     struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
5867     if (!open_schannel_session_store(NULL, lp_ctx)) {
5868     exit_daemon("ERROR: Samba cannot open schannel store for secured NETLOGON operations.", EACCES);
5869     diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c
5870     index cc0701e597a..f09b029fd13 100644
5871     --- a/source3/winbindd/winbindd_misc.c
5872     +++ b/source3/winbindd/winbindd_misc.c
5873     @@ -75,7 +75,7 @@ static char *get_trust_type_string(TALLOC_CTX *mem_ctx,
5874     case SEC_CHAN_BDC: {
5875     int role = lp_server_role();
5876    
5877     - if (role == ROLE_DOMAIN_PDC) {
5878     + if (role == ROLE_DOMAIN_PDC || role == ROLE_IPA_DC) {
5879     s = talloc_strdup(mem_ctx, "PDC");
5880     if (s == NULL) {
5881     return NULL;
5882     diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
5883     index 315eb366a52..04e79e70f6b 100644
5884     --- a/source3/winbindd/winbindd_util.c
5885     +++ b/source3/winbindd/winbindd_util.c
5886     @@ -1225,15 +1225,37 @@ bool init_domain_list(void)
5887     secure_channel_type = SEC_CHAN_LOCAL;
5888     }
5889    
5890     - status = add_trusted_domain(get_global_sam_name(),
5891     - NULL,
5892     - get_global_sam_sid(),
5893     - LSA_TRUST_TYPE_DOWNLEVEL,
5894     - trust_flags,
5895     - 0, /* trust_attribs */
5896     - secure_channel_type,
5897     - NULL,
5898     - &domain);
5899     + if ((pdb_domain_info != NULL) && (role == ROLE_IPA_DC)) {
5900     + /* This is IPA DC that presents itself as
5901     + * an Active Directory domain controller to trusted AD
5902     + * forests but in fact is a classic domain controller.
5903     + */
5904     + trust_flags = NETR_TRUST_FLAG_PRIMARY;
5905     + trust_flags |= NETR_TRUST_FLAG_IN_FOREST;
5906     + trust_flags |= NETR_TRUST_FLAG_NATIVE;
5907     + trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
5908     + trust_flags |= NETR_TRUST_FLAG_TREEROOT;
5909     + status = add_trusted_domain(pdb_domain_info->name,
5910     + pdb_domain_info->dns_domain,
5911     + &pdb_domain_info->sid,
5912     + LSA_TRUST_TYPE_UPLEVEL,
5913     + trust_flags,
5914     + LSA_TRUST_ATTRIBUTE_WITHIN_FOREST,
5915     + secure_channel_type,
5916     + NULL,
5917     + &domain);
5918     + TALLOC_FREE(pdb_domain_info);
5919     + } else {
5920     + status = add_trusted_domain(get_global_sam_name(),
5921     + NULL,
5922     + get_global_sam_sid(),
5923     + LSA_TRUST_TYPE_DOWNLEVEL,
5924     + trust_flags,
5925     + 0, /* trust_attribs */
5926     + secure_channel_type,
5927     + NULL,
5928     + &domain);
5929     + }
5930     if (!NT_STATUS_IS_OK(status)) {
5931     DBG_ERR("Failed to add local SAM to "
5932     "domain to winbindd's internal list\n");
5933     diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
5934     index f754bd5cd44..7dab02b5c4d 100644
5935     --- a/source4/auth/ntlm/auth.c
5936     +++ b/source4/auth/ntlm/auth.c
5937     @@ -773,6 +773,7 @@ const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *
5938     case ROLE_DOMAIN_BDC:
5939     case ROLE_DOMAIN_PDC:
5940     case ROLE_ACTIVE_DIRECTORY_DC:
5941     + case ROLE_IPA_DC:
5942     auth_methods = str_list_make(mem_ctx, "anonymous sam winbind sam_ignoredomain", NULL);
5943     break;
5944     }
5945     diff --git a/source4/kdc/kdc-heimdal.c b/source4/kdc/kdc-heimdal.c
5946     index b5de5a790d4..49aa560470c 100644
5947     --- a/source4/kdc/kdc-heimdal.c
5948     +++ b/source4/kdc/kdc-heimdal.c
5949     @@ -276,6 +276,7 @@ static NTSTATUS kdc_task_init(struct task_server *task)
5950     return NT_STATUS_INVALID_DOMAIN_ROLE;
5951     case ROLE_DOMAIN_PDC:
5952     case ROLE_DOMAIN_BDC:
5953     + case ROLE_IPA_DC:
5954     task_server_terminate(
5955     task, "Cannot start KDC as a 'classic Samba' DC", false);
5956     return NT_STATUS_INVALID_DOMAIN_ROLE;
5957     diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
5958     index 51fed4da62b..1f09b721408 100644
5959     --- a/source4/rpc_server/samr/dcesrv_samr.c
5960     +++ b/source4/rpc_server/samr/dcesrv_samr.c
5961     @@ -568,6 +568,7 @@ static NTSTATUS dcesrv_samr_info_DomGeneralInformation(struct samr_domain_state
5962     break;
5963     case ROLE_DOMAIN_PDC:
5964     case ROLE_DOMAIN_BDC:
5965     + case ROLE_IPA_DC:
5966     case ROLE_AUTO:
5967     return NT_STATUS_INTERNAL_ERROR;
5968     case ROLE_DOMAIN_MEMBER:
5969     @@ -675,6 +676,7 @@ static NTSTATUS dcesrv_samr_info_DomInfo7(struct samr_domain_state *state,
5970     break;
5971     case ROLE_DOMAIN_PDC:
5972     case ROLE_DOMAIN_BDC:
5973     + case ROLE_IPA_DC:
5974     case ROLE_AUTO:
5975     return NT_STATUS_INTERNAL_ERROR;
5976     case ROLE_DOMAIN_MEMBER:
5977     --
5978     2.39.0
5979    
5980    
5981     From 3a8b4d3b410508dfb0538376046a5b38c53f9568 Mon Sep 17 00:00:00 2001
5982     From: Stefan Metzmacher <metze@samba.org>
5983     Date: Tue, 5 Oct 2021 18:11:57 +0200
5984     Subject: [PATCH 073/142] CVE-2020-25717: auth/gensec: always require a PAC in
5985     domain mode (DC or member)
5986    
5987     AD domains always provide a PAC unless UF_NO_AUTH_DATA_REQUIRED is set
5988     on the service account, which can only be explicitly configured,
5989     but that's an invalid configuration!
5990    
5991     We still try to support standalone servers in an MIT realm,
5992     as legacy setup.
5993    
5994     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
5995     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
5996    
5997     Signed-off-by: Stefan Metzmacher <metze@samba.org>
5998     ---
5999     auth/gensec/gensec_util.c | 27 +++++++++++++++++++++++----
6000     1 file changed, 23 insertions(+), 4 deletions(-)
6001    
6002     diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c
6003     index e185acc0c20..694661b53b5 100644
6004     --- a/auth/gensec/gensec_util.c
6005     +++ b/auth/gensec/gensec_util.c
6006     @@ -25,6 +25,8 @@
6007     #include "auth/gensec/gensec_internal.h"
6008     #include "auth/common_auth.h"
6009     #include "../lib/util/asn1.h"
6010     +#include "param/param.h"
6011     +#include "libds/common/roles.h"
6012    
6013     #undef DBGC_CLASS
6014     #define DBGC_CLASS DBGC_AUTH
6015     @@ -46,10 +48,27 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx,
6016     session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
6017    
6018     if (!pac_blob) {
6019     - if (gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) {
6020     - DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n",
6021     - principal_string));
6022     - return NT_STATUS_ACCESS_DENIED;
6023     + enum server_role server_role =
6024     + lpcfg_server_role(gensec_security->settings->lp_ctx);
6025     +
6026     + /*
6027     + * For any domain setup (DC or member) we require having
6028     + * a PAC, as the service ticket comes from an AD DC,
6029     + * which will always provide a PAC, unless
6030     + * UF_NO_AUTH_DATA_REQUIRED is configured for our
6031     + * account, but that's just an invalid configuration,
6032     + * the admin configured for us!
6033     + *
6034     + * As a legacy case, we still allow kerberos tickets from an MIT
6035     + * realm, but only in standalone mode. In that mode we'll only
6036     + * ever accept a kerberos authentication with a keytab file
6037     + * being explicitly configured via the 'keytab method' option.
6038     + */
6039     + if (server_role != ROLE_STANDALONE) {
6040     + DBG_WARNING("Unable to find PAC in ticket from %s, "
6041     + "failing to allow access\n",
6042     + principal_string);
6043     + return NT_STATUS_NO_IMPERSONATION_TOKEN;
6044     }
6045     DBG_NOTICE("Unable to find PAC for %s, resorting to local "
6046     "user lookup\n", principal_string);
6047     --
6048     2.39.0
6049    
6050    
6051     From 15cca0f7ee6f4b8d96b6b650b2d009b030a2bc5f Mon Sep 17 00:00:00 2001
6052     From: Stefan Metzmacher <metze@samba.org>
6053     Date: Mon, 11 Oct 2021 23:17:19 +0200
6054     Subject: [PATCH 074/142] CVE-2020-25717: s4:auth: remove unused
6055     auth_generate_session_info_principal()
6056    
6057     We'll require a PAC at the main gensec layer already.
6058    
6059     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
6060     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
6061    
6062     Signed-off-by: Stefan Metzmacher <metze@samba.org>
6063    
6064     [abartlet@samba.org Backported from master/4.15 as
6065     check_password is sync in 4.14]
6066     ---
6067     source4/auth/auth.h | 8 ------
6068     source4/auth/ntlm/auth.c | 49 ++++--------------------------------
6069     source4/auth/ntlm/auth_sam.c | 12 ---------
6070     3 files changed, 5 insertions(+), 64 deletions(-)
6071    
6072     diff --git a/source4/auth/auth.h b/source4/auth/auth.h
6073     index 51895c9259f..f16d0649de2 100644
6074     --- a/source4/auth/auth.h
6075     +++ b/source4/auth/auth.h
6076     @@ -73,14 +73,6 @@ struct auth_operations {
6077     TALLOC_CTX *mem_ctx,
6078     struct auth_user_info_dc **interim_info,
6079     bool *authoritative);
6080     -
6081     - /* Lookup a 'session info interim' return based only on the principal or DN */
6082     - NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx,
6083     - struct auth4_context *auth_context,
6084     - const char *principal,
6085     - struct ldb_dn *user_dn,
6086     - struct auth_user_info_dc **interim_info);
6087     - uint32_t flags;
6088     };
6089    
6090     struct auth_method_context {
6091     diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
6092     index 7dab02b5c4d..2765fd1b13c 100644
6093     --- a/source4/auth/ntlm/auth.c
6094     +++ b/source4/auth/ntlm/auth.c
6095     @@ -86,48 +86,6 @@ _PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t cha
6096     return NT_STATUS_OK;
6097     }
6098    
6099     -/****************************************************************************
6100     -Used in the gensec_gssapi and gensec_krb5 server-side code, where the
6101     -PAC isn't available, and for tokenGroups in the DSDB stack.
6102     -
6103     - Supply either a principal or a DN
6104     -****************************************************************************/
6105     -static NTSTATUS auth_generate_session_info_principal(struct auth4_context *auth_ctx,
6106     - TALLOC_CTX *mem_ctx,
6107     - const char *principal,
6108     - struct ldb_dn *user_dn,
6109     - uint32_t session_info_flags,
6110     - struct auth_session_info **session_info)
6111     -{
6112     - NTSTATUS nt_status;
6113     - struct auth_method_context *method;
6114     - struct auth_user_info_dc *user_info_dc;
6115     -
6116     - for (method = auth_ctx->methods; method; method = method->next) {
6117     - if (!method->ops->get_user_info_dc_principal) {
6118     - continue;
6119     - }
6120     -
6121     - nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, &user_info_dc);
6122     - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
6123     - continue;
6124     - }
6125     - if (!NT_STATUS_IS_OK(nt_status)) {
6126     - return nt_status;
6127     - }
6128     -
6129     - nt_status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx,
6130     - user_info_dc,
6131     - user_info_dc->info->account_name,
6132     - session_info_flags, session_info);
6133     - talloc_free(user_info_dc);
6134     -
6135     - return nt_status;
6136     - }
6137     -
6138     - return NT_STATUS_NOT_IMPLEMENTED;
6139     -}
6140     -
6141     /**
6142     * Check a user's Plaintext, LM or NTLM password.
6143     * (sync version)
6144     @@ -663,8 +621,11 @@ static NTSTATUS auth_generate_session_info_pac(struct auth4_context *auth_ctx,
6145     TALLOC_CTX *tmp_ctx;
6146    
6147     if (!pac_blob) {
6148     - return auth_generate_session_info_principal(auth_ctx, mem_ctx, principal_name,
6149     - NULL, session_info_flags, session_info);
6150     + /*
6151     + * This should already be catched at the main
6152     + * gensec layer, but better check twice
6153     + */
6154     + return NT_STATUS_INTERNAL_ERROR;
6155     }
6156    
6157     tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context");
6158     diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
6159     index fb88cb87f66..a8c7d8b4b85 100644
6160     --- a/source4/auth/ntlm/auth_sam.c
6161     +++ b/source4/auth/ntlm/auth_sam.c
6162     @@ -854,28 +854,16 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx,
6163     return NT_STATUS_OK;
6164     }
6165    
6166     -/* Wrapper for the auth subsystem pointer */
6167     -static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx,
6168     - struct auth4_context *auth_context,
6169     - const char *principal,
6170     - struct ldb_dn *user_dn,
6171     - struct auth_user_info_dc **user_info_dc)
6172     -{
6173     - return authsam_get_user_info_dc_principal(mem_ctx, auth_context->lp_ctx, auth_context->sam_ctx,
6174     - principal, user_dn, user_info_dc);
6175     -}
6176     static const struct auth_operations sam_ignoredomain_ops = {
6177     .name = "sam_ignoredomain",
6178     .want_check = authsam_ignoredomain_want_check,
6179     .check_password = authsam_check_password_internals,
6180     - .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
6181     };
6182    
6183     static const struct auth_operations sam_ops = {
6184     .name = "sam",
6185     .want_check = authsam_want_check,
6186     .check_password = authsam_check_password_internals,
6187     - .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
6188     };
6189    
6190     _PUBLIC_ NTSTATUS auth4_sam_init(TALLOC_CTX *);
6191     --
6192     2.39.0
6193    
6194    
6195     From ec14a33f17e638870c997b56d4b5ce9096cbb27a Mon Sep 17 00:00:00 2001
6196     From: Stefan Metzmacher <metze@samba.org>
6197     Date: Tue, 21 Sep 2021 12:27:28 +0200
6198     Subject: [PATCH 075/142] CVE-2020-25717: s3:ntlm_auth: fix memory leaks in
6199     ntlm_auth_generate_session_info_pac()
6200    
6201     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
6202     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
6203    
6204     Signed-off-by: Stefan Metzmacher <metze@samba.org>
6205     ---
6206     source3/utils/ntlm_auth.c | 18 ++++++++++++------
6207     1 file changed, 12 insertions(+), 6 deletions(-)
6208    
6209     diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
6210     index 3f70732a837..fefdd32bf11 100644
6211     --- a/source3/utils/ntlm_auth.c
6212     +++ b/source3/utils/ntlm_auth.c
6213     @@ -827,23 +827,27 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
6214     if (!p) {
6215     DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
6216     princ_name));
6217     - return NT_STATUS_LOGON_FAILURE;
6218     + status = NT_STATUS_LOGON_FAILURE;
6219     + goto done;
6220     }
6221    
6222     user = talloc_strndup(mem_ctx, princ_name, p - princ_name);
6223     if (!user) {
6224     - return NT_STATUS_NO_MEMORY;
6225     + status = NT_STATUS_NO_MEMORY;
6226     + goto done;
6227     }
6228    
6229     realm = talloc_strdup(talloc_tos(), p + 1);
6230     if (!realm) {
6231     - return NT_STATUS_NO_MEMORY;
6232     + status = NT_STATUS_NO_MEMORY;
6233     + goto done;
6234     }
6235    
6236     if (!strequal(realm, lp_realm())) {
6237     DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm));
6238     if (!lp_allow_trusted_domains()) {
6239     - return NT_STATUS_LOGON_FAILURE;
6240     + status = NT_STATUS_LOGON_FAILURE;
6241     + goto done;
6242     }
6243     }
6244    
6245     @@ -851,7 +855,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
6246     domain = talloc_strdup(mem_ctx,
6247     logon_info->info3.base.logon_domain.string);
6248     if (!domain) {
6249     - return NT_STATUS_NO_MEMORY;
6250     + status = NT_STATUS_NO_MEMORY;
6251     + goto done;
6252     }
6253     DEBUG(10, ("Domain is [%s] (using PAC)\n", domain));
6254     } else {
6255     @@ -881,7 +886,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
6256     domain = talloc_strdup(mem_ctx, realm);
6257     }
6258     if (!domain) {
6259     - return NT_STATUS_NO_MEMORY;
6260     + status = NT_STATUS_NO_MEMORY;
6261     + goto done;
6262     }
6263     DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain));
6264     }
6265     --
6266     2.39.0
6267    
6268    
6269     From 9e036a77eca721c4ea23c3f629d9e504d5780f79 Mon Sep 17 00:00:00 2001
6270     From: Stefan Metzmacher <metze@samba.org>
6271     Date: Tue, 21 Sep 2021 12:44:01 +0200
6272     Subject: [PATCH 076/142] CVE-2020-25717: s3:ntlm_auth: let
6273     ntlm_auth_generate_session_info_pac() base the name on the PAC LOGON_INFO
6274     only
6275    
6276     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
6277     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
6278    
6279     Signed-off-by: Stefan Metzmacher <metze@samba.org>
6280     ---
6281     source3/utils/ntlm_auth.c | 91 ++++++++++++---------------------------
6282     1 file changed, 28 insertions(+), 63 deletions(-)
6283    
6284     diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
6285     index fefdd32bf11..ff2fd30a9ae 100644
6286     --- a/source3/utils/ntlm_auth.c
6287     +++ b/source3/utils/ntlm_auth.c
6288     @@ -799,10 +799,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
6289     struct PAC_LOGON_INFO *logon_info = NULL;
6290     char *unixuser;
6291     NTSTATUS status;
6292     - char *domain = NULL;
6293     - char *realm = NULL;
6294     - char *user = NULL;
6295     - char *p;
6296     + const char *domain = "";
6297     + const char *user = "";
6298    
6299     tmp_ctx = talloc_new(mem_ctx);
6300     if (!tmp_ctx) {
6301     @@ -819,79 +817,46 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
6302     if (!NT_STATUS_IS_OK(status)) {
6303     goto done;
6304     }
6305     - }
6306     -
6307     - DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
6308     -
6309     - p = strchr_m(princ_name, '@');
6310     - if (!p) {
6311     - DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
6312     - princ_name));
6313     - status = NT_STATUS_LOGON_FAILURE;
6314     + } else {
6315     + status = NT_STATUS_ACCESS_DENIED;
6316     + DBG_WARNING("Kerberos ticket for[%s] has no PAC: %s\n",
6317     + princ_name, nt_errstr(status));
6318     goto done;
6319     }
6320    
6321     - user = talloc_strndup(mem_ctx, princ_name, p - princ_name);
6322     - if (!user) {
6323     - status = NT_STATUS_NO_MEMORY;
6324     - goto done;
6325     + if (logon_info->info3.base.account_name.string != NULL) {
6326     + user = logon_info->info3.base.account_name.string;
6327     + } else {
6328     + user = "";
6329     + }
6330     + if (logon_info->info3.base.logon_domain.string != NULL) {
6331     + domain = logon_info->info3.base.logon_domain.string;
6332     + } else {
6333     + domain = "";
6334     }
6335    
6336     - realm = talloc_strdup(talloc_tos(), p + 1);
6337     - if (!realm) {
6338     - status = NT_STATUS_NO_MEMORY;
6339     + if (strlen(user) == 0 || strlen(domain) == 0) {
6340     + status = NT_STATUS_ACCESS_DENIED;
6341     + DBG_WARNING("Kerberos ticket for[%s] has invalid "
6342     + "account_name[%s]/logon_domain[%s]: %s\n",
6343     + princ_name,
6344     + logon_info->info3.base.account_name.string,
6345     + logon_info->info3.base.logon_domain.string,
6346     + nt_errstr(status));
6347     goto done;
6348     }
6349    
6350     - if (!strequal(realm, lp_realm())) {
6351     - DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm));
6352     + DBG_NOTICE("Kerberos ticket principal name is [%s] "
6353     + "account_name[%s]/logon_domain[%s]\n",
6354     + princ_name, user, domain);
6355     +
6356     + if (!strequal(domain, lp_workgroup())) {
6357     if (!lp_allow_trusted_domains()) {
6358     status = NT_STATUS_LOGON_FAILURE;
6359     goto done;
6360     }
6361     }
6362    
6363     - if (logon_info && logon_info->info3.base.logon_domain.string) {
6364     - domain = talloc_strdup(mem_ctx,
6365     - logon_info->info3.base.logon_domain.string);
6366     - if (!domain) {
6367     - status = NT_STATUS_NO_MEMORY;
6368     - goto done;
6369     - }
6370     - DEBUG(10, ("Domain is [%s] (using PAC)\n", domain));
6371     - } else {
6372     -
6373     - /* If we have winbind running, we can (and must) shorten the
6374     - username by using the short netbios name. Otherwise we will
6375     - have inconsistent user names. With Kerberos, we get the
6376     - fully qualified realm, with ntlmssp we get the short
6377     - name. And even w2k3 does use ntlmssp if you for example
6378     - connect to an ip address. */
6379     -
6380     - wbcErr wbc_status;
6381     - struct wbcDomainInfo *info = NULL;
6382     -
6383     - DEBUG(10, ("Mapping [%s] to short name using winbindd\n",
6384     - realm));
6385     -
6386     - wbc_status = wbcDomainInfo(realm, &info);
6387     -
6388     - if (WBC_ERROR_IS_OK(wbc_status)) {
6389     - domain = talloc_strdup(mem_ctx,
6390     - info->short_name);
6391     - wbcFreeMemory(info);
6392     - } else {
6393     - DEBUG(3, ("Could not find short name: %s\n",
6394     - wbcErrorString(wbc_status)));
6395     - domain = talloc_strdup(mem_ctx, realm);
6396     - }
6397     - if (!domain) {
6398     - status = NT_STATUS_NO_MEMORY;
6399     - goto done;
6400     - }
6401     - DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain));
6402     - }
6403     -
6404     unixuser = talloc_asprintf(tmp_ctx, "%s%c%s", domain, winbind_separator(), user);
6405     if (!unixuser) {
6406     status = NT_STATUS_NO_MEMORY;
6407     --
6408     2.39.0
6409    
6410    
6411     From 4c01fd62e30b8e1137e7de01ecb41c94550dac24 Mon Sep 17 00:00:00 2001
6412     From: Stefan Metzmacher <metze@samba.org>
6413     Date: Mon, 4 Oct 2021 19:42:20 +0200
6414     Subject: [PATCH 077/142] CVE-2020-25717: s3:auth: let
6415     auth3_generate_session_info_pac() delegate everything to
6416     make_server_info_wbcAuthUserInfo()
6417    
6418     This consolidates the code paths used for NTLMSSP and Kerberos!
6419    
6420     I checked what we were already doing for NTLMSSP, which is this:
6421    
6422     a) source3/auth/auth_winbind.c calls wbcAuthenticateUserEx()
6423     b) as a domain member we require a valid response from winbindd,
6424     otherwise we'll return NT_STATUS_NO_LOGON_SERVERS
6425     c) we call make_server_info_wbcAuthUserInfo(), which internally
6426     calls make_server_info_info3()
6427     d) auth_check_ntlm_password() calls
6428     smb_pam_accountcheck(unix_username, rhost), where rhost
6429     is only an ipv4 or ipv6 address (without reverse dns lookup)
6430     e) from auth3_check_password_send/auth3_check_password_recv()
6431     server_returned_info will be passed to auth3_generate_session_info(),
6432     triggered by gensec_session_info(), which means we'll call into
6433     create_local_token() in order to transform auth_serversupplied_info
6434     into auth_session_info.
6435    
6436     For Kerberos gensec_session_info() will call
6437     auth3_generate_session_info_pac() via the gensec_generate_session_info_pac()
6438     helper function. The current logic is this:
6439    
6440     a) gensec_generate_session_info_pac() is the function that
6441     evaluates the 'gensec:require_pac', which defaulted to 'no'
6442     before.
6443     b) auth3_generate_session_info_pac() called
6444     wbcAuthenticateUserEx() in order to pass the PAC blob
6445     to winbindd, but only to prime its cache, e.g. netsamlogon cache
6446     and others. Most failures were just ignored.
6447     c) If the PAC blob is available, it extracted the PAC_LOGON_INFO
6448     from it.
6449     d) Then we called the horrible get_user_from_kerberos_info() function:
6450     - It uses a first part of the tickets principal name (before the @)
6451     as username and combines that with the 'logon_info->base.logon_domain'
6452     if the logon_info (PAC) is present.
6453     - As a fallback without a PAC it's tries to ask winbindd for a mapping
6454     from realm to netbios domain name.
6455     - Finally is falls back to using the realm as netbios domain name
6456     With this information is builds 'userdomain+winbind_separator+useraccount'
6457     and calls map_username() followed by smb_getpwnam() with create=true,
6458     Note this is similar to the make_server_info_info3() => check_account()
6459     => smb_getpwnam() logic under 3.
6460     - It also calls smb_pam_accountcheck(), but may pass the reverse DNS lookup name
6461     instead of the ip address as rhost.
6462     - It does some MAP_TO_GUEST_ON_BAD_UID logic and auto creates the
6463     guest account.
6464     e) We called create_info3_from_pac_logon_info()
6465     f) make_session_info_krb5() calls gets called and triggers this:
6466     - If get_user_from_kerberos_info() mapped to guest, it calls
6467     make_server_info_guest()
6468     - If create_info3_from_pac_logon_info() created a info3 from logon_info,
6469     it calls make_server_info_info3()
6470     - Without a PAC it tries pdb_getsampwnam()/make_server_info_sam() with
6471     a fallback to make_server_info_pw()
6472     From there it calls create_local_token()
6473    
6474     I tried to change auth3_generate_session_info_pac() to behave similar
6475     to auth_winbind.c together with auth3_generate_session_info() as
6476     a domain member, as we now rely on a PAC:
6477    
6478     a) As domain member we require a PAC and always call wbcAuthenticateUserEx()
6479     and require a valid response!
6480     b) we call make_server_info_wbcAuthUserInfo(), which internally
6481     calls make_server_info_info3(). Note make_server_info_info3()
6482     handles MAP_TO_GUEST_ON_BAD_UID and make_server_info_guest()
6483     internally.
6484     c) Similar to auth_check_ntlm_password() we now call
6485     smb_pam_accountcheck(unix_username, rhost), where rhost
6486     is only an ipv4 or ipv6 address (without reverse dns lookup)
6487     d) From there it calls create_local_token()
6488    
6489     As standalone server (in an MIT realm) we continue
6490     with the already existing code logic, which works without a PAC:
6491     a) we keep smb_getpwnam() with create=true logic as it
6492     also requires an explicit 'add user script' option.
6493     b) In the following commits we assert that there's
6494     actually no PAC in this mode, which means we can
6495     remove unused and confusing code.
6496    
6497     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14646
6498     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
6499    
6500     Signed-off-by: Stefan Metzmacher <metze@samba.org>
6501    
6502     [abartlet@samba.org Backported due to change in structure
6503     initialization with { 0 } to zero ]
6504     [abartlet@samba.org backported to 4.12 due to conflict
6505     with code not present to reload shared on krb5 login]
6506     ---
6507     source3/auth/auth_generic.c | 139 ++++++++++++++++++++++++++++--------
6508     1 file changed, 110 insertions(+), 29 deletions(-)
6509    
6510     diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
6511     index 26a38f92b30..3099e8f9057 100644
6512     --- a/source3/auth/auth_generic.c
6513     +++ b/source3/auth/auth_generic.c
6514     @@ -46,6 +46,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
6515     uint32_t session_info_flags,
6516     struct auth_session_info **session_info)
6517     {
6518     + enum server_role server_role = lp_server_role();
6519     TALLOC_CTX *tmp_ctx;
6520     struct PAC_LOGON_INFO *logon_info = NULL;
6521     struct netr_SamInfo3 *info3_copy = NULL;
6522     @@ -54,39 +55,59 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
6523     char *ntuser;
6524     char *ntdomain;
6525     char *username;
6526     - char *rhost;
6527     + const char *rhost;
6528     struct passwd *pw;
6529     NTSTATUS status;
6530     - int rc;
6531    
6532     tmp_ctx = talloc_new(mem_ctx);
6533     if (!tmp_ctx) {
6534     return NT_STATUS_NO_MEMORY;
6535     }
6536    
6537     - if (pac_blob) {
6538     -#ifdef HAVE_KRB5
6539     - struct wbcAuthUserParams params = {};
6540     + if (tsocket_address_is_inet(remote_address, "ip")) {
6541     + rhost = tsocket_address_inet_addr_string(
6542     + remote_address, tmp_ctx);
6543     + if (rhost == NULL) {
6544     + status = NT_STATUS_NO_MEMORY;
6545     + goto done;
6546     + }
6547     + } else {
6548     + rhost = "127.0.0.1";
6549     + }
6550     +
6551     + if (server_role != ROLE_STANDALONE) {
6552     + struct wbcAuthUserParams params = { 0 };
6553     struct wbcAuthUserInfo *info = NULL;
6554     struct wbcAuthErrorInfo *err = NULL;
6555     + struct auth_serversupplied_info *server_info = NULL;
6556     + char *original_user_name = NULL;
6557     + char *p = NULL;
6558     wbcErr wbc_err;
6559    
6560     + if (pac_blob == NULL) {
6561     + /*
6562     + * This should already be catched at the main
6563     + * gensec layer, but better check twice
6564     + */
6565     + status = NT_STATUS_INTERNAL_ERROR;
6566     + goto done;
6567     + }
6568     +
6569     /*
6570     * Let winbind decode the PAC.
6571     * This will also store the user
6572     * data in the netsamlogon cache.
6573     *
6574     - * We need to do this *before* we
6575     - * call get_user_from_kerberos_info()
6576     - * as that does a user lookup that
6577     - * expects info in the netsamlogon cache.
6578     - *
6579     - * See BUG: https://bugzilla.samba.org/show_bug.cgi?id=11259
6580     + * This used to be a cache prime
6581     + * optimization, but now we delegate
6582     + * all logic to winbindd, as we require
6583     + * winbindd as domain member anyway.
6584     */
6585     params.level = WBC_AUTH_USER_LEVEL_PAC;
6586     params.password.pac.data = pac_blob->data;
6587     params.password.pac.length = pac_blob->length;
6588    
6589     + /* we are contacting the privileged pipe */
6590     become_root();
6591     wbc_err = wbcAuthenticateUserEx(&params, &info, &err);
6592     unbecome_root();
6593     @@ -99,18 +120,90 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
6594     */
6595    
6596     switch (wbc_err) {
6597     - case WBC_ERR_WINBIND_NOT_AVAILABLE:
6598     case WBC_ERR_SUCCESS:
6599     break;
6600     + case WBC_ERR_WINBIND_NOT_AVAILABLE:
6601     + status = NT_STATUS_NO_LOGON_SERVERS;
6602     + DBG_ERR("winbindd not running - "
6603     + "but required as domain member: %s\n",
6604     + nt_errstr(status));
6605     + goto done;
6606     case WBC_ERR_AUTH_ERROR:
6607     status = NT_STATUS(err->nt_status);
6608     wbcFreeMemory(err);
6609     goto done;
6610     + case WBC_ERR_NO_MEMORY:
6611     + status = NT_STATUS_NO_MEMORY;
6612     + goto done;
6613     default:
6614     status = NT_STATUS_LOGON_FAILURE;
6615     goto done;
6616     }
6617    
6618     + status = make_server_info_wbcAuthUserInfo(tmp_ctx,
6619     + info->account_name,
6620     + info->domain_name,
6621     + info, &server_info);
6622     + if (!NT_STATUS_IS_OK(status)) {
6623     + DEBUG(10, ("make_server_info_wbcAuthUserInfo failed: %s\n",
6624     + nt_errstr(status)));
6625     + goto done;
6626     + }
6627     +
6628     + /* We skip doing this step if the caller asked us not to */
6629     + if (!(server_info->guest)) {
6630     + const char *unix_username = server_info->unix_name;
6631     +
6632     + /* We might not be root if we are an RPC call */
6633     + become_root();
6634     + status = smb_pam_accountcheck(unix_username, rhost);
6635     + unbecome_root();
6636     +
6637     + if (!NT_STATUS_IS_OK(status)) {
6638     + DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] "
6639     + "FAILED with error %s\n",
6640     + unix_username, nt_errstr(status)));
6641     + goto done;
6642     + }
6643     +
6644     + DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] "
6645     + "succeeded\n", unix_username));
6646     + }
6647     +
6648     + DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
6649     +
6650     + p = strchr_m(princ_name, '@');
6651     + if (!p) {
6652     + DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
6653     + princ_name));
6654     + status = NT_STATUS_LOGON_FAILURE;
6655     + goto done;
6656     + }
6657     +
6658     + original_user_name = talloc_strndup(tmp_ctx, princ_name, p - princ_name);
6659     + if (original_user_name == NULL) {
6660     + status = NT_STATUS_NO_MEMORY;
6661     + goto done;
6662     + }
6663     +
6664     + status = create_local_token(mem_ctx,
6665     + server_info,
6666     + NULL,
6667     + original_user_name,
6668     + session_info);
6669     + if (!NT_STATUS_IS_OK(status)) {
6670     + DEBUG(10, ("create_local_token failed: %s\n",
6671     + nt_errstr(status)));
6672     + goto done;
6673     + }
6674     +
6675     + goto session_info_ready;
6676     + }
6677     +
6678     + /* This is the standalone legacy code path */
6679     +
6680     + if (pac_blob != NULL) {
6681     +#ifdef HAVE_KRB5
6682     status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL,
6683     NULL, NULL, 0, &logon_info);
6684     #else
6685     @@ -121,22 +214,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
6686     }
6687     }
6688    
6689     - rc = get_remote_hostname(remote_address,
6690     - &rhost,
6691     - tmp_ctx);
6692     - if (rc < 0) {
6693     - status = NT_STATUS_NO_MEMORY;
6694     - goto done;
6695     - }
6696     - if (strequal(rhost, "UNKNOWN")) {
6697     - rhost = tsocket_address_inet_addr_string(remote_address,
6698     - tmp_ctx);
6699     - if (rhost == NULL) {
6700     - status = NT_STATUS_NO_MEMORY;
6701     - goto done;
6702     - }
6703     - }
6704     -
6705     status = get_user_from_kerberos_info(tmp_ctx, rhost,
6706     princ_name, logon_info,
6707     &is_mapped, &is_guest,
6708     @@ -170,6 +247,8 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
6709     goto done;
6710     }
6711    
6712     +session_info_ready:
6713     +
6714     /* setup the string used by %U */
6715     set_current_user_info((*session_info)->unix_info->sanitized_username,
6716     (*session_info)->unix_info->unix_name,
6717     @@ -179,7 +258,9 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
6718     lp_load_with_shares(get_dyn_CONFIGFILE());
6719    
6720     DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
6721     - ntuser, ntdomain, rhost));
6722     + (*session_info)->info->account_name,
6723     + (*session_info)->info->domain_name,
6724     + rhost));
6725    
6726     status = NT_STATUS_OK;
6727    
6728     --
6729     2.39.0
6730    
6731    
6732     From 2d7cd152d95e091447731b3699be9654ca13cffc Mon Sep 17 00:00:00 2001
6733     From: Stefan Metzmacher <metze@samba.org>
6734     Date: Tue, 5 Oct 2021 17:14:01 +0200
6735     Subject: [PATCH 078/142] CVE-2020-25717: selftest: configure 'ktest' env with
6736     winbindd and idmap_autorid
6737    
6738     The 'ktest' environment was/is designed to test kerberos in an active
6739     directory member setup. It was created at a time we wanted to test
6740     smbd/winbindd with kerberos without having the source4 ad dc available.
6741    
6742     This still applies to testing the build with system krb5 libraries
6743     but without relying on a running ad dc.
6744    
6745     As a domain member setup requires a running winbindd, we should test it
6746     that way, in order to reflect a valid setup.
6747    
6748     As a side effect it provides a way to demonstrate that we can accept
6749     smb connections authenticated via kerberos, but no connection to
6750     a domain controller! In order get this working offline, we need an
6751     idmap backend with ID_TYPE_BOTH support, so we use 'autorid', which
6752     should be the default choice.
6753    
6754     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14646
6755     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
6756    
6757     Signed-off-by: Stefan Metzmacher <metze@samba.org>
6758    
6759     [scabrero@samba.org Backported to 4.11 Run winbindd in offline mode
6760     but keep the user name mapping to avoid having to backport fixes
6761     for bso#14539]
6762     ---
6763     selftest/target/Samba3.pm | 2 +-
6764     1 file changed, 1 insertion(+), 1 deletion(-)
6765    
6766     diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
6767     index bbbefea44b7..7034127ef0b 100755
6768     --- a/selftest/target/Samba3.pm
6769     +++ b/selftest/target/Samba3.pm
6770     @@ -1176,7 +1176,7 @@ $ret->{USERNAME} = KTEST/Administrator
6771     # access the share for tests.
6772     chmod 0777, "$prefix/share";
6773    
6774     - if (not $self->check_or_start($ret, "yes", "no", "yes")) {
6775     + if (not $self->check_or_start($ret, "yes", "offline", "yes")) {
6776     return undef;
6777     }
6778     return $ret;
6779     --
6780     2.39.0
6781    
6782    
6783     From 6b4c3693d4ae3c54fd4c890b71829ac582436dee Mon Sep 17 00:00:00 2001
6784     From: Stefan Metzmacher <metze@samba.org>
6785     Date: Tue, 5 Oct 2021 18:12:49 +0200
6786     Subject: [PATCH 079/142] CVE-2020-25717: s3:auth: let
6787     auth3_generate_session_info_pac() reject a PAC in standalone mode
6788    
6789     We should be strict in standalone mode, that we only support MIT realms
6790     without a PAC in order to keep the code sane.
6791    
6792     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
6793    
6794     Signed-off-by: Stefan Metzmacher <metze@samba.org>
6795    
6796     [abartlet@samba.org Backported to Samba 4.12 has conflcits
6797     as the share reload code is in a different spot]
6798     ---
6799     source3/auth/auth_generic.c | 29 +++++++++--------------------
6800     1 file changed, 9 insertions(+), 20 deletions(-)
6801    
6802     diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
6803     index 3099e8f9057..23f746c078e 100644
6804     --- a/source3/auth/auth_generic.c
6805     +++ b/source3/auth/auth_generic.c
6806     @@ -48,8 +48,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
6807     {
6808     enum server_role server_role = lp_server_role();
6809     TALLOC_CTX *tmp_ctx;
6810     - struct PAC_LOGON_INFO *logon_info = NULL;
6811     - struct netr_SamInfo3 *info3_copy = NULL;
6812     bool is_mapped;
6813     bool is_guest;
6814     char *ntuser;
6815     @@ -203,19 +201,20 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
6816     /* This is the standalone legacy code path */
6817    
6818     if (pac_blob != NULL) {
6819     -#ifdef HAVE_KRB5
6820     - status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL,
6821     - NULL, NULL, 0, &logon_info);
6822     -#else
6823     - status = NT_STATUS_ACCESS_DENIED;
6824     -#endif
6825     + /*
6826     + * In standalone mode we don't expect a PAC!
6827     + * we only support MIT realms
6828     + */
6829     + status = NT_STATUS_BAD_TOKEN_TYPE;
6830     + DBG_WARNING("Unexpected PAC for [%s] in standalone mode - %s\n",
6831     + princ_name, nt_errstr(status));
6832     if (!NT_STATUS_IS_OK(status)) {
6833     goto done;
6834     }
6835     }
6836    
6837     status = get_user_from_kerberos_info(tmp_ctx, rhost,
6838     - princ_name, logon_info,
6839     + princ_name, NULL,
6840     &is_mapped, &is_guest,
6841     &ntuser, &ntdomain,
6842     &username, &pw);
6843     @@ -226,19 +225,9 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
6844     goto done;
6845     }
6846    
6847     - /* Get the info3 from the PAC data if we have it */
6848     - if (logon_info) {
6849     - status = create_info3_from_pac_logon_info(tmp_ctx,
6850     - logon_info,
6851     - &info3_copy);
6852     - if (!NT_STATUS_IS_OK(status)) {
6853     - goto done;
6854     - }
6855     - }
6856     -
6857     status = make_session_info_krb5(mem_ctx,
6858     ntuser, ntdomain, username, pw,
6859     - info3_copy, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
6860     + NULL, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
6861     session_info);
6862     if (!NT_STATUS_IS_OK(status)) {
6863     DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
6864     --
6865     2.39.0
6866    
6867    
6868     From 6f6a1fedb97d119a7f15831f7295b1774e806ba8 Mon Sep 17 00:00:00 2001
6869     From: Stefan Metzmacher <metze@samba.org>
6870     Date: Fri, 8 Oct 2021 17:59:59 +0200
6871     Subject: [PATCH 080/142] CVE-2020-25717: s3:auth: simplify
6872     get_user_from_kerberos_info() by removing the unused logon_info argument
6873    
6874     This code is only every called in standalone mode on a MIT realm,
6875     it means we never have a PAC and we also don't have winbindd arround.
6876    
6877     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
6878    
6879     Signed-off-by: Stefan Metzmacher <metze@samba.org>
6880     ---
6881     source3/auth/auth_generic.c | 2 +-
6882     source3/auth/proto.h | 1 -
6883     source3/auth/user_krb5.c | 57 +++++++------------------------------
6884     3 files changed, 11 insertions(+), 49 deletions(-)
6885    
6886     diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
6887     index 23f746c078e..a11aae713f5 100644
6888     --- a/source3/auth/auth_generic.c
6889     +++ b/source3/auth/auth_generic.c
6890     @@ -214,7 +214,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
6891     }
6892    
6893     status = get_user_from_kerberos_info(tmp_ctx, rhost,
6894     - princ_name, NULL,
6895     + princ_name,
6896     &is_mapped, &is_guest,
6897     &ntuser, &ntdomain,
6898     &username, &pw);
6899     diff --git a/source3/auth/proto.h b/source3/auth/proto.h
6900     index fcfd1f36ca2..1ed3f4a2f77 100644
6901     --- a/source3/auth/proto.h
6902     +++ b/source3/auth/proto.h
6903     @@ -416,7 +416,6 @@ struct PAC_LOGON_INFO;
6904     NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
6905     const char *cli_name,
6906     const char *princ_name,
6907     - struct PAC_LOGON_INFO *logon_info,
6908     bool *is_mapped,
6909     bool *mapped_to_guest,
6910     char **ntuser,
6911     diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c
6912     index 074e8c7eb71..7b69ca6c222 100644
6913     --- a/source3/auth/user_krb5.c
6914     +++ b/source3/auth/user_krb5.c
6915     @@ -31,7 +31,6 @@
6916     NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
6917     const char *cli_name,
6918     const char *princ_name,
6919     - struct PAC_LOGON_INFO *logon_info,
6920     bool *is_mapped,
6921     bool *mapped_to_guest,
6922     char **ntuser,
6923     @@ -40,8 +39,8 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
6924     struct passwd **_pw)
6925     {
6926     NTSTATUS status;
6927     - char *domain = NULL;
6928     - char *realm = NULL;
6929     + const char *domain = NULL;
6930     + const char *realm = NULL;
6931     char *user = NULL;
6932     char *p;
6933     char *fuser = NULL;
6934     @@ -62,55 +61,16 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
6935     return NT_STATUS_NO_MEMORY;
6936     }
6937    
6938     - realm = talloc_strdup(talloc_tos(), p + 1);
6939     - if (!realm) {
6940     - return NT_STATUS_NO_MEMORY;
6941     - }
6942     + realm = p + 1;
6943    
6944     if (!strequal(realm, lp_realm())) {
6945     DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm));
6946     if (!lp_allow_trusted_domains()) {
6947     return NT_STATUS_LOGON_FAILURE;
6948     }
6949     - }
6950     -
6951     - if (logon_info && logon_info->info3.base.logon_domain.string) {
6952     - domain = talloc_strdup(mem_ctx,
6953     - logon_info->info3.base.logon_domain.string);
6954     - if (!domain) {
6955     - return NT_STATUS_NO_MEMORY;
6956     - }
6957     - DEBUG(10, ("Domain is [%s] (using PAC)\n", domain));
6958     + domain = realm;
6959     } else {
6960     -
6961     - /* If we have winbind running, we can (and must) shorten the
6962     - username by using the short netbios name. Otherwise we will
6963     - have inconsistent user names. With Kerberos, we get the
6964     - fully qualified realm, with ntlmssp we get the short
6965     - name. And even w2k3 does use ntlmssp if you for example
6966     - connect to an ip address. */
6967     -
6968     - wbcErr wbc_status;
6969     - struct wbcDomainInfo *info = NULL;
6970     -
6971     - DEBUG(10, ("Mapping [%s] to short name using winbindd\n",
6972     - realm));
6973     -
6974     - wbc_status = wbcDomainInfo(realm, &info);
6975     -
6976     - if (WBC_ERROR_IS_OK(wbc_status)) {
6977     - domain = talloc_strdup(mem_ctx,
6978     - info->short_name);
6979     - wbcFreeMemory(info);
6980     - } else {
6981     - DEBUG(3, ("Could not find short name: %s\n",
6982     - wbcErrorString(wbc_status)));
6983     - domain = talloc_strdup(mem_ctx, realm);
6984     - }
6985     - if (!domain) {
6986     - return NT_STATUS_NO_MEMORY;
6987     - }
6988     - DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain));
6989     + domain = lp_workgroup();
6990     }
6991    
6992     fuser = talloc_asprintf(mem_ctx,
6993     @@ -175,7 +135,11 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
6994     return NT_STATUS_NO_MEMORY;
6995     }
6996     *ntuser = user;
6997     - *ntdomain = domain;
6998     + *ntdomain = talloc_strdup(mem_ctx, domain);
6999     + if (*ntdomain == NULL) {
7000     + return NT_STATUS_NO_MEMORY;
7001     + }
7002     +
7003     *_pw = pw;
7004    
7005     return NT_STATUS_OK;
7006     @@ -282,7 +246,6 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
7007     NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
7008     const char *cli_name,
7009     const char *princ_name,
7010     - struct PAC_LOGON_INFO *logon_info,
7011     bool *is_mapped,
7012     bool *mapped_to_guest,
7013     char **ntuser,
7014     --
7015     2.39.0
7016    
7017    
7018     From 8fd8d952c4396484f822c51f71667baaf49402b4 Mon Sep 17 00:00:00 2001
7019     From: Stefan Metzmacher <metze@samba.org>
7020     Date: Fri, 8 Oct 2021 18:03:04 +0200
7021     Subject: [PATCH 081/142] CVE-2020-25717: s3:auth: simplify
7022     make_session_info_krb5() by removing unused arguments
7023    
7024     This is only ever be called in standalone mode with an MIT realm,
7025     so we don't have a PAC/info3 structure.
7026    
7027     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
7028    
7029     Signed-off-by: Stefan Metzmacher <metze@samba.org>
7030     ---
7031     source3/auth/auth_generic.c | 2 +-
7032     source3/auth/proto.h | 2 --
7033     source3/auth/user_krb5.c | 20 +-------------------
7034     3 files changed, 2 insertions(+), 22 deletions(-)
7035    
7036     diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
7037     index a11aae713f5..4dd1af784bf 100644
7038     --- a/source3/auth/auth_generic.c
7039     +++ b/source3/auth/auth_generic.c
7040     @@ -227,7 +227,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
7041    
7042     status = make_session_info_krb5(mem_ctx,
7043     ntuser, ntdomain, username, pw,
7044     - NULL, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
7045     + is_guest, is_mapped,
7046     session_info);
7047     if (!NT_STATUS_IS_OK(status)) {
7048     DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
7049     diff --git a/source3/auth/proto.h b/source3/auth/proto.h
7050     index 1ed3f4a2f77..c00ac70fd3f 100644
7051     --- a/source3/auth/proto.h
7052     +++ b/source3/auth/proto.h
7053     @@ -427,9 +427,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
7054     char *ntdomain,
7055     char *username,
7056     struct passwd *pw,
7057     - const struct netr_SamInfo3 *info3,
7058     bool mapped_to_guest, bool username_was_mapped,
7059     - DATA_BLOB *session_key,
7060     struct auth_session_info **session_info);
7061    
7062     /* The following definitions come from auth/auth_samba4.c */
7063     diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c
7064     index 7b69ca6c222..b8f37cbeee0 100644
7065     --- a/source3/auth/user_krb5.c
7066     +++ b/source3/auth/user_krb5.c
7067     @@ -150,9 +150,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
7068     char *ntdomain,
7069     char *username,
7070     struct passwd *pw,
7071     - const struct netr_SamInfo3 *info3,
7072     bool mapped_to_guest, bool username_was_mapped,
7073     - DATA_BLOB *session_key,
7074     struct auth_session_info **session_info)
7075     {
7076     NTSTATUS status;
7077     @@ -166,20 +164,6 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
7078     return status;
7079     }
7080    
7081     - } else if (info3) {
7082     - /* pass the unmapped username here since map_username()
7083     - will be called again in make_server_info_info3() */
7084     -
7085     - status = make_server_info_info3(mem_ctx,
7086     - ntuser, ntdomain,
7087     - &server_info,
7088     - info3);
7089     - if (!NT_STATUS_IS_OK(status)) {
7090     - DEBUG(1, ("make_server_info_info3 failed: %s!\n",
7091     - nt_errstr(status)));
7092     - return status;
7093     - }
7094     -
7095     } else {
7096     /*
7097     * We didn't get a PAC, we have to make up the user
7098     @@ -231,7 +215,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
7099    
7100     server_info->nss_token |= username_was_mapped;
7101    
7102     - status = create_local_token(mem_ctx, server_info, session_key, ntuser, session_info);
7103     + status = create_local_token(mem_ctx, server_info, NULL, ntuser, session_info);
7104     talloc_free(server_info);
7105     if (!NT_STATUS_IS_OK(status)) {
7106     DEBUG(10,("failed to create local token: %s\n",
7107     @@ -261,9 +245,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
7108     char *ntdomain,
7109     char *username,
7110     struct passwd *pw,
7111     - const struct netr_SamInfo3 *info3,
7112     bool mapped_to_guest, bool username_was_mapped,
7113     - DATA_BLOB *session_key,
7114     struct auth_session_info **session_info)
7115     {
7116     return NT_STATUS_NOT_IMPLEMENTED;
7117     --
7118     2.39.0
7119    
7120    
7121     From bf0696ec4f3080ebd0b61cac5a05a9284ccabda8 Mon Sep 17 00:00:00 2001
7122     From: Joseph Sutton <josephsutton@catalyst.net.nz>
7123     Date: Wed, 1 Sep 2021 15:39:19 +1200
7124     Subject: [PATCH 082/142] krb5pac.idl: Add ticket checksum PAC buffer type
7125    
7126     Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
7127     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
7128     Reviewed-by: Isaac Boukris <iboukris@samba.org>
7129     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881
7130     (cherry picked from commit ff2f38fae79220e16765e17671972f9a55eb7cce)
7131     ---
7132     librpc/idl/krb5pac.idl | 4 +++-
7133     1 file changed, 3 insertions(+), 1 deletion(-)
7134    
7135     diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl
7136     index f27e7243ee4..711b7f94b6c 100644
7137     --- a/librpc/idl/krb5pac.idl
7138     +++ b/librpc/idl/krb5pac.idl
7139     @@ -112,7 +112,8 @@ interface krb5pac
7140     PAC_TYPE_KDC_CHECKSUM = 7,
7141     PAC_TYPE_LOGON_NAME = 10,
7142     PAC_TYPE_CONSTRAINED_DELEGATION = 11,
7143     - PAC_TYPE_UPN_DNS_INFO = 12
7144     + PAC_TYPE_UPN_DNS_INFO = 12,
7145     + PAC_TYPE_TICKET_CHECKSUM = 16
7146     } PAC_TYPE;
7147    
7148     typedef struct {
7149     @@ -128,6 +129,7 @@ interface krb5pac
7150     [case(PAC_TYPE_CONSTRAINED_DELEGATION)][subcontext(0xFFFFFC01)]
7151     PAC_CONSTRAINED_DELEGATION_CTR constrained_delegation;
7152     [case(PAC_TYPE_UPN_DNS_INFO)] PAC_UPN_DNS_INFO upn_dns_info;
7153     + [case(PAC_TYPE_TICKET_CHECKSUM)] PAC_SIGNATURE_DATA ticket_checksum;
7154     /* when new PAC info types are added they are supposed to be done
7155     in such a way that they are backwards compatible with existing
7156     servers. This makes it safe to just use a [default] for
7157     --
7158     2.39.0
7159    
7160    
7161     From 7a9f618fdbf32872594f47dd4bc83ce087af4bbc Mon Sep 17 00:00:00 2001
7162     From: Joseph Sutton <josephsutton@catalyst.net.nz>
7163     Date: Wed, 1 Sep 2021 15:40:59 +1200
7164     Subject: [PATCH 083/142] security.idl: Add well-known SIDs for FAST
7165    
7166     Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
7167     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
7168     Reviewed-by: Isaac Boukris <iboukris@samba.org>
7169     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881
7170     (cherry picked from commit 0092b4a3ed58b2c256d4dd9117cce927a3edde12)
7171     ---
7172     librpc/idl/security.idl | 3 +++
7173     1 file changed, 3 insertions(+)
7174    
7175     diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl
7176     index 5930f448955..e6065a35691 100644
7177     --- a/librpc/idl/security.idl
7178     +++ b/librpc/idl/security.idl
7179     @@ -292,6 +292,9 @@ interface security
7180     const string SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = "S-1-18-1";
7181     const string SID_SERVICE_ASSERTED_IDENTITY = "S-1-18-2";
7182    
7183     + const string SID_COMPOUNDED_AUTHENTICATION = "S-1-5-21-0-0-0-496";
7184     + const string SID_CLAIMS_VALID = "S-1-5-21-0-0-0-497";
7185     +
7186     /*
7187     * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
7188     */
7189     --
7190     2.39.0
7191    
7192    
7193     From 7713b56a8a8b26e05aa9a517348e3f95da1144a7 Mon Sep 17 00:00:00 2001
7194     From: Joseph Sutton <josephsutton@catalyst.net.nz>
7195     Date: Wed, 29 Sep 2021 16:15:26 +1300
7196     Subject: [PATCH 084/142] krb5pac.idl: Add missing buffer type values
7197    
7198     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642
7199    
7200     Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
7201     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
7202     Backported-by: Andreas Schneider <asn@samba.org>
7203     ---
7204     librpc/idl/krb5pac.idl | 3 +++
7205     1 file changed, 3 insertions(+)
7206    
7207     diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl
7208     index 711b7f94b6c..141894ec5f1 100644
7209     --- a/librpc/idl/krb5pac.idl
7210     +++ b/librpc/idl/krb5pac.idl
7211     @@ -113,6 +113,9 @@ interface krb5pac
7212     PAC_TYPE_LOGON_NAME = 10,
7213     PAC_TYPE_CONSTRAINED_DELEGATION = 11,
7214     PAC_TYPE_UPN_DNS_INFO = 12,
7215     + PAC_TYPE_CLIENT_CLAIMS_INFO = 13,
7216     + PAC_TYPE_DEVICE_INFO = 14,
7217     + PAC_TYPE_DEVICE_CLAIMS_INFO = 15,
7218     PAC_TYPE_TICKET_CHECKSUM = 16
7219     } PAC_TYPE;
7220    
7221     --
7222     2.39.0
7223    
7224    
7225     From a85bf1d86d6e081c781cc93a8e7aaa049c3818d0 Mon Sep 17 00:00:00 2001
7226     From: Joseph Sutton <josephsutton@catalyst.net.nz>
7227     Date: Tue, 26 Oct 2021 20:33:38 +1300
7228     Subject: [PATCH 085/142] CVE-2020-25719 krb5pac.idl: Add PAC_ATTRIBUTES_INFO
7229     PAC buffer type
7230    
7231     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561
7232    
7233     Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
7234     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
7235     ---
7236     librpc/idl/krb5pac.idl | 14 +++++++++++++-
7237     1 file changed, 13 insertions(+), 1 deletion(-)
7238    
7239     diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl
7240     index 141894ec5f1..4bfec2de5e6 100644
7241     --- a/librpc/idl/krb5pac.idl
7242     +++ b/librpc/idl/krb5pac.idl
7243     @@ -97,6 +97,16 @@ interface krb5pac
7244     PAC_UPN_DNS_FLAGS flags;
7245     } PAC_UPN_DNS_INFO;
7246    
7247     + typedef [bitmap32bit] bitmap {
7248     + PAC_ATTRIBUTE_FLAG_PAC_WAS_REQUESTED = 0x00000001,
7249     + PAC_ATTRIBUTE_FLAG_PAC_WAS_GIVEN_IMPLICITLY = 0x00000002
7250     + } PAC_ATTRIBUTE_INFO_FLAGS;
7251     +
7252     + typedef struct {
7253     + uint32 flags_length; /* length in bits */
7254     + PAC_ATTRIBUTE_INFO_FLAGS flags;
7255     + } PAC_ATTRIBUTES_INFO;
7256     +
7257     typedef [public] struct {
7258     PAC_LOGON_INFO *info;
7259     } PAC_LOGON_INFO_CTR;
7260     @@ -116,7 +126,8 @@ interface krb5pac
7261     PAC_TYPE_CLIENT_CLAIMS_INFO = 13,
7262     PAC_TYPE_DEVICE_INFO = 14,
7263     PAC_TYPE_DEVICE_CLAIMS_INFO = 15,
7264     - PAC_TYPE_TICKET_CHECKSUM = 16
7265     + PAC_TYPE_TICKET_CHECKSUM = 16,
7266     + PAC_TYPE_ATTRIBUTES_INFO = 17
7267     } PAC_TYPE;
7268    
7269     typedef struct {
7270     @@ -133,6 +144,7 @@ interface krb5pac
7271     PAC_CONSTRAINED_DELEGATION_CTR constrained_delegation;
7272     [case(PAC_TYPE_UPN_DNS_INFO)] PAC_UPN_DNS_INFO upn_dns_info;
7273     [case(PAC_TYPE_TICKET_CHECKSUM)] PAC_SIGNATURE_DATA ticket_checksum;
7274     + [case(PAC_TYPE_ATTRIBUTES_INFO)] PAC_ATTRIBUTES_INFO attributes_info;
7275     /* when new PAC info types are added they are supposed to be done
7276     in such a way that they are backwards compatible with existing
7277     servers. This makes it safe to just use a [default] for
7278     --
7279     2.39.0
7280    
7281    
7282     From 57e4c415ecae66ee984a30eb66d5d248e0e8587d Mon Sep 17 00:00:00 2001
7283     From: Joseph Sutton <josephsutton@catalyst.net.nz>
7284     Date: Tue, 26 Oct 2021 20:33:49 +1300
7285     Subject: [PATCH 086/142] CVE-2020-25719 krb5pac.idl: Add PAC_REQUESTER_SID PAC
7286     buffer type
7287    
7288     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561
7289    
7290     Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
7291     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
7292     ---
7293     librpc/idl/krb5pac.idl | 8 +++++++-
7294     1 file changed, 7 insertions(+), 1 deletion(-)
7295    
7296     diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl
7297     index 4bfec2de5e6..f750359a069 100644
7298     --- a/librpc/idl/krb5pac.idl
7299     +++ b/librpc/idl/krb5pac.idl
7300     @@ -107,6 +107,10 @@ interface krb5pac
7301     PAC_ATTRIBUTE_INFO_FLAGS flags;
7302     } PAC_ATTRIBUTES_INFO;
7303    
7304     + typedef struct {
7305     + dom_sid sid;
7306     + } PAC_REQUESTER_SID;
7307     +
7308     typedef [public] struct {
7309     PAC_LOGON_INFO *info;
7310     } PAC_LOGON_INFO_CTR;
7311     @@ -127,7 +131,8 @@ interface krb5pac
7312     PAC_TYPE_DEVICE_INFO = 14,
7313     PAC_TYPE_DEVICE_CLAIMS_INFO = 15,
7314     PAC_TYPE_TICKET_CHECKSUM = 16,
7315     - PAC_TYPE_ATTRIBUTES_INFO = 17
7316     + PAC_TYPE_ATTRIBUTES_INFO = 17,
7317     + PAC_TYPE_REQUESTER_SID = 18
7318     } PAC_TYPE;
7319    
7320     typedef struct {
7321     @@ -145,6 +150,7 @@ interface krb5pac
7322     [case(PAC_TYPE_UPN_DNS_INFO)] PAC_UPN_DNS_INFO upn_dns_info;
7323     [case(PAC_TYPE_TICKET_CHECKSUM)] PAC_SIGNATURE_DATA ticket_checksum;
7324     [case(PAC_TYPE_ATTRIBUTES_INFO)] PAC_ATTRIBUTES_INFO attributes_info;
7325     + [case(PAC_TYPE_REQUESTER_SID)] PAC_REQUESTER_SID requester_sid;
7326     /* when new PAC info types are added they are supposed to be done
7327     in such a way that they are backwards compatible with existing
7328     servers. This makes it safe to just use a [default] for
7329     --
7330     2.39.0
7331    
7332    
7333     From 7782a97868ead29b6e87fa98dcef8dbc2706b67d Mon Sep 17 00:00:00 2001
7334     From: Andrew Bartlett <abartlet@samba.org>
7335     Date: Mon, 27 Sep 2021 11:20:19 +1300
7336     Subject: [PATCH 087/142] CVE-2020-25721 krb5pac: Add new buffers for
7337     samAccountName and objectSID
7338    
7339     These appear when PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID is set.
7340    
7341     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14835
7342    
7343     Signed-off-by: Andrew Bartlett <abartlet@samba.org>
7344     Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
7345     ---
7346     librpc/idl/krb5pac.idl | 18 ++++++++++++++++--
7347     librpc/ndr/ndr_krb5pac.c | 4 ++--
7348     2 files changed, 18 insertions(+), 4 deletions(-)
7349    
7350     diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl
7351     index f750359a069..94b9160d6eb 100644
7352     --- a/librpc/idl/krb5pac.idl
7353     +++ b/librpc/idl/krb5pac.idl
7354     @@ -86,15 +86,29 @@ interface krb5pac
7355     } PAC_CONSTRAINED_DELEGATION;
7356    
7357     typedef [bitmap32bit] bitmap {
7358     - PAC_UPN_DNS_FLAG_CONSTRUCTED = 0x00000001
7359     + PAC_UPN_DNS_FLAG_CONSTRUCTED = 0x00000001,
7360     + PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID = 0x00000002
7361     } PAC_UPN_DNS_FLAGS;
7362    
7363     + typedef struct {
7364     + [value(2*strlen_m(samaccountname))] uint16 samaccountname_size;
7365     + [relative_short,subcontext(0),subcontext_size(samaccountname_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *samaccountname;
7366     + [value(ndr_size_dom_sid(objectsid, ndr->flags))] uint16 objectsid_size;
7367     + [relative_short,subcontext(0),subcontext_size(objectsid_size)] dom_sid *objectsid;
7368     + } PAC_UPN_DNS_INFO_SAM_NAME_AND_SID;
7369     +
7370     + typedef [nodiscriminant] union {
7371     + [case(PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID)] PAC_UPN_DNS_INFO_SAM_NAME_AND_SID sam_name_and_sid;
7372     + [default];
7373     + } PAC_UPN_DNS_INFO_EX;
7374     +
7375     typedef struct {
7376     [value(2*strlen_m(upn_name))] uint16 upn_name_size;
7377     [relative_short,subcontext(0),subcontext_size(upn_name_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *upn_name;
7378     [value(2*strlen_m(dns_domain_name))] uint16 dns_domain_name_size;
7379     [relative_short,subcontext(0),subcontext_size(dns_domain_name_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *dns_domain_name;
7380     PAC_UPN_DNS_FLAGS flags;
7381     + [switch_is(flags & PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID)] PAC_UPN_DNS_INFO_EX ex;
7382     } PAC_UPN_DNS_INFO;
7383    
7384     typedef [bitmap32bit] bitmap {
7385     @@ -160,7 +174,7 @@ interface krb5pac
7386    
7387     typedef [public,nopush,nopull] struct {
7388     PAC_TYPE type;
7389     - [value(_ndr_size_PAC_INFO(info, type, 0))] uint32 _ndr_size;
7390     + [value(_ndr_size_PAC_INFO(info, type, LIBNDR_FLAG_ALIGN8))] uint32 _ndr_size;
7391     /*
7392     * We need to have two subcontexts to get the padding right,
7393     * the outer subcontext uses NDR_ROUND(_ndr_size, 8), while
7394     diff --git a/librpc/ndr/ndr_krb5pac.c b/librpc/ndr/ndr_krb5pac.c
7395     index a9ae2c4a789..57b28df9e52 100644
7396     --- a/librpc/ndr/ndr_krb5pac.c
7397     +++ b/librpc/ndr/ndr_krb5pac.c
7398     @@ -41,7 +41,7 @@ enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const
7399     if (ndr_flags & NDR_SCALARS) {
7400     NDR_CHECK(ndr_push_align(ndr, 4));
7401     NDR_CHECK(ndr_push_PAC_TYPE(ndr, NDR_SCALARS, r->type));
7402     - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size_PAC_INFO(r->info,r->type,0)));
7403     + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size_PAC_INFO(r->info,r->type,LIBNDR_FLAG_ALIGN8)));
7404     {
7405     uint32_t _flags_save_PAC_INFO = ndr->flags;
7406     ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8);
7407     @@ -59,7 +59,7 @@ enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const
7408     {
7409     struct ndr_push *_ndr_info_pad;
7410     struct ndr_push *_ndr_info;
7411     - size_t _ndr_size = _ndr_size_PAC_INFO(r->info, r->type, 0);
7412     + size_t _ndr_size = _ndr_size_PAC_INFO(r->info, r->type, LIBNDR_FLAG_ALIGN8);
7413     NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info_pad, 0, NDR_ROUND(_ndr_size, 8)));
7414     NDR_CHECK(ndr_push_subcontext_start(_ndr_info_pad, &_ndr_info, 0, _ndr_size));
7415     NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->info, r->type));
7416     --
7417     2.39.0
7418    
7419    
7420     From 44e8dd1a9a3c02dee31497fe20411758fce1acf9 Mon Sep 17 00:00:00 2001
7421     From: Alexander Bokovoy <ab@samba.org>
7422     Date: Fri, 12 Nov 2021 19:06:01 +0200
7423     Subject: [PATCH 088/142] IPA DC: add missing checks
7424    
7425     When introducing FreeIPA support, two places were forgotten:
7426    
7427     - schannel gensec module needs to be aware of IPA DC
7428     - _lsa_QueryInfoPolicy should treat IPA DC as PDC
7429    
7430     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14903
7431    
7432     Signed-off-by: Alexander Bokovoy <ab@samba.org>
7433     Reviewed-by: Guenther Deschner <gd@samba.org>
7434    
7435     Autobuild-User(master): Alexander Bokovoy <ab@samba.org>
7436     Autobuild-Date(master): Sat Nov 13 07:01:26 UTC 2021 on sn-devel-184
7437    
7438     (cherry picked from commit c69b66f649c1d47a7367f7efe25b8df32369a3a5)
7439     ---
7440     auth/gensec/schannel.c | 1 +
7441     source3/rpc_server/lsa/srv_lsa_nt.c | 1 +
7442     2 files changed, 2 insertions(+)
7443    
7444     diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c
7445     index 71e9afdf48e..f23c1effb23 100644
7446     --- a/auth/gensec/schannel.c
7447     +++ b/auth/gensec/schannel.c
7448     @@ -740,6 +740,7 @@ static NTSTATUS schannel_server_start(struct gensec_security *gensec_security)
7449     case ROLE_DOMAIN_BDC:
7450     case ROLE_DOMAIN_PDC:
7451     case ROLE_ACTIVE_DIRECTORY_DC:
7452     + case ROLE_IPA_DC:
7453     return NT_STATUS_OK;
7454     default:
7455     return NT_STATUS_NOT_IMPLEMENTED;
7456     diff --git a/source3/rpc_server/lsa/srv_lsa_nt.c b/source3/rpc_server/lsa/srv_lsa_nt.c
7457     index 57bfc596005..3f77856457e 100644
7458     --- a/source3/rpc_server/lsa/srv_lsa_nt.c
7459     +++ b/source3/rpc_server/lsa/srv_lsa_nt.c
7460     @@ -672,6 +672,7 @@ NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
7461     switch (lp_server_role()) {
7462     case ROLE_DOMAIN_PDC:
7463     case ROLE_DOMAIN_BDC:
7464     + case ROLE_IPA_DC:
7465     name = get_global_sam_name();
7466     sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
7467     if (!sid) {
7468     --
7469     2.39.0
7470    
7471    
7472     From c64bcd68614871cdddc9fe37c860729f490b4da1 Mon Sep 17 00:00:00 2001
7473     From: Stefan Metzmacher <metze@samba.org>
7474     Date: Fri, 12 Nov 2021 15:27:58 +0100
7475     Subject: [PATCH 089/142] CVE-2020-25717: idmap_nss: verify that the name of
7476     the sid belongs to the configured domain
7477    
7478     We already check the sid belongs to the domain, but checking the name
7479     too feels better and make it easier to understand.
7480    
7481     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901
7482    
7483     Signed-off-by: Stefan Metzmacher <metze@samba.org>
7484     Reviewed-by: Ralph Boehme <slow@samba.org>
7485    
7486     [abartlet@samba.org backorted from commit bfd093648b4af51d104096c0cb3535e8706671e5
7487     as header libcli/security/dom_sid.h was not present for struct dom_sid_buf]
7488    
7489     [abartlet@samba.org fix CVE marker]
7490     ---
7491     source3/winbindd/idmap_nss.c | 27 ++++++++++++++++++++++-----
7492     1 file changed, 22 insertions(+), 5 deletions(-)
7493    
7494     diff --git a/source3/winbindd/idmap_nss.c b/source3/winbindd/idmap_nss.c
7495     index 3fe98cbc729..243b67ccafd 100644
7496     --- a/source3/winbindd/idmap_nss.c
7497     +++ b/source3/winbindd/idmap_nss.c
7498     @@ -25,6 +25,7 @@
7499     #include "nsswitch/winbind_client.h"
7500     #include "idmap.h"
7501     #include "lib/winbind_util.h"
7502     +#include "libcli/security/dom_sid.h"
7503    
7504     #undef DBGC_CLASS
7505     #define DBGC_CLASS DBGC_IDMAP
7506     @@ -135,18 +136,21 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
7507     for (i = 0; ids[i]; i++) {
7508     struct group *gr;
7509     enum lsa_SidType type;
7510     - const char *p = NULL;
7511     + const char *_domain = NULL;
7512     + const char *_name = NULL;
7513     + char *domain = NULL;
7514     char *name = NULL;
7515     bool ret;
7516    
7517     /* by default calls to winbindd are disabled
7518     the following call will not recurse so this is safe */
7519     (void)winbind_on();
7520     - ret = winbind_lookup_sid(talloc_tos(), ids[i]->sid, NULL,
7521     - &p, &type);
7522     + ret = winbind_lookup_sid(talloc_tos(),
7523     + ids[i]->sid,
7524     + &_domain,
7525     + &_name,
7526     + &type);
7527     (void)winbind_off();
7528     - name = discard_const_p(char, p);
7529     -
7530     if (!ret) {
7531     /* TODO: how do we know if the name is really not mapped,
7532     * or something just failed ? */
7533     @@ -154,6 +158,18 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
7534     continue;
7535     }
7536    
7537     + domain = discard_const_p(char, _domain);
7538     + name = discard_const_p(char, _name);
7539     +
7540     + if (!strequal(domain, dom->name)) {
7541     + struct dom_sid_buf buf;
7542     + DBG_ERR("DOMAIN[%s] ignoring SID[%s] belongs to %s [%s\\%s]\n",
7543     + dom->name, dom_sid_str_buf(ids[i]->sid, &buf),
7544     + sid_type_lookup(type), domain, name);
7545     + ids[i]->status = ID_UNMAPPED;
7546     + continue;
7547     + }
7548     +
7549     switch (type) {
7550     case SID_NAME_USER: {
7551     struct passwd *pw;
7552     @@ -186,6 +202,7 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
7553     ids[i]->status = ID_UNKNOWN;
7554     break;
7555     }
7556     + TALLOC_FREE(domain);
7557     TALLOC_FREE(name);
7558     }
7559     return NT_STATUS_OK;
7560     --
7561     2.39.0
7562    
7563    
7564     From c7d277ef2c902482eca00fc981bf340a088fbfe1 Mon Sep 17 00:00:00 2001
7565     From: Joseph Sutton <josephsutton@catalyst.net.nz>
7566     Date: Fri, 12 Nov 2021 20:53:30 +1300
7567     Subject: [PATCH 090/142] CVE-2020-25717: nsswitch/nsstest.c: Lower 'non
7568     existent uid' to make room for new accounts
7569    
7570     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901
7571    
7572     Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
7573     Reviewed-by: Stefan Metzmacher <metze@samba.org>
7574     Reviewed-by: Ralph Boehme <slow@samba.org>
7575     (cherry picked from commit fdbee5e074ebd76d659613b8b7114d70f938c38a)
7576     ---
7577     nsswitch/nsstest.c | 2 +-
7578     1 file changed, 1 insertion(+), 1 deletion(-)
7579    
7580     diff --git a/nsswitch/nsstest.c b/nsswitch/nsstest.c
7581     index 46f96795f39..8ce7493d1b6 100644
7582     --- a/nsswitch/nsstest.c
7583     +++ b/nsswitch/nsstest.c
7584     @@ -460,7 +460,7 @@ static void nss_test_errors(void)
7585     printf("ERROR Non existent user gave error %d\n", last_error);
7586     }
7587    
7588     - pwd = getpwuid(0xFFF0);
7589     + pwd = getpwuid(0xFF00);
7590     if (pwd || last_error != NSS_STATUS_NOTFOUND) {
7591     total_errors++;
7592     printf("ERROR Non existent uid gave error %d\n", last_error);
7593     --
7594     2.39.0
7595    
7596    
7597     From 0ff9bba35a043267a2781c294f5832378cd6da54 Mon Sep 17 00:00:00 2001
7598     From: Andrew Bartlett <abartlet@samba.org>
7599     Date: Fri, 12 Nov 2021 16:10:31 +1300
7600     Subject: [PATCH 091/142] CVE-2020-25717: s3:auth: Fallback to a SID/UID based
7601     mapping if the named based lookup fails
7602     MIME-Version: 1.0
7603     Content-Type: text/plain; charset=UTF-8
7604     Content-Transfer-Encoding: 8bit
7605    
7606     Before the CVE-2020-25717 fixes we had a fallback from
7607     getpwnam('DOMAIN\user') to getpwnam('user') which was very dangerous and
7608     unpredictable.
7609    
7610     Now we do the fallback based on sid_to_uid() followed by
7611     getpwuid() on the returned uid.
7612    
7613     This obsoletes 'username map [script]' based workaround adviced
7614     for CVE-2020-25717, when nss_winbindd is not used or
7615     idmap_nss is actually used.
7616    
7617     In future we may decide to prefer or only do the SID/UID based
7618     lookup, but for now we want to keep this unchanged as much as possible.
7619    
7620     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901
7621    
7622     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
7623    
7624     Signed-off-by: Andrew Bartlett <abartlet@samba.org>
7625     Signed-off-by: Stefan Metzmacher <metze@samba.org>
7626    
7627     [metze@samba.org moved the new logic into the fallback codepath only
7628     in order to avoid behavior changes as much as possible]
7629     Reviewed-by: Ralph Boehme <slow@samba.org>
7630    
7631     Autobuild-User(master): Ralph Böhme <slow@samba.org>
7632     Autobuild-Date(master): Mon Nov 15 19:01:56 UTC 2021 on sn-devel-184
7633    
7634     [abartlet@samba.org backported from commit 0a546be05295a7e4a552f9f4f0c74aeb2e9a0d6e
7635     as usage.py is not present in Samba 4.10]
7636     ---
7637     source3/auth/auth_util.c | 34 +++++++++++++++++++++++++++++++++-
7638     1 file changed, 33 insertions(+), 1 deletion(-)
7639    
7640     diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
7641     index c0e5cfd7fa8..b463059f259 100644
7642     --- a/source3/auth/auth_util.c
7643     +++ b/source3/auth/auth_util.c
7644     @@ -1837,7 +1837,9 @@ const struct auth_session_info *get_session_info_system(void)
7645     ***************************************************************************/
7646    
7647     static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
7648     - const char *username, char **found_username,
7649     + const char *username,
7650     + const struct dom_sid *sid,
7651     + char **found_username,
7652     struct passwd **pwd,
7653     bool *username_was_mapped)
7654     {
7655     @@ -1872,6 +1874,31 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
7656     }
7657    
7658     passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
7659     + if (!passwd && !*username_was_mapped) {
7660     + struct dom_sid_buf buf;
7661     + uid_t uid;
7662     + bool ok;
7663     +
7664     + DBG_DEBUG("Failed to find authenticated user %s via "
7665     + "getpwnam(), fallback to sid_to_uid(%s).\n",
7666     + dom_user, dom_sid_str_buf(sid, &buf));
7667     +
7668     + ok = sid_to_uid(sid, &uid);
7669     + if (!ok) {
7670     + DBG_ERR("Failed to convert SID %s to a UID (dom_user[%s])\n",
7671     + dom_sid_str_buf(sid, &buf), dom_user);
7672     + return NT_STATUS_NO_SUCH_USER;
7673     + }
7674     + passwd = getpwuid_alloc(mem_ctx, uid);
7675     + if (!passwd) {
7676     + DBG_ERR("Failed to find local account with UID %lld for SID %s (dom_user[%s])\n",
7677     + (long long)uid,
7678     + dom_sid_str_buf(sid, &buf),
7679     + dom_user);
7680     + return NT_STATUS_NO_SUCH_USER;
7681     + }
7682     + real_username = talloc_strdup(mem_ctx, passwd->pw_name);
7683     + }
7684     if (!passwd) {
7685     DEBUG(3, ("Failed to find authenticated user %s via "
7686     "getpwnam(), denying access.\n", dom_user));
7687     @@ -2017,6 +2044,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
7688     bool username_was_mapped;
7689     struct passwd *pwd;
7690     struct auth_serversupplied_info *result;
7691     + struct dom_sid sid;
7692     TALLOC_CTX *tmp_ctx = talloc_stackframe();
7693    
7694     /*
7695     @@ -2063,9 +2091,13 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
7696    
7697     /* this call will try to create the user if necessary */
7698    
7699     + sid_copy(&sid, info3->base.domain_sid);
7700     + sid_append_rid(&sid, info3->base.rid);
7701     +
7702     nt_status = check_account(tmp_ctx,
7703     nt_domain,
7704     nt_username,
7705     + &sid,
7706     &found_username,
7707     &pwd,
7708     &username_was_mapped);
7709     --
7710     2.39.0
7711    
7712    
7713     From f035c041e42594bacfe7c3f4e5ea5d05399e1c5a Mon Sep 17 00:00:00 2001
7714     From: Ralph Boehme <slow@samba.org>
7715     Date: Fri, 26 Nov 2021 10:57:17 +0100
7716     Subject: [PATCH 092/142] CVE-2020-25717: s3-auth: fix MIT Realm regression
7717    
7718     This looks like a regression introduced by the recent security fixes. This
7719     commit should hopefully fixes it.
7720    
7721     As a quick solution it might be possible to use the username map script based on
7722     the example in https://bugzilla.samba.org/show_bug.cgi?id=14901#c0. We're not
7723     sure this behaves identical, but it might work in the standalone server case.
7724    
7725     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14922
7726    
7727     Reported-at: https://lists.samba.org/archive/samba/2021-November/238720.html
7728    
7729     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
7730    
7731     Signed-off-by: Ralph Boehme <slow@samba.org>
7732     Signed-off-by: Stefan Metzmacher <metze@samba.org>
7733     (cherry picked from commit 1e61de8306604a0d3858342df8a1d2412d8d418b)
7734     ---
7735     source3/auth/user_krb5.c | 9 +++++++++
7736     1 file changed, 9 insertions(+)
7737    
7738     diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c
7739     index b8f37cbeee0..169bf563368 100644
7740     --- a/source3/auth/user_krb5.c
7741     +++ b/source3/auth/user_krb5.c
7742     @@ -46,6 +46,7 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
7743     char *fuser = NULL;
7744     char *unixuser = NULL;
7745     struct passwd *pw = NULL;
7746     + bool may_retry = false;
7747    
7748     DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
7749    
7750     @@ -71,6 +72,7 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
7751     domain = realm;
7752     } else {
7753     domain = lp_workgroup();
7754     + may_retry = true;
7755     }
7756    
7757     fuser = talloc_asprintf(mem_ctx,
7758     @@ -89,6 +91,13 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
7759     *mapped_to_guest = false;
7760    
7761     pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true);
7762     + if (may_retry && pw == NULL && !*is_mapped) {
7763     + fuser = talloc_strdup(mem_ctx, user);
7764     + if (!fuser) {
7765     + return NT_STATUS_NO_MEMORY;
7766     + }
7767     + pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true);
7768     + }
7769     if (pw) {
7770     if (!unixuser) {
7771     return NT_STATUS_NO_MEMORY;
7772     --
7773     2.39.0
7774    
7775    
7776     From 8b8d1b20b16381c305c23ce03a559b8c7de67f5d Mon Sep 17 00:00:00 2001
7777     From: Ralph Boehme <slow@samba.org>
7778     Date: Thu, 13 Jan 2022 16:48:01 +0100
7779     Subject: [PATCH 093/142] CVE-2021-44142: libadouble: add defines for icon
7780     lengths
7781    
7782     From https://www.ietf.org/rfc/rfc1740.txt
7783    
7784     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914
7785    
7786     Signed-off-by: Ralph Boehme <slow@samba.org>
7787     ---
7788     source3/modules/vfs_fruit.c | 2 ++
7789     1 file changed, 2 insertions(+)
7790    
7791     diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
7792     index afad70ce180..3a35620bfe4 100644
7793     --- a/source3/modules/vfs_fruit.c
7794     +++ b/source3/modules/vfs_fruit.c
7795     @@ -283,6 +283,8 @@ typedef enum {ADOUBLE_META, ADOUBLE_RSRC} adouble_type_t;
7796     #define ADEDLEN_MACFILEI 4
7797     #define ADEDLEN_PRODOSFILEI 8
7798     #define ADEDLEN_MSDOSFILEI 2
7799     +#define ADEDLEN_ICONBW 128
7800     +#define ADEDLEN_ICONCOL 1024
7801     #define ADEDLEN_DID 4
7802     #define ADEDLEN_PRIVDEV 8
7803     #define ADEDLEN_PRIVINO 8
7804     --
7805     2.39.0
7806    
7807    
7808     From 3f2e9a6de36c086cff0bb3296f00c85a37a2653c Mon Sep 17 00:00:00 2001
7809     From: Ralph Boehme <slow@samba.org>
7810     Date: Sat, 20 Nov 2021 16:36:42 +0100
7811     Subject: [PATCH 094/142] CVE-2021-44142: smbd: add Netatalk xattr used by
7812     vfs_fruit to the list of private Samba xattrs
7813    
7814     This is an internal xattr that should not be user visible.
7815    
7816     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914
7817    
7818     Signed-off-by: Ralph Boehme <slow@samba.org>
7819     [slow@samba.org: conflict due to changed includes in source3/smbd/trans2.c]
7820     ---
7821     source3/smbd/trans2.c | 11 +++++++++++
7822     1 file changed, 11 insertions(+)
7823    
7824     diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
7825     index f8d987bbe63..406087c0419 100644
7826     --- a/source3/smbd/trans2.c
7827     +++ b/source3/smbd/trans2.c
7828     @@ -176,6 +176,16 @@ void aapl_force_zero_file_id(struct smbd_server_connection *sconn)
7829     Refuse to allow clients to overwrite our private xattrs.
7830     ****************************************************************************/
7831    
7832     +/*
7833     + * Taken from vfs_fruit.c
7834     + */
7835     +#define NETATALK_META_XATTR "org.netatalk.Metadata"
7836     +#if defined(HAVE_ATTROPEN)
7837     +#define AFPINFO_EA_NETATALK NETATALK_META_XATTR
7838     +#else
7839     +#define AFPINFO_EA_NETATALK "user." NETATALK_META_XATTR
7840     +#endif
7841     +
7842     bool samba_private_attr_name(const char *unix_ea_name)
7843     {
7844     static const char * const prohibited_ea_names[] = {
7845     @@ -183,6 +193,7 @@ bool samba_private_attr_name(const char *unix_ea_name)
7846     SAMBA_XATTR_DOS_ATTRIB,
7847     SAMBA_XATTR_MARKER,
7848     XATTR_NTACL_NAME,
7849     + AFPINFO_EA_NETATALK,
7850     NULL
7851     };
7852    
7853     --
7854     2.39.0
7855    
7856    
7857     From 00287584703e9e91e804e0f182bd844b7c436716 Mon Sep 17 00:00:00 2001
7858     From: Ralph Boehme <slow@samba.org>
7859     Date: Fri, 26 Nov 2021 07:19:32 +0100
7860     Subject: [PATCH 095/142] CVE-2021-44142: libadouble: harden ad_unpack_xattrs()
7861    
7862     This ensures ad_unpack_xattrs() is only called for an ad_type of ADOUBLE_RSRC,
7863     which is used for parsing ._ AppleDouble sidecar files, and the buffer
7864     ad->ad_data is AD_XATTR_MAX_HDR_SIZE bytes large which is a prerequisite for all
7865     buffer out-of-bounds access checks in ad_unpack_xattrs().
7866    
7867     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914
7868    
7869     Signed-off-by: Ralph Boehme <slow@samba.org>
7870     ---
7871     source3/modules/vfs_fruit.c | 22 ++++++++++++++++++----
7872     1 file changed, 18 insertions(+), 4 deletions(-)
7873    
7874     diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
7875     index 3a35620bfe4..76139e51047 100644
7876     --- a/source3/modules/vfs_fruit.c
7877     +++ b/source3/modules/vfs_fruit.c
7878     @@ -728,14 +728,27 @@ static bool ad_pack(struct adouble *ad)
7879     static bool ad_unpack_xattrs(struct adouble *ad)
7880     {
7881     struct ad_xattr_header *h = &ad->adx_header;
7882     + size_t bufsize = talloc_get_size(ad->ad_data);
7883     const char *p = ad->ad_data;
7884     uint32_t hoff;
7885     uint32_t i;
7886    
7887     + if (ad->ad_type != ADOUBLE_RSRC) {
7888     + return false;
7889     + }
7890     +
7891     if (ad_getentrylen(ad, ADEID_FINDERI) <= ADEDLEN_FINDERI) {
7892     return true;
7893     }
7894    
7895     + /*
7896     + * Ensure the buffer ad->ad_data was allocated by ad_alloc() for an
7897     + * ADOUBLE_RSRC type (._ AppleDouble file on-disk).
7898     + */
7899     + if (bufsize != AD_XATTR_MAX_HDR_SIZE) {
7900     + return false;
7901     + }
7902     +
7903     /* 2 bytes padding */
7904     hoff = ad_getentryoff(ad, ADEID_FINDERI) + ADEDLEN_FINDERI + 2;
7905    
7906     @@ -985,11 +998,12 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries,
7907     ad->ad_eid[eid].ade_len = len;
7908     }
7909    
7910     - ok = ad_unpack_xattrs(ad);
7911     - if (!ok) {
7912     - return false;
7913     + if (ad->ad_type == ADOUBLE_RSRC) {
7914     + ok = ad_unpack_xattrs(ad);
7915     + if (!ok) {
7916     + return false;
7917     + }
7918     }
7919     -
7920     return true;
7921     }
7922    
7923     --
7924     2.39.0
7925    
7926    
7927     From 94141fa38e082e4ab50be6c2f79c8506e72bc274 Mon Sep 17 00:00:00 2001
7928     From: Ralph Boehme <slow@samba.org>
7929     Date: Thu, 25 Nov 2021 15:04:03 +0100
7930     Subject: [PATCH 096/142] CVE-2021-44142: libadouble: add basic cmocka tests
7931    
7932     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914
7933    
7934     Signed-off-by: Ralph Boehme <slow@samba.org>
7935     [slow@samba.org: conflict due to missing test in selftest/tests.py]
7936     ---
7937     selftest/knownfail.d/samba.unittests.adouble | 3 +
7938     selftest/tests.py | 2 +
7939     source3/lib/test_adouble.c | 393 +++++++++++++++++++
7940     source3/wscript_build | 5 +
7941     4 files changed, 403 insertions(+)
7942     create mode 100644 selftest/knownfail.d/samba.unittests.adouble
7943     create mode 100644 source3/lib/test_adouble.c
7944    
7945     diff --git a/selftest/knownfail.d/samba.unittests.adouble b/selftest/knownfail.d/samba.unittests.adouble
7946     new file mode 100644
7947     index 00000000000..8b0314f2fae
7948     --- /dev/null
7949     +++ b/selftest/knownfail.d/samba.unittests.adouble
7950     @@ -0,0 +1,3 @@
7951     +^samba.unittests.adouble.parse_abouble_finderinfo2\(none\)
7952     +^samba.unittests.adouble.parse_abouble_finderinfo3\(none\)
7953     +^samba.unittests.adouble.parse_abouble_date2\(none\)
7954     diff --git a/selftest/tests.py b/selftest/tests.py
7955     index e3f7d9acb4a..4bc4d301c4c 100644
7956     --- a/selftest/tests.py
7957     +++ b/selftest/tests.py
7958     @@ -260,3 +260,5 @@ plantestsuite("samba.unittests.ntlm_check", "none",
7959     [os.path.join(bindir(), "default/libcli/auth/test_ntlm_check")])
7960     plantestsuite("samba.unittests.test_registry_regfio", "none",
7961     [os.path.join(bindir(), "default/source3/test_registry_regfio")])
7962     +plantestsuite("samba.unittests.adouble", "none",
7963     + [os.path.join(bindir(), "test_adouble")])
7964     diff --git a/source3/lib/test_adouble.c b/source3/lib/test_adouble.c
7965     new file mode 100644
7966     index 00000000000..667d2a7542e
7967     --- /dev/null
7968     +++ b/source3/lib/test_adouble.c
7969     @@ -0,0 +1,393 @@
7970     +/*
7971     + * Unix SMB/CIFS implementation.
7972     + *
7973     + * Copyright (C) 2021 Ralph Boehme <slow@samba.org>
7974     + *
7975     + * This program is free software; you can redistribute it and/or modify
7976     + * it under the terms of the GNU General Public License as published by
7977     + * the Free Software Foundation; either version 3 of the License, or
7978     + * (at your option) any later version.
7979     + *
7980     + * This program is distributed in the hope that it will be useful,
7981     + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7982     + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7983     + * GNU General Public License for more details.
7984     + *
7985     + * You should have received a copy of the GNU General Public License
7986     + * along with this program. If not, see <http://www.gnu.org/licenses/>.
7987     + */
7988     +
7989     +#include "includes.h"
7990     +extern NTSTATUS vfs_fruit_init(TALLOC_CTX *mem_ctx);
7991     +
7992     +#include "vfs_fruit.c"
7993     +#include <cmocka.h>
7994     +
7995     +
7996     +static int setup_talloc_context(void **state)
7997     +{
7998     + TALLOC_CTX *frame = talloc_stackframe();
7999     +
8000     + *state = frame;
8001     + return 0;
8002     +}
8003     +
8004     +static int teardown_talloc_context(void **state)
8005     +{
8006     + TALLOC_CTX *frame = *state;
8007     +
8008     + TALLOC_FREE(frame);
8009     + return 0;
8010     +}
8011     +
8012     +/*
8013     + * Basic and sane buffer.
8014     + */
8015     +static uint8_t ad_basic[] = {
8016     + 0x00, 0x05, 0x16, 0x07, /* Magic */
8017     + 0x00, 0x02, 0x00, 0x00, /* Version */
8018     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8019     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8020     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8021     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8022     + 0x00, 0x02, /* Count */
8023     + /* adentry 1: FinderInfo */
8024     + 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */
8025     + 0x00, 0x00, 0x00, 0x32, /* offset */
8026     + 0x00, 0x00, 0x00, 0x20, /* length */
8027     + /* adentry 2: Resourcefork */
8028     + 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */
8029     + 0x00, 0x00, 0x00, 0x52, /* offset */
8030     + 0xff, 0xff, 0xff, 0x00, /* length */
8031     + /* FinderInfo data: 32 bytes */
8032     + 0x00, 0x00, 0x00, 0x00,
8033     + 0x00, 0x00, 0x00, 0x00,
8034     + 0x00, 0x00, 0x00, 0x00,
8035     + 0x00, 0x00, 0x00, 0x00,
8036     + 0x00, 0x00, 0x00, 0x00,
8037     + 0x00, 0x00, 0x00, 0x00,
8038     + 0x00, 0x00, 0x00, 0x00,
8039     + 0x00, 0x00, 0x00, 0x00,
8040     +};
8041     +
8042     +/*
8043     + * An empty FinderInfo entry.
8044     + */
8045     +static uint8_t ad_finderinfo1[] = {
8046     + 0x00, 0x05, 0x16, 0x07, /* Magic */
8047     + 0x00, 0x02, 0x00, 0x00, /* Version */
8048     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8049     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8050     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8051     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8052     + 0x00, 0x02, /* Count */
8053     + /* adentry 1: FinderInfo */
8054     + 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */
8055     + 0x00, 0x00, 0x00, 0x52, /* off: points at end of buffer */
8056     + 0x00, 0x00, 0x00, 0x00, /* len: 0, so off+len don't exceed bufferlen */
8057     + /* adentry 2: Resourcefork */
8058     + 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */
8059     + 0x00, 0x00, 0x00, 0x52, /* offset */
8060     + 0xff, 0xff, 0xff, 0x00, /* length */
8061     + /* FinderInfo data: 32 bytes */
8062     + 0x00, 0x00, 0x00, 0x00,
8063     + 0x00, 0x00, 0x00, 0x00,
8064     + 0x00, 0x00, 0x00, 0x00,
8065     + 0x00, 0x00, 0x00, 0x00,
8066     + 0x00, 0x00, 0x00, 0x00,
8067     + 0x00, 0x00, 0x00, 0x00,
8068     + 0x00, 0x00, 0x00, 0x00,
8069     + 0x00, 0x00, 0x00, 0x00,
8070     +};
8071     +
8072     +/*
8073     + * A dangerous FinderInfo with correct length exceeding buffer by one byte.
8074     + */
8075     +static uint8_t ad_finderinfo2[] = {
8076     + 0x00, 0x05, 0x16, 0x07, /* Magic */
8077     + 0x00, 0x02, 0x00, 0x00, /* Version */
8078     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8079     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8080     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8081     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8082     + 0x00, 0x02, /* Count */
8083     + /* adentry 1: FinderInfo */
8084     + 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */
8085     + 0x00, 0x00, 0x00, 0x33, /* off: points at beginng of data + 1 */
8086     + 0x00, 0x00, 0x00, 0x20, /* len: 32, so off+len exceeds bufferlen by 1 */
8087     + /* adentry 2: Resourcefork */
8088     + 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */
8089     + 0x00, 0x00, 0x00, 0x52, /* offset */
8090     + 0xff, 0xff, 0xff, 0x00, /* length */
8091     + /* FinderInfo data: 32 bytes */
8092     + 0x00, 0x00, 0x00, 0x00,
8093     + 0x00, 0x00, 0x00, 0x00,
8094     + 0x00, 0x00, 0x00, 0x00,
8095     + 0x00, 0x00, 0x00, 0x00,
8096     + 0x00, 0x00, 0x00, 0x00,
8097     + 0x00, 0x00, 0x00, 0x00,
8098     + 0x00, 0x00, 0x00, 0x00,
8099     + 0x00, 0x00, 0x00, 0x00,
8100     +};
8101     +
8102     +static uint8_t ad_finderinfo3[] = {
8103     + 0x00, 0x05, 0x16, 0x07, /* Magic */
8104     + 0x00, 0x02, 0x00, 0x00, /* Version */
8105     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8106     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8107     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8108     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8109     + 0x00, 0x02, /* Count */
8110     + /* adentry 1: FinderInfo */
8111     + 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */
8112     + 0x00, 0x00, 0x00, 0x33, /* off: points at beginng of data + 1 */
8113     + 0x00, 0x00, 0x00, 0x1f, /* len: 31, so off+len don't exceed buf */
8114     + /* adentry 2: Resourcefork */
8115     + 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */
8116     + 0x00, 0x00, 0x00, 0x52, /* offset */
8117     + 0xff, 0xff, 0xff, 0x00, /* length */
8118     + /* FinderInfo data: 32 bytes */
8119     + 0x00, 0x00, 0x00, 0x00,
8120     + 0x00, 0x00, 0x00, 0x00,
8121     + 0x00, 0x00, 0x00, 0x00,
8122     + 0x00, 0x00, 0x00, 0x00,
8123     + 0x00, 0x00, 0x00, 0x00,
8124     + 0x00, 0x00, 0x00, 0x00,
8125     + 0x00, 0x00, 0x00, 0x00,
8126     + 0x00, 0x00, 0x00, 0x00,
8127     +};
8128     +
8129     +/*
8130     + * A dangerous name entry.
8131     + */
8132     +static uint8_t ad_name[] = {
8133     + 0x00, 0x05, 0x16, 0x07, /* Magic */
8134     + 0x00, 0x02, 0x00, 0x00, /* Version */
8135     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8136     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8137     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8138     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8139     + 0x00, 0x02, /* Count */
8140     + /* adentry 1: FinderInfo */
8141     + 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */
8142     + 0x00, 0x00, 0x00, 0x32, /* offset */
8143     + 0x00, 0x00, 0x00, 0x20, /* length */
8144     + /* adentry 2: Name */
8145     + 0x00, 0x00, 0x00, 0x03, /* eid: Name */
8146     + 0x00, 0x00, 0x00, 0x52, /* off: points at end of buffer */
8147     + 0x00, 0x00, 0x00, 0x01, /* len: 1, so off+len exceeds bufferlen */
8148     + /* FinderInfo data: 32 bytes */
8149     + 0x00, 0x00, 0x00, 0x00,
8150     + 0x00, 0x00, 0x00, 0x00,
8151     + 0x00, 0x00, 0x00, 0x00,
8152     + 0x00, 0x00, 0x00, 0x00,
8153     + 0x00, 0x00, 0x00, 0x00,
8154     + 0x00, 0x00, 0x00, 0x00,
8155     + 0x00, 0x00, 0x00, 0x00,
8156     + 0x00, 0x00, 0x00, 0x00,
8157     +};
8158     +
8159     +/*
8160     + * A empty ADEID_FILEDATESI entry.
8161     + */
8162     +static uint8_t ad_date1[] = {
8163     + 0x00, 0x05, 0x16, 0x07, /* Magic */
8164     + 0x00, 0x02, 0x00, 0x00, /* Version */
8165     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8166     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8167     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8168     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8169     + 0x00, 0x02, /* Count */
8170     + /* adentry 1: FinderInfo */
8171     + 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */
8172     + 0x00, 0x00, 0x00, 0x32, /* offset */
8173     + 0x00, 0x00, 0x00, 0x20, /* length */
8174     + /* adentry 2: Dates */
8175     + 0x00, 0x00, 0x00, 0x08, /* eid: dates */
8176     + 0x00, 0x00, 0x00, 0x52, /* off: end of buffer */
8177     + 0x00, 0x00, 0x00, 0x00, /* len: 0, empty entry, valid */
8178     + /* FinderInfo data: 32 bytes */
8179     + 0x00, 0x00, 0x00, 0x00,
8180     + 0x00, 0x00, 0x00, 0x00,
8181     + 0x00, 0x00, 0x00, 0x00,
8182     + 0x00, 0x00, 0x00, 0x00,
8183     + 0x00, 0x00, 0x00, 0x00,
8184     + 0x00, 0x00, 0x00, 0x00,
8185     + 0x00, 0x00, 0x00, 0x00,
8186     + 0x00, 0x00, 0x00, 0x00,
8187     +};
8188     +
8189     +/*
8190     + * A dangerous ADEID_FILEDATESI entry, invalid length.
8191     + */
8192     +static uint8_t ad_date2[] = {
8193     + 0x00, 0x05, 0x16, 0x07, /* Magic */
8194     + 0x00, 0x02, 0x00, 0x00, /* Version */
8195     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8196     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8197     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8198     + 0x00, 0x00, 0x00, 0x00, /* Filler */
8199     + 0x00, 0x02, /* Count */
8200     + /* adentry 1: FinderInfo */
8201     + 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */
8202     + 0x00, 0x00, 0x00, 0x32, /* offset */
8203     + 0x00, 0x00, 0x00, 0x20, /* length */
8204     + /* adentry 2: Dates */
8205     + 0x00, 0x00, 0x00, 0x08, /* eid: dates */
8206     + 0x00, 0x00, 0x00, 0x43, /* off: FinderInfo buf but one byte short */
8207     + 0x00, 0x00, 0x00, 0x0f, /* len: 15, so off+len don't exceed bufferlen */
8208     + /* FinderInfo data: 32 bytes */
8209     + 0x00, 0x00, 0x00, 0x00,
8210     + 0x00, 0x00, 0x00, 0x00,
8211     + 0x00, 0x00, 0x00, 0x00,
8212     + 0x00, 0x00, 0x00, 0x00,
8213     + 0x00, 0x00, 0x00, 0x00,
8214     + 0x00, 0x00, 0x00, 0x00,
8215     + 0x00, 0x00, 0x00, 0x00,
8216     + 0x00, 0x00, 0x00, 0x00,
8217     +};
8218     +
8219     +static struct adouble *parse_adouble(TALLOC_CTX *mem_ctx,
8220     + uint8_t *adbuf,
8221     + size_t adsize,
8222     + off_t filesize)
8223     +{
8224     + struct adouble *ad = NULL;
8225     + bool ok;
8226     +
8227     + ad = talloc_zero(mem_ctx, struct adouble);
8228     + ad->ad_data = talloc_zero_size(ad, adsize);
8229     + assert_non_null(ad);
8230     +
8231     + memcpy(ad->ad_data, adbuf, adsize);
8232     +
8233     + ok = ad_unpack(ad, 2, filesize);
8234     + if (!ok) {
8235     + return NULL;
8236     + }
8237     +
8238     + return ad;
8239     +}
8240     +
8241     +static void parse_abouble_basic(void **state)
8242     +{
8243     + TALLOC_CTX *frame = *state;
8244     + struct adouble *ad = NULL;
8245     + char *p = NULL;
8246     +
8247     + ad = parse_adouble(frame, ad_basic, sizeof(ad_basic), 0xffffff52);
8248     + assert_non_null(ad);
8249     +
8250     + p = ad_get_entry(ad, ADEID_FINDERI);
8251     + assert_non_null(p);
8252     +
8253     + return;
8254     +}
8255     +
8256     +static void parse_abouble_finderinfo1(void **state)
8257     +{
8258     + TALLOC_CTX *frame = *state;
8259     + struct adouble *ad = NULL;
8260     + char *p = NULL;
8261     +
8262     + ad = parse_adouble(frame,
8263     + ad_finderinfo1,
8264     + sizeof(ad_finderinfo1),
8265     + 0xffffff52);
8266     + assert_non_null(ad);
8267     +
8268     + p = ad_get_entry(ad, ADEID_FINDERI);
8269     + assert_null(p);
8270     +
8271     + return;
8272     +}
8273     +
8274     +static void parse_abouble_finderinfo2(void **state)
8275     +{
8276     + TALLOC_CTX *frame = *state;
8277     + struct adouble *ad = NULL;
8278     +
8279     + ad = parse_adouble(frame,
8280     + ad_finderinfo2,
8281     + sizeof(ad_finderinfo2),
8282     + 0xffffff52);
8283     + assert_null(ad);
8284     +
8285     + return;
8286     +}
8287     +
8288     +static void parse_abouble_finderinfo3(void **state)
8289     +{
8290     + TALLOC_CTX *frame = *state;
8291     + struct adouble *ad = NULL;
8292     +
8293     + ad = parse_adouble(frame,
8294     + ad_finderinfo3,
8295     + sizeof(ad_finderinfo3),
8296     + 0xffffff52);
8297     + assert_null(ad);
8298     +
8299     + return;
8300     +}
8301     +
8302     +static void parse_abouble_name(void **state)
8303     +{
8304     + TALLOC_CTX *frame = *state;
8305     + struct adouble *ad = NULL;
8306     +
8307     + ad = parse_adouble(frame, ad_name, sizeof(ad_name), 0x52);
8308     + assert_null(ad);
8309     +
8310     + return;
8311     +}
8312     +
8313     +static void parse_abouble_date1(void **state)
8314     +{
8315     + TALLOC_CTX *frame = *state;
8316     + struct adouble *ad = NULL;
8317     + char *p = NULL;
8318     +
8319     + ad = parse_adouble(frame, ad_date1, sizeof(ad_date1), 0x52);
8320     + assert_non_null(ad);
8321     +
8322     + p = ad_get_entry(ad, ADEID_FILEDATESI);
8323     + assert_null(p);
8324     +
8325     + return;
8326     +}
8327     +
8328     +static void parse_abouble_date2(void **state)
8329     +{
8330     + TALLOC_CTX *frame = *state;
8331     + struct adouble *ad = NULL;
8332     +
8333     + ad = parse_adouble(frame, ad_date2, sizeof(ad_date2), 0x52);
8334     + assert_null(ad);
8335     +
8336     + return;
8337     +}
8338     +
8339     +int main(int argc, char *argv[])
8340     +{
8341     + int rc;
8342     + const struct CMUnitTest tests[] = {
8343     + cmocka_unit_test(parse_abouble_basic),
8344     + cmocka_unit_test(parse_abouble_finderinfo1),
8345     + cmocka_unit_test(parse_abouble_finderinfo2),
8346     + cmocka_unit_test(parse_abouble_finderinfo3),
8347     + cmocka_unit_test(parse_abouble_name),
8348     + cmocka_unit_test(parse_abouble_date1),
8349     + cmocka_unit_test(parse_abouble_date2),
8350     + };
8351     +
8352     + if (argc == 2) {
8353     + cmocka_set_test_filter(argv[1]);
8354     + }
8355     + cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
8356     +
8357     + rc = cmocka_run_group_tests(tests,
8358     + setup_talloc_context,
8359     + teardown_talloc_context);
8360     +
8361     + return rc;
8362     +}
8363     diff --git a/source3/wscript_build b/source3/wscript_build
8364     index 26e251f442a..5230ae32934 100644
8365     --- a/source3/wscript_build
8366     +++ b/source3/wscript_build
8367     @@ -1080,6 +1080,11 @@ bld.SAMBA3_SUBSYSTEM('SPOOLSSD',
8368    
8369     ########################## BINARIES #################################
8370    
8371     +bld.SAMBA3_BINARY('test_adouble',
8372     + source='lib/test_adouble.c',
8373     + deps='smbd_base STRING_REPLACE cmocka OFFLOAD_TOKEN',
8374     + install=False)
8375     +
8376     bld.SAMBA3_BINARY('smbd/smbd',
8377     source='smbd/server.c smbd/smbd_cleanupd.c',
8378     deps='''
8379     --
8380     2.39.0
8381    
8382    
8383     From 5c1c2ea3dbe554f621014bb2b3133c0859dce2da Mon Sep 17 00:00:00 2001
8384     From: Ralph Boehme <slow@samba.org>
8385     Date: Thu, 13 Jan 2022 17:03:02 +0100
8386     Subject: [PATCH 097/142] CVE-2021-44142: libadouble: harden parsing code
8387    
8388     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914
8389    
8390     Signed-off-by: Ralph Boehme <slow@samba.org>
8391     ---
8392     selftest/knownfail.d/samba.unittests.adouble | 3 -
8393     source3/modules/vfs_fruit.c | 114 ++++++++++++++++---
8394     2 files changed, 100 insertions(+), 17 deletions(-)
8395     delete mode 100644 selftest/knownfail.d/samba.unittests.adouble
8396    
8397     diff --git a/selftest/knownfail.d/samba.unittests.adouble b/selftest/knownfail.d/samba.unittests.adouble
8398     deleted file mode 100644
8399     index 8b0314f2fae..00000000000
8400     --- a/selftest/knownfail.d/samba.unittests.adouble
8401     +++ /dev/null
8402     @@ -1,3 +0,0 @@
8403     -^samba.unittests.adouble.parse_abouble_finderinfo2\(none\)
8404     -^samba.unittests.adouble.parse_abouble_finderinfo3\(none\)
8405     -^samba.unittests.adouble.parse_abouble_date2\(none\)
8406     diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
8407     index 76139e51047..17e97d15bdb 100644
8408     --- a/source3/modules/vfs_fruit.c
8409     +++ b/source3/modules/vfs_fruit.c
8410     @@ -540,6 +540,94 @@ static AfpInfo *afpinfo_new(TALLOC_CTX *ctx);
8411     static ssize_t afpinfo_pack(const AfpInfo *ai, char *buf);
8412     static AfpInfo *afpinfo_unpack(TALLOC_CTX *ctx, const void *data);
8413    
8414     +/*
8415     + * All entries besides FinderInfo and resource fork must fit into the
8416     + * buffer. FinderInfo is special as it may be larger then the default 32 bytes
8417     + * if it contains marshalled xattrs, which we will fixup that in
8418     + * ad_convert(). The first 32 bytes however must also be part of the buffer.
8419     + *
8420     + * The resource fork is never accessed directly by the ad_data buf.
8421     + */
8422     +static bool ad_entry_check_size(uint32_t eid,
8423     + size_t bufsize,
8424     + uint32_t off,
8425     + uint32_t got_len)
8426     +{
8427     + struct {
8428     + off_t expected_len;
8429     + bool fixed_size;
8430     + bool minimum_size;
8431     + } ad_checks[] = {
8432     + [ADEID_DFORK] = {-1, false, false}, /* not applicable */
8433     + [ADEID_RFORK] = {-1, false, false}, /* no limit */
8434     + [ADEID_NAME] = {ADEDLEN_NAME, false, false},
8435     + [ADEID_COMMENT] = {ADEDLEN_COMMENT, false, false},
8436     + [ADEID_ICONBW] = {ADEDLEN_ICONBW, true, false},
8437     + [ADEID_ICONCOL] = {ADEDLEN_ICONCOL, false, false},
8438     + [ADEID_FILEI] = {ADEDLEN_FILEI, true, false},
8439     + [ADEID_FILEDATESI] = {ADEDLEN_FILEDATESI, true, false},
8440     + [ADEID_FINDERI] = {ADEDLEN_FINDERI, false, true},
8441     + [ADEID_MACFILEI] = {ADEDLEN_MACFILEI, true, false},
8442     + [ADEID_PRODOSFILEI] = {ADEDLEN_PRODOSFILEI, true, false},
8443     + [ADEID_MSDOSFILEI] = {ADEDLEN_MSDOSFILEI, true, false},
8444     + [ADEID_SHORTNAME] = {ADEDLEN_SHORTNAME, false, false},
8445     + [ADEID_AFPFILEI] = {ADEDLEN_AFPFILEI, true, false},
8446     + [ADEID_DID] = {ADEDLEN_DID, true, false},
8447     + [ADEID_PRIVDEV] = {ADEDLEN_PRIVDEV, true, false},
8448     + [ADEID_PRIVINO] = {ADEDLEN_PRIVINO, true, false},
8449     + [ADEID_PRIVSYN] = {ADEDLEN_PRIVSYN, true, false},
8450     + [ADEID_PRIVID] = {ADEDLEN_PRIVID, true, false},
8451     + };
8452     +
8453     + if (eid >= ADEID_MAX) {
8454     + return false;
8455     + }
8456     + if (got_len == 0) {
8457     + /* Entry present, but empty, allow */
8458     + return true;
8459     + }
8460     + if (ad_checks[eid].expected_len == 0) {
8461     + /*
8462     + * Shouldn't happen: implicitly initialized to zero because
8463     + * explicit initializer missing.
8464     + */
8465     + return false;
8466     + }
8467     + if (ad_checks[eid].expected_len == -1) {
8468     + /* Unused or no limit */
8469     + return true;
8470     + }
8471     + if (ad_checks[eid].fixed_size) {
8472     + if (ad_checks[eid].expected_len != got_len) {
8473     + /* Wrong size fo fixed size entry. */
8474     + return false;
8475     + }
8476     + } else {
8477     + if (ad_checks[eid].minimum_size) {
8478     + if (got_len < ad_checks[eid].expected_len) {
8479     + /*
8480     + * Too small for variable sized entry with
8481     + * minimum size.
8482     + */
8483     + return false;
8484     + }
8485     + } else {
8486     + if (got_len > ad_checks[eid].expected_len) {
8487     + /* Too big for variable sized entry. */
8488     + return false;
8489     + }
8490     + }
8491     + }
8492     + if (off + got_len < off) {
8493     + /* wrap around */
8494     + return false;
8495     + }
8496     + if (off + got_len > bufsize) {
8497     + /* overflow */
8498     + return false;
8499     + }
8500     + return true;
8501     +}
8502    
8503     /**
8504     * Return a pointer to an AppleDouble entry
8505     @@ -548,8 +636,15 @@ static AfpInfo *afpinfo_unpack(TALLOC_CTX *ctx, const void *data);
8506     **/
8507     static char *ad_get_entry(const struct adouble *ad, int eid)
8508     {
8509     + size_t bufsize = talloc_get_size(ad->ad_data);
8510     off_t off = ad_getentryoff(ad, eid);
8511     size_t len = ad_getentrylen(ad, eid);
8512     + bool valid;
8513     +
8514     + valid = ad_entry_check_size(eid, bufsize, off, len);
8515     + if (!valid) {
8516     + return NULL;
8517     + }
8518    
8519     if (off == 0 || len == 0) {
8520     return NULL;
8521     @@ -935,20 +1030,11 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries,
8522     return false;
8523     }
8524    
8525     - /*
8526     - * All entries besides FinderInfo and resource fork
8527     - * must fit into the buffer. FinderInfo is special as
8528     - * it may be larger then the default 32 bytes (if it
8529     - * contains marshalled xattrs), but we will fixup that
8530     - * in ad_convert(). And the resource fork is never
8531     - * accessed directly by the ad_data buf (also see
8532     - * comment above) anyway.
8533     - */
8534     - if ((eid != ADEID_RFORK) &&
8535     - (eid != ADEID_FINDERI) &&
8536     - ((off + len) > bufsize)) {
8537     - DEBUG(1, ("bogus eid %d: off: %" PRIu32 ", len: %" PRIu32 "\n",
8538     - eid, off, len));
8539     + ok = ad_entry_check_size(eid, bufsize, off, len);
8540     + if (!ok) {
8541     + DBG_ERR("bogus eid [%"PRIu32"] bufsize [%zu] "
8542     + "off [%"PRIu32"] len [%"PRIu32"]\n",
8543     + eid, bufsize, off, len);
8544     return false;
8545     }
8546    
8547     --
8548     2.39.0
8549    
8550    
8551     From 2c1f15a39367493733e4d275c3709a6497225917 Mon Sep 17 00:00:00 2001
8552     From: Christof Schmitt <cs@samba.org>
8553     Date: Fri, 5 Mar 2021 15:48:29 -0700
8554     Subject: [PATCH 098/142] winbind: Only use unixid2sid mapping when module
8555     reports ID_MAPPED
8556    
8557     Only consider a mapping to be valid when the idmap module reports
8558     ID_MAPPED. Otherwise return the null SID.
8559    
8560     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14663
8561    
8562     Signed-off-by: Christof Schmitt <cs@samba.org>
8563     Reviewed-by: Volker Lendecke <vl@samba.org>
8564     (cherry picked from commit db2afa57e4aa926b478db1be4d693edbdf4d2a23)
8565     (cherry picked from commit 3aa06edf38bc4002f031476baa50712fd1a67f4d)
8566     ---
8567     source3/winbindd/winbindd_dual_srv.c | 6 ++++--
8568     1 file changed, 4 insertions(+), 2 deletions(-)
8569    
8570     diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
8571     index 0842241e02e..94331163006 100644
8572     --- a/source3/winbindd/winbindd_dual_srv.c
8573     +++ b/source3/winbindd/winbindd_dual_srv.c
8574     @@ -275,8 +275,10 @@ NTSTATUS _wbint_UnixIDs2Sids(struct pipes_struct *p,
8575     }
8576    
8577     for (i=0; i<r->in.num_ids; i++) {
8578     - r->out.xids[i] = maps[i]->xid;
8579     - sid_copy(&r->out.sids[i], maps[i]->sid);
8580     + if (maps[i]->status == ID_MAPPED) {
8581     + r->out.xids[i] = maps[i]->xid;
8582     + sid_copy(&r->out.sids[i], maps[i]->sid);
8583     + }
8584     }
8585    
8586     TALLOC_FREE(maps);
8587     --
8588     2.39.0
8589    
8590    
8591     From 754ece447c2dea8cccbe8740df5aff75dca7b646 Mon Sep 17 00:00:00 2001
8592     From: Christof Schmitt <cs@samba.org>
8593     Date: Fri, 5 Mar 2021 16:01:13 -0700
8594     Subject: [PATCH 099/142] idmap_rfc2307: Do not return SID from unixids_to_sids
8595     on type mismatch
8596    
8597     The call to winbind_lookup_name already wrote the result in the id_map
8598     array. The later check for the type detected a mismatch, but that did
8599     not remove the SID from the result struct.
8600    
8601     Change this by first assigning the SID to a temporary variable and only
8602     write it to the id_map array after the type checks.
8603    
8604     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14663
8605    
8606     Signed-off-by: Christof Schmitt <cs@samba.org>
8607     (cherry picked from commit 79dd4b133c37451c98fe7f7c45da881e89e91ffc)
8608     (cherry picked from commit af37d5abae924d095e7b35620d850cf1f19021c4)
8609     ---
8610     source3/winbindd/idmap_rfc2307.c | 4 +++-
8611     source3/winbindd/winbindd_dual_srv.c | 2 ++
8612     2 files changed, 5 insertions(+), 1 deletion(-)
8613    
8614     diff --git a/source3/winbindd/idmap_rfc2307.c b/source3/winbindd/idmap_rfc2307.c
8615     index e3bf58d8165..2fffaec6cca 100644
8616     --- a/source3/winbindd/idmap_rfc2307.c
8617     +++ b/source3/winbindd/idmap_rfc2307.c
8618     @@ -228,6 +228,7 @@ static void idmap_rfc2307_map_sid_results(struct idmap_rfc2307_context *ctx,
8619    
8620     for (i = 0; i < count; i++) {
8621     char *name;
8622     + struct dom_sid sid;
8623     enum lsa_SidType lsa_type;
8624     struct id_map *map;
8625     uint32_t id;
8626     @@ -276,7 +277,7 @@ static void idmap_rfc2307_map_sid_results(struct idmap_rfc2307_context *ctx,
8627     the following call will not recurse so this is safe */
8628     (void)winbind_on();
8629     /* Lookup name from PDC using lsa_lookup_names() */
8630     - b = winbind_lookup_name(dom_name, name, map->sid, &lsa_type);
8631     + b = winbind_lookup_name(dom_name, name, &sid, &lsa_type);
8632     (void)winbind_off();
8633    
8634     if (!b) {
8635     @@ -300,6 +301,7 @@ static void idmap_rfc2307_map_sid_results(struct idmap_rfc2307_context *ctx,
8636     }
8637    
8638     map->status = ID_MAPPED;
8639     + sid_copy(map->sid, &sid);
8640     }
8641     }
8642    
8643     diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
8644     index 94331163006..34375b3858f 100644
8645     --- a/source3/winbindd/winbindd_dual_srv.c
8646     +++ b/source3/winbindd/winbindd_dual_srv.c
8647     @@ -278,6 +278,8 @@ NTSTATUS _wbint_UnixIDs2Sids(struct pipes_struct *p,
8648     if (maps[i]->status == ID_MAPPED) {
8649     r->out.xids[i] = maps[i]->xid;
8650     sid_copy(&r->out.sids[i], maps[i]->sid);
8651     + } else {
8652     + r->out.sids[i] = (struct dom_sid) { 0 };
8653     }
8654     }
8655    
8656     --
8657     2.39.0
8658    
8659    
8660     From f831d80dde35ba0e29014a9e4f34cb3ce6eb6161 Mon Sep 17 00:00:00 2001
8661     From: Christof Schmitt <cs@samba.org>
8662     Date: Fri, 5 Mar 2021 16:07:54 -0700
8663     Subject: [PATCH 100/142] idmap_nss: Do not return SID from unixids_to_sids on
8664     type mismatch
8665    
8666     The call to winbind_lookup_name already wrote the result in the id_map
8667     array. The later check for the type detected a mismatch, but that did
8668     not remove the SID from the result struct.
8669    
8670     Change this by first assigning the SID to a temporary variable and only
8671     write it to the id_map array after the type checks.
8672    
8673     BUG: https://bugzilla.samba.org/show_bug.cgi?id=14663
8674    
8675     Signed-off-by: Christof Schmitt <cs@samba.org>
8676     Reviewed-by: Volker Lendecke <vl@samba.org>
8677    
8678     Autobuild-User(master): Volker Lendecke <vl@samba.org>
8679     Autobuild-Date(master): Thu Mar 11 08:38:41 UTC 2021 on sn-devel-184
8680    
8681     (cherry picked from commit 0e789ba1802ca22e5a01abd6e93ef66cd45566a7)
8682     (cherry picked from commit 3f366878d33cf977230137021f6376936b2a1862)
8683     ---
8684     source3/winbindd/idmap_nss.c | 5 ++++-
8685     1 file changed, 4 insertions(+), 1 deletion(-)
8686    
8687     diff --git a/source3/winbindd/idmap_nss.c b/source3/winbindd/idmap_nss.c
8688     index 243b67ccafd..e4bf1923786 100644
8689     --- a/source3/winbindd/idmap_nss.c
8690     +++ b/source3/winbindd/idmap_nss.c
8691     @@ -56,6 +56,7 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
8692     struct passwd *pw;
8693     struct group *gr;
8694     const char *name;
8695     + struct dom_sid sid;
8696     enum lsa_SidType type;
8697     bool ret;
8698    
8699     @@ -87,7 +88,7 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
8700     the following call will not recurse so this is safe */
8701     (void)winbind_on();
8702     /* Lookup name from PDC using lsa_lookup_names() */
8703     - ret = winbind_lookup_name(dom->name, name, ids[i]->sid, &type);
8704     + ret = winbind_lookup_name(dom->name, name, &sid, &type);
8705     (void)winbind_off();
8706    
8707     if (!ret) {
8708     @@ -100,6 +101,7 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
8709     switch (type) {
8710     case SID_NAME_USER:
8711     if (ids[i]->xid.type == ID_TYPE_UID) {
8712     + sid_copy(ids[i]->sid, &sid);
8713     ids[i]->status = ID_MAPPED;
8714     }
8715     break;
8716     @@ -108,6 +110,7 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
8717     case SID_NAME_ALIAS:
8718     case SID_NAME_WKN_GRP:
8719     if (ids[i]->xid.type == ID_TYPE_GID) {
8720     + sid_copy(ids[i]->sid, &sid);
8721     ids[i]->status = ID_MAPPED;
8722     }
8723     break;
8724     --
8725     2.39.0
8726    
8727    
8728     From 4ef3d95fb680cf278e68b6794459ff7bce1489aa Mon Sep 17 00:00:00 2001
8729     From: Andreas Schneider <asn@samba.org>
8730     Date: Tue, 23 Nov 2021 15:48:57 +0100
8731     Subject: [PATCH 101/142] s3:winbind: Fix possible NULL pointer dereference
8732    
8733     BUG: https://bugzilla.redhat.com/show_bug.cgi?id=2019888
8734    
8735     Signed-off-by: Andreas Schneider <asn@samba.org>
8736     Rewiewed-by: Jeremy Allison <jra@samba.org>
8737    
8738     Autobuild-User(master): Jeremy Allison <jra@samba.org>
8739     Autobuild-Date(master): Mon Nov 29 19:40:50 UTC 2021 on sn-devel-184
8740    
8741     (cherry picked from commit cbf312f02bc86f9325fb89f6f5441bc61fd3974f)
8742     ---
8743     source3/winbindd/winbindd_util.c | 3 +++
8744     1 file changed, 3 insertions(+)
8745    
8746     diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
8747     index 04e79e70f6b..d1bd81b2372 100644
8748     --- a/source3/winbindd/winbindd_util.c
8749     +++ b/source3/winbindd/winbindd_util.c
8750     @@ -1691,6 +1691,9 @@ char *fill_domain_username_talloc(TALLOC_CTX *mem_ctx,
8751     }
8752    
8753     tmp_user = talloc_strdup(mem_ctx, user);
8754     + if (tmp_user == NULL) {
8755     + return NULL;
8756     + }
8757     if (!strlower_m(tmp_user)) {
8758     TALLOC_FREE(tmp_user);
8759     return NULL;
8760     --
8761     2.39.0
8762    
8763    
8764     From 95c9485bb600e965f24712534850d1a7fd325c44 Mon Sep 17 00:00:00 2001
8765     From: Ralph Boehme <slow@samba.org>
8766     Date: Tue, 6 Dec 2022 16:00:36 +0100
8767     Subject: [PATCH 102/142] CVE-2022-38023 docs-xml: improve wording for several
8768     options: "takes precedence" -> "overrides"
8769    
8770     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
8771    
8772     Signed-off-by: Ralph Boehme <slow@samba.org>
8773     Reviewed-by: Stefan Metzmacher <metze@samba.org>
8774     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
8775     (cherry picked from commit 8ec62694a94c346e6ba8f3144a417c9984a1c8b9)
8776     ---
8777     docs-xml/smbdotconf/logon/rejectmd5clients.xml | 2 +-
8778     docs-xml/smbdotconf/security/serverschannel.xml | 2 +-
8779     docs-xml/smbdotconf/winbind/rejectmd5servers.xml | 2 +-
8780     docs-xml/smbdotconf/winbind/requirestrongkey.xml | 2 +-
8781     4 files changed, 4 insertions(+), 4 deletions(-)
8782    
8783     diff --git a/docs-xml/smbdotconf/logon/rejectmd5clients.xml b/docs-xml/smbdotconf/logon/rejectmd5clients.xml
8784     index 41684ef1080..0bb9f6f6c8e 100644
8785     --- a/docs-xml/smbdotconf/logon/rejectmd5clients.xml
8786     +++ b/docs-xml/smbdotconf/logon/rejectmd5clients.xml
8787     @@ -10,7 +10,7 @@
8788     <para>You can set this to yes if all domain members support aes.
8789     This will prevent downgrade attacks.</para>
8790    
8791     - <para>This option takes precedence to the 'allow nt4 crypto' option.</para>
8792     + <para>This option overrides the 'allow nt4 crypto' option.</para>
8793     </description>
8794    
8795     <value type="default">no</value>
8796     diff --git a/docs-xml/smbdotconf/security/serverschannel.xml b/docs-xml/smbdotconf/security/serverschannel.xml
8797     index b682d086f76..79e4e73a95c 100644
8798     --- a/docs-xml/smbdotconf/security/serverschannel.xml
8799     +++ b/docs-xml/smbdotconf/security/serverschannel.xml
8800     @@ -59,7 +59,7 @@
8801     See CVE-2020-1472(ZeroLogon) https://bugzilla.samba.org/show_bug.cgi?id=14497
8802     </para>
8803    
8804     - <para>This option takes precedence to the <smbconfoption name="server schannel"/> option.</para>
8805     + <para>This option overrides the <smbconfoption name="server schannel"/> option.</para>
8806    
8807     <programlisting>
8808     server require schannel:LEGACYCOMPUTER1$ = no
8809     diff --git a/docs-xml/smbdotconf/winbind/rejectmd5servers.xml b/docs-xml/smbdotconf/winbind/rejectmd5servers.xml
8810     index 37656293aa4..151b4676c57 100644
8811     --- a/docs-xml/smbdotconf/winbind/rejectmd5servers.xml
8812     +++ b/docs-xml/smbdotconf/winbind/rejectmd5servers.xml
8813     @@ -15,7 +15,7 @@
8814     <para>The behavior can be controlled per netbios domain
8815     by using 'reject md5 servers:NETBIOSDOMAIN = yes' as option.</para>
8816    
8817     - <para>This option takes precedence to the <smbconfoption name="require strong key"/> option.</para>
8818     + <para>This option overrides the <smbconfoption name="require strong key"/> option.</para>
8819     </description>
8820    
8821     <value type="default">no</value>
8822     diff --git a/docs-xml/smbdotconf/winbind/requirestrongkey.xml b/docs-xml/smbdotconf/winbind/requirestrongkey.xml
8823     index 4db62bfb02d..b17620ec8f1 100644
8824     --- a/docs-xml/smbdotconf/winbind/requirestrongkey.xml
8825     +++ b/docs-xml/smbdotconf/winbind/requirestrongkey.xml
8826     @@ -19,7 +19,7 @@
8827    
8828     <para>This option yields precedence to the <smbconfoption name="reject md5 servers"/> option.</para>
8829    
8830     - <para>This option takes precedence to the <smbconfoption name="client schannel"/> option.</para>
8831     + <para>This option overrides the <smbconfoption name="client schannel"/> option.</para>
8832     </description>
8833    
8834     <value type="default">yes</value>
8835     --
8836     2.39.0
8837    
8838    
8839     From d6ab8377e55e4bda76c86de9bba1ddee30361481 Mon Sep 17 00:00:00 2001
8840     From: Ralph Boehme <slow@samba.org>
8841     Date: Tue, 6 Dec 2022 16:05:26 +0100
8842     Subject: [PATCH 103/142] CVE-2022-38023 docs-xml: improve wording for several
8843     options: "yields precedence" -> "is over-riden"
8844    
8845     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
8846    
8847     Signed-off-by: Ralph Boehme <slow@samba.org>
8848     Reviewed-by: Stefan Metzmacher <metze@samba.org>
8849     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
8850     (cherry picked from commit 830e865ba5648f6520bc552ffd71b61f754b8251)
8851     ---
8852     docs-xml/smbdotconf/logon/allownt4crypto.xml | 2 +-
8853     docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml | 2 +-
8854     docs-xml/smbdotconf/security/clientschannel.xml | 2 +-
8855     docs-xml/smbdotconf/security/serverschannel.xml | 2 +-
8856     docs-xml/smbdotconf/winbind/requirestrongkey.xml | 2 +-
8857     5 files changed, 5 insertions(+), 5 deletions(-)
8858    
8859     diff --git a/docs-xml/smbdotconf/logon/allownt4crypto.xml b/docs-xml/smbdotconf/logon/allownt4crypto.xml
8860     index 03dc8fa93f7..06afcef73b1 100644
8861     --- a/docs-xml/smbdotconf/logon/allownt4crypto.xml
8862     +++ b/docs-xml/smbdotconf/logon/allownt4crypto.xml
8863     @@ -18,7 +18,7 @@
8864    
8865     <para>"allow nt4 crypto = yes" allows weak crypto to be negotiated, maybe via downgrade attacks.</para>
8866    
8867     - <para>This option yields precedence to the 'reject md5 clients' option.</para>
8868     + <para>This option is over-ridden by the 'reject md5 clients' option.</para>
8869     </description>
8870    
8871     <value type="default">no</value>
8872     diff --git a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
8873     index 03531adbfb3..8bccab391cc 100644
8874     --- a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
8875     +++ b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
8876     @@ -15,7 +15,7 @@
8877     <para>The behavior can be overwritten per interface name (e.g. lsarpc, netlogon, samr, srvsvc,
8878     winreg, wkssvc ...) by using 'allow dcerpc auth level connect:interface = yes' as option.</para>
8879    
8880     - <para>This option yields precedence to the implementation specific restrictions.
8881     + <para>This option is over-ridden by the implementation specific restrictions.
8882     E.g. the drsuapi and backupkey protocols require DCERPC_AUTH_LEVEL_PRIVACY.
8883     The dnsserver protocol requires DCERPC_AUTH_LEVEL_INTEGRITY.
8884     </para>
8885     diff --git a/docs-xml/smbdotconf/security/clientschannel.xml b/docs-xml/smbdotconf/security/clientschannel.xml
8886     index 5b07da95050..d124ad48181 100644
8887     --- a/docs-xml/smbdotconf/security/clientschannel.xml
8888     +++ b/docs-xml/smbdotconf/security/clientschannel.xml
8889     @@ -23,7 +23,7 @@
8890     <para>Note that for active directory domains this is hardcoded to
8891     <smbconfoption name="client schannel">yes</smbconfoption>.</para>
8892    
8893     - <para>This option yields precedence to the <smbconfoption name="require strong key"/> option.</para>
8894     + <para>This option is over-ridden by the <smbconfoption name="require strong key"/> option.</para>
8895     </description>
8896     <value type="default">yes</value>
8897     <value type="example">auto</value>
8898     diff --git a/docs-xml/smbdotconf/security/serverschannel.xml b/docs-xml/smbdotconf/security/serverschannel.xml
8899     index 79e4e73a95c..3e66df1c203 100644
8900     --- a/docs-xml/smbdotconf/security/serverschannel.xml
8901     +++ b/docs-xml/smbdotconf/security/serverschannel.xml
8902     @@ -23,7 +23,7 @@
8903     <para>If you still have legacy domain members use the <smbconfoption name="server require schannel:COMPUTERACCOUNT"/> option.
8904     </para>
8905    
8906     - <para>This option yields precedence to the <smbconfoption name="server require schannel:COMPUTERACCOUNT"/> option.</para>
8907     + <para>This option is over-ridden by the <smbconfoption name="server require schannel:COMPUTERACCOUNT"/> option.</para>
8908    
8909     </description>
8910    
8911     diff --git a/docs-xml/smbdotconf/winbind/requirestrongkey.xml b/docs-xml/smbdotconf/winbind/requirestrongkey.xml
8912     index b17620ec8f1..9c1c1d7af14 100644
8913     --- a/docs-xml/smbdotconf/winbind/requirestrongkey.xml
8914     +++ b/docs-xml/smbdotconf/winbind/requirestrongkey.xml
8915     @@ -17,7 +17,7 @@
8916    
8917     <para>Note for active directory domain this option is hardcoded to 'yes'</para>
8918    
8919     - <para>This option yields precedence to the <smbconfoption name="reject md5 servers"/> option.</para>
8920     + <para>This option is over-ridden by the <smbconfoption name="reject md5 servers"/> option.</para>
8921    
8922     <para>This option overrides the <smbconfoption name="client schannel"/> option.</para>
8923     </description>
8924     --
8925     2.39.0
8926    
8927    
8928     From 976080e72039b68ab66b757f1c3cb258eaca23df Mon Sep 17 00:00:00 2001
8929     From: Stefan Metzmacher <metze@samba.org>
8930     Date: Wed, 30 Nov 2022 14:46:59 +0100
8931     Subject: [PATCH 104/142] CVE-2022-38023 libcli/auth: pass lp_ctx to
8932     netlogon_creds_cli_set_global_db()
8933    
8934     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
8935    
8936     Signed-off-by: Stefan Metzmacher <metze@samba.org>
8937     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
8938     Reviewed-by: Ralph Boehme <slow@samba.org>
8939     (cherry picked from commit 992f39a2c8a58301ceeb965f401e29cd64c5a209)
8940     ---
8941     libcli/auth/netlogon_creds_cli.c | 3 ++-
8942     libcli/auth/netlogon_creds_cli.h | 2 +-
8943     source3/rpc_client/cli_netlogon.c | 2 +-
8944     source3/utils/destroy_netlogon_creds_cli.c | 2 +-
8945     4 files changed, 5 insertions(+), 4 deletions(-)
8946    
8947     diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
8948     index 0f6ca11ff96..c9873a5748e 100644
8949     --- a/libcli/auth/netlogon_creds_cli.c
8950     +++ b/libcli/auth/netlogon_creds_cli.c
8951     @@ -201,7 +201,8 @@ static NTSTATUS netlogon_creds_cli_context_common(
8952    
8953     static struct db_context *netlogon_creds_cli_global_db;
8954    
8955     -NTSTATUS netlogon_creds_cli_set_global_db(struct db_context **db)
8956     +NTSTATUS netlogon_creds_cli_set_global_db(struct loadparm_context *lp_ctx,
8957     + struct db_context **db)
8958     {
8959     if (netlogon_creds_cli_global_db != NULL) {
8960     return NT_STATUS_INVALID_PARAMETER_MIX;
8961     diff --git a/libcli/auth/netlogon_creds_cli.h b/libcli/auth/netlogon_creds_cli.h
8962     index 56a2dd9bc77..2ce5de9d305 100644
8963     --- a/libcli/auth/netlogon_creds_cli.h
8964     +++ b/libcli/auth/netlogon_creds_cli.h
8965     @@ -31,7 +31,7 @@ struct messaging_context;
8966     struct dcerpc_binding_handle;
8967     struct db_context;
8968    
8969     -NTSTATUS netlogon_creds_cli_set_global_db(struct db_context **db);
8970     +NTSTATUS netlogon_creds_cli_set_global_db(struct loadparm_context *lp_ctx, struct db_context **db);
8971     NTSTATUS netlogon_creds_cli_open_global_db(struct loadparm_context *lp_ctx);
8972     void netlogon_creds_cli_close_global_db(void);
8973    
8974     diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
8975     index f073f0d925e..b784064f17e 100644
8976     --- a/source3/rpc_client/cli_netlogon.c
8977     +++ b/source3/rpc_client/cli_netlogon.c
8978     @@ -76,7 +76,7 @@ NTSTATUS rpccli_pre_open_netlogon_creds(void)
8979     return NT_STATUS_NO_MEMORY;
8980     }
8981    
8982     - status = netlogon_creds_cli_set_global_db(&global_db);
8983     + status = netlogon_creds_cli_set_global_db(lp_ctx, &global_db);
8984     TALLOC_FREE(frame);
8985     if (!NT_STATUS_IS_OK(status)) {
8986     return status;
8987     diff --git a/source3/utils/destroy_netlogon_creds_cli.c b/source3/utils/destroy_netlogon_creds_cli.c
8988     index 137ac8393e7..95a650f4654 100644
8989     --- a/source3/utils/destroy_netlogon_creds_cli.c
8990     +++ b/source3/utils/destroy_netlogon_creds_cli.c
8991     @@ -83,7 +83,7 @@ int main(int argc, const char *argv[])
8992     goto done;
8993     }
8994    
8995     - status = netlogon_creds_cli_set_global_db(&global_db);
8996     + status = netlogon_creds_cli_set_global_db(lp_ctx, &global_db);
8997     if (!NT_STATUS_IS_OK(status)) {
8998     fprintf(stderr,
8999     "netlogon_creds_cli_set_global_db failed: %s\n",
9000     --
9001     2.39.0
9002    
9003    
9004     From dfe17c3453980d53445a2cc6221cb8728fc9e3cf Mon Sep 17 00:00:00 2001
9005     From: Stefan Metzmacher <metze@samba.org>
9006     Date: Wed, 30 Nov 2022 14:47:33 +0100
9007     Subject: [PATCH 105/142] CVE-2022-38023 libcli/auth: add/use
9008     netlogon_creds_cli_warn_options()
9009    
9010     This warns the admin about insecure options
9011    
9012     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
9013    
9014     Signed-off-by: Stefan Metzmacher <metze@samba.org>
9015     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
9016     Reviewed-by: Ralph Boehme <slow@samba.org>
9017    
9018     (similar to commit 7e7adf86e59e8a673fbe87de46cef0d62221e800)
9019     [jsutton@samba.org Replaced call to tevent_cached_getpid() with one to
9020     getpid()]
9021     ---
9022     libcli/auth/netlogon_creds_cli.c | 66 ++++++++++++++++++++++++++++++++
9023     libcli/auth/netlogon_creds_cli.h | 2 +
9024     2 files changed, 68 insertions(+)
9025    
9026     diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
9027     index c9873a5748e..20a3da5060f 100644
9028     --- a/libcli/auth/netlogon_creds_cli.c
9029     +++ b/libcli/auth/netlogon_creds_cli.c
9030     @@ -204,6 +204,8 @@ static struct db_context *netlogon_creds_cli_global_db;
9031     NTSTATUS netlogon_creds_cli_set_global_db(struct loadparm_context *lp_ctx,
9032     struct db_context **db)
9033     {
9034     + netlogon_creds_cli_warn_options(lp_ctx);
9035     +
9036     if (netlogon_creds_cli_global_db != NULL) {
9037     return NT_STATUS_INVALID_PARAMETER_MIX;
9038     }
9039     @@ -218,6 +220,8 @@ NTSTATUS netlogon_creds_cli_open_global_db(struct loadparm_context *lp_ctx)
9040     struct db_context *global_db;
9041     int hash_size, tdb_flags;
9042    
9043     + netlogon_creds_cli_warn_options(lp_ctx);
9044     +
9045     if (netlogon_creds_cli_global_db != NULL) {
9046     return NT_STATUS_OK;
9047     }
9048     @@ -258,6 +262,68 @@ void netlogon_creds_cli_close_global_db(void)
9049     TALLOC_FREE(netlogon_creds_cli_global_db);
9050     }
9051    
9052     +void netlogon_creds_cli_warn_options(struct loadparm_context *lp_ctx)
9053     +{
9054     + bool global_reject_md5_servers = lpcfg_reject_md5_servers(lp_ctx);
9055     + bool global_require_strong_key = lpcfg_require_strong_key(lp_ctx);
9056     + int global_client_schannel = lpcfg_client_schannel(lp_ctx);
9057     + bool global_seal_secure_channel = lpcfg_winbind_sealed_pipes(lp_ctx);
9058     + static bool warned_global_reject_md5_servers = false;
9059     + static bool warned_global_require_strong_key = false;
9060     + static bool warned_global_client_schannel = false;
9061     + static bool warned_global_seal_secure_channel = false;
9062     + static int warned_global_pid = 0;
9063     + int current_pid = getpid();
9064     +
9065     + if (warned_global_pid != current_pid) {
9066     + warned_global_reject_md5_servers = false;
9067     + warned_global_require_strong_key = false;
9068     + warned_global_client_schannel = false;
9069     + warned_global_seal_secure_channel = false;
9070     + warned_global_pid = current_pid;
9071     + }
9072     +
9073     + if (!global_reject_md5_servers && !warned_global_reject_md5_servers) {
9074     + /*
9075     + * We want admins to notice their misconfiguration!
9076     + */
9077     + DBG_ERR("CVE-2022-38023 (and others): "
9078     + "Please configure 'reject md5 servers = yes' (the default), "
9079     + "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
9080     + warned_global_reject_md5_servers = true;
9081     + }
9082     +
9083     + if (!global_require_strong_key && !warned_global_require_strong_key) {
9084     + /*
9085     + * We want admins to notice their misconfiguration!
9086     + */
9087     + DBG_ERR("CVE-2022-38023 (and others): "
9088     + "Please configure 'require strong key = yes' (the default), "
9089     + "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
9090     + warned_global_require_strong_key = true;
9091     + }
9092     +
9093     + if (global_client_schannel != true && !warned_global_client_schannel) {
9094     + /*
9095     + * We want admins to notice their misconfiguration!
9096     + */
9097     + DBG_ERR("CVE-2022-38023 (and others): "
9098     + "Please configure 'client schannel = yes' (the default), "
9099     + "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
9100     + warned_global_client_schannel = true;
9101     + }
9102     +
9103     + if (!global_seal_secure_channel && !warned_global_seal_secure_channel) {
9104     + /*
9105     + * We want admins to notice their misconfiguration!
9106     + */
9107     + DBG_ERR("CVE-2022-38023 (and others): "
9108     + "Please configure 'winbind sealed pipes = yes' (the default), "
9109     + "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
9110     + warned_global_seal_secure_channel = true;
9111     + }
9112     +}
9113     +
9114     NTSTATUS netlogon_creds_cli_context_global(struct loadparm_context *lp_ctx,
9115     struct messaging_context *msg_ctx,
9116     const char *client_account,
9117     diff --git a/libcli/auth/netlogon_creds_cli.h b/libcli/auth/netlogon_creds_cli.h
9118     index 2ce5de9d305..e4e0232e92f 100644
9119     --- a/libcli/auth/netlogon_creds_cli.h
9120     +++ b/libcli/auth/netlogon_creds_cli.h
9121     @@ -35,6 +35,8 @@ NTSTATUS netlogon_creds_cli_set_global_db(struct loadparm_context *lp_ctx, struc
9122     NTSTATUS netlogon_creds_cli_open_global_db(struct loadparm_context *lp_ctx);
9123     void netlogon_creds_cli_close_global_db(void);
9124    
9125     +void netlogon_creds_cli_warn_options(struct loadparm_context *lp_ctx);
9126     +
9127     NTSTATUS netlogon_creds_cli_context_global(struct loadparm_context *lp_ctx,
9128     struct messaging_context *msg_ctx,
9129     const char *client_account,
9130     --
9131     2.39.0
9132    
9133    
9134     From 75c44fdccf18bfa34530f05937e8e3305b2c927e Mon Sep 17 00:00:00 2001
9135     From: Stefan Metzmacher <metze@samba.org>
9136     Date: Wed, 30 Nov 2022 16:16:05 +0100
9137     Subject: [PATCH 106/142] CVE-2022-38023 s3:net: add and use
9138     net_warn_member_options() helper
9139    
9140     This makes sure domain member related 'net' commands print warnings
9141     about unsecure smb.conf options.
9142    
9143     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
9144    
9145     Signed-off-by: Stefan Metzmacher <metze@samba.org>
9146     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
9147     Reviewed-by: Ralph Boehme <slow@samba.org>
9148     (cherry picked from commit 1fdf1d55a5dd550bdb16d037b5dc995c33c1a67a)
9149     ---
9150     source3/utils/net.c | 6 ++++++
9151     source3/utils/net_ads.c | 14 ++++++++++++++
9152     source3/utils/net_dom.c | 2 ++
9153     source3/utils/net_join.c | 2 ++
9154     source3/utils/net_proto.h | 2 ++
9155     source3/utils/net_rpc.c | 10 ++++++++++
9156     source3/utils/net_util.c | 15 +++++++++++++++
9157     7 files changed, 51 insertions(+)
9158    
9159     diff --git a/source3/utils/net.c b/source3/utils/net.c
9160     index 8350e8c0967..c17dd972c3f 100644
9161     --- a/source3/utils/net.c
9162     +++ b/source3/utils/net.c
9163     @@ -83,6 +83,8 @@ enum netr_SchannelType get_sec_channel_type(const char *param)
9164    
9165     static int net_changetrustpw(struct net_context *c, int argc, const char **argv)
9166     {
9167     + net_warn_member_options();
9168     +
9169     if (net_ads_check_our_domain(c) == 0)
9170     return net_ads_changetrustpw(c, argc, argv);
9171    
9172     @@ -110,6 +112,8 @@ static int net_primarytrust_dumpinfo(struct net_context *c, int argc,
9173     return 1;
9174     }
9175    
9176     + net_warn_member_options();
9177     +
9178     if (c->opt_stdin) {
9179     set_line_buffering(stdin);
9180     set_line_buffering(stdout);
9181     @@ -185,6 +189,8 @@ static int net_changesecretpw(struct net_context *c, int argc,
9182     return 1;
9183     }
9184    
9185     + net_warn_member_options();
9186     +
9187     if(c->opt_force) {
9188     struct secrets_domain_info1 *info = NULL;
9189     struct secrets_domain_info1_change *prev = NULL;
9190     diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
9191     index 3cf8fbbf7c8..32a7b2d7f7f 100644
9192     --- a/source3/utils/net_ads.c
9193     +++ b/source3/utils/net_ads.c
9194     @@ -1290,6 +1290,8 @@ static int net_ads_status(struct net_context *c, int argc, const char **argv)
9195     return 0;
9196     }
9197    
9198     + net_warn_member_options();
9199     +
9200     if (!ADS_ERR_OK(ads_startup(c, true, &ads))) {
9201     return -1;
9202     }
9203     @@ -1431,6 +1433,8 @@ static NTSTATUS net_ads_join_ok(struct net_context *c)
9204     return NT_STATUS_ACCESS_DENIED;
9205     }
9206    
9207     + net_warn_member_options();
9208     +
9209     net_use_krb_machine_account(c);
9210    
9211     get_dc_name(lp_workgroup(), lp_realm(), dc_name, &dcip);
9212     @@ -1461,6 +1465,8 @@ int net_ads_testjoin(struct net_context *c, int argc, const char **argv)
9213     return 0;
9214     }
9215    
9216     + net_warn_member_options();
9217     +
9218     /* Display success or failure */
9219     status = net_ads_join_ok(c);
9220     if (!NT_STATUS_IS_OK(status)) {
9221     @@ -1846,6 +1852,8 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
9222     if (c->display_usage)
9223     return net_ads_join_usage(c, argc, argv);
9224    
9225     + net_warn_member_options();
9226     +
9227     if (!modify_config) {
9228    
9229     werr = check_ads_config();
9230     @@ -2732,6 +2740,8 @@ int net_ads_changetrustpw(struct net_context *c, int argc, const char **argv)
9231     return -1;
9232     }
9233    
9234     + net_warn_member_options();
9235     +
9236     net_use_krb_machine_account(c);
9237    
9238     use_in_memory_ccache();
9239     @@ -3001,6 +3011,8 @@ static int net_ads_keytab_add(struct net_context *c,
9240     return 0;
9241     }
9242    
9243     + net_warn_member_options();
9244     +
9245     d_printf(_("Processing principals to add...\n"));
9246     if (!ADS_ERR_OK(ads_startup(c, true, &ads))) {
9247     return -1;
9248     @@ -3040,6 +3052,8 @@ static int net_ads_keytab_create(struct net_context *c, int argc, const char **a
9249     return 0;
9250     }
9251    
9252     + net_warn_member_options();
9253     +
9254     if (!ADS_ERR_OK(ads_startup(c, true, &ads))) {
9255     return -1;
9256     }
9257     diff --git a/source3/utils/net_dom.c b/source3/utils/net_dom.c
9258     index 1e45c59220c..db6e34e52de 100644
9259     --- a/source3/utils/net_dom.c
9260     +++ b/source3/utils/net_dom.c
9261     @@ -154,6 +154,8 @@ static int net_dom_join(struct net_context *c, int argc, const char **argv)
9262     return net_dom_usage(c, argc, argv);
9263     }
9264    
9265     + net_warn_member_options();
9266     +
9267     if (c->opt_host) {
9268     server_name = c->opt_host;
9269     }
9270     diff --git a/source3/utils/net_join.c b/source3/utils/net_join.c
9271     index 1493dff74d7..f67f08f79a8 100644
9272     --- a/source3/utils/net_join.c
9273     +++ b/source3/utils/net_join.c
9274     @@ -39,6 +39,8 @@ int net_join(struct net_context *c, int argc, const char **argv)
9275     return 0;
9276     }
9277    
9278     + net_warn_member_options();
9279     +
9280     if (net_ads_check_our_domain(c) == 0) {
9281     if (net_ads_join(c, argc, argv) == 0)
9282     return 0;
9283     diff --git a/source3/utils/net_proto.h b/source3/utils/net_proto.h
9284     index 22fe39e0f1c..38581a796cb 100644
9285     --- a/source3/utils/net_proto.h
9286     +++ b/source3/utils/net_proto.h
9287     @@ -423,6 +423,8 @@ int net_run_function(struct net_context *c, int argc, const char **argv,
9288     const char *whoami, struct functable *table);
9289     void net_display_usage_from_functable(struct functable *table);
9290    
9291     +void net_warn_member_options(void);
9292     +
9293     const char *net_share_type_str(int num_type);
9294    
9295     NTSTATUS net_scan_dc(struct net_context *c,
9296     diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
9297     index f2d63d2af65..52c2ec37a89 100644
9298     --- a/source3/utils/net_rpc.c
9299     +++ b/source3/utils/net_rpc.c
9300     @@ -370,6 +370,8 @@ static int net_rpc_oldjoin(struct net_context *c, int argc, const char **argv)
9301     return 0;
9302     }
9303    
9304     + net_warn_member_options();
9305     +
9306     mem_ctx = talloc_init("net_rpc_oldjoin");
9307     if (!mem_ctx) {
9308     return -1;
9309     @@ -489,6 +491,8 @@ int net_rpc_testjoin(struct net_context *c, int argc, const char **argv)
9310     return 0;
9311     }
9312    
9313     + net_warn_member_options();
9314     +
9315     mem_ctx = talloc_init("net_rpc_testjoin");
9316     if (!mem_ctx) {
9317     return -1;
9318     @@ -563,6 +567,8 @@ static int net_rpc_join_newstyle(struct net_context *c, int argc, const char **a
9319     return 0;
9320     }
9321    
9322     + net_warn_member_options();
9323     +
9324     mem_ctx = talloc_init("net_rpc_join_newstyle");
9325     if (!mem_ctx) {
9326     return -1;
9327     @@ -684,6 +690,8 @@ int net_rpc_join(struct net_context *c, int argc, const char **argv)
9328     return -1;
9329     }
9330    
9331     + net_warn_member_options();
9332     +
9333     if (strlen(lp_netbios_name()) > 15) {
9334     d_printf(_("Our netbios name can be at most 15 chars long, "
9335     "\"%s\" is %u chars long\n"),
9336     @@ -814,6 +822,8 @@ int net_rpc_info(struct net_context *c, int argc, const char **argv)
9337     return 0;
9338     }
9339    
9340     + net_warn_member_options();
9341     +
9342     return run_rpc_command(c, NULL, &ndr_table_samr,
9343     NET_FLAGS_PDC, rpc_info_internals,
9344     argc, argv);
9345     diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c
9346     index a84b4f5500e..94a8dc9defe 100644
9347     --- a/source3/utils/net_util.c
9348     +++ b/source3/utils/net_util.c
9349     @@ -29,6 +29,8 @@
9350     #include "secrets.h"
9351     #include "../libcli/security/security.h"
9352     #include "libsmb/libsmb.h"
9353     +#include "libcli/auth/netlogon_creds_cli.h"
9354     +#include "lib/param/param.h"
9355    
9356     NTSTATUS net_rpc_lookup_name(struct net_context *c,
9357     TALLOC_CTX *mem_ctx, struct cli_state *cli,
9358     @@ -534,6 +536,19 @@ void net_display_usage_from_functable(struct functable *table)
9359     }
9360     }
9361    
9362     +void net_warn_member_options(void)
9363     +{
9364     + TALLOC_CTX *frame = talloc_stackframe();
9365     + struct loadparm_context *lp_ctx = NULL;
9366     +
9367     + lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
9368     + if (lp_ctx != NULL) {
9369     + netlogon_creds_cli_warn_options(lp_ctx);
9370     + }
9371     +
9372     + TALLOC_FREE(frame);
9373     +}
9374     +
9375     const char *net_share_type_str(int num_type)
9376     {
9377     switch(num_type) {
9378     --
9379     2.39.0
9380    
9381    
9382     From 9d7eba489e7f798dd3115439da1bc92a87059ce1 Mon Sep 17 00:00:00 2001
9383     From: Stefan Metzmacher <metze@samba.org>
9384     Date: Wed, 30 Nov 2022 14:59:36 +0100
9385     Subject: [PATCH 107/142] CVE-2022-38023 s3:winbindd: also allow per domain
9386     "winbind sealed pipes:DOMAIN" and "require strong key:DOMAIN"
9387    
9388     This avoids advising insecure defaults for the global options.
9389    
9390     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
9391    
9392     Signed-off-by: Stefan Metzmacher <metze@samba.org>
9393     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
9394     Reviewed-by: Ralph Boehme <slow@samba.org>
9395     (cherry picked from commit d60828f6391307a59abaa02b72b6a8acf66b2fef)
9396     ---
9397     source3/winbindd/winbindd_cm.c | 41 +++++++++++++++++++++++++++-------
9398     1 file changed, 33 insertions(+), 8 deletions(-)
9399    
9400     diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
9401     index 502331f7260..1a8017cf4cc 100644
9402     --- a/source3/winbindd/winbindd_cm.c
9403     +++ b/source3/winbindd/winbindd_cm.c
9404     @@ -2734,6 +2734,8 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
9405     struct netlogon_creds_cli_context *p_creds;
9406     struct cli_credentials *creds = NULL;
9407     bool retry = false; /* allow one retry attempt for expired session */
9408     + bool sealed_pipes = true;
9409     + bool strong_key = true;
9410    
9411     if (sid_check_is_our_sam(&domain->sid)) {
9412     if (domain->rodc == false || need_rw_dc == false) {
9413     @@ -2907,14 +2909,24 @@ retry:
9414    
9415     anonymous:
9416    
9417     + sealed_pipes = lp_winbind_sealed_pipes();
9418     + sealed_pipes = lp_parm_bool(-1, "winbind sealed pipes",
9419     + domain->name,
9420     + sealed_pipes);
9421     + strong_key = lp_require_strong_key();
9422     + strong_key = lp_parm_bool(-1, "require strong key",
9423     + domain->name,
9424     + strong_key);
9425     +
9426     /* Finally fall back to anonymous. */
9427     - if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
9428     + if (sealed_pipes || strong_key) {
9429     status = NT_STATUS_DOWNGRADE_DETECTED;
9430     DEBUG(1, ("Unwilling to make SAMR connection to domain %s "
9431     "without connection level security, "
9432     - "must set 'winbind sealed pipes = false' and "
9433     - "'require strong key = false' to proceed: %s\n",
9434     - domain->name, nt_errstr(status)));
9435     + "must set 'winbind sealed pipes:%s = false' and "
9436     + "'require strong key:%s = false' to proceed: %s\n",
9437     + domain->name, domain->name, domain->name,
9438     + nt_errstr(status)));
9439     goto done;
9440     }
9441     status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr,
9442     @@ -3061,6 +3073,8 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
9443     struct netlogon_creds_cli_context *p_creds;
9444     struct cli_credentials *creds = NULL;
9445     bool retry = false; /* allow one retry attempt for expired session */
9446     + bool sealed_pipes = true;
9447     + bool strong_key = true;
9448    
9449     retry:
9450     result = init_dc_connection_rpc(domain, false);
9451     @@ -3216,13 +3230,24 @@ retry:
9452     goto done;
9453     }
9454    
9455     - if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
9456     + sealed_pipes = lp_winbind_sealed_pipes();
9457     + sealed_pipes = lp_parm_bool(-1, "winbind sealed pipes",
9458     + domain->name,
9459     + sealed_pipes);
9460     + strong_key = lp_require_strong_key();
9461     + strong_key = lp_parm_bool(-1, "require strong key",
9462     + domain->name,
9463     + strong_key);
9464     +
9465     + /* Finally fall back to anonymous. */
9466     + if (sealed_pipes || strong_key) {
9467     result = NT_STATUS_DOWNGRADE_DETECTED;
9468     DEBUG(1, ("Unwilling to make LSA connection to domain %s "
9469     "without connection level security, "
9470     - "must set 'winbind sealed pipes = false' and "
9471     - "'require strong key = false' to proceed: %s\n",
9472     - domain->name, nt_errstr(result)));
9473     + "must set 'winbind sealed pipes:%s = false' and "
9474     + "'require strong key:%s = false' to proceed: %s\n",
9475     + domain->name, domain->name, domain->name,
9476     + nt_errstr(result)));
9477     goto done;
9478     }
9479    
9480     --
9481     2.39.0
9482    
9483    
9484     From b310b2672f80a717188675b6c762d184436a190c Mon Sep 17 00:00:00 2001
9485     From: Stefan Metzmacher <metze@samba.org>
9486     Date: Thu, 24 Nov 2022 18:22:23 +0100
9487     Subject: [PATCH 108/142] CVE-2022-38023 docs-xml/smbdotconf: change 'reject
9488     md5 servers' default to yes
9489    
9490     AES is supported by Windows >= 2008R2 and Samba >= 4.0 so there's no
9491     reason to allow md5 servers by default.
9492    
9493     Note the change in netlogon_creds_cli_context_global() is only cosmetic,
9494     but avoids confusion while reading the code. Check with:
9495    
9496     git show -U35 libcli/auth/netlogon_creds_cli.c
9497    
9498     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
9499    
9500     Signed-off-by: Stefan Metzmacher <metze@samba.org>
9501     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
9502     Reviewed-by: Ralph Boehme <slow@samba.org>
9503     (cherry picked from commit 1c6c1129905d0c7a60018e7bf0f17a0fd198a584)
9504     ---
9505     docs-xml/smbdotconf/winbind/rejectmd5servers.xml | 7 +++++--
9506     lib/param/loadparm.c | 1 +
9507     libcli/auth/netlogon_creds_cli.c | 4 ++--
9508     source3/param/loadparm.c | 1 +
9509     4 files changed, 9 insertions(+), 4 deletions(-)
9510    
9511     diff --git a/docs-xml/smbdotconf/winbind/rejectmd5servers.xml b/docs-xml/smbdotconf/winbind/rejectmd5servers.xml
9512     index 151b4676c57..3bc4eaf7b02 100644
9513     --- a/docs-xml/smbdotconf/winbind/rejectmd5servers.xml
9514     +++ b/docs-xml/smbdotconf/winbind/rejectmd5servers.xml
9515     @@ -13,10 +13,13 @@
9516     This will prevent downgrade attacks.</para>
9517    
9518     <para>The behavior can be controlled per netbios domain
9519     - by using 'reject md5 servers:NETBIOSDOMAIN = yes' as option.</para>
9520     + by using 'reject md5 servers:NETBIOSDOMAIN = no' as option.</para>
9521     +
9522     + <para>The default changed from 'no' to 'yes, with the patches for CVE-2022-38023,
9523     + see https://bugzilla.samba.org/show_bug.cgi?id=15240</para>
9524    
9525     <para>This option overrides the <smbconfoption name="require strong key"/> option.</para>
9526     </description>
9527    
9528     -<value type="default">no</value>
9529     +<value type="default">yes</value>
9530     </samba:parameter>
9531     diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
9532     index 4aa91f4d404..dc659a449ea 100644
9533     --- a/lib/param/loadparm.c
9534     +++ b/lib/param/loadparm.c
9535     @@ -2733,6 +2733,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
9536     lpcfg_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
9537     lpcfg_do_global_parameter(lp_ctx, "winbind scan trusted domains", "True");
9538     lpcfg_do_global_parameter(lp_ctx, "require strong key", "True");
9539     + lpcfg_do_global_parameter(lp_ctx, "reject md5 servers", "True");
9540     lpcfg_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
9541     lpcfg_do_global_parameter(lp_ctx, "ntp signd socket directory", dyn_NTP_SIGND_SOCKET_DIR);
9542     lpcfg_do_global_parameter_var(lp_ctx, "gpo update command", "%s/samba-gpupdate", dyn_SCRIPTSBINDIR);
9543     diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
9544     index 20a3da5060f..0558cb237a4 100644
9545     --- a/libcli/auth/netlogon_creds_cli.c
9546     +++ b/libcli/auth/netlogon_creds_cli.c
9547     @@ -340,8 +340,8 @@ NTSTATUS netlogon_creds_cli_context_global(struct loadparm_context *lp_ctx,
9548     const char *client_computer;
9549     uint32_t proposed_flags;
9550     uint32_t required_flags = 0;
9551     - bool reject_md5_servers = false;
9552     - bool require_strong_key = false;
9553     + bool reject_md5_servers = true;
9554     + bool require_strong_key = true;
9555     int require_sign_or_seal = true;
9556     bool seal_secure_channel = true;
9557     enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
9558     diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
9559     index 98e05d13d59..fbc987e119a 100644
9560     --- a/source3/param/loadparm.c
9561     +++ b/source3/param/loadparm.c
9562     @@ -657,6 +657,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
9563     Globals.client_schannel = true;
9564     Globals.winbind_sealed_pipes = true;
9565     Globals.require_strong_key = true;
9566     + Globals.reject_md5_servers = true;
9567     Globals.server_schannel = true;
9568     Globals.read_raw = true;
9569     Globals.write_raw = true;
9570     --
9571     2.39.0
9572    
9573    
9574     From b62fb90dd434c99131086f27cb74cf2c109fb9d2 Mon Sep 17 00:00:00 2001
9575     From: Stefan Metzmacher <metze@samba.org>
9576     Date: Tue, 6 Dec 2022 10:56:29 +0100
9577     Subject: [PATCH 109/142] CVE-2022-38023 s4:rpc_server/netlogon: 'server
9578     schannel != yes' warning to dcesrv_interface_netlogon_bind
9579    
9580     This will simplify the following changes.
9581    
9582     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
9583    
9584     Signed-off-by: Stefan Metzmacher <metze@samba.org>
9585     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
9586     Reviewed-by: Ralph Boehme <slow@samba.org>
9587     (cherry picked from commit e060ea5b3edbe3cba492062c9605f88fae212ee0)
9588     ---
9589     source4/rpc_server/netlogon/dcerpc_netlogon.c | 26 +++++++++++--------
9590     1 file changed, 15 insertions(+), 11 deletions(-)
9591    
9592     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
9593     index 7668a9eb923..e7f8cd5c075 100644
9594     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
9595     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
9596     @@ -60,6 +60,21 @@
9597     static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_connection_context *context,
9598     const struct dcesrv_interface *iface)
9599     {
9600     + struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
9601     + int schannel = lpcfg_server_schannel(lp_ctx);
9602     + bool schannel_global_required = (schannel == true);
9603     + static bool warned_global_schannel_once = false;
9604     +
9605     + if (!schannel_global_required && !warned_global_schannel_once) {
9606     + /*
9607     + * We want admins to notice their misconfiguration!
9608     + */
9609     + D_ERR("CVE-2020-1472(ZeroLogon): "
9610     + "Please configure 'server schannel = yes' (the default), "
9611     + "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n");
9612     + warned_global_schannel_once = true;
9613     + }
9614     +
9615     return dcesrv_interface_bind_reject_connect(context, iface);
9616     }
9617    
9618     @@ -629,7 +644,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9619     enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
9620     uint16_t opnum = dce_call->pkt.u.request.opnum;
9621     const char *opname = "<unknown>";
9622     - static bool warned_global_once = false;
9623    
9624     if (opnum < ndr_table_netlogon.num_calls) {
9625     opname = ndr_table_netlogon.calls[opnum].name;
9626     @@ -681,16 +695,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9627     return NT_STATUS_ACCESS_DENIED;
9628     }
9629    
9630     - if (!schannel_global_required && !warned_global_once) {
9631     - /*
9632     - * We want admins to notice their misconfiguration!
9633     - */
9634     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
9635     - "Please configure 'server schannel = yes', "
9636     - "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n");
9637     - warned_global_once = true;
9638     - }
9639     -
9640     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
9641     DBG_ERR("CVE-2020-1472(ZeroLogon): "
9642     "%s request (opnum[%u]) WITH schannel from "
9643     --
9644     2.39.0
9645    
9646    
9647     From dbddee016499bddab42870226eda0b19facca936 Mon Sep 17 00:00:00 2001
9648     From: Stefan Metzmacher <metze@samba.org>
9649     Date: Mon, 12 Dec 2022 14:03:50 +0100
9650     Subject: [PATCH 110/142] CVE-2022-38023 s4:rpc_server/netlogon: add a lp_ctx
9651     variable to dcesrv_netr_creds_server_step_check()
9652    
9653     This will simplify the following changes.
9654    
9655     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
9656    
9657     Signed-off-by: Stefan Metzmacher <metze@samba.org>
9658     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
9659     Reviewed-by: Ralph Boehme <slow@samba.org>
9660     (cherry picked from commit 7baabbe9819cd5a2714e7ea4e57a0c23062c0150)
9661     ---
9662     source4/rpc_server/netlogon/dcerpc_netlogon.c | 7 ++++---
9663     1 file changed, 4 insertions(+), 3 deletions(-)
9664    
9665     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
9666     index e7f8cd5c075..bd3a36e60cc 100644
9667     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
9668     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
9669     @@ -635,8 +635,9 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9670     struct netr_Authenticator *return_authenticator,
9671     struct netlogon_creds_CredentialState **creds_out)
9672     {
9673     + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
9674     NTSTATUS nt_status;
9675     - int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx);
9676     + int schannel = lpcfg_server_schannel(lp_ctx);
9677     bool schannel_global_required = (schannel == true);
9678     bool schannel_required = schannel_global_required;
9679     const char *explicit_opt = NULL;
9680     @@ -652,7 +653,7 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9681     dcesrv_call_auth_info(dce_call, &auth_type, NULL);
9682    
9683     nt_status = schannel_check_creds_state(mem_ctx,
9684     - dce_call->conn->dce_ctx->lp_ctx,
9685     + lp_ctx,
9686     computer_name,
9687     received_authenticator,
9688     return_authenticator,
9689     @@ -667,7 +668,7 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9690     * need the explicit_opt pointer in order to
9691     * adjust the debug messages.
9692     */
9693     - explicit_opt = lpcfg_get_parametric(dce_call->conn->dce_ctx->lp_ctx,
9694     + explicit_opt = lpcfg_get_parametric(lp_ctx,
9695     NULL,
9696     "server require schannel",
9697     creds->account_name);
9698     --
9699     2.39.0
9700    
9701    
9702     From da1c4d9055c0b7fcb5e6952e3e63c7089b2b0432 Mon Sep 17 00:00:00 2001
9703     From: Stefan Metzmacher <metze@samba.org>
9704     Date: Mon, 12 Dec 2022 14:03:50 +0100
9705     Subject: [PATCH 111/142] CVE-2022-38023 s4:rpc_server/netlogon: add
9706     talloc_stackframe() to dcesrv_netr_creds_server_step_check()
9707    
9708     This will simplify the following changes.
9709    
9710     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
9711    
9712     Signed-off-by: Stefan Metzmacher <metze@samba.org>
9713     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
9714     Reviewed-by: Ralph Boehme <slow@samba.org>
9715     (cherry picked from commit 0e6a2ba83ef1be3c6a0f5514c21395121621a145)
9716     ---
9717     source4/rpc_server/netlogon/dcerpc_netlogon.c | 32 +++++++++++--------
9718     1 file changed, 19 insertions(+), 13 deletions(-)
9719    
9720     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
9721     index bd3a36e60cc..b842fa6a556 100644
9722     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
9723     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
9724     @@ -636,6 +636,7 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9725     struct netlogon_creds_CredentialState **creds_out)
9726     {
9727     struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
9728     + TALLOC_CTX *frame = talloc_stackframe();
9729     NTSTATUS nt_status;
9730     int schannel = lpcfg_server_schannel(lp_ctx);
9731     bool schannel_global_required = (schannel == true);
9732     @@ -679,6 +680,7 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9733     if (schannel_required) {
9734     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
9735     *creds_out = creds;
9736     + TALLOC_FREE(frame);
9737     return NT_STATUS_OK;
9738     }
9739    
9740     @@ -686,13 +688,15 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9741     "%s request (opnum[%u]) without schannel from "
9742     "client_account[%s] client_computer_name[%s]\n",
9743     opname, opnum,
9744     - log_escape(mem_ctx, creds->account_name),
9745     - log_escape(mem_ctx, creds->computer_name));
9746     + log_escape(frame, creds->account_name),
9747     + log_escape(frame, creds->computer_name));
9748     DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
9749     - "'server require schannel:%s = no' is needed! \n",
9750     - log_escape(mem_ctx, creds->account_name));
9751     + "'server require schannel:%s = no' "
9752     + "might be needed for a legacy client.\n",
9753     + log_escape(frame, creds->account_name));
9754     TALLOC_FREE(creds);
9755     ZERO_STRUCTP(return_authenticator);
9756     + TALLOC_FREE(frame);
9757     return NT_STATUS_ACCESS_DENIED;
9758     }
9759    
9760     @@ -701,13 +705,14 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9761     "%s request (opnum[%u]) WITH schannel from "
9762     "client_account[%s] client_computer_name[%s]\n",
9763     opname, opnum,
9764     - log_escape(mem_ctx, creds->account_name),
9765     - log_escape(mem_ctx, creds->computer_name));
9766     + log_escape(frame, creds->account_name),
9767     + log_escape(frame, creds->computer_name));
9768     DBG_ERR("CVE-2020-1472(ZeroLogon): "
9769     "Option 'server require schannel:%s = no' not needed!?\n",
9770     - log_escape(mem_ctx, creds->account_name));
9771     + log_escape(frame, creds->account_name));
9772    
9773     *creds_out = creds;
9774     + TALLOC_FREE(frame);
9775     return NT_STATUS_OK;
9776     }
9777    
9778     @@ -717,24 +722,25 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9779     "%s request (opnum[%u]) without schannel from "
9780     "client_account[%s] client_computer_name[%s]\n",
9781     opname, opnum,
9782     - log_escape(mem_ctx, creds->account_name),
9783     - log_escape(mem_ctx, creds->computer_name));
9784     + log_escape(frame, creds->account_name),
9785     + log_escape(frame, creds->computer_name));
9786     DBG_INFO("CVE-2020-1472(ZeroLogon): "
9787     "Option 'server require schannel:%s = no' still needed!\n",
9788     - log_escape(mem_ctx, creds->account_name));
9789     + log_escape(frame, creds->account_name));
9790     } else {
9791     DBG_ERR("CVE-2020-1472(ZeroLogon): "
9792     "%s request (opnum[%u]) without schannel from "
9793     "client_account[%s] client_computer_name[%s]\n",
9794     opname, opnum,
9795     - log_escape(mem_ctx, creds->account_name),
9796     - log_escape(mem_ctx, creds->computer_name));
9797     + log_escape(frame, creds->account_name),
9798     + log_escape(frame, creds->computer_name));
9799     DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
9800     "'server require schannel:%s = no' might be needed!\n",
9801     - log_escape(mem_ctx, creds->account_name));
9802     + log_escape(frame, creds->account_name));
9803     }
9804    
9805     *creds_out = creds;
9806     + TALLOC_FREE(frame);
9807     return NT_STATUS_OK;
9808     }
9809    
9810     --
9811     2.39.0
9812    
9813    
9814     From 01d4d64eaca505da9c542f2149c0bd362ad180d1 Mon Sep 17 00:00:00 2001
9815     From: Stefan Metzmacher <metze@samba.org>
9816     Date: Wed, 30 Nov 2022 12:37:03 +0100
9817     Subject: [PATCH 112/142] CVE-2022-38023 s4:rpc_server/netlogon: re-order
9818     checking in dcesrv_netr_creds_server_step_check()
9819    
9820     This will simplify the following changes.
9821    
9822     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
9823    
9824     Signed-off-by: Stefan Metzmacher <metze@samba.org>
9825     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
9826     Reviewed-by: Ralph Boehme <slow@samba.org>
9827     (cherry picked from commit ec62151a2fb49ecbeaa3bf924f49a956832b735e)
9828     ---
9829     source4/rpc_server/netlogon/dcerpc_netlogon.c | 41 +++++++++----------
9830     1 file changed, 19 insertions(+), 22 deletions(-)
9831    
9832     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
9833     index b842fa6a556..9b3a933abca 100644
9834     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
9835     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
9836     @@ -677,13 +677,27 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9837     schannel_required = lp_bool(explicit_opt);
9838     }
9839    
9840     - if (schannel_required) {
9841     - if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
9842     - *creds_out = creds;
9843     - TALLOC_FREE(frame);
9844     - return NT_STATUS_OK;
9845     + if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
9846     + if (!schannel_required) {
9847     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
9848     + "%s request (opnum[%u]) WITH schannel from "
9849     + "client_account[%s] client_computer_name[%s]\n",
9850     + opname, opnum,
9851     + log_escape(frame, creds->account_name),
9852     + log_escape(frame, creds->computer_name));
9853     + }
9854     + if (explicit_opt != NULL && !schannel_required) {
9855     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
9856     + "Option 'server require schannel:%s = no' not needed!?\n",
9857     + log_escape(frame, creds->account_name));
9858     }
9859    
9860     + *creds_out = creds;
9861     + TALLOC_FREE(frame);
9862     + return NT_STATUS_OK;
9863     + }
9864     +
9865     + if (schannel_required) {
9866     DBG_ERR("CVE-2020-1472(ZeroLogon): "
9867     "%s request (opnum[%u]) without schannel from "
9868     "client_account[%s] client_computer_name[%s]\n",
9869     @@ -700,23 +714,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9870     return NT_STATUS_ACCESS_DENIED;
9871     }
9872    
9873     - if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
9874     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
9875     - "%s request (opnum[%u]) WITH schannel from "
9876     - "client_account[%s] client_computer_name[%s]\n",
9877     - opname, opnum,
9878     - log_escape(frame, creds->account_name),
9879     - log_escape(frame, creds->computer_name));
9880     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
9881     - "Option 'server require schannel:%s = no' not needed!?\n",
9882     - log_escape(frame, creds->account_name));
9883     -
9884     - *creds_out = creds;
9885     - TALLOC_FREE(frame);
9886     - return NT_STATUS_OK;
9887     - }
9888     -
9889     -
9890     if (explicit_opt != NULL) {
9891     DBG_INFO("CVE-2020-1472(ZeroLogon): "
9892     "%s request (opnum[%u]) without schannel from "
9893     --
9894     2.39.0
9895    
9896    
9897     From 90531a4cb89b0d390261de1920f17a8ea7a9cbcb Mon Sep 17 00:00:00 2001
9898     From: Stefan Metzmacher <metze@samba.org>
9899     Date: Wed, 30 Nov 2022 12:37:03 +0100
9900     Subject: [PATCH 113/142] CVE-2022-38023 s4:rpc_server/netlogon: improve
9901     CVE-2020-1472(ZeroLogon) debug messages
9902    
9903     In order to avoid generating useless debug messages during make test,
9904     we will use 'CVE_2020_1472:warn_about_unused_debug_level = 3'
9905     and 'CVE_2020_1472:error_debug_level = 2' in order to avoid schannel warnings.
9906    
9907     Review with: git show -w
9908    
9909     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
9910    
9911     Signed-off-by: Stefan Metzmacher <metze@samba.org>
9912     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
9913     Reviewed-by: Ralph Boehme <slow@samba.org>
9914     (cherry picked from commit 16ee03efc194d9c1c2c746f63236b977a419918d)
9915     ---
9916     source4/rpc_server/netlogon/dcerpc_netlogon.c | 147 +++++++++++++-----
9917     1 file changed, 106 insertions(+), 41 deletions(-)
9918    
9919     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
9920     index 9b3a933abca..8084061aabc 100644
9921     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
9922     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
9923     @@ -643,15 +643,34 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9924     bool schannel_required = schannel_global_required;
9925     const char *explicit_opt = NULL;
9926     struct netlogon_creds_CredentialState *creds = NULL;
9927     + int CVE_2020_1472_warn_level = lpcfg_parm_int(lp_ctx, NULL,
9928     + "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
9929     + int CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
9930     + "CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
9931     + unsigned int dbg_lvl = DBGLVL_DEBUG;
9932     enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
9933     + enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
9934     uint16_t opnum = dce_call->pkt.u.request.opnum;
9935     const char *opname = "<unknown>";
9936     + const char *reason = "<unknown>";
9937    
9938     if (opnum < ndr_table_netlogon.num_calls) {
9939     opname = ndr_table_netlogon.calls[opnum].name;
9940     }
9941    
9942     - dcesrv_call_auth_info(dce_call, &auth_type, NULL);
9943     + dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
9944     +
9945     + if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
9946     + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
9947     + reason = "WITH SEALED";
9948     + } else if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
9949     + reason = "WITH SIGNED";
9950     + } else {
9951     + smb_panic("Schannel without SIGN/SEAL");
9952     + }
9953     + } else {
9954     + reason = "WITHOUT";
9955     + }
9956    
9957     nt_status = schannel_check_creds_state(mem_ctx,
9958     lp_ctx,
9959     @@ -678,62 +697,108 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
9960     }
9961    
9962     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
9963     - if (!schannel_required) {
9964     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
9965     - "%s request (opnum[%u]) WITH schannel from "
9966     - "client_account[%s] client_computer_name[%s]\n",
9967     - opname, opnum,
9968     - log_escape(frame, creds->account_name),
9969     - log_escape(frame, creds->computer_name));
9970     + nt_status = NT_STATUS_OK;
9971     +
9972     + if (explicit_opt != NULL && !schannel_required) {
9973     + dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
9974     + } else if (!schannel_required) {
9975     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
9976     }
9977     +
9978     + DEBUG(dbg_lvl, (
9979     + "CVE-2020-1472(ZeroLogon): "
9980     + "%s request (opnum[%u]) %s schannel from "
9981     + "client_account[%s] client_computer_name[%s] %s\n",
9982     + opname, opnum, reason,
9983     + log_escape(frame, creds->account_name),
9984     + log_escape(frame, creds->computer_name),
9985     + nt_errstr(nt_status)));
9986     +
9987     if (explicit_opt != NULL && !schannel_required) {
9988     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
9989     - "Option 'server require schannel:%s = no' not needed!?\n",
9990     - log_escape(frame, creds->account_name));
9991     + DEBUG(CVE_2020_1472_warn_level, (
9992     + "CVE-2020-1472(ZeroLogon): "
9993     + "Option 'server require schannel:%s = no' not needed for '%s'!\n",
9994     + log_escape(frame, creds->account_name),
9995     + log_escape(frame, creds->computer_name)));
9996     }
9997    
9998     *creds_out = creds;
9999     TALLOC_FREE(frame);
10000     - return NT_STATUS_OK;
10001     + return nt_status;
10002     }
10003    
10004     if (schannel_required) {
10005     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
10006     - "%s request (opnum[%u]) without schannel from "
10007     - "client_account[%s] client_computer_name[%s]\n",
10008     - opname, opnum,
10009     - log_escape(frame, creds->account_name),
10010     - log_escape(frame, creds->computer_name));
10011     - DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
10012     - "'server require schannel:%s = no' "
10013     - "might be needed for a legacy client.\n",
10014     - log_escape(frame, creds->account_name));
10015     + nt_status = NT_STATUS_ACCESS_DENIED;
10016     +
10017     + if (explicit_opt != NULL) {
10018     + dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
10019     + } else {
10020     + dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
10021     + }
10022     +
10023     + DEBUG(dbg_lvl, (
10024     + "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
10025     + "%s request (opnum[%u]) %s schannel from "
10026     + "client_account[%s] client_computer_name[%s] %s\n",
10027     + opname, opnum, reason,
10028     + log_escape(frame, creds->account_name),
10029     + log_escape(frame, creds->computer_name),
10030     + nt_errstr(nt_status)));
10031     + if (explicit_opt != NULL) {
10032     + D_NOTICE("CVE-2020-1472(ZeroLogon): Option "
10033     + "'server require schannel:%s = yes' "
10034     + "rejects access for client.\n",
10035     + log_escape(frame, creds->account_name));
10036     + } else {
10037     + DEBUG(CVE_2020_1472_error_level, (
10038     + "CVE-2020-1472(ZeroLogon): Check if option "
10039     + "'server require schannel:%s = no' "
10040     + "might be needed for a legacy client.\n",
10041     + log_escape(frame, creds->account_name)));
10042     + }
10043     TALLOC_FREE(creds);
10044     ZERO_STRUCTP(return_authenticator);
10045     TALLOC_FREE(frame);
10046     - return NT_STATUS_ACCESS_DENIED;
10047     + return nt_status;
10048     }
10049    
10050     + nt_status = NT_STATUS_OK;
10051     +
10052     if (explicit_opt != NULL) {
10053     - DBG_INFO("CVE-2020-1472(ZeroLogon): "
10054     - "%s request (opnum[%u]) without schannel from "
10055     - "client_account[%s] client_computer_name[%s]\n",
10056     - opname, opnum,
10057     - log_escape(frame, creds->account_name),
10058     - log_escape(frame, creds->computer_name));
10059     - DBG_INFO("CVE-2020-1472(ZeroLogon): "
10060     - "Option 'server require schannel:%s = no' still needed!\n",
10061     - log_escape(frame, creds->account_name));
10062     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
10063     } else {
10064     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
10065     - "%s request (opnum[%u]) without schannel from "
10066     - "client_account[%s] client_computer_name[%s]\n",
10067     - opname, opnum,
10068     - log_escape(frame, creds->account_name),
10069     - log_escape(frame, creds->computer_name));
10070     - DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
10071     - "'server require schannel:%s = no' might be needed!\n",
10072     - log_escape(frame, creds->account_name));
10073     + dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
10074     + }
10075     +
10076     + DEBUG(dbg_lvl, (
10077     + "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
10078     + "%s request (opnum[%u]) %s schannel from "
10079     + "client_account[%s] client_computer_name[%s] %s\n",
10080     + opname, opnum, reason,
10081     + log_escape(frame, creds->account_name),
10082     + log_escape(frame, creds->computer_name),
10083     + nt_errstr(nt_status)));
10084     +
10085     + if (explicit_opt != NULL) {
10086     + D_INFO("CVE-2020-1472(ZeroLogon): Option "
10087     + "'server require schannel:%s = no' "
10088     + "still needed for '%s'!\n",
10089     + log_escape(frame, creds->account_name),
10090     + log_escape(frame, creds->computer_name));
10091     + } else {
10092     + /*
10093     + * admins should set
10094     + * server require schannel:COMPUTER$ = no
10095     + * in order to avoid the level 0 messages.
10096     + * Over time they can switch the global value
10097     + * to be strict.
10098     + */
10099     + DEBUG(CVE_2020_1472_error_level, (
10100     + "CVE-2020-1472(ZeroLogon): "
10101     + "Please use 'server require schannel:%s = no' "
10102     + "for '%s' to avoid this warning!\n",
10103     + log_escape(frame, creds->account_name),
10104     + log_escape(frame, creds->computer_name)));
10105     }
10106    
10107     *creds_out = creds;
10108     --
10109     2.39.0
10110    
10111    
10112     From 2ea49737a5cac8ead895da30d40f18019103b285 Mon Sep 17 00:00:00 2001
10113     From: Stefan Metzmacher <metze@samba.org>
10114     Date: Wed, 30 Nov 2022 12:26:01 +0100
10115     Subject: [PATCH 114/142] CVE-2022-38023 selftest:Samba4: avoid global 'server
10116     schannel = auto'
10117    
10118     Instead of using the generic deprecated option use the specific
10119     server require schannel:COMPUTERACCOUNT = no in order to allow
10120     legacy tests for pass.
10121    
10122     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
10123    
10124     Signed-off-by: Stefan Metzmacher <metze@samba.org>
10125     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
10126     Reviewed-by: Ralph Boehme <slow@samba.org>
10127     (cherry picked from commit 63c96ea6c02981795e67336401143f2a8836992c)
10128     ---
10129     selftest/target/Samba4.pm | 37 ++++++++++++++++++++++++++++++++++---
10130     1 file changed, 34 insertions(+), 3 deletions(-)
10131    
10132     diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
10133     index 0f644661176..8dad74cae43 100755
10134     --- a/selftest/target/Samba4.pm
10135     +++ b/selftest/target/Samba4.pm
10136     @@ -1708,7 +1708,24 @@ sub provision_ad_dc_ntvfs($$)
10137     dsdb event notification = true
10138     dsdb password event notification = true
10139     dsdb group change notification = true
10140     - server schannel = auto
10141     +
10142     + CVE_2020_1472:warn_about_unused_debug_level = 3
10143     + server require schannel:schannel0\$ = no
10144     + server require schannel:schannel1\$ = no
10145     + server require schannel:schannel2\$ = no
10146     + server require schannel:schannel3\$ = no
10147     + server require schannel:schannel4\$ = no
10148     + server require schannel:schannel5\$ = no
10149     + server require schannel:schannel6\$ = no
10150     + server require schannel:schannel7\$ = no
10151     + server require schannel:schannel8\$ = no
10152     + server require schannel:schannel9\$ = no
10153     + server require schannel:schannel10\$ = no
10154     + server require schannel:schannel11\$ = no
10155     + server require schannel:torturetest\$ = no
10156     +
10157     + # needed for 'samba.tests.auth_log' tests
10158     + server require schannel:LOCALDC\$ = no
10159     ";
10160     my $extra_provision_options = ["--use-ntvfs"];
10161     my $ret = $self->provision($prefix,
10162     @@ -2085,8 +2102,22 @@ sub provision_ad_dc($$$$$$)
10163     lpq cache time = 0
10164     print notify backchannel = yes
10165    
10166     - server schannel = auto
10167     - auth event notification = true
10168     + CVE_2020_1472:warn_about_unused_debug_level = 3
10169     + server require schannel:schannel0\$ = no
10170     + server require schannel:schannel1\$ = no
10171     + server require schannel:schannel2\$ = no
10172     + server require schannel:schannel3\$ = no
10173     + server require schannel:schannel4\$ = no
10174     + server require schannel:schannel5\$ = no
10175     + server require schannel:schannel6\$ = no
10176     + server require schannel:schannel7\$ = no
10177     + server require schannel:schannel8\$ = no
10178     + server require schannel:schannel9\$ = no
10179     + server require schannel:schannel10\$ = no
10180     + server require schannel:schannel11\$ = no
10181     + server require schannel:torturetest\$ = no
10182     +
10183     + auth event notification = true
10184     dsdb event notification = true
10185     dsdb password event notification = true
10186     dsdb group change notification = true
10187     --
10188     2.39.0
10189    
10190    
10191     From a9ad04a6a886c4f17120fcf585bba7b979752d3c Mon Sep 17 00:00:00 2001
10192     From: Stefan Metzmacher <metze@samba.org>
10193     Date: Mon, 28 Nov 2022 15:02:13 +0100
10194     Subject: [PATCH 115/142] CVE-2022-38023 s4:torture: use
10195     NETLOGON_NEG_SUPPORTS_AES by default
10196    
10197     For generic tests we should use the best available features.
10198    
10199     And AES will be required by default soon.
10200    
10201     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
10202    
10203     Signed-off-by: Stefan Metzmacher <metze@samba.org>
10204     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
10205     Reviewed-by: Ralph Boehme <slow@samba.org>
10206     (cherry picked from commit cfd55a22cda113fbb2bfa373b54091dde1ea6e66)
10207     ---
10208     source4/torture/ntp/ntp_signd.c | 2 +-
10209     source4/torture/rpc/lsa.c | 4 ++--
10210     source4/torture/rpc/netlogon.c | 18 +++++++++---------
10211     source4/torture/rpc/samba3rpc.c | 15 ++++++++++++---
10212     4 files changed, 24 insertions(+), 15 deletions(-)
10213    
10214     diff --git a/source4/torture/ntp/ntp_signd.c b/source4/torture/ntp/ntp_signd.c
10215     index d2a41819fcf..66f2b8956a2 100644
10216     --- a/source4/torture/ntp/ntp_signd.c
10217     +++ b/source4/torture/ntp/ntp_signd.c
10218     @@ -68,7 +68,7 @@ static bool test_ntp_signd(struct torture_context *tctx,
10219     uint32_t rid;
10220     const char *machine_name;
10221     const struct samr_Password *pwhash = cli_credentials_get_nt_hash(credentials, mem_ctx);
10222     - uint32_t negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
10223     + uint32_t negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
10224    
10225     struct sign_request sign_req;
10226     struct signed_reply signed_reply;
10227     diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c
10228     index 7bdc0cf679a..52e220ce225 100644
10229     --- a/source4/torture/rpc/lsa.c
10230     +++ b/source4/torture/rpc/lsa.c
10231     @@ -4260,7 +4260,7 @@ static bool check_dom_trust_pw(struct dcerpc_pipe *p,
10232     torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
10233    
10234     ok = check_pw_with_ServerAuthenticate3(p1, tctx,
10235     - NETLOGON_NEG_AUTH2_ADS_FLAGS,
10236     + NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
10237     server_name,
10238     incoming_creds, &creds);
10239     torture_assert_int_equal(tctx, ok, expected_result,
10240     @@ -4357,7 +4357,7 @@ static bool check_dom_trust_pw(struct dcerpc_pipe *p,
10241     torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
10242    
10243     ok = check_pw_with_ServerAuthenticate3(p2, tctx,
10244     - NETLOGON_NEG_AUTH2_ADS_FLAGS,
10245     + NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
10246     server_name,
10247     incoming_creds, &creds);
10248     torture_assert(tctx, ok, "check_pw_with_ServerAuthenticate3 with changed password");
10249     diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
10250     index 97c16688bc9..1fceeae88cc 100644
10251     --- a/source4/torture/rpc/netlogon.c
10252     +++ b/source4/torture/rpc/netlogon.c
10253     @@ -189,7 +189,7 @@ bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
10254    
10255     /* This allows the tests to continue against the more fussy windows 2008 */
10256     if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
10257     - return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
10258     + return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
10259     credentials,
10260     cli_credentials_get_secure_channel_type(credentials),
10261     creds_out);
10262     @@ -423,7 +423,7 @@ bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
10263     "ServerAuthenticate3 failed");
10264     torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_DOWNGRADE_DETECTED, "ServerAuthenticate3 should have failed");
10265    
10266     - negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
10267     + negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
10268     creds = netlogon_creds_client_init(tctx, a.in.account_name,
10269     a.in.computer_name,
10270     a.in.secure_channel_type,
10271     @@ -490,7 +490,7 @@ static bool test_ServerReqChallenge(
10272     const char *machine_name;
10273     struct dcerpc_binding_handle *b = p->binding_handle;
10274     struct netr_ServerAuthenticate2 a;
10275     - uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
10276     + uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
10277     uint32_t out_negotiate_flags = 0;
10278     const struct samr_Password *mach_password = NULL;
10279     enum netr_SchannelType sec_chan_type = 0;
10280     @@ -562,7 +562,7 @@ static bool test_ServerReqChallenge_zero_challenge(
10281     const char *machine_name;
10282     struct dcerpc_binding_handle *b = p->binding_handle;
10283     struct netr_ServerAuthenticate2 a;
10284     - uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
10285     + uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
10286     uint32_t out_negotiate_flags = 0;
10287     const struct samr_Password *mach_password = NULL;
10288     enum netr_SchannelType sec_chan_type = 0;
10289     @@ -639,7 +639,7 @@ static bool test_ServerReqChallenge_5_repeats(
10290     const char *machine_name;
10291     struct dcerpc_binding_handle *b = p->binding_handle;
10292     struct netr_ServerAuthenticate2 a;
10293     - uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
10294     + uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
10295     uint32_t out_negotiate_flags = 0;
10296     const struct samr_Password *mach_password = NULL;
10297     enum netr_SchannelType sec_chan_type = 0;
10298     @@ -723,7 +723,7 @@ static bool test_ServerReqChallenge_4_repeats(
10299     const char *machine_name;
10300     struct dcerpc_binding_handle *b = p->binding_handle;
10301     struct netr_ServerAuthenticate2 a;
10302     - uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
10303     + uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
10304     uint32_t out_negotiate_flags = 0;
10305     const struct samr_Password *mach_password = NULL;
10306     enum netr_SchannelType sec_chan_type = 0;
10307     @@ -3459,7 +3459,7 @@ static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
10308     struct dcerpc_pipe *p = NULL;
10309     struct dcerpc_binding_handle *b = NULL;
10310    
10311     - if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
10312     + if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
10313     machine_credentials, &creds)) {
10314     return false;
10315     }
10316     @@ -4398,7 +4398,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx,
10317    
10318     torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
10319    
10320     - if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
10321     + if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
10322     machine_credentials, &creds)) {
10323     return false;
10324     }
10325     @@ -4973,7 +4973,7 @@ static bool test_GetDomainInfo_async(struct torture_context *tctx,
10326    
10327     torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
10328    
10329     - if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
10330     + if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
10331     machine_credentials, &creds)) {
10332     return false;
10333     }
10334     diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c
10335     index 9cd479c9baf..6fc4ed326d2 100644
10336     --- a/source4/torture/rpc/samba3rpc.c
10337     +++ b/source4/torture/rpc/samba3rpc.c
10338     @@ -1074,7 +1074,7 @@ static bool auth2(struct torture_context *tctx,
10339     goto done;
10340     }
10341    
10342     - negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
10343     + negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
10344     E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash);
10345    
10346     a.in.server_name = talloc_asprintf(
10347     @@ -1264,10 +1264,19 @@ static bool schan(struct torture_context *tctx,
10348     E_md4hash(cli_credentials_get_password(user_creds),
10349     pinfo.ntpassword.hash);
10350    
10351     - netlogon_creds_arcfour_crypt(creds_state, pinfo.ntpassword.hash, 16);
10352     -
10353     logon.password = &pinfo;
10354    
10355     + /*
10356     + * We don't use this here:
10357     + *
10358     + * netlogon_creds_encrypt_samlogon_logon(creds_state,
10359     + * NetlogonInteractiveInformation,
10360     + * &logon);
10361     + *
10362     + * in order to detect bugs
10363     + */
10364     + netlogon_creds_aes_encrypt(creds_state, pinfo.ntpassword.hash, 16);
10365     +
10366     r.in.logon_level = NetlogonInteractiveInformation;
10367     r.in.logon = &logon;
10368     r.out.return_authenticator = &return_authenticator;
10369     --
10370     2.39.0
10371    
10372    
10373     From 6088b76def86b8f56511707c69b6cdd016722715 Mon Sep 17 00:00:00 2001
10374     From: Stefan Metzmacher <metze@samba.org>
10375     Date: Fri, 25 Nov 2022 09:54:17 +0100
10376     Subject: [PATCH 116/142] CVE-2022-38023 s4:rpc_server/netlogon: split out
10377     dcesrv_netr_ServerAuthenticate3_check_downgrade()
10378    
10379     We'll soon make it possible to use 'reject md5 servers:CLIENTACCOUNT$ = no',
10380     which means we'll need the downgrade detection in more places.
10381    
10382     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
10383    
10384     Signed-off-by: Stefan Metzmacher <metze@samba.org>
10385     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
10386     Reviewed-by: Ralph Boehme <slow@samba.org>
10387     (cherry picked from commit b6339fd1dcbe903e73efeea074ab0bd04ef83561)
10388     ---
10389     source4/rpc_server/netlogon/dcerpc_netlogon.c | 114 ++++++++++--------
10390     1 file changed, 67 insertions(+), 47 deletions(-)
10391    
10392     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
10393     index 8084061aabc..6a00fe4efcf 100644
10394     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
10395     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
10396     @@ -128,6 +128,67 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal
10397     return NT_STATUS_OK;
10398     }
10399    
10400     +static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
10401     + struct dcesrv_call_state *dce_call,
10402     + struct netr_ServerAuthenticate3 *r,
10403     + struct netlogon_server_pipe_state *pipe_state,
10404     + uint32_t negotiate_flags,
10405     + NTSTATUS orig_status)
10406     +{
10407     + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
10408     + bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(lp_ctx);
10409     + bool reject_des_client = !allow_nt4_crypto;
10410     + bool reject_md5_client = lpcfg_reject_md5_clients(lp_ctx);
10411     +
10412     + if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
10413     + reject_des_client = false;
10414     + }
10415     +
10416     + if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
10417     + reject_des_client = false;
10418     + reject_md5_client = false;
10419     + }
10420     +
10421     + if (reject_des_client || reject_md5_client) {
10422     + /*
10423     + * Here we match Windows 2012 and return no flags.
10424     + */
10425     + *r->out.negotiate_flags = 0;
10426     + return NT_STATUS_DOWNGRADE_DETECTED;
10427     + }
10428     +
10429     + /*
10430     + * This talloc_free is important to prevent re-use of the
10431     + * challenge. We have to delay it this far due to NETApp
10432     + * servers per:
10433     + * https://bugzilla.samba.org/show_bug.cgi?id=11291
10434     + */
10435     + TALLOC_FREE(pipe_state);
10436     +
10437     + /*
10438     + * At this point we must also cleanup the TDB cache
10439     + * entry, if we fail the client needs to call
10440     + * netr_ServerReqChallenge again.
10441     + *
10442     + * Note: this handles a non existing record just fine,
10443     + * the r->in.computer_name might not be the one used
10444     + * in netr_ServerReqChallenge(), but we are trying to
10445     + * just tidy up the normal case to prevent re-use.
10446     + */
10447     + schannel_delete_challenge(dce_call->conn->dce_ctx->lp_ctx,
10448     + r->in.computer_name);
10449     +
10450     + /*
10451     + * According to Microsoft (see bugid #6099)
10452     + * Windows 7 looks at the negotiate_flags
10453     + * returned in this structure *even if the
10454     + * call fails with access denied!
10455     + */
10456     + *r->out.negotiate_flags = negotiate_flags;
10457     +
10458     + return orig_status;
10459     +}
10460     +
10461     /*
10462     * Do the actual processing of a netr_ServerAuthenticate3 message.
10463     * called from dcesrv_netr_ServerAuthenticate3, which handles the logging.
10464     @@ -155,11 +216,9 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10465     "objectSid", "samAccountName", NULL};
10466     uint32_t server_flags = 0;
10467     uint32_t negotiate_flags = 0;
10468     - bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(dce_call->conn->dce_ctx->lp_ctx);
10469     - bool reject_des_client = !allow_nt4_crypto;
10470     - bool reject_md5_client = lpcfg_reject_md5_clients(dce_call->conn->dce_ctx->lp_ctx);
10471    
10472     ZERO_STRUCTP(r->out.return_credentials);
10473     + *r->out.negotiate_flags = 0;
10474     *r->out.rid = 0;
10475    
10476     pipe_state = dcesrv_iface_state_find_conn(dce_call,
10477     @@ -238,52 +297,13 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10478    
10479     negotiate_flags = *r->in.negotiate_flags & server_flags;
10480    
10481     - if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
10482     - reject_des_client = false;
10483     - }
10484     -
10485     - if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
10486     - reject_des_client = false;
10487     - reject_md5_client = false;
10488     - }
10489     -
10490     - if (reject_des_client || reject_md5_client) {
10491     - /*
10492     - * Here we match Windows 2012 and return no flags.
10493     - */
10494     - *r->out.negotiate_flags = 0;
10495     - return NT_STATUS_DOWNGRADE_DETECTED;
10496     + nt_status = dcesrv_netr_ServerAuthenticate3_check_downgrade(
10497     + dce_call, r, pipe_state, negotiate_flags,
10498     + NT_STATUS_OK);
10499     + if (!NT_STATUS_IS_OK(nt_status)) {
10500     + return nt_status;
10501     }
10502    
10503     - /*
10504     - * This talloc_free is important to prevent re-use of the
10505     - * challenge. We have to delay it this far due to NETApp
10506     - * servers per:
10507     - * https://bugzilla.samba.org/show_bug.cgi?id=11291
10508     - */
10509     - TALLOC_FREE(pipe_state);
10510     -
10511     - /*
10512     - * At this point we must also cleanup the TDB cache
10513     - * entry, if we fail the client needs to call
10514     - * netr_ServerReqChallenge again.
10515     - *
10516     - * Note: this handles a non existing record just fine,
10517     - * the r->in.computer_name might not be the one used
10518     - * in netr_ServerReqChallenge(), but we are trying to
10519     - * just tidy up the normal case to prevent re-use.
10520     - */
10521     - schannel_delete_challenge(dce_call->conn->dce_ctx->lp_ctx,
10522     - r->in.computer_name);
10523     -
10524     - /*
10525     - * According to Microsoft (see bugid #6099)
10526     - * Windows 7 looks at the negotiate_flags
10527     - * returned in this structure *even if the
10528     - * call fails with access denied!
10529     - */
10530     - *r->out.negotiate_flags = negotiate_flags;
10531     -
10532     switch (r->in.secure_channel_type) {
10533     case SEC_CHAN_WKSTA:
10534     case SEC_CHAN_DNS_DOMAIN:
10535     --
10536     2.39.0
10537    
10538    
10539     From 3e43111a1417414b545fcc46a72e701cf6e71c59 Mon Sep 17 00:00:00 2001
10540     From: Stefan Metzmacher <metze@samba.org>
10541     Date: Thu, 24 Nov 2022 18:26:18 +0100
10542     Subject: [PATCH 117/142] CVE-2022-38023 docs-xml/smbdotconf: change 'reject
10543     md5 clients' default to yes
10544    
10545     AES is supported by Windows Server >= 2008R2, Windows (Client) >= 7 and Samba >= 4.0,
10546     so there's no reason to allow md5 clients by default.
10547     However some third party domain members may need it.
10548    
10549     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
10550    
10551     Signed-off-by: Stefan Metzmacher <metze@samba.org>
10552     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
10553     Reviewed-by: Ralph Boehme <slow@samba.org>
10554     (cherry picked from commit c8e53394b98b128ed460a6111faf05dfbad980d1)
10555     ---
10556     docs-xml/smbdotconf/logon/rejectmd5clients.xml | 11 ++++++++---
10557     lib/param/loadparm.c | 1 +
10558     selftest/target/Samba4.pm | 4 ++++
10559     source3/param/loadparm.c | 1 +
10560     4 files changed, 14 insertions(+), 3 deletions(-)
10561    
10562     diff --git a/docs-xml/smbdotconf/logon/rejectmd5clients.xml b/docs-xml/smbdotconf/logon/rejectmd5clients.xml
10563     index 0bb9f6f6c8e..edcbe02e99a 100644
10564     --- a/docs-xml/smbdotconf/logon/rejectmd5clients.xml
10565     +++ b/docs-xml/smbdotconf/logon/rejectmd5clients.xml
10566     @@ -7,11 +7,16 @@
10567     only in 'active directory domain controller' mode), will
10568     reject clients which does not support NETLOGON_NEG_SUPPORTS_AES.</para>
10569    
10570     - <para>You can set this to yes if all domain members support aes.
10571     - This will prevent downgrade attacks.</para>
10572     + <para>Support for NETLOGON_NEG_SUPPORTS_AES was added in Windows
10573     + starting with Server 2008R2 and Windows 7, it's available in Samba
10574     + starting with 4.0, however third party domain members like NetApp ONTAP
10575     + still uses RC4 (HMAC-MD5), see https://www.samba.org/samba/security/CVE-2022-38023.html for more details.</para>
10576     +
10577     + <para>The default changed from 'no' to 'yes', with the patches for CVE-2022-38023,
10578     + see https://bugzilla.samba.org/show_bug.cgi?id=15240</para>
10579    
10580     <para>This option overrides the 'allow nt4 crypto' option.</para>
10581     </description>
10582    
10583     -<value type="default">no</value>
10584     +<value type="default">yes</value>
10585     </samba:parameter>
10586     diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
10587     index dc659a449ea..77a80176f7d 100644
10588     --- a/lib/param/loadparm.c
10589     +++ b/lib/param/loadparm.c
10590     @@ -2790,6 +2790,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
10591     lpcfg_do_global_parameter(lp_ctx, "winbind nss info", "template");
10592    
10593     lpcfg_do_global_parameter(lp_ctx, "server schannel", "True");
10594     + lpcfg_do_global_parameter(lp_ctx, "reject md5 clients", "True");
10595    
10596     lpcfg_do_global_parameter(lp_ctx, "short preserve case", "True");
10597    
10598     diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
10599     index 8dad74cae43..7e3d7c9de8e 100755
10600     --- a/selftest/target/Samba4.pm
10601     +++ b/selftest/target/Samba4.pm
10602     @@ -1709,6 +1709,8 @@ sub provision_ad_dc_ntvfs($$)
10603     dsdb password event notification = true
10604     dsdb group change notification = true
10605    
10606     + reject md5 clients = no
10607     +
10608     CVE_2020_1472:warn_about_unused_debug_level = 3
10609     server require schannel:schannel0\$ = no
10610     server require schannel:schannel1\$ = no
10611     @@ -2102,6 +2104,8 @@ sub provision_ad_dc($$$$$$)
10612     lpq cache time = 0
10613     print notify backchannel = yes
10614    
10615     + reject md5 clients = no
10616     +
10617     CVE_2020_1472:warn_about_unused_debug_level = 3
10618     server require schannel:schannel0\$ = no
10619     server require schannel:schannel1\$ = no
10620     diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
10621     index fbc987e119a..1cf468b1009 100644
10622     --- a/source3/param/loadparm.c
10623     +++ b/source3/param/loadparm.c
10624     @@ -659,6 +659,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
10625     Globals.require_strong_key = true;
10626     Globals.reject_md5_servers = true;
10627     Globals.server_schannel = true;
10628     + Globals.reject_md5_clients = true;
10629     Globals.read_raw = true;
10630     Globals.write_raw = true;
10631     Globals.null_passwords = false;
10632     --
10633     2.39.0
10634    
10635    
10636     From 886878d18d22eb4a2f3b63663e0ffe284ed9788b Mon Sep 17 00:00:00 2001
10637     From: Stefan Metzmacher <metze@samba.org>
10638     Date: Fri, 25 Nov 2022 10:31:08 +0100
10639     Subject: [PATCH 118/142] CVE-2022-38023 s4:rpc_server/netlogon: defer
10640     downgrade check until we found the account in our SAM
10641    
10642     We'll soon make it possible to use 'reject md5 servers:CLIENTACCOUNT$ = no',
10643     which means we'll need use the account name from our SAM.
10644    
10645     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
10646    
10647     Signed-off-by: Stefan Metzmacher <metze@samba.org>
10648     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
10649     Reviewed-by: Ralph Boehme <slow@samba.org>
10650     (cherry picked from commit b09f51eefc311bbb1525efd1dc7b9a837f7ec3c2)
10651     ---
10652     source4/rpc_server/netlogon/dcerpc_netlogon.c | 76 +++++++++++++------
10653     1 file changed, 53 insertions(+), 23 deletions(-)
10654    
10655     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
10656     index 6a00fe4efcf..1c180343252 100644
10657     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
10658     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
10659     @@ -297,13 +297,6 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10660    
10661     negotiate_flags = *r->in.negotiate_flags & server_flags;
10662    
10663     - nt_status = dcesrv_netr_ServerAuthenticate3_check_downgrade(
10664     - dce_call, r, pipe_state, negotiate_flags,
10665     - NT_STATUS_OK);
10666     - if (!NT_STATUS_IS_OK(nt_status)) {
10667     - return nt_status;
10668     - }
10669     -
10670     switch (r->in.secure_channel_type) {
10671     case SEC_CHAN_WKSTA:
10672     case SEC_CHAN_DNS_DOMAIN:
10673     @@ -312,11 +305,15 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10674     case SEC_CHAN_RODC:
10675     break;
10676     case SEC_CHAN_NULL:
10677     - return NT_STATUS_INVALID_PARAMETER;
10678     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10679     + dce_call, r, pipe_state, negotiate_flags,
10680     + NT_STATUS_INVALID_PARAMETER);
10681     default:
10682     DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
10683     r->in.secure_channel_type));
10684     - return NT_STATUS_INVALID_PARAMETER;
10685     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10686     + dce_call, r, pipe_state, negotiate_flags,
10687     + NT_STATUS_INVALID_PARAMETER);
10688     }
10689    
10690     sam_ctx = samdb_connect(mem_ctx,
10691     @@ -326,7 +323,9 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10692     dce_call->conn->remote_address,
10693     0);
10694     if (sam_ctx == NULL) {
10695     - return NT_STATUS_INVALID_SYSTEM_SERVICE;
10696     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10697     + dce_call, r, pipe_state, negotiate_flags,
10698     + NT_STATUS_INVALID_SYSTEM_SERVICE);
10699     }
10700    
10701     if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
10702     @@ -355,16 +354,22 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10703     encoded_name = ldb_binary_encode_string(mem_ctx,
10704     r->in.account_name);
10705     if (encoded_name == NULL) {
10706     - return NT_STATUS_NO_MEMORY;
10707     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10708     + dce_call, r, pipe_state, negotiate_flags,
10709     + NT_STATUS_NO_MEMORY);
10710     }
10711    
10712     len = strlen(encoded_name);
10713     if (len < 2) {
10714     - return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
10715     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10716     + dce_call, r, pipe_state, negotiate_flags,
10717     + NT_STATUS_NO_TRUST_SAM_ACCOUNT);
10718     }
10719    
10720     if (require_trailer && encoded_name[len - 1] != trailer) {
10721     - return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
10722     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10723     + dce_call, r, pipe_state, negotiate_flags,
10724     + NT_STATUS_NO_TRUST_SAM_ACCOUNT);
10725     }
10726     encoded_name[len - 1] = '\0';
10727    
10728     @@ -382,30 +387,42 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10729     "but there's no tdo for [%s] => [%s] \n",
10730     log_escape(mem_ctx, r->in.account_name),
10731     encoded_name));
10732     - return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
10733     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10734     + dce_call, r, pipe_state, negotiate_flags,
10735     + NT_STATUS_NO_TRUST_SAM_ACCOUNT);
10736     }
10737     if (!NT_STATUS_IS_OK(nt_status)) {
10738     - return nt_status;
10739     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10740     + dce_call, r, pipe_state, negotiate_flags,
10741     + nt_status);
10742     }
10743    
10744     nt_status = dsdb_trust_get_incoming_passwords(tdo_msg, mem_ctx,
10745     &curNtHash,
10746     &prevNtHash);
10747     if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED)) {
10748     - return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
10749     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10750     + dce_call, r, pipe_state, negotiate_flags,
10751     + NT_STATUS_NO_TRUST_SAM_ACCOUNT);
10752     }
10753     if (!NT_STATUS_IS_OK(nt_status)) {
10754     - return nt_status;
10755     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10756     + dce_call, r, pipe_state, negotiate_flags,
10757     + nt_status);
10758     }
10759    
10760     flatname = ldb_msg_find_attr_as_string(tdo_msg, "flatName", NULL);
10761     if (flatname == NULL) {
10762     - return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
10763     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10764     + dce_call, r, pipe_state, negotiate_flags,
10765     + NT_STATUS_NO_TRUST_SAM_ACCOUNT);
10766     }
10767    
10768     *trust_account_for_search = talloc_asprintf(mem_ctx, "%s$", flatname);
10769     if (*trust_account_for_search == NULL) {
10770     - return NT_STATUS_NO_MEMORY;
10771     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10772     + dce_call, r, pipe_state, negotiate_flags,
10773     + NT_STATUS_NO_MEMORY);
10774     }
10775     } else {
10776     *trust_account_for_search = r->in.account_name;
10777     @@ -420,14 +437,18 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10778     if (num_records == 0) {
10779     DEBUG(3,("Couldn't find user [%s] in samdb.\n",
10780     log_escape(mem_ctx, r->in.account_name)));
10781     - return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
10782     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10783     + dce_call, r, pipe_state, negotiate_flags,
10784     + NT_STATUS_NO_TRUST_SAM_ACCOUNT);
10785     }
10786    
10787     if (num_records > 1) {
10788     DEBUG(0,("Found %d records matching user [%s]\n",
10789     num_records,
10790     log_escape(mem_ctx, r->in.account_name)));
10791     - return NT_STATUS_INTERNAL_DB_CORRUPTION;
10792     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10793     + dce_call, r, pipe_state, negotiate_flags,
10794     + NT_STATUS_INTERNAL_DB_CORRUPTION);
10795     }
10796    
10797     *trust_account_in_db = ldb_msg_find_attr_as_string(msgs[0],
10798     @@ -436,9 +457,18 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10799     if (*trust_account_in_db == NULL) {
10800     DEBUG(0,("No samAccountName returned in record matching user [%s]\n",
10801     r->in.account_name));
10802     - return NT_STATUS_INTERNAL_DB_CORRUPTION;
10803     + return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10804     + dce_call, r, pipe_state, negotiate_flags,
10805     + NT_STATUS_INTERNAL_DB_CORRUPTION);
10806     }
10807     -
10808     +
10809     + nt_status = dcesrv_netr_ServerAuthenticate3_check_downgrade(
10810     + dce_call, r, pipe_state, negotiate_flags,
10811     + NT_STATUS_OK);
10812     + if (!NT_STATUS_IS_OK(nt_status)) {
10813     + return nt_status;
10814     + }
10815     +
10816     user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
10817    
10818     if (user_account_control & UF_ACCOUNTDISABLE) {
10819     --
10820     2.39.0
10821    
10822    
10823     From ed628f5bf355801023c1bb2ac4aabd06c5c878a6 Mon Sep 17 00:00:00 2001
10824     From: Stefan Metzmacher <metze@samba.org>
10825     Date: Fri, 25 Nov 2022 13:13:36 +0100
10826     Subject: [PATCH 119/142] CVE-2022-38023 s4:rpc_server/netlogon: add 'server
10827     reject md5 schannel:COMPUTERACCOUNT = no' and 'allow nt4
10828     crypto:COMPUTERACCOUNT = yes'
10829    
10830     This makes it more flexible when we change the global default to
10831     'reject md5 servers = yes'.
10832    
10833     'allow nt4 crypto = no' is already the default.
10834    
10835     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
10836    
10837     Signed-off-by: Stefan Metzmacher <metze@samba.org>
10838     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
10839     Reviewed-by: Ralph Boehme <slow@samba.org>
10840     (cherry picked from commit 69b36541606d7064de9648cd54b35adfdf8f0e8f)
10841     ---
10842     source4/rpc_server/netlogon/dcerpc_netlogon.c | 58 ++++++++++++++++++-
10843     1 file changed, 55 insertions(+), 3 deletions(-)
10844    
10845     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
10846     index 1c180343252..b605daea794 100644
10847     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
10848     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
10849     @@ -133,12 +133,48 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
10850     struct netr_ServerAuthenticate3 *r,
10851     struct netlogon_server_pipe_state *pipe_state,
10852     uint32_t negotiate_flags,
10853     + const char *trust_account_in_db,
10854     NTSTATUS orig_status)
10855     {
10856     struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
10857     - bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(lp_ctx);
10858     - bool reject_des_client = !allow_nt4_crypto;
10859     - bool reject_md5_client = lpcfg_reject_md5_clients(lp_ctx);
10860     + bool global_allow_nt4_crypto = lpcfg_allow_nt4_crypto(lp_ctx);
10861     + bool account_allow_nt4_crypto = global_allow_nt4_crypto;
10862     + const char *explicit_nt4_opt = NULL;
10863     + bool global_reject_md5_client = lpcfg_reject_md5_clients(lp_ctx);
10864     + bool account_reject_md5_client = global_reject_md5_client;
10865     + const char *explicit_md5_opt = NULL;
10866     + bool reject_des_client;
10867     + bool allow_nt4_crypto;
10868     + bool reject_md5_client;
10869     +
10870     + /*
10871     + * We don't use lpcfg_parm_bool(), as we
10872     + * need the explicit_opt pointer in order to
10873     + * adjust the debug messages.
10874     + */
10875     +
10876     + if (trust_account_in_db != NULL) {
10877     + explicit_nt4_opt = lpcfg_get_parametric(lp_ctx,
10878     + NULL,
10879     + "allow nt4 crypto",
10880     + trust_account_in_db);
10881     + }
10882     + if (explicit_nt4_opt != NULL) {
10883     + account_allow_nt4_crypto = lp_bool(explicit_nt4_opt);
10884     + }
10885     + allow_nt4_crypto = account_allow_nt4_crypto;
10886     + if (trust_account_in_db != NULL) {
10887     + explicit_md5_opt = lpcfg_get_parametric(lp_ctx,
10888     + NULL,
10889     + "server reject md5 schannel",
10890     + trust_account_in_db);
10891     + }
10892     + if (explicit_md5_opt != NULL) {
10893     + account_reject_md5_client = lp_bool(explicit_md5_opt);
10894     + }
10895     + reject_md5_client = account_reject_md5_client;
10896     +
10897     + reject_des_client = !allow_nt4_crypto;
10898    
10899     if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
10900     reject_des_client = false;
10901     @@ -307,12 +343,14 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10902     case SEC_CHAN_NULL:
10903     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10904     dce_call, r, pipe_state, negotiate_flags,
10905     + NULL, /* trust_account_in_db */
10906     NT_STATUS_INVALID_PARAMETER);
10907     default:
10908     DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
10909     r->in.secure_channel_type));
10910     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10911     dce_call, r, pipe_state, negotiate_flags,
10912     + NULL, /* trust_account_in_db */
10913     NT_STATUS_INVALID_PARAMETER);
10914     }
10915    
10916     @@ -325,6 +363,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10917     if (sam_ctx == NULL) {
10918     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10919     dce_call, r, pipe_state, negotiate_flags,
10920     + NULL, /* trust_account_in_db */
10921     NT_STATUS_INVALID_SYSTEM_SERVICE);
10922     }
10923    
10924     @@ -356,6 +395,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10925     if (encoded_name == NULL) {
10926     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10927     dce_call, r, pipe_state, negotiate_flags,
10928     + NULL, /* trust_account_in_db */
10929     NT_STATUS_NO_MEMORY);
10930     }
10931    
10932     @@ -363,12 +403,14 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10933     if (len < 2) {
10934     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10935     dce_call, r, pipe_state, negotiate_flags,
10936     + NULL, /* trust_account_in_db */
10937     NT_STATUS_NO_TRUST_SAM_ACCOUNT);
10938     }
10939    
10940     if (require_trailer && encoded_name[len - 1] != trailer) {
10941     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10942     dce_call, r, pipe_state, negotiate_flags,
10943     + NULL, /* trust_account_in_db */
10944     NT_STATUS_NO_TRUST_SAM_ACCOUNT);
10945     }
10946     encoded_name[len - 1] = '\0';
10947     @@ -389,11 +431,13 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10948     encoded_name));
10949     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10950     dce_call, r, pipe_state, negotiate_flags,
10951     + NULL, /* trust_account_in_db */
10952     NT_STATUS_NO_TRUST_SAM_ACCOUNT);
10953     }
10954     if (!NT_STATUS_IS_OK(nt_status)) {
10955     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10956     dce_call, r, pipe_state, negotiate_flags,
10957     + NULL, /* trust_account_in_db */
10958     nt_status);
10959     }
10960    
10961     @@ -403,11 +447,13 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10962     if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED)) {
10963     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10964     dce_call, r, pipe_state, negotiate_flags,
10965     + NULL, /* trust_account_in_db */
10966     NT_STATUS_NO_TRUST_SAM_ACCOUNT);
10967     }
10968     if (!NT_STATUS_IS_OK(nt_status)) {
10969     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10970     dce_call, r, pipe_state, negotiate_flags,
10971     + NULL, /* trust_account_in_db */
10972     nt_status);
10973     }
10974    
10975     @@ -415,6 +461,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10976     if (flatname == NULL) {
10977     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10978     dce_call, r, pipe_state, negotiate_flags,
10979     + NULL, /* trust_account_in_db */
10980     NT_STATUS_NO_TRUST_SAM_ACCOUNT);
10981     }
10982    
10983     @@ -422,6 +469,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10984     if (*trust_account_for_search == NULL) {
10985     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10986     dce_call, r, pipe_state, negotiate_flags,
10987     + NULL, /* trust_account_in_db */
10988     NT_STATUS_NO_MEMORY);
10989     }
10990     } else {
10991     @@ -439,6 +487,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
10992     log_escape(mem_ctx, r->in.account_name)));
10993     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
10994     dce_call, r, pipe_state, negotiate_flags,
10995     + NULL, /* trust_account_in_db */
10996     NT_STATUS_NO_TRUST_SAM_ACCOUNT);
10997     }
10998    
10999     @@ -448,6 +497,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
11000     log_escape(mem_ctx, r->in.account_name)));
11001     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
11002     dce_call, r, pipe_state, negotiate_flags,
11003     + NULL, /* trust_account_in_db */
11004     NT_STATUS_INTERNAL_DB_CORRUPTION);
11005     }
11006    
11007     @@ -459,11 +509,13 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
11008     r->in.account_name));
11009     return dcesrv_netr_ServerAuthenticate3_check_downgrade(
11010     dce_call, r, pipe_state, negotiate_flags,
11011     + NULL, /* trust_account_in_db */
11012     NT_STATUS_INTERNAL_DB_CORRUPTION);
11013     }
11014    
11015     nt_status = dcesrv_netr_ServerAuthenticate3_check_downgrade(
11016     dce_call, r, pipe_state, negotiate_flags,
11017     + *trust_account_in_db,
11018     NT_STATUS_OK);
11019     if (!NT_STATUS_IS_OK(nt_status)) {
11020     return nt_status;
11021     --
11022     2.39.0
11023    
11024    
11025     From b15c69701d065504588671187a5cec9eea9dcf57 Mon Sep 17 00:00:00 2001
11026     From: Stefan Metzmacher <metze@samba.org>
11027     Date: Fri, 25 Nov 2022 13:31:14 +0100
11028     Subject: [PATCH 120/142] CVE-2022-38023 docs-xml/smbdotconf: document "allow
11029     nt4 crypto:COMPUTERACCOUNT = no"
11030    
11031     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
11032    
11033     Signed-off-by: Stefan Metzmacher <metze@samba.org>
11034     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
11035     Reviewed-by: Ralph Boehme <slow@samba.org>
11036     (cherry picked from commit bd429d025981b445bf63935063e8e302bfab3f9b)
11037     ---
11038     docs-xml/smbdotconf/logon/allownt4crypto.xml | 76 +++++++++++++++++++-
11039     1 file changed, 74 insertions(+), 2 deletions(-)
11040    
11041     diff --git a/docs-xml/smbdotconf/logon/allownt4crypto.xml b/docs-xml/smbdotconf/logon/allownt4crypto.xml
11042     index 06afcef73b1..bbd03a42db7 100644
11043     --- a/docs-xml/smbdotconf/logon/allownt4crypto.xml
11044     +++ b/docs-xml/smbdotconf/logon/allownt4crypto.xml
11045     @@ -1,11 +1,18 @@
11046     <samba:parameter name="allow nt4 crypto"
11047     context="G"
11048     type="boolean"
11049     + deprecated="1"
11050     xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
11051     <description>
11052     + <para>
11053     + This option is deprecated and will be removed in future,
11054     + as it is a security problem if not set to "no" (which will be
11055     + the hardcoded behavior in future).
11056     + </para>
11057     +
11058     <para>This option controls whether the netlogon server (currently
11059     only in 'active directory domain controller' mode), will
11060     - reject clients which does not support NETLOGON_NEG_STRONG_KEYS
11061     + reject clients which do not support NETLOGON_NEG_STRONG_KEYS
11062     nor NETLOGON_NEG_SUPPORTS_AES.</para>
11063    
11064     <para>This option was added with Samba 4.2.0. It may lock out clients
11065     @@ -18,8 +25,73 @@
11066    
11067     <para>"allow nt4 crypto = yes" allows weak crypto to be negotiated, maybe via downgrade attacks.</para>
11068    
11069     - <para>This option is over-ridden by the 'reject md5 clients' option.</para>
11070     + <para><emphasis>Avoid using this option!</emphasis> Use explicit '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">yes</smbconfoption>' instead!
11071     + Which is available with the patches for
11072     + <ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>
11073     + see <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink></para>
11074     +
11075     + <para>
11076     + Samba will log an error in the log files at log level 0
11077     + if legacy a client is rejected or allowed without an explicit,
11078     + '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">yes</smbconfoption>' option
11079     + for the client. The message will indicate
11080     + the explicit '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">yes</smbconfoption>'
11081     + line to be added, if the legacy client software requires it. (The log level can be adjusted with
11082     + '<smbconfoption name="CVE_2022_38023:error_debug_level">1</smbconfoption>'
11083     + in order to complain only at a higher log level).
11084     + </para>
11085     +
11086     + <para>This allows admins to use "yes" only for a short grace period,
11087     + in order to collect the explicit
11088     + '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">yes</smbconfoption>' options.</para>
11089     +
11090     + <para>This option is over-ridden by the '<smbconfoption name="reject md5 clients">yes</smbconfoption>' option.</para>
11091     </description>
11092    
11093     <value type="default">no</value>
11094     </samba:parameter>
11095     +
11096     +<samba:parameter name="allow nt4 crypto:COMPUTERACCOUNT"
11097     + context="G"
11098     + type="string"
11099     + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
11100     +<description>
11101     +
11102     + <para>If you still have legacy domain members which required 'allow nt4 crypto = yes',
11103     + it is possible to specify an explicit exception per computer account
11104     + by using 'allow nt4 crypto:COMPUTERACCOUNT = yes' as option.
11105     + Note that COMPUTERACCOUNT has to be the sAMAccountName value of
11106     + the computer account (including the trailing '$' sign).
11107     + </para>
11108     +
11109     + <para>
11110     + Samba will log a complaint in the log files at log level 0
11111     + about the security problem if the option is set to "yes",
11112     + but the related computer does not require it.
11113     + (The log level can be adjusted with
11114     + '<smbconfoption name="CVE_2022_38023:warn_about_unused_debug_level">1</smbconfoption>'
11115     + in order to complain only at a higher log level).
11116     + </para>
11117     +
11118     + <para>
11119     + Samba will log a warning in the log files at log level 5,
11120     + if a setting is still needed for the specified computer account.
11121     + </para>
11122     +
11123     + <para>
11124     + See <ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>,
11125     + <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink>.
11126     + </para>
11127     +
11128     + <para>This option overrides the <smbconfoption name="allow nt4 crypto"/> option.</para>
11129     +
11130     + <para>This option is over-ridden by the '<smbconfoption name="reject md5 clients">yes</smbconfoption>' option.</para>
11131     +
11132     + <programlisting>
11133     + allow nt4 crypto:LEGACYCOMPUTER1$ = yes
11134     + allow nt4 crypto:NASBOX$ = yes
11135     + allow nt4 crypto:LEGACYCOMPUTER2$ = yes
11136     + </programlisting>
11137     +</description>
11138     +
11139     +</samba:parameter>
11140     --
11141     2.39.0
11142    
11143    
11144     From bbc9f54fdc1ebbfc0c27b61aff43a63a16aed9d9 Mon Sep 17 00:00:00 2001
11145     From: Stefan Metzmacher <metze@samba.org>
11146     Date: Fri, 25 Nov 2022 14:02:11 +0100
11147     Subject: [PATCH 121/142] CVE-2022-38023 docs-xml/smbdotconf: document "server
11148     reject md5 schannel:COMPUTERACCOUNT"
11149    
11150     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
11151    
11152     Signed-off-by: Stefan Metzmacher <metze@samba.org>
11153     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
11154     Reviewed-by: Ralph Boehme <slow@samba.org>
11155     (cherry picked from commit 2ad302b42254e3c2800aaf11669fe2e6d55fa8a1)
11156     ---
11157     docs-xml/smbdotconf/logon/allownt4crypto.xml | 13 ++-
11158     .../smbdotconf/logon/rejectmd5clients.xml | 96 ++++++++++++++++++-
11159     2 files changed, 103 insertions(+), 6 deletions(-)
11160    
11161     diff --git a/docs-xml/smbdotconf/logon/allownt4crypto.xml b/docs-xml/smbdotconf/logon/allownt4crypto.xml
11162     index bbd03a42db7..ee63e6cc245 100644
11163     --- a/docs-xml/smbdotconf/logon/allownt4crypto.xml
11164     +++ b/docs-xml/smbdotconf/logon/allownt4crypto.xml
11165     @@ -45,7 +45,9 @@
11166     in order to collect the explicit
11167     '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">yes</smbconfoption>' options.</para>
11168    
11169     - <para>This option is over-ridden by the '<smbconfoption name="reject md5 clients">yes</smbconfoption>' option.</para>
11170     + <para>This option is over-ridden by the effective value of 'yes' from
11171     + the '<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT"/>'
11172     + and/or '<smbconfoption name="reject md5 clients"/>' options.</para>
11173     </description>
11174    
11175     <value type="default">no</value>
11176     @@ -85,12 +87,19 @@
11177    
11178     <para>This option overrides the <smbconfoption name="allow nt4 crypto"/> option.</para>
11179    
11180     - <para>This option is over-ridden by the '<smbconfoption name="reject md5 clients">yes</smbconfoption>' option.</para>
11181     + <para>This option is over-ridden by the effective value of 'yes' from
11182     + the '<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT"/>'
11183     + and/or '<smbconfoption name="reject md5 clients"/>' options.</para>
11184     + <para>Which means '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">yes</smbconfoption>'
11185     + is only useful in combination with '<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT">no</smbconfoption>'</para>
11186    
11187     <programlisting>
11188     allow nt4 crypto:LEGACYCOMPUTER1$ = yes
11189     + server reject md5 schannel:LEGACYCOMPUTER1$ = no
11190     allow nt4 crypto:NASBOX$ = yes
11191     + server reject md5 schannel:NASBOX$ = no
11192     allow nt4 crypto:LEGACYCOMPUTER2$ = yes
11193     + server reject md5 schannel:LEGACYCOMPUTER2$ = no
11194     </programlisting>
11195     </description>
11196    
11197     diff --git a/docs-xml/smbdotconf/logon/rejectmd5clients.xml b/docs-xml/smbdotconf/logon/rejectmd5clients.xml
11198     index edcbe02e99a..fe7701d9277 100644
11199     --- a/docs-xml/smbdotconf/logon/rejectmd5clients.xml
11200     +++ b/docs-xml/smbdotconf/logon/rejectmd5clients.xml
11201     @@ -1,8 +1,15 @@
11202     <samba:parameter name="reject md5 clients"
11203     context="G"
11204     type="boolean"
11205     + deprecated="1"
11206     xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
11207     <description>
11208     + <para>
11209     + This option is deprecated and will be removed in a future release,
11210     + as it is a security problem if not set to "yes" (which will be
11211     + the hardcoded behavior in the future).
11212     + </para>
11213     +
11214     <para>This option controls whether the netlogon server (currently
11215     only in 'active directory domain controller' mode), will
11216     reject clients which does not support NETLOGON_NEG_SUPPORTS_AES.</para>
11217     @@ -10,13 +17,94 @@
11218     <para>Support for NETLOGON_NEG_SUPPORTS_AES was added in Windows
11219     starting with Server 2008R2 and Windows 7, it's available in Samba
11220     starting with 4.0, however third party domain members like NetApp ONTAP
11221     - still uses RC4 (HMAC-MD5), see https://www.samba.org/samba/security/CVE-2022-38023.html for more details.</para>
11222     + still uses RC4 (HMAC-MD5), see
11223     + <ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">https://www.samba.org/samba/security/CVE-2022-38023.html</ulink>
11224     + for more details.
11225     + </para>
11226     +
11227     + <para>The default changed from 'no' to 'yes', with the patches for
11228     + <ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>
11229     + see <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink>.
11230     + </para>
11231     +
11232     + <para><emphasis>Avoid using this option!</emphasis> Use an explicit per machine account
11233     + '<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT"/>' instead!
11234     + Which is available with the patches for
11235     + <ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>
11236     + see <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink>.
11237     + </para>
11238    
11239     - <para>The default changed from 'no' to 'yes', with the patches for CVE-2022-38023,
11240     - see https://bugzilla.samba.org/show_bug.cgi?id=15240</para>
11241     + <para>
11242     + Samba will log an error in the log files at log level 0
11243     + if legacy a client is rejected or allowed without an explicit,
11244     + '<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT">no</smbconfoption>' option
11245     + for the client. The message will indicate
11246     + the explicit '<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT">no</smbconfoption>'
11247     + line to be added, if the legacy client software requires it. (The log level can be adjusted with
11248     + '<smbconfoption name="CVE_2022_38023:error_debug_level">1</smbconfoption>'
11249     + in order to complain only at a higher log level).
11250     + </para>
11251    
11252     - <para>This option overrides the 'allow nt4 crypto' option.</para>
11253     + <para>This allows admins to use "no" only for a short grace period,
11254     + in order to collect the explicit
11255     + '<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT">no</smbconfoption>' options.</para>
11256     +
11257     + <para>When set to 'yes' this option overrides the
11258     + '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT"/>' and
11259     + '<smbconfoption name="allow nt4 crypto"/>' options and implies
11260     + '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">no</smbconfoption>'.
11261     + </para>
11262     </description>
11263    
11264     <value type="default">yes</value>
11265     </samba:parameter>
11266     +
11267     +<samba:parameter name="server reject md5 schannel:COMPUTERACCOUNT"
11268     + context="G"
11269     + type="string"
11270     + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
11271     +<description>
11272     +
11273     + <para>If you still have legacy domain members or trusted domains,
11274     + which required "reject md5 clients = no" before,
11275     + it is possible to specify an explicit exception per computer account
11276     + by setting 'server reject md5 schannel:COMPUTERACCOUNT = no'.
11277     + Note that COMPUTERACCOUNT has to be the sAMAccountName value of
11278     + the computer account (including the trailing '$' sign).
11279     + </para>
11280     +
11281     + <para>
11282     + Samba will log a complaint in the log files at log level 0
11283     + about the security problem if the option is set to "no",
11284     + but the related computer does not require it.
11285     + (The log level can be adjusted with
11286     + '<smbconfoption name="CVE_2022_38023:warn_about_unused_debug_level">1</smbconfoption>'
11287     + in order to complain only at a higher log level).
11288     + </para>
11289     +
11290     + <para>
11291     + Samba will log a warning in the log files at log level 5
11292     + if a setting is still needed for the specified computer account.
11293     + </para>
11294     +
11295     + <para>
11296     + See <ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>,
11297     + <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink>.
11298     + </para>
11299     +
11300     + <para>This option overrides the <smbconfoption name="reject md5 clients"/> option.</para>
11301     +
11302     + <para>When set to 'yes' this option overrides the
11303     + '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT"/>' and
11304     + '<smbconfoption name="allow nt4 crypto"/>' options and implies
11305     + '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">no</smbconfoption>'.
11306     + </para>
11307     +
11308     + <programlisting>
11309     + server reject md5 schannel:LEGACYCOMPUTER1$ = no
11310     + server reject md5 schannel:NASBOX$ = no
11311     + server reject md5 schannel:LEGACYCOMPUTER2$ = no
11312     + </programlisting>
11313     +</description>
11314     +
11315     +</samba:parameter>
11316     --
11317     2.39.0
11318    
11319    
11320     From 88311bae73bfdd2863ee94f421ef89266bff97f0 Mon Sep 17 00:00:00 2001
11321     From: Stefan Metzmacher <metze@samba.org>
11322     Date: Fri, 25 Nov 2022 13:13:36 +0100
11323     Subject: [PATCH 122/142] CVE-2022-38023 s4:rpc_server/netlogon: debug 'reject
11324     md5 servers' and 'allow nt4 crypto' misconfigurations
11325    
11326     This allows the admin to notice what's wrong in order to adjust the
11327     configuration if required.
11328    
11329     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
11330    
11331     Signed-off-by: Stefan Metzmacher <metze@samba.org>
11332     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
11333     Reviewed-by: Ralph Boehme <slow@samba.org>
11334     (cherry picked from commit 43df4be35950f491864ae8ada05d51b42a556381)
11335     ---
11336     source4/rpc_server/netlogon/dcerpc_netlogon.c | 121 ++++++++++++++++++
11337     1 file changed, 121 insertions(+)
11338    
11339     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
11340     index b605daea794..b93ff08abcd 100644
11341     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
11342     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
11343     @@ -61,10 +61,34 @@ static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_connection_context
11344     const struct dcesrv_interface *iface)
11345     {
11346     struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
11347     + bool global_allow_nt4_crypto = lpcfg_allow_nt4_crypto(lp_ctx);
11348     + bool global_reject_md5_client = lpcfg_reject_md5_clients(lp_ctx);
11349     int schannel = lpcfg_server_schannel(lp_ctx);
11350     bool schannel_global_required = (schannel == true);
11351     + static bool warned_global_nt4_once = false;
11352     + static bool warned_global_md5_once = false;
11353     static bool warned_global_schannel_once = false;
11354    
11355     + if (global_allow_nt4_crypto && !warned_global_nt4_once) {
11356     + /*
11357     + * We want admins to notice their misconfiguration!
11358     + */
11359     + D_ERR("CVE-2022-38023 (and others): "
11360     + "Please configure 'allow nt4 crypto = no' (the default), "
11361     + "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
11362     + warned_global_nt4_once = true;
11363     + }
11364     +
11365     + if (!global_reject_md5_client && !warned_global_md5_once) {
11366     + /*
11367     + * We want admins to notice their misconfiguration!
11368     + */
11369     + D_ERR("CVE-2022-38023: "
11370     + "Please configure 'reject md5 clients = yes' (the default), "
11371     + "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
11372     + warned_global_md5_once = true;
11373     + }
11374     +
11375     if (!schannel_global_required && !warned_global_schannel_once) {
11376     /*
11377     * We want admins to notice their misconfiguration!
11378     @@ -146,6 +170,12 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
11379     bool reject_des_client;
11380     bool allow_nt4_crypto;
11381     bool reject_md5_client;
11382     + bool need_des = true;
11383     + bool need_md5 = true;
11384     + int CVE_2022_38023_warn_level = lpcfg_parm_int(lp_ctx, NULL,
11385     + "CVE_2022_38023", "warn_about_unused_debug_level", DBGLVL_ERR);
11386     + int CVE_2022_38023_error_level = lpcfg_parm_int(lp_ctx, NULL,
11387     + "CVE_2022_38023", "error_debug_level", DBGLVL_ERR);
11388    
11389     /*
11390     * We don't use lpcfg_parm_bool(), as we
11391     @@ -177,19 +207,62 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
11392     reject_des_client = !allow_nt4_crypto;
11393    
11394     if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
11395     + need_des = false;
11396     reject_des_client = false;
11397     }
11398    
11399     if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
11400     + need_des = false;
11401     + need_md5 = false;
11402     reject_des_client = false;
11403     reject_md5_client = false;
11404     }
11405    
11406     if (reject_des_client || reject_md5_client) {
11407     + TALLOC_CTX *frame = talloc_stackframe();
11408     +
11409     + DEBUG(CVE_2022_38023_error_level, (
11410     + "CVE-2022-38023: "
11411     + "client_account[%s] computer_name[%s] "
11412     + "schannel_type[%u] "
11413     + "client_negotiate_flags[0x%x] "
11414     + "%s%s%s "
11415     + "NT_STATUS_DOWNGRADE_DETECTED "
11416     + "reject_des[%u] reject_md5[%u]\n",
11417     + log_escape(frame, r->in.account_name),
11418     + log_escape(frame, r->in.computer_name),
11419     + r->in.secure_channel_type,
11420     + (unsigned)*r->in.negotiate_flags,
11421     + trust_account_in_db ? "real_account[" : "",
11422     + trust_account_in_db ? trust_account_in_db : "",
11423     + trust_account_in_db ? "]" : "",
11424     + reject_des_client,
11425     + reject_md5_client));
11426     + if (trust_account_in_db == NULL) {
11427     + goto return_downgrade;
11428     + }
11429     +
11430     + if (reject_md5_client && explicit_md5_opt == NULL) {
11431     + DEBUG(CVE_2022_38023_error_level, (
11432     + "CVE-2022-38023: Check if option "
11433     + "'server reject md5 schannel:%s = no' "
11434     + "might be needed for a legacy client.\n",
11435     + trust_account_in_db));
11436     + }
11437     + if (reject_des_client && explicit_nt4_opt == NULL) {
11438     + DEBUG(CVE_2022_38023_error_level, (
11439     + "CVE-2022-38023: Check if option "
11440     + "'allow nt4 crypto:%s = yes' "
11441     + "might be needed for a legacy client.\n",
11442     + trust_account_in_db));
11443     + }
11444     +
11445     +return_downgrade:
11446     /*
11447     * Here we match Windows 2012 and return no flags.
11448     */
11449     *r->out.negotiate_flags = 0;
11450     + TALLOC_FREE(frame);
11451     return NT_STATUS_DOWNGRADE_DETECTED;
11452     }
11453    
11454     @@ -222,6 +295,54 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
11455     */
11456     *r->out.negotiate_flags = negotiate_flags;
11457    
11458     + if (!NT_STATUS_IS_OK(orig_status) || trust_account_in_db == NULL) {
11459     + return orig_status;
11460     + }
11461     +
11462     + if (global_reject_md5_client && account_reject_md5_client && explicit_md5_opt) {
11463     + D_INFO("CVE-2022-38023: Check if option "
11464     + "'server reject md5 schannel:%s = yes' not needed!?\n",
11465     + trust_account_in_db);
11466     + } else if (need_md5 && !account_reject_md5_client && explicit_md5_opt) {
11467     + D_INFO("CVE-2022-38023: Check if option "
11468     + "'server reject md5 schannel:%s = no' "
11469     + "still needed for a legacy client.\n",
11470     + trust_account_in_db);
11471     + } else if (need_md5 && explicit_md5_opt == NULL) {
11472     + DEBUG(CVE_2022_38023_error_level, (
11473     + "CVE-2022-38023: Check if option "
11474     + "'server reject md5 schannel:%s = no' "
11475     + "might be needed for a legacy client.\n",
11476     + trust_account_in_db));
11477     + } else if (!account_reject_md5_client && explicit_md5_opt) {
11478     + DEBUG(CVE_2022_38023_warn_level, (
11479     + "CVE-2022-38023: Check if option "
11480     + "'server reject md5 schannel:%s = no' not needed!?\n",
11481     + trust_account_in_db));
11482     + }
11483     +
11484     + if (!global_allow_nt4_crypto && !account_allow_nt4_crypto && explicit_nt4_opt) {
11485     + D_INFO("CVE-2022-38023: Check if option "
11486     + "'allow nt4 crypto:%s = no' not needed!?\n",
11487     + trust_account_in_db);
11488     + } else if (need_des && account_allow_nt4_crypto && explicit_nt4_opt) {
11489     + D_INFO("CVE-2022-38023: Check if option "
11490     + "'allow nt4 crypto:%s = yes' "
11491     + "still needed for a legacy client.\n",
11492     + trust_account_in_db);
11493     + } else if (need_des && explicit_nt4_opt == NULL) {
11494     + DEBUG(CVE_2022_38023_error_level, (
11495     + "CVE-2022-38023: Check if option "
11496     + "'allow nt4 crypto:%s = yes' "
11497     + "might be needed for a legacy client.\n",
11498     + trust_account_in_db));
11499     + } else if (account_allow_nt4_crypto && explicit_nt4_opt) {
11500     + DEBUG(CVE_2022_38023_warn_level, (
11501     + "CVE-2022-38023: Check if option "
11502     + "'allow nt4 crypto:%s = yes' not needed!?\n",
11503     + trust_account_in_db));
11504     + }
11505     +
11506     return orig_status;
11507     }
11508    
11509     --
11510     2.39.0
11511    
11512    
11513     From 73230d08dd1ec2390e52b24f0398d328a55e5866 Mon Sep 17 00:00:00 2001
11514     From: Stefan Metzmacher <metze@samba.org>
11515     Date: Wed, 30 Nov 2022 14:57:20 +0100
11516     Subject: [PATCH 123/142] CVE-2022-38023 selftest:Samba4: avoid global 'allow
11517     nt4 crypto = yes' and 'reject md5 clients = no'
11518    
11519     Instead of using the generic deprecated option use the specific
11520     allow nt4 crypto:COMPUTERACCOUNT = yes and
11521     server reject md5 schannel:COMPUTERACCOUNT = no
11522     in order to allow legacy tests for pass.
11523    
11524     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
11525    
11526     Signed-off-by: Stefan Metzmacher <metze@samba.org>
11527     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
11528     Reviewed-by: Ralph Boehme <slow@samba.org>
11529     (backported from commit 7ae3735810c2db32fa50f309f8af3c76ffa29768)
11530     ---
11531     selftest/target/Samba4.pm | 60 ++++++++++++++++++++++++++++++++++-----
11532     1 file changed, 53 insertions(+), 7 deletions(-)
11533    
11534     diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
11535     index 7e3d7c9de8e..aafb9ee14ca 100755
11536     --- a/selftest/target/Samba4.pm
11537     +++ b/selftest/target/Samba4.pm
11538     @@ -1700,7 +1700,6 @@ sub provision_ad_dc_ntvfs($$)
11539     my $extra_conf_options = "netbios aliases = localDC1-a
11540     server services = +winbind -winbindd
11541     ldap server require strong auth = allow_sasl_over_tls
11542     - allow nt4 crypto = yes
11543     raw NTLMv2 auth = yes
11544     lsa over netlogon = yes
11545     rpc server port = 1027
11546     @@ -1709,9 +1708,19 @@ sub provision_ad_dc_ntvfs($$)
11547     dsdb password event notification = true
11548     dsdb group change notification = true
11549    
11550     - reject md5 clients = no
11551     -
11552     CVE_2020_1472:warn_about_unused_debug_level = 3
11553     + CVE_2022_38023:warn_about_unused_debug_level = 3
11554     + allow nt4 crypto:torturetest\$ = yes
11555     + server reject md5 schannel:schannel2\$ = no
11556     + server reject md5 schannel:schannel3\$ = no
11557     + server reject md5 schannel:schannel8\$ = no
11558     + server reject md5 schannel:schannel9\$ = no
11559     + server reject md5 schannel:torturetest\$ = no
11560     + server reject md5 schannel:tests4u2proxywk\$ = no
11561     + server reject md5 schannel:tests4u2selfbdc\$ = no
11562     + server reject md5 schannel:tests4u2selfwk\$ = no
11563     + server reject md5 schannel:torturepacbdc\$ = no
11564     + server reject md5 schannel:torturepacwksta\$ = no
11565     server require schannel:schannel0\$ = no
11566     server require schannel:schannel1\$ = no
11567     server require schannel:schannel2\$ = no
11568     @@ -1770,6 +1779,13 @@ sub provision_fl2000dc($$)
11569     my $extra_conf_options = "
11570     spnego:simulate_w2k=yes
11571     ntlmssp_server:force_old_spnego=yes
11572     +
11573     + CVE_2022_38023:warn_about_unused_debug_level = 3
11574     + server reject md5 schannel:tests4u2proxywk\$ = no
11575     + server reject md5 schannel:tests4u2selfbdc\$ = no
11576     + server reject md5 schannel:tests4u2selfwk\$ = no
11577     + server reject md5 schannel:torturepacbdc\$ = no
11578     + server reject md5 schannel:torturepacwksta\$ = no
11579     ";
11580     my $extra_provision_options = ["--use-ntvfs"];
11581     # This environment uses plain text secrets
11582     @@ -1818,7 +1834,16 @@ sub provision_fl2003dc($$$)
11583     my $extra_conf_options = "allow dns updates = nonsecure and secure
11584     dcesrv:header signing = no
11585     dcesrv:max auth states = 0
11586     - dns forwarder = 127.0.0.$swiface1 127.0.0.$swiface2";
11587     + dns forwarder = 127.0.0.$swiface1 127.0.0.$swiface2
11588     +
11589     + CVE_2022_38023:warn_about_unused_debug_level = 3
11590     + server reject md5 schannel:tests4u2proxywk\$ = no
11591     + server reject md5 schannel:tests4u2selfbdc\$ = no
11592     + server reject md5 schannel:tests4u2selfwk\$ = no
11593     + server reject md5 schannel:torturepacbdc\$ = no
11594     + server reject md5 schannel:torturepacwksta\$ = no
11595     +";
11596     +
11597     my $extra_provision_options = ["--use-ntvfs"];
11598     my $ret = $self->provision($prefix,
11599     "domain controller",
11600     @@ -1874,8 +1899,18 @@ sub provision_fl2008r2dc($$$)
11601     my ($self, $prefix, $dcvars) = @_;
11602    
11603     print "PROVISIONING DC WITH FOREST LEVEL 2008r2...\n";
11604     - my $extra_conf_options = "ldap server require strong auth = no";
11605     + my $extra_conf_options = "
11606     + ldap server require strong auth = no
11607     +
11608     + CVE_2022_38023:warn_about_unused_debug_level = 3
11609     + server reject md5 schannel:tests4u2proxywk\$ = no
11610     + server reject md5 schannel:tests4u2selfbdc\$ = no
11611     + server reject md5 schannel:tests4u2selfwk\$ = no
11612     + server reject md5 schannel:torturepacbdc\$ = no
11613     + server reject md5 schannel:torturepacwksta\$ = no
11614     +";
11615     my $extra_provision_options = ["--use-ntvfs"];
11616     +
11617     my $ret = $self->provision($prefix,
11618     "domain controller",
11619     "dc7",
11620     @@ -2104,9 +2139,20 @@ sub provision_ad_dc($$$$$$)
11621     lpq cache time = 0
11622     print notify backchannel = yes
11623    
11624     - reject md5 clients = no
11625     -
11626     CVE_2020_1472:warn_about_unused_debug_level = 3
11627     + CVE_2022_38023:warn_about_unused_debug_level = 3
11628     + CVE_2022_38023:error_debug_level = 2
11629     + server reject md5 schannel:schannel2\$ = no
11630     + server reject md5 schannel:schannel3\$ = no
11631     + server reject md5 schannel:schannel8\$ = no
11632     + server reject md5 schannel:schannel9\$ = no
11633     + server reject md5 schannel:torturetest\$ = no
11634     + server reject md5 schannel:tests4u2proxywk\$ = no
11635     + server reject md5 schannel:tests4u2selfbdc\$ = no
11636     + server reject md5 schannel:tests4u2selfwk\$ = no
11637     + server reject md5 schannel:torturepacbdc\$ = no
11638     + server reject md5 schannel:torturepacwksta\$ = no
11639     + server reject md5 schannel:samlogontest\$ = no
11640     server require schannel:schannel0\$ = no
11641     server require schannel:schannel1\$ = no
11642     server require schannel:schannel2\$ = no
11643     --
11644     2.39.0
11645    
11646    
11647     From 2efdacb36c42985595284db6db90953feecc6e1a Mon Sep 17 00:00:00 2001
11648     From: Stefan Metzmacher <metze@samba.org>
11649     Date: Wed, 30 Nov 2022 16:57:24 +0100
11650     Subject: [PATCH 124/142] CVE-2022-38023 s4:rpc_server/netlogon: split out
11651     dcesrv_netr_check_schannel() function
11652    
11653     This will allow us to reuse the function in other places.
11654     As it will also get some additional checks soon.
11655    
11656     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
11657    
11658     Signed-off-by: Stefan Metzmacher <metze@samba.org>
11659     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
11660     Reviewed-by: Ralph Boehme <slow@samba.org>
11661     (cherry picked from commit f43dc4f0bd60d4e127b714565147f82435aa4f07)
11662     ---
11663     source4/rpc_server/netlogon/dcerpc_netlogon.c | 84 +++++++++++--------
11664     1 file changed, 51 insertions(+), 33 deletions(-)
11665    
11666     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
11667     index b93ff08abcd..94adb74165f 100644
11668     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
11669     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
11670     @@ -845,18 +845,11 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_ca
11671     return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
11672     }
11673    
11674     -/*
11675     - * NOTE: The following functions are nearly identical to the ones available in
11676     - * source3/rpc_server/srv_nelog_nt.c
11677     - * The reason we keep 2 copies is that they use different structures to
11678     - * represent the auth_info and the decrpc pipes.
11679     - */
11680     -static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
11681     - TALLOC_CTX *mem_ctx,
11682     - const char *computer_name,
11683     - struct netr_Authenticator *received_authenticator,
11684     - struct netr_Authenticator *return_authenticator,
11685     - struct netlogon_creds_CredentialState **creds_out)
11686     +static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
11687     + const struct netlogon_creds_CredentialState *creds,
11688     + enum dcerpc_AuthType auth_type,
11689     + enum dcerpc_AuthLevel auth_level,
11690     + uint16_t opnum)
11691     {
11692     struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
11693     TALLOC_CTX *frame = talloc_stackframe();
11694     @@ -865,15 +858,11 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
11695     bool schannel_global_required = (schannel == true);
11696     bool schannel_required = schannel_global_required;
11697     const char *explicit_opt = NULL;
11698     - struct netlogon_creds_CredentialState *creds = NULL;
11699     int CVE_2020_1472_warn_level = lpcfg_parm_int(lp_ctx, NULL,
11700     "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
11701     int CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
11702     "CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
11703     unsigned int dbg_lvl = DBGLVL_DEBUG;
11704     - enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
11705     - enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
11706     - uint16_t opnum = dce_call->pkt.u.request.opnum;
11707     const char *opname = "<unknown>";
11708     const char *reason = "<unknown>";
11709    
11710     @@ -881,8 +870,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
11711     opname = ndr_table_netlogon.calls[opnum].name;
11712     }
11713    
11714     - dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
11715     -
11716     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
11717     if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
11718     reason = "WITH SEALED";
11719     @@ -895,17 +882,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
11720     reason = "WITHOUT";
11721     }
11722    
11723     - nt_status = schannel_check_creds_state(mem_ctx,
11724     - lp_ctx,
11725     - computer_name,
11726     - received_authenticator,
11727     - return_authenticator,
11728     - &creds);
11729     - if (!NT_STATUS_IS_OK(nt_status)) {
11730     - ZERO_STRUCTP(return_authenticator);
11731     - return nt_status;
11732     - }
11733     -
11734     /*
11735     * We don't use lpcfg_parm_bool(), as we
11736     * need the explicit_opt pointer in order to
11737     @@ -945,7 +921,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
11738     log_escape(frame, creds->computer_name)));
11739     }
11740    
11741     - *creds_out = creds;
11742     TALLOC_FREE(frame);
11743     return nt_status;
11744     }
11745     @@ -979,8 +954,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
11746     "might be needed for a legacy client.\n",
11747     log_escape(frame, creds->account_name)));
11748     }
11749     - TALLOC_FREE(creds);
11750     - ZERO_STRUCTP(return_authenticator);
11751     TALLOC_FREE(frame);
11752     return nt_status;
11753     }
11754     @@ -1024,11 +997,56 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
11755     log_escape(frame, creds->computer_name)));
11756     }
11757    
11758     - *creds_out = creds;
11759     TALLOC_FREE(frame);
11760     return NT_STATUS_OK;
11761     }
11762    
11763     +/*
11764     + * NOTE: The following functions are nearly identical to the ones available in
11765     + * source3/rpc_server/srv_nelog_nt.c
11766     + * The reason we keep 2 copies is that they use different structures to
11767     + * represent the auth_info and the decrpc pipes.
11768     + */
11769     +static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
11770     + TALLOC_CTX *mem_ctx,
11771     + const char *computer_name,
11772     + struct netr_Authenticator *received_authenticator,
11773     + struct netr_Authenticator *return_authenticator,
11774     + struct netlogon_creds_CredentialState **creds_out)
11775     +{
11776     + NTSTATUS nt_status;
11777     + struct netlogon_creds_CredentialState *creds = NULL;
11778     + enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
11779     + enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
11780     +
11781     + dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
11782     +
11783     + nt_status = schannel_check_creds_state(mem_ctx,
11784     + dce_call->conn->dce_ctx->lp_ctx,
11785     + computer_name,
11786     + received_authenticator,
11787     + return_authenticator,
11788     + &creds);
11789     + if (!NT_STATUS_IS_OK(nt_status)) {
11790     + ZERO_STRUCTP(return_authenticator);
11791     + return nt_status;
11792     + }
11793     +
11794     + nt_status = dcesrv_netr_check_schannel(dce_call,
11795     + creds,
11796     + auth_type,
11797     + auth_level,
11798     + dce_call->pkt.u.request.opnum);
11799     + if (!NT_STATUS_IS_OK(nt_status)) {
11800     + TALLOC_FREE(creds);
11801     + ZERO_STRUCTP(return_authenticator);
11802     + return nt_status;
11803     + }
11804     +
11805     + *creds_out = creds;
11806     + return NT_STATUS_OK;
11807     +}
11808     +
11809     /*
11810     Change the machine account password for the currently connected
11811     client. Supplies only the NT#.
11812     --
11813     2.39.0
11814    
11815    
11816     From b95d07ebad63544c585a43590bdeaf5247cbaf46 Mon Sep 17 00:00:00 2001
11817     From: Stefan Metzmacher <metze@samba.org>
11818     Date: Wed, 30 Nov 2022 17:15:36 +0100
11819     Subject: [PATCH 125/142] CVE-2022-38023 s4:rpc_server/netlogon: make sure all
11820     dcesrv_netr_LogonSamLogon*() calls go through dcesrv_netr_check_schannel()
11821    
11822     We'll soon add some additional contraints in dcesrv_netr_check_schannel(),
11823     which are also required for dcesrv_netr_LogonSamLogonEx().
11824    
11825     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
11826    
11827     Signed-off-by: Stefan Metzmacher <metze@samba.org>
11828     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
11829     Reviewed-by: Ralph Boehme <slow@samba.org>
11830     (cherry picked from commit 689507457f5e6666488732f91a355a2183fb1662)
11831     ---
11832     source4/rpc_server/netlogon/dcerpc_netlogon.c | 36 +++++++++++++++----
11833     1 file changed, 29 insertions(+), 7 deletions(-)
11834    
11835     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
11836     index 94adb74165f..f4413d7a03b 100644
11837     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
11838     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
11839     @@ -1408,6 +1408,35 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base_call(struct dcesrv_netr_LogonSamL
11840     struct auth_usersupplied_info *user_info = NULL;
11841     NTSTATUS nt_status;
11842     struct tevent_req *subreq = NULL;
11843     + enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
11844     + enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
11845     +
11846     + dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
11847     +
11848     + switch (dce_call->pkt.u.request.opnum) {
11849     + case NDR_NETR_LOGONSAMLOGON:
11850     + case NDR_NETR_LOGONSAMLOGONWITHFLAGS:
11851     + /*
11852     + * These already called dcesrv_netr_check_schannel()
11853     + * via dcesrv_netr_creds_server_step_check()
11854     + */
11855     + break;
11856     + case NDR_NETR_LOGONSAMLOGONEX:
11857     + default:
11858     + if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
11859     + return NT_STATUS_ACCESS_DENIED;
11860     + }
11861     +
11862     + nt_status = dcesrv_netr_check_schannel(dce_call,
11863     + creds,
11864     + auth_type,
11865     + auth_level,
11866     + dce_call->pkt.u.request.opnum);
11867     + if (!NT_STATUS_IS_OK(nt_status)) {
11868     + return nt_status;
11869     + }
11870     + break;
11871     + }
11872    
11873     *r->out.authoritative = 1;
11874    
11875     @@ -1739,7 +1768,6 @@ static void dcesrv_netr_LogonSamLogon_base_reply(
11876     static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
11877     struct netr_LogonSamLogonEx *r)
11878     {
11879     - enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
11880     struct dcesrv_netr_LogonSamLogon_base_state *state;
11881     NTSTATUS nt_status;
11882    
11883     @@ -1777,12 +1805,6 @@ static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call,
11884     return nt_status;
11885     }
11886    
11887     - dcesrv_call_auth_info(dce_call, &auth_type, NULL);
11888     -
11889     - if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
11890     - return NT_STATUS_ACCESS_DENIED;
11891     - }
11892     -
11893     nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
11894    
11895     if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
11896     --
11897     2.39.0
11898    
11899    
11900     From 5e5019dbdf9b49e07bd5f88bafa7275d5d076166 Mon Sep 17 00:00:00 2001
11901     From: Stefan Metzmacher <metze@samba.org>
11902     Date: Fri, 25 Nov 2022 16:53:35 +0100
11903     Subject: [PATCH 126/142] CVE-2022-38023 docs-xml/smbdotconf: add "server
11904     schannel require seal[:COMPUTERACCOUNT]" options
11905    
11906     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
11907    
11908     Signed-off-by: Stefan Metzmacher <metze@samba.org>
11909     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
11910     Reviewed-by: Ralph Boehme <slow@samba.org>
11911     (cherry picked from commit 7732a4b0bde1d9f98a0371f17d22648495329470)
11912     ---
11913     .../smbdotconf/security/serverschannel.xml | 43 ++++++-
11914     .../security/serverschannelrequireseal.xml | 118 ++++++++++++++++++
11915     lib/param/loadparm.c | 1 +
11916     source3/param/loadparm.c | 1 +
11917     4 files changed, 157 insertions(+), 6 deletions(-)
11918     create mode 100644 docs-xml/smbdotconf/security/serverschannelrequireseal.xml
11919    
11920     diff --git a/docs-xml/smbdotconf/security/serverschannel.xml b/docs-xml/smbdotconf/security/serverschannel.xml
11921     index 3e66df1c203..42a657912ca 100644
11922     --- a/docs-xml/smbdotconf/security/serverschannel.xml
11923     +++ b/docs-xml/smbdotconf/security/serverschannel.xml
11924     @@ -12,19 +12,37 @@
11925     the hardcoded behavior in future).
11926     </para>
11927    
11928     - <para>
11929     - Samba will complain in the log files at log level 0,
11930     - about the security problem if the option is not set to "yes".
11931     + <para><emphasis>Avoid using this option!</emphasis> Use explicit '<smbconfoption name="server require schannel:COMPUTERACCOUNT">no</smbconfoption>' instead!
11932     </para>
11933     +
11934     + <para>
11935     + Samba will log an error in the log files at log level 0
11936     + if legacy a client is rejected or allowed without an explicit,
11937     + '<smbconfoption name="server require schannel:COMPUTERACCOUNT">no</smbconfoption>' option
11938     + for the client. The message will indicate
11939     + the explicit '<smbconfoption name="server require schannel:COMPUTERACCOUNT">no</smbconfoption>'
11940     + line to be added, if the legacy client software requires it. (The log level can be adjusted with
11941     + '<smbconfoption name="CVE_2020_1472:error_debug_level">1</smbconfoption>'
11942     + in order to complain only at a higher log level).
11943     + </para>
11944     +
11945     <para>
11946     - See CVE-2020-1472(ZeroLogon) https://bugzilla.samba.org/show_bug.cgi?id=14497
11947     + This allows admins to use "auto" only for a short grace period,
11948     + in order to collect the explicit
11949     + '<smbconfoption name="server require schannel:COMPUTERACCOUNT">no</smbconfoption>' options.
11950     </para>
11951    
11952     - <para>If you still have legacy domain members use the <smbconfoption name="server require schannel:COMPUTERACCOUNT"/> option.
11953     + <para>
11954     + See <ulink url="https://www.samba.org/samba/security/CVE-2020-1472.html">CVE-2020-1472(ZeroLogon)</ulink>,
11955     + <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=14497">https://bugzilla.samba.org/show_bug.cgi?id=14497</ulink>.
11956     </para>
11957    
11958     <para>This option is over-ridden by the <smbconfoption name="server require schannel:COMPUTERACCOUNT"/> option.</para>
11959    
11960     + <para>This option is over-ridden by the effective value of 'yes' from
11961     + the '<smbconfoption name="server schannel require seal:COMPUTERACCOUNT"/>'
11962     + and/or '<smbconfoption name="server schannel require seal"/>' options.</para>
11963     +
11964     </description>
11965    
11966     <value type="default">yes</value>
11967     @@ -48,6 +66,9 @@
11968     about the security problem if the option is not set to "no",
11969     but the related computer is actually using the netlogon
11970     secure channel (schannel) feature.
11971     + (The log level can be adjusted with
11972     + '<smbconfoption name="CVE_2020_1472:warn_about_unused_debug_level">1</smbconfoption>'
11973     + in order to complain only at a higher log level).
11974     </para>
11975    
11976     <para>
11977     @@ -56,15 +77,25 @@
11978     </para>
11979    
11980     <para>
11981     - See CVE-2020-1472(ZeroLogon) https://bugzilla.samba.org/show_bug.cgi?id=14497
11982     + See <ulink url="https://www.samba.org/samba/security/CVE-2020-1472.html">CVE-2020-1472(ZeroLogon)</ulink>,
11983     + <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=14497">https://bugzilla.samba.org/show_bug.cgi?id=14497</ulink>.
11984     </para>
11985    
11986     <para>This option overrides the <smbconfoption name="server schannel"/> option.</para>
11987    
11988     + <para>This option is over-ridden by the effective value of 'yes' from
11989     + the '<smbconfoption name="server schannel require seal:COMPUTERACCOUNT"/>'
11990     + and/or '<smbconfoption name="server schannel require seal"/>' options.</para>
11991     + <para>Which means '<smbconfoption name="server require schannel:COMPUTERACCOUNT">no</smbconfoption>'
11992     + is only useful in combination with '<smbconfoption name="server schannel require seal:COMPUTERACCOUNT">no</smbconfoption>'</para>
11993     +
11994     <programlisting>
11995     server require schannel:LEGACYCOMPUTER1$ = no
11996     + server require schannel seal:LEGACYCOMPUTER1$ = no
11997     server require schannel:NASBOX$ = no
11998     + server require schannel seal:NASBOX$ = no
11999     server require schannel:LEGACYCOMPUTER2$ = no
12000     + server require schannel seal:LEGACYCOMPUTER2$ = no
12001     </programlisting>
12002     </description>
12003    
12004     diff --git a/docs-xml/smbdotconf/security/serverschannelrequireseal.xml b/docs-xml/smbdotconf/security/serverschannelrequireseal.xml
12005     new file mode 100644
12006     index 00000000000..d4620d1252d
12007     --- /dev/null
12008     +++ b/docs-xml/smbdotconf/security/serverschannelrequireseal.xml
12009     @@ -0,0 +1,118 @@
12010     +<samba:parameter name="server schannel require seal"
12011     + context="G"
12012     + type="boolean"
12013     + deprecated="1"
12014     + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
12015     +<description>
12016     +
12017     + <para>
12018     + This option is deprecated and will be removed in future,
12019     + as it is a security problem if not set to "yes" (which will be
12020     + the hardcoded behavior in future).
12021     + </para>
12022     +
12023     + <para>
12024     + This option controls whether the netlogon server (currently
12025     + only in 'active directory domain controller' mode), will
12026     + reject the usage of netlogon secure channel without privacy/enryption.
12027     + </para>
12028     +
12029     + <para>
12030     + The option is modelled after the registry key available on Windows.
12031     + </para>
12032     +
12033     + <programlisting>
12034     + HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\RequireSeal=2
12035     + </programlisting>
12036     +
12037     + <para>
12038     + <emphasis>Avoid using this option!</emphasis> Use the per computer account specific option
12039     + '<smbconfoption name="server schannel require seal:COMPUTERACCOUNT"/>' instead!
12040     + Which is available with the patches for
12041     + <ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>
12042     + see <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink>.
12043     + </para>
12044     +
12045     + <para>
12046     + Samba will log an error in the log files at log level 0
12047     + if legacy a client is rejected or allowed without an explicit,
12048     + '<smbconfoption name="server schannel require seal:COMPUTERACCOUNT">no</smbconfoption>' option
12049     + for the client. The message will indicate
12050     + the explicit '<smbconfoption name="server schannel require seal:COMPUTERACCOUNT">no</smbconfoption>'
12051     + line to be added, if the legacy client software requires it. (The log level can be adjusted with
12052     + '<smbconfoption name="CVE_2022_38023:error_debug_level">1</smbconfoption>'
12053     + in order to complain only at a higher log level).
12054     + </para>
12055     +
12056     + <para>This allows admins to use "no" only for a short grace period,
12057     + in order to collect the explicit
12058     + '<smbconfoption name="server schannel require seal:COMPUTERACCOUNT">no</smbconfoption>' options.</para>
12059     +
12060     + <para>
12061     + When set to 'yes' this option overrides the
12062     + '<smbconfoption name="server require schannel:COMPUTERACCOUNT"/>' and
12063     + '<smbconfoption name="server schannel"/>' options and implies
12064     + '<smbconfoption name="server require schannel:COMPUTERACCOUNT">yes</smbconfoption>'.
12065     + </para>
12066     +
12067     + <para>
12068     + This option is over-ridden by the <smbconfoption name="server schannel require seal:COMPUTERACCOUNT"/> option.
12069     + </para>
12070     +
12071     +</description>
12072     +
12073     +<value type="default">yes</value>
12074     +</samba:parameter>
12075     +
12076     +<samba:parameter name="server schannel require seal:COMPUTERACCOUNT"
12077     + context="G"
12078     + type="string"
12079     + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
12080     +<description>
12081     +
12082     + <para>
12083     + If you still have legacy domain members, which required "server schannel require seal = no" before,
12084     + it is possible to specify explicit exception per computer account
12085     + by using 'server schannel require seal:COMPUTERACCOUNT = no' as option.
12086     + Note that COMPUTERACCOUNT has to be the sAMAccountName value of
12087     + the computer account (including the trailing '$' sign).
12088     + </para>
12089     +
12090     + <para>
12091     + Samba will log a complaint in the log files at log level 0
12092     + about the security problem if the option is set to "no",
12093     + but the related computer does not require it.
12094     + (The log level can be adjusted with
12095     + '<smbconfoption name="CVE_2022_38023:warn_about_unused_debug_level">1</smbconfoption>'
12096     + in order to complain only at a higher log level).
12097     + </para>
12098     +
12099     + <para>
12100     + Samba will warn in the log files at log level 5,
12101     + if a setting is still needed for the specified computer account.
12102     + </para>
12103     +
12104     + <para>
12105     + See <ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>,
12106     + <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink>.
12107     + </para>
12108     +
12109     + <para>
12110     + This option overrides the '<smbconfoption name="server schannel require seal"/>' option.
12111     + </para>
12112     +
12113     + <para>
12114     + When set to 'yes' this option overrides the
12115     + '<smbconfoption name="server require schannel:COMPUTERACCOUNT"/>' and
12116     + '<smbconfoption name="server schannel"/>' options and implies
12117     + '<smbconfoption name="server require schannel:COMPUTERACCOUNT">yes</smbconfoption>'.
12118     + </para>
12119     +
12120     + <programlisting>
12121     + server require schannel seal:LEGACYCOMPUTER1$ = no
12122     + server require schannel seal:NASBOX$ = no
12123     + server require schannel seal:LEGACYCOMPUTER2$ = no
12124     + </programlisting>
12125     +</description>
12126     +
12127     +</samba:parameter>
12128     diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
12129     index 77a80176f7d..4b3976ebdb6 100644
12130     --- a/lib/param/loadparm.c
12131     +++ b/lib/param/loadparm.c
12132     @@ -2790,6 +2790,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
12133     lpcfg_do_global_parameter(lp_ctx, "winbind nss info", "template");
12134    
12135     lpcfg_do_global_parameter(lp_ctx, "server schannel", "True");
12136     + lpcfg_do_global_parameter(lp_ctx, "server schannel require seal", "True");
12137     lpcfg_do_global_parameter(lp_ctx, "reject md5 clients", "True");
12138    
12139     lpcfg_do_global_parameter(lp_ctx, "short preserve case", "True");
12140     diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
12141     index 1cf468b1009..8dab202fc17 100644
12142     --- a/source3/param/loadparm.c
12143     +++ b/source3/param/loadparm.c
12144     @@ -659,6 +659,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
12145     Globals.require_strong_key = true;
12146     Globals.reject_md5_servers = true;
12147     Globals.server_schannel = true;
12148     + Globals.server_schannel_require_seal = true;
12149     Globals.reject_md5_clients = true;
12150     Globals.read_raw = true;
12151     Globals.write_raw = true;
12152     --
12153     2.39.0
12154    
12155    
12156     From 83be39efadc4c4fad4a873e23016e1c5a8d65380 Mon Sep 17 00:00:00 2001
12157     From: Stefan Metzmacher <metze@samba.org>
12158     Date: Fri, 2 Dec 2022 14:31:26 +0100
12159     Subject: [PATCH 127/142] CVE-2022-38023 s4:rpc_server/netlogon: add a per
12160     connection cache to dcesrv_netr_check_schannel()
12161    
12162     It's enough to warn the admin once per connection.
12163    
12164     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
12165    
12166     Signed-off-by: Stefan Metzmacher <metze@samba.org>
12167     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
12168     Reviewed-by: Ralph Boehme <slow@samba.org>
12169     (cherry picked from commit 3c57608e1109c1d6e8bb8fbad2ef0b5d79d00e1a)
12170     ---
12171     source4/rpc_server/netlogon/dcerpc_netlogon.c | 193 ++++++++++++++----
12172     1 file changed, 153 insertions(+), 40 deletions(-)
12173    
12174     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
12175     index f4413d7a03b..474d0806e6b 100644
12176     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
12177     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
12178     @@ -845,23 +845,105 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_ca
12179     return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
12180     }
12181    
12182     -static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
12183     - const struct netlogon_creds_CredentialState *creds,
12184     - enum dcerpc_AuthType auth_type,
12185     - enum dcerpc_AuthLevel auth_level,
12186     - uint16_t opnum)
12187     +struct dcesrv_netr_check_schannel_state {
12188     + struct dom_sid account_sid;
12189     + enum dcerpc_AuthType auth_type;
12190     + enum dcerpc_AuthLevel auth_level;
12191     +
12192     + bool schannel_global_required;
12193     + bool schannel_required;
12194     + bool schannel_explicitly_set;
12195     +
12196     + NTSTATUS result;
12197     +};
12198     +
12199     +static NTSTATUS dcesrv_netr_check_schannel_get_state(struct dcesrv_call_state *dce_call,
12200     + const struct netlogon_creds_CredentialState *creds,
12201     + enum dcerpc_AuthType auth_type,
12202     + enum dcerpc_AuthLevel auth_level,
12203     + struct dcesrv_netr_check_schannel_state **_s)
12204     {
12205     struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
12206     - TALLOC_CTX *frame = talloc_stackframe();
12207     - NTSTATUS nt_status;
12208     int schannel = lpcfg_server_schannel(lp_ctx);
12209     bool schannel_global_required = (schannel == true);
12210     bool schannel_required = schannel_global_required;
12211     const char *explicit_opt = NULL;
12212     +#define DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC (NETLOGON_SERVER_PIPE_STATE_MAGIC+1)
12213     + struct dcesrv_netr_check_schannel_state *s = NULL;
12214     + NTSTATUS status;
12215     +
12216     + *_s = NULL;
12217     +
12218     + s = dcesrv_iface_state_find_conn(dce_call,
12219     + DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
12220     + struct dcesrv_netr_check_schannel_state);
12221     + if (s != NULL) {
12222     + if (!dom_sid_equal(&s->account_sid, creds->sid)) {
12223     + goto new_state;
12224     + }
12225     + if (s->auth_type != auth_type) {
12226     + goto new_state;
12227     + }
12228     + if (s->auth_level != auth_level) {
12229     + goto new_state;
12230     + }
12231     +
12232     + *_s = s;
12233     + return NT_STATUS_OK;
12234     + }
12235     +
12236     +new_state:
12237     + TALLOC_FREE(s);
12238     + s = talloc_zero(dce_call,
12239     + struct dcesrv_netr_check_schannel_state);
12240     + if (s == NULL) {
12241     + return NT_STATUS_NO_MEMORY;
12242     + }
12243     +
12244     + s->account_sid = *creds->sid;
12245     + s->auth_type = auth_type;
12246     + s->auth_level = auth_level;
12247     + s->result = NT_STATUS_MORE_PROCESSING_REQUIRED;
12248     +
12249     + /*
12250     + * We don't use lpcfg_parm_bool(), as we
12251     + * need the explicit_opt pointer in order to
12252     + * adjust the debug messages.
12253     + */
12254     + explicit_opt = lpcfg_get_parametric(lp_ctx,
12255     + NULL,
12256     + "server require schannel",
12257     + creds->account_name);
12258     + if (explicit_opt != NULL) {
12259     + schannel_required = lp_bool(explicit_opt);
12260     + }
12261     +
12262     + s->schannel_global_required = schannel_global_required;
12263     + s->schannel_required = schannel_required;
12264     + s->schannel_explicitly_set = explicit_opt != NULL;
12265     +
12266     + status = dcesrv_iface_state_store_conn(dce_call,
12267     + DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
12268     + s);
12269     + if (!NT_STATUS_IS_OK(status)) {
12270     + return status;
12271     + }
12272     +
12273     + *_s = s;
12274     + return NT_STATUS_OK;
12275     +}
12276     +
12277     +static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_call,
12278     + struct dcesrv_netr_check_schannel_state *s,
12279     + const struct netlogon_creds_CredentialState *creds,
12280     + uint16_t opnum)
12281     +{
12282     + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
12283     int CVE_2020_1472_warn_level = lpcfg_parm_int(lp_ctx, NULL,
12284     "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
12285     int CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
12286     "CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
12287     + TALLOC_CTX *frame = talloc_stackframe();
12288     unsigned int dbg_lvl = DBGLVL_DEBUG;
12289     const char *opname = "<unknown>";
12290     const char *reason = "<unknown>";
12291     @@ -870,37 +952,43 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
12292     opname = ndr_table_netlogon.calls[opnum].name;
12293     }
12294    
12295     - if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
12296     - if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
12297     + if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
12298     + if (s->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
12299     reason = "WITH SEALED";
12300     - } else if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
12301     + } else if (s->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
12302     reason = "WITH SIGNED";
12303     } else {
12304     - smb_panic("Schannel without SIGN/SEAL");
12305     + reason = "WITH INVALID";
12306     + dbg_lvl = DBGLVL_ERR;
12307     + s->result = NT_STATUS_INTERNAL_ERROR;
12308     }
12309     } else {
12310     reason = "WITHOUT";
12311     }
12312    
12313     - /*
12314     - * We don't use lpcfg_parm_bool(), as we
12315     - * need the explicit_opt pointer in order to
12316     - * adjust the debug messages.
12317     - */
12318     - explicit_opt = lpcfg_get_parametric(lp_ctx,
12319     - NULL,
12320     - "server require schannel",
12321     - creds->account_name);
12322     - if (explicit_opt != NULL) {
12323     - schannel_required = lp_bool(explicit_opt);
12324     + if (!NT_STATUS_EQUAL(s->result, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
12325     + if (!NT_STATUS_IS_OK(s->result)) {
12326     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
12327     + }
12328     +
12329     + DEBUG(dbg_lvl, (
12330     + "CVE-2020-1472(ZeroLogon): "
12331     + "%s request (opnum[%u]) %s schannel from "
12332     + "client_account[%s] client_computer_name[%s] %s\n",
12333     + opname, opnum, reason,
12334     + log_escape(frame, creds->account_name),
12335     + log_escape(frame, creds->computer_name),
12336     + nt_errstr(s->result)));
12337     + TALLOC_FREE(frame);
12338     + return s->result;
12339     }
12340    
12341     - if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
12342     - nt_status = NT_STATUS_OK;
12343     + if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
12344     + s->result = NT_STATUS_OK;
12345    
12346     - if (explicit_opt != NULL && !schannel_required) {
12347     + if (s->schannel_explicitly_set && !s->schannel_required) {
12348     dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
12349     - } else if (!schannel_required) {
12350     + } else if (!s->schannel_required) {
12351     dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
12352     }
12353    
12354     @@ -911,9 +999,8 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
12355     opname, opnum, reason,
12356     log_escape(frame, creds->account_name),
12357     log_escape(frame, creds->computer_name),
12358     - nt_errstr(nt_status)));
12359     -
12360     - if (explicit_opt != NULL && !schannel_required) {
12361     + nt_errstr(s->result)));
12362     + if (s->schannel_explicitly_set && !s->schannel_required) {
12363     DEBUG(CVE_2020_1472_warn_level, (
12364     "CVE-2020-1472(ZeroLogon): "
12365     "Option 'server require schannel:%s = no' not needed for '%s'!\n",
12366     @@ -922,13 +1009,13 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
12367     }
12368    
12369     TALLOC_FREE(frame);
12370     - return nt_status;
12371     + return s->result;
12372     }
12373    
12374     - if (schannel_required) {
12375     - nt_status = NT_STATUS_ACCESS_DENIED;
12376     + if (s->schannel_required) {
12377     + s->result = NT_STATUS_ACCESS_DENIED;
12378    
12379     - if (explicit_opt != NULL) {
12380     + if (s->schannel_explicitly_set) {
12381     dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
12382     } else {
12383     dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
12384     @@ -941,8 +1028,8 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
12385     opname, opnum, reason,
12386     log_escape(frame, creds->account_name),
12387     log_escape(frame, creds->computer_name),
12388     - nt_errstr(nt_status)));
12389     - if (explicit_opt != NULL) {
12390     + nt_errstr(s->result)));
12391     + if (s->schannel_explicitly_set) {
12392     D_NOTICE("CVE-2020-1472(ZeroLogon): Option "
12393     "'server require schannel:%s = yes' "
12394     "rejects access for client.\n",
12395     @@ -955,12 +1042,12 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
12396     log_escape(frame, creds->account_name)));
12397     }
12398     TALLOC_FREE(frame);
12399     - return nt_status;
12400     + return s->result;
12401     }
12402    
12403     - nt_status = NT_STATUS_OK;
12404     + s->result = NT_STATUS_OK;
12405    
12406     - if (explicit_opt != NULL) {
12407     + if (s->schannel_explicitly_set) {
12408     dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
12409     } else {
12410     dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
12411     @@ -973,9 +1060,9 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
12412     opname, opnum, reason,
12413     log_escape(frame, creds->account_name),
12414     log_escape(frame, creds->computer_name),
12415     - nt_errstr(nt_status)));
12416     + nt_errstr(s->result)));
12417    
12418     - if (explicit_opt != NULL) {
12419     + if (s->schannel_explicitly_set) {
12420     D_INFO("CVE-2020-1472(ZeroLogon): Option "
12421     "'server require schannel:%s = no' "
12422     "still needed for '%s'!\n",
12423     @@ -998,6 +1085,32 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
12424     }
12425    
12426     TALLOC_FREE(frame);
12427     + return s->result;
12428     +}
12429     +
12430     +static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
12431     + const struct netlogon_creds_CredentialState *creds,
12432     + enum dcerpc_AuthType auth_type,
12433     + enum dcerpc_AuthLevel auth_level,
12434     + uint16_t opnum)
12435     +{
12436     + struct dcesrv_netr_check_schannel_state *s = NULL;
12437     + NTSTATUS status;
12438     +
12439     + status = dcesrv_netr_check_schannel_get_state(dce_call,
12440     + creds,
12441     + auth_type,
12442     + auth_level,
12443     + &s);
12444     + if (!NT_STATUS_IS_OK(status)) {
12445     + return status;
12446     + }
12447     +
12448     + status = dcesrv_netr_check_schannel_once(dce_call, s, creds, opnum);
12449     + if (!NT_STATUS_IS_OK(status)) {
12450     + return status;
12451     + }
12452     +
12453     return NT_STATUS_OK;
12454     }
12455    
12456     --
12457     2.39.0
12458    
12459    
12460     From ef51add9def64d75f17b394924c238fffc81168f Mon Sep 17 00:00:00 2001
12461     From: Stefan Metzmacher <metze@samba.org>
12462     Date: Fri, 25 Nov 2022 14:05:30 +0100
12463     Subject: [PATCH 128/142] CVE-2022-38023 s4:rpc_server/netlogon: implement
12464     "server schannel require seal[:COMPUTERACCOUNT]"
12465    
12466     By default we'll now require schannel connections with
12467     privacy/sealing/encryption.
12468    
12469     But we allow exceptions for specific computer/trust accounts.
12470    
12471     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
12472    
12473     Signed-off-by: Stefan Metzmacher <metze@samba.org>
12474     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
12475     Reviewed-by: Ralph Boehme <slow@samba.org>
12476     (cherry picked from commit b3ed90a0541a271a7c6d4bee1201fa47adc3c0c1)
12477     ---
12478     selftest/target/Samba4.pm | 27 ++
12479     source4/rpc_server/netlogon/dcerpc_netlogon.c | 244 +++++++++++++++++-
12480     2 files changed, 270 insertions(+), 1 deletion(-)
12481    
12482     diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
12483     index aafb9ee14ca..c267b81d865 100755
12484     --- a/selftest/target/Samba4.pm
12485     +++ b/selftest/target/Samba4.pm
12486     @@ -1734,9 +1734,23 @@ sub provision_ad_dc_ntvfs($$)
12487     server require schannel:schannel10\$ = no
12488     server require schannel:schannel11\$ = no
12489     server require schannel:torturetest\$ = no
12490     + server schannel require seal:schannel0\$ = no
12491     + server schannel require seal:schannel1\$ = no
12492     + server schannel require seal:schannel2\$ = no
12493     + server schannel require seal:schannel3\$ = no
12494     + server schannel require seal:schannel4\$ = no
12495     + server schannel require seal:schannel5\$ = no
12496     + server schannel require seal:schannel6\$ = no
12497     + server schannel require seal:schannel7\$ = no
12498     + server schannel require seal:schannel8\$ = no
12499     + server schannel require seal:schannel9\$ = no
12500     + server schannel require seal:schannel10\$ = no
12501     + server schannel require seal:schannel11\$ = no
12502     + server schannel require seal:torturetest\$ = no
12503    
12504     # needed for 'samba.tests.auth_log' tests
12505     server require schannel:LOCALDC\$ = no
12506     + server schannel require seal:LOCALDC\$ = no
12507     ";
12508     my $extra_provision_options = ["--use-ntvfs"];
12509     my $ret = $self->provision($prefix,
12510     @@ -2166,6 +2180,19 @@ sub provision_ad_dc($$$$$$)
12511     server require schannel:schannel10\$ = no
12512     server require schannel:schannel11\$ = no
12513     server require schannel:torturetest\$ = no
12514     + server schannel require seal:schannel0\$ = no
12515     + server schannel require seal:schannel1\$ = no
12516     + server schannel require seal:schannel2\$ = no
12517     + server schannel require seal:schannel3\$ = no
12518     + server schannel require seal:schannel4\$ = no
12519     + server schannel require seal:schannel5\$ = no
12520     + server schannel require seal:schannel6\$ = no
12521     + server schannel require seal:schannel7\$ = no
12522     + server schannel require seal:schannel8\$ = no
12523     + server schannel require seal:schannel9\$ = no
12524     + server schannel require seal:schannel10\$ = no
12525     + server schannel require seal:schannel11\$ = no
12526     + server schannel require seal:torturetest\$ = no
12527    
12528     auth event notification = true
12529     dsdb event notification = true
12530     diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
12531     index 474d0806e6b..343cd53473c 100644
12532     --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
12533     +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
12534     @@ -65,9 +65,11 @@ static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_connection_context
12535     bool global_reject_md5_client = lpcfg_reject_md5_clients(lp_ctx);
12536     int schannel = lpcfg_server_schannel(lp_ctx);
12537     bool schannel_global_required = (schannel == true);
12538     + bool global_require_seal = lpcfg_server_schannel_require_seal(lp_ctx);
12539     static bool warned_global_nt4_once = false;
12540     static bool warned_global_md5_once = false;
12541     static bool warned_global_schannel_once = false;
12542     + static bool warned_global_seal_once = false;
12543    
12544     if (global_allow_nt4_crypto && !warned_global_nt4_once) {
12545     /*
12546     @@ -99,6 +101,16 @@ static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_connection_context
12547     warned_global_schannel_once = true;
12548     }
12549    
12550     + if (!global_require_seal && !warned_global_seal_once) {
12551     + /*
12552     + * We want admins to notice their misconfiguration!
12553     + */
12554     + D_ERR("CVE-2022-38023 (and others): "
12555     + "Please configure 'server schannel require seal = yes' (the default), "
12556     + "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
12557     + warned_global_seal_once = true;
12558     + }
12559     +
12560     return dcesrv_interface_bind_reject_connect(context, iface);
12561     }
12562    
12563     @@ -854,6 +866,10 @@ struct dcesrv_netr_check_schannel_state {
12564     bool schannel_required;
12565     bool schannel_explicitly_set;
12566    
12567     + bool seal_global_required;
12568     + bool seal_required;
12569     + bool seal_explicitly_set;
12570     +
12571     NTSTATUS result;
12572     };
12573    
12574     @@ -868,6 +884,9 @@ static NTSTATUS dcesrv_netr_check_schannel_get_state(struct dcesrv_call_state *d
12575     bool schannel_global_required = (schannel == true);
12576     bool schannel_required = schannel_global_required;
12577     const char *explicit_opt = NULL;
12578     + bool global_require_seal = lpcfg_server_schannel_require_seal(lp_ctx);
12579     + bool require_seal = global_require_seal;
12580     + const char *explicit_seal_opt = NULL;
12581     #define DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC (NETLOGON_SERVER_PIPE_STATE_MAGIC+1)
12582     struct dcesrv_netr_check_schannel_state *s = NULL;
12583     NTSTATUS status;
12584     @@ -905,6 +924,19 @@ new_state:
12585     s->auth_level = auth_level;
12586     s->result = NT_STATUS_MORE_PROCESSING_REQUIRED;
12587    
12588     + /*
12589     + * We don't use lpcfg_parm_bool(), as we
12590     + * need the explicit_opt pointer in order to
12591     + * adjust the debug messages.
12592     + */
12593     + explicit_seal_opt = lpcfg_get_parametric(lp_ctx,
12594     + NULL,
12595     + "server schannel require seal",
12596     + creds->account_name);
12597     + if (explicit_seal_opt != NULL) {
12598     + require_seal = lp_bool(explicit_seal_opt);
12599     + }
12600     +
12601     /*
12602     * We don't use lpcfg_parm_bool(), as we
12603     * need the explicit_opt pointer in order to
12604     @@ -922,6 +954,10 @@ new_state:
12605     s->schannel_required = schannel_required;
12606     s->schannel_explicitly_set = explicit_opt != NULL;
12607    
12608     + s->seal_global_required = global_require_seal;
12609     + s->seal_required = require_seal;
12610     + s->seal_explicitly_set = explicit_seal_opt != NULL;
12611     +
12612     status = dcesrv_iface_state_store_conn(dce_call,
12613     DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
12614     s);
12615     @@ -943,6 +979,10 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
12616     "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
12617     int CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
12618     "CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
12619     + int CVE_2022_38023_warn_level = lpcfg_parm_int(lp_ctx, NULL,
12620     + "CVE_2022_38023", "warn_about_unused_debug_level", DBGLVL_ERR);
12621     + int CVE_2022_38023_error_level = lpcfg_parm_int(lp_ctx, NULL,
12622     + "CVE_2022_38023", "error_debug_level", DBGLVL_ERR);
12623     TALLOC_CTX *frame = talloc_stackframe();
12624     unsigned int dbg_lvl = DBGLVL_DEBUG;
12625     const char *opname = "<unknown>";
12626     @@ -972,18 +1012,107 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
12627     }
12628    
12629     DEBUG(dbg_lvl, (
12630     - "CVE-2020-1472(ZeroLogon): "
12631     + "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
12632     + "%s request (opnum[%u]) %s schannel from "
12633     + "client_account[%s] client_computer_name[%s] %s\n",
12634     + opname, opnum, reason,
12635     + log_escape(frame, creds->account_name),
12636     + log_escape(frame, creds->computer_name),
12637     + nt_errstr(s->result)));
12638     + TALLOC_FREE(frame);
12639     + return s->result;
12640     + }
12641     +
12642     + if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
12643     + s->auth_level == DCERPC_AUTH_LEVEL_PRIVACY)
12644     + {
12645     + s->result = NT_STATUS_OK;
12646     +
12647     + if (s->schannel_explicitly_set && !s->schannel_required) {
12648     + dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
12649     + } else if (!s->schannel_required) {
12650     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
12651     + }
12652     + if (s->seal_explicitly_set && !s->seal_required) {
12653     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
12654     + } else if (!s->seal_required) {
12655     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
12656     + }
12657     +
12658     + DEBUG(dbg_lvl, (
12659     + "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
12660     "%s request (opnum[%u]) %s schannel from "
12661     "client_account[%s] client_computer_name[%s] %s\n",
12662     opname, opnum, reason,
12663     log_escape(frame, creds->account_name),
12664     log_escape(frame, creds->computer_name),
12665     nt_errstr(s->result)));
12666     +
12667     + if (s->schannel_explicitly_set && !s->schannel_required) {
12668     + DEBUG(CVE_2020_1472_warn_level, (
12669     + "CVE-2020-1472(ZeroLogon): "
12670     + "Option 'server require schannel:%s = no' not needed for '%s'!\n",
12671     + log_escape(frame, creds->account_name),
12672     + log_escape(frame, creds->computer_name)));
12673     + }
12674     +
12675     + if (s->seal_explicitly_set && !s->seal_required) {
12676     + DEBUG(CVE_2022_38023_warn_level, (
12677     + "CVE-2022-38023: "
12678     + "Option 'server schannel require seal:%s = no' not needed for '%s'!\n",
12679     + log_escape(frame, creds->account_name),
12680     + log_escape(frame, creds->computer_name)));
12681     + }
12682     +
12683     TALLOC_FREE(frame);
12684     return s->result;
12685     }
12686    
12687     if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
12688     + if (s->seal_required) {
12689     + s->result = NT_STATUS_ACCESS_DENIED;
12690     +
12691     + if (s->seal_explicitly_set) {
12692     + dbg_lvl = DBGLVL_NOTICE;
12693     + } else {
12694     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
12695     + }
12696     + if (s->schannel_explicitly_set && !s->schannel_required) {
12697     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
12698     + }
12699     +
12700     + DEBUG(dbg_lvl, (
12701     + "CVE-2022-38023: "
12702     + "%s request (opnum[%u]) %s schannel from "
12703     + "from client_account[%s] client_computer_name[%s] %s\n",
12704     + opname, opnum, reason,
12705     + log_escape(frame, creds->account_name),
12706     + log_escape(frame, creds->computer_name),
12707     + nt_errstr(s->result)));
12708     + if (s->seal_explicitly_set) {
12709     + D_NOTICE("CVE-2022-38023: Option "
12710     + "'server schannel require seal:%s = yes' "
12711     + "rejects access for client.\n",
12712     + log_escape(frame, creds->account_name));
12713     + } else {
12714     + DEBUG(CVE_2020_1472_error_level, (
12715     + "CVE-2022-38023: Check if option "
12716     + "'server schannel require seal:%s = no' "
12717     + "might be needed for a legacy client.\n",
12718     + log_escape(frame, creds->account_name)));
12719     + }
12720     + if (s->schannel_explicitly_set && !s->schannel_required) {
12721     + DEBUG(CVE_2020_1472_warn_level, (
12722     + "CVE-2020-1472(ZeroLogon): Option "
12723     + "'server require schannel:%s = no' "
12724     + "not needed for '%s'!\n",
12725     + log_escape(frame, creds->account_name),
12726     + log_escape(frame, creds->computer_name)));
12727     + }
12728     + TALLOC_FREE(frame);
12729     + return s->result;
12730     + }
12731     +
12732     s->result = NT_STATUS_OK;
12733    
12734     if (s->schannel_explicitly_set && !s->schannel_required) {
12735     @@ -991,6 +1120,11 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
12736     } else if (!s->schannel_required) {
12737     dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
12738     }
12739     + if (s->seal_explicitly_set && !s->seal_required) {
12740     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
12741     + } else if (!s->seal_required) {
12742     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
12743     + }
12744    
12745     DEBUG(dbg_lvl, (
12746     "CVE-2020-1472(ZeroLogon): "
12747     @@ -1007,11 +1141,81 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
12748     log_escape(frame, creds->account_name),
12749     log_escape(frame, creds->computer_name)));
12750     }
12751     + if (s->seal_explicitly_set && !s->seal_required) {
12752     + D_INFO("CVE-2022-38023: "
12753     + "Option 'server schannel require seal:%s = no' still needed for '%s'!\n",
12754     + log_escape(frame, creds->account_name),
12755     + log_escape(frame, creds->computer_name));
12756     + } else if (!s->seal_required) {
12757     + /*
12758     + * admins should set
12759     + * server schannel require seal:COMPUTER$ = no
12760     + * in order to avoid the level 0 messages.
12761     + * Over time they can switch the global value
12762     + * to be strict.
12763     + */
12764     + DEBUG(CVE_2022_38023_error_level, (
12765     + "CVE-2022-38023: "
12766     + "Please use 'server schannel require seal:%s = no' "
12767     + "for '%s' to avoid this warning!\n",
12768     + log_escape(frame, creds->account_name),
12769     + log_escape(frame, creds->computer_name)));
12770     + }
12771    
12772     TALLOC_FREE(frame);
12773     return s->result;
12774     }
12775    
12776     + if (s->seal_required) {
12777     + s->result = NT_STATUS_ACCESS_DENIED;
12778     +
12779     + if (s->seal_explicitly_set) {
12780     + dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
12781     + } else {
12782     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
12783     + }
12784     + if (!s->schannel_explicitly_set) {
12785     + dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
12786     + } else if (s->schannel_required) {
12787     + dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
12788     + }
12789     +
12790     + DEBUG(dbg_lvl, (
12791     + "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
12792     + "%s request (opnum[%u]) %s schannel from "
12793     + "from client_account[%s] client_computer_name[%s] %s\n",
12794     + opname, opnum, reason,
12795     + log_escape(frame, creds->account_name),
12796     + log_escape(frame, creds->computer_name),
12797     + nt_errstr(s->result)));
12798     + if (s->seal_explicitly_set) {
12799     + D_NOTICE("CVE-2022-38023: Option "
12800     + "'server schannel require seal:%s = yes' "
12801     + "rejects access for client.\n",
12802     + log_escape(frame, creds->account_name));
12803     + } else {
12804     + DEBUG(CVE_2022_38023_error_level, (
12805     + "CVE-2022-38023: Check if option "
12806     + "'server schannel require seal:%s = no' "
12807     + "might be needed for a legacy client.\n",
12808     + log_escape(frame, creds->account_name)));
12809     + }
12810     + if (!s->schannel_explicitly_set) {
12811     + DEBUG(CVE_2020_1472_error_level, (
12812     + "CVE-2020-1472(ZeroLogon): Check if option "
12813     + "'server require schannel:%s = no' "
12814     + "might be needed for a legacy client.\n",
12815     + log_escape(frame, creds->account_name)));
12816     + } else if (s->schannel_required) {
12817     + D_NOTICE("CVE-2022-38023: Option "
12818     + "'server require schannel:%s = yes' "
12819     + "also rejects access for client.\n",
12820     + log_escape(frame, creds->account_name));
12821     + }
12822     + TALLOC_FREE(frame);
12823     + return s->result;
12824     + }
12825     +
12826     if (s->schannel_required) {
12827     s->result = NT_STATUS_ACCESS_DENIED;
12828    
12829     @@ -1020,6 +1224,9 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
12830     } else {
12831     dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
12832     }
12833     + if (!s->seal_explicitly_set) {
12834     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
12835     + }
12836    
12837     DEBUG(dbg_lvl, (
12838     "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
12839     @@ -1041,12 +1248,25 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
12840     "might be needed for a legacy client.\n",
12841     log_escape(frame, creds->account_name)));
12842     }
12843     + if (!s->seal_explicitly_set) {
12844     + DEBUG(CVE_2022_38023_error_level, (
12845     + "CVE-2022-38023: Check if option "
12846     + "'server schannel require seal:%s = no' "
12847     + "might be needed for a legacy client.\n",
12848     + log_escape(frame, creds->account_name)));
12849     + }
12850     TALLOC_FREE(frame);
12851     return s->result;
12852     }
12853    
12854     s->result = NT_STATUS_OK;
12855    
12856     + if (s->seal_explicitly_set) {
12857     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
12858     + } else {
12859     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
12860     + }
12861     +
12862     if (s->schannel_explicitly_set) {
12863     dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
12864     } else {
12865     @@ -1062,6 +1282,28 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
12866     log_escape(frame, creds->computer_name),
12867     nt_errstr(s->result)));
12868    
12869     + if (s->seal_explicitly_set) {
12870     + D_INFO("CVE-2022-38023: Option "
12871     + "'server schannel require seal:%s = no' "
12872     + "still needed for '%s'!\n",
12873     + log_escape(frame, creds->account_name),
12874     + log_escape(frame, creds->computer_name));
12875     + } else {
12876     + /*
12877     + * admins should set
12878     + * server schannel require seal:COMPUTER$ = no
12879     + * in order to avoid the level 0 messages.
12880     + * Over time they can switch the global value
12881     + * to be strict.
12882     + */
12883     + DEBUG(CVE_2022_38023_error_level, (
12884     + "CVE-2022-38023: Please use "
12885     + "'server schannel require seal:%s = no' "
12886     + "for '%s' to avoid this warning!\n",
12887     + log_escape(frame, creds->account_name),
12888     + log_escape(frame, creds->computer_name)));
12889     + }
12890     +
12891     if (s->schannel_explicitly_set) {
12892     D_INFO("CVE-2020-1472(ZeroLogon): Option "
12893     "'server require schannel:%s = no' "
12894     --
12895     2.39.0
12896    
12897    
12898     From fe38dc0186d3505db4c105f78dc46c2270c43240 Mon Sep 17 00:00:00 2001
12899     From: Stefan Metzmacher <metze@samba.org>
12900     Date: Wed, 30 Nov 2022 15:13:47 +0100
12901     Subject: [PATCH 129/142] CVE-2022-38023 testparm: warn about server/client
12902     schannel != yes
12903    
12904     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
12905    
12906     Signed-off-by: Stefan Metzmacher <metze@samba.org>
12907     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
12908     Reviewed-by: Ralph Boehme <slow@samba.org>
12909     (cherry picked from commit f964c0c357214637f80d0089723b9b11d1b38f7e)
12910     ---
12911     source3/utils/testparm.c | 21 +++++++++++++++++++++
12912     1 file changed, 21 insertions(+)
12913    
12914     diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c
12915     index c673ef71a92..aa990b729d7 100644
12916     --- a/source3/utils/testparm.c
12917     +++ b/source3/utils/testparm.c
12918     @@ -522,6 +522,27 @@ static int do_global_checks(void)
12919     ret = 1;
12920     }
12921    
12922     + if (lp_server_schannel() != true) { /* can be 'auto' */
12923     + fprintf(stderr,
12924     + "WARNING: You have not configured "
12925     + "'server schannel = yes' (the default). "
12926     + "Your server is vulernable to \"ZeroLogon\" "
12927     + "(CVE-2020-1472)\n"
12928     + "If required use individual "
12929     + "'server require schannel:COMPUTERACCOUNT$ = no' "
12930     + "options\n\n");
12931     + }
12932     + if (lp_client_schannel() != true) { /* can be 'auto' */
12933     + fprintf(stderr,
12934     + "WARNING: You have not configured "
12935     + "'client schannel = yes' (the default). "
12936     + "Your server is vulernable to \"ZeroLogon\" "
12937     + "(CVE-2020-1472)\n"
12938     + "If required use individual "
12939     + "'client schannel:NETBIOSDOMAIN = no' "
12940     + "options\n\n");
12941     + }
12942     +
12943     return ret;
12944     }
12945    
12946     --
12947     2.39.0
12948    
12949    
12950     From c870a61377d0245a3fd25f5d5c8663d965fe469a Mon Sep 17 00:00:00 2001
12951     From: Stefan Metzmacher <metze@samba.org>
12952     Date: Tue, 6 Dec 2022 13:36:17 +0100
12953     Subject: [PATCH 130/142] CVE-2022-38023 testparm: warn about unsecure schannel
12954     related options
12955    
12956     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
12957    
12958     Signed-off-by: Stefan Metzmacher <metze@samba.org>
12959     Reviewed-by: Andrew Bartlett <abartlet@samba.org>
12960     Reviewed-by: Ralph Boehme <slow@samba.org>
12961     (cherry picked from commit 4d540473c3d43d048a30dd63efaeae9ff87b2aeb)
12962     ---
12963     source3/utils/testparm.c | 61 ++++++++++++++++++++++++++++++++++++++++
12964     1 file changed, 61 insertions(+)
12965    
12966     diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c
12967     index aa990b729d7..f9253d323aa 100644
12968     --- a/source3/utils/testparm.c
12969     +++ b/source3/utils/testparm.c
12970     @@ -532,6 +532,37 @@ static int do_global_checks(void)
12971     "'server require schannel:COMPUTERACCOUNT$ = no' "
12972     "options\n\n");
12973     }
12974     + if (lp_allow_nt4_crypto()) {
12975     + fprintf(stderr,
12976     + "WARNING: You have not configured "
12977     + "'allow nt4 crypto = no' (the default). "
12978     + "Your server is vulernable to "
12979     + "CVE-2022-38023 and others!\n"
12980     + "If required use individual "
12981     + "'allow nt4 crypto:COMPUTERACCOUNT$ = yes' "
12982     + "options\n\n");
12983     + }
12984     + if (!lp_reject_md5_clients()) {
12985     + fprintf(stderr,
12986     + "WARNING: You have not configured "
12987     + "'reject md5 clients = yes' (the default). "
12988     + "Your server is vulernable to "
12989     + "CVE-2022-38023!\n"
12990     + "If required use individual "
12991     + "'server reject md5 schannel:COMPUTERACCOUNT$ = yes' "
12992     + "options\n\n");
12993     + }
12994     + if (!lp_server_schannel_require_seal()) {
12995     + fprintf(stderr,
12996     + "WARNING: You have not configured "
12997     + "'server schannel require seal = yes' (the default). "
12998     + "Your server is vulernable to "
12999     + "CVE-2022-38023!\n"
13000     + "If required use individual "
13001     + "'server schannel require seal:COMPUTERACCOUNT$ = no' "
13002     + "options\n\n");
13003     + }
13004     +
13005     if (lp_client_schannel() != true) { /* can be 'auto' */
13006     fprintf(stderr,
13007     "WARNING: You have not configured "
13008     @@ -542,6 +573,36 @@ static int do_global_checks(void)
13009     "'client schannel:NETBIOSDOMAIN = no' "
13010     "options\n\n");
13011     }
13012     + if (!lp_reject_md5_servers()) {
13013     + fprintf(stderr,
13014     + "WARNING: You have not configured "
13015     + "'reject md5 servers = yes' (the default). "
13016     + "Your server is vulernable to "
13017     + "CVE-2022-38023\n"
13018     + "If required use individual "
13019     + "'reject md5 servers:NETBIOSDOMAIN = no' "
13020     + "options\n\n");
13021     + }
13022     + if (!lp_require_strong_key()) {
13023     + fprintf(stderr,
13024     + "WARNING: You have not configured "
13025     + "'require strong key = yes' (the default). "
13026     + "Your server is vulernable to "
13027     + "CVE-2022-38023\n"
13028     + "If required use individual "
13029     + "'require strong key:NETBIOSDOMAIN = no' "
13030     + "options\n\n");
13031     + }
13032     + if (!lp_winbind_sealed_pipes()) {
13033     + fprintf(stderr,
13034     + "WARNING: You have not configured "
13035     + "'winbind sealed pipes = yes' (the default). "
13036     + "Your server is vulernable to "
13037     + "CVE-2022-38023\n"
13038     + "If required use individual "
13039     + "'winbind sealed pipes:NETBIOSDOMAIN = no' "
13040     + "options\n\n");
13041     + }
13042    
13043     return ret;
13044     }
13045     --
13046     2.39.0
13047    
13048    
13049     From 938168a5f7c3225562ed772bf8a9bbecc0badb62 Mon Sep 17 00:00:00 2001
13050     From: Andreas Schneider <asn@samba.org>
13051     Date: Mon, 12 Sep 2022 16:31:05 +0200
13052     Subject: [PATCH 131/142] s3:auth: Flush the GETPWSID in memory cache for NTLM
13053     auth
13054    
13055     Example valgrind output:
13056    
13057     ==22502== 22,747,002 bytes in 21,049 blocks are possibly lost in loss record 1,075 of 1,075
13058     ==22502== at 0x4C29F73: malloc (vg_replace_malloc.c:309)
13059     ==22502== by 0x11D7089C: _talloc_pooled_object (in /usr/lib64/libtalloc.so.2.1.16)
13060     ==22502== by 0x9027834: tcopy_passwd (in /usr/lib64/libsmbconf.so.0)
13061     ==22502== by 0x6A1E1A3: pdb_copy_sam_account (in /usr/lib64/libsamba-passdb.so.0.27.2)
13062     ==22502== by 0x6A28AB7: pdb_getsampwnam (in /usr/lib64/libsamba-passdb.so.0.27.2)
13063     ==22502== by 0x65D0BC4: check_sam_security (in /usr/lib64/samba/libauth-samba4.so)
13064     ==22502== by 0x65C70F0: ??? (in /usr/lib64/samba/libauth-samba4.so)
13065     ==22502== by 0x65C781A: auth_check_ntlm_password (in /usr/lib64/samba/libauth-samba4.so)
13066     ==22502== by 0x14E464: ??? (in /usr/sbin/winbindd)
13067     ==22502== by 0x151CED: winbind_dual_SamLogon (in /usr/sbin/winbindd)
13068     ==22502== by 0x152072: winbindd_dual_pam_auth_crap (in /usr/sbin/winbindd)
13069     ==22502== by 0x167DE0: ??? (in /usr/sbin/winbindd)
13070     ==22502== by 0x12F29B12: tevent_common_invoke_fd_handler (in /usr/lib64/libtevent.so.0.9.39)
13071     ==22502== by 0x12F30086: ??? (in /usr/lib64/libtevent.so.0.9.39)
13072     ==22502== by 0x12F2E056: ??? (in /usr/lib64/libtevent.so.0.9.39)
13073     ==22502== by 0x12F2925C: _tevent_loop_once (in /usr/lib64/libtevent.so.0.9.39)
13074     ==22502== by 0x16A243: ??? (in /usr/sbin/winbindd)
13075     ==22502== by 0x16AA04: ??? (in /usr/sbin/winbindd)
13076     ==22502== by 0x12F29F68: tevent_common_invoke_immediate_handler (in /usr/lib64/libtevent.so.0.9.39)
13077     ==22502== by 0x12F29F8F: tevent_common_loop_immediate (in /usr/lib64/libtevent.so.0.9.39)
13078     ==22502== by 0x12F2FE3C: ??? (in /usr/lib64/libtevent.so.0.9.39)
13079     ==22502== by 0x12F2E056: ??? (in /usr/lib64/libtevent.so.0.9.39)
13080     ==22502== by 0x12F2925C: _tevent_loop_once (in /usr/lib64/libtevent.so.0.9.39)
13081     ==22502== by 0x12F4C7: main (in /usr/sbin/winbindd)
13082    
13083     You can find one for each string in pdb_copy_sam_account(), in total
13084     this already has 67 MB in total for this valgrind run.
13085    
13086     pdb_getsampwnam() -> memcache_add_talloc(NULL, PDB_GETPWSID_CACHE, ...)
13087    
13088     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15169
13089    
13090     Signed-off-by: Andreas Schneider <asn@samba.org>
13091     Reviewed-by: Jeremy Allison <jra@samba.org>
13092    
13093     Autobuild-User(master): Jeremy Allison <jra@samba.org>
13094     Autobuild-Date(master): Fri Sep 16 20:30:31 UTC 2022 on sn-devel-184
13095    
13096     (cherry picked from commit 9ef2f7345f0d387567fca598cc7008af95598903)
13097     ---
13098     source3/auth/check_samsec.c | 8 ++++++--
13099     1 file changed, 6 insertions(+), 2 deletions(-)
13100    
13101     diff --git a/source3/auth/check_samsec.c b/source3/auth/check_samsec.c
13102     index 53b6da53dc1..4276c3060ed 100644
13103     --- a/source3/auth/check_samsec.c
13104     +++ b/source3/auth/check_samsec.c
13105     @@ -24,6 +24,7 @@
13106     #include "auth.h"
13107     #include "../libcli/auth/libcli_auth.h"
13108     #include "passdb.h"
13109     +#include "lib/util/memcache.h"
13110    
13111     #undef DBGC_CLASS
13112     #define DBGC_CLASS DBGC_AUTH
13113     @@ -487,8 +488,6 @@ NTSTATUS check_sam_security(const DATA_BLOB *challenge,
13114     nt_status = make_server_info_sam(mem_ctx, sampass, server_info);
13115     unbecome_root();
13116    
13117     - TALLOC_FREE(sampass);
13118     -
13119     if (!NT_STATUS_IS_OK(nt_status)) {
13120     DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status)));
13121     goto done;
13122     @@ -507,6 +506,11 @@ NTSTATUS check_sam_security(const DATA_BLOB *challenge,
13123     (*server_info)->nss_token |= user_info->was_mapped;
13124    
13125     done:
13126     + /*
13127     + * Always flush the getpwsid cache or this will grow indefinetly for
13128     + * each NTLM auththentication.
13129     + */
13130     + memcache_flush(NULL, PDB_GETPWSID_CACHE);
13131     TALLOC_FREE(sampass);
13132     data_blob_free(&user_sess_key);
13133     data_blob_free(&lm_sess_key);
13134     --
13135     2.39.0
13136    
13137    
13138     From 296612a8c1dda253e1f2c0618f1f8330e2e23b34 Mon Sep 17 00:00:00 2001
13139     From: Samuel Cabrero <scabrero@suse.de>
13140     Date: Thu, 22 Dec 2022 16:46:15 +0100
13141     Subject: [PATCH 132/142] CVE-2022-38023 selftest:Samba3: avoid global 'server
13142     schannel = auto'
13143    
13144     Instead of using the generic deprecated option use the specific
13145     server require schannel:COMPUTERACCOUNT = no in order to allow
13146     legacy tests for pass.
13147    
13148     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
13149    
13150     Signed-off-by: Samuel Cabrero <scabrero@samba.org>
13151     Reviewed-by: Andreas Schneider <asn@samba.org>
13152     (cherry picked from commit 3cd18690f83d2f85e847fc703ac127b4b04189fc)
13153     ---
13154     selftest/target/Samba3.pm | 17 ++++++++++++++++-
13155     1 file changed, 16 insertions(+), 1 deletion(-)
13156    
13157     diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
13158     index 7034127ef0b..0c14f02be11 100755
13159     --- a/selftest/target/Samba3.pm
13160     +++ b/selftest/target/Samba3.pm
13161     @@ -199,7 +199,6 @@ sub setup_nt4_dc
13162     lanman auth = yes
13163     ntlm auth = yes
13164     raw NTLMv2 auth = yes
13165     - server schannel = auto
13166    
13167     rpc_server:epmapper = external
13168     rpc_server:spoolss = external
13169     @@ -213,6 +212,22 @@ sub setup_nt4_dc
13170     rpc_daemon:spoolssd = fork
13171     rpc_daemon:lsasd = fork
13172     rpc_daemon:fssd = fork
13173     +
13174     + CVE_2020_1472:warn_about_unused_debug_level = 3
13175     + server require schannel:schannel0\$ = no
13176     + server require schannel:schannel1\$ = no
13177     + server require schannel:schannel2\$ = no
13178     + server require schannel:schannel3\$ = no
13179     + server require schannel:schannel4\$ = no
13180     + server require schannel:schannel5\$ = no
13181     + server require schannel:schannel6\$ = no
13182     + server require schannel:schannel7\$ = no
13183     + server require schannel:schannel8\$ = no
13184     + server require schannel:schannel9\$ = no
13185     + server require schannel:schannel10\$ = no
13186     + server require schannel:schannel11\$ = no
13187     + server require schannel:torturetest\$ = no
13188     +
13189     fss: sequence timeout = 1
13190     check parent directory delete on close = yes
13191     ";
13192     --
13193     2.39.0
13194    
13195    
13196     From 1a90fc7cbc4054f9815ffaca710b5bdba0dffd6f Mon Sep 17 00:00:00 2001
13197     From: Samuel Cabrero <scabrero@suse.de>
13198     Date: Thu, 22 Dec 2022 11:33:12 +0100
13199     Subject: [PATCH 133/142] CVE-2022-38023 s3:rpc_server/netlogon: add
13200     talloc_stackframe() to dcesrv_netr_creds_server_step_check()
13201    
13202     This will simplify the following changes.
13203    
13204     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
13205    
13206     Signed-off-by: Samuel Cabrero <scabrero@samba.org>
13207     ---
13208     source3/rpc_server/netlogon/srv_netlog_nt.c | 38 ++++++++++++---------
13209     1 file changed, 22 insertions(+), 16 deletions(-)
13210    
13211     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
13212     index 7f6704adbda..f9b674d0052 100644
13213     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
13214     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
13215     @@ -1071,6 +1071,7 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13216     struct netr_Authenticator *return_authenticator,
13217     struct netlogon_creds_CredentialState **creds_out)
13218     {
13219     + TALLOC_CTX *frame = talloc_stackframe();
13220     NTSTATUS status;
13221     bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
13222     bool schannel_required = schannel_global_required;
13223     @@ -1092,19 +1093,19 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13224    
13225     auth_type = p->auth.auth_type;
13226    
13227     - lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers());
13228     + lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
13229     if (lp_ctx == NULL) {
13230     DEBUG(0, ("loadparm_init_s3 failed\n"));
13231     + TALLOC_FREE(frame);
13232     return NT_STATUS_INTERNAL_ERROR;
13233     }
13234    
13235     status = schannel_check_creds_state(mem_ctx, lp_ctx,
13236     computer_name, received_authenticator,
13237     return_authenticator, &creds);
13238     - talloc_unlink(mem_ctx, lp_ctx);
13239     -
13240     if (!NT_STATUS_IS_OK(status)) {
13241     ZERO_STRUCTP(return_authenticator);
13242     + TALLOC_FREE(frame);
13243     return status;
13244     }
13245    
13246     @@ -1125,6 +1126,7 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13247     if (schannel_required) {
13248     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
13249     *creds_out = creds;
13250     + TALLOC_FREE(frame);
13251     return NT_STATUS_OK;
13252     }
13253    
13254     @@ -1132,13 +1134,15 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13255     "%s request (opnum[%u]) without schannel from "
13256     "client_account[%s] client_computer_name[%s]\n",
13257     opname, opnum,
13258     - log_escape(mem_ctx, creds->account_name),
13259     - log_escape(mem_ctx, creds->computer_name));
13260     + log_escape(frame, creds->account_name),
13261     + log_escape(frame, creds->computer_name));
13262     DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
13263     - "'server require schannel:%s = no' is needed! \n",
13264     - log_escape(mem_ctx, creds->account_name));
13265     + "'server require schannel:%s = no' "
13266     + "might be needed for a legacy client.\n",
13267     + log_escape(frame, creds->account_name));
13268     TALLOC_FREE(creds);
13269     ZERO_STRUCTP(return_authenticator);
13270     + TALLOC_FREE(frame);
13271     return NT_STATUS_ACCESS_DENIED;
13272     }
13273    
13274     @@ -1157,13 +1161,14 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13275     "%s request (opnum[%u]) WITH schannel from "
13276     "client_account[%s] client_computer_name[%s]\n",
13277     opname, opnum,
13278     - log_escape(mem_ctx, creds->account_name),
13279     - log_escape(mem_ctx, creds->computer_name));
13280     + log_escape(frame, creds->account_name),
13281     + log_escape(frame, creds->computer_name));
13282     DBG_ERR("CVE-2020-1472(ZeroLogon): "
13283     "Option 'server require schannel:%s = no' not needed!?\n",
13284     - log_escape(mem_ctx, creds->account_name));
13285     + log_escape(frame, creds->account_name));
13286    
13287     *creds_out = creds;
13288     + TALLOC_FREE(frame);
13289     return NT_STATUS_OK;
13290     }
13291    
13292     @@ -1172,24 +1177,25 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13293     "%s request (opnum[%u]) without schannel from "
13294     "client_account[%s] client_computer_name[%s]\n",
13295     opname, opnum,
13296     - log_escape(mem_ctx, creds->account_name),
13297     - log_escape(mem_ctx, creds->computer_name));
13298     + log_escape(frame, creds->account_name),
13299     + log_escape(frame, creds->computer_name));
13300     DBG_INFO("CVE-2020-1472(ZeroLogon): "
13301     "Option 'server require schannel:%s = no' still needed!\n",
13302     - log_escape(mem_ctx, creds->account_name));
13303     + log_escape(frame, creds->account_name));
13304     } else {
13305     DBG_ERR("CVE-2020-1472(ZeroLogon): "
13306     "%s request (opnum[%u]) without schannel from "
13307     "client_account[%s] client_computer_name[%s]\n",
13308     opname, opnum,
13309     - log_escape(mem_ctx, creds->account_name),
13310     - log_escape(mem_ctx, creds->computer_name));
13311     + log_escape(frame, creds->account_name),
13312     + log_escape(frame, creds->computer_name));
13313     DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
13314     "'server require schannel:%s = no' might be needed!\n",
13315     - log_escape(mem_ctx, creds->account_name));
13316     + log_escape(frame, creds->account_name));
13317     }
13318    
13319     *creds_out = creds;
13320     + TALLOC_FREE(frame);
13321     return NT_STATUS_OK;
13322     }
13323    
13324     --
13325     2.39.0
13326    
13327    
13328     From d3e503e670501186fcce9702b72cda3b03afc0cf Mon Sep 17 00:00:00 2001
13329     From: Samuel Cabrero <scabrero@suse.de>
13330     Date: Wed, 21 Dec 2022 18:17:57 +0100
13331     Subject: [PATCH 134/142] CVE-2022-38023 s3:rpc_server/netlogon: re-order
13332     checking in netr_creds_server_step_check()
13333    
13334     This will simplify the following changes.
13335    
13336     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
13337    
13338     Signed-off-by: Samuel Cabrero <scabrero@samba.org>
13339     ---
13340     source3/rpc_server/netlogon/srv_netlog_nt.c | 40 ++++++++++-----------
13341     1 file changed, 19 insertions(+), 21 deletions(-)
13342    
13343     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
13344     index f9b674d0052..b42794eea8d 100644
13345     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
13346     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
13347     @@ -1123,13 +1123,27 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13348     schannel_required = lp_bool(explicit_opt);
13349     }
13350    
13351     - if (schannel_required) {
13352     - if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
13353     - *creds_out = creds;
13354     - TALLOC_FREE(frame);
13355     - return NT_STATUS_OK;
13356     + if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
13357     + if (!schannel_required) {
13358     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
13359     + "%s request (opnum[%u]) WITH schannel from "
13360     + "client_account[%s] client_computer_name[%s]\n",
13361     + opname, opnum,
13362     + log_escape(frame, creds->account_name),
13363     + log_escape(frame, creds->computer_name));
13364     + }
13365     + if (explicit_opt != NULL && !schannel_required) {
13366     + DBG_ERR("CVE-2020-1472(ZeroLogon): "
13367     + "Option 'server require schannel:%s = no' not needed!?\n",
13368     + log_escape(frame, creds->account_name));
13369     }
13370    
13371     + *creds_out = creds;
13372     + TALLOC_FREE(frame);
13373     + return NT_STATUS_OK;
13374     + }
13375     +
13376     + if (schannel_required) {
13377     DBG_ERR("CVE-2020-1472(ZeroLogon): "
13378     "%s request (opnum[%u]) without schannel from "
13379     "client_account[%s] client_computer_name[%s]\n",
13380     @@ -1156,22 +1170,6 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13381     warned_global_once = true;
13382     }
13383    
13384     - if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
13385     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
13386     - "%s request (opnum[%u]) WITH schannel from "
13387     - "client_account[%s] client_computer_name[%s]\n",
13388     - opname, opnum,
13389     - log_escape(frame, creds->account_name),
13390     - log_escape(frame, creds->computer_name));
13391     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
13392     - "Option 'server require schannel:%s = no' not needed!?\n",
13393     - log_escape(frame, creds->account_name));
13394     -
13395     - *creds_out = creds;
13396     - TALLOC_FREE(frame);
13397     - return NT_STATUS_OK;
13398     - }
13399     -
13400     if (explicit_opt != NULL) {
13401     DBG_INFO("CVE-2020-1472(ZeroLogon): "
13402     "%s request (opnum[%u]) without schannel from "
13403     --
13404     2.39.0
13405    
13406    
13407     From 44de3ae0d4b6f1a728124429dfc748c538714a05 Mon Sep 17 00:00:00 2001
13408     From: Samuel Cabrero <scabrero@suse.de>
13409     Date: Thu, 22 Dec 2022 11:35:57 +0100
13410     Subject: [PATCH 135/142] CVE-2022-38023 s3:rpc_server/netlogon: improve
13411     CVE-2020-1472(ZeroLogon) debug messages
13412    
13413     In order to avoid generating useless debug messages during make test,
13414     we will use 'CVE_2020_1472:warn_about_unused_debug_level = 3'
13415     and 'CVE_2020_1472:error_debug_level = 2' in order to avoid schannel warnings.
13416    
13417     Review with: git show -w
13418    
13419     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
13420    
13421     Signed-off-by: Samuel Cabrero <scabrero@samba.org>
13422     ---
13423     source3/rpc_server/netlogon/srv_netlog_nt.c | 149 ++++++++++++++------
13424     1 file changed, 109 insertions(+), 40 deletions(-)
13425    
13426     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
13427     index b42794eea8d..1d261c9a639 100644
13428     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
13429     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
13430     @@ -1078,9 +1078,14 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13431     const char *explicit_opt = NULL;
13432     struct loadparm_context *lp_ctx;
13433     struct netlogon_creds_CredentialState *creds = NULL;
13434     + int CVE_2020_1472_warn_level = DBGLVL_ERR;
13435     + int CVE_2020_1472_error_level = DBGLVL_ERR;
13436     + unsigned int dbg_lvl = DBGLVL_DEBUG;
13437     enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
13438     + enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
13439     uint16_t opnum = p->opnum;
13440     const char *opname = "<unknown>";
13441     + const char *reason = "<unknown>";
13442     static bool warned_global_once = false;
13443    
13444     if (creds_out != NULL) {
13445     @@ -1092,6 +1097,7 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13446     }
13447    
13448     auth_type = p->auth.auth_type;
13449     + auth_level = p->auth.auth_level;
13450    
13451     lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
13452     if (lp_ctx == NULL) {
13453     @@ -1100,6 +1106,23 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13454     return NT_STATUS_INTERNAL_ERROR;
13455     }
13456    
13457     + CVE_2020_1472_warn_level = lpcfg_parm_int(lp_ctx, NULL,
13458     + "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
13459     + CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
13460     + "CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
13461     +
13462     + if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
13463     + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
13464     + reason = "WITH SEALED";
13465     + } else if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
13466     + reason = "WITH SIGNED";
13467     + } else {
13468     + smb_panic("Schannel without SIGN/SEAL");
13469     + }
13470     + } else {
13471     + reason = "WITHOUT";
13472     + }
13473     +
13474     status = schannel_check_creds_state(mem_ctx, lp_ctx,
13475     computer_name, received_authenticator,
13476     return_authenticator, &creds);
13477     @@ -1124,40 +1147,69 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13478     }
13479    
13480     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
13481     - if (!schannel_required) {
13482     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
13483     - "%s request (opnum[%u]) WITH schannel from "
13484     - "client_account[%s] client_computer_name[%s]\n",
13485     - opname, opnum,
13486     - log_escape(frame, creds->account_name),
13487     - log_escape(frame, creds->computer_name));
13488     + status = NT_STATUS_OK;
13489     +
13490     + if (explicit_opt != NULL && !schannel_required) {
13491     + dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
13492     + } else if (!schannel_required) {
13493     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
13494     }
13495     +
13496     + DEBUG(dbg_lvl, (
13497     + "CVE-2020-1472(ZeroLogon): "
13498     + "%s request (opnum[%u]) %s schannel from "
13499     + "client_account[%s] client_computer_name[%s] %s\n",
13500     + opname, opnum, reason,
13501     + log_escape(frame, creds->account_name),
13502     + log_escape(frame, creds->computer_name),
13503     + nt_errstr(status)));
13504     +
13505     if (explicit_opt != NULL && !schannel_required) {
13506     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
13507     - "Option 'server require schannel:%s = no' not needed!?\n",
13508     - log_escape(frame, creds->account_name));
13509     + DEBUG(CVE_2020_1472_warn_level, (
13510     + "CVE-2020-1472(ZeroLogon): "
13511     + "Option 'server require schannel:%s = no' not needed for '%s'!\n",
13512     + log_escape(frame, creds->account_name),
13513     + log_escape(frame, creds->computer_name)));
13514     }
13515    
13516     *creds_out = creds;
13517     TALLOC_FREE(frame);
13518     - return NT_STATUS_OK;
13519     + return status;
13520     }
13521    
13522     if (schannel_required) {
13523     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
13524     - "%s request (opnum[%u]) without schannel from "
13525     - "client_account[%s] client_computer_name[%s]\n",
13526     - opname, opnum,
13527     - log_escape(frame, creds->account_name),
13528     - log_escape(frame, creds->computer_name));
13529     - DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
13530     - "'server require schannel:%s = no' "
13531     - "might be needed for a legacy client.\n",
13532     - log_escape(frame, creds->account_name));
13533     + status = NT_STATUS_ACCESS_DENIED;
13534     +
13535     + if (explicit_opt != NULL) {
13536     + dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
13537     + } else {
13538     + dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
13539     + }
13540     +
13541     + DEBUG(dbg_lvl, (
13542     + "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
13543     + "%s request (opnum[%u]) %s schannel from "
13544     + "client_account[%s] client_computer_name[%s] %s\n",
13545     + opname, opnum, reason,
13546     + log_escape(frame, creds->account_name),
13547     + log_escape(frame, creds->computer_name),
13548     + nt_errstr(status)));
13549     + if (explicit_opt != NULL) {
13550     + D_NOTICE("CVE-2020-1472(ZeroLogon): Option "
13551     + "'server require schannel:%s = yes' "
13552     + "rejects access for client.\n",
13553     + log_escape(frame, creds->account_name));
13554     + } else {
13555     + DEBUG(CVE_2020_1472_error_level, (
13556     + "CVE-2020-1472(ZeroLogon): Check if option "
13557     + "'server require schannel:%s = no' "
13558     + "might be needed for a legacy client.\n",
13559     + log_escape(frame, creds->account_name)));
13560     + }
13561     TALLOC_FREE(creds);
13562     ZERO_STRUCTP(return_authenticator);
13563     TALLOC_FREE(frame);
13564     - return NT_STATUS_ACCESS_DENIED;
13565     + return status;
13566     }
13567    
13568     if (!schannel_global_required && !warned_global_once) {
13569     @@ -1170,26 +1222,43 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13570     warned_global_once = true;
13571     }
13572    
13573     + status = NT_STATUS_OK;
13574     +
13575     if (explicit_opt != NULL) {
13576     - DBG_INFO("CVE-2020-1472(ZeroLogon): "
13577     - "%s request (opnum[%u]) without schannel from "
13578     - "client_account[%s] client_computer_name[%s]\n",
13579     - opname, opnum,
13580     - log_escape(frame, creds->account_name),
13581     - log_escape(frame, creds->computer_name));
13582     - DBG_INFO("CVE-2020-1472(ZeroLogon): "
13583     - "Option 'server require schannel:%s = no' still needed!\n",
13584     - log_escape(frame, creds->account_name));
13585     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
13586     } else {
13587     - DBG_ERR("CVE-2020-1472(ZeroLogon): "
13588     - "%s request (opnum[%u]) without schannel from "
13589     - "client_account[%s] client_computer_name[%s]\n",
13590     - opname, opnum,
13591     - log_escape(frame, creds->account_name),
13592     - log_escape(frame, creds->computer_name));
13593     - DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
13594     - "'server require schannel:%s = no' might be needed!\n",
13595     - log_escape(frame, creds->account_name));
13596     + dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
13597     + }
13598     +
13599     + DEBUG(dbg_lvl, (
13600     + "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
13601     + "%s request (opnum[%u]) %s schannel from "
13602     + "client_account[%s] client_computer_name[%s] %s\n",
13603     + opname, opnum, reason,
13604     + log_escape(frame, creds->account_name),
13605     + log_escape(frame, creds->computer_name),
13606     + nt_errstr(status)));
13607     +
13608     + if (explicit_opt != NULL) {
13609     + D_INFO("CVE-2020-1472(ZeroLogon): Option "
13610     + "'server require schannel:%s = no' "
13611     + "still needed for '%s'!\n",
13612     + log_escape(frame, creds->account_name),
13613     + log_escape(frame, creds->computer_name));
13614     + } else {
13615     + /*
13616     + * admins should set
13617     + * server require schannel:COMPUTER$ = no
13618     + * in order to avoid the level 0 messages.
13619     + * Over time they can switch the global value
13620     + * to be strict.
13621     + */
13622     + DEBUG(CVE_2020_1472_error_level, (
13623     + "CVE-2020-1472(ZeroLogon): "
13624     + "Please use 'server require schannel:%s = no' "
13625     + "for '%s' to avoid this warning!\n",
13626     + log_escape(frame, creds->account_name),
13627     + log_escape(frame, creds->computer_name)));
13628     }
13629    
13630     *creds_out = creds;
13631     --
13632     2.39.0
13633    
13634    
13635     From 7e0bfe3db2b4d274b3bf2e5f011ae8207ce6f4ab Mon Sep 17 00:00:00 2001
13636     From: Samuel Cabrero <scabrero@suse.de>
13637     Date: Wed, 21 Dec 2022 18:37:05 +0100
13638     Subject: [PATCH 136/142] CVE-2022-38023 selftest:Samba3: avoid global 'server
13639     schannel = auto'
13640    
13641     Instead of using the generic deprecated option use the specific
13642     server require schannel:COMPUTERACCOUNT = no in order to allow
13643     legacy tests for pass.
13644    
13645     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
13646    
13647     Signed-off-by: Samuel Cabrero <scabrero@samba.org>
13648     ---
13649     selftest/target/Samba3.pm | 21 ++++++++++++++++++---
13650     1 file changed, 18 insertions(+), 3 deletions(-)
13651    
13652     diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
13653     index 0c14f02be11..e8a4c3bbbb6 100755
13654     --- a/selftest/target/Samba3.pm
13655     +++ b/selftest/target/Samba3.pm
13656     @@ -140,7 +140,7 @@ sub getlog_env_app($$$)
13657     close(LOG);
13658    
13659     return "" if $out eq $title;
13660     -
13661     +
13662     return $out;
13663     }
13664    
13665     @@ -200,6 +200,21 @@ sub setup_nt4_dc
13666     ntlm auth = yes
13667     raw NTLMv2 auth = yes
13668    
13669     + CVE_2020_1472:warn_about_unused_debug_level = 3
13670     + server require schannel:schannel0\$ = no
13671     + server require schannel:schannel1\$ = no
13672     + server require schannel:schannel2\$ = no
13673     + server require schannel:schannel3\$ = no
13674     + server require schannel:schannel4\$ = no
13675     + server require schannel:schannel5\$ = no
13676     + server require schannel:schannel6\$ = no
13677     + server require schannel:schannel7\$ = no
13678     + server require schannel:schannel8\$ = no
13679     + server require schannel:schannel9\$ = no
13680     + server require schannel:schannel10\$ = no
13681     + server require schannel:schannel11\$ = no
13682     + server require schannel:torturetest\$ = no
13683     +
13684     rpc_server:epmapper = external
13685     rpc_server:spoolss = external
13686     rpc_server:lsarpc = external
13687     @@ -1588,7 +1603,7 @@ sub provision($$$$$$$$$)
13688     my $nmbdsockdir="$prefix_abs/nmbd";
13689     unlink($nmbdsockdir);
13690    
13691     - ##
13692     + ##
13693     ## create the test directory layout
13694     ##
13695     die ("prefix_abs = ''") if $prefix_abs eq "";
13696     @@ -2393,7 +2408,7 @@ sub provision($$$$$$$$$)
13697     unless (open(PASSWD, ">$nss_wrapper_passwd")) {
13698     warn("Unable to open $nss_wrapper_passwd");
13699     return undef;
13700     - }
13701     + }
13702     print PASSWD "nobody:x:$uid_nobody:$gid_nobody:nobody gecos:$prefix_abs:/bin/false
13703     $unix_name:x:$unix_uid:$unix_gids[0]:$unix_name gecos:$prefix_abs:/bin/false
13704     pdbtest:x:$uid_pdbtest:$gid_nogroup:pdbtest gecos:$prefix_abs:/bin/false
13705     --
13706     2.39.0
13707    
13708    
13709     From 340bdcc92d979eb67d67e2a2d8056f939a011f37 Mon Sep 17 00:00:00 2001
13710     From: Samuel Cabrero <scabrero@suse.de>
13711     Date: Thu, 22 Dec 2022 11:42:51 +0100
13712     Subject: [PATCH 137/142] CVE-2022-38023 s3:rpc_server/netlogon: split out
13713     netr_check_schannel() function
13714    
13715     This will allow us to reuse the function in other places.
13716     As it will also get some additional checks soon.
13717    
13718     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
13719    
13720     Signed-off-by: Samuel Cabrero <scabrero@samba.org>
13721     ---
13722     source3/rpc_server/netlogon/srv_netlog_nt.c | 107 ++++++++++++--------
13723     1 file changed, 62 insertions(+), 45 deletions(-)
13724    
13725     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
13726     index 1d261c9a639..eb364eaf29a 100644
13727     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
13728     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
13729     @@ -1064,53 +1064,30 @@ NTSTATUS _netr_ServerAuthenticate2(struct pipes_struct *p,
13730     /*************************************************************************
13731     *************************************************************************/
13732    
13733     -static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13734     - TALLOC_CTX *mem_ctx,
13735     - const char *computer_name,
13736     - struct netr_Authenticator *received_authenticator,
13737     - struct netr_Authenticator *return_authenticator,
13738     - struct netlogon_creds_CredentialState **creds_out)
13739     +static NTSTATUS netr_check_schannel(struct pipes_struct *p,
13740     + const struct netlogon_creds_CredentialState *creds,
13741     + enum dcerpc_AuthType auth_type,
13742     + enum dcerpc_AuthLevel auth_level,
13743     + uint16_t opnum)
13744     {
13745     TALLOC_CTX *frame = talloc_stackframe();
13746     NTSTATUS status;
13747     bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
13748     bool schannel_required = schannel_global_required;
13749     const char *explicit_opt = NULL;
13750     - struct loadparm_context *lp_ctx;
13751     - struct netlogon_creds_CredentialState *creds = NULL;
13752     - int CVE_2020_1472_warn_level = DBGLVL_ERR;
13753     - int CVE_2020_1472_error_level = DBGLVL_ERR;
13754     + int CVE_2020_1472_warn_level = lp_parm_int(GLOBAL_SECTION_SNUM,
13755     + "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
13756     + int CVE_2020_1472_error_level = lp_parm_int(GLOBAL_SECTION_SNUM,
13757     + "CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
13758     unsigned int dbg_lvl = DBGLVL_DEBUG;
13759     - enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
13760     - enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
13761     - uint16_t opnum = p->opnum;
13762     const char *opname = "<unknown>";
13763     const char *reason = "<unknown>";
13764     static bool warned_global_once = false;
13765    
13766     - if (creds_out != NULL) {
13767     - *creds_out = NULL;
13768     - }
13769     -
13770     if (opnum < ndr_table_netlogon.num_calls) {
13771     opname = ndr_table_netlogon.calls[opnum].name;
13772     }
13773    
13774     - auth_type = p->auth.auth_type;
13775     - auth_level = p->auth.auth_level;
13776     -
13777     - lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
13778     - if (lp_ctx == NULL) {
13779     - DEBUG(0, ("loadparm_init_s3 failed\n"));
13780     - TALLOC_FREE(frame);
13781     - return NT_STATUS_INTERNAL_ERROR;
13782     - }
13783     -
13784     - CVE_2020_1472_warn_level = lpcfg_parm_int(lp_ctx, NULL,
13785     - "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
13786     - CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
13787     - "CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
13788     -
13789     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
13790     if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
13791     reason = "WITH SEALED";
13792     @@ -1123,15 +1100,6 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13793     reason = "WITHOUT";
13794     }
13795    
13796     - status = schannel_check_creds_state(mem_ctx, lp_ctx,
13797     - computer_name, received_authenticator,
13798     - return_authenticator, &creds);
13799     - if (!NT_STATUS_IS_OK(status)) {
13800     - ZERO_STRUCTP(return_authenticator);
13801     - TALLOC_FREE(frame);
13802     - return status;
13803     - }
13804     -
13805     /*
13806     * We don't use lp_parm_bool(), as we
13807     * need the explicit_opt pointer in order to
13808     @@ -1172,7 +1140,6 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13809     log_escape(frame, creds->computer_name)));
13810     }
13811    
13812     - *creds_out = creds;
13813     TALLOC_FREE(frame);
13814     return status;
13815     }
13816     @@ -1206,8 +1173,6 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13817     "might be needed for a legacy client.\n",
13818     log_escape(frame, creds->account_name)));
13819     }
13820     - TALLOC_FREE(creds);
13821     - ZERO_STRUCTP(return_authenticator);
13822     TALLOC_FREE(frame);
13823     return status;
13824     }
13825     @@ -1261,11 +1226,63 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13826     log_escape(frame, creds->computer_name)));
13827     }
13828    
13829     - *creds_out = creds;
13830     TALLOC_FREE(frame);
13831     return NT_STATUS_OK;
13832     }
13833    
13834     +static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
13835     + TALLOC_CTX *mem_ctx,
13836     + const char *computer_name,
13837     + struct netr_Authenticator *received_authenticator,
13838     + struct netr_Authenticator *return_authenticator,
13839     + struct netlogon_creds_CredentialState **creds_out)
13840     +{
13841     + struct loadparm_context *lp_ctx = NULL;
13842     + NTSTATUS status;
13843     + struct netlogon_creds_CredentialState *creds = NULL;
13844     + enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
13845     + enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
13846     + uint16_t opnum = p->opnum;
13847     +
13848     + if (creds_out != NULL) {
13849     + *creds_out = NULL;
13850     + }
13851     +
13852     + auth_type = p->auth.auth_type;
13853     + auth_level = p->auth.auth_level;
13854     +
13855     + lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers());
13856     + if (lp_ctx == NULL) {
13857     + DEBUG(0, ("loadparm_init_s3 failed\n"));
13858     + return NT_STATUS_INTERNAL_ERROR;
13859     + }
13860     +
13861     + status = schannel_check_creds_state(mem_ctx,
13862     + lp_ctx,
13863     + computer_name,
13864     + received_authenticator,
13865     + return_authenticator,
13866     + &creds);
13867     + TALLOC_FREE(lp_ctx);
13868     + if (!NT_STATUS_IS_OK(status)) {
13869     + ZERO_STRUCTP(return_authenticator);
13870     + return status;
13871     + }
13872     +
13873     + status = netr_check_schannel(p,
13874     + creds,
13875     + auth_type,
13876     + auth_level,
13877     + opnum);
13878     + if (!NT_STATUS_IS_OK(status)) {
13879     + TALLOC_FREE(creds);
13880     + ZERO_STRUCTP(return_authenticator);
13881     + return status;
13882     + }
13883     +
13884     + *creds_out = creds;
13885     + return NT_STATUS_OK;
13886     +}
13887    
13888     /*************************************************************************
13889     *************************************************************************/
13890     --
13891     2.39.0
13892    
13893    
13894     From 8b52bfc3bb274d7d1607b505c18b4ccafe25cad7 Mon Sep 17 00:00:00 2001
13895     From: Samuel Cabrero <scabrero@suse.de>
13896     Date: Thu, 22 Dec 2022 09:29:04 +0100
13897     Subject: [PATCH 138/142] CVE-2022-38023 s3:rpc_server/netlogon: make sure all
13898     dcesrv_netr_LogonSamLogon*() calls go through netr_check_schannel()
13899    
13900     We'll soon add some additional contraints in dcesrv_netr_check_schannel(),
13901     which are also required for dcesrv_netr_LogonSamLogonEx().
13902    
13903     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
13904    
13905     Signed-off-by: Samuel Cabrero <scabrero@samba.org>
13906     ---
13907     source3/rpc_server/netlogon/srv_netlog_nt.c | 30 ++++++++++++++++-----
13908     1 file changed, 23 insertions(+), 7 deletions(-)
13909    
13910     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
13911     index eb364eaf29a..ca343d3e28a 100644
13912     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
13913     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
13914     @@ -1766,6 +1766,8 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
13915     struct auth_serversupplied_info *server_info = NULL;
13916     struct auth_context *auth_context = NULL;
13917     const char *fn;
13918     + enum dcerpc_AuthType auth_type = p->auth.auth_type;
13919     + enum dcerpc_AuthLevel auth_level = p->auth.auth_level;
13920    
13921     #ifdef DEBUG_PASSWORD
13922     logon = netlogon_creds_shallow_copy_logon(p->mem_ctx,
13923     @@ -1779,11 +1781,32 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
13924     switch (p->opnum) {
13925     case NDR_NETR_LOGONSAMLOGON:
13926     fn = "_netr_LogonSamLogon";
13927     + /*
13928     + * Already called netr_check_schannel() via
13929     + * netr_creds_server_step_check()
13930     + */
13931     break;
13932     case NDR_NETR_LOGONSAMLOGONWITHFLAGS:
13933     fn = "_netr_LogonSamLogonWithFlags";
13934     + /*
13935     + * Already called netr_check_schannel() via
13936     + * netr_creds_server_step_check()
13937     + */
13938     break;
13939     case NDR_NETR_LOGONSAMLOGONEX:
13940     + if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
13941     + return NT_STATUS_ACCESS_DENIED;
13942     + }
13943     +
13944     + status = netr_check_schannel(p,
13945     + creds,
13946     + auth_type,
13947     + auth_level,
13948     + p->opnum);
13949     + if (NT_STATUS_IS_ERR(status)) {
13950     + return status;
13951     + }
13952     +
13953     fn = "_netr_LogonSamLogonEx";
13954     break;
13955     default:
13956     @@ -2123,13 +2146,6 @@ NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p,
13957     return status;
13958     }
13959    
13960     - /* Only allow this if the pipe is protected. */
13961     - if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
13962     - DEBUG(0,("_netr_LogonSamLogonEx: client %s not using schannel for netlogon\n",
13963     - get_remote_machine_name() ));
13964     - return NT_STATUS_INVALID_PARAMETER;
13965     - }
13966     -
13967     lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
13968     if (lp_ctx == NULL) {
13969     DEBUG(0, ("loadparm_init_s3 failed\n"));
13970     --
13971     2.39.0
13972    
13973    
13974     From 43dca97088ce82a5e346887b8078f346e8249929 Mon Sep 17 00:00:00 2001
13975     From: Samuel Cabrero <scabrero@suse.de>
13976     Date: Wed, 4 Jan 2023 17:23:41 +0100
13977     Subject: [PATCH 139/142] CVE-2022-38023 s3:rpc_server/netlogon: Rename
13978     variable
13979    
13980     This will simplify the following changes.
13981    
13982     Signed-off-by: Samuel Cabrero <scabrero@suse.de>
13983     ---
13984     source3/rpc_server/netlogon/srv_netlog_nt.c | 16 +++++++++-------
13985     1 file changed, 9 insertions(+), 7 deletions(-)
13986    
13987     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
13988     index ca343d3e28a..5500a421334 100644
13989     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
13990     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
13991     @@ -1072,9 +1072,10 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
13992     {
13993     TALLOC_CTX *frame = talloc_stackframe();
13994     NTSTATUS status;
13995     + const char *explicit_opt = NULL;
13996     bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
13997     bool schannel_required = schannel_global_required;
13998     - const char *explicit_opt = NULL;
13999     + bool schannel_explicitly_set = false;
14000     int CVE_2020_1472_warn_level = lp_parm_int(GLOBAL_SECTION_SNUM,
14001     "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
14002     int CVE_2020_1472_error_level = lp_parm_int(GLOBAL_SECTION_SNUM,
14003     @@ -1113,11 +1114,12 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14004     if (explicit_opt != NULL) {
14005     schannel_required = lp_bool(explicit_opt);
14006     }
14007     + schannel_explicitly_set = explicit_opt != NULL;
14008    
14009     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
14010     status = NT_STATUS_OK;
14011    
14012     - if (explicit_opt != NULL && !schannel_required) {
14013     + if (schannel_explicitly_set && !schannel_required) {
14014     dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
14015     } else if (!schannel_required) {
14016     dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
14017     @@ -1132,7 +1134,7 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14018     log_escape(frame, creds->computer_name),
14019     nt_errstr(status)));
14020    
14021     - if (explicit_opt != NULL && !schannel_required) {
14022     + if (schannel_explicitly_set && !schannel_required) {
14023     DEBUG(CVE_2020_1472_warn_level, (
14024     "CVE-2020-1472(ZeroLogon): "
14025     "Option 'server require schannel:%s = no' not needed for '%s'!\n",
14026     @@ -1147,7 +1149,7 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14027     if (schannel_required) {
14028     status = NT_STATUS_ACCESS_DENIED;
14029    
14030     - if (explicit_opt != NULL) {
14031     + if (schannel_explicitly_set) {
14032     dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
14033     } else {
14034     dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
14035     @@ -1161,7 +1163,7 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14036     log_escape(frame, creds->account_name),
14037     log_escape(frame, creds->computer_name),
14038     nt_errstr(status)));
14039     - if (explicit_opt != NULL) {
14040     + if (schannel_explicitly_set) {
14041     D_NOTICE("CVE-2020-1472(ZeroLogon): Option "
14042     "'server require schannel:%s = yes' "
14043     "rejects access for client.\n",
14044     @@ -1189,7 +1191,7 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14045    
14046     status = NT_STATUS_OK;
14047    
14048     - if (explicit_opt != NULL) {
14049     + if (schannel_explicitly_set) {
14050     dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
14051     } else {
14052     dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
14053     @@ -1204,7 +1206,7 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14054     log_escape(frame, creds->computer_name),
14055     nt_errstr(status)));
14056    
14057     - if (explicit_opt != NULL) {
14058     + if (schannel_explicitly_set) {
14059     D_INFO("CVE-2020-1472(ZeroLogon): Option "
14060     "'server require schannel:%s = no' "
14061     "still needed for '%s'!\n",
14062     --
14063     2.39.0
14064    
14065    
14066     From 4ae0a15ed4ebde7b1725f9ada406c179de238267 Mon Sep 17 00:00:00 2001
14067     From: Samuel Cabrero <scabrero@suse.de>
14068     Date: Wed, 4 Jan 2023 17:39:20 +0100
14069     Subject: [PATCH 140/142] CVE-2022-38023 s3:rpc_server/netlogon: Return error
14070     on invalid auth level
14071    
14072     Signed-off-by: Samuel Cabrero <scabrero@suse.de>
14073     ---
14074     source3/rpc_server/netlogon/srv_netlog_nt.c | 23 +++++++++++++++++++--
14075     1 file changed, 21 insertions(+), 2 deletions(-)
14076    
14077     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
14078     index 5500a421334..fb5a05b75c8 100644
14079     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
14080     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
14081     @@ -1071,7 +1071,7 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14082     uint16_t opnum)
14083     {
14084     TALLOC_CTX *frame = talloc_stackframe();
14085     - NTSTATUS status;
14086     + NTSTATUS status = NT_STATUS_MORE_PROCESSING_REQUIRED;
14087     const char *explicit_opt = NULL;
14088     bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
14089     bool schannel_required = schannel_global_required;
14090     @@ -1095,12 +1095,31 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14091     } else if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
14092     reason = "WITH SIGNED";
14093     } else {
14094     - smb_panic("Schannel without SIGN/SEAL");
14095     + reason = "WITH INVALID";
14096     + dbg_lvl = DBGLVL_ERR;
14097     + status = NT_STATUS_INTERNAL_ERROR;
14098     }
14099     } else {
14100     reason = "WITHOUT";
14101     }
14102    
14103     + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
14104     + if (!NT_STATUS_IS_OK(status)) {
14105     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
14106     + }
14107     +
14108     + DEBUG(dbg_lvl, (
14109     + "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
14110     + "%s request (opnum[%u]) %s schannel from "
14111     + "client_account[%s] client_computer_name[%s] %s\n",
14112     + opname, opnum, reason,
14113     + log_escape(frame, creds->account_name),
14114     + log_escape(frame, creds->computer_name),
14115     + nt_errstr(status)));
14116     + TALLOC_FREE(frame);
14117     + return status;
14118     + }
14119     +
14120     /*
14121     * We don't use lp_parm_bool(), as we
14122     * need the explicit_opt pointer in order to
14123     --
14124     2.39.0
14125    
14126    
14127     From f59b49f3c23a9a7879a6975aa77e9cf2560a68be Mon Sep 17 00:00:00 2001
14128     From: Samuel Cabrero <scabrero@suse.de>
14129     Date: Wed, 4 Jan 2023 17:42:37 +0100
14130     Subject: [PATCH 141/142] CVE-2022-38023 s3:rpc_server/netlogon: Rename
14131     variable
14132    
14133     This will simplify the following changes.
14134    
14135     Signed-off-by: Samuel Cabrero <scabrero@samba.org>
14136     ---
14137     source3/rpc_server/netlogon/srv_netlog_nt.c | 6 +++---
14138     1 file changed, 3 insertions(+), 3 deletions(-)
14139    
14140     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
14141     index fb5a05b75c8..fd128a70c8b 100644
14142     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
14143     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
14144     @@ -1083,7 +1083,7 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14145     unsigned int dbg_lvl = DBGLVL_DEBUG;
14146     const char *opname = "<unknown>";
14147     const char *reason = "<unknown>";
14148     - static bool warned_global_once = false;
14149     + static bool warned_global_schannel_once = false;
14150    
14151     if (opnum < ndr_table_netlogon.num_calls) {
14152     opname = ndr_table_netlogon.calls[opnum].name;
14153     @@ -1198,14 +1198,14 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14154     return status;
14155     }
14156    
14157     - if (!schannel_global_required && !warned_global_once) {
14158     + if (!schannel_global_required && !warned_global_schannel_once) {
14159     /*
14160     * We want admins to notice their misconfiguration!
14161     */
14162     DBG_ERR("CVE-2020-1472(ZeroLogon): "
14163     "Please configure 'server schannel = yes', "
14164     "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n");
14165     - warned_global_once = true;
14166     + warned_global_schannel_once = true;
14167     }
14168    
14169     status = NT_STATUS_OK;
14170     --
14171     2.39.0
14172    
14173    
14174     From 6b038af7f70f0331d85dac00647cfe8dedefec28 Mon Sep 17 00:00:00 2001
14175     From: Samuel Cabrero <scabrero@suse.de>
14176     Date: Wed, 4 Jan 2023 17:50:04 +0100
14177     Subject: [PATCH 142/142] CVE-2022-38023 s3:rpc_server/netlogon: implement
14178     "server schannel require seal[:COMPUTERACCOUNT]"
14179    
14180     By default we'll now require schannel connections with
14181     privacy/sealing/encryption.
14182    
14183     But we allow exceptions for specific computer/trust accounts.
14184    
14185     BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
14186    
14187     Signed-off-by: Samuel Cabrero <scabrero@suse.de>
14188     ---
14189     selftest/target/Samba3.pm | 14 ++
14190     source3/rpc_server/netlogon/srv_netlog_nt.c | 237 +++++++++++++++++++-
14191     2 files changed, 249 insertions(+), 2 deletions(-)
14192    
14193     diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
14194     index e8a4c3bbbb6..cf6c38562de 100755
14195     --- a/selftest/target/Samba3.pm
14196     +++ b/selftest/target/Samba3.pm
14197     @@ -215,6 +215,20 @@ sub setup_nt4_dc
14198     server require schannel:schannel11\$ = no
14199     server require schannel:torturetest\$ = no
14200    
14201     + server schannel require seal:schannel0\$ = no
14202     + server schannel require seal:schannel1\$ = no
14203     + server schannel require seal:schannel2\$ = no
14204     + server schannel require seal:schannel3\$ = no
14205     + server schannel require seal:schannel4\$ = no
14206     + server schannel require seal:schannel5\$ = no
14207     + server schannel require seal:schannel6\$ = no
14208     + server schannel require seal:schannel7\$ = no
14209     + server schannel require seal:schannel8\$ = no
14210     + server schannel require seal:schannel9\$ = no
14211     + server schannel require seal:schannel10\$ = no
14212     + server schannel require seal:schannel11\$ = no
14213     + server schannel require seal:torturetest\$ = no
14214     +
14215     rpc_server:epmapper = external
14216     rpc_server:spoolss = external
14217     rpc_server:lsarpc = external
14218     diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
14219     index fd128a70c8b..38772586d81 100644
14220     --- a/source3/rpc_server/netlogon/srv_netlog_nt.c
14221     +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
14222     @@ -1076,14 +1076,22 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14223     bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
14224     bool schannel_required = schannel_global_required;
14225     bool schannel_explicitly_set = false;
14226     + bool seal_global_required = (lp_server_schannel_require_seal() == true) ? true:false;
14227     + bool seal_required = seal_global_required;
14228     + bool seal_explicitly_set = false;
14229     int CVE_2020_1472_warn_level = lp_parm_int(GLOBAL_SECTION_SNUM,
14230     "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
14231     int CVE_2020_1472_error_level = lp_parm_int(GLOBAL_SECTION_SNUM,
14232     "CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
14233     + int CVE_2022_38023_warn_level = lp_parm_int(GLOBAL_SECTION_SNUM,
14234     + "CVE_2022_38023", "warn_about_unused_debug_level", DBGLVL_ERR);
14235     + int CVE_2022_38023_error_level = lp_parm_int(GLOBAL_SECTION_SNUM,
14236     + "CVE_2022_38023", "error_debug_level", DBGLVL_ERR);
14237     unsigned int dbg_lvl = DBGLVL_DEBUG;
14238     const char *opname = "<unknown>";
14239     const char *reason = "<unknown>";
14240     static bool warned_global_schannel_once = false;
14241     + static bool warned_global_seal_once = false;
14242    
14243     if (opnum < ndr_table_netlogon.num_calls) {
14244     opname = ndr_table_netlogon.calls[opnum].name;
14245     @@ -1120,6 +1128,20 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14246     return status;
14247     }
14248    
14249     + /*
14250     + * We don't use lp_parm_bool(), as we
14251     + * need the explicit_opt pointer in order to
14252     + * adjust the debug messages.
14253     + */
14254     + explicit_opt = lp_parm_const_string(GLOBAL_SECTION_SNUM,
14255     + "server schannel require seal",
14256     + creds->account_name,
14257     + NULL);
14258     + if (explicit_opt != NULL) {
14259     + seal_required = lp_bool(explicit_opt);
14260     + }
14261     + seal_explicitly_set = explicit_opt != NULL;
14262     +
14263     /*
14264     * We don't use lp_parm_bool(), as we
14265     * need the explicit_opt pointer in order to
14266     @@ -1135,7 +1157,96 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14267     }
14268     schannel_explicitly_set = explicit_opt != NULL;
14269    
14270     + if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
14271     + auth_level == DCERPC_AUTH_LEVEL_PRIVACY)
14272     + {
14273     + status = NT_STATUS_OK;
14274     +
14275     + if (schannel_explicitly_set && !schannel_required) {
14276     + dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
14277     + } else if (!schannel_required) {
14278     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
14279     + }
14280     + if (seal_explicitly_set && !seal_required) {
14281     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
14282     + } else if (!seal_required) {
14283     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
14284     + }
14285     +
14286     + DEBUG(dbg_lvl, (
14287     + "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
14288     + "%s request (opnum[%u]) %s schannel from "
14289     + "client_account[%s] client_computer_name[%s] %s\n",
14290     + opname, opnum, reason,
14291     + log_escape(frame, creds->account_name),
14292     + log_escape(frame, creds->computer_name),
14293     + nt_errstr(status)));
14294     +
14295     + if (schannel_explicitly_set && !schannel_required) {
14296     + DEBUG(CVE_2020_1472_warn_level, (
14297     + "CVE-2020-1472(ZeroLogon): "
14298     + "Option 'server require schannel:%s = no' not needed for '%s'!\n",
14299     + log_escape(frame, creds->account_name),
14300     + log_escape(frame, creds->computer_name)));
14301     + }
14302     +
14303     + if (seal_explicitly_set && !seal_required) {
14304     + DEBUG(CVE_2022_38023_warn_level, (
14305     + "CVE-2022-38023: "
14306     + "Option 'server schannel require seal:%s = no' not needed for '%s'!\n",
14307     + log_escape(frame, creds->account_name),
14308     + log_escape(frame, creds->computer_name)));
14309     + }
14310     +
14311     + TALLOC_FREE(frame);
14312     + return status;
14313     + }
14314     +
14315     if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
14316     + if (seal_required) {
14317     + status = NT_STATUS_ACCESS_DENIED;
14318     +
14319     + if (seal_explicitly_set) {
14320     + dbg_lvl = DBGLVL_NOTICE;
14321     + } else {
14322     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
14323     + }
14324     + if (schannel_explicitly_set && !schannel_required) {
14325     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
14326     + }
14327     +
14328     + DEBUG(dbg_lvl, (
14329     + "CVE-2022-38023: "
14330     + "%s request (opnum[%u]) %s schannel from "
14331     + "from client_account[%s] client_computer_name[%s] %s\n",
14332     + opname, opnum, reason,
14333     + log_escape(frame, creds->account_name),
14334     + log_escape(frame, creds->computer_name),
14335     + nt_errstr(status)));
14336     + if (seal_explicitly_set) {
14337     + D_NOTICE("CVE-2022-38023: Option "
14338     + "'server schannel require seal:%s = yes' "
14339     + "rejects access for client.\n",
14340     + log_escape(frame, creds->account_name));
14341     + } else {
14342     + DEBUG(CVE_2020_1472_error_level, (
14343     + "CVE-2022-38023: Check if option "
14344     + "'server schannel require seal:%s = no' "
14345     + "might be needed for a legacy client.\n",
14346     + log_escape(frame, creds->account_name)));
14347     + }
14348     + if (schannel_explicitly_set && !schannel_required) {
14349     + DEBUG(CVE_2020_1472_warn_level, (
14350     + "CVE-2020-1472(ZeroLogon): Option "
14351     + "'server require schannel:%s = no' "
14352     + "not needed for '%s'!\n",
14353     + log_escape(frame, creds->account_name),
14354     + log_escape(frame, creds->computer_name)));
14355     + }
14356     + TALLOC_FREE(frame);
14357     + return status;
14358     + }
14359     +
14360     status = NT_STATUS_OK;
14361    
14362     if (schannel_explicitly_set && !schannel_required) {
14363     @@ -1143,6 +1254,11 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14364     } else if (!schannel_required) {
14365     dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
14366     }
14367     + if (seal_explicitly_set && !seal_required) {
14368     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
14369     + } else if (!seal_required) {
14370     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
14371     + }
14372    
14373     DEBUG(dbg_lvl, (
14374     "CVE-2020-1472(ZeroLogon): "
14375     @@ -1152,7 +1268,6 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14376     log_escape(frame, creds->account_name),
14377     log_escape(frame, creds->computer_name),
14378     nt_errstr(status)));
14379     -
14380     if (schannel_explicitly_set && !schannel_required) {
14381     DEBUG(CVE_2020_1472_warn_level, (
14382     "CVE-2020-1472(ZeroLogon): "
14383     @@ -1160,7 +1275,77 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14384     log_escape(frame, creds->account_name),
14385     log_escape(frame, creds->computer_name)));
14386     }
14387     + if (seal_explicitly_set && !seal_required) {
14388     + D_INFO("CVE-2022-38023: "
14389     + "Option 'server schannel require seal:%s = no' still needed for '%s'!\n",
14390     + log_escape(frame, creds->account_name),
14391     + log_escape(frame, creds->computer_name));
14392     + } else if (!seal_required) {
14393     + /*
14394     + * admins should set
14395     + * server schannel require seal:COMPUTER$ = no
14396     + * in order to avoid the level 0 messages.
14397     + * Over time they can switch the global value
14398     + * to be strict.
14399     + */
14400     + DEBUG(CVE_2022_38023_error_level, (
14401     + "CVE-2022-38023: "
14402     + "Please use 'server schannel require seal:%s = no' "
14403     + "for '%s' to avoid this warning!\n",
14404     + log_escape(frame, creds->account_name),
14405     + log_escape(frame, creds->computer_name)));
14406     + }
14407     +
14408     + TALLOC_FREE(frame);
14409     + return status;
14410     + }
14411     +
14412     + if (seal_required) {
14413     + status = NT_STATUS_ACCESS_DENIED;
14414    
14415     + if (seal_explicitly_set) {
14416     + dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
14417     + } else {
14418     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
14419     + }
14420     + if (!schannel_explicitly_set) {
14421     + dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
14422     + } else if (schannel_required) {
14423     + dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
14424     + }
14425     +
14426     + DEBUG(dbg_lvl, (
14427     + "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
14428     + "%s request (opnum[%u]) %s schannel from "
14429     + "from client_account[%s] client_computer_name[%s] %s\n",
14430     + opname, opnum, reason,
14431     + log_escape(frame, creds->account_name),
14432     + log_escape(frame, creds->computer_name),
14433     + nt_errstr(status)));
14434     + if (seal_explicitly_set) {
14435     + D_NOTICE("CVE-2022-38023: Option "
14436     + "'server schannel require seal:%s = yes' "
14437     + "rejects access for client.\n",
14438     + log_escape(frame, creds->account_name));
14439     + } else {
14440     + DEBUG(CVE_2022_38023_error_level, (
14441     + "CVE-2022-38023: Check if option "
14442     + "'server schannel require seal:%s = no' "
14443     + "might be needed for a legacy client.\n",
14444     + log_escape(frame, creds->account_name)));
14445     + }
14446     + if (!schannel_explicitly_set) {
14447     + DEBUG(CVE_2020_1472_error_level, (
14448     + "CVE-2020-1472(ZeroLogon): Check if option "
14449     + "'server require schannel:%s = no' "
14450     + "might be needed for a legacy client.\n",
14451     + log_escape(frame, creds->account_name)));
14452     + } else if (schannel_required) {
14453     + D_NOTICE("CVE-2022-38023: Option "
14454     + "'server require schannel:%s = yes' "
14455     + "also rejects access for client.\n",
14456     + log_escape(frame, creds->account_name));
14457     + }
14458     TALLOC_FREE(frame);
14459     return status;
14460     }
14461     @@ -1173,6 +1358,9 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14462     } else {
14463     dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
14464     }
14465     + if (!seal_explicitly_set) {
14466     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
14467     + }
14468    
14469     DEBUG(dbg_lvl, (
14470     "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
14471     @@ -1194,6 +1382,13 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14472     "might be needed for a legacy client.\n",
14473     log_escape(frame, creds->account_name)));
14474     }
14475     + if (!seal_explicitly_set) {
14476     + DEBUG(CVE_2022_38023_error_level, (
14477     + "CVE-2022-38023: Check if option "
14478     + "'server schannel require seal:%s = no' "
14479     + "might be needed for a legacy client.\n",
14480     + log_escape(frame, creds->account_name)));
14481     + }
14482     TALLOC_FREE(frame);
14483     return status;
14484     }
14485     @@ -1208,8 +1403,24 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14486     warned_global_schannel_once = true;
14487     }
14488    
14489     + if (!seal_global_required && !warned_global_seal_once) {
14490     + /*
14491     + * We want admins to notice their misconfiguration!
14492     + */
14493     + DBG_ERR("CVE-2022-38023 (and others): "
14494     + "Please configure 'server schannel require seal = yes' (the default), "
14495     + "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
14496     + warned_global_seal_once = true;
14497     + }
14498     +
14499     status = NT_STATUS_OK;
14500    
14501     + if (seal_explicitly_set) {
14502     + dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
14503     + } else {
14504     + dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
14505     + }
14506     +
14507     if (schannel_explicitly_set) {
14508     dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
14509     } else {
14510     @@ -1225,6 +1436,28 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14511     log_escape(frame, creds->computer_name),
14512     nt_errstr(status)));
14513    
14514     + if (seal_explicitly_set) {
14515     + D_INFO("CVE-2022-38023: Option "
14516     + "'server schannel require seal:%s = no' "
14517     + "still needed for '%s'!\n",
14518     + log_escape(frame, creds->account_name),
14519     + log_escape(frame, creds->computer_name));
14520     + } else {
14521     + /*
14522     + * admins should set
14523     + * server schannel require seal:COMPUTER$ = no
14524     + * in order to avoid the level 0 messages.
14525     + * Over time they can switch the global value
14526     + * to be strict.
14527     + */
14528     + DEBUG(CVE_2022_38023_error_level, (
14529     + "CVE-2022-38023: Please use "
14530     + "'server schannel require seal:%s = no' "
14531     + "for '%s' to avoid this warning!\n",
14532     + log_escape(frame, creds->account_name),
14533     + log_escape(frame, creds->computer_name)));
14534     + }
14535     +
14536     if (schannel_explicitly_set) {
14537     D_INFO("CVE-2020-1472(ZeroLogon): Option "
14538     "'server require schannel:%s = no' "
14539     @@ -1248,7 +1481,7 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
14540     }
14541    
14542     TALLOC_FREE(frame);
14543     - return NT_STATUS_OK;
14544     + return status;
14545     }
14546    
14547     static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
14548     --
14549     2.39.0
14550    

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed