fix CVE-2020-25717,CVE-2020-25718,CVE-2020-25719,CVE-2020-25721,CVE-2020-25722,CVE-2016-2124,CVE-2021-3738
(cherry picked from commit aee849c6c0708056f62f6445e3b5274d1cec6408)
This commit is contained in:
parent
30f926a987
commit
8378df4821
@ -0,0 +1,65 @@
|
||||
From 4290223ed40183e5f01c25da00df438b9ccf302a Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Thu, 24 Nov 2016 09:12:59 +0100
|
||||
Subject: [PATCH 254/266] CVE-2016-2124: s4:libcli/sesssetup: don't fallback to
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=4290223ed40183e5f01c25da00df438b9ccf302a
|
||||
|
||||
non spnego authentication if we require kerberos
|
||||
|
||||
We should not send NTLM[v2] data on the wire if the user asked for kerberos
|
||||
only.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12444
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
---
|
||||
source4/libcli/smb_composite/sesssetup.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c
|
||||
index 6ee4929e8d7..a0a1f4baa56 100644
|
||||
--- a/source4/libcli/smb_composite/sesssetup.c
|
||||
+++ b/source4/libcli/smb_composite/sesssetup.c
|
||||
@@ -620,6 +620,8 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se
|
||||
struct composite_context *c;
|
||||
struct sesssetup_state *state;
|
||||
NTSTATUS status;
|
||||
+ enum credentials_use_kerberos krb5_state =
|
||||
+ cli_credentials_get_kerberos_state(io->in.credentials);
|
||||
|
||||
c = composite_create(session, session->transport->ev);
|
||||
if (c == NULL) return NULL;
|
||||
@@ -635,6 +637,10 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se
|
||||
|
||||
/* no session setup at all in earliest protocol varients */
|
||||
if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) {
|
||||
+ if (krb5_state == CRED_MUST_USE_KERBEROS) {
|
||||
+ composite_error(c, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
|
||||
+ return c;
|
||||
+ }
|
||||
ZERO_STRUCT(io->out);
|
||||
composite_done(c);
|
||||
return c;
|
||||
@@ -642,9 +648,17 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se
|
||||
|
||||
/* see what session setup interface we will use */
|
||||
if (session->transport->negotiate.protocol < PROTOCOL_NT1) {
|
||||
+ if (krb5_state == CRED_MUST_USE_KERBEROS) {
|
||||
+ composite_error(c, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
|
||||
+ return c;
|
||||
+ }
|
||||
status = session_setup_old(c, session, io, &state->req);
|
||||
} else if (!session->transport->options.use_spnego ||
|
||||
!(io->in.capabilities & CAP_EXTENDED_SECURITY)) {
|
||||
+ if (krb5_state == CRED_MUST_USE_KERBEROS) {
|
||||
+ composite_error(c, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
|
||||
+ return c;
|
||||
+ }
|
||||
status = session_setup_nt1(c, session, io, &state->req);
|
||||
} else {
|
||||
struct tevent_req *subreq = NULL;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
110
backport-0000-CVE-2020-25718-simplify.patch
Normal file
110
backport-0000-CVE-2020-25718-simplify.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From 6f4ebdc95e40eaedc850604327a57730f35232e5 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Tue, 8 Dec 2020 22:00:55 +1300
|
||||
Subject: [PATCH 001/284] CVE-2020-25718 ldb/attrib_handler casefold: simplify
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=6f4ebdc95e40eaedc850604327a57730f35232e5
|
||||
|
||||
space dropping
|
||||
|
||||
As seen in CVE-2021-20277, ldb_handler_fold() has been making mistakes
|
||||
when collapsing spaces down to a single space.
|
||||
|
||||
This patch fixes the way it handles internal spaces (CVE-2021-20277
|
||||
was about leading spaces), and involves a rewrite of the parsing loop.
|
||||
|
||||
The bug has a detailed description of the problem.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14656
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
|
||||
Autobuild-Date(master): Wed Apr 7 03:16:39 UTC 2021 on sn-devel-184
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558
|
||||
|
||||
(cherry picked from commit 24ddc1ca9cad95673bdd8023d99867707b37085f)
|
||||
---
|
||||
lib/ldb/common/attrib_handlers.c | 53 +++++++++++++++-----------------
|
||||
1 files changed, 25 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/lib/ldb/common/attrib_handlers.c b/lib/ldb/common/attrib_handlers.c
|
||||
index c6ef5ad477b0..f0fd4f50d8df 100644
|
||||
--- a/lib/ldb/common/attrib_handlers.c
|
||||
+++ b/lib/ldb/common/attrib_handlers.c
|
||||
@@ -54,8 +54,8 @@ int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx,
|
||||
int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx,
|
||||
const struct ldb_val *in, struct ldb_val *out)
|
||||
{
|
||||
- char *s, *t;
|
||||
- size_t l;
|
||||
+ char *s, *t, *start;
|
||||
+ bool in_space;
|
||||
|
||||
if (!in || !out || !(in->data)) {
|
||||
return -1;
|
||||
@@ -67,36 +67,33 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx,
|
||||
return -1;
|
||||
}
|
||||
|
||||
- s = (char *)(out->data);
|
||||
-
|
||||
- /* remove trailing spaces if any */
|
||||
- l = strlen(s);
|
||||
- while (l > 0 && s[l - 1] == ' ') l--;
|
||||
- s[l] = '\0';
|
||||
-
|
||||
- /* remove leading spaces if any */
|
||||
- if (*s == ' ') {
|
||||
- for (t = s; *s == ' '; s++, l--) ;
|
||||
-
|
||||
- /* remove leading spaces by moving down the string */
|
||||
- memmove(t, s, l);
|
||||
-
|
||||
- s = t;
|
||||
+ start = (char *)(out->data);
|
||||
+ in_space = true;
|
||||
+ t = start;
|
||||
+ for (s = start; *s != '\0'; s++) {
|
||||
+ if (*s == ' ') {
|
||||
+ if (in_space) {
|
||||
+ /*
|
||||
+ * We already have one (or this is the start)
|
||||
+ * and we don't want to add more
|
||||
+ */
|
||||
+ continue;
|
||||
+ }
|
||||
+ in_space = true;
|
||||
+ } else {
|
||||
+ in_space = false;
|
||||
+ }
|
||||
+ *t = *s;
|
||||
+ t++;
|
||||
}
|
||||
|
||||
- /* check middle spaces */
|
||||
- while ((t = strchr(s, ' ')) != NULL) {
|
||||
- for (s = t; *s == ' '; s++) ;
|
||||
-
|
||||
- if ((s - t) > 1) {
|
||||
- l = strlen(s);
|
||||
-
|
||||
- /* remove all spaces but one by moving down the string */
|
||||
- memmove(t + 1, s, l);
|
||||
- }
|
||||
+ if (in_space && t != start) {
|
||||
+ /* the loop will have left a single trailing space */
|
||||
+ t--;
|
||||
}
|
||||
+ *t = '\0';
|
||||
|
||||
- out->length = strlen((char *)out->data);
|
||||
+ out->length = t - start;
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.25.1
|
||||
@ -0,0 +1,57 @@
|
||||
From 4754bf4daf3ca5e9809a8a9d538d8ae38c9ef344 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schneider <asn@samba.org>
|
||||
Date: Mon, 12 Jul 2021 12:32:12 +0200
|
||||
Subject: [PATCH 200/266] CVE-2020-25719 mit-samba: Make ks_get_principal()
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=4754bf4daf3ca5e9809a8a9d538d8ae38c9ef344
|
||||
|
||||
internally public
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561
|
||||
|
||||
Signed-off-by: Andreas Schneider <asn@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source4/kdc/mit-kdb/kdb_samba.h | 5 +++++
|
||||
source4/kdc/mit-kdb/kdb_samba_principals.c | 8 ++++----
|
||||
2 files changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/source4/kdc/mit-kdb/kdb_samba.h b/source4/kdc/mit-kdb/kdb_samba.h
|
||||
index ad4f6e27573..132dcfed363 100644
|
||||
--- a/source4/kdc/mit-kdb/kdb_samba.h
|
||||
+++ b/source4/kdc/mit-kdb/kdb_samba.h
|
||||
@@ -41,6 +41,11 @@
|
||||
|
||||
struct mit_samba_context *ks_get_context(krb5_context kcontext);
|
||||
|
||||
+krb5_error_code ks_get_principal(krb5_context context,
|
||||
+ krb5_const_principal principal,
|
||||
+ unsigned int kflags,
|
||||
+ krb5_db_entry **kentry);
|
||||
+
|
||||
bool ks_data_eq_string(krb5_data d, const char *s);
|
||||
|
||||
krb5_data ks_make_data(void *data, unsigned int len);
|
||||
diff --git a/source4/kdc/mit-kdb/kdb_samba_principals.c b/source4/kdc/mit-kdb/kdb_samba_principals.c
|
||||
index 8b67436dc47..79219e5a274 100644
|
||||
--- a/source4/kdc/mit-kdb/kdb_samba_principals.c
|
||||
+++ b/source4/kdc/mit-kdb/kdb_samba_principals.c
|
||||
@@ -33,10 +33,10 @@
|
||||
#define ADMIN_LIFETIME 60*60*3 /* 3 hours */
|
||||
#define CHANGEPW_LIFETIME 60*5 /* 5 minutes */
|
||||
|
||||
-static krb5_error_code ks_get_principal(krb5_context context,
|
||||
- krb5_const_principal principal,
|
||||
- unsigned int kflags,
|
||||
- krb5_db_entry **kentry)
|
||||
+krb5_error_code ks_get_principal(krb5_context context,
|
||||
+ krb5_const_principal principal,
|
||||
+ unsigned int kflags,
|
||||
+ krb5_db_entry **kentry)
|
||||
{
|
||||
struct mit_samba_context *mit_ctx;
|
||||
krb5_error_code code;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,90 @@
|
||||
From 52a505512a2b7d077a4b458a77094c2d2ff72e5e Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Mon, 27 Sep 2021 11:20:19 +1300
|
||||
Subject: [PATCH 081/266] CVE-2020-25721 krb5pac: Add new buffers for
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=52a505512a2b7d077a4b458a77094c2d2ff72e5e
|
||||
|
||||
samAccountName and objectSID
|
||||
|
||||
These appear when PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID is set.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14835
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
---
|
||||
librpc/idl/krb5pac.idl | 18 ++++++++++++++++--
|
||||
librpc/ndr/ndr_krb5pac.c | 4 ++--
|
||||
2 files changed, 18 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl
|
||||
index 515150ab9cd..ed488dee425 100644
|
||||
--- a/librpc/idl/krb5pac.idl
|
||||
+++ b/librpc/idl/krb5pac.idl
|
||||
@@ -86,15 +86,29 @@ interface krb5pac
|
||||
} PAC_CONSTRAINED_DELEGATION;
|
||||
|
||||
typedef [bitmap32bit] bitmap {
|
||||
- PAC_UPN_DNS_FLAG_CONSTRUCTED = 0x00000001
|
||||
+ PAC_UPN_DNS_FLAG_CONSTRUCTED = 0x00000001,
|
||||
+ PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID = 0x00000002
|
||||
} PAC_UPN_DNS_FLAGS;
|
||||
|
||||
+ typedef struct {
|
||||
+ [value(2*strlen_m(samaccountname))] uint16 samaccountname_size;
|
||||
+ [relative_short,subcontext(0),subcontext_size(samaccountname_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *samaccountname;
|
||||
+ [value(ndr_size_dom_sid(objectsid, ndr->flags))] uint16 objectsid_size;
|
||||
+ [relative_short,subcontext(0),subcontext_size(objectsid_size)] dom_sid *objectsid;
|
||||
+ } PAC_UPN_DNS_INFO_SAM_NAME_AND_SID;
|
||||
+
|
||||
+ typedef [nodiscriminant] union {
|
||||
+ [case(PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID)] PAC_UPN_DNS_INFO_SAM_NAME_AND_SID sam_name_and_sid;
|
||||
+ [default];
|
||||
+ } PAC_UPN_DNS_INFO_EX;
|
||||
+
|
||||
typedef struct {
|
||||
[value(2*strlen_m(upn_name))] uint16 upn_name_size;
|
||||
[relative_short,subcontext(0),subcontext_size(upn_name_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *upn_name;
|
||||
[value(2*strlen_m(dns_domain_name))] uint16 dns_domain_name_size;
|
||||
[relative_short,subcontext(0),subcontext_size(dns_domain_name_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *dns_domain_name;
|
||||
PAC_UPN_DNS_FLAGS flags;
|
||||
+ [switch_is(flags & PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID)] PAC_UPN_DNS_INFO_EX ex;
|
||||
} PAC_UPN_DNS_INFO;
|
||||
|
||||
typedef [public] struct {
|
||||
@@ -142,7 +156,7 @@ interface krb5pac
|
||||
|
||||
typedef [public,nopush,nopull] struct {
|
||||
PAC_TYPE type;
|
||||
- [value(_ndr_size_PAC_INFO(info, type, 0))] uint32 _ndr_size;
|
||||
+ [value(_ndr_size_PAC_INFO(info, type, LIBNDR_FLAG_ALIGN8))] uint32 _ndr_size;
|
||||
/*
|
||||
* We need to have two subcontexts to get the padding right,
|
||||
* the outer subcontext uses NDR_ROUND(_ndr_size, 8), while
|
||||
diff --git a/librpc/ndr/ndr_krb5pac.c b/librpc/ndr/ndr_krb5pac.c
|
||||
index a9ae2c4a789..57b28df9e52 100644
|
||||
--- a/librpc/ndr/ndr_krb5pac.c
|
||||
+++ b/librpc/ndr/ndr_krb5pac.c
|
||||
@@ -41,7 +41,7 @@ enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const
|
||||
if (ndr_flags & NDR_SCALARS) {
|
||||
NDR_CHECK(ndr_push_align(ndr, 4));
|
||||
NDR_CHECK(ndr_push_PAC_TYPE(ndr, NDR_SCALARS, r->type));
|
||||
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size_PAC_INFO(r->info,r->type,0)));
|
||||
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size_PAC_INFO(r->info,r->type,LIBNDR_FLAG_ALIGN8)));
|
||||
{
|
||||
uint32_t _flags_save_PAC_INFO = ndr->flags;
|
||||
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8);
|
||||
@@ -59,7 +59,7 @@ enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const
|
||||
{
|
||||
struct ndr_push *_ndr_info_pad;
|
||||
struct ndr_push *_ndr_info;
|
||||
- size_t _ndr_size = _ndr_size_PAC_INFO(r->info, r->type, 0);
|
||||
+ size_t _ndr_size = _ndr_size_PAC_INFO(r->info, r->type, LIBNDR_FLAG_ALIGN8);
|
||||
NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info_pad, 0, NDR_ROUND(_ndr_size, 8)));
|
||||
NDR_CHECK(ndr_push_subcontext_start(_ndr_info_pad, &_ndr_info, 0, _ndr_size));
|
||||
NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->info, r->type));
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
From ec1ea05e8f1dcca14ed7a92a0645da9ff73f33d3 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Thu, 5 Aug 2021 10:34:06 +0200
|
||||
Subject: [PATCH 258/266] CVE-2021-3738 s4:torture/drsuapi: maintain
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=ec1ea05e8f1dcca14ed7a92a0645da9ff73f33d3
|
||||
|
||||
priv->admin_credentials
|
||||
|
||||
This will be used in the next commits.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14468
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
[abartlet@samba.org Backported from patch for master to use
|
||||
the older popt functions as master has the new common command
|
||||
line handling]
|
||||
---
|
||||
source4/torture/rpc/drsuapi.c | 3 +++
|
||||
source4/torture/rpc/drsuapi.h | 1 +
|
||||
2 files changed, 4 insertions(+)
|
||||
|
||||
diff --git a/source4/torture/rpc/drsuapi.c b/source4/torture/rpc/drsuapi.c
|
||||
index 1cd595e5d8e..3e8105af07b 100644
|
||||
--- a/source4/torture/rpc/drsuapi.c
|
||||
+++ b/source4/torture/rpc/drsuapi.c
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
+#include "lib/cmdline/popt_common.h"
|
||||
#include "librpc/gen_ndr/ndr_drsuapi_c.h"
|
||||
#include "torture/rpc/torture_rpc.h"
|
||||
#include "param/param.h"
|
||||
@@ -777,6 +778,8 @@ bool torture_drsuapi_tcase_setup_common(struct torture_context *tctx, struct DsP
|
||||
|
||||
torture_assert(tctx, priv, "Invalid argument");
|
||||
|
||||
+ priv->admin_credentials = popt_get_cmdline_credentials();
|
||||
+
|
||||
torture_comment(tctx, "Create DRSUAPI pipe\n");
|
||||
status = torture_rpc_connection(tctx,
|
||||
&priv->drs_pipe,
|
||||
diff --git a/source4/torture/rpc/drsuapi.h b/source4/torture/rpc/drsuapi.h
|
||||
index f327c54cda4..3cc4be49d99 100644
|
||||
--- a/source4/torture/rpc/drsuapi.h
|
||||
+++ b/source4/torture/rpc/drsuapi.h
|
||||
@@ -27,6 +27,7 @@
|
||||
* Data structure common for most of DRSUAPI tests
|
||||
*/
|
||||
struct DsPrivate {
|
||||
+ struct cli_credentials *admin_credentials;
|
||||
struct dcerpc_pipe *drs_pipe;
|
||||
struct policy_handle bind_handle;
|
||||
struct GUID bind_guid;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
From 721e40dd379a85e153c31b294d1054eeb3718aa0 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Thu, 27 Oct 2016 10:40:28 +0200
|
||||
Subject: [PATCH 255/266] CVE-2016-2124: s3:libsmb: don't fallback to non
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=721e40dd379a85e153c31b294d1054eeb3718aa0
|
||||
|
||||
spnego authentication if we require kerberos
|
||||
|
||||
We should not send NTLM[v2] nor plaintext data on the wire if the user
|
||||
asked for kerberos only.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12444
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
---
|
||||
source3/libsmb/cliconnect.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
|
||||
index 1fb1f0127b9..a79abfaf157 100644
|
||||
--- a/source3/libsmb/cliconnect.c
|
||||
+++ b/source3/libsmb/cliconnect.c
|
||||
@@ -1443,6 +1443,8 @@ struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
|
||||
uint32_t in_sess_key = 0;
|
||||
const char *in_native_os = NULL;
|
||||
const char *in_native_lm = NULL;
|
||||
+ krb5_state =
|
||||
+ cli_credentials_get_kerberos_state(creds);
|
||||
NTSTATUS status;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
@@ -1484,6 +1486,13 @@ struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
|
||||
return req;
|
||||
}
|
||||
|
||||
+ if (krb5_state == CRED_MUST_USE_KERBEROS) {
|
||||
+ DBG_WARNING("Kerberos authentication requested, but "
|
||||
+ "the server does not support SPNEGO authentication\n");
|
||||
+ tevent_req_nterror(req, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
|
||||
+ return tevent_req_post(req, ev);
|
||||
+ }
|
||||
+
|
||||
if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
|
||||
/*
|
||||
* SessionSetupAndX was introduced by LANMAN 1.0. So we skip
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,411 @@
|
||||
From f3957ca5ce206e1224874e6495780b5130d6de0c Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Fri, 11 Sep 2020 12:16:00 +0200
|
||||
Subject: [PATCH 011/266] CVE-2020-25717 winbindd: add generic
|
||||
wb_parent_idmap_setup_send/recv() helpers
|
||||
|
||||
This is more or less a copy of wb_xids2sids_init_dom_maps_send/recv,
|
||||
but it's more generic and doesn't imply global state.
|
||||
|
||||
It also closes a initialization race by using a tevent_queue to
|
||||
serialize the calls.
|
||||
|
||||
In the next commits we'll replace wb_xids2sids_init_dom_maps_send/recv.
|
||||
|
||||
We'll also use the new function in the wb_sids2xids code.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
(cherry picked from commit 209e81a2ea8c972ee57e2f0c9579da843c0e2ac7)
|
||||
---
|
||||
source3/winbindd/winbindd.h | 13 ++
|
||||
source3/winbindd/winbindd_idmap.c | 314 ++++++++++++++++++++++++++++++
|
||||
source3/winbindd/winbindd_proto.h | 5 +
|
||||
3 files changed, 332 insertions(+)
|
||||
|
||||
Conflict:bool is_idmap_child(const struct winbindd_child *child); --> struct dcerpc_binding_handle *idmap_child_handle(void);
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=f3957ca5ce206e1224874e6495780b5130d6de0c
|
||||
|
||||
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
|
||||
index a72d6aa7830..480ba4f1282 100644
|
||||
--- a/source3/winbindd/winbindd.h
|
||||
+++ b/source3/winbindd/winbindd.h
|
||||
@@ -189,6 +189,19 @@ struct winbindd_domain {
|
||||
struct winbindd_domain *prev, *next;
|
||||
};
|
||||
|
||||
+struct wb_parent_idmap_config_dom {
|
||||
+ unsigned low_id;
|
||||
+ unsigned high_id;
|
||||
+ const char *name;
|
||||
+ struct dom_sid sid;
|
||||
+};
|
||||
+
|
||||
+struct wb_parent_idmap_config {
|
||||
+ struct tevent_queue *queue;
|
||||
+ uint32_t num_doms;
|
||||
+ struct wb_parent_idmap_config_dom *doms;
|
||||
+};
|
||||
+
|
||||
struct wb_acct_info {
|
||||
const char *acct_name; /* account name */
|
||||
const char *acct_desc; /* account name */
|
||||
diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c
|
||||
index bd5f3a67aad..487f27fd94d 100644
|
||||
--- a/source3/winbindd/winbindd_idmap.c
|
||||
+++ b/source3/winbindd/winbindd_idmap.c
|
||||
@@ -23,12 +23,21 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "winbindd.h"
|
||||
+#include "../libcli/security/security.h"
|
||||
+#include "passdb/lookup_sid.h"
|
||||
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_WINBIND
|
||||
|
||||
static struct winbindd_child static_idmap_child;
|
||||
|
||||
+/*
|
||||
+ * Map idmap ranges to domain names, taken from smb.conf. This is
|
||||
+ * stored in the parent winbind and used to assemble xids2sids/sids2xids calls
|
||||
+ * into per-idmap-domain chunks.
|
||||
+ */
|
||||
+static struct wb_parent_idmap_config static_parent_idmap_config;
|
||||
+
|
||||
struct winbindd_child *idmap_child(void)
|
||||
{
|
||||
return &static_idmap_child;
|
||||
@@ -73,3 +82,308 @@ void init_idmap_child(void)
|
||||
idmap_dispatch_table,
|
||||
"log.winbindd", "idmap");
|
||||
}
|
||||
+
|
||||
+struct wb_parent_idmap_setup_state {
|
||||
+ struct tevent_context *ev;
|
||||
+ struct wb_parent_idmap_config *cfg;
|
||||
+ size_t dom_idx;
|
||||
+};
|
||||
+
|
||||
+static void wb_parent_idmap_setup_cleanup(struct tevent_req *req,
|
||||
+ enum tevent_req_state req_state)
|
||||
+{
|
||||
+ struct wb_parent_idmap_setup_state *state =
|
||||
+ tevent_req_data(req,
|
||||
+ struct wb_parent_idmap_setup_state);
|
||||
+
|
||||
+ if (req_state == TEVENT_REQ_DONE) {
|
||||
+ state->cfg = NULL;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (state->cfg == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ state->cfg->num_doms = 0;
|
||||
+ TALLOC_FREE(state->cfg->doms);
|
||||
+ state->cfg = NULL;
|
||||
+}
|
||||
+
|
||||
+static void wb_parent_idmap_setup_queue_wait_done(struct tevent_req *subreq);
|
||||
+static bool wb_parent_idmap_setup_scan_config(const char *domname,
|
||||
+ void *private_data);
|
||||
+static void wb_parent_idmap_setup_lookupname_next(struct tevent_req *req);
|
||||
+static void wb_parent_idmap_setup_lookupname_done(struct tevent_req *subreq);
|
||||
+
|
||||
+struct tevent_req *wb_parent_idmap_setup_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev)
|
||||
+{
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct wb_parent_idmap_setup_state *state = NULL;
|
||||
+ struct tevent_req *subreq = NULL;
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state,
|
||||
+ struct wb_parent_idmap_setup_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ *state = (struct wb_parent_idmap_setup_state) {
|
||||
+ .ev = ev,
|
||||
+ .cfg = &static_parent_idmap_config,
|
||||
+ .dom_idx = 0,
|
||||
+ };
|
||||
+
|
||||
+ if (state->cfg->queue == NULL) {
|
||||
+ state->cfg->queue = tevent_queue_create(NULL,
|
||||
+ "wb_parent_idmap_config_queue");
|
||||
+ if (tevent_req_nomem(state->cfg->queue, req)) {
|
||||
+ return tevent_req_post(req, ev);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ subreq = tevent_queue_wait_send(state, state->ev, state->cfg->queue);
|
||||
+ if (tevent_req_nomem(subreq, req)) {
|
||||
+ return tevent_req_post(req, ev);
|
||||
+ }
|
||||
+ tevent_req_set_callback(subreq,
|
||||
+ wb_parent_idmap_setup_queue_wait_done,
|
||||
+ req);
|
||||
+
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static void wb_parent_idmap_setup_queue_wait_done(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct tevent_req *req =
|
||||
+ tevent_req_callback_data(subreq,
|
||||
+ struct tevent_req);
|
||||
+ struct wb_parent_idmap_setup_state *state =
|
||||
+ tevent_req_data(req,
|
||||
+ struct wb_parent_idmap_setup_state);
|
||||
+ bool ok;
|
||||
+
|
||||
+ /*
|
||||
+ * Note we don't call TALLOC_FREE(subreq) here in order to block the
|
||||
+ * queue until tevent_req_received() in wb_parent_idmap_setup_recv()
|
||||
+ * will destroy it implicitly.
|
||||
+ */
|
||||
+ ok = tevent_queue_wait_recv(subreq);
|
||||
+ if (!ok) {
|
||||
+ DBG_ERR("tevent_queue_wait_recv() failed\n");
|
||||
+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (state->cfg->num_doms != 0) {
|
||||
+ /*
|
||||
+ * If we're not the first one we're done.
|
||||
+ */
|
||||
+ tevent_req_done(req);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * From this point we start changing state->cfg,
|
||||
+ * which is &static_parent_idmap_config,
|
||||
+ * so we better setup a cleanup function
|
||||
+ * to undo the changes on failure.
|
||||
+ */
|
||||
+ tevent_req_set_cleanup_fn(req, wb_parent_idmap_setup_cleanup);
|
||||
+
|
||||
+ /*
|
||||
+ * Put the passdb idmap domain first. We always need to try
|
||||
+ * there first.
|
||||
+ */
|
||||
+ state->cfg->doms = talloc_zero_array(NULL,
|
||||
+ struct wb_parent_idmap_config_dom,
|
||||
+ 1);
|
||||
+ if (tevent_req_nomem(state->cfg->doms, req)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ state->cfg->doms[0].low_id = 0;
|
||||
+ state->cfg->doms[0].high_id = UINT_MAX;
|
||||
+ state->cfg->doms[0].name = talloc_strdup(state->cfg->doms,
|
||||
+ get_global_sam_name());
|
||||
+ if (tevent_req_nomem(state->cfg->doms[0].name, req)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ state->cfg->num_doms += 1;
|
||||
+
|
||||
+ lp_scan_idmap_domains(wb_parent_idmap_setup_scan_config, req);
|
||||
+ if (!tevent_req_is_in_progress(req)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ wb_parent_idmap_setup_lookupname_next(req);
|
||||
+}
|
||||
+
|
||||
+static bool wb_parent_idmap_setup_scan_config(const char *domname,
|
||||
+ void *private_data)
|
||||
+{
|
||||
+ struct tevent_req *req =
|
||||
+ talloc_get_type_abort(private_data,
|
||||
+ struct tevent_req);
|
||||
+ struct wb_parent_idmap_setup_state *state =
|
||||
+ tevent_req_data(req,
|
||||
+ struct wb_parent_idmap_setup_state);
|
||||
+ struct wb_parent_idmap_config_dom *map = NULL;
|
||||
+ size_t i;
|
||||
+ const char *range;
|
||||
+ unsigned low_id, high_id;
|
||||
+ int ret;
|
||||
+
|
||||
+ range = idmap_config_const_string(domname, "range", NULL);
|
||||
+ if (range == NULL) {
|
||||
+ DBG_DEBUG("No range for domain %s found\n", domname);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ ret = sscanf(range, "%u - %u", &low_id, &high_id);
|
||||
+ if (ret != 2) {
|
||||
+ DBG_DEBUG("Invalid range spec \"%s\" for domain %s\n",
|
||||
+ range, domname);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (low_id > high_id) {
|
||||
+ DBG_DEBUG("Invalid range %u - %u for domain %s\n",
|
||||
+ low_id, high_id, domname);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ for (i=0; i<state->cfg->num_doms; i++) {
|
||||
+ if (strequal(domname, state->cfg->doms[i].name)) {
|
||||
+ map = &state->cfg->doms[i];
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (map == NULL) {
|
||||
+ struct wb_parent_idmap_config_dom *tmp;
|
||||
+ char *name;
|
||||
+
|
||||
+ name = talloc_strdup(state, domname);
|
||||
+ if (name == NULL) {
|
||||
+ DBG_ERR("talloc failed\n");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ tmp = talloc_realloc(
|
||||
+ NULL, state->cfg->doms, struct wb_parent_idmap_config_dom,
|
||||
+ state->cfg->num_doms+1);
|
||||
+ if (tmp == NULL) {
|
||||
+ DBG_ERR("talloc failed\n");
|
||||
+ return false;
|
||||
+ }
|
||||
+ state->cfg->doms = tmp;
|
||||
+
|
||||
+ map = &state->cfg->doms[state->cfg->num_doms];
|
||||
+ state->cfg->num_doms += 1;
|
||||
+ ZERO_STRUCTP(map);
|
||||
+ map->name = talloc_move(state->cfg->doms, &name);
|
||||
+ }
|
||||
+
|
||||
+ map->low_id = low_id;
|
||||
+ map->high_id = high_id;
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static void wb_parent_idmap_setup_lookupname_next(struct tevent_req *req)
|
||||
+{
|
||||
+ struct wb_parent_idmap_setup_state *state =
|
||||
+ tevent_req_data(req,
|
||||
+ struct wb_parent_idmap_setup_state);
|
||||
+ struct wb_parent_idmap_config_dom *dom =
|
||||
+ &state->cfg->doms[state->dom_idx];
|
||||
+ struct tevent_req *subreq = NULL;
|
||||
+
|
||||
+ next_domain:
|
||||
+ if (state->dom_idx == state->cfg->num_doms) {
|
||||
+ tevent_req_done(req);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (strequal(dom->name, "*")) {
|
||||
+ state->dom_idx++;
|
||||
+ goto next_domain;
|
||||
+ }
|
||||
+
|
||||
+ subreq = wb_lookupname_send(state,
|
||||
+ state->ev,
|
||||
+ dom->name,
|
||||
+ dom->name,
|
||||
+ "",
|
||||
+ LOOKUP_NAME_NO_NSS);
|
||||
+ if (tevent_req_nomem(subreq, req)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ tevent_req_set_callback(subreq,
|
||||
+ wb_parent_idmap_setup_lookupname_done,
|
||||
+ req);
|
||||
+}
|
||||
+
|
||||
+static void wb_parent_idmap_setup_lookupname_done(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct tevent_req *req =
|
||||
+ tevent_req_callback_data(subreq,
|
||||
+ struct tevent_req);
|
||||
+ struct wb_parent_idmap_setup_state *state =
|
||||
+ tevent_req_data(req,
|
||||
+ struct wb_parent_idmap_setup_state);
|
||||
+ struct wb_parent_idmap_config_dom *dom =
|
||||
+ &state->cfg->doms[state->dom_idx];
|
||||
+ enum lsa_SidType type;
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ status = wb_lookupname_recv(subreq, &dom->sid, &type);
|
||||
+ TALLOC_FREE(subreq);
|
||||
+ if (!NT_STATUS_IS_OK(status)) {
|
||||
+ DBG_ERR("Lookup domain name '%s' failed '%s'\n",
|
||||
+ dom->name,
|
||||
+ nt_errstr(status));
|
||||
+
|
||||
+ state->dom_idx++;
|
||||
+ wb_parent_idmap_setup_lookupname_next(req);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (type != SID_NAME_DOMAIN) {
|
||||
+ struct dom_sid_buf buf;
|
||||
+
|
||||
+ DBG_ERR("SID %s for idmap domain name '%s' "
|
||||
+ "not a domain SID\n",
|
||||
+ dom_sid_str_buf(&dom->sid, &buf),
|
||||
+ dom->name);
|
||||
+
|
||||
+ ZERO_STRUCT(dom->sid);
|
||||
+ }
|
||||
+
|
||||
+ state->dom_idx++;
|
||||
+ wb_parent_idmap_setup_lookupname_next(req);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+NTSTATUS wb_parent_idmap_setup_recv(struct tevent_req *req,
|
||||
+ const struct wb_parent_idmap_config **_cfg)
|
||||
+{
|
||||
+ const struct wb_parent_idmap_config *cfg = &static_parent_idmap_config;
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ *_cfg = NULL;
|
||||
+
|
||||
+ if (tevent_req_is_nterror(req, &status)) {
|
||||
+ tevent_req_received(req);
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Note state->cfg is already set to NULL by
|
||||
+ * wb_parent_idmap_setup_cleanup()
|
||||
+ */
|
||||
+ *_cfg = cfg;
|
||||
+ tevent_req_received(req);
|
||||
+ return NT_STATUS_OK;
|
||||
+}
|
||||
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
|
||||
index 97c38018aac..8923bb3124f 100644
|
||||
--- a/source3/winbindd/winbindd_proto.h
|
||||
+++ b/source3/winbindd/winbindd_proto.h
|
||||
@@ -364,6 +364,11 @@ NTSTATUS winbindd_print_groupmembers(struct db_context *members,
|
||||
|
||||
/* The following definitions come from winbindd/winbindd_idmap.c */
|
||||
|
||||
+struct tevent_req *wb_parent_idmap_setup_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev);
|
||||
+NTSTATUS wb_parent_idmap_setup_recv(struct tevent_req *req,
|
||||
+ const struct wb_parent_idmap_config **_cfg);
|
||||
+
|
||||
void init_idmap_child(void);
|
||||
struct winbindd_child *idmap_child(void);
|
||||
struct dcerpc_binding_handle *idmap_child_handle(void);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
144
backport-0001-CVE-2020-25718-trailing-chunk-must-match.patch
Normal file
144
backport-0001-CVE-2020-25718-trailing-chunk-must-match.patch
Normal file
@ -0,0 +1,144 @@
|
||||
From 84998f4d717de484c510594e00fd0a6f07babf1c Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 3 Mar 2021 19:17:36 +1300
|
||||
Subject: [PATCH 002/284] CVE-2020-25718 ldb_match: trailing chunk must match
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=84998f4d717de484c510594e00fd0a6f07babf1c
|
||||
|
||||
end of string
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
A wildcard search is divided into chunks by the asterisks. While most
|
||||
chunks match the first suitable string, the last chunk matches the
|
||||
last possible string (unless there is a trailing asterisk, in which
|
||||
case this distinction is moot).
|
||||
|
||||
We always knew this in our hearts, but we tried to do it in a funny
|
||||
complicated way that stepped through the string, comparing here and
|
||||
there, leading to CVE-2019-3824 and missed matches (bug 14044).
|
||||
|
||||
With this patch, we just jump to the end of the string and compare it.
|
||||
As well as being correct, this should also improve performance, as the
|
||||
previous algorithm involved a quadratic loop of erroneous memmem()s.
|
||||
|
||||
See https://tools.ietf.org/html/rfc4517
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14044
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Bj枚rn Jacke <bjacke@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558
|
||||
|
||||
(cherry picked from commit cc098f1cad04b2cfec4ddd6b2511cd5a600f31c6)
|
||||
---
|
||||
lib/ldb/common/ldb_match.c | 80 +++++++++++++++++---------------------
|
||||
1 file changed, 35 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/lib/ldb/common/ldb_match.c b/lib/ldb/common/ldb_match.c
|
||||
index 829afa77e716..da595615bd94 100644
|
||||
--- a/lib/ldb/common/ldb_match.c
|
||||
+++ b/lib/ldb/common/ldb_match.c
|
||||
@@ -295,8 +295,9 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
|
||||
uint8_t *p;
|
||||
|
||||
chunk = tree->u.substring.chunks[c];
|
||||
- if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch;
|
||||
-
|
||||
+ if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) {
|
||||
+ goto mismatch;
|
||||
+ }
|
||||
/*
|
||||
* Empty strings are returned as length 0. Ensure
|
||||
* we can cope with this.
|
||||
@@ -304,52 +305,41 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
|
||||
if (cnk.length == 0) {
|
||||
goto mismatch;
|
||||
}
|
||||
- /*
|
||||
- * Values might be binary blobs. Don't use string
|
||||
- * search, but memory search instead.
|
||||
- */
|
||||
- p = memmem((const void *)val.data,val.length,
|
||||
- (const void *)cnk.data, cnk.length);
|
||||
- if (p == NULL) goto mismatch;
|
||||
-
|
||||
- /*
|
||||
- * At this point we know cnk.length <= val.length as
|
||||
- * otherwise there could be no match
|
||||
- */
|
||||
+ if (cnk.length > val.length) {
|
||||
+ goto mismatch;
|
||||
+ }
|
||||
|
||||
- if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) {
|
||||
- uint8_t *g;
|
||||
- uint8_t *end = val.data + val.length;
|
||||
- do { /* greedy */
|
||||
-
|
||||
- /*
|
||||
- * haystack is a valid pointer in val
|
||||
- * because the memmem() can only
|
||||
- * succeed if the needle (cnk.length)
|
||||
- * is <= haystacklen
|
||||
- *
|
||||
- * p will be a pointer at least
|
||||
- * cnk.length from the end of haystack
|
||||
- */
|
||||
- uint8_t *haystack
|
||||
- = p + cnk.length;
|
||||
- size_t haystacklen
|
||||
- = end - (haystack);
|
||||
-
|
||||
- g = memmem(haystack,
|
||||
- haystacklen,
|
||||
- (const uint8_t *)cnk.data,
|
||||
- cnk.length);
|
||||
- if (g) {
|
||||
- p = g;
|
||||
- }
|
||||
- } while(g);
|
||||
+ if ( (tree->u.substring.chunks[c + 1]) == NULL &&
|
||||
+ (! tree->u.substring.end_with_wildcard) ) {
|
||||
+ /*
|
||||
+ * The last bit, after all the asterisks, must match
|
||||
+ * exactly the last bit of the string.
|
||||
+ */
|
||||
+ int cmp;
|
||||
+ p = val.data + val.length - cnk.length;
|
||||
+ cmp = memcmp(p,
|
||||
+ cnk.data,
|
||||
+ cnk.length);
|
||||
+ if (cmp != 0) {
|
||||
+ goto mismatch;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Values might be binary blobs. Don't use string
|
||||
+ * search, but memory search instead.
|
||||
+ */
|
||||
+ p = memmem((const void *)val.data, val.length,
|
||||
+ (const void *)cnk.data, cnk.length);
|
||||
+ if (p == NULL) {
|
||||
+ goto mismatch;
|
||||
+ }
|
||||
+ /* move val to the end of the match */
|
||||
+ p += cnk.length;
|
||||
+ val.length -= (p - val.data);
|
||||
+ val.data = p;
|
||||
}
|
||||
- val.length = val.length - (p - (uint8_t *)(val.data)) - cnk.length;
|
||||
- val.data = (uint8_t *)(p + cnk.length);
|
||||
c++;
|
||||
- talloc_free(cnk.data);
|
||||
- cnk.data = NULL;
|
||||
+ TALLOC_FREE(cnk.data);
|
||||
}
|
||||
|
||||
/* last chunk may not have reached end of string */
|
||||
--
|
||||
2.25.1
|
||||
@ -0,0 +1,101 @@
|
||||
From 9902f1b0bf30b663a457230d3b3dcd92fd279879 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schneider <asn@samba.org>
|
||||
Date: Wed, 14 Jul 2021 14:51:34 +0200
|
||||
Subject: [PATCH 201/266] CVE-2020-25719 mit-samba: Add ks_free_principal()
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=9902f1b0bf30b663a457230d3b3dcd92fd279879
|
||||
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561
|
||||
|
||||
[abartlet@samba.org As submitted in patch to Samba bugzilla
|
||||
to address this issue as https://attachments.samba.org/attachment.cgi?id=16724
|
||||
on overall bug https://bugzilla.samba.org/show_bug.cgi?id=14725]
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
---
|
||||
source4/kdc/mit-kdb/kdb_samba.h | 2 +
|
||||
source4/kdc/mit-kdb/kdb_samba_principals.c | 52 ++++++++++++++++++++++
|
||||
2 files changed, 54 insertions(+)
|
||||
|
||||
diff --git a/source4/kdc/mit-kdb/kdb_samba.h b/source4/kdc/mit-kdb/kdb_samba.h
|
||||
index 132dcfed363..2ff8642cc50 100644
|
||||
--- a/source4/kdc/mit-kdb/kdb_samba.h
|
||||
+++ b/source4/kdc/mit-kdb/kdb_samba.h
|
||||
@@ -46,6 +46,8 @@ krb5_error_code ks_get_principal(krb5_context context,
|
||||
unsigned int kflags,
|
||||
krb5_db_entry **kentry);
|
||||
|
||||
+void ks_free_principal(krb5_context context, krb5_db_entry *entry);
|
||||
+
|
||||
bool ks_data_eq_string(krb5_data d, const char *s);
|
||||
|
||||
krb5_data ks_make_data(void *data, unsigned int len);
|
||||
diff --git a/source4/kdc/mit-kdb/kdb_samba_principals.c b/source4/kdc/mit-kdb/kdb_samba_principals.c
|
||||
index 79219e5a274..cc67c2392be 100644
|
||||
--- a/source4/kdc/mit-kdb/kdb_samba_principals.c
|
||||
+++ b/source4/kdc/mit-kdb/kdb_samba_principals.c
|
||||
@@ -59,6 +59,58 @@ cleanup:
|
||||
return code;
|
||||
}
|
||||
|
||||
+static void ks_free_principal_e_data(krb5_context context, krb5_octet *e_data)
|
||||
+{
|
||||
+ struct samba_kdc_entry *skdc_entry;
|
||||
+
|
||||
+ skdc_entry = talloc_get_type_abort(e_data,
|
||||
+ struct samba_kdc_entry);
|
||||
+ talloc_set_destructor(skdc_entry, NULL);
|
||||
+ TALLOC_FREE(skdc_entry);
|
||||
+}
|
||||
+
|
||||
+void ks_free_principal(krb5_context context, krb5_db_entry *entry)
|
||||
+{
|
||||
+ krb5_tl_data *tl_data_next = NULL;
|
||||
+ krb5_tl_data *tl_data = NULL;
|
||||
+ size_t i, j;
|
||||
+
|
||||
+ if (entry != NULL) {
|
||||
+ krb5_free_principal(context, entry->princ);
|
||||
+
|
||||
+ for (tl_data = entry->tl_data; tl_data; tl_data = tl_data_next) {
|
||||
+ tl_data_next = tl_data->tl_data_next;
|
||||
+ if (tl_data->tl_data_contents != NULL) {
|
||||
+ free(tl_data->tl_data_contents);
|
||||
+ }
|
||||
+ free(tl_data);
|
||||
+ }
|
||||
+
|
||||
+ if (entry->key_data != NULL) {
|
||||
+ for (i = 0; i < entry->n_key_data; i++) {
|
||||
+ for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
|
||||
+ if (entry->key_data[i].key_data_length[j] != 0) {
|
||||
+ if (entry->key_data[i].key_data_contents[j] != NULL) {
|
||||
+ memset(entry->key_data[i].key_data_contents[j], 0, entry->key_data[i].key_data_length[j]);
|
||||
+ free(entry->key_data[i].key_data_contents[j]);
|
||||
+ }
|
||||
+ }
|
||||
+ entry->key_data[i].key_data_contents[j] = NULL;
|
||||
+ entry->key_data[i].key_data_length[j] = 0;
|
||||
+ entry->key_data[i].key_data_type[j] = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ free(entry->key_data);
|
||||
+ }
|
||||
+
|
||||
+ if (entry->e_data) {
|
||||
+ ks_free_principal_e_data(context, entry->e_data);
|
||||
+ }
|
||||
+
|
||||
+ free(entry);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static krb5_boolean ks_is_master_key_principal(krb5_context context,
|
||||
krb5_const_principal princ)
|
||||
{
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From c59f5762ead77bcf9add3994a88a6d2b8e383869 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Mon, 27 Sep 2021 12:10:02 +1300
|
||||
Subject: [PATCH 227/266] CVE-2020-25721 auth: Fill in the new
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=c59f5762ead77bcf9add3994a88a6d2b8e383869
|
||||
|
||||
HAS_SAM_NAME_AND_SID values
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14835
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
---
|
||||
python/samba/tests/krb5/s4u_tests.py | 2 --
|
||||
selftest/knownfail_heimdal_kdc | 10 ----------
|
||||
selftest/knownfail_mit_kdc | 4 ----
|
||||
source4/kdc/pac-glue.c | 8 ++++++++
|
||||
4 files changed, 8 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c
|
||||
index cb0a923fc2d..95f71c04b23 100644
|
||||
--- a/source4/kdc/pac-glue.c
|
||||
+++ b/source4/kdc/pac-glue.c
|
||||
@@ -101,6 +101,14 @@ NTSTATUS samba_get_upn_info_pac_blob(TALLOC_CTX *mem_ctx,
|
||||
pac_upn.upn_dns_info.flags |= PAC_UPN_DNS_FLAG_CONSTRUCTED;
|
||||
}
|
||||
|
||||
+ pac_upn.upn_dns_info.flags |= PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID;
|
||||
+
|
||||
+ pac_upn.upn_dns_info.ex.sam_name_and_sid.samaccountname
|
||||
+ = info->info->account_name;
|
||||
+
|
||||
+ pac_upn.upn_dns_info.ex.sam_name_and_sid.objectsid
|
||||
+ = &info->sids[0];
|
||||
+
|
||||
ndr_err = ndr_push_union_blob(upn_data, mem_ctx, &pac_upn,
|
||||
PAC_TYPE_UPN_DNS_INFO,
|
||||
(ndr_push_flags_fn_t)ndr_push_PAC_INFO);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,149 @@
|
||||
From 0c20aa465c4543055fcb38d3e28cefb9ee603f87 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Thu, 12 Aug 2021 11:10:09 +1200
|
||||
Subject: [PATCH 056/266] CVE-2020-25722 dsdb: Move krbtgt password setup after
|
||||
the point of checking if any passwords are changed
|
||||
|
||||
This allows the add of an RODC, before setting the password, to avoid
|
||||
this module, which helps isolate testing of security around the
|
||||
msDS-SecondaryKrbTgtNumber attribute.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14703
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/0c20aa465c4543055fcb38d3e28cefb9ee603f87
|
||||
|
||||
---
|
||||
.../dsdb/samdb/ldb_modules/password_hash.c | 106 +++++++++---------
|
||||
1 files changed, 53 insertions(+), 53 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
|
||||
index 82d9e8ebd2e..bb437a3b982 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
|
||||
@@ -2476,6 +2476,59 @@ static int setup_password_fields(struct setup_password_fields_io *io)
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
+ if (io->u.is_krbtgt) {
|
||||
+ size_t min = 196;
|
||||
+ size_t max = 255;
|
||||
+ size_t diff = max - min;
|
||||
+ size_t len = max;
|
||||
+ struct ldb_val *krbtgt_utf16 = NULL;
|
||||
+
|
||||
+ if (!io->ac->pwd_reset) {
|
||||
+ return dsdb_module_werror(io->ac->module,
|
||||
+ LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS,
|
||||
+ WERR_DS_ATT_ALREADY_EXISTS,
|
||||
+ "Password change on krbtgt not permitted!");
|
||||
+ }
|
||||
+
|
||||
+ if (io->n.cleartext_utf16 == NULL) {
|
||||
+ return dsdb_module_werror(io->ac->module,
|
||||
+ LDB_ERR_UNWILLING_TO_PERFORM,
|
||||
+ WERR_DS_INVALID_ATTRIBUTE_SYNTAX,
|
||||
+ "Password reset on krbtgt requires UTF16!");
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Instead of taking the callers value,
|
||||
+ * we just generate a new random value here.
|
||||
+ *
|
||||
+ * Include null termination in the array.
|
||||
+ */
|
||||
+ if (diff > 0) {
|
||||
+ size_t tmp;
|
||||
+
|
||||
+ generate_random_buffer((uint8_t *)&tmp, sizeof(tmp));
|
||||
+
|
||||
+ tmp %= diff;
|
||||
+
|
||||
+ len = min + tmp;
|
||||
+ }
|
||||
+
|
||||
+ krbtgt_utf16 = talloc_zero(io->ac, struct ldb_val);
|
||||
+ if (krbtgt_utf16 == NULL) {
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+
|
||||
+ *krbtgt_utf16 = data_blob_talloc_zero(krbtgt_utf16,
|
||||
+ (len+1)*2);
|
||||
+ if (krbtgt_utf16->data == NULL) {
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+ krbtgt_utf16->length = len * 2;
|
||||
+ generate_secret_buffer(krbtgt_utf16->data,
|
||||
+ krbtgt_utf16->length);
|
||||
+ io->n.cleartext_utf16 = krbtgt_utf16;
|
||||
+ }
|
||||
+
|
||||
/* transform the old password (for password changes) */
|
||||
ret = setup_given_passwords(io, &io->og);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
@@ -3653,59 +3706,6 @@ static int setup_io(struct ph_context *ac,
|
||||
return ldb_operr(ldb);
|
||||
}
|
||||
|
||||
- if (io->u.is_krbtgt) {
|
||||
- size_t min = 196;
|
||||
- size_t max = 255;
|
||||
- size_t diff = max - min;
|
||||
- size_t len = max;
|
||||
- struct ldb_val *krbtgt_utf16 = NULL;
|
||||
-
|
||||
- if (!ac->pwd_reset) {
|
||||
- return dsdb_module_werror(ac->module,
|
||||
- LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS,
|
||||
- WERR_DS_ATT_ALREADY_EXISTS,
|
||||
- "Password change on krbtgt not permitted!");
|
||||
- }
|
||||
-
|
||||
- if (io->n.cleartext_utf16 == NULL) {
|
||||
- return dsdb_module_werror(ac->module,
|
||||
- LDB_ERR_UNWILLING_TO_PERFORM,
|
||||
- WERR_DS_INVALID_ATTRIBUTE_SYNTAX,
|
||||
- "Password reset on krbtgt requires UTF16!");
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * Instead of taking the callers value,
|
||||
- * we just generate a new random value here.
|
||||
- *
|
||||
- * Include null termination in the array.
|
||||
- */
|
||||
- if (diff > 0) {
|
||||
- size_t tmp;
|
||||
-
|
||||
- generate_random_buffer((uint8_t *)&tmp, sizeof(tmp));
|
||||
-
|
||||
- tmp %= diff;
|
||||
-
|
||||
- len = min + tmp;
|
||||
- }
|
||||
-
|
||||
- krbtgt_utf16 = talloc_zero(io->ac, struct ldb_val);
|
||||
- if (krbtgt_utf16 == NULL) {
|
||||
- return ldb_oom(ldb);
|
||||
- }
|
||||
-
|
||||
- *krbtgt_utf16 = data_blob_talloc_zero(krbtgt_utf16,
|
||||
- (len+1)*2);
|
||||
- if (krbtgt_utf16->data == NULL) {
|
||||
- return ldb_oom(ldb);
|
||||
- }
|
||||
- krbtgt_utf16->length = len * 2;
|
||||
- generate_secret_buffer(krbtgt_utf16->data,
|
||||
- krbtgt_utf16->length);
|
||||
- io->n.cleartext_utf16 = krbtgt_utf16;
|
||||
- }
|
||||
-
|
||||
if (existing_msg != NULL) {
|
||||
NTSTATUS status;
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,183 @@
|
||||
From 7c3b037600077ade1d0ee97f5707e1c5061c1b28 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Thu, 5 Aug 2021 14:22:32 +0200
|
||||
Subject: [PATCH 261/266] CVE-2021-3738 s4:rpc_server/common: provide
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=7c3b037600077ade1d0ee97f5707e1c5061c1b28
|
||||
|
||||
assoc_group aware dcesrv_samdb_connect_as_{system,user}() helpers
|
||||
|
||||
We already had dcesrv_samdb_connect_as_system(), but it uses the per
|
||||
connection memory of auth_session_info and remote_address.
|
||||
|
||||
But in order to use the samdb connection on a per association group
|
||||
context/policy handle, we need to make copies, which last for the
|
||||
whole lifetime of the 'samdb' context.
|
||||
|
||||
We need the same logic also for all cases we make use of
|
||||
the almost same logic where we want to create a samdb context
|
||||
on behalf of the authenticated user (without allowing system access),
|
||||
so we introduce dcesrv_samdb_connect_as_user().
|
||||
|
||||
In the end we need to replace all direct callers to samdb_connect()
|
||||
from source4/rpc_server.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14468
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source4/rpc_server/common/server_info.c | 121 ++++++++++++++++++++----
|
||||
1 file changed, 105 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/source4/rpc_server/common/server_info.c b/source4/rpc_server/common/server_info.c
|
||||
index 6e475bcc796..a2af37653ef 100644
|
||||
--- a/source4/rpc_server/common/server_info.c
|
||||
+++ b/source4/rpc_server/common/server_info.c
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "param/param.h"
|
||||
#include "rpc_server/common/common.h"
|
||||
#include "libds/common/roles.h"
|
||||
+#include "auth/auth_util.h"
|
||||
+#include "lib/tsocket/tsocket.h"
|
||||
|
||||
/*
|
||||
Here are common server info functions used by some dcerpc server interfaces
|
||||
@@ -188,30 +190,117 @@ bool dcesrv_common_validate_share_name(TALLOC_CTX *mem_ctx, const char *share_na
|
||||
return true;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Open an ldb connection under the system session and save the remote users
|
||||
- * session details in a ldb_opaque. This will allow the audit logging to
|
||||
- * log the original session for operations performed in the system session.
|
||||
- */
|
||||
-struct ldb_context *dcesrv_samdb_connect_as_system(
|
||||
+static struct ldb_context *dcesrv_samdb_connect_common(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
- struct dcesrv_call_state *dce_call)
|
||||
+ struct dcesrv_call_state *dce_call,
|
||||
+ bool as_system)
|
||||
{
|
||||
struct ldb_context *samdb = NULL;
|
||||
+ struct auth_session_info *system_session_info = NULL;
|
||||
+ const struct auth_session_info *call_session_info =
|
||||
+ dcesrv_call_session_info(dce_call);
|
||||
+ struct auth_session_info *user_session_info = NULL;
|
||||
+ struct auth_session_info *ldb_session_info = NULL;
|
||||
+ struct auth_session_info *audit_session_info = NULL;
|
||||
+ struct tsocket_address *remote_address = NULL;
|
||||
+
|
||||
+ if (as_system) {
|
||||
+ system_session_info = system_session(dce_call->conn->dce_ctx->lp_ctx);
|
||||
+ if (system_session_info == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ user_session_info = copy_session_info(mem_ctx, call_session_info);
|
||||
+ if (user_session_info == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (dce_call->conn->remote_address != NULL) {
|
||||
+ remote_address = tsocket_address_copy(dce_call->conn->remote_address,
|
||||
+ user_session_info);
|
||||
+ if (remote_address == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (system_session_info != NULL) {
|
||||
+ ldb_session_info = system_session_info;
|
||||
+ audit_session_info = user_session_info;
|
||||
+ } else {
|
||||
+ ldb_session_info = user_session_info;
|
||||
+ audit_session_info = NULL;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * We need to make sure every argument
|
||||
+ * stays arround for the lifetime of 'samdb',
|
||||
+ * typically it is allocated on the scope of
|
||||
+ * an assoc group, so we can't reference dce_call->conn,
|
||||
+ * as the assoc group may stay when the current connection
|
||||
+ * gets disconnected.
|
||||
+ *
|
||||
+ * The following are global per process:
|
||||
+ * - dce_call->conn->dce_ctx->lp_ctx
|
||||
+ * - dce_call->event_ctx
|
||||
+ * - system_session
|
||||
+ *
|
||||
+ * We make a copy of:
|
||||
+ * - dce_call->conn->remote_address
|
||||
+ * - dce_call->auth_state->session_info
|
||||
+ */
|
||||
samdb = samdb_connect(
|
||||
mem_ctx,
|
||||
dce_call->event_ctx,
|
||||
dce_call->conn->dce_ctx->lp_ctx,
|
||||
- system_session(dce_call->conn->dce_ctx->lp_ctx),
|
||||
- dce_call->conn->remote_address,
|
||||
+ ldb_session_info,
|
||||
+ remote_address,
|
||||
0);
|
||||
- if (samdb) {
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
- ldb_set_opaque(
|
||||
- samdb,
|
||||
- DSDB_NETWORK_SESSION_INFO,
|
||||
- session_info);
|
||||
+ if (samdb == NULL) {
|
||||
+ talloc_free(user_session_info);
|
||||
+ return NULL;
|
||||
}
|
||||
+ talloc_move(samdb, &user_session_info);
|
||||
+
|
||||
+ if (audit_session_info != NULL) {
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ldb_set_opaque(samdb,
|
||||
+ DSDB_NETWORK_SESSION_INFO,
|
||||
+ audit_session_info);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ talloc_free(samdb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return samdb;
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * Open an ldb connection under the system session and save the remote users
|
||||
+ * session details in a ldb_opaque. This will allow the audit logging to
|
||||
+ * log the original session for operations performed in the system session.
|
||||
+ *
|
||||
+ * Access checks are required by the caller!
|
||||
+ */
|
||||
+struct ldb_context *dcesrv_samdb_connect_as_system(
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ struct dcesrv_call_state *dce_call)
|
||||
+{
|
||||
+ return dcesrv_samdb_connect_common(mem_ctx, dce_call,
|
||||
+ true /* as_system */);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Open an ldb connection under the remote users session details.
|
||||
+ *
|
||||
+ * Access checks are done at the ldb level.
|
||||
+ */
|
||||
+struct ldb_context *dcesrv_samdb_connect_as_user(
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ struct dcesrv_call_state *dce_call)
|
||||
+{
|
||||
+ return dcesrv_samdb_connect_common(mem_ctx, dce_call,
|
||||
+ false /* not as_system */);
|
||||
+}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,362 @@
|
||||
From 5e04b985acc4c774e0057056887a9f1ed05faf9b Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Fri, 11 Sep 2020 12:31:13 +0200
|
||||
Subject: [PATCH 012/266] CVE-2020-25717 wb_xids2sids: make use of the new
|
||||
wb_parent_idmap_setup_send/recv() helpers
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
(cherry picked from commit a8f57c94fc2294c309ecb18ea79d0acac86c495b)
|
||||
---
|
||||
source3/winbindd/wb_xids2sids.c | 255 +++-----------------------------
|
||||
1 file changed, 17 insertions(+), 238 deletions(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=5e04b985acc4c774e0057056887a9f1ed05faf9b
|
||||
|
||||
diff --git a/source3/winbindd/wb_xids2sids.c b/source3/winbindd/wb_xids2sids.c
|
||||
index f88c9be58a8..c68939b2bcd 100644
|
||||
--- a/source3/winbindd/wb_xids2sids.c
|
||||
+++ b/source3/winbindd/wb_xids2sids.c
|
||||
@@ -25,231 +25,13 @@
|
||||
#include "librpc/gen_ndr/ndr_netlogon.h"
|
||||
#include "passdb/lookup_sid.h"
|
||||
|
||||
-struct wb_xids2sids_dom_map {
|
||||
- unsigned low_id;
|
||||
- unsigned high_id;
|
||||
- const char *name;
|
||||
- struct dom_sid sid;
|
||||
-};
|
||||
-
|
||||
-/*
|
||||
- * Map idmap ranges to domain names, taken from smb.conf. This is
|
||||
- * stored in the parent winbind and used to assemble xid2sid calls
|
||||
- * into per-idmap-domain chunks.
|
||||
- */
|
||||
-static struct wb_xids2sids_dom_map *dom_maps;
|
||||
-
|
||||
-static bool wb_xids2sids_add_dom(const char *domname,
|
||||
- void *private_data)
|
||||
-{
|
||||
- struct wb_xids2sids_dom_map *map = NULL;
|
||||
- size_t num_maps = talloc_array_length(dom_maps);
|
||||
- size_t i;
|
||||
- const char *range;
|
||||
- unsigned low_id, high_id;
|
||||
- int ret;
|
||||
-
|
||||
- range = idmap_config_const_string(domname, "range", NULL);
|
||||
- if (range == NULL) {
|
||||
- DBG_DEBUG("No range for domain %s found\n", domname);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- ret = sscanf(range, "%u - %u", &low_id, &high_id);
|
||||
- if (ret != 2) {
|
||||
- DBG_DEBUG("Invalid range spec \"%s\" for domain %s\n",
|
||||
- range, domname);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- if (low_id > high_id) {
|
||||
- DBG_DEBUG("Invalid range %u - %u for domain %s\n",
|
||||
- low_id, high_id, domname);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- for (i=0; i<num_maps; i++) {
|
||||
- if (strequal(domname, dom_maps[i].name)) {
|
||||
- map = &dom_maps[i];
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (map == NULL) {
|
||||
- struct wb_xids2sids_dom_map *tmp;
|
||||
- char *name;
|
||||
-
|
||||
- name = talloc_strdup(talloc_tos(), domname);
|
||||
- if (name == NULL) {
|
||||
- DBG_DEBUG("talloc failed\n");
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- tmp = talloc_realloc(
|
||||
- NULL, dom_maps, struct wb_xids2sids_dom_map,
|
||||
- num_maps+1);
|
||||
- if (tmp == NULL) {
|
||||
- TALLOC_FREE(name);
|
||||
- return false;
|
||||
- }
|
||||
- dom_maps = tmp;
|
||||
-
|
||||
- map = &dom_maps[num_maps];
|
||||
- ZERO_STRUCTP(map);
|
||||
- map->name = talloc_move(dom_maps, &name);
|
||||
- }
|
||||
-
|
||||
- map->low_id = low_id;
|
||||
- map->high_id = high_id;
|
||||
-
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
-struct wb_xids2sids_init_dom_maps_state {
|
||||
- struct tevent_context *ev;
|
||||
- struct tevent_req *req;
|
||||
- size_t dom_idx;
|
||||
-};
|
||||
-
|
||||
-static void wb_xids2sids_init_dom_maps_lookupname_next(
|
||||
- struct wb_xids2sids_init_dom_maps_state *state);
|
||||
-
|
||||
-static void wb_xids2sids_init_dom_maps_lookupname_done(
|
||||
- struct tevent_req *subreq);
|
||||
-
|
||||
-static struct tevent_req *wb_xids2sids_init_dom_maps_send(
|
||||
- TALLOC_CTX *mem_ctx, struct tevent_context *ev)
|
||||
-{
|
||||
- struct tevent_req *req = NULL;
|
||||
- struct wb_xids2sids_init_dom_maps_state *state = NULL;
|
||||
-
|
||||
- req = tevent_req_create(mem_ctx, &state,
|
||||
- struct wb_xids2sids_init_dom_maps_state);
|
||||
- if (req == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
- *state = (struct wb_xids2sids_init_dom_maps_state) {
|
||||
- .ev = ev,
|
||||
- .req = req,
|
||||
- .dom_idx = 0,
|
||||
- };
|
||||
-
|
||||
- if (dom_maps != NULL) {
|
||||
- tevent_req_done(req);
|
||||
- return tevent_req_post(req, ev);
|
||||
- }
|
||||
- /*
|
||||
- * Put the passdb idmap domain first. We always need to try
|
||||
- * there first.
|
||||
- */
|
||||
-
|
||||
- dom_maps = talloc_zero_array(NULL, struct wb_xids2sids_dom_map, 1);
|
||||
- if (tevent_req_nomem(dom_maps, req)) {
|
||||
- return tevent_req_post(req, ev);
|
||||
- }
|
||||
- dom_maps[0].low_id = 0;
|
||||
- dom_maps[0].high_id = UINT_MAX;
|
||||
- dom_maps[0].name = talloc_strdup(dom_maps, get_global_sam_name());
|
||||
- if (tevent_req_nomem(dom_maps[0].name, req)) {
|
||||
- TALLOC_FREE(dom_maps);
|
||||
- return tevent_req_post(req, ev);
|
||||
- }
|
||||
-
|
||||
- lp_scan_idmap_domains(wb_xids2sids_add_dom, NULL);
|
||||
-
|
||||
- wb_xids2sids_init_dom_maps_lookupname_next(state);
|
||||
- if (!tevent_req_is_in_progress(req)) {
|
||||
- tevent_req_post(req, ev);
|
||||
- }
|
||||
- return req;
|
||||
-}
|
||||
-
|
||||
-static void wb_xids2sids_init_dom_maps_lookupname_next(
|
||||
- struct wb_xids2sids_init_dom_maps_state *state)
|
||||
-{
|
||||
- struct tevent_req *subreq = NULL;
|
||||
-
|
||||
- if (state->dom_idx == talloc_array_length(dom_maps)) {
|
||||
- tevent_req_done(state->req);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- if (strequal(dom_maps[state->dom_idx].name, "*")) {
|
||||
- state->dom_idx++;
|
||||
- if (state->dom_idx == talloc_array_length(dom_maps)) {
|
||||
- tevent_req_done(state->req);
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- subreq = wb_lookupname_send(state,
|
||||
- state->ev,
|
||||
- dom_maps[state->dom_idx].name,
|
||||
- dom_maps[state->dom_idx].name,
|
||||
- "",
|
||||
- LOOKUP_NAME_NO_NSS);
|
||||
- if (tevent_req_nomem(subreq, state->req)) {
|
||||
- return;
|
||||
- }
|
||||
- tevent_req_set_callback(subreq,
|
||||
- wb_xids2sids_init_dom_maps_lookupname_done,
|
||||
- state->req);
|
||||
-}
|
||||
-
|
||||
-static void wb_xids2sids_init_dom_maps_lookupname_done(
|
||||
- struct tevent_req *subreq)
|
||||
-{
|
||||
- struct tevent_req *req = tevent_req_callback_data(
|
||||
- subreq, struct tevent_req);
|
||||
- struct wb_xids2sids_init_dom_maps_state *state = tevent_req_data(
|
||||
- req, struct wb_xids2sids_init_dom_maps_state);
|
||||
- enum lsa_SidType type;
|
||||
- NTSTATUS status;
|
||||
-
|
||||
- status = wb_lookupname_recv(subreq,
|
||||
- &dom_maps[state->dom_idx].sid,
|
||||
- &type);
|
||||
- TALLOC_FREE(subreq);
|
||||
- if (!NT_STATUS_IS_OK(status)) {
|
||||
- DBG_WARNING("Lookup domain name '%s' failed '%s'\n",
|
||||
- dom_maps[state->dom_idx].name,
|
||||
- nt_errstr(status));
|
||||
-
|
||||
- state->dom_idx++;
|
||||
- wb_xids2sids_init_dom_maps_lookupname_next(state);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- if (type != SID_NAME_DOMAIN) {
|
||||
- struct dom_sid_buf buf;
|
||||
-
|
||||
- DBG_WARNING("SID %s for idmap domain name '%s' "
|
||||
- "not a domain SID\n",
|
||||
- dom_sid_str_buf(&dom_maps[state->dom_idx].sid,
|
||||
- &buf),
|
||||
- dom_maps[state->dom_idx].name);
|
||||
-
|
||||
- ZERO_STRUCT(dom_maps[state->dom_idx].sid);
|
||||
- }
|
||||
-
|
||||
- state->dom_idx++;
|
||||
- wb_xids2sids_init_dom_maps_lookupname_next(state);
|
||||
-
|
||||
- return;
|
||||
-}
|
||||
-
|
||||
-static NTSTATUS wb_xids2sids_init_dom_maps_recv(struct tevent_req *req)
|
||||
-{
|
||||
- return tevent_req_simple_recv_ntstatus(req);
|
||||
-}
|
||||
-
|
||||
struct wb_xids2sids_dom_state {
|
||||
struct tevent_context *ev;
|
||||
struct unixid *all_xids;
|
||||
const bool *cached;
|
||||
size_t num_all_xids;
|
||||
struct dom_sid *all_sids;
|
||||
- struct wb_xids2sids_dom_map *dom_map;
|
||||
+ const struct wb_parent_idmap_config_dom *dom_map;
|
||||
bool tried_dclookup;
|
||||
|
||||
size_t num_dom_xids;
|
||||
@@ -262,7 +44,7 @@ static void wb_xids2sids_dom_gotdc(struct tevent_req *subreq);
|
||||
|
||||
static struct tevent_req *wb_xids2sids_dom_send(
|
||||
TALLOC_CTX *mem_ctx, struct tevent_context *ev,
|
||||
- struct wb_xids2sids_dom_map *dom_map,
|
||||
+ const struct wb_parent_idmap_config_dom *dom_map,
|
||||
struct unixid *xids,
|
||||
const bool *cached,
|
||||
size_t num_xids,
|
||||
@@ -334,7 +116,7 @@ static void wb_xids2sids_dom_done(struct tevent_req *subreq)
|
||||
subreq, struct tevent_req);
|
||||
struct wb_xids2sids_dom_state *state = tevent_req_data(
|
||||
req, struct wb_xids2sids_dom_state);
|
||||
- struct wb_xids2sids_dom_map *dom_map = state->dom_map;
|
||||
+ const struct wb_parent_idmap_config_dom *dom_map = state->dom_map;
|
||||
NTSTATUS status, result;
|
||||
size_t i;
|
||||
size_t dom_sid_idx;
|
||||
@@ -437,10 +219,11 @@ struct wb_xids2sids_state {
|
||||
bool *cached;
|
||||
|
||||
size_t dom_idx;
|
||||
+ const struct wb_parent_idmap_config *cfg;
|
||||
};
|
||||
|
||||
+static void wb_xids2sids_idmap_setup_done(struct tevent_req *subreq);
|
||||
static void wb_xids2sids_done(struct tevent_req *subreq);
|
||||
-static void wb_xids2sids_init_dom_maps_done(struct tevent_req *subreq);
|
||||
|
||||
struct tevent_req *wb_xids2sids_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
@@ -495,38 +278,32 @@ struct tevent_req *wb_xids2sids_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
- subreq = wb_xids2sids_init_dom_maps_send(
|
||||
- state, state->ev);
|
||||
+ subreq = wb_parent_idmap_setup_send(state, state->ev);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
- tevent_req_set_callback(subreq, wb_xids2sids_init_dom_maps_done, req);
|
||||
+ tevent_req_set_callback(subreq, wb_xids2sids_idmap_setup_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
-static void wb_xids2sids_init_dom_maps_done(struct tevent_req *subreq)
|
||||
+static void wb_xids2sids_idmap_setup_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct wb_xids2sids_state *state = tevent_req_data(
|
||||
req, struct wb_xids2sids_state);
|
||||
- size_t num_domains;
|
||||
NTSTATUS status;
|
||||
|
||||
- status = wb_xids2sids_init_dom_maps_recv(subreq);
|
||||
+ status = wb_parent_idmap_setup_recv(subreq, &state->cfg);
|
||||
TALLOC_FREE(subreq);
|
||||
if (tevent_req_nterror(req, status)) {
|
||||
return;
|
||||
}
|
||||
-
|
||||
- num_domains = talloc_array_length(dom_maps);
|
||||
- if (num_domains == 0) {
|
||||
- tevent_req_done(req);
|
||||
- return;
|
||||
- }
|
||||
+ SMB_ASSERT(state->cfg->num_doms > 0);
|
||||
|
||||
subreq = wb_xids2sids_dom_send(
|
||||
- state, state->ev, &dom_maps[state->dom_idx],
|
||||
+ state, state->ev,
|
||||
+ &state->cfg->doms[state->dom_idx],
|
||||
state->xids, state->cached, state->num_xids, state->sids);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
@@ -541,7 +318,6 @@ static void wb_xids2sids_done(struct tevent_req *subreq)
|
||||
subreq, struct tevent_req);
|
||||
struct wb_xids2sids_state *state = tevent_req_data(
|
||||
req, struct wb_xids2sids_state);
|
||||
- size_t num_domains = talloc_array_length(dom_maps);
|
||||
size_t i;
|
||||
NTSTATUS status;
|
||||
|
||||
@@ -553,10 +329,13 @@ static void wb_xids2sids_done(struct tevent_req *subreq)
|
||||
|
||||
state->dom_idx += 1;
|
||||
|
||||
- if (state->dom_idx < num_domains) {
|
||||
+ if (state->dom_idx < state->cfg->num_doms) {
|
||||
+ const struct wb_parent_idmap_config_dom *dom_map =
|
||||
+ &state->cfg->doms[state->dom_idx];
|
||||
+
|
||||
subreq = wb_xids2sids_dom_send(state,
|
||||
state->ev,
|
||||
- &dom_maps[state->dom_idx],
|
||||
+ dom_map,
|
||||
state->xids,
|
||||
state->cached,
|
||||
state->num_xids,
|
||||
--
|
||||
2.23.0
|
||||
|
||||
42
backport-0002-CVE-2020-25718-fix-ldb_comparison_fold.patch
Normal file
42
backport-0002-CVE-2020-25718-fix-ldb_comparison_fold.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From a94ea2c5bcb6d62b4fe6dda590cf3ed44616f6a2 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Sat, 6 Mar 2021 16:05:15 +1300
|
||||
Subject: [PATCH 003/284] CVE-2020-25718 ldb: fix ldb_comparison_fold
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=a94ea2c5bcb6d62b4fe6dda590cf3ed44616f6a2
|
||||
|
||||
off-by-one overrun
|
||||
|
||||
We run one character over in comparing all the bytes in two ldb_vals.
|
||||
|
||||
In almost all circumstances both ldb_vals would have an allocated '\0'
|
||||
in the overrun position, but it is best not to rely on that.
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558
|
||||
|
||||
(cherry picked from commit 2b2f4f519454beb6f2a46705675a62274019fc09)
|
||||
---
|
||||
lib/ldb/common/attrib_handlers.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/ldb/common/attrib_handlers.c b/lib/ldb/common/attrib_handlers.c
|
||||
index f0fd4f50d8df..6a885065f773 100644
|
||||
--- a/lib/ldb/common/attrib_handlers.c
|
||||
+++ b/lib/ldb/common/attrib_handlers.c
|
||||
@@ -334,8 +334,8 @@ int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx,
|
||||
if (toupper((unsigned char)*s1) != toupper((unsigned char)*s2))
|
||||
break;
|
||||
if (*s1 == ' ') {
|
||||
- while (n1 && s1[0] == s1[1]) { s1++; n1--; }
|
||||
- while (n2 && s2[0] == s2[1]) { s2++; n2--; }
|
||||
+ while (n1 > 1 && s1[0] == s1[1]) { s1++; n1--; }
|
||||
+ while (n2 > 1 && s2[0] == s2[1]) { s2++; n2--; }
|
||||
}
|
||||
s1++; s2++;
|
||||
n1--; n2--;
|
||||
--
|
||||
2.25.1
|
||||
@ -0,0 +1,70 @@
|
||||
From 34347586375dea9b615fb6a0218bcb5927031e4d Mon Sep 17 00:00:00 2001
|
||||
From: Isaac Boukris <iboukris@gmail.com>
|
||||
Date: Thu, 16 Jan 2020 22:00:21 +0100
|
||||
Subject: [PATCH] Sign and verify PAC with ticket principal instead of canon
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=34347586375dea9b615fb6a0218bcb5927031e4d
|
||||
|
||||
principal
|
||||
|
||||
With MIT library 1.18 the KDC no longer set
|
||||
KRB5_KDB_FLAG_CANONICALIZE for enterprise principals which allows
|
||||
us to not canonicalize them (like in Windows / Heimdal).
|
||||
|
||||
However, it now breaks the PAC signature verification as it was
|
||||
wrongly done using canonical client rather than ticket client name.
|
||||
|
||||
Signed-off-by: Isaac Boukris <iboukris@samba.org>
|
||||
Reviewed-by: Andreas Schneider <asn@samba.org>
|
||||
Reviewed-by: Guenther Deschner <gd@samba.org>
|
||||
---
|
||||
source4/kdc/mit-kdb/kdb_samba_policies.c | 12 ++----------
|
||||
1 file changed, 2 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c
|
||||
index 586cf81451d..2eec496fa92 100644
|
||||
--- a/source4/kdc/mit-kdb/kdb_samba_policies.c
|
||||
+++ b/source4/kdc/mit-kdb/kdb_samba_policies.c
|
||||
@@ -301,20 +301,12 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
||||
krb5_authdata **tgt_auth_data,
|
||||
krb5_authdata ***signed_auth_data)
|
||||
{
|
||||
- krb5_const_principal ks_client_princ;
|
||||
krb5_authdata **authdata = NULL;
|
||||
krb5_boolean is_as_req;
|
||||
krb5_error_code code;
|
||||
krb5_pac pac = NULL;
|
||||
krb5_data pac_data;
|
||||
|
||||
- /* Prefer canonicalised name from client entry */
|
||||
- if (client != NULL) {
|
||||
- ks_client_princ = client->princ;
|
||||
- } else {
|
||||
- ks_client_princ = client_princ;
|
||||
- }
|
||||
-
|
||||
is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
|
||||
|
||||
if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) {
|
||||
@@ -354,7 +346,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
||||
if (!is_as_req) {
|
||||
code = ks_verify_pac(context,
|
||||
flags,
|
||||
- ks_client_princ,
|
||||
+ client_princ,
|
||||
client,
|
||||
server,
|
||||
krbtgt,
|
||||
@@ -381,7 +373,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- code = krb5_pac_sign(context, pac, authtime, ks_client_princ,
|
||||
+ code = krb5_pac_sign(context, pac, authtime, client_princ,
|
||||
server_key, krbtgt_key, &pac_data);
|
||||
if (code != 0) {
|
||||
DBG_ERR("krb5_pac_sign failed: %d\n", code);
|
||||
--
|
||||
GitLab
|
||||
|
||||
@ -0,0 +1,235 @@
|
||||
From 448585950bda2c1daab8ffeb3971870ed0416634 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Fri, 13 Aug 2021 17:42:23 +1200
|
||||
Subject: [PATCH 057/266] CVE-2020-25722 dsdb: Restrict the setting of
|
||||
privileged attributes during LDAP add/modify
|
||||
|
||||
The remaining failures in the priv_attrs (not the strict one) test are
|
||||
due to missing objectclass constraints on the administrator which should
|
||||
be addressed, but are not a security issue.
|
||||
|
||||
A better test for confirming constraints between objectclass and
|
||||
userAccountControl UF_NORMAL_ACCONT/UF_WORKSTATION_TRUST values would
|
||||
be user_account_control.py.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14703
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14778
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14775
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/448585950bda2c1daab8ffeb3971870ed0416634
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 148 +++++++++++++++++++++---
|
||||
1 files changed, 129 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 4da8564c77a..cb5fda324a4 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -1976,6 +1976,29 @@ static int samldb_check_user_account_control_invariants(struct samldb_ctx *ac,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int samldb_get_domain_secdesc(struct samldb_ctx *ac,
|
||||
+ struct security_descriptor **domain_sd)
|
||||
+{
|
||||
+ const char * const sd_attrs[] = {"ntSecurityDescriptor", NULL};
|
||||
+ struct ldb_result *res;
|
||||
+ struct ldb_dn *domain_dn = ldb_get_default_basedn(ldb_module_get_ctx(ac->module));
|
||||
+ int ret = dsdb_module_search_dn(ac->module, ac, &res,
|
||||
+ domain_dn,
|
||||
+ sd_attrs,
|
||||
+ DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED,
|
||||
+ ac->req);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ if (res->count != 1) {
|
||||
+ return ldb_module_operr(ac->module);
|
||||
+ }
|
||||
+
|
||||
+ return dsdb_get_sd_from_ldb_message(ldb_module_get_ctx(ac->module),
|
||||
+ ac, res->msgs[0], domain_sd);
|
||||
+
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Validate that the restriction in point 5 of MS-SAMR 3.1.1.8.10 userAccountControl is honoured
|
||||
*
|
||||
@@ -1987,12 +2010,8 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac,
|
||||
{
|
||||
int i, ret = 0;
|
||||
bool need_acl_check = false;
|
||||
- struct ldb_result *res;
|
||||
- const char * const sd_attrs[] = {"ntSecurityDescriptor", NULL};
|
||||
struct security_token *user_token;
|
||||
struct security_descriptor *domain_sd;
|
||||
- struct ldb_dn *domain_dn = ldb_get_default_basedn(ldb_module_get_ctx(ac->module));
|
||||
- struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
const struct uac_to_guid {
|
||||
uint32_t uac;
|
||||
uint32_t priv_to_change_from;
|
||||
@@ -2078,21 +2097,7 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac,
|
||||
return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
||||
}
|
||||
|
||||
- ret = dsdb_module_search_dn(ac->module, ac, &res,
|
||||
- domain_dn,
|
||||
- sd_attrs,
|
||||
- DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED,
|
||||
- ac->req);
|
||||
- if (ret != LDB_SUCCESS) {
|
||||
- return ret;
|
||||
- }
|
||||
- if (res->count != 1) {
|
||||
- return ldb_module_operr(ac->module);
|
||||
- }
|
||||
-
|
||||
- ret = dsdb_get_sd_from_ldb_message(ldb,
|
||||
- ac, res->msgs[0], &domain_sd);
|
||||
-
|
||||
+ ret = samldb_get_domain_secdesc(ac, &domain_sd);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
@@ -2154,6 +2159,8 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac,
|
||||
return ldb_module_operr(ac->module);
|
||||
}
|
||||
if (map[i].guid) {
|
||||
+ struct ldb_dn *domain_dn
|
||||
+ = ldb_get_default_basedn(ldb_module_get_ctx(ac->module));
|
||||
dsdb_acl_debug(domain_sd, acl_user_token(ac->module),
|
||||
domain_dn,
|
||||
true,
|
||||
@@ -3486,7 +3493,98 @@ static char *refer_if_rodc(struct ldb_context *ldb, struct ldb_request *req,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Restrict all access to sensitive attributes.
|
||||
+ *
|
||||
+ * We don't want to even inspect the values, so we can use the same
|
||||
+ * routine for ADD and MODIFY.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+static int samldb_check_sensitive_attributes(struct samldb_ctx *ac)
|
||||
+{
|
||||
+ struct ldb_message_element *el = NULL;
|
||||
+ struct security_token *user_token = NULL;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (dsdb_module_am_system(ac->module)) {
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ user_token = acl_user_token(ac->module);
|
||||
+ if (user_token == NULL) {
|
||||
+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
||||
+ }
|
||||
+
|
||||
+ el = ldb_msg_find_element(ac->msg, "sidHistory");
|
||||
+ if (el) {
|
||||
+ /*
|
||||
+ * sidHistory is restricted to the (not implemented
|
||||
+ * yet in Samba) DsAddSidHistory call (direct LDB access is
|
||||
+ * as SYSTEM so will bypass this).
|
||||
+ *
|
||||
+ * If you want to modify this, say to merge domains,
|
||||
+ * directly modify the sam.ldb as root.
|
||||
+ */
|
||||
+ ldb_asprintf_errstring(ldb_module_get_ctx(ac->module),
|
||||
+ "sidHistory "
|
||||
+ "(entry %s) cannot be created "
|
||||
+ "or changed over LDAP!",
|
||||
+ ldb_dn_get_linearized(ac->msg->dn));
|
||||
+ return LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
|
||||
+ el = ldb_msg_find_element(ac->msg, "msDS-SecondaryKrbTgtNumber");
|
||||
+ if (el) {
|
||||
+ struct security_descriptor *domain_sd;
|
||||
+ /*
|
||||
+ * msDS-SecondaryKrbTgtNumber allows the creator to
|
||||
+ * become an RODC, this is trusted as an RODC
|
||||
+ * account
|
||||
+ */
|
||||
+ ret = samldb_get_domain_secdesc(ac, &domain_sd);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ ret = acl_check_extended_right(ac, domain_sd,
|
||||
+ user_token,
|
||||
+ GUID_DRS_DS_INSTALL_REPLICA,
|
||||
+ SEC_ADS_CONTROL_ACCESS,
|
||||
+ NULL);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ ldb_asprintf_errstring(ldb_module_get_ctx(ac->module),
|
||||
+ "msDS-SecondaryKrbTgtNumber "
|
||||
+ "(entry %s) cannot be created "
|
||||
+ "or changed without "
|
||||
+ "DS-Install-Replica extended right!",
|
||||
+ ldb_dn_get_linearized(ac->msg->dn));
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ el = ldb_msg_find_element(ac->msg, "msDS-AllowedToDelegateTo");
|
||||
+ if (el) {
|
||||
+ /*
|
||||
+ * msDS-AllowedToDelegateTo is incredibly powerful,
|
||||
+ * given that it allows a server to become ANY USER on
|
||||
+ * the target server only listed by SPN so needs to be
|
||||
+ * protected just as the userAccountControl
|
||||
+ * UF_TRUSTED_FOR_DELEGATION is.
|
||||
+ */
|
||||
+
|
||||
+ bool have_priv = security_token_has_privilege(user_token,
|
||||
+ SEC_PRIV_ENABLE_DELEGATION);
|
||||
+ if (have_priv == false) {
|
||||
+ ldb_asprintf_errstring(ldb_module_get_ctx(ac->module),
|
||||
+ "msDS-AllowedToDelegateTo "
|
||||
+ "(entry %s) cannot be created "
|
||||
+ "or changed without SePrivEnableDelegation!",
|
||||
+ ldb_dn_get_linearized(ac->msg->dn));
|
||||
+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
||||
+ }
|
||||
+ }
|
||||
+ return LDB_SUCCESS;
|
||||
+}
|
||||
/* add */
|
||||
static int samldb_add(struct ldb_module *module, struct ldb_request *req)
|
||||
{
|
||||
@@ -3533,6 +3631,12 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req)
|
||||
return ldb_operr(ldb);
|
||||
}
|
||||
|
||||
+ ret = samldb_check_sensitive_attributes(ac);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ talloc_free(ac);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
el = ldb_msg_find_element(ac->msg, "fSMORoleOwner");
|
||||
if (el != NULL) {
|
||||
ret = samldb_fsmo_role_owner_check(ac);
|
||||
@@ -3740,6 +3844,12 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
|
||||
return ldb_operr(ldb);
|
||||
}
|
||||
|
||||
+ ret = samldb_check_sensitive_attributes(ac);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ talloc_free(ac);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (is_undelete == NULL) {
|
||||
el = ldb_msg_find_element(ac->msg, "primaryGroupID");
|
||||
if (el != NULL) {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,106 @@
|
||||
From 061c125c6129634d220c1074fa8ed5eaa8b0e09c Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Thu, 5 Aug 2021 13:31:29 +0200
|
||||
Subject: [PATCH 262/266] CVE-2021-3738 s4:rpc_server/drsuapi: make use of
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=061c125c6129634d220c1074fa8ed5eaa8b0e09c
|
||||
|
||||
assoc_group aware dcesrv_samdb_connect_as_*() helpers
|
||||
|
||||
This avoids a crash that's triggered by windows clients using
|
||||
DsCrackNames across multiple connections within an association group
|
||||
on the same DsBind context(policy) handle.
|
||||
|
||||
It also improves the auditing for the dcesrv_samdb_connect_as_system() case.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14468
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 55 +++++++------------
|
||||
1 files changed, 19 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
|
||||
index 7e2b6174d2f..239971d7009 100644
|
||||
--- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
|
||||
+++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
|
||||
@@ -73,9 +73,7 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
|
||||
uint32_t supported_extensions;
|
||||
uint32_t req_length;
|
||||
int ret;
|
||||
- struct auth_session_info *auth_info;
|
||||
WERROR werr;
|
||||
- bool connected_as_system = false;
|
||||
|
||||
r->out.bind_info = NULL;
|
||||
ZERO_STRUCTP(r->out.bind_handle);
|
||||
@@ -86,45 +84,30 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
|
||||
/* if this is a DC connecting, give them system level access */
|
||||
werr = drs_security_level_check(dce_call, NULL, SECURITY_DOMAIN_CONTROLLER, NULL);
|
||||
if (W_ERROR_IS_OK(werr)) {
|
||||
- DEBUG(3,(__location__ ": doing DsBind with system_session\n"));
|
||||
- auth_info = system_session(dce_call->conn->dce_ctx->lp_ctx);
|
||||
- connected_as_system = true;
|
||||
+ DBG_NOTICE("doing DsBind with system_session\n");
|
||||
+ b_state->sam_ctx_system = dcesrv_samdb_connect_as_system(b_state, dce_call);
|
||||
+ if (b_state->sam_ctx_system == NULL) {
|
||||
+ return WERR_DS_UNAVAILABLE;
|
||||
+ }
|
||||
+ b_state->sam_ctx = b_state->sam_ctx_system;
|
||||
} else {
|
||||
- auth_info = dcesrv_call_session_info(dce_call);
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * connect to the samdb
|
||||
- */
|
||||
- b_state->sam_ctx = samdb_connect(
|
||||
- b_state,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- auth_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
- if (!b_state->sam_ctx) {
|
||||
- return WERR_FOOBAR;
|
||||
- }
|
||||
+ b_state->sam_ctx = dcesrv_samdb_connect_as_user(b_state, dce_call);
|
||||
+ if (b_state->sam_ctx == NULL) {
|
||||
+ return WERR_DS_UNAVAILABLE;
|
||||
+ }
|
||||
|
||||
- if (connected_as_system) {
|
||||
- b_state->sam_ctx_system = b_state->sam_ctx;
|
||||
- } else {
|
||||
- /* an RODC also needs system samdb access for secret
|
||||
- attribute replication */
|
||||
+ /*
|
||||
+ * an RODC also needs system samdb access for secret
|
||||
+ * attribute replication
|
||||
+ */
|
||||
werr = drs_security_level_check(dce_call, NULL, SECURITY_RO_DOMAIN_CONTROLLER,
|
||||
samdb_domain_sid(b_state->sam_ctx));
|
||||
if (W_ERROR_IS_OK(werr)) {
|
||||
- b_state->sam_ctx_system
|
||||
- = samdb_connect(
|
||||
- b_state,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- system_session(dce_call->conn->dce_ctx->lp_ctx),
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
- if (!b_state->sam_ctx_system) {
|
||||
- return WERR_FOOBAR;
|
||||
+ DBG_NOTICE("doing DsBind as RODC\n");
|
||||
+ b_state->sam_ctx_system =
|
||||
+ dcesrv_samdb_connect_as_system(b_state, dce_call);
|
||||
+ if (b_state->sam_ctx_system == NULL) {
|
||||
+ return WERR_DS_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,94 @@
|
||||
From a3cca16fac5d834f2f29e1daa31ced38938fada9 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Fri, 11 Sep 2020 12:52:40 +0200
|
||||
Subject: [PATCH 013/266] CVE-2020-25717 wb_sids2xids: call
|
||||
wb_parent_idmap_setup_send/recv as the first step
|
||||
|
||||
This isn't really used yet, but it will in the next commits.
|
||||
|
||||
Also idmap_child_handle() will soon assert that
|
||||
wb_parent_idmap_setup_send/recv() was called before it's used.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
(cherry picked from commit d42aaeba6e0820acd17f204ff7ab6d1aede1b303)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/a3cca16fac5d834f2f29e1daa31ced38938fada9
|
||||
---
|
||||
source3/winbindd/wb_sids2xids.c | 34 +++++++++++++++++++++++++++++----
|
||||
1 file changed, 30 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c
|
||||
index b47856520ea..59f6ba5891e 100644
|
||||
--- a/source3/winbindd/wb_sids2xids.c
|
||||
+++ b/source3/winbindd/wb_sids2xids.c
|
||||
@@ -29,6 +29,8 @@
|
||||
struct wb_sids2xids_state {
|
||||
struct tevent_context *ev;
|
||||
|
||||
+ const struct wb_parent_idmap_config *cfg;
|
||||
+
|
||||
struct dom_sid *sids;
|
||||
uint32_t num_sids;
|
||||
|
||||
@@ -58,7 +60,7 @@ struct wb_sids2xids_state {
|
||||
struct wbint_TransIDArray ids;
|
||||
};
|
||||
|
||||
-
|
||||
+static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq);
|
||||
static bool wb_sids2xids_in_cache(struct dom_sid *sid, struct id_map *map);
|
||||
static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq);
|
||||
static void wb_sids2xids_done(struct tevent_req *subreq);
|
||||
@@ -126,15 +128,39 @@ struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx,
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
- subreq = wb_lookupsids_send(state, ev, state->non_cached,
|
||||
- state->num_non_cached);
|
||||
+ subreq = wb_parent_idmap_setup_send(state, state->ev);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
- tevent_req_set_callback(subreq, wb_sids2xids_lookupsids_done, req);
|
||||
+ tevent_req_set_callback(subreq, wb_sids2xids_idmap_setup_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
+static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct tevent_req *req = tevent_req_callback_data(
|
||||
+ subreq, struct tevent_req);
|
||||
+ struct wb_sids2xids_state *state = tevent_req_data(
|
||||
+ req, struct wb_sids2xids_state);
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ status = wb_parent_idmap_setup_recv(subreq, &state->cfg);
|
||||
+ TALLOC_FREE(subreq);
|
||||
+ if (tevent_req_nterror(req, status)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ SMB_ASSERT(state->cfg->num_doms > 0);
|
||||
+
|
||||
+ subreq = wb_lookupsids_send(state,
|
||||
+ state->ev,
|
||||
+ state->non_cached,
|
||||
+ state->num_non_cached);
|
||||
+ if (tevent_req_nomem(subreq, req)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ tevent_req_set_callback(subreq, wb_sids2xids_lookupsids_done, req);
|
||||
+}
|
||||
+
|
||||
static bool wb_sids2xids_in_cache(struct dom_sid *sid, struct id_map *map)
|
||||
{
|
||||
struct unixid id;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,105 @@
|
||||
From 5e63f9c3c5e3d48e1aaf625649cb065c0dfae1df Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Tue, 19 Jan 2021 16:53:55 +0100
|
||||
Subject: [PATCH 004/284] CVE-2020-25718 pyldb: catch potential overflow error
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=5e63f9c3c5e3d48e1aaf625649cb065c0dfae1df
|
||||
|
||||
in py_timestring
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Pair-Programmed-With: Bj枚rn Baumbach <bb@sernet.de>
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Signed-off-by: Bj枚rn Baumbach <bb@sernet.de>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558
|
||||
|
||||
(cherry picked from commit 71e8b24b8a031de26b21539e36a60f459257d2fd)
|
||||
---
|
||||
lib/ldb/common/ldb_msg.c | 1 +
|
||||
lib/ldb/pyldb.c | 7 +++++++
|
||||
lib/ldb/tests/python/api.py | 19 +++++++++++++++++++
|
||||
3 files changed, 27 insertions(+)
|
||||
|
||||
diff --git a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c
|
||||
index 7131f013f71b..57dfc5a04c2b 100644
|
||||
--- a/lib/ldb/common/ldb_msg.c
|
||||
+++ b/lib/ldb/common/ldb_msg.c
|
||||
@@ -1272,6 +1272,7 @@ char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t)
|
||||
|
||||
if (r != 17) {
|
||||
talloc_free(ts);
|
||||
+ errno = EOVERFLOW;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c
|
||||
index d093daedf5c7..257351b2bc45 100644
|
||||
--- a/lib/ldb/pyldb.c
|
||||
+++ b/lib/ldb/pyldb.c
|
||||
@@ -4227,6 +4227,13 @@ static PyObject *py_timestring(PyObject *module, PyObject *args)
|
||||
if (!PyArg_ParseTuple(args, "l", &t_val))
|
||||
return NULL;
|
||||
tresult = ldb_timestring(NULL, (time_t) t_val);
|
||||
+ if (tresult == NULL) {
|
||||
+ /*
|
||||
+ * Most likely EOVERFLOW from gmtime()
|
||||
+ */
|
||||
+ PyErr_SetFromErrno(PyExc_OSError);
|
||||
+ return NULL;
|
||||
+ }
|
||||
ret = PyUnicode_FromString(tresult);
|
||||
talloc_free(tresult);
|
||||
return ret;
|
||||
diff --git a/lib/ldb/tests/python/api.py b/lib/ldb/tests/python/api.py
|
||||
index 675b5859af8f..8d154aac6adf 100755
|
||||
--- a/lib/ldb/tests/python/api.py
|
||||
+++ b/lib/ldb/tests/python/api.py
|
||||
@@ -5,10 +5,12 @@
|
||||
import os
|
||||
from unittest import TestCase
|
||||
import sys
|
||||
+sys.path.insert(0, "bin/python")
|
||||
import gc
|
||||
import time
|
||||
import ldb
|
||||
import shutil
|
||||
+import errno
|
||||
|
||||
PY3 = sys.version_info > (3, 0)
|
||||
|
||||
@@ -42,10 +44,27 @@ class NoContextTests(TestCase):
|
||||
self.assertEqual("19700101000000.0Z", ldb.timestring(0))
|
||||
self.assertEqual("20071119191012.0Z", ldb.timestring(1195499412))
|
||||
|
||||
+ self.assertEqual("00000101000000.0Z", ldb.timestring(-62167219200))
|
||||
+ self.assertEqual("99991231235959.0Z", ldb.timestring(253402300799))
|
||||
+
|
||||
+ # should result with OSError EOVERFLOW from gmtime()
|
||||
+ with self.assertRaises(OSError) as err:
|
||||
+ ldb.timestring(-62167219201)
|
||||
+ self.assertEqual(err.exception.errno, errno.EOVERFLOW)
|
||||
+ with self.assertRaises(OSError) as err:
|
||||
+ ldb.timestring(253402300800)
|
||||
+ self.assertEqual(err.exception.errno, errno.EOVERFLOW)
|
||||
+ with self.assertRaises(OSError) as err:
|
||||
+ ldb.timestring(0x7fffffffffffffff)
|
||||
+ self.assertEqual(err.exception.errno, errno.EOVERFLOW)
|
||||
+
|
||||
def test_string_to_time(self):
|
||||
self.assertEqual(0, ldb.string_to_time("19700101000000.0Z"))
|
||||
self.assertEqual(1195499412, ldb.string_to_time("20071119191012.0Z"))
|
||||
|
||||
+ self.assertEqual(-62167219200, ldb.string_to_time("00000101000000.0Z"))
|
||||
+ self.assertEqual(253402300799, ldb.string_to_time("99991231235959.0Z"))
|
||||
+
|
||||
def test_binary_encode(self):
|
||||
encoded = ldb.binary_encode(b'test\\x')
|
||||
decoded = ldb.binary_decode(encoded)
|
||||
--
|
||||
2.25.1
|
||||
@ -0,0 +1,153 @@
|
||||
From 940ddac4572b3caa419579c3bf60f6af0e019d18 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schneider <asn@samba.org>
|
||||
Date: Mon, 12 Jul 2021 11:20:29 +0200
|
||||
Subject: [PATCH 202/266] CVE-2020-25719 mit-samba: If we use client_princ,
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=940ddac4572b3caa419579c3bf60f6af0e019d18
|
||||
|
||||
always lookup the db entry
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561
|
||||
|
||||
Signed-off-by: Andreas Schneider <asn@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
[abartlet@samba.org backported due to support for MIT KDB < 10
|
||||
in Samba 4.14]
|
||||
---
|
||||
source4/kdc/mit-kdb/kdb_samba_policies.c | 81 ++++++++++++++++++++++--
|
||||
1 file changed, 75 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c
|
||||
index 9197551ed61..dce87c50049 100644
|
||||
--- a/source4/kdc/mit-kdb/kdb_samba_policies.c
|
||||
+++ b/source4/kdc/mit-kdb/kdb_samba_policies.c
|
||||
@@ -323,6 +323,8 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
||||
krb5_authdata **tgt_auth_data,
|
||||
krb5_authdata ***signed_auth_data)
|
||||
{
|
||||
+ krb5_const_principal ks_client_princ = NULL;
|
||||
+ krb5_db_entry *client_entry = NULL;
|
||||
krb5_authdata **authdata = NULL;
|
||||
krb5_boolean is_as_req;
|
||||
krb5_error_code code;
|
||||
@@ -341,8 +343,72 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
||||
|
||||
is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
|
||||
|
||||
+ /*
|
||||
+ * When using s4u2proxy client_princ actually refers to the proxied user
|
||||
+ * while client->princ to the proxy service asking for the TGS on behalf
|
||||
+ * of the proxied user. So always use client_princ in preference.
|
||||
+ *
|
||||
+ * Note that when client principal is not NULL, client entry might be
|
||||
+ * NULL for cross-realm case, so we need to make sure to not
|
||||
+ * dereference NULL pointer here.
|
||||
+ */
|
||||
+ if (client_princ != NULL) {
|
||||
+ ks_client_princ = client_princ;
|
||||
+ if (!is_as_req) {
|
||||
+ krb5_boolean is_equal = false;
|
||||
+
|
||||
+ if (client != NULL && client->princ != NULL) {
|
||||
+ is_equal =
|
||||
+ krb5_principal_compare(context,
|
||||
+ client_princ,
|
||||
+ client->princ);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * When client principal is the same as supplied client
|
||||
+ * entry, don't fetch it.
|
||||
+ */
|
||||
+ if (!is_equal) {
|
||||
+ code = ks_get_principal(context,
|
||||
+ ks_client_princ,
|
||||
+ 0,
|
||||
+ &client_entry);
|
||||
+ if (code != 0) {
|
||||
+ char *client_name = NULL;
|
||||
+
|
||||
+ (void)krb5_unparse_name(context,
|
||||
+ ks_client_princ,
|
||||
+ &client_name);
|
||||
+
|
||||
+ DBG_DEBUG("We didn't find the client "
|
||||
+ "principal [%s] in our "
|
||||
+ "database.\n",
|
||||
+ client_name);
|
||||
+ SAFE_FREE(client_name);
|
||||
+
|
||||
+ /*
|
||||
+ * If we didn't find client_princ in our
|
||||
+ * database it might be from another
|
||||
+ * realm.
|
||||
+ */
|
||||
+ client_entry = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (client == NULL) {
|
||||
+ *signed_auth_data = NULL;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ ks_client_princ = client->princ;
|
||||
+ }
|
||||
+
|
||||
+ if (client_entry == NULL) {
|
||||
+ client_entry = client;
|
||||
+ }
|
||||
+
|
||||
if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) {
|
||||
- code = ks_get_pac(context, client, client_key, &pac);
|
||||
+ code = ks_get_pac(context, client_entry, client_key, &pac);
|
||||
if (code != 0) {
|
||||
goto done;
|
||||
}
|
||||
@@ -351,8 +417,8 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
||||
if (!is_as_req) {
|
||||
code = ks_verify_pac(context,
|
||||
flags,
|
||||
- client_princ,
|
||||
- client,
|
||||
+ ks_client_princ,
|
||||
+ client_entry,
|
||||
server,
|
||||
krbtgt,
|
||||
server_key,
|
||||
@@ -365,9 +431,9 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
||||
}
|
||||
}
|
||||
|
||||
- if (pac == NULL && client != NULL) {
|
||||
+ if (pac == NULL) {
|
||||
|
||||
- code = ks_get_pac(context, client, client_key, &pac);
|
||||
+ code = ks_get_pac(context, client_entry, client_key, &pac);
|
||||
if (code != 0) {
|
||||
goto done;
|
||||
}
|
||||
@@ -378,7 +444,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- code = krb5_pac_sign(context, pac, authtime, client_princ,
|
||||
+ code = krb5_pac_sign(context, pac, authtime, ks_client_princ,
|
||||
server_key, krbtgt_key, &pac_data);
|
||||
if (code != 0) {
|
||||
DBG_ERR("krb5_pac_sign failed: %d\n", code);
|
||||
@@ -412,6 +478,9 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
||||
code = 0;
|
||||
|
||||
done:
|
||||
+ if (client_entry != NULL && client_entry != client) {
|
||||
+ ks_free_principal(context, client_entry);
|
||||
+ }
|
||||
krb5_pac_free(context, pac);
|
||||
krb5_free_authdata(context, authdata);
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,137 @@
|
||||
From e3021debe82e6a35f128eb600bc11df40c441a98 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Thu, 16 Sep 2021 08:46:42 +1200
|
||||
Subject: [PATCH 063/266] CVE-2020-25722 dsdb: objectclass computer becomes
|
||||
UF_WORKSTATION_TRUST by default
|
||||
|
||||
There are a lot of knownfail entries added with this commit. These
|
||||
all need to be addressed and removed in subsequent commits which
|
||||
will restructure the tests to pass within this new reality.
|
||||
|
||||
This default applies even to users with administrator rights,
|
||||
as changing the default based on permissions would break
|
||||
to many assumptions.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/e3021debe82e6a35f128eb600bc11df40c441a98
|
||||
|
||||
---
|
||||
selftest/knownfail.d/uac_objectclass_restrict | 42 +++++++++++++++++++
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 27 +++++++++---
|
||||
2 files changed, 64 insertions(+), 5 deletions(-)
|
||||
create mode 100644 selftest/knownfail.d/uac_objectclass_restrict
|
||||
|
||||
diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict
|
||||
new file mode 100644
|
||||
index 00000000000..a076f9cfedb
|
||||
--- /dev/null
|
||||
+++ b/selftest/knownfail.d/uac_objectclass_restrict
|
||||
@@ -0,0 +1,42 @@
|
||||
+# Knownfail entries due to restricting the creation of computer/user
|
||||
+# accounts (in terms of userAccountControl) that do not match the objectclass
|
||||
+#
|
||||
+# All these tests need to be fixed and the entries here removed
|
||||
+
|
||||
+^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_isCriticalSystemObject\(fl2008r2dc\)
|
||||
+^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_userAccountControl\(fl2008r2dc\)
|
||||
+^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_users_groups\(fl2008r2dc\)
|
||||
+^samba4.ldap.python\(ad_dc_default\).__main__.BasicTests.test_all\(ad_dc_default\)
|
||||
+^samba4.sam.python\(ad_dc_default\).__main__.SamTests.test_isCriticalSystemObject\(ad_dc_default\)
|
||||
+^samba4.sam.python\(ad_dc_default\).__main__.SamTests.test_userAccountControl\(ad_dc_default\)
|
||||
+^samba4.sam.python\(ad_dc_default\).__main__.SamTests.test_users_groups\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_add_computer_sd_cc\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_admin_mod_uac\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_computer_cc\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_0x10000000\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_0x20000000\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_0x40000000\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_0x80000000\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00000004\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00000400\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00004000\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00008000\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_ACCOUNTDISABLE\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_DONT_EXPIRE_PASSWD\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_DONT_REQUIRE_PREAUTH\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_HOMEDIR_REQUIRED\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_LOCKOUT\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_MNS_LOGON_ACCOUNT\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_NORMAL_ACCOUNT\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_NOT_DELEGATED\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_NO_AUTH_DATA_REQUIRED\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_PASSWD_CANT_CHANGE\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_PASSWD_NOTREQD\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_PASSWORD_EXPIRED\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_SCRIPT\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_SMARTCARD_REQUIRED\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_USE_AES_KEYS\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_USE_DES_KEY_ONLY\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_default\)
|
||||
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_NORMAL_ACCOUNT\(ad_dc_default\)
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index cb5fda324a4..8df86f29883 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -1413,19 +1413,33 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac)
|
||||
|
||||
switch(ac->type) {
|
||||
case SAMLDB_TYPE_USER: {
|
||||
+ bool is_computer_objectclass;
|
||||
bool uac_generated = false, uac_add_flags = false;
|
||||
-
|
||||
+ uint32_t default_user_account_control = UF_NORMAL_ACCOUNT;
|
||||
/* Step 1.2: Default values */
|
||||
ret = dsdb_user_obj_set_defaults(ldb, ac->msg, ac->req);
|
||||
if (ret != LDB_SUCCESS) return ret;
|
||||
|
||||
+ is_computer_objectclass
|
||||
+ = (samdb_find_attribute(ldb,
|
||||
+ ac->msg,
|
||||
+ "objectclass",
|
||||
+ "computer")
|
||||
+ != NULL);
|
||||
+
|
||||
+ if (is_computer_objectclass) {
|
||||
+ default_user_account_control
|
||||
+ = UF_WORKSTATION_TRUST_ACCOUNT;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
/* On add operations we might need to generate a
|
||||
* "userAccountControl" (if it isn't specified). */
|
||||
el = ldb_msg_find_element(ac->msg, "userAccountControl");
|
||||
if ((el == NULL) && (ac->req->operation == LDB_ADD)) {
|
||||
ret = samdb_msg_set_uint(ldb, ac->msg, ac->msg,
|
||||
"userAccountControl",
|
||||
- UF_NORMAL_ACCOUNT);
|
||||
+ default_user_account_control);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
@@ -1444,11 +1458,14 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac)
|
||||
raw_uac = user_account_control;
|
||||
/*
|
||||
* "userAccountControl" = 0 or missing one of
|
||||
- * the types means "UF_NORMAL_ACCOUNT". See
|
||||
- * MS-SAMR 3.1.1.8.10 point 8
|
||||
+ * the types means "UF_NORMAL_ACCOUNT"
|
||||
+ * or "UF_WORKSTATION_TRUST_ACCOUNT" (if a computer).
|
||||
+ * See MS-SAMR 3.1.1.8.10 point 8
|
||||
*/
|
||||
if ((user_account_control & UF_ACCOUNT_TYPE_MASK) == 0) {
|
||||
- user_account_control = UF_NORMAL_ACCOUNT | user_account_control;
|
||||
+ user_account_control
|
||||
+ = default_user_account_control
|
||||
+ | user_account_control;
|
||||
uac_generated = true;
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
From caf3d32f68f91ea83c7f601577dd1f7c98f030e5 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Thu, 5 Aug 2021 14:22:47 +0200
|
||||
Subject: [PATCH 263/266] CVE-2021-3738 s4:rpc_server/dnsserver: make use of
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=caf3d32f68f91ea83c7f601577dd1f7c98f030e5
|
||||
|
||||
dcesrv_samdb_connect_as_user() helper
|
||||
|
||||
This is not strictly required, but it makes it easier to audit that
|
||||
source4/rpc_server no longer calls samdb_connect() directly.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14468
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source4/rpc_server/dnsserver/dcerpc_dnsserver.c | 11 ++---------
|
||||
1 file changed, 2 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
|
||||
index 88efc01f154..b84b737d0b8 100644
|
||||
--- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
|
||||
+++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "includes.h"
|
||||
#include "talloc.h"
|
||||
#include "rpc_server/dcerpc_server.h"
|
||||
+#include "rpc_server/common/common.h"
|
||||
#include "dsdb/samdb/samdb.h"
|
||||
#include "lib/util/dlinklist.h"
|
||||
#include "librpc/gen_ndr/ndr_dnsserver.h"
|
||||
@@ -104,8 +105,6 @@ static void dnsserver_reload_zones(struct dnsserver_state *dsstate)
|
||||
|
||||
static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_call)
|
||||
{
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
struct dnsserver_state *dsstate;
|
||||
struct dnsserver_zone *zones, *z, *znext;
|
||||
struct dnsserver_partition *partitions, *p;
|
||||
@@ -125,13 +124,7 @@ static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_c
|
||||
|
||||
dsstate->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
|
||||
|
||||
- /* FIXME: create correct auth_session_info for connecting user */
|
||||
- dsstate->samdb = samdb_connect(dsstate,
|
||||
- dce_call->event_ctx,
|
||||
- dsstate->lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ dsstate->samdb = dcesrv_samdb_connect_as_user(dsstate, dce_call);
|
||||
if (dsstate->samdb == NULL) {
|
||||
DEBUG(0,("dnsserver: Failed to open samdb"));
|
||||
goto failed;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,96 @@
|
||||
From 3812930e641d10d1ead10b52ddc7240dd585d0f6 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Fri, 11 Sep 2020 15:42:42 +0200
|
||||
Subject: [PATCH 016/266] CVE-2020-25717 winbindd: defer the setup_child() from
|
||||
init_idmap_child()
|
||||
|
||||
At startup we trigger a wb_parent_idmap_setup_send() and make
|
||||
sure setup_child() is called just before wb_parent_idmap_setup_recv()
|
||||
finished.
|
||||
|
||||
This makes sure our view of the idmap config in the parent matches
|
||||
what we have in the child.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
(cherry picked from commit 28e020c0a863411cfa95e3b1ed943d922b8635bd)
|
||||
---
|
||||
source3/winbindd/winbindd_idmap.c | 45 ++++++++++++++++++++++++++++---
|
||||
1 file changed, 42 insertions(+), 3 deletions(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=3812930e641d10d1ead10b52ddc7240dd585d0f6
|
||||
|
||||
diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c
|
||||
index 14836e3b8a0..3e2461478a9 100644
|
||||
--- a/source3/winbindd/winbindd_idmap.c
|
||||
+++ b/source3/winbindd/winbindd_idmap.c
|
||||
@@ -81,11 +81,44 @@ static const struct winbindd_child_dispatch_table idmap_dispatch_table[] = {
|
||||
}
|
||||
};
|
||||
|
||||
+static void init_idmap_child_done(struct tevent_req *subreq);
|
||||
+
|
||||
void init_idmap_child(void)
|
||||
{
|
||||
- setup_child(NULL, &static_idmap_child,
|
||||
- idmap_dispatch_table,
|
||||
- "log.winbindd", "idmap");
|
||||
+ struct tevent_req *subreq = NULL;
|
||||
+
|
||||
+ subreq = wb_parent_idmap_setup_send(global_event_context(),
|
||||
+ global_event_context());
|
||||
+ if (subreq == NULL) {
|
||||
+ /*
|
||||
+ * This is only an optimization, so we're free to
|
||||
+ * to ignore errors
|
||||
+ */
|
||||
+ DBG_ERR("wb_parent_idmap_setup_send() failed\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ tevent_req_set_callback(subreq, init_idmap_child_done, NULL);
|
||||
+ DBG_DEBUG("wb_parent_idmap_setup_send() started\n");
|
||||
+}
|
||||
+
|
||||
+static void init_idmap_child_done(struct tevent_req *subreq)
|
||||
+{
|
||||
+ const struct wb_parent_idmap_config *cfg = NULL;
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ status = wb_parent_idmap_setup_recv(subreq, &cfg);
|
||||
+ TALLOC_FREE(subreq);
|
||||
+ if (!NT_STATUS_IS_OK(status)) {
|
||||
+ /*
|
||||
+ * This is only an optimization, so we're free to
|
||||
+ * to ignore errors
|
||||
+ */
|
||||
+ DBG_ERR("wb_parent_idmap_setup_recv() failed %s\n",
|
||||
+ nt_errstr(status));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ DBG_DEBUG("wb_parent_idmap_setup_recv() finished\n");
|
||||
}
|
||||
|
||||
struct wb_parent_idmap_setup_state {
|
||||
@@ -306,6 +339,12 @@ static void wb_parent_idmap_setup_lookupname_next(struct tevent_req *req)
|
||||
|
||||
next_domain:
|
||||
if (state->dom_idx == state->cfg->num_doms) {
|
||||
+ /*
|
||||
+ * We're done, so start the idmap child
|
||||
+ */
|
||||
+ setup_child(NULL, &static_idmap_child,
|
||||
+ idmap_dispatch_table,
|
||||
+ "log.winbindd", "idmap");
|
||||
tevent_req_done(req);
|
||||
return;
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
From 0e09aaa3e6410ba6963099a3504c70603180a66d Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schneider <asn@samba.org>
|
||||
Date: Mon, 12 Jul 2021 13:12:00 +0200
|
||||
Subject: [PATCH 203/266] CVE-2020-25719 mit-samba: Add
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=0e09aaa3e6410ba6963099a3504c70603180a66d
|
||||
|
||||
mit_samba_princ_needs_pac()
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561
|
||||
|
||||
Signed-off-by: Andreas Schneider <asn@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source4/kdc/mit_samba.c | 8 ++++++++
|
||||
source4/kdc/mit_samba.h | 2 ++
|
||||
2 files changed, 10 insertions(+)
|
||||
|
||||
diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
|
||||
index 689e14e1c38..6aed3134544 100644
|
||||
--- a/source4/kdc/mit_samba.c
|
||||
+++ b/source4/kdc/mit_samba.c
|
||||
@@ -1153,3 +1153,11 @@ void mit_samba_update_bad_password_count(krb5_db_entry *db_entry)
|
||||
p->msg,
|
||||
ldb_get_default_basedn(p->kdc_db_ctx->samdb));
|
||||
}
|
||||
+
|
||||
+bool mit_samba_princ_needs_pac(krb5_db_entry *db_entry)
|
||||
+{
|
||||
+ struct samba_kdc_entry *skdc_entry =
|
||||
+ talloc_get_type_abort(db_entry->e_data, struct samba_kdc_entry);
|
||||
+
|
||||
+ return samba_princ_needs_pac(skdc_entry);
|
||||
+}
|
||||
diff --git a/source4/kdc/mit_samba.h b/source4/kdc/mit_samba.h
|
||||
index ba824557bd5..636c77ec97c 100644
|
||||
--- a/source4/kdc/mit_samba.h
|
||||
+++ b/source4/kdc/mit_samba.h
|
||||
@@ -85,4 +85,6 @@ void mit_samba_zero_bad_password_count(krb5_db_entry *db_entry);
|
||||
|
||||
void mit_samba_update_bad_password_count(krb5_db_entry *db_entry);
|
||||
|
||||
+bool mit_samba_princ_needs_pac(krb5_db_entry *db_entry);
|
||||
+
|
||||
#endif /* _MIT_SAMBA_H */
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,264 @@
|
||||
From f77231f1ae963599b834dde167a8854da08ca6d7 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Fri, 22 Oct 2021 16:07:46 +1300
|
||||
Subject: [PATCH 066/266] CVE-2020-25722 dsdb: Prohibit mismatch between UF_
|
||||
account types and objectclass.
|
||||
|
||||
There are a lot of knownfail entries added with this commit. These
|
||||
all need to be addressed and removed in subsequent commits which
|
||||
will restructure the tests to pass within this new reality.
|
||||
|
||||
The restriction is not applied to users with administrator rights,
|
||||
as this breaks a lot of tests and provides no security benefit.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/f77231f1ae963599b834dde167a8854da08ca6d7
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 153 ++++++++++++++----
|
||||
1 files changed, 122 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 8df86f29883..15459abcbca 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -1365,7 +1365,8 @@ static int samldb_check_user_account_control_rules(struct samldb_ctx *ac,
|
||||
struct dom_sid *sid,
|
||||
uint32_t req_uac,
|
||||
uint32_t user_account_control,
|
||||
- uint32_t user_account_control_old);
|
||||
+ uint32_t user_account_control_old,
|
||||
+ bool is_computer_objectclass);
|
||||
|
||||
/*
|
||||
* "Objectclass" trigger (MS-SAMR 3.1.1.8.1)
|
||||
@@ -1484,21 +1485,12 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac)
|
||||
ret = samldb_check_user_account_control_rules(ac, NULL,
|
||||
raw_uac,
|
||||
user_account_control,
|
||||
- 0);
|
||||
+ 0,
|
||||
+ is_computer_objectclass);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
- /* Workstation and (read-only) DC objects do need objectclass "computer" */
|
||||
- if ((samdb_find_attribute(ldb, ac->msg,
|
||||
- "objectclass", "computer") == NULL) &&
|
||||
- (user_account_control &
|
||||
- (UF_SERVER_TRUST_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT))) {
|
||||
- ldb_set_errstring(ldb,
|
||||
- "samldb: Requested account type does need objectclass 'computer'!");
|
||||
- return LDB_ERR_OBJECT_CLASS_VIOLATION;
|
||||
- }
|
||||
-
|
||||
/* add "sAMAccountType" attribute */
|
||||
ret = dsdb_user_obj_set_account_type(ldb, ac->msg, user_account_control, NULL);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
@@ -1993,6 +1985,106 @@ static int samldb_check_user_account_control_invariants(struct samldb_ctx *ac,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * It would be best if these rules apply, always, but for now they
|
||||
+ * apply only to non-admins
|
||||
+ */
|
||||
+static int samldb_check_user_account_control_objectclass_invariants(
|
||||
+ struct samldb_ctx *ac,
|
||||
+ uint32_t user_account_control,
|
||||
+ uint32_t user_account_control_old,
|
||||
+ bool is_computer_objectclass)
|
||||
+{
|
||||
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
+
|
||||
+ uint32_t old_ufa = user_account_control_old & UF_ACCOUNT_TYPE_MASK;
|
||||
+ uint32_t new_ufa = user_account_control & UF_ACCOUNT_TYPE_MASK;
|
||||
+
|
||||
+ uint32_t old_rodc = user_account_control_old & UF_PARTIAL_SECRETS_ACCOUNT;
|
||||
+ uint32_t new_rodc = user_account_control & UF_PARTIAL_SECRETS_ACCOUNT;
|
||||
+
|
||||
+ bool is_admin;
|
||||
+ struct security_token *user_token
|
||||
+ = acl_user_token(ac->module);
|
||||
+ if (user_token == NULL) {
|
||||
+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
||||
+ }
|
||||
+
|
||||
+ is_admin
|
||||
+ = security_token_has_builtin_administrators(user_token);
|
||||
+
|
||||
+
|
||||
+ /*
|
||||
+ * We want to allow changes to (eg) disable an account
|
||||
+ * that was created wrong, only checking the
|
||||
+ * objectclass if the account type changes.
|
||||
+ */
|
||||
+ if (old_ufa == new_ufa && old_rodc == new_rodc) {
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ switch (new_ufa) {
|
||||
+ case UF_NORMAL_ACCOUNT:
|
||||
+ if (is_computer_objectclass && !is_admin) {
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "%08X: samldb: UF_NORMAL_ACCOUNT "
|
||||
+ "requires objectclass 'user' not 'computer'!",
|
||||
+ W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4));
|
||||
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case UF_INTERDOMAIN_TRUST_ACCOUNT:
|
||||
+ if (is_computer_objectclass) {
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "%08X: samldb: UF_INTERDOMAIN_TRUST_ACCOUNT "
|
||||
+ "requires objectclass 'user' not 'computer'!",
|
||||
+ W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4));
|
||||
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case UF_WORKSTATION_TRUST_ACCOUNT:
|
||||
+ if (!is_computer_objectclass) {
|
||||
+ /*
|
||||
+ * Modify of a user account account into a
|
||||
+ * workstation without objectclass computer
|
||||
+ * as an admin is still permitted, but not
|
||||
+ * to make an RODC
|
||||
+ */
|
||||
+ if (is_admin
|
||||
+ && ac->req->operation == LDB_MODIFY
|
||||
+ && new_rodc == 0) {
|
||||
+ break;
|
||||
+ }
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "%08X: samldb: UF_WORKSTATION_TRUST_ACCOUNT "
|
||||
+ "requires objectclass 'computer'!",
|
||||
+ W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4));
|
||||
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case UF_SERVER_TRUST_ACCOUNT:
|
||||
+ if (!is_computer_objectclass) {
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "%08X: samldb: UF_SERVER_TRUST_ACCOUNT "
|
||||
+ "requires objectclass 'computer'!",
|
||||
+ W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4));
|
||||
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "%08X: samldb: invalid userAccountControl[0x%08X]",
|
||||
+ W_ERROR_V(WERR_INVALID_PARAMETER),
|
||||
+ user_account_control);
|
||||
+ return LDB_ERR_OTHER;
|
||||
+ }
|
||||
+ return LDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
static int samldb_get_domain_secdesc(struct samldb_ctx *ac,
|
||||
struct security_descriptor **domain_sd)
|
||||
{
|
||||
@@ -2191,7 +2283,8 @@ static int samldb_check_user_account_control_rules(struct samldb_ctx *ac,
|
||||
struct dom_sid *sid,
|
||||
uint32_t req_uac,
|
||||
uint32_t user_account_control,
|
||||
- uint32_t user_account_control_old)
|
||||
+ uint32_t user_account_control_old,
|
||||
+ bool is_computer_objectclass)
|
||||
{
|
||||
int ret;
|
||||
struct dsdb_control_password_user_account_control *uac = NULL;
|
||||
@@ -2200,6 +2293,14 @@ static int samldb_check_user_account_control_rules(struct samldb_ctx *ac,
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
+ ret = samldb_check_user_account_control_objectclass_invariants(ac,
|
||||
+ user_account_control,
|
||||
+ user_account_control_old,
|
||||
+ is_computer_objectclass);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
ret = samldb_check_user_account_control_acl(ac, sid, user_account_control, user_account_control_old);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
@@ -2261,7 +2362,7 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
|
||||
"objectSid",
|
||||
NULL
|
||||
};
|
||||
- bool is_computer = false;
|
||||
+ bool is_computer_objectclass = false;
|
||||
bool old_is_critical = false;
|
||||
bool new_is_critical = false;
|
||||
|
||||
@@ -2316,7 +2417,10 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
|
||||
"lockoutTime", 0);
|
||||
old_is_critical = ldb_msg_find_attr_as_bool(res->msgs[0],
|
||||
"isCriticalSystemObject", 0);
|
||||
- /* When we do not have objectclass "computer" we cannot switch to a (read-only) DC */
|
||||
+ /*
|
||||
+ * When we do not have objectclass "computer" we cannot
|
||||
+ * switch to a workstation or (RO)DC
|
||||
+ */
|
||||
el = ldb_msg_find_element(res->msgs[0], "objectClass");
|
||||
if (el == NULL) {
|
||||
return ldb_operr(ldb);
|
||||
@@ -2324,7 +2428,7 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
|
||||
computer_val = data_blob_string_const("computer");
|
||||
val = ldb_msg_find_val(el, &computer_val);
|
||||
if (val != NULL) {
|
||||
- is_computer = true;
|
||||
+ is_computer_objectclass = true;
|
||||
}
|
||||
|
||||
old_ufa = old_uac & UF_ACCOUNT_TYPE_MASK;
|
||||
@@ -2349,7 +2453,8 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
|
||||
ret = samldb_check_user_account_control_rules(ac, sid,
|
||||
raw_uac,
|
||||
new_uac,
|
||||
- old_uac);
|
||||
+ old_uac,
|
||||
+ is_computer_objectclass);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
@@ -2371,25 +2476,11 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
|
||||
case UF_WORKSTATION_TRUST_ACCOUNT:
|
||||
new_is_critical = false;
|
||||
if (new_uac & UF_PARTIAL_SECRETS_ACCOUNT) {
|
||||
- if (!is_computer) {
|
||||
- ldb_asprintf_errstring(ldb,
|
||||
- "%08X: samldb: UF_PARTIAL_SECRETS_ACCOUNT "
|
||||
- "requires objectclass 'computer'!",
|
||||
- W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4));
|
||||
- return LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
- }
|
||||
new_is_critical = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case UF_SERVER_TRUST_ACCOUNT:
|
||||
- if (!is_computer) {
|
||||
- ldb_asprintf_errstring(ldb,
|
||||
- "%08X: samldb: UF_SERVER_TRUST_ACCOUNT "
|
||||
- "requires objectclass 'computer'!",
|
||||
- W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4));
|
||||
- return LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
- }
|
||||
new_is_critical = true;
|
||||
break;
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From 79d62d83e23fe5969cb432262ab9addad59a3b8d Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Thu, 5 Aug 2021 14:24:25 +0200
|
||||
Subject: [PATCH 264/266] CVE-2021-3738 s4:rpc_server/lsa: make use of
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=79d62d83e23fe5969cb432262ab9addad59a3b8d
|
||||
|
||||
dcesrv_samdb_connect_as_user() helper
|
||||
|
||||
This avoids a crash that's triggered by windows clients using
|
||||
handles from OpenPolicy[2]() on across multiple connections within
|
||||
an association group.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14468
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source4/rpc_server/lsa/lsa_init.c | 7 +------
|
||||
1 file changed, 1 insertion(+), 6 deletions(-)
|
||||
|
||||
diff --git a/source4/rpc_server/lsa/lsa_init.c b/source4/rpc_server/lsa/lsa_init.c
|
||||
index f33b61c4035..400c5093079 100644
|
||||
--- a/source4/rpc_server/lsa/lsa_init.c
|
||||
+++ b/source4/rpc_server/lsa/lsa_init.c
|
||||
@@ -71,12 +71,7 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call,
|
||||
}
|
||||
|
||||
/* make sure the sam database is accessible */
|
||||
- state->sam_ldb = samdb_connect(state,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ state->sam_ldb = dcesrv_samdb_connect_as_user(state, dce_call);
|
||||
if (state->sam_ldb == NULL) {
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,169 @@
|
||||
From ed1542b9f37734bc77906c4ba49ea6ea3be09af8 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Thu, 10 Sep 2020 17:13:14 +0200
|
||||
Subject: [PATCH 026/266] CVE-2020-25717 wb_sids2xids: build state->idmap_doms
|
||||
based on wb_parent_idmap_config
|
||||
|
||||
In future we'll try to avoid wb_lookupsids_send() and only call
|
||||
it if needed.
|
||||
|
||||
The domain name passed should be only relevant to find the correct
|
||||
idmap backend, and these should all be available in
|
||||
wb_parent_idmap_config as it was created before the idmap child was forked.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
(cherry picked from commit c55f4f37589130a0d8952489da175bbcf53f6748)
|
||||
---
|
||||
source3/winbindd/wb_sids2xids.c | 101 +++++++++++++++++++-------------
|
||||
1 file changed, 61 insertions(+), 40 deletions(-)
|
||||
|
||||
Conflict:lookup_sids --> non_cached
|
||||
lookup_count --> num_non_cached
|
||||
li --> i
|
||||
delete 'uint32_t ai = state->tmp_idx[i]'
|
||||
state->all_ids.ids[i] --> &state->ids.ids[i]
|
||||
add 't->xid.id = UINT32_MAX;
|
||||
t->xid.type = t->type;'
|
||||
type_hint --> type
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=ed1542b9f37734bc77906c4ba49ea6ea3be09af8
|
||||
|
||||
diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c
|
||||
index 21bf5f901f3..3a3d47abbe5 100644
|
||||
--- a/source3/winbindd/wb_sids2xids.c
|
||||
+++ b/source3/winbindd/wb_sids2xids.c
|
||||
@@ -193,6 +193,7 @@ static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq)
|
||||
struct wb_sids2xids_state *state = tevent_req_data(
|
||||
req, struct wb_sids2xids_state);
|
||||
NTSTATUS status;
|
||||
+ uint32_t i;
|
||||
|
||||
status = wb_parent_idmap_setup_recv(subreq, &state->cfg);
|
||||
TALLOC_FREE(subreq);
|
||||
@@ -201,6 +202,66 @@ static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq)
|
||||
}
|
||||
SMB_ASSERT(state->cfg->num_doms > 0);
|
||||
|
||||
+ /*
|
||||
+ * Now we build a list with all domain
|
||||
+ * with non cached entries
|
||||
+ */
|
||||
+ for (i=0; i<state->num_sids; i++) {
|
||||
+ struct wbint_TransID *t = &state->ids.ids[i];
|
||||
+ struct dom_sid domain_sid;
|
||||
+ const char *domain_name = NULL;
|
||||
+ int domain_index;
|
||||
+ uint32_t rid = 0;
|
||||
+ uint32_t di;
|
||||
+
|
||||
+ if (t->domain_index == UINT32_MAX) {
|
||||
+ /* ignore already filled entries */
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ sid_copy(&domain_sid, &state->sids[i]);
|
||||
+ sid_split_rid(&domain_sid, &rid);
|
||||
+
|
||||
+ for (di = 0; di < state->cfg->num_doms; di++) {
|
||||
+ struct wb_parent_idmap_config_dom *dom =
|
||||
+ &state->cfg->doms[di];
|
||||
+ bool match;
|
||||
+
|
||||
+ match = dom_sid_equal(&domain_sid,
|
||||
+ &dom->sid);
|
||||
+ if (!match) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ domain_name = dom->name;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (domain_name == NULL) {
|
||||
+ struct winbindd_domain *wb_domain = NULL;
|
||||
+
|
||||
+ /*
|
||||
+ * Try to fill the name if we already know it
|
||||
+ */
|
||||
+ wb_domain = find_domain_from_sid_noinit(&state->sids[i]);
|
||||
+ if (wb_domain != NULL) {
|
||||
+ domain_name = wb_domain->name;
|
||||
+ }
|
||||
+ }
|
||||
+ if (domain_name == NULL) {
|
||||
+ domain_name = "";
|
||||
+ }
|
||||
+
|
||||
+ domain_index = init_lsa_ref_domain_list(state,
|
||||
+ &state->idmap_doms,
|
||||
+ domain_name,
|
||||
+ &domain_sid);
|
||||
+ if (domain_index == -1) {
|
||||
+ tevent_req_oom(req);
|
||||
+ return;
|
||||
+ }
|
||||
+ t->domain_index = domain_index;
|
||||
+ }
|
||||
+
|
||||
subreq = wb_lookupsids_send(state,
|
||||
state->ev,
|
||||
state->non_cached,
|
||||
@@ -251,51 +312,11 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq)
|
||||
}
|
||||
|
||||
for (i=0; i<state->num_non_cached; i++) {
|
||||
- const struct dom_sid *sid = &state->non_cached[i];
|
||||
- struct dom_sid dom_sid;
|
||||
struct lsa_TranslatedName *n = &names->names[i];
|
||||
struct wbint_TransID *t = &state->ids.ids[i];
|
||||
- int domain_index;
|
||||
- const char *domain_name = NULL;
|
||||
-
|
||||
- if (n->sid_index != UINT32_MAX) {
|
||||
- const struct lsa_DomainInfo *info;
|
||||
- bool match;
|
||||
-
|
||||
- info = &domains->domains[n->sid_index];
|
||||
- match = dom_sid_in_domain(info->sid, sid);
|
||||
- if (match) {
|
||||
- domain_name = info->name.string;
|
||||
- }
|
||||
- }
|
||||
- if (domain_name == NULL) {
|
||||
- struct winbindd_domain *wb_domain = NULL;
|
||||
-
|
||||
- /*
|
||||
- * This is needed to handle Samba DCs
|
||||
- * which always return sid_index == UINT32_MAX for
|
||||
- * unknown sids.
|
||||
- */
|
||||
- wb_domain = find_domain_from_sid_noinit(sid);
|
||||
- if (wb_domain != NULL) {
|
||||
- domain_name = wb_domain->name;
|
||||
- }
|
||||
- }
|
||||
- if (domain_name == NULL) {
|
||||
- domain_name = "";
|
||||
- }
|
||||
|
||||
- sid_copy(&dom_sid, sid);
|
||||
- sid_split_rid(&dom_sid, &t->rid);
|
||||
t->type = lsa_SidType_to_id_type(n->sid_type);
|
||||
- domain_index = init_lsa_ref_domain_list(
|
||||
- state, &state->idmap_doms, domain_name, &dom_sid);
|
||||
- if (domain_index == -1) {
|
||||
- tevent_req_oom(req);
|
||||
- return;
|
||||
- }
|
||||
- t->domain_index = domain_index;
|
||||
|
||||
t->xid.id = UINT32_MAX;
|
||||
t->xid.type = t->type;
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
47
backport-0005-CVE-2020-25718-Fix-Message-items-for-a.patch
Normal file
47
backport-0005-CVE-2020-25718-Fix-Message-items-for-a.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From 0af7600146dda42beb4c06a197f76ae51156cd21 Mon Sep 17 00:00:00 2001
|
||||
From: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
Date: Fri, 28 May 2021 14:15:43 +1200
|
||||
Subject: [PATCH 006/284] CVE-2020-25718 pyldb: Fix Message.items() for a
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=0af7600146dda42beb4c06a197f76ae51156cd21
|
||||
|
||||
message containing elements
|
||||
|
||||
Previously, message elements were being freed before the call to
|
||||
Py_BuildValue(), resulting in an exception being raised. Additionally,
|
||||
only the first element of the returned list was ever assigned to.
|
||||
|
||||
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558
|
||||
|
||||
(cherry picked from commit 3e4ec0a90a222c1cff4a91912afc703ca4cbbb0e)
|
||||
---
|
||||
lib/ldb/pyldb.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c
|
||||
index 257351b2bc45..df7c5c54eaaa 100644
|
||||
--- a/lib/ldb/pyldb.c
|
||||
+++ b/lib/ldb/pyldb.c
|
||||
@@ -3535,13 +3535,13 @@ static PyObject *py_ldb_msg_items(PyLdbMessageObject *self,
|
||||
PyObject *value = NULL;
|
||||
PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
|
||||
int res = 0;
|
||||
- Py_CLEAR(py_el);
|
||||
value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
|
||||
+ Py_CLEAR(py_el);
|
||||
if (value == NULL ) {
|
||||
Py_CLEAR(l);
|
||||
return NULL;
|
||||
}
|
||||
- res = PyList_SetItem(l, 0, value);
|
||||
+ res = PyList_SetItem(l, j, value);
|
||||
if (res == -1) {
|
||||
Py_CLEAR(l);
|
||||
return NULL;
|
||||
--
|
||||
2.25.1
|
||||
@ -0,0 +1,199 @@
|
||||
From f99cff8c0515d5f29aba9d605415744b1d1c3b08 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schneider <asn@samba.org>
|
||||
Date: Mon, 12 Jul 2021 14:00:19 +0200
|
||||
Subject: [PATCH 205/266] CVE-2020-25719 mit-samba: Rework PAC handling in
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=f99cff8c0515d5f29aba9d605415744b1d1c3b08
|
||||
|
||||
kdb_samba_db_sign_auth_data()
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561
|
||||
|
||||
Signed-off-by: Andreas Schneider <asn@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
selftest/knownfail_mit_kdc | 6 +-
|
||||
source4/kdc/mit-kdb/kdb_samba_policies.c | 116 ++++++++++++++++++-----
|
||||
2 files changed, 93 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c
|
||||
index dce87c50049..7bc9a7b3347 100644
|
||||
--- a/source4/kdc/mit-kdb/kdb_samba_policies.c
|
||||
+++ b/source4/kdc/mit-kdb/kdb_samba_policies.c
|
||||
@@ -4,7 +4,7 @@
|
||||
Samba KDB plugin for MIT Kerberos
|
||||
|
||||
Copyright (c) 2010 Simo Sorce <idra@samba.org>.
|
||||
- Copyright (c) 2014 Andreas Schneider <asn@samba.org>
|
||||
+ Copyright (c) 2014-2021 Andreas Schneider <asn@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -325,11 +325,16 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
||||
{
|
||||
krb5_const_principal ks_client_princ = NULL;
|
||||
krb5_db_entry *client_entry = NULL;
|
||||
+ krb5_authdata **pac_auth_data = NULL;
|
||||
krb5_authdata **authdata = NULL;
|
||||
krb5_boolean is_as_req;
|
||||
krb5_error_code code;
|
||||
krb5_pac pac = NULL;
|
||||
krb5_data pac_data;
|
||||
+ bool with_pac = false;
|
||||
+ bool generate_pac = false;
|
||||
+ char *client_name = NULL;
|
||||
+
|
||||
|
||||
is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
|
||||
|
||||
@@ -374,8 +379,6 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
||||
0,
|
||||
&client_entry);
|
||||
if (code != 0) {
|
||||
- char *client_name = NULL;
|
||||
-
|
||||
(void)krb5_unparse_name(context,
|
||||
ks_client_princ,
|
||||
&client_name);
|
||||
@@ -407,43 +410,105 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
||||
client_entry = client;
|
||||
}
|
||||
|
||||
- if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) {
|
||||
+ if (is_as_req) {
|
||||
+ with_pac = mit_samba_princ_needs_pac(client_entry);
|
||||
+ } else {
|
||||
+ with_pac = mit_samba_princ_needs_pac(server);
|
||||
+ }
|
||||
+
|
||||
+ code = krb5_unparse_name(context,
|
||||
+ client_princ,
|
||||
+ &client_name);
|
||||
+ if (code != 0) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC) != 0) {
|
||||
+ generate_pac = true;
|
||||
+ }
|
||||
+
|
||||
+ DBG_DEBUG("*** Sign data for client principal: %s [%s %s%s]\n",
|
||||
+ client_name,
|
||||
+ is_as_req ? "AS-REQ" : "TGS_REQ",
|
||||
+ with_pac ? is_as_req ? "WITH_PAC" : "FIND_PAC" : "NO_PAC",
|
||||
+ generate_pac ? " GENERATE_PAC" : "");
|
||||
+
|
||||
+ /*
|
||||
+ * Generate PAC for the AS-REQ or check or generate one for the TGS if
|
||||
+ * needed.
|
||||
+ */
|
||||
+ if (with_pac && generate_pac) {
|
||||
+ DBG_DEBUG("Generate PAC for AS-REQ [%s]\n", client_name);
|
||||
code = ks_get_pac(context, client_entry, client_key, &pac);
|
||||
if (code != 0) {
|
||||
goto done;
|
||||
}
|
||||
- }
|
||||
-
|
||||
- if (!is_as_req) {
|
||||
- code = ks_verify_pac(context,
|
||||
- flags,
|
||||
- ks_client_princ,
|
||||
- client_entry,
|
||||
- server,
|
||||
- krbtgt,
|
||||
- server_key,
|
||||
- krbtgt_key,
|
||||
- authtime,
|
||||
- tgt_auth_data,
|
||||
- &pac);
|
||||
+ } else if (with_pac && !is_as_req) {
|
||||
+ /*
|
||||
+ * Find the PAC in the TGS, if one exists.
|
||||
+ */
|
||||
+ code = krb5_find_authdata(context,
|
||||
+ tgt_auth_data,
|
||||
+ NULL,
|
||||
+ KRB5_AUTHDATA_WIN2K_PAC,
|
||||
+ &pac_auth_data);
|
||||
if (code != 0) {
|
||||
+ DBG_ERR("krb5_find_authdata failed: %d\n", code);
|
||||
goto done;
|
||||
}
|
||||
- }
|
||||
+ DBG_DEBUG("Found PAC data for TGS-REQ [%s]\n", client_name);
|
||||
|
||||
- if (pac == NULL) {
|
||||
+ if (pac_auth_data != NULL && pac_auth_data[0] != NULL) {
|
||||
+ if (pac_auth_data[1] != NULL) {
|
||||
+ DBG_ERR("Invalid PAC data!\n");
|
||||
+ code = KRB5KDC_ERR_BADOPTION;
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
- code = ks_get_pac(context, client_entry, client_key, &pac);
|
||||
- if (code != 0) {
|
||||
- goto done;
|
||||
+ DBG_DEBUG("Verify PAC for TGS [%s]\n",
|
||||
+ client_name);
|
||||
+
|
||||
+ code = ks_verify_pac(context,
|
||||
+ flags,
|
||||
+ ks_client_princ,
|
||||
+ client_entry,
|
||||
+ server,
|
||||
+ krbtgt,
|
||||
+ server_key,
|
||||
+ krbtgt_key,
|
||||
+ authtime,
|
||||
+ tgt_auth_data,
|
||||
+ &pac);
|
||||
+ if (code != 0) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION) {
|
||||
+ DBG_DEBUG("Generate PAC for constrained"
|
||||
+ "delegation TGS [%s]\n",
|
||||
+ client_name);
|
||||
+
|
||||
+ code = ks_get_pac(context,
|
||||
+ client_entry,
|
||||
+ client_key,
|
||||
+ &pac);
|
||||
+ if (code != 0 && code != ENOENT) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
if (pac == NULL) {
|
||||
- code = KRB5_KDB_DBTYPE_NOSUP;
|
||||
+ DBG_DEBUG("No PAC data - we're done [%s]\n", client_name);
|
||||
+ *signed_auth_data = NULL;
|
||||
+ code = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ DBG_DEBUG("Signing PAC for %s [%s]\n",
|
||||
+ is_as_req ? "AS-REQ" : "TGS-REQ",
|
||||
+ client_name);
|
||||
code = krb5_pac_sign(context, pac, authtime, ks_client_princ,
|
||||
server_key, krbtgt_key, &pac_data);
|
||||
if (code != 0) {
|
||||
@@ -481,8 +546,9 @@ done:
|
||||
if (client_entry != NULL && client_entry != client) {
|
||||
ks_free_principal(context, client_entry);
|
||||
}
|
||||
- krb5_pac_free(context, pac);
|
||||
+ SAFE_FREE(client_name);
|
||||
krb5_free_authdata(context, authdata);
|
||||
+ krb5_pac_free(context, pac);
|
||||
|
||||
return code;
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,249 @@
|
||||
From a76d5d6202379c1f38f7f91df1cce006754463b2 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Wed, 22 Sep 2021 11:29:02 +1200
|
||||
Subject: [PATCH 070/266] CVE-2020-25722 dsdb: Add restrictions on computer
|
||||
accounts without a trailing $
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/a76d5d6202379c1f38f7f91df1cce006754463b2
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 172 +++++++++++++++++++++---
|
||||
1 file changed, 155 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 283a2de..7881dd0 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -68,6 +68,13 @@ struct samldb_ctx {
|
||||
/* used for add operations */
|
||||
enum samldb_add_type type;
|
||||
|
||||
+ /*
|
||||
+ * should we apply the need_trailing_dollar restriction to
|
||||
+ * samAccountName
|
||||
+ */
|
||||
+
|
||||
+ bool need_trailing_dollar;
|
||||
+
|
||||
/* the resulting message */
|
||||
struct ldb_message *msg;
|
||||
|
||||
@@ -232,12 +239,86 @@ static int samldb_unique_attr_check(struct samldb_ctx *ac, const char *attr,
|
||||
|
||||
static int samldb_sam_accountname_valid_check(struct samldb_ctx *ac)
|
||||
{
|
||||
- int ret = samldb_unique_attr_check(ac, "samAccountName", NULL,
|
||||
- ldb_get_default_basedn(
|
||||
- ldb_module_get_ctx(ac->module)));
|
||||
- if (ret == LDB_ERR_OBJECT_CLASS_VIOLATION) {
|
||||
+ int ret = 0;
|
||||
+ bool is_admin;
|
||||
+ struct security_token *user_token = NULL;
|
||||
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
+ struct ldb_message_element *el = dsdb_get_single_valued_attr(ac->msg, "samAccountName",
|
||||
+ ac->req->operation);
|
||||
+ if (el == NULL || el->num_values == 0) {
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "%08X: samldb: 'samAccountName' can't be deleted/empty!",
|
||||
+ W_ERROR_V(WERR_DS_ILLEGAL_MOD_OPERATION));
|
||||
+ if (ac->req->operation == LDB_ADD) {
|
||||
+ return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
+ } else {
|
||||
+ return LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = samldb_unique_attr_check(ac, "samAccountName", NULL,
|
||||
+ ldb_get_default_basedn(
|
||||
+ ldb_module_get_ctx(ac->module)));
|
||||
+
|
||||
+ /*
|
||||
+ * Error code munging to try and match what must be some quite
|
||||
+ * strange code-paths in Windows
|
||||
+ */
|
||||
+ if (ret == LDB_ERR_CONSTRAINT_VIOLATION
|
||||
+ && ac->req->operation == LDB_MODIFY) {
|
||||
+ ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
|
||||
+ } else if (ret == LDB_ERR_OBJECT_CLASS_VIOLATION) {
|
||||
ret = LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
+
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (!ac->need_trailing_dollar) {
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ /* This does not permit a single $ */
|
||||
+ if (el->values[0].length < 2) {
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "%08X: samldb: 'samAccountName' "
|
||||
+ "can't just be one character!",
|
||||
+ W_ERROR_V(WERR_DS_ILLEGAL_MOD_OPERATION));
|
||||
+ return LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
+
|
||||
+ user_token = acl_user_token(ac->module);
|
||||
+ if (user_token == NULL) {
|
||||
+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
||||
+ }
|
||||
+
|
||||
+ is_admin
|
||||
+ = security_token_has_builtin_administrators(user_token);
|
||||
+
|
||||
+ if (is_admin) {
|
||||
+ /*
|
||||
+ * Administrators are allowed to select strange names.
|
||||
+ * This is poor practice but not prevented.
|
||||
+ */
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (el->values[0].data[el->values[0].length - 1] != '$') {
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "%08X: samldb: 'samAccountName' "
|
||||
+ "must have a trailing $!",
|
||||
+ W_ERROR_V(WERR_DS_ILLEGAL_MOD_OPERATION));
|
||||
+ return LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
+ if (el->values[0].data[el->values[0].length - 2] == '$') {
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "%08X: samldb: 'samAccountName' "
|
||||
+ "must not have a double trailing $!",
|
||||
+ W_ERROR_V(WERR_DS_ILLEGAL_MOD_OPERATION));
|
||||
+ return LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -554,17 +635,32 @@ static int samldb_schema_add_handle_mapiid(struct samldb_ctx *ac)
|
||||
}
|
||||
|
||||
/* sAMAccountName handling */
|
||||
-static int samldb_generate_sAMAccountName(struct ldb_context *ldb,
|
||||
+static int samldb_generate_sAMAccountName(struct samldb_ctx *ac,
|
||||
struct ldb_message *msg)
|
||||
{
|
||||
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
char *name;
|
||||
|
||||
- /* Format: $000000-000000000000 */
|
||||
+ /*
|
||||
+ * This is currently a Samba-only behaviour, to add a trailing
|
||||
+ * $ even for the generated accounts.
|
||||
+ */
|
||||
+
|
||||
+ if (ac->need_trailing_dollar) {
|
||||
+ /* Format: $000000-00000000000$ */
|
||||
+ name = talloc_asprintf(msg, "$%.6X-%.6X%.5X$",
|
||||
+ (unsigned int)generate_random(),
|
||||
+ (unsigned int)generate_random(),
|
||||
+ (unsigned int)generate_random());
|
||||
+ } else {
|
||||
+ /* Format: $000000-000000000000 */
|
||||
+
|
||||
+ name = talloc_asprintf(msg, "$%.6X-%.6X%.6X",
|
||||
+ (unsigned int)generate_random(),
|
||||
+ (unsigned int)generate_random(),
|
||||
+ (unsigned int)generate_random());
|
||||
+ }
|
||||
|
||||
- name = talloc_asprintf(msg, "$%.6X-%.6X%.6X",
|
||||
- (unsigned int)generate_random(),
|
||||
- (unsigned int)generate_random(),
|
||||
- (unsigned int)generate_random());
|
||||
if (name == NULL) {
|
||||
return ldb_oom(ldb);
|
||||
}
|
||||
@@ -573,11 +669,10 @@ static int samldb_generate_sAMAccountName(struct ldb_context *ldb,
|
||||
|
||||
static int samldb_check_sAMAccountName(struct samldb_ctx *ac)
|
||||
{
|
||||
- struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
int ret;
|
||||
|
||||
if (ldb_msg_find_element(ac->msg, "sAMAccountName") == NULL) {
|
||||
- ret = samldb_generate_sAMAccountName(ldb, ac->msg);
|
||||
+ ret = samldb_generate_sAMAccountName(ac, ac->msg);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
@@ -1473,6 +1568,20 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac)
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * Require, for non-admin modifications, a trailing $
|
||||
+ * for either objectclass=computer or a trust account
|
||||
+ * type in userAccountControl
|
||||
+ */
|
||||
+ if ((user_account_control
|
||||
+ & UF_TRUST_ACCOUNT_MASK) != 0) {
|
||||
+ ac->need_trailing_dollar = true;
|
||||
+ }
|
||||
+
|
||||
+ if (is_computer_objectclass) {
|
||||
+ ac->need_trailing_dollar = true;
|
||||
+ }
|
||||
|
||||
/* add "sAMAccountType" attribute */
|
||||
ret = dsdb_user_obj_set_account_type(ldb, ac->msg, user_account_control, NULL);
|
||||
@@ -3989,12 +4098,41 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
|
||||
|
||||
el = ldb_msg_find_element(ac->msg, "sAMAccountName");
|
||||
if (el != NULL) {
|
||||
+ uint32_t user_account_control;
|
||||
+ struct ldb_result *res = NULL;
|
||||
+ const char * const attrs[] = { "userAccountControl",
|
||||
+ "objectclass",
|
||||
+ NULL };
|
||||
+ ret = dsdb_module_search_dn(ac->module,
|
||||
+ ac,
|
||||
+ &res,
|
||||
+ ac->msg->dn,
|
||||
+ attrs,
|
||||
+ DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED,
|
||||
+ ac->req);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ user_account_control
|
||||
+ = ldb_msg_find_attr_as_uint(res->msgs[0],
|
||||
+ "userAccountControl",
|
||||
+ 0);
|
||||
+
|
||||
+ if ((user_account_control
|
||||
+ & UF_TRUST_ACCOUNT_MASK) != 0) {
|
||||
+ ac->need_trailing_dollar = true;
|
||||
+
|
||||
+ } else if (samdb_find_attribute(ldb,
|
||||
+ res->msgs[0],
|
||||
+ "objectclass",
|
||||
+ "computer")
|
||||
+ != NULL) {
|
||||
+ ac->need_trailing_dollar = true;
|
||||
+ }
|
||||
+
|
||||
ret = samldb_sam_accountname_valid_check(ac);
|
||||
- /*
|
||||
- * Other errors are checked for elsewhere, we just
|
||||
- * want to prevent duplicates
|
||||
- */
|
||||
- if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,340 @@
|
||||
From 08b6c8fda591c129adecd0779bf4a62386b8c740 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Thu, 5 Aug 2021 15:09:04 +0200
|
||||
Subject: [PATCH 265/266] CVE-2021-3738 s4:rpc_server/netlogon: make use of
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=08b6c8fda591c129adecd0779bf4a62386b8c740
|
||||
|
||||
dcesrv_samdb_connect_as_*() helper
|
||||
|
||||
This is not strictly required, but it makes it easier to audit that
|
||||
source4/rpc_server no longer calls samdb_connect() directly and
|
||||
also improves auditing for the dcesrv_samdb_connect_as_system() case.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14468
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source4/rpc_server/netlogon/dcerpc_netlogon.c | 136 +++---------------
|
||||
1 file changed, 18 insertions(+), 118 deletions(-)
|
||||
|
||||
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
index 09d0252c0c2..a1036a36787 100644
|
||||
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "rpc_server/dcerpc_server.h"
|
||||
+#include "rpc_server/common/common.h"
|
||||
#include "auth/auth.h"
|
||||
#include "auth/auth_sam_reply.h"
|
||||
#include "dsdb/samdb/samdb.h"
|
||||
@@ -283,12 +284,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- system_session(dce_call->conn->dce_ctx->lp_ctx),
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
@@ -756,12 +752,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call
|
||||
&creds);
|
||||
NT_STATUS_NOT_OK_RETURN(nt_status);
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- system_session(dce_call->conn->dce_ctx->lp_ctx),
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
@@ -825,12 +816,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
|
||||
&creds);
|
||||
NT_STATUS_NOT_OK_RETURN(nt_status);
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- system_session(dce_call->conn->dce_ctx->lp_ctx),
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
@@ -1716,8 +1702,6 @@ static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALL
|
||||
static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct netr_GetDcName *r)
|
||||
{
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
const char * const attrs[] = { NULL };
|
||||
struct ldb_context *sam_ctx;
|
||||
struct ldb_message **res;
|
||||
@@ -1744,12 +1728,7 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C
|
||||
*/
|
||||
}
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return WERR_DS_UNAVAILABLE;
|
||||
}
|
||||
@@ -1951,13 +1930,8 @@ static WERROR dcesrv_netr_LogonControl_base_call(struct dcesrv_netr_LogonControl
|
||||
if (!ok) {
|
||||
struct ldb_context *sam_ctx;
|
||||
|
||||
- sam_ctx = samdb_connect(
|
||||
- state,
|
||||
- state->dce_call->event_ctx,
|
||||
- lp_ctx,
|
||||
- system_session(lp_ctx),
|
||||
- state->dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_system(state,
|
||||
+ state->dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return WERR_DS_UNAVAILABLE;
|
||||
}
|
||||
@@ -2154,8 +2128,6 @@ static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
|
||||
static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct netr_GetAnyDCName *r)
|
||||
{
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
struct netr_DomainTrustList *trusts;
|
||||
struct ldb_context *sam_ctx;
|
||||
struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
|
||||
@@ -2169,12 +2141,7 @@ static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLO
|
||||
r->in.domainname = lpcfg_workgroup(lp_ctx);
|
||||
}
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return WERR_DS_UNAVAILABLE;
|
||||
}
|
||||
@@ -2316,17 +2283,9 @@ static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state
|
||||
static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct netr_DsRGetSiteName *r)
|
||||
{
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
struct ldb_context *sam_ctx;
|
||||
- struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return WERR_DS_UNAVAILABLE;
|
||||
}
|
||||
@@ -2525,12 +2484,7 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
|
||||
}
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- system_session(dce_call->conn->dce_ctx->lp_ctx),
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
@@ -2922,12 +2876,7 @@ static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_cal
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- system_session(dce_call->conn->dce_ctx->lp_ctx),
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
@@ -3038,8 +2987,6 @@ static void dcesrv_netr_DsRGetDCName_base_done(struct tevent_req *subreq);
|
||||
static WERROR dcesrv_netr_DsRGetDCName_base_call(struct dcesrv_netr_DsRGetDCName_base_state *state)
|
||||
{
|
||||
struct dcesrv_call_state *dce_call = state->dce_call;
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
TALLOC_CTX *mem_ctx = state->mem_ctx;
|
||||
struct netr_DsRGetDCNameEx2 *r = &state->r;
|
||||
struct ldb_context *sam_ctx;
|
||||
@@ -3062,12 +3009,7 @@ static WERROR dcesrv_netr_DsRGetDCName_base_call(struct dcesrv_netr_DsRGetDCName
|
||||
|
||||
ZERO_STRUCTP(r->out.info);
|
||||
|
||||
- sam_ctx = samdb_connect(state,
|
||||
- dce_call->event_ctx,
|
||||
- lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return WERR_DS_UNAVAILABLE;
|
||||
}
|
||||
@@ -3522,11 +3464,8 @@ static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state
|
||||
static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct netr_DsRAddressToSitenamesExW *r)
|
||||
{
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
struct ldb_context *sam_ctx;
|
||||
struct netr_DsRAddressToSitenamesExWCtr *ctr;
|
||||
- struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
|
||||
sa_family_t sin_family;
|
||||
struct sockaddr_in *addr;
|
||||
#ifdef HAVE_IPV6
|
||||
@@ -3539,12 +3478,7 @@ static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce
|
||||
const char *res;
|
||||
uint32_t i;
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return WERR_DS_UNAVAILABLE;
|
||||
}
|
||||
@@ -3656,18 +3590,10 @@ static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_c
|
||||
static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct netr_DsrGetDcSiteCoverageW *r)
|
||||
{
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
struct ldb_context *sam_ctx;
|
||||
struct DcSitesCtr *ctr;
|
||||
- struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return WERR_DS_UNAVAILABLE;
|
||||
}
|
||||
@@ -3793,8 +3719,6 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct netr_DsrEnumerateDomainTrusts *r)
|
||||
{
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
struct netr_DomainTrustList *trusts;
|
||||
struct ldb_context *sam_ctx;
|
||||
int ret;
|
||||
@@ -3836,12 +3760,7 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
|
||||
trusts->count = 0;
|
||||
r->out.trusts = trusts;
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return WERR_GEN_FAILURE;
|
||||
}
|
||||
@@ -3951,7 +3870,6 @@ static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct netr_DsRGetForestTrustInformation *r)
|
||||
{
|
||||
- struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
|
||||
struct auth_session_info *session_info =
|
||||
dcesrv_call_session_info(dce_call);
|
||||
enum security_user_level security_level;
|
||||
@@ -3975,12 +3893,7 @@ static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state
|
||||
return WERR_INVALID_FLAGS;
|
||||
}
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return WERR_GEN_FAILURE;
|
||||
}
|
||||
@@ -4107,9 +4020,6 @@ static NTSTATUS dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct netr_GetForestTrustInformation *r)
|
||||
{
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
- struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
|
||||
struct netlogon_creds_CredentialState *creds = NULL;
|
||||
struct ldb_context *sam_ctx = NULL;
|
||||
struct ldb_dn *domain_dn = NULL;
|
||||
@@ -4133,12 +4043,7 @@ static NTSTATUS dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
@@ -4232,12 +4137,7 @@ static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_cal
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- lp_ctx,
|
||||
- system_session(lp_ctx),
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,83 @@
|
||||
From 04e10a843187810e97bf565731ddc5d70b0f4245 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Tue, 15 Sep 2020 17:26:11 +0200
|
||||
Subject: [PATCH 027/266] CVE-2020-25717 winbindd: allow idmap backends to mark
|
||||
entries with ID_[TYPE_WB_]REQUIRE_TYPE
|
||||
|
||||
This must only be used between winbindd parent and child!
|
||||
It must not leak into outside world.
|
||||
|
||||
Some backends require ID_TYPE_UID or ID_TYPE_GID as type_hint,
|
||||
while others may only need ID_TYPE_BOTH in order to validate that
|
||||
the domain exists.
|
||||
|
||||
This will allow us to skip the wb_lookupsids_send/recv in the winbindd parent
|
||||
in future and only do that on demand.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
(cherry picked from commit 493f5d6b078e0b0f80d1ef25043e2834cb4fcb87)
|
||||
---
|
||||
librpc/idl/idmap.idl | 23 +++++++++++++++++--
|
||||
source3/passdb/lookup_sid.c | 7 ++++++
|
||||
source3/winbindd/idmap_autorid.c | 6 ++---
|
||||
source3/winbindd/idmap_ldap.c | 29 ++++++++++++++++++++++++
|
||||
source3/winbindd/idmap_rw.c | 32 +++++++++++++++++++++++++--
|
||||
source3/winbindd/idmap_tdb_common.c | 22 +++++++++++++++++-
|
||||
source3/winbindd/wb_sids2xids.c | 11 +++++++++
|
||||
source3/winbindd/winbindd_dual_srv.c | 6 +++++
|
||||
source3/winbindd/winbindd_getgroups.c | 7 ++++++
|
||||
9 files changed, 135 insertions(+), 8 deletions(-)
|
||||
|
||||
Conflict:only remain the first chunk
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=04e10a843187810e97bf565731ddc5d70b0f4245
|
||||
|
||||
diff --git a/librpc/idl/idmap.idl b/librpc/idl/idmap.idl
|
||||
index 54fd888dcab..e58e39210c7 100644
|
||||
--- a/librpc/idl/idmap.idl
|
||||
+++ b/librpc/idl/idmap.idl
|
||||
@@ -11,7 +11,18 @@ interface idmap
|
||||
ID_TYPE_NOT_SPECIFIED,
|
||||
ID_TYPE_UID,
|
||||
ID_TYPE_GID,
|
||||
- ID_TYPE_BOTH
|
||||
+ ID_TYPE_BOTH,
|
||||
+ /*
|
||||
+ * This are internal between winbindd
|
||||
+ * parent and child.
|
||||
+ *
|
||||
+ * It means the idmap backend/child requires a valid type_hint
|
||||
+ * for wbint_Sids2UnixIDs():
|
||||
+ *
|
||||
+ * - ID_TYPE_UID or ID_TYPE_GID means the user/group exists
|
||||
+ * - ID_TYPE_BOTH means that only the domain exist
|
||||
+ */
|
||||
+ ID_TYPE_WB_REQUIRE_TYPE
|
||||
} id_type;
|
||||
|
||||
typedef [public] struct {
|
||||
@@ -23,7 +34,15 @@ interface idmap
|
||||
ID_UNKNOWN,
|
||||
ID_MAPPED,
|
||||
ID_UNMAPPED,
|
||||
- ID_EXPIRED
|
||||
+ ID_EXPIRED,
|
||||
+ /*
|
||||
+ * This means the idmap backend requires a valid type_hint
|
||||
+ * in order to map a sid to a unix id.
|
||||
+ *
|
||||
+ * - ID_TYPE_UID or ID_TYPE_GID means the user/group exists
|
||||
+ * - ID_TYPE_BOTH means that only the domain exist
|
||||
+ */
|
||||
+ ID_REQUIRE_TYPE
|
||||
} id_mapping;
|
||||
|
||||
typedef [public] struct {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
304
backport-0006-CVE-2020-25718-Change-sid-list.patch
Normal file
304
backport-0006-CVE-2020-25718-Change-sid-list.patch
Normal file
@ -0,0 +1,304 @@
|
||||
From fc65e4b49c9900aeca06276f05f31e20d28a6c20 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Fri, 1 Oct 2021 10:47:29 +1300
|
||||
Subject: [PATCH 232/284] CVE-2020-25718 s4-rpc_server: Change sid list
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=fc65e4b49c9900aeca06276f05f31e20d28a6c20
|
||||
|
||||
functions to operate on a array of struct dom_sid
|
||||
|
||||
This is instead of an array of struct dom_sid *.
|
||||
|
||||
The reason is that auth_user_info_dc has an array of struct dom_sid
|
||||
(the user token) and for checking if an RODC should be allowed
|
||||
to print a particular ticket, we want to reuse that a rather
|
||||
then reconstruct it via tokenGroups.
|
||||
|
||||
This also avoids a lot of memory allocation.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
---
|
||||
source4/rpc_server/common/sid_helper.c | 44 +++++++++----------
|
||||
source4/rpc_server/drsuapi/getncchanges.c | 33 +++++++++-----
|
||||
source4/rpc_server/netlogon/dcerpc_netlogon.c | 33 +++++++++-----
|
||||
3 files changed, 67 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/source4/rpc_server/common/sid_helper.c b/source4/rpc_server/common/sid_helper.c
|
||||
index 698249391ef5..65d7e7c7271e 100644
|
||||
--- a/source4/rpc_server/common/sid_helper.c
|
||||
+++ b/source4/rpc_server/common/sid_helper.c
|
||||
@@ -29,13 +29,16 @@
|
||||
/*
|
||||
see if any SIDs in list1 are in list2
|
||||
*/
|
||||
-bool sid_list_match(const struct dom_sid **list1, const struct dom_sid **list2)
|
||||
+bool sid_list_match(uint32_t num_sids1,
|
||||
+ const struct dom_sid *list1,
|
||||
+ uint32_t num_sids2,
|
||||
+ const struct dom_sid *list2)
|
||||
{
|
||||
unsigned int i, j;
|
||||
/* do we ever have enough SIDs here to worry about O(n^2) ? */
|
||||
- for (i=0; list1[i]; i++) {
|
||||
- for (j=0; list2[j]; j++) {
|
||||
- if (dom_sid_equal(list1[i], list2[j])) {
|
||||
+ for (i=0; i < num_sids1; i++) {
|
||||
+ for (j=0; j < num_sids2; j++) {
|
||||
+ if (dom_sid_equal(&list1[i], &list2[j])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -51,9 +54,10 @@ WERROR samdb_result_sid_array_ndr(struct ldb_context *sam_ctx,
|
||||
struct ldb_message *msg,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const char *attr,
|
||||
- const struct dom_sid ***sids,
|
||||
- const struct dom_sid **additional_sids,
|
||||
- unsigned int num_additional)
|
||||
+ uint32_t *num_sids,
|
||||
+ struct dom_sid **sids,
|
||||
+ const struct dom_sid *additional_sids,
|
||||
+ unsigned int num_additional)
|
||||
{
|
||||
struct ldb_message_element *el;
|
||||
unsigned int i, j;
|
||||
@@ -65,30 +69,25 @@ WERROR samdb_result_sid_array_ndr(struct ldb_context *sam_ctx,
|
||||
}
|
||||
|
||||
/* Make array long enough for NULL and additional SID */
|
||||
- (*sids) = talloc_array(mem_ctx, const struct dom_sid *,
|
||||
- el->num_values + num_additional + 1);
|
||||
+ (*sids) = talloc_array(mem_ctx, struct dom_sid,
|
||||
+ el->num_values + num_additional);
|
||||
W_ERROR_HAVE_NO_MEMORY(*sids);
|
||||
|
||||
for (i=0; i<el->num_values; i++) {
|
||||
enum ndr_err_code ndr_err;
|
||||
- struct dom_sid *sid;
|
||||
|
||||
- sid = talloc(*sids, struct dom_sid);
|
||||
- W_ERROR_HAVE_NO_MEMORY(sid);
|
||||
-
|
||||
- ndr_err = ndr_pull_struct_blob(&el->values[i], sid, sid,
|
||||
+ ndr_err = ndr_pull_struct_blob_all_noalloc(&el->values[i], &(*sids)[i],
|
||||
(ndr_pull_flags_fn_t)ndr_pull_dom_sid);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
return WERR_INTERNAL_DB_CORRUPTION;
|
||||
}
|
||||
- (*sids)[i] = sid;
|
||||
}
|
||||
|
||||
for (j = 0; j < num_additional; j++) {
|
||||
(*sids)[i++] = additional_sids[j];
|
||||
}
|
||||
|
||||
- (*sids)[i] = NULL;
|
||||
+ *num_sids = i;
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
@@ -101,7 +100,8 @@ WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx,
|
||||
struct ldb_message *msg,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const char *attr,
|
||||
- const struct dom_sid ***sids)
|
||||
+ uint32_t *num_sids,
|
||||
+ struct dom_sid **sids)
|
||||
{
|
||||
struct ldb_message_element *el;
|
||||
unsigned int i;
|
||||
@@ -112,23 +112,21 @@ WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx,
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
- (*sids) = talloc_array(mem_ctx, const struct dom_sid *, el->num_values + 1);
|
||||
+ (*sids) = talloc_array(mem_ctx, struct dom_sid, el->num_values + 1);
|
||||
W_ERROR_HAVE_NO_MEMORY(*sids);
|
||||
|
||||
for (i=0; i<el->num_values; i++) {
|
||||
struct ldb_dn *dn = ldb_dn_from_ldb_val(mem_ctx, sam_ctx, &el->values[i]);
|
||||
NTSTATUS status;
|
||||
- struct dom_sid *sid;
|
||||
+ struct dom_sid sid = { 0, };
|
||||
|
||||
- sid = talloc(*sids, struct dom_sid);
|
||||
- W_ERROR_HAVE_NO_MEMORY(sid);
|
||||
- status = dsdb_get_extended_dn_sid(dn, sid, "SID");
|
||||
+ status = dsdb_get_extended_dn_sid(dn, &sid, "SID");
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return WERR_INTERNAL_DB_CORRUPTION;
|
||||
}
|
||||
(*sids)[i] = sid;
|
||||
}
|
||||
- (*sids)[i] = NULL;
|
||||
+ *num_sids = i;
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c
|
||||
index e458b2a99311..c7d2addd104d 100644
|
||||
--- a/source4/rpc_server/drsuapi/getncchanges.c
|
||||
+++ b/source4/rpc_server/drsuapi/getncchanges.c
|
||||
@@ -1171,10 +1171,10 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state,
|
||||
const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", "objectGUID", NULL };
|
||||
const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL };
|
||||
struct ldb_result *rodc_res = NULL, *obj_res = NULL;
|
||||
- const struct dom_sid **never_reveal_sids, **reveal_sids, **token_sids;
|
||||
+ uint32_t num_never_reveal_sids, num_reveal_sids, num_token_sids;
|
||||
+ struct dom_sid *never_reveal_sids, *reveal_sids, *token_sids;
|
||||
const struct dom_sid *object_sid = NULL;
|
||||
WERROR werr;
|
||||
- const struct dom_sid *additional_sids[] = { NULL, NULL };
|
||||
|
||||
DEBUG(3,(__location__ ": DRSUAPI_EXOP_REPL_SECRET extended op on %s\n",
|
||||
drs_ObjectIdentifier_to_string(mem_ctx, ncRoot)));
|
||||
@@ -1259,12 +1259,13 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state,
|
||||
|
||||
/* if the object SID is equal to the user_sid, allow */
|
||||
object_sid = samdb_result_dom_sid(mem_ctx, obj_res->msgs[0], "objectSid");
|
||||
+ if (object_sid == NULL) {
|
||||
+ goto failed;
|
||||
+ }
|
||||
if (dom_sid_equal(user_sid, object_sid)) {
|
||||
goto allowed;
|
||||
}
|
||||
|
||||
- additional_sids[0] = object_sid;
|
||||
-
|
||||
/*
|
||||
* Must be an RODC account at this point, verify machine DN matches the
|
||||
* SID account
|
||||
@@ -1294,13 +1295,17 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state,
|
||||
}
|
||||
|
||||
werr = samdb_result_sid_array_dn(b_state->sam_ctx_system, rodc_res->msgs[0],
|
||||
- mem_ctx, "msDS-NeverRevealGroup", &never_reveal_sids);
|
||||
+ mem_ctx, "msDS-NeverRevealGroup",
|
||||
+ &num_never_reveal_sids,
|
||||
+ &never_reveal_sids);
|
||||
if (!W_ERROR_IS_OK(werr)) {
|
||||
goto denied;
|
||||
}
|
||||
|
||||
werr = samdb_result_sid_array_dn(b_state->sam_ctx_system, rodc_res->msgs[0],
|
||||
- mem_ctx, "msDS-RevealOnDemandGroup", &reveal_sids);
|
||||
+ mem_ctx, "msDS-RevealOnDemandGroup",
|
||||
+ &num_reveal_sids,
|
||||
+ &reveal_sids);
|
||||
if (!W_ERROR_IS_OK(werr)) {
|
||||
goto denied;
|
||||
}
|
||||
@@ -1311,19 +1316,27 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state,
|
||||
* TODO determine if sIDHistory is required for this check
|
||||
*/
|
||||
werr = samdb_result_sid_array_ndr(b_state->sam_ctx_system, obj_res->msgs[0],
|
||||
- mem_ctx, "tokenGroups", &token_sids,
|
||||
- additional_sids, 1);
|
||||
+ mem_ctx, "tokenGroups",
|
||||
+ &num_token_sids,
|
||||
+ &token_sids,
|
||||
+ object_sid, 1);
|
||||
if (!W_ERROR_IS_OK(werr) || token_sids==NULL) {
|
||||
goto denied;
|
||||
}
|
||||
|
||||
if (never_reveal_sids &&
|
||||
- sid_list_match(token_sids, never_reveal_sids)) {
|
||||
+ sid_list_match(num_token_sids,
|
||||
+ token_sids,
|
||||
+ num_never_reveal_sids,
|
||||
+ never_reveal_sids)) {
|
||||
goto denied;
|
||||
}
|
||||
|
||||
if (reveal_sids &&
|
||||
- sid_list_match(token_sids, reveal_sids)) {
|
||||
+ sid_list_match(num_token_sids,
|
||||
+ token_sids,
|
||||
+ num_reveal_sids,
|
||||
+ reveal_sids)) {
|
||||
goto allowed;
|
||||
}
|
||||
|
||||
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
index 9972138dbdef..c8dd0ceeb775 100644
|
||||
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
@@ -2850,10 +2850,10 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
|
||||
struct ldb_dn *rodc_dn;
|
||||
int ret;
|
||||
struct ldb_result *rodc_res = NULL, *obj_res = NULL;
|
||||
- const struct dom_sid *additional_sids[] = { NULL, NULL };
|
||||
WERROR werr;
|
||||
struct dom_sid *object_sid;
|
||||
- const struct dom_sid **never_reveal_sids, **reveal_sids, **token_sids;
|
||||
+ uint32_t num_never_reveal_sids, num_reveal_sids, num_token_sids;
|
||||
+ struct dom_sid *never_reveal_sids, *reveal_sids, *token_sids;
|
||||
|
||||
rodc_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
|
||||
dom_sid_string(mem_ctx, user_sid));
|
||||
@@ -2868,17 +2868,22 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
|
||||
if (ret != LDB_SUCCESS || obj_res->count != 1) goto denied;
|
||||
|
||||
object_sid = samdb_result_dom_sid(mem_ctx, obj_res->msgs[0], "objectSid");
|
||||
-
|
||||
- additional_sids[0] = object_sid;
|
||||
+ if (object_sid == NULL) {
|
||||
+ goto denied;
|
||||
+ }
|
||||
|
||||
werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0],
|
||||
- mem_ctx, "msDS-NeverRevealGroup", &never_reveal_sids);
|
||||
+ mem_ctx, "msDS-NeverRevealGroup",
|
||||
+ &num_never_reveal_sids,
|
||||
+ &never_reveal_sids);
|
||||
if (!W_ERROR_IS_OK(werr)) {
|
||||
goto denied;
|
||||
}
|
||||
|
||||
werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0],
|
||||
- mem_ctx, "msDS-RevealOnDemandGroup", &reveal_sids);
|
||||
+ mem_ctx, "msDS-RevealOnDemandGroup",
|
||||
+ &num_reveal_sids,
|
||||
+ &reveal_sids);
|
||||
if (!W_ERROR_IS_OK(werr)) {
|
||||
goto denied;
|
||||
}
|
||||
@@ -2889,19 +2894,27 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
|
||||
* TODO determine if sIDHistory is required for this check
|
||||
*/
|
||||
werr = samdb_result_sid_array_ndr(sam_ctx, obj_res->msgs[0],
|
||||
- mem_ctx, "tokenGroups", &token_sids,
|
||||
- additional_sids, 1);
|
||||
+ mem_ctx, "tokenGroups",
|
||||
+ &num_token_sids,
|
||||
+ &token_sids,
|
||||
+ object_sid, 1);
|
||||
if (!W_ERROR_IS_OK(werr) || token_sids==NULL) {
|
||||
goto denied;
|
||||
}
|
||||
|
||||
if (never_reveal_sids &&
|
||||
- sid_list_match(token_sids, never_reveal_sids)) {
|
||||
+ sid_list_match(num_token_sids,
|
||||
+ token_sids,
|
||||
+ num_never_reveal_sids,
|
||||
+ never_reveal_sids)) {
|
||||
goto denied;
|
||||
}
|
||||
|
||||
if (reveal_sids &&
|
||||
- sid_list_match(token_sids, reveal_sids)) {
|
||||
+ sid_list_match(num_token_sids,
|
||||
+ token_sids,
|
||||
+ num_reveal_sids,
|
||||
+ reveal_sids)) {
|
||||
goto allowed;
|
||||
}
|
||||
|
||||
--
|
||||
2.25.1
|
||||
@ -0,0 +1,42 @@
|
||||
From 55d821ca8b5baaa69f88127b228bd4906e2cee68 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Thu, 21 Oct 2021 13:02:42 +1300
|
||||
Subject: [PATCH 072/266] CVE-2020-25722 samdb: Fill in isCriticalSystemObject
|
||||
on any account type change
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/55d821ca8b5baaa69f88127b228bd4906e2cee68
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 10 ++++++++--
|
||||
1 files changed, 8 insertions(+), 2 deletions(-)
|
||||
delete mode 100644 selftest/knownfail.d/sam-isCriticalSystemObject
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index aeef663d2f0..5352af1099f 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -2621,8 +2621,14 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
|
||||
el->flags = LDB_FLAG_MOD_REPLACE;
|
||||
}
|
||||
|
||||
- /* "isCriticalSystemObject" might be set/changed */
|
||||
- if (old_is_critical != new_is_critical) {
|
||||
+ /*
|
||||
+ * "isCriticalSystemObject" might be set/changed
|
||||
+ *
|
||||
+ * Even a change from UF_NORMAL_ACCOUNT (implicitly FALSE) to
|
||||
+ * UF_WORKSTATION_TRUST_ACCOUNT (actually FALSE) triggers
|
||||
+ * creating the attribute.
|
||||
+ */
|
||||
+ if (old_is_critical != new_is_critical || old_atype != new_atype) {
|
||||
ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject",
|
||||
new_is_critical ? "TRUE": "FALSE");
|
||||
if (ret != LDB_SUCCESS) {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,176 @@
|
||||
From 0203330e2fa23482d99809e777ccb8a93a728aa3 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Thu, 5 Aug 2021 14:24:40 +0200
|
||||
Subject: [PATCH 266/266] CVE-2021-3738 s4:rpc_server/samr: make use of
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=0203330e2fa23482d99809e777ccb8a93a728aa3
|
||||
|
||||
dcesrv_samdb_connect_as_*() helper
|
||||
|
||||
This avoids a crash that's triggered by windows clients using
|
||||
handles from samr_Connect*() on across multiple connections within
|
||||
an association group.
|
||||
|
||||
In other cases is not strictly required, but it makes it easier to audit that
|
||||
source4/rpc_server no longer calls samdb_connect() directly and also
|
||||
improves the auditing for the dcesrv_samdb_connect_as_system() case.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14468
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
[abartlet@samba.org Backported from master as Samba 4.13 does not
|
||||
call dcerpc_is_transport_encrypted() and so session_info becomes
|
||||
unused.]
|
||||
---
|
||||
source4/rpc_server/samr/dcesrv_samr.c | 19 ++------------
|
||||
source4/rpc_server/samr/samr_password.c | 33 ++++---------------------
|
||||
2 files changed, 7 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
|
||||
index 7345cac6bd6..c810aac7c8a 100644
|
||||
--- a/source4/rpc_server/samr/dcesrv_samr.c
|
||||
+++ b/source4/rpc_server/samr/dcesrv_samr.c
|
||||
@@ -210,8 +210,6 @@ exit:
|
||||
static NTSTATUS dcesrv_samr_Connect(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct samr_Connect *r)
|
||||
{
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
struct samr_connect_state *c_state;
|
||||
struct dcesrv_handle *handle;
|
||||
|
||||
@@ -223,18 +221,12 @@ static NTSTATUS dcesrv_samr_Connect(struct dcesrv_call_state *dce_call, TALLOC_C
|
||||
}
|
||||
|
||||
/* make sure the sam database is accessible */
|
||||
- c_state->sam_ctx = samdb_connect(c_state,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ c_state->sam_ctx = dcesrv_samdb_connect_as_user(c_state, dce_call);
|
||||
if (c_state->sam_ctx == NULL) {
|
||||
talloc_free(c_state);
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
|
||||
-
|
||||
handle = dcesrv_handle_create(dce_call, SAMR_HANDLE_CONNECT);
|
||||
if (!handle) {
|
||||
talloc_free(c_state);
|
||||
@@ -4807,8 +4799,6 @@ static NTSTATUS dcesrv_samr_RemoveMultipleMembersFromAlias(struct dcesrv_call_st
|
||||
static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct samr_GetDomPwInfo *r)
|
||||
{
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
struct ldb_message **msgs;
|
||||
int ret;
|
||||
const char * const attrs[] = {"minPwdLength", "pwdProperties", NULL };
|
||||
@@ -4816,12 +4806,7 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
|
||||
|
||||
ZERO_STRUCTP(r->out.info);
|
||||
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
|
||||
index 52a644176e2..9144c23155b 100644
|
||||
--- a/source4/rpc_server/samr/samr_password.c
|
||||
+++ b/source4/rpc_server/samr/samr_password.c
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "rpc_server/dcerpc_server.h"
|
||||
+#include "rpc_server/common/common.h"
|
||||
#include "rpc_server/samr/dcesrv_samr.h"
|
||||
#include "system/time.h"
|
||||
#include "../lib/crypto/crypto.h"
|
||||
@@ -101,8 +102,6 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct samr_OemChangePasswordUser2 *r)
|
||||
{
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
NTSTATUS status = NT_STATUS_WRONG_PASSWORD;
|
||||
DATA_BLOB new_password, new_unicode_password;
|
||||
char *new_pass;
|
||||
@@ -146,12 +145,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
|
||||
|
||||
/* Connect to a SAMDB with system privileges for fetching the old pw
|
||||
* hashes. */
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- system_session(dce_call->conn->dce_ctx->lp_ctx),
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
@@ -249,12 +243,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
|
||||
}
|
||||
|
||||
/* Connect to a SAMDB with user privileges for the password change */
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
@@ -327,8 +316,6 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct samr_ChangePasswordUser3 *r)
|
||||
{
|
||||
- struct auth_session_info *session_info =
|
||||
- dcesrv_call_session_info(dce_call);
|
||||
NTSTATUS status = NT_STATUS_WRONG_PASSWORD;
|
||||
DATA_BLOB new_password;
|
||||
struct ldb_context *sam_ctx = NULL;
|
||||
@@ -374,12 +361,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
|
||||
|
||||
/* Connect to a SAMDB with system privileges for fetching the old pw
|
||||
* hashes. */
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- system_session(dce_call->conn->dce_ctx->lp_ctx),
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
@@ -485,12 +467,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
|
||||
}
|
||||
|
||||
/* Connect to a SAMDB with user privileges for the password change */
|
||||
- sam_ctx = samdb_connect(mem_ctx,
|
||||
- dce_call->event_ctx,
|
||||
- dce_call->conn->dce_ctx->lp_ctx,
|
||||
- session_info,
|
||||
- dce_call->conn->remote_address,
|
||||
- 0);
|
||||
+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,104 @@
|
||||
From 4925a110c4e0586ca74566beca2450bbc4d18e4c Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Fri, 23 Oct 2020 12:21:57 +0200
|
||||
Subject: [PATCH 029/266] CVE-2020-25717 s3:idmap_hash: reliable return
|
||||
ID_TYPE_BOTH
|
||||
|
||||
idmap_hash used to bounce back the requested type,
|
||||
which was ID_TYPE_UID, ID_TYPE_GID or ID_TYPE_NOT_SPECIFIED
|
||||
before as the winbindd parent always used a lookupsids.
|
||||
When the lookupsids failed because of an unknown domain,
|
||||
the idmap child weren't requested at all and the caller
|
||||
sees ID_TYPE_NOT_SPECIFIED.
|
||||
|
||||
This module should have supported ID_TYPE_BOTH since
|
||||
samba-4.1.0, similar to idmap_rid and idmap_autorid.
|
||||
|
||||
Now that the winbindd parent will pass ID_TYPE_BOTH in order to
|
||||
indicate that the domain exists, it's better to always return
|
||||
ID_TYPE_BOTH instead of a random mix of ID_TYPE_UID, ID_TYPE_GID
|
||||
or ID_TYPE_BOTH. In order to request a type_hint it will return
|
||||
ID_REQUIRE_TYPE for ID_TYPE_NOT_SPECIFIED, which means that
|
||||
the parent at least assures that the domain sid exists.
|
||||
And the caller still gets ID_TYPE_NOT_SPECIFIED if the
|
||||
domain doesn't exist.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
|
||||
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
|
||||
Autobuild-Date(master): Fri Jan 22 11:32:46 UTC 2021 on sn-devel-184
|
||||
|
||||
(cherry picked from commit d8339056eef2845805f573bd8b0f3323370ecc8f)
|
||||
Reviewed-by: Ralph Boehme <slow@samba.org>
|
||||
|
||||
Autobuild-User(v4-14-test): Karolin Seeger <kseeger@samba.org>
|
||||
Autobuild-Date(v4-14-test): Wed Jan 27 17:06:51 UTC 2021 on sn-devel-184
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
(cherry picked from commit 99673b77b069674a6145552eb870de8829dfa503)
|
||||
---
|
||||
source3/winbindd/idmap_hash/idmap_hash.c | 35 ++++++++++++++++++++++++
|
||||
1 file changed, 35 insertions(+)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=4925a110c4e0586ca74566beca2450bbc4d18e4c
|
||||
|
||||
diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c
|
||||
index be0ba45a044..d0bed7631a6 100644
|
||||
--- a/source3/winbindd/idmap_hash/idmap_hash.c
|
||||
+++ b/source3/winbindd/idmap_hash/idmap_hash.c
|
||||
@@ -261,6 +261,25 @@ static NTSTATUS sids_to_unixids(struct idmap_domain *dom,
|
||||
|
||||
ids[i]->status = ID_UNMAPPED;
|
||||
|
||||
+ if (ids[i]->xid.type == ID_TYPE_NOT_SPECIFIED) {
|
||||
+ /*
|
||||
+ * idmap_hash used to bounce back the requested type,
|
||||
+ * which was ID_TYPE_UID, ID_TYPE_GID or
|
||||
+ * ID_TYPE_NOT_SPECIFIED before as the winbindd parent
|
||||
+ * always used a lookupsids. When the lookupsids
|
||||
+ * failed because of an unknown domain, the idmap child
|
||||
+ * weren't requested at all and the caller sees
|
||||
+ * ID_TYPE_NOT_SPECIFIED.
|
||||
+ *
|
||||
+ * Now that the winbindd parent will pass ID_TYPE_BOTH
|
||||
+ * in order to indicate that the domain exists.
|
||||
+ * We should ask the parent to fallback to lookupsids
|
||||
+ * if the domain is not known yet.
|
||||
+ */
|
||||
+ ids[i]->status = ID_REQUIRE_TYPE;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
sid_copy(&sid, ids[i]->sid);
|
||||
sid_split_rid(&sid, &rid);
|
||||
|
||||
@@ -270,6 +289,22 @@ static NTSTATUS sids_to_unixids(struct idmap_domain *dom,
|
||||
/* Check that both hashes are non-zero*/
|
||||
|
||||
if (h_domain && h_rid) {
|
||||
+ /*
|
||||
+ * idmap_hash used to bounce back the requested type,
|
||||
+ * which was ID_TYPE_UID, ID_TYPE_GID or
|
||||
+ * ID_TYPE_NOT_SPECIFIED before as the winbindd parent
|
||||
+ * always used a lookupsids.
|
||||
+ *
|
||||
+ * This module should have supported ID_TYPE_BOTH since
|
||||
+ * samba-4.1.0, similar to idmap_rid and idmap_autorid.
|
||||
+ *
|
||||
+ * Now that the winbindd parent will pass ID_TYPE_BOTH
|
||||
+ * in order to indicate that the domain exists, it's
|
||||
+ * better to always return ID_TYPE_BOTH instead of a
|
||||
+ * random mix of ID_TYPE_UID, ID_TYPE_GID or
|
||||
+ * ID_TYPE_BOTH.
|
||||
+ */
|
||||
+ ids[i]->xid.type = ID_TYPE_BOTH;
|
||||
ids[i]->xid.id = combine_hashes(h_domain, h_rid);
|
||||
ids[i]->status = ID_MAPPED;
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
117
backport-0007-CVE-2020-25718-Obtain-the-user.patch
Normal file
117
backport-0007-CVE-2020-25718-Obtain-the-user.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From 96ed96ea6a535185ecefeff6612e13f86d79de62 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Fri, 1 Oct 2021 11:09:48 +1300
|
||||
Subject: [PATCH 233/284] CVE-2020-25718 s4-rpc_server: Obtain the user
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=96ed96ea6a535185ecefeff6612e13f86d79de62
|
||||
|
||||
tokenGroups earlier
|
||||
|
||||
This will allow the creation of a common helper routine that
|
||||
takes the token SID list (from tokenGroups or struct auth_user_info_dc)
|
||||
and returns the allowed/denied result.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
---
|
||||
source4/rpc_server/drsuapi/getncchanges.c | 28 +++++++++----------
|
||||
source4/rpc_server/netlogon/dcerpc_netlogon.c | 28 +++++++++----------
|
||||
2 files changed, 28 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c
|
||||
index c7d2addd104d..bc30e73e06bf 100644
|
||||
--- a/source4/rpc_server/drsuapi/getncchanges.c
|
||||
+++ b/source4/rpc_server/drsuapi/getncchanges.c
|
||||
@@ -1282,6 +1282,20 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state,
|
||||
goto allowed;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * The SID list needs to include itself as well as the tokenGroups.
|
||||
+ *
|
||||
+ * TODO determine if sIDHistory is required for this check
|
||||
+ */
|
||||
+ werr = samdb_result_sid_array_ndr(b_state->sam_ctx_system, obj_res->msgs[0],
|
||||
+ mem_ctx, "tokenGroups",
|
||||
+ &num_token_sids,
|
||||
+ &token_sids,
|
||||
+ object_sid, 1);
|
||||
+ if (!W_ERROR_IS_OK(werr) || token_sids==NULL) {
|
||||
+ goto denied;
|
||||
+ }
|
||||
+
|
||||
/* but it isn't allowed to get anyone elses krbtgt secrets */
|
||||
if (samdb_result_dn(b_state->sam_ctx_system, mem_ctx,
|
||||
obj_res->msgs[0], "msDS-KrbTgtLinkBL", NULL)) {
|
||||
@@ -1310,20 +1324,6 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state,
|
||||
goto denied;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * The SID list needs to include itself as well as the tokenGroups.
|
||||
- *
|
||||
- * TODO determine if sIDHistory is required for this check
|
||||
- */
|
||||
- werr = samdb_result_sid_array_ndr(b_state->sam_ctx_system, obj_res->msgs[0],
|
||||
- mem_ctx, "tokenGroups",
|
||||
- &num_token_sids,
|
||||
- &token_sids,
|
||||
- object_sid, 1);
|
||||
- if (!W_ERROR_IS_OK(werr) || token_sids==NULL) {
|
||||
- goto denied;
|
||||
- }
|
||||
-
|
||||
if (never_reveal_sids &&
|
||||
sid_list_match(num_token_sids,
|
||||
token_sids,
|
||||
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
index c8dd0ceeb775..51c6666a1649 100644
|
||||
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
@@ -2872,6 +2872,20 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
|
||||
goto denied;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * The SID list needs to include itself as well as the tokenGroups.
|
||||
+ *
|
||||
+ * TODO determine if sIDHistory is required for this check
|
||||
+ */
|
||||
+ werr = samdb_result_sid_array_ndr(sam_ctx, obj_res->msgs[0],
|
||||
+ mem_ctx, "tokenGroups",
|
||||
+ &num_token_sids,
|
||||
+ &token_sids,
|
||||
+ object_sid, 1);
|
||||
+ if (!W_ERROR_IS_OK(werr) || token_sids==NULL) {
|
||||
+ goto denied;
|
||||
+ }
|
||||
+
|
||||
werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0],
|
||||
mem_ctx, "msDS-NeverRevealGroup",
|
||||
&num_never_reveal_sids,
|
||||
@@ -2888,20 +2902,6 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
|
||||
goto denied;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * The SID list needs to include itself as well as the tokenGroups.
|
||||
- *
|
||||
- * TODO determine if sIDHistory is required for this check
|
||||
- */
|
||||
- werr = samdb_result_sid_array_ndr(sam_ctx, obj_res->msgs[0],
|
||||
- mem_ctx, "tokenGroups",
|
||||
- &num_token_sids,
|
||||
- &token_sids,
|
||||
- object_sid, 1);
|
||||
- if (!W_ERROR_IS_OK(werr) || token_sids==NULL) {
|
||||
- goto denied;
|
||||
- }
|
||||
-
|
||||
if (never_reveal_sids &&
|
||||
sid_list_match(num_token_sids,
|
||||
token_sids,
|
||||
--
|
||||
2.25.1
|
||||
@ -0,0 +1,472 @@
|
||||
From ae9eb6c7d85deda7a20867eeecb8835defc1990a Mon Sep 17 00:00:00 2001
|
||||
From: Nadezhda Ivanova <nivanova@symas.com>
|
||||
Date: Mon, 18 Oct 2021 14:27:59 +0300
|
||||
Subject: [PATCH 136/266] CVE-2020-25722: s4-acl: Make sure Control Access
|
||||
Rights honor the Applies-to attribute
|
||||
|
||||
Validate Writes and Control Access Rights only grant access if the
|
||||
object is of the type listed in the Right's appliesTo attribute. For
|
||||
example, even though a Validated-SPN access may be granted to a user
|
||||
object in the SD, it should only pass if the object is of class
|
||||
computer This patch enforces the appliesTo attribute classes for
|
||||
access checks from within the ldb stack.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14832
|
||||
|
||||
Signed-off-by: Nadezhda Ivanova <nivanova@symas.com>
|
||||
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/ae9eb6c7d85deda7a20867eeecb8835defc1990a
|
||||
---
|
||||
source4/dsdb/common/util.c | 11 +++
|
||||
source4/dsdb/samdb/ldb_modules/acl.c | 87 +++++++++++++++++++----
|
||||
source4/dsdb/samdb/ldb_modules/acl_util.c | 40 +++++++++++
|
||||
source4/dsdb/samdb/ldb_modules/dirsync.c | 13 +++-
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 56 ++++++++-------
|
||||
6 files changed, 168 insertions(+), 40 deletions(-)
|
||||
delete mode 100644 selftest/knownfail.d/bug-14832
|
||||
|
||||
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
|
||||
index ef03782f588..62e04d08003 100644
|
||||
--- a/source4/dsdb/common/util.c
|
||||
+++ b/source4/dsdb/common/util.c
|
||||
@@ -1179,6 +1179,17 @@ struct ldb_dn *samdb_sites_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx)
|
||||
return new_dn;
|
||||
}
|
||||
|
||||
+struct ldb_dn *samdb_extended_rights_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx)
|
||||
+{
|
||||
+ struct ldb_dn *new_dn;
|
||||
+
|
||||
+ new_dn = ldb_dn_copy(mem_ctx, ldb_get_config_basedn(sam_ctx));
|
||||
+ if ( ! ldb_dn_add_child_fmt(new_dn, "CN=Extended-Rights")) {
|
||||
+ talloc_free(new_dn);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ return new_dn;
|
||||
+}
|
||||
/*
|
||||
work out the domain sid for the current open ldb
|
||||
*/
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
|
||||
index b1bbf936006..9cae15881de 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/acl.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
|
||||
@@ -698,7 +698,12 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx,
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module),
|
||||
+ ret = acl_check_extended_right(tmp_ctx,
|
||||
+ module,
|
||||
+ req,
|
||||
+ objectclass,
|
||||
+ sd,
|
||||
+ acl_user_token(module),
|
||||
GUID_DRS_VALIDATE_SPN,
|
||||
SEC_ADS_SELF_WRITE,
|
||||
sid);
|
||||
@@ -911,7 +916,7 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req)
|
||||
return ldb_next_request(module, req);
|
||||
}
|
||||
|
||||
-/* ckecks if modifications are allowed on "Member" attribute */
|
||||
+/* checks if modifications are allowed on "Member" attribute */
|
||||
static int acl_check_self_membership(TALLOC_CTX *mem_ctx,
|
||||
struct ldb_module *module,
|
||||
struct ldb_request *req,
|
||||
@@ -925,6 +930,16 @@ static int acl_check_self_membership(TALLOC_CTX *mem_ctx,
|
||||
struct ldb_context *ldb = ldb_module_get_ctx(module);
|
||||
struct ldb_dn *user_dn;
|
||||
struct ldb_message_element *member_el;
|
||||
+ const struct ldb_message *msg = NULL;
|
||||
+
|
||||
+ if (req->operation == LDB_MODIFY) {
|
||||
+ msg = req->op.mod.message;
|
||||
+ } else if (req->operation == LDB_ADD) {
|
||||
+ msg = req->op.add.message;
|
||||
+ } else {
|
||||
+ return LDB_ERR_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+
|
||||
/* if we have wp, we can do whatever we like */
|
||||
if (acl_check_access_on_attribute(module,
|
||||
mem_ctx,
|
||||
@@ -935,13 +950,13 @@ static int acl_check_self_membership(TALLOC_CTX *mem_ctx,
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
/* if we are adding/deleting ourselves, check for self membership */
|
||||
- ret = dsdb_find_dn_by_sid(ldb, mem_ctx,
|
||||
- &acl_user_token(module)->sids[PRIMARY_USER_SID_INDEX],
|
||||
+ ret = dsdb_find_dn_by_sid(ldb, mem_ctx,
|
||||
+ &acl_user_token(module)->sids[PRIMARY_USER_SID_INDEX],
|
||||
&user_dn);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
- member_el = ldb_msg_find_element(req->op.mod.message, "member");
|
||||
+ member_el = ldb_msg_find_element(msg, "member");
|
||||
if (!member_el) {
|
||||
return ldb_operr(ldb);
|
||||
}
|
||||
@@ -955,13 +970,18 @@ static int acl_check_self_membership(TALLOC_CTX *mem_ctx,
|
||||
return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
||||
}
|
||||
}
|
||||
- ret = acl_check_extended_right(mem_ctx, sd, acl_user_token(module),
|
||||
+ ret = acl_check_extended_right(mem_ctx,
|
||||
+ module,
|
||||
+ req,
|
||||
+ objectclass,
|
||||
+ sd,
|
||||
+ acl_user_token(module),
|
||||
GUID_DRS_SELF_MEMBERSHIP,
|
||||
SEC_ADS_SELF_WRITE,
|
||||
sid);
|
||||
if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
|
||||
dsdb_acl_debug(sd, acl_user_token(module),
|
||||
- req->op.mod.message->dn,
|
||||
+ msg->dn,
|
||||
true,
|
||||
10);
|
||||
}
|
||||
@@ -1021,6 +1041,9 @@ static int acl_check_password_rights(
|
||||
* so we don't have to strict verification of the input.
|
||||
*/
|
||||
ret = acl_check_extended_right(tmp_ctx,
|
||||
+ module,
|
||||
+ req,
|
||||
+ objectclass,
|
||||
sd,
|
||||
acl_user_token(module),
|
||||
GUID_DRS_USER_CHANGE_PASSWORD,
|
||||
@@ -1044,7 +1067,12 @@ static int acl_check_password_rights(
|
||||
* the only caller is samdb_set_password_internal(),
|
||||
* so we don't have to strict verification of the input.
|
||||
*/
|
||||
- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module),
|
||||
+ ret = acl_check_extended_right(tmp_ctx,
|
||||
+ module,
|
||||
+ req,
|
||||
+ objectclass,
|
||||
+ sd,
|
||||
+ acl_user_token(module),
|
||||
GUID_DRS_FORCE_CHANGE_PASSWORD,
|
||||
SEC_ADS_CONTROL_ACCESS,
|
||||
sid);
|
||||
@@ -1097,7 +1125,12 @@ static int acl_check_password_rights(
|
||||
if (rep_attr_cnt > 0) {
|
||||
pav->pwd_reset = true;
|
||||
|
||||
- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module),
|
||||
+ ret = acl_check_extended_right(tmp_ctx,
|
||||
+ module,
|
||||
+ req,
|
||||
+ objectclass,
|
||||
+ sd,
|
||||
+ acl_user_token(module),
|
||||
GUID_DRS_FORCE_CHANGE_PASSWORD,
|
||||
SEC_ADS_CONTROL_ACCESS,
|
||||
sid);
|
||||
@@ -1107,7 +1140,12 @@ static int acl_check_password_rights(
|
||||
if (add_attr_cnt != del_attr_cnt) {
|
||||
pav->pwd_reset = true;
|
||||
|
||||
- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module),
|
||||
+ ret = acl_check_extended_right(tmp_ctx,
|
||||
+ module,
|
||||
+ req,
|
||||
+ objectclass,
|
||||
+ sd,
|
||||
+ acl_user_token(module),
|
||||
GUID_DRS_FORCE_CHANGE_PASSWORD,
|
||||
SEC_ADS_CONTROL_ACCESS,
|
||||
sid);
|
||||
@@ -1117,7 +1155,12 @@ static int acl_check_password_rights(
|
||||
if (add_val_cnt == 1 && del_val_cnt == 1) {
|
||||
pav->pwd_reset = false;
|
||||
|
||||
- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module),
|
||||
+ ret = acl_check_extended_right(tmp_ctx,
|
||||
+ module,
|
||||
+ req,
|
||||
+ objectclass,
|
||||
+ sd,
|
||||
+ acl_user_token(module),
|
||||
GUID_DRS_USER_CHANGE_PASSWORD,
|
||||
SEC_ADS_CONTROL_ACCESS,
|
||||
sid);
|
||||
@@ -1131,7 +1174,12 @@ static int acl_check_password_rights(
|
||||
if (add_val_cnt == 1 && del_val_cnt == 0) {
|
||||
pav->pwd_reset = true;
|
||||
|
||||
- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module),
|
||||
+ ret = acl_check_extended_right(tmp_ctx,
|
||||
+ module,
|
||||
+ req,
|
||||
+ objectclass,
|
||||
+ sd,
|
||||
+ acl_user_token(module),
|
||||
GUID_DRS_FORCE_CHANGE_PASSWORD,
|
||||
SEC_ADS_CONTROL_ACCESS,
|
||||
sid);
|
||||
@@ -1686,6 +1734,9 @@ static int acl_check_reanimate_tombstone(TALLOC_CTX *mem_ctx,
|
||||
struct ldb_result *acl_res;
|
||||
struct security_descriptor *sd = NULL;
|
||||
struct dom_sid *sid = NULL;
|
||||
+ const struct dsdb_schema *schema = NULL;
|
||||
+ const struct dsdb_class *objectclass = NULL;
|
||||
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
|
||||
static const char *acl_attrs[] = {
|
||||
"nTSecurityDescriptor",
|
||||
"objectClass",
|
||||
@@ -1706,10 +1757,20 @@ static int acl_check_reanimate_tombstone(TALLOC_CTX *mem_ctx,
|
||||
|
||||
ret = dsdb_get_sd_from_ldb_message(mem_ctx, req, acl_res->msgs[0], &sd);
|
||||
sid = samdb_result_dom_sid(mem_ctx, acl_res->msgs[0], "objectSid");
|
||||
+ schema = dsdb_get_schema(ldb, req);
|
||||
+ if (!schema) {
|
||||
+ return LDB_ERR_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+ objectclass = dsdb_get_structural_oc_from_msg(schema, acl_res->msgs[0]);
|
||||
if (ret != LDB_SUCCESS || !sd) {
|
||||
return ldb_operr(ldb_module_get_ctx(module));
|
||||
}
|
||||
- return acl_check_extended_right(mem_ctx, sd, acl_user_token(module),
|
||||
+ return acl_check_extended_right(mem_ctx,
|
||||
+ module,
|
||||
+ req,
|
||||
+ objectclass,
|
||||
+ sd,
|
||||
+ acl_user_token(module),
|
||||
GUID_DRS_REANIMATE_TOMBSTONE,
|
||||
SEC_ADS_CONTROL_ACCESS, sid);
|
||||
}
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/acl_util.c b/source4/dsdb/samdb/ldb_modules/acl_util.c
|
||||
index f917d99517a..08a95c1c310 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/acl_util.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/acl_util.c
|
||||
@@ -197,6 +197,9 @@ fail:
|
||||
|
||||
/* checks for validated writes */
|
||||
int acl_check_extended_right(TALLOC_CTX *mem_ctx,
|
||||
+ struct ldb_module *module,
|
||||
+ struct ldb_request *req,
|
||||
+ const struct dsdb_class *objectclass,
|
||||
struct security_descriptor *sd,
|
||||
struct security_token *token,
|
||||
const char *ext_right,
|
||||
@@ -208,6 +211,43 @@ int acl_check_extended_right(TALLOC_CTX *mem_ctx,
|
||||
uint32_t access_granted;
|
||||
struct object_tree *root = NULL;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
|
||||
+ static const char *no_attrs[] = { NULL };
|
||||
+ struct ldb_result *extended_rights_res = NULL;
|
||||
+ struct ldb_dn *extended_rights_dn = NULL;
|
||||
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * Find the extended right and check if applies to
|
||||
+ * the objectclass of the object
|
||||
+ */
|
||||
+ extended_rights_dn = samdb_extended_rights_dn(ldb, req);
|
||||
+ if (!extended_rights_dn) {
|
||||
+ ldb_set_errstring(ldb,
|
||||
+ "access_check: CN=Extended-Rights dn could not be generated!");
|
||||
+ return LDB_ERR_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ /* Note: we are checking only the structural object class. */
|
||||
+ ret = dsdb_module_search(module, req, &extended_rights_res,
|
||||
+ extended_rights_dn, LDB_SCOPE_ONELEVEL,
|
||||
+ no_attrs,
|
||||
+ DSDB_FLAG_NEXT_MODULE |
|
||||
+ DSDB_FLAG_AS_SYSTEM,
|
||||
+ req,
|
||||
+ "(&(rightsGuid=%s)(appliesTo=%s))",
|
||||
+ ext_right,
|
||||
+ GUID_string(tmp_ctx,
|
||||
+ &(objectclass->schemaIDGUID)));
|
||||
+
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ } else if (extended_rights_res->count == 0 ) {
|
||||
+ ldb_debug(ldb, LDB_DEBUG_TRACE,
|
||||
+ "acl_check_extended_right: Could not find appliesTo for %s\n",
|
||||
+ ext_right);
|
||||
+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
||||
+ }
|
||||
|
||||
GUID_from_string(ext_right, &right);
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/dirsync.c b/source4/dsdb/samdb/ldb_modules/dirsync.c
|
||||
index 21555491159..a58e290607c 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/dirsync.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/dirsync.c
|
||||
@@ -1065,7 +1065,9 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req
|
||||
if (!(dirsync_ctl->flags & LDAP_DIRSYNC_OBJECT_SECURITY)) {
|
||||
struct dom_sid *sid;
|
||||
struct security_descriptor *sd = NULL;
|
||||
- const char *acl_attrs[] = { "nTSecurityDescriptor", "objectSid", NULL };
|
||||
+ const char *acl_attrs[] = { "nTSecurityDescriptor", "objectSid", "objectClass", NULL };
|
||||
+ const struct dsdb_schema *schema = NULL;
|
||||
+ const struct dsdb_class *objectclass = NULL;
|
||||
/*
|
||||
* If we don't have the flag and if we have the "replicate directory change" granted
|
||||
* then we upgrade ourself to system to not be blocked by the acl
|
||||
@@ -1095,7 +1097,14 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
- ret = acl_check_extended_right(dsc, sd, acl_user_token(module), GUID_DRS_GET_CHANGES, SEC_ADS_CONTROL_ACCESS, sid);
|
||||
+ schema = dsdb_get_schema(ldb, req);
|
||||
+ if (!schema) {
|
||||
+ return LDB_ERR_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+ objectclass = dsdb_get_structural_oc_from_msg(schema, acl_res->msgs[0]);
|
||||
+ ret = acl_check_extended_right(dsc, module, req, objectclass,
|
||||
+ sd, acl_user_token(module),
|
||||
+ GUID_DRS_GET_CHANGES, SEC_ADS_CONTROL_ACCESS, sid);
|
||||
|
||||
if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
|
||||
return ret;
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 5352af1099f..6db7840b0c1 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -2192,12 +2192,15 @@ static int samldb_check_user_account_control_objectclass_invariants(
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
-static int samldb_get_domain_secdesc(struct samldb_ctx *ac,
|
||||
- struct security_descriptor **domain_sd)
|
||||
+static int samldb_get_domain_secdesc_and_oc(struct samldb_ctx *ac,
|
||||
+ struct security_descriptor **domain_sd,
|
||||
+ const struct dsdb_class **objectclass)
|
||||
{
|
||||
- const char * const sd_attrs[] = {"ntSecurityDescriptor", NULL};
|
||||
+ const char * const sd_attrs[] = {"ntSecurityDescriptor", "objectClass", NULL};
|
||||
struct ldb_result *res;
|
||||
struct ldb_dn *domain_dn = ldb_get_default_basedn(ldb_module_get_ctx(ac->module));
|
||||
+ const struct dsdb_schema *schema = NULL;
|
||||
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
int ret = dsdb_module_search_dn(ac->module, ac, &res,
|
||||
domain_dn,
|
||||
sd_attrs,
|
||||
@@ -2210,6 +2213,11 @@ static int samldb_get_domain_secdesc(struct samldb_ctx *ac,
|
||||
return ldb_module_operr(ac->module);
|
||||
}
|
||||
|
||||
+ schema = dsdb_get_schema(ldb, ac->req);
|
||||
+ if (!schema) {
|
||||
+ return ldb_module_operr(ac->module);;
|
||||
+ }
|
||||
+ *objectclass = dsdb_get_structural_oc_from_msg(schema, res->msgs[0]);
|
||||
return dsdb_get_sd_from_ldb_message(ldb_module_get_ctx(ac->module),
|
||||
ac, res->msgs[0], domain_sd);
|
||||
|
||||
@@ -2228,6 +2236,7 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac,
|
||||
bool need_acl_check = false;
|
||||
struct security_token *user_token;
|
||||
struct security_descriptor *domain_sd;
|
||||
+ const struct dsdb_class *objectclass = NULL;
|
||||
const struct uac_to_guid {
|
||||
uint32_t uac;
|
||||
uint32_t priv_to_change_from;
|
||||
@@ -2313,7 +2322,7 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac,
|
||||
return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
||||
}
|
||||
|
||||
- ret = samldb_get_domain_secdesc(ac, &domain_sd);
|
||||
+ ret = samldb_get_domain_secdesc_and_oc(ac, &domain_sd, &objectclass);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
@@ -2344,7 +2353,11 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac,
|
||||
ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
||||
}
|
||||
} else if (map[i].guid) {
|
||||
- ret = acl_check_extended_right(ac, domain_sd,
|
||||
+ ret = acl_check_extended_right(ac,
|
||||
+ ac->module,
|
||||
+ ac->req,
|
||||
+ objectclass,
|
||||
+ domain_sd,
|
||||
user_token,
|
||||
map[i].guid,
|
||||
SEC_ADS_CONTROL_ACCESS,
|
||||
@@ -2684,12 +2697,11 @@ static int samldb_check_pwd_last_set_acl(struct samldb_ctx *ac,
|
||||
{
|
||||
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
int ret = 0;
|
||||
- struct ldb_result *res = NULL;
|
||||
- const char * const sd_attrs[] = {"ntSecurityDescriptor", NULL};
|
||||
struct security_token *user_token = NULL;
|
||||
struct security_descriptor *domain_sd = NULL;
|
||||
struct ldb_dn *domain_dn = ldb_get_default_basedn(ldb_module_get_ctx(ac->module));
|
||||
const char *operation = "";
|
||||
+ const struct dsdb_class *objectclass = NULL;
|
||||
|
||||
if (dsdb_module_am_system(ac->module)) {
|
||||
return LDB_SUCCESS;
|
||||
@@ -2711,24 +2723,15 @@ static int samldb_check_pwd_last_set_acl(struct samldb_ctx *ac,
|
||||
return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
||||
}
|
||||
|
||||
- ret = dsdb_module_search_dn(ac->module, ac, &res,
|
||||
- domain_dn,
|
||||
- sd_attrs,
|
||||
- DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED,
|
||||
- ac->req);
|
||||
- if (ret != LDB_SUCCESS) {
|
||||
- return ret;
|
||||
- }
|
||||
- if (res->count != 1) {
|
||||
- return ldb_module_operr(ac->module);
|
||||
- }
|
||||
-
|
||||
- ret = dsdb_get_sd_from_ldb_message(ldb, ac, res->msgs[0], &domain_sd);
|
||||
+ ret = samldb_get_domain_secdesc_and_oc(ac, &domain_sd, &objectclass);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
-
|
||||
- ret = acl_check_extended_right(ac, domain_sd,
|
||||
+ ret = acl_check_extended_right(ac,
|
||||
+ ac->module,
|
||||
+ ac->req,
|
||||
+ objectclass,
|
||||
+ domain_sd,
|
||||
user_token,
|
||||
GUID_DRS_UNEXPIRE_PASSWORD,
|
||||
SEC_ADS_CONTROL_ACCESS,
|
||||
@@ -3758,16 +3761,21 @@ static int samldb_check_sensitive_attributes(struct samldb_ctx *ac)
|
||||
el = ldb_msg_find_element(ac->msg, "msDS-SecondaryKrbTgtNumber");
|
||||
if (el) {
|
||||
struct security_descriptor *domain_sd;
|
||||
+ const struct dsdb_class *objectclass = NULL;
|
||||
/*
|
||||
* msDS-SecondaryKrbTgtNumber allows the creator to
|
||||
* become an RODC, this is trusted as an RODC
|
||||
* account
|
||||
*/
|
||||
- ret = samldb_get_domain_secdesc(ac, &domain_sd);
|
||||
+ ret = samldb_get_domain_secdesc_and_oc(ac, &domain_sd, &objectclass);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
- ret = acl_check_extended_right(ac, domain_sd,
|
||||
+ ret = acl_check_extended_right(ac,
|
||||
+ ac->module,
|
||||
+ ac->req,
|
||||
+ objectclass,
|
||||
+ domain_sd,
|
||||
user_token,
|
||||
GUID_DRS_DS_INSTALL_REPLICA,
|
||||
SEC_ADS_CONTROL_ACCESS,
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
From 4a68c748e47e906f0d812a1572168e677afc1eb4 Mon Sep 17 00:00:00 2001
|
||||
From: Ralph Boehme <slow@samba.org>
|
||||
Date: Tue, 31 Aug 2021 17:04:56 +0200
|
||||
Subject: [PATCH 030/266] CVE-2020-25717 winbindd: call
|
||||
wb_parent_idmap_setup_send() in wb_queryuser_send()
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14804
|
||||
|
||||
Signed-off-by: Ralph Boehme <slow@samba.org>
|
||||
Reviewed-by: Volker Lendecke <vl@samba.org>
|
||||
(cherry picked from commit 39c2ec72cb77945c3eb611fb1d7d7e9aad52bdfd)
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
(cherry picked from commit 7d1dd87a6538f8c7f1e4938b0ff52cbd231fff90)
|
||||
---
|
||||
source3/winbindd/wb_queryuser.c | 30 +++++++++++++++++++++++++++---
|
||||
1 file changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=4a68c748e47e906f0d812a1572168e677afc1eb4
|
||||
|
||||
diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c
|
||||
index 9db51909c02..f5bc96f03f6 100644
|
||||
--- a/source3/winbindd/wb_queryuser.c
|
||||
+++ b/source3/winbindd/wb_queryuser.c
|
||||
@@ -25,10 +25,12 @@
|
||||
|
||||
struct wb_queryuser_state {
|
||||
struct tevent_context *ev;
|
||||
- struct wbint_userinfo *info;
|
||||
+ struct wbint_userinfo *info;
|
||||
+ const struct wb_parent_idmap_config *idmap_cfg;
|
||||
bool tried_dclookup;
|
||||
};
|
||||
|
||||
+static void wb_queryuser_idmap_setup_done(struct tevent_req *subreq);
|
||||
static void wb_queryuser_got_uid(struct tevent_req *subreq);
|
||||
static void wb_queryuser_got_domain(struct tevent_req *subreq);
|
||||
static void wb_queryuser_got_dc(struct tevent_req *subreq);
|
||||
@@ -60,13 +62,35 @@ struct tevent_req *wb_queryuser_send(TALLOC_CTX *mem_ctx,
|
||||
|
||||
sid_copy(&info->user_sid, user_sid);
|
||||
|
||||
+ subreq = wb_parent_idmap_setup_send(state, state->ev);
|
||||
+ if (tevent_req_nomem(subreq, req)) {
|
||||
+ return tevent_req_post(req, ev);
|
||||
+ }
|
||||
+ tevent_req_set_callback(subreq, wb_queryuser_idmap_setup_done, req);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static void wb_queryuser_idmap_setup_done(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct tevent_req *req = tevent_req_callback_data(
|
||||
+ subreq, struct tevent_req);
|
||||
+ struct wb_queryuser_state *state = tevent_req_data(
|
||||
+ req, struct wb_queryuser_state);
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ status = wb_parent_idmap_setup_recv(subreq, &state->idmap_cfg);
|
||||
+ TALLOC_FREE(subreq);
|
||||
+ if (tevent_req_nterror(req, status)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
subreq = wb_sids2xids_send(
|
||||
state, state->ev, &state->info->user_sid, 1);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
- return tevent_req_post(req, ev);
|
||||
+ return;
|
||||
}
|
||||
tevent_req_set_callback(subreq, wb_queryuser_got_uid, req);
|
||||
- return req;
|
||||
+ return;
|
||||
}
|
||||
|
||||
static void wb_queryuser_got_uid(struct tevent_req *subreq)
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,195 @@
|
||||
From 43f321dce53fbc7865933041ba3c877b9ee5cb6c Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Fri, 1 Oct 2021 11:38:16 +1300
|
||||
Subject: [PATCH] CVE-2020-25718 s4-rpc_server: Put RODC reveal/never reveal
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=43f321dce53fbc7865933041ba3c877b9ee5cb6c
|
||||
|
||||
logic into a single helper function
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
---
|
||||
source4/rpc_server/common/sid_helper.c | 49 +++++++++++++++++++
|
||||
source4/rpc_server/drsuapi/getncchanges.c | 37 +++-----------
|
||||
source4/rpc_server/netlogon/dcerpc_netlogon.c | 38 +++-----------
|
||||
3 files changed, 63 insertions(+), 61 deletions(-)
|
||||
|
||||
diff --git a/source4/rpc_server/common/sid_helper.c b/source4/rpc_server/common/sid_helper.c
|
||||
index 65d7e7c7271..eaeab236fc0 100644
|
||||
--- a/source4/rpc_server/common/sid_helper.c
|
||||
+++ b/source4/rpc_server/common/sid_helper.c
|
||||
@@ -130,3 +130,52 @@ WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx,
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
+
|
||||
+WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ctx,
|
||||
+ struct ldb_message *rodc_msg,
|
||||
+ uint32_t num_token_sids,
|
||||
+ struct dom_sid *token_sids)
|
||||
+{
|
||||
+ uint32_t num_never_reveal_sids, num_reveal_sids;
|
||||
+ struct dom_sid *never_reveal_sids, *reveal_sids;
|
||||
+ TALLOC_CTX *frame = talloc_stackframe();
|
||||
+ WERROR werr = samdb_result_sid_array_dn(sam_ctx, rodc_msg,
|
||||
+ frame, "msDS-NeverRevealGroup",
|
||||
+ &num_never_reveal_sids,
|
||||
+ &never_reveal_sids);
|
||||
+ if (!W_ERROR_IS_OK(werr)) {
|
||||
+ TALLOC_FREE(frame);
|
||||
+ return WERR_DS_DRA_SECRETS_DENIED;
|
||||
+ }
|
||||
+
|
||||
+ werr = samdb_result_sid_array_dn(sam_ctx, rodc_msg,
|
||||
+ frame, "msDS-RevealOnDemandGroup",
|
||||
+ &num_reveal_sids,
|
||||
+ &reveal_sids);
|
||||
+ if (!W_ERROR_IS_OK(werr)) {
|
||||
+ TALLOC_FREE(frame);
|
||||
+ return WERR_DS_DRA_SECRETS_DENIED;
|
||||
+ }
|
||||
+
|
||||
+ if (never_reveal_sids &&
|
||||
+ sid_list_match(num_token_sids,
|
||||
+ token_sids,
|
||||
+ num_never_reveal_sids,
|
||||
+ never_reveal_sids)) {
|
||||
+ TALLOC_FREE(frame);
|
||||
+ return WERR_DS_DRA_SECRETS_DENIED;
|
||||
+ }
|
||||
+
|
||||
+ if (reveal_sids &&
|
||||
+ sid_list_match(num_token_sids,
|
||||
+ token_sids,
|
||||
+ num_reveal_sids,
|
||||
+ reveal_sids)) {
|
||||
+ TALLOC_FREE(frame);
|
||||
+ return WERR_OK;
|
||||
+ }
|
||||
+
|
||||
+ TALLOC_FREE(frame);
|
||||
+ return WERR_DS_DRA_SECRETS_DENIED;
|
||||
+
|
||||
+}
|
||||
diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c
|
||||
index bc30e73e06b..3b1d674573f 100644
|
||||
--- a/source4/rpc_server/drsuapi/getncchanges.c
|
||||
+++ b/source4/rpc_server/drsuapi/getncchanges.c
|
||||
@@ -1171,8 +1171,8 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state,
|
||||
const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", "objectGUID", NULL };
|
||||
const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL };
|
||||
struct ldb_result *rodc_res = NULL, *obj_res = NULL;
|
||||
- uint32_t num_never_reveal_sids, num_reveal_sids, num_token_sids;
|
||||
- struct dom_sid *never_reveal_sids, *reveal_sids, *token_sids;
|
||||
+ uint32_t num_token_sids;
|
||||
+ struct dom_sid *token_sids;
|
||||
const struct dom_sid *object_sid = NULL;
|
||||
WERROR werr;
|
||||
|
||||
@@ -1308,35 +1308,12 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state,
|
||||
goto denied;
|
||||
}
|
||||
|
||||
- werr = samdb_result_sid_array_dn(b_state->sam_ctx_system, rodc_res->msgs[0],
|
||||
- mem_ctx, "msDS-NeverRevealGroup",
|
||||
- &num_never_reveal_sids,
|
||||
- &never_reveal_sids);
|
||||
- if (!W_ERROR_IS_OK(werr)) {
|
||||
- goto denied;
|
||||
- }
|
||||
-
|
||||
- werr = samdb_result_sid_array_dn(b_state->sam_ctx_system, rodc_res->msgs[0],
|
||||
- mem_ctx, "msDS-RevealOnDemandGroup",
|
||||
- &num_reveal_sids,
|
||||
- &reveal_sids);
|
||||
- if (!W_ERROR_IS_OK(werr)) {
|
||||
- goto denied;
|
||||
- }
|
||||
-
|
||||
- if (never_reveal_sids &&
|
||||
- sid_list_match(num_token_sids,
|
||||
- token_sids,
|
||||
- num_never_reveal_sids,
|
||||
- never_reveal_sids)) {
|
||||
- goto denied;
|
||||
- }
|
||||
+ werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(b_state->sam_ctx_system,
|
||||
+ rodc_res->msgs[0],
|
||||
+ num_token_sids,
|
||||
+ token_sids);
|
||||
|
||||
- if (reveal_sids &&
|
||||
- sid_list_match(num_token_sids,
|
||||
- token_sids,
|
||||
- num_reveal_sids,
|
||||
- reveal_sids)) {
|
||||
+ if (W_ERROR_IS_OK(werr)) {
|
||||
goto allowed;
|
||||
}
|
||||
|
||||
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
index 51c6666a164..1aecd65bb61 100644
|
||||
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
@@ -2852,8 +2852,8 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
|
||||
struct ldb_result *rodc_res = NULL, *obj_res = NULL;
|
||||
WERROR werr;
|
||||
struct dom_sid *object_sid;
|
||||
- uint32_t num_never_reveal_sids, num_reveal_sids, num_token_sids;
|
||||
- struct dom_sid *never_reveal_sids, *reveal_sids, *token_sids;
|
||||
+ uint32_t num_token_sids;
|
||||
+ struct dom_sid *token_sids;
|
||||
|
||||
rodc_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
|
||||
dom_sid_string(mem_ctx, user_sid));
|
||||
@@ -2886,38 +2886,14 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
|
||||
goto denied;
|
||||
}
|
||||
|
||||
- werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0],
|
||||
- mem_ctx, "msDS-NeverRevealGroup",
|
||||
- &num_never_reveal_sids,
|
||||
- &never_reveal_sids);
|
||||
- if (!W_ERROR_IS_OK(werr)) {
|
||||
- goto denied;
|
||||
- }
|
||||
-
|
||||
- werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0],
|
||||
- mem_ctx, "msDS-RevealOnDemandGroup",
|
||||
- &num_reveal_sids,
|
||||
- &reveal_sids);
|
||||
- if (!W_ERROR_IS_OK(werr)) {
|
||||
- goto denied;
|
||||
- }
|
||||
+ werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(sam_ctx,
|
||||
+ rodc_res->msgs[0],
|
||||
+ num_token_sids,
|
||||
+ token_sids);
|
||||
|
||||
- if (never_reveal_sids &&
|
||||
- sid_list_match(num_token_sids,
|
||||
- token_sids,
|
||||
- num_never_reveal_sids,
|
||||
- never_reveal_sids)) {
|
||||
- goto denied;
|
||||
- }
|
||||
-
|
||||
- if (reveal_sids &&
|
||||
- sid_list_match(num_token_sids,
|
||||
- token_sids,
|
||||
- num_reveal_sids,
|
||||
- reveal_sids)) {
|
||||
+ if (W_ERROR_IS_OK(werr)) {
|
||||
goto allowed;
|
||||
}
|
||||
-
|
||||
denied:
|
||||
return false;
|
||||
allowed:
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@ -0,0 +1,97 @@
|
||||
From f1c64ed29ea0911beaa1cd3b80915ef5b44085af Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Mon, 1 Nov 2021 17:19:29 +1300
|
||||
Subject: [PATCH 137/266] CVE-2020-25722 Check all elements in acl_check_spn()
|
||||
not just the first one
|
||||
|
||||
Thankfully we are aleady in a loop over all the message elements in
|
||||
acl_modify() so this is an easy and safe change to make.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/f1c64ed29ea0911beaa1cd3b80915ef5b44085af
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/acl.c | 31 +++++++++++++++++++++-------
|
||||
1 files changed, 23 insertions(+), 8 deletions(-)
|
||||
delete mode 100644 selftest/knownfail.d/acl-spn
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
|
||||
index 9cae15881de..d0b3da4d9e8 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/acl.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
|
||||
@@ -653,9 +653,14 @@ success:
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Passing in 'el' is critical, we want to check all the values.
|
||||
+ *
|
||||
+ */
|
||||
static int acl_check_spn(TALLOC_CTX *mem_ctx,
|
||||
struct ldb_module *module,
|
||||
struct ldb_request *req,
|
||||
+ const struct ldb_message_element *el,
|
||||
struct security_descriptor *sd,
|
||||
struct dom_sid *sid,
|
||||
const struct dsdb_attribute *attr,
|
||||
@@ -667,7 +672,6 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx,
|
||||
struct ldb_context *ldb = ldb_module_get_ctx(module);
|
||||
struct ldb_result *acl_res;
|
||||
struct ldb_result *netbios_res;
|
||||
- struct ldb_message_element *el;
|
||||
struct ldb_dn *partitions_dn = samdb_partitions_dn(ldb, tmp_ctx);
|
||||
uint32_t userAccountControl;
|
||||
const char *samAccountName;
|
||||
@@ -717,6 +721,23 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * If we have "validated write spn", allow delete of any
|
||||
+ * existing value (this keeps constrained delete to the same
|
||||
+ * rules as unconstrained)
|
||||
+ */
|
||||
+ if (req->operation == LDB_MODIFY) {
|
||||
+ /*
|
||||
+ * If not add or replace (eg delete),
|
||||
+ * return success
|
||||
+ */
|
||||
+ if ((el->flags
|
||||
+ & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE)) == 0) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
ret = dsdb_module_search_dn(module, tmp_ctx,
|
||||
&acl_res, req->op.mod.message->dn,
|
||||
acl_attrs,
|
||||
@@ -745,13 +766,6 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx,
|
||||
|
||||
netbios_name = ldb_msg_find_attr_as_string(netbios_res->msgs[0], "nETBIOSName", NULL);
|
||||
|
||||
- el = ldb_msg_find_element(req->op.mod.message, "servicePrincipalName");
|
||||
- if (!el) {
|
||||
- talloc_free(tmp_ctx);
|
||||
- return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR,
|
||||
- "Error finding element for servicePrincipalName.");
|
||||
- }
|
||||
-
|
||||
/* NTDSDSA objectGuid of object we are checking SPN for */
|
||||
if (userAccountControl & (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) {
|
||||
ret = dsdb_module_find_ntdsguid_for_computer(module, tmp_ctx,
|
||||
@@ -1510,6 +1524,7 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req)
|
||||
ret = acl_check_spn(tmp_ctx,
|
||||
module,
|
||||
req,
|
||||
+ el,
|
||||
sd,
|
||||
sid,
|
||||
attr,
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,109 @@
|
||||
From 4a39d8a1610b635760ac182be894d206eb0a1ee7 Mon Sep 17 00:00:00 2001
|
||||
From: Ralph Boehme <slow@samba.org>
|
||||
Date: Fri, 20 Aug 2021 15:04:49 +0200
|
||||
Subject: [PATCH 031/266] CVE-2020-25717 winbind: ensure
|
||||
wb_parent_idmap_setup_send() gets called in winbindd_allocate_uid_send()
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14804
|
||||
RN: winbindd can crash because idmap child state is not fully initialized
|
||||
|
||||
Signed-off-by: Ralph Boehme <slow@samba.org>
|
||||
Reviewed-by: Volker Lendecke <vl@samba.org>
|
||||
|
||||
Autobuild-User(master): Volker Lendecke <vl@samba.org>
|
||||
Autobuild-Date(master): Thu Sep 2 15:20:06 UTC 2021 on sn-devel-184
|
||||
|
||||
(cherry picked from commit d0f6d54354b02f5591706814fbd1e4844788fdfa)
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
(cherry picked from commit 446f89510f2e55a551e2975a6cbf01c6a023ba0c)
|
||||
---
|
||||
source3/winbindd/winbindd_allocate_uid.c | 44 +++++++++++++++++++++---
|
||||
1 file changed, 39 insertions(+), 5 deletions(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=4a39d8a1610b635760ac182be894d206eb0a1ee7
|
||||
|
||||
diff --git a/source3/winbindd/winbindd_allocate_uid.c b/source3/winbindd/winbindd_allocate_uid.c
|
||||
index 69ce61c872e..64711f1b661 100644
|
||||
--- a/source3/winbindd/winbindd_allocate_uid.c
|
||||
+++ b/source3/winbindd/winbindd_allocate_uid.c
|
||||
@@ -22,9 +22,11 @@
|
||||
#include "librpc/gen_ndr/ndr_winbind_c.h"
|
||||
|
||||
struct winbindd_allocate_uid_state {
|
||||
+ struct tevent_context *ev;
|
||||
uint64_t uid;
|
||||
};
|
||||
|
||||
+static void winbindd_allocate_uid_initialized(struct tevent_req *subreq);
|
||||
static void winbindd_allocate_uid_done(struct tevent_req *subreq);
|
||||
|
||||
struct tevent_req *winbindd_allocate_uid_send(TALLOC_CTX *mem_ctx,
|
||||
@@ -34,25 +36,57 @@ struct tevent_req *winbindd_allocate_uid_send(TALLOC_CTX *mem_ctx,
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct winbindd_allocate_uid_state *state;
|
||||
- struct dcerpc_binding_handle *child_binding_handle = NULL;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct winbindd_allocate_uid_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
+ state->ev = ev;
|
||||
|
||||
DEBUG(3, ("allocate_uid\n"));
|
||||
|
||||
- child_binding_handle = idmap_child_handle();
|
||||
+ subreq = wb_parent_idmap_setup_send(state, ev);
|
||||
+ if (tevent_req_nomem(subreq, req)) {
|
||||
+ return tevent_req_post(req, ev);
|
||||
+ }
|
||||
+ tevent_req_set_callback(subreq, winbindd_allocate_uid_initialized, req);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static void winbindd_allocate_uid_initialized(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct tevent_req *req = tevent_req_callback_data(
|
||||
+ subreq, struct tevent_req);
|
||||
+ struct dcerpc_binding_handle *child_binding_handle = NULL;
|
||||
+ struct winbindd_allocate_uid_state *state = tevent_req_data(
|
||||
+ req, struct winbindd_allocate_uid_state);
|
||||
+ const struct wb_parent_idmap_config *cfg = NULL;
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ status = wb_parent_idmap_setup_recv(subreq, &cfg);
|
||||
+ TALLOC_FREE(subreq);
|
||||
+ if (tevent_req_nterror(req, status)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (cfg->num_doms == 0) {
|
||||
+ /*
|
||||
+ * idmap_tdb also returns UNSUCCESSFUL if a range is full
|
||||
+ */
|
||||
+ tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ child_binding_handle = idmap_child_handle();
|
||||
|
||||
- subreq = dcerpc_wbint_AllocateUid_send(state, ev, child_binding_handle,
|
||||
+ subreq = dcerpc_wbint_AllocateUid_send(state,
|
||||
+ state->ev,
|
||||
+ child_binding_handle,
|
||||
&state->uid);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
- return tevent_req_post(req, ev);
|
||||
+ return;
|
||||
}
|
||||
tevent_req_set_callback(subreq, winbindd_allocate_uid_done, req);
|
||||
- return req;
|
||||
}
|
||||
|
||||
static void winbindd_allocate_uid_done(struct tevent_req *subreq)
|
||||
--
|
||||
2.23.0
|
||||
|
||||
110
backport-0009-CVE-2020-25718-Put-msDS-KrbTgtLinkBL.patch
Normal file
110
backport-0009-CVE-2020-25718-Put-msDS-KrbTgtLinkBL.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From f83e48a60bee40e5a20ed8281aca97906d047639 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Fri, 1 Oct 2021 11:55:11 +1300
|
||||
Subject: [PATCH 235/284] CVE-2020-25718 s4-rpc_server: Put msDS-KrbTgtLinkBL
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=f83e48a60bee40e5a20ed8281aca97906d047639
|
||||
|
||||
and UF_INTERDOMAIN_TRUST_ACCOUNT RODC checks in common
|
||||
|
||||
While these checks were not in the NETLOGON case, there is no sense where
|
||||
an RODC should be resetting a bad password count on either a
|
||||
UF_INTERDOMAIN_TRUST_ACCOUNT nor a RODC krbtgt account.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
---
|
||||
source4/rpc_server/common/sid_helper.c | 29 ++++++++++++++++---
|
||||
source4/rpc_server/drsuapi/getncchanges.c | 13 +--------
|
||||
source4/rpc_server/netlogon/dcerpc_netlogon.c | 1 +
|
||||
3 files changed, 27 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/source4/rpc_server/common/sid_helper.c b/source4/rpc_server/common/sid_helper.c
|
||||
index eaeab236fc01..ab2b4373b473 100644
|
||||
--- a/source4/rpc_server/common/sid_helper.c
|
||||
+++ b/source4/rpc_server/common/sid_helper.c
|
||||
@@ -133,16 +133,37 @@ WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx,
|
||||
|
||||
WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ctx,
|
||||
struct ldb_message *rodc_msg,
|
||||
+ struct ldb_message *obj_msg,
|
||||
uint32_t num_token_sids,
|
||||
struct dom_sid *token_sids)
|
||||
{
|
||||
uint32_t num_never_reveal_sids, num_reveal_sids;
|
||||
struct dom_sid *never_reveal_sids, *reveal_sids;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
- WERROR werr = samdb_result_sid_array_dn(sam_ctx, rodc_msg,
|
||||
- frame, "msDS-NeverRevealGroup",
|
||||
- &num_never_reveal_sids,
|
||||
- &never_reveal_sids);
|
||||
+ WERROR werr;
|
||||
+
|
||||
+ /*
|
||||
+ * We are not allowed to get anyone elses krbtgt secrets (and
|
||||
+ * in callers that don't shortcut before this, the RODC should
|
||||
+ * not deal with any krbtgt)
|
||||
+ */
|
||||
+ if (samdb_result_dn(sam_ctx, frame,
|
||||
+ obj_msg, "msDS-KrbTgtLinkBL", NULL)) {
|
||||
+ TALLOC_FREE(frame);
|
||||
+ return WERR_DS_DRA_SECRETS_DENIED;
|
||||
+ }
|
||||
+
|
||||
+ if (ldb_msg_find_attr_as_uint(obj_msg,
|
||||
+ "userAccountControl", 0) &
|
||||
+ UF_INTERDOMAIN_TRUST_ACCOUNT) {
|
||||
+ TALLOC_FREE(frame);
|
||||
+ return WERR_DS_DRA_SECRETS_DENIED;
|
||||
+ }
|
||||
+
|
||||
+ werr = samdb_result_sid_array_dn(sam_ctx, rodc_msg,
|
||||
+ frame, "msDS-NeverRevealGroup",
|
||||
+ &num_never_reveal_sids,
|
||||
+ &never_reveal_sids);
|
||||
if (!W_ERROR_IS_OK(werr)) {
|
||||
TALLOC_FREE(frame);
|
||||
return WERR_DS_DRA_SECRETS_DENIED;
|
||||
diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c
|
||||
index 3b1d674573ff..a9d305fc9a05 100644
|
||||
--- a/source4/rpc_server/drsuapi/getncchanges.c
|
||||
+++ b/source4/rpc_server/drsuapi/getncchanges.c
|
||||
@@ -1296,20 +1296,9 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state,
|
||||
goto denied;
|
||||
}
|
||||
|
||||
- /* but it isn't allowed to get anyone elses krbtgt secrets */
|
||||
- if (samdb_result_dn(b_state->sam_ctx_system, mem_ctx,
|
||||
- obj_res->msgs[0], "msDS-KrbTgtLinkBL", NULL)) {
|
||||
- goto denied;
|
||||
- }
|
||||
-
|
||||
- if (ldb_msg_find_attr_as_uint(obj_res->msgs[0],
|
||||
- "userAccountControl", 0) &
|
||||
- UF_INTERDOMAIN_TRUST_ACCOUNT) {
|
||||
- goto denied;
|
||||
- }
|
||||
-
|
||||
werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(b_state->sam_ctx_system,
|
||||
rodc_res->msgs[0],
|
||||
+ obj_res->msgs[0],
|
||||
num_token_sids,
|
||||
token_sids);
|
||||
|
||||
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
index 1aecd65bb618..92dd693ddcc1 100644
|
||||
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
@@ -2888,6 +2888,7 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
|
||||
|
||||
werr = samdb_confirm_rodc_allowed_to_repl_to_sid_list(sam_ctx,
|
||||
rodc_res->msgs[0],
|
||||
+ obj_res->msgs[0],
|
||||
num_token_sids,
|
||||
token_sids);
|
||||
|
||||
--
|
||||
2.25.1
|
||||
@ -0,0 +1,35 @@
|
||||
From ef7f582772a6c621205fd16a8a7f2b826b7397d7 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Mon, 1 Nov 2021 17:21:16 +1300
|
||||
Subject: [PATCH 138/266] CVE-2020-25722 Check for all errors from
|
||||
acl_check_extended_right() in acl_check_spn()
|
||||
|
||||
We should not fail open on error.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/ef7f582772a6c621205fd16a8a7f2b826b7397d7
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/acl.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
|
||||
index d0b3da4d9e8..712724909e3 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/acl.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
|
||||
@@ -712,7 +712,7 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx,
|
||||
SEC_ADS_SELF_WRITE,
|
||||
sid);
|
||||
|
||||
- if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
dsdb_acl_debug(sd, acl_user_token(module),
|
||||
req->op.mod.message->dn,
|
||||
true,
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,228 @@
|
||||
From eb4123b5caed6c5cbfe8ef050f198e2d5a03f8b7 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <ab@samba.org>
|
||||
Date: Wed, 11 Nov 2020 14:42:55 +0200
|
||||
Subject: [PATCH 032/266] CVE-2020-25717 auth_sam: use pdb_get_domain_info to
|
||||
look up DNS forest information
|
||||
|
||||
When Samba is used as a part of FreeIPA domain controller, Windows
|
||||
clients for a trusted AD forest may try to authenticate (perform logon
|
||||
operation) as a REALM\name user account.
|
||||
|
||||
Fix auth_sam plugins to accept DNS forest name if we are running on a DC
|
||||
with PASSDB module providing domain information (e.g. pdb_get_domain_info()
|
||||
returning non-NULL structure). Right now, only FreeIPA or Samba AD DC
|
||||
PASSDB backends return this information but Samba AD DC configuration is
|
||||
explicitly ignored by the two auth_sam (strict and netlogon3) modules.
|
||||
|
||||
Detailed logs below:
|
||||
|
||||
[2020/11/11 09:23:53.281296, 1, pid=42677, effective(65534, 65534), real(65534, 0), class=rpc_parse] ../../librpc/ndr/ndr.c:482(ndr_print_function_debug)
|
||||
netr_LogonSamLogonWithFlags: struct netr_LogonSamLogonWithFlags
|
||||
in: struct netr_LogonSamLogonWithFlags
|
||||
server_name : *
|
||||
server_name : '\\master.ipa.test'
|
||||
computer_name : *
|
||||
computer_name : 'AD1'
|
||||
credential : *
|
||||
credential: struct netr_Authenticator
|
||||
cred: struct netr_Credential
|
||||
data : 529f4b087c5f6546
|
||||
timestamp : Wed Nov 11 09:23:55 AM 2020 UTC
|
||||
return_authenticator : *
|
||||
return_authenticator: struct netr_Authenticator
|
||||
cred: struct netr_Credential
|
||||
data : 204f28f622010000
|
||||
timestamp : Fri May 2 06:37:50 AM 1986 UTC
|
||||
logon_level : NetlogonNetworkTransitiveInformation (6)
|
||||
logon : *
|
||||
logon : union netr_LogonLevel(case 6)
|
||||
network : *
|
||||
network: struct netr_NetworkInfo
|
||||
identity_info: struct netr_IdentityInfo
|
||||
domain_name: struct lsa_String
|
||||
length : 0x0010 (16)
|
||||
size : 0x01fe (510)
|
||||
string : *
|
||||
string : 'IPA.TEST'
|
||||
parameter_control : 0x00002ae0 (10976)
|
||||
0: MSV1_0_CLEARTEXT_PASSWORD_ALLOWED
|
||||
0: MSV1_0_UPDATE_LOGON_STATISTICS
|
||||
0: MSV1_0_RETURN_USER_PARAMETERS
|
||||
0: MSV1_0_DONT_TRY_GUEST_ACCOUNT
|
||||
1: MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
|
||||
1: MSV1_0_RETURN_PASSWORD_EXPIRY
|
||||
1: MSV1_0_USE_CLIENT_CHALLENGE
|
||||
0: MSV1_0_TRY_GUEST_ACCOUNT_ONLY
|
||||
1: MSV1_0_RETURN_PROFILE_PATH
|
||||
0: MSV1_0_TRY_SPECIFIED_DOMAIN_ONLY
|
||||
1: MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
|
||||
0: MSV1_0_DISABLE_PERSONAL_FALLBACK
|
||||
1: MSV1_0_ALLOW_FORCE_GUEST
|
||||
0: MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED
|
||||
0: MSV1_0_USE_DOMAIN_FOR_ROUTING_ONLY
|
||||
0: MSV1_0_ALLOW_MSVCHAPV2
|
||||
0: MSV1_0_S4U2SELF
|
||||
0: MSV1_0_CHECK_LOGONHOURS_FOR_S4U
|
||||
0: MSV1_0_SUBAUTHENTICATION_DLL_EX
|
||||
logon_id : 0x0000000000884ef2 (8933106)
|
||||
account_name: struct lsa_String
|
||||
length : 0x000e (14)
|
||||
size : 0x000e (14)
|
||||
string : *
|
||||
string : 'idmuser'
|
||||
workstation: struct lsa_String
|
||||
length : 0x0000 (0)
|
||||
size : 0x0000 (0)
|
||||
string : *
|
||||
string : ''
|
||||
challenge : 417207867bd33c74
|
||||
nt: struct netr_ChallengeResponse
|
||||
length : 0x00c0 (192)
|
||||
size : 0x00c0 (192)
|
||||
data : *
|
||||
data: ARRAY(192)
|
||||
[0000] A5 24 62 6E 31 DF 69 66 9E DC 54 D6 63 4C D6 2F .$bn1.if ..T.cL./
|
||||
[0010] 01 01 00 00 00 00 00 00 50 37 D7 60 0C B8 D6 01 ........ P7.`....
|
||||
[0020] 15 1B 38 4F 47 95 4D 62 00 00 00 00 02 00 0E 00 ..8OG.Mb ........
|
||||
[0030] 57 00 49 00 4E 00 32 00 30 00 31 00 36 00 01 00 W.I.N.2. 0.1.6...
|
||||
[0040] 06 00 41 00 44 00 31 00 04 00 18 00 77 00 69 00 ..A.D.1. ....w.i.
|
||||
[0050] 6E 00 32 00 30 00 31 00 36 00 2E 00 74 00 65 00 n.2.0.1. 6...t.e.
|
||||
[0060] 73 00 74 00 03 00 20 00 61 00 64 00 31 00 2E 00 s.t... . a.d.1...
|
||||
[0070] 77 00 69 00 6E 00 32 00 30 00 31 00 36 00 2E 00 w.i.n.2. 0.1.6...
|
||||
[0080] 74 00 65 00 73 00 74 00 05 00 18 00 77 00 69 00 t.e.s.t. ....w.i.
|
||||
[0090] 6E 00 32 00 30 00 31 00 36 00 2E 00 74 00 65 00 n.2.0.1. 6...t.e.
|
||||
[00A0] 73 00 74 00 07 00 08 00 50 37 D7 60 0C B8 D6 01 s.t..... P7.`....
|
||||
[00B0] 06 00 04 00 02 00 00 00 00 00 00 00 00 00 00 00 ........ ........
|
||||
lm: struct netr_ChallengeResponse
|
||||
length : 0x0018 (24)
|
||||
size : 0x0018 (24)
|
||||
data : *
|
||||
data : 000000000000000000000000000000000000000000000000
|
||||
validation_level : 0x0006 (6)
|
||||
flags : *
|
||||
flags : 0x00000000 (0)
|
||||
0: NETLOGON_SAMLOGON_FLAG_PASS_TO_FOREST_ROOT
|
||||
0: NETLOGON_SAMLOGON_FLAG_PASS_CROSS_FOREST_HOP
|
||||
0: NETLOGON_SAMLOGON_FLAG_RODC_TO_OTHER_DOMAIN
|
||||
0: NETLOGON_SAMLOGON_FLAG_RODC_NTLM_REQUEST
|
||||
|
||||
In such case checks for a workgroup name will not match the DNS forest
|
||||
name used in the username specification:
|
||||
|
||||
[2020/11/11 09:23:53.283055, 3, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:200(auth_check_ntlm_password)
|
||||
check_ntlm_password: Checking password for unmapped user [IPA.TEST]\[idmuser]@[] with the new password interface
|
||||
[2020/11/11 09:23:53.283073, 3, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:203(auth_check_ntlm_password)
|
||||
check_ntlm_password: mapped user is: [IPA.TEST]\[idmuser]@[]
|
||||
[2020/11/11 09:23:53.283082, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:213(auth_check_ntlm_password)
|
||||
check_ntlm_password: auth_context challenge created by fixed
|
||||
[2020/11/11 09:23:53.283091, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:216(auth_check_ntlm_password)
|
||||
challenge is:
|
||||
[2020/11/11 09:23:53.283099, 5, pid=42677, effective(65534, 65534), real(65534, 0)] ../../lib/util/util.c:678(dump_data)
|
||||
[0000] 41 72 07 86 7B D3 3C 74 Ar..{.<t
|
||||
[2020/11/11 09:23:53.283113, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth_sam.c:209(auth_sam_netlogon3_auth)
|
||||
auth_sam_netlogon3_auth: Check auth for: [IPA.TEST]\[idmuser]
|
||||
[2020/11/11 09:23:53.283123, 5, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth_sam.c:234(auth_sam_netlogon3_auth)
|
||||
auth_sam_netlogon3_auth: IPA.TEST is not our domain name (DC for IPA)
|
||||
[2020/11/11 09:23:53.283131, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:249(auth_check_ntlm_password)
|
||||
auth_check_ntlm_password: sam_netlogon3 had nothing to say
|
||||
|
||||
and overall authentication attempt will fail: auth_winbind will complain
|
||||
that this domain is not a trusted one and refuse operating on it:
|
||||
|
||||
[2020/11/11 09:23:53.283784, 10, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd.c:742(process_request_send)
|
||||
process_request_send: process_request: Handling async request smbd(42677):PAM_AUTH_CRAP
|
||||
[2020/11/11 09:23:53.283796, 3, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd_pam_auth_crap.c:110(winbindd_pam_auth_crap_send)
|
||||
[42677]: pam auth crap domain: [IPA.TEST] user: idmuser
|
||||
[2020/11/11 09:23:53.283810, 3, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd_pam.c:409(find_auth_domain)
|
||||
Authentication for domain [IPA.TEST] refused as it is not a trusted domain
|
||||
[2020/11/11 09:23:53.283825, 10, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd.c:810(process_request_done)
|
||||
process_request_done: [smbd(42677):PAM_AUTH_CRAP]: NT_STATUS_NO_SUCH_USER
|
||||
[2020/11/11 09:23:53.283844, 10, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd.c:855(process_request_written)
|
||||
process_request_written: [smbd(42677):PAM_AUTH_CRAP]: delivered response to client
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <ab@samba.org>
|
||||
Reviewed-by: Andreas Schneider <asn@samba.org>
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
(cherry picked from commit 2a8b672652dcbcf55ec59be537773d76f0f14d0a)
|
||||
---
|
||||
source3/auth/auth_sam.c | 45 +++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 41 insertions(+), 4 deletions(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=eb4123b5caed6c5cbfe8ef050f198e2d5a03f8b7
|
||||
|
||||
diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
|
||||
index 3c12f959faf..e8e0d543f8c 100644
|
||||
--- a/source3/auth/auth_sam.c
|
||||
+++ b/source3/auth/auth_sam.c
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "auth.h"
|
||||
+#include "passdb.h"
|
||||
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_AUTH
|
||||
@@ -142,10 +143,28 @@ static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context,
|
||||
break;
|
||||
case ROLE_DOMAIN_PDC:
|
||||
case ROLE_DOMAIN_BDC:
|
||||
- if ( !is_local_name && !is_my_domain ) {
|
||||
- DEBUG(6,("check_samstrict_security: %s is not one of my local names or domain name (DC)\n",
|
||||
- effective_domain));
|
||||
- return NT_STATUS_NOT_IMPLEMENTED;
|
||||
+ if (!is_local_name && !is_my_domain) {
|
||||
+ /* If we are running on a DC that has PASSDB module with domain
|
||||
+ * information, check if DNS forest name is matching the domain
|
||||
+ * name. This is the case of FreeIPA domain controller when
|
||||
+ * trusted AD DCs attempt to authenticate FreeIPA users using
|
||||
+ * the forest root domain (which is the only domain in FreeIPA).
|
||||
+ */
|
||||
+ struct pdb_domain_info *dom_info = NULL;
|
||||
+
|
||||
+ dom_info = pdb_get_domain_info(mem_ctx);
|
||||
+ if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
|
||||
+ is_my_domain = strequal(user_info->mapped.domain_name,
|
||||
+ dom_info->dns_forest);
|
||||
+ }
|
||||
+
|
||||
+ TALLOC_FREE(dom_info);
|
||||
+ if (!is_my_domain) {
|
||||
+ DEBUG(6,("check_samstrict_security: %s is not one "
|
||||
+ "of my local names or domain name (DC)\n",
|
||||
+ effective_domain));
|
||||
+ return NT_STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -230,6 +249,24 @@ static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context,
|
||||
}
|
||||
|
||||
is_my_domain = strequal(user_info->mapped.domain_name, lp_workgroup());
|
||||
+ if (!is_my_domain) {
|
||||
+ /* If we are running on a DC that has PASSDB module with domain
|
||||
+ * information, check if DNS forest name is matching the domain
|
||||
+ * name. This is the case of FreeIPA domain controller when
|
||||
+ * trusted AD DCs attempt to authenticate FreeIPA users using
|
||||
+ * the forest root domain (which is the only domain in FreeIPA).
|
||||
+ */
|
||||
+ struct pdb_domain_info *dom_info = NULL;
|
||||
+ dom_info = pdb_get_domain_info(mem_ctx);
|
||||
+
|
||||
+ if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
|
||||
+ is_my_domain = strequal(user_info->mapped.domain_name,
|
||||
+ dom_info->dns_forest);
|
||||
+ }
|
||||
+
|
||||
+ TALLOC_FREE(dom_info);
|
||||
+ }
|
||||
+
|
||||
if (!is_my_domain) {
|
||||
DBG_INFO("%s is not our domain name (DC for %s)\n",
|
||||
effective_domain, lp_workgroup());
|
||||
--
|
||||
2.23.0
|
||||
|
||||
89
backport-0010-CVE-2020-25718-Confirm-that-the-RODC.patch
Normal file
89
backport-0010-CVE-2020-25718-Confirm-that-the-RODC.patch
Normal file
@ -0,0 +1,89 @@
|
||||
From a3443838c09576bace20a12ffb0605ec56b3fe28 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Fri, 1 Oct 2021 12:01:12 +1300
|
||||
Subject: [PATCH 236/284] CVE-2020-25718 s4-rpc_server: Confirm that the RODC
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=a3443838c09576bace20a12ffb0605ec56b3fe28
|
||||
|
||||
has the UF_PARTIAL_SECRETS_ACCOUNT bit
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
---
|
||||
source4/rpc_server/common/sid_helper.c | 13 +++++++++++++
|
||||
source4/rpc_server/drsuapi/getncchanges.c | 7 ++++++-
|
||||
source4/rpc_server/netlogon/dcerpc_netlogon.c | 7 ++++++-
|
||||
3 files changed, 25 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/source4/rpc_server/common/sid_helper.c b/source4/rpc_server/common/sid_helper.c
|
||||
index ab2b4373b473..99c5fc20d9d5 100644
|
||||
--- a/source4/rpc_server/common/sid_helper.c
|
||||
+++ b/source4/rpc_server/common/sid_helper.c
|
||||
@@ -141,6 +141,7 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct
|
||||
struct dom_sid *never_reveal_sids, *reveal_sids;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
WERROR werr;
|
||||
+ uint32_t rodc_uac;
|
||||
|
||||
/*
|
||||
* We are not allowed to get anyone elses krbtgt secrets (and
|
||||
@@ -160,6 +161,18 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct
|
||||
return WERR_DS_DRA_SECRETS_DENIED;
|
||||
}
|
||||
|
||||
+ /* Be very sure the RODC is really an RODC */
|
||||
+ rodc_uac = ldb_msg_find_attr_as_uint(rodc_msg,
|
||||
+ "userAccountControl",
|
||||
+ 0);
|
||||
+ if ((rodc_uac & UF_PARTIAL_SECRETS_ACCOUNT)
|
||||
+ != UF_PARTIAL_SECRETS_ACCOUNT) {
|
||||
+ TALLOC_FREE(frame);
|
||||
+ DBG_ERR("Attempt to use an RODC account that is not an RODC: %s\n",
|
||||
+ ldb_dn_get_linearized(rodc_msg->dn));
|
||||
+ return WERR_DS_DRA_SECRETS_DENIED;
|
||||
+ }
|
||||
+
|
||||
werr = samdb_result_sid_array_dn(sam_ctx, rodc_msg,
|
||||
frame, "msDS-NeverRevealGroup",
|
||||
&num_never_reveal_sids,
|
||||
diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c
|
||||
index a9d305fc9a05..2fbd178cedca 100644
|
||||
--- a/source4/rpc_server/drsuapi/getncchanges.c
|
||||
+++ b/source4/rpc_server/drsuapi/getncchanges.c
|
||||
@@ -1168,7 +1168,12 @@ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state,
|
||||
struct ldb_dn *ntds_dn = NULL, *server_dn = NULL;
|
||||
struct ldb_dn *rodc_dn, *krbtgt_link_dn;
|
||||
int ret;
|
||||
- const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", "objectGUID", NULL };
|
||||
+ const char *rodc_attrs[] = { "msDS-KrbTgtLink",
|
||||
+ "msDS-NeverRevealGroup",
|
||||
+ "msDS-RevealOnDemandGroup",
|
||||
+ "objectGUID",
|
||||
+ "userAccountControl",
|
||||
+ NULL };
|
||||
const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL };
|
||||
struct ldb_result *rodc_res = NULL, *obj_res = NULL;
|
||||
uint32_t num_token_sids;
|
||||
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
index 92dd693ddcc1..ff33389401c1 100644
|
||||
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
||||
@@ -2845,7 +2845,12 @@ static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
|
||||
struct dom_sid *user_sid,
|
||||
struct ldb_dn *obj_dn)
|
||||
{
|
||||
- const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", "objectGUID", NULL };
|
||||
+ const char *rodc_attrs[] = { "msDS-KrbTgtLink",
|
||||
+ "msDS-NeverRevealGroup",
|
||||
+ "msDS-RevealOnDemandGroup",
|
||||
+ "objectGUID",
|
||||
+ "userAccountControl",
|
||||
+ NULL };
|
||||
const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL };
|
||||
struct ldb_dn *rodc_dn;
|
||||
int ret;
|
||||
--
|
||||
2.25.1
|
||||
@ -0,0 +1,54 @@
|
||||
From c1973cedbaa5313448a436f86dc4d662efbe497e Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 11 Aug 2021 16:56:07 +1200
|
||||
Subject: [PATCH 141/266] CVE-2020-25722 s4/dsdb/cracknames: always free
|
||||
tmp_ctx in spn_alias
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/c1973cedbaa5313448a436f86dc4d662efbe497e
|
||||
---
|
||||
source4/dsdb/samdb/cracknames.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c
|
||||
index b4bd9d8f9c9..7336778ec53 100644
|
||||
--- a/source4/dsdb/samdb/cracknames.c
|
||||
+++ b/source4/dsdb/samdb/cracknames.c
|
||||
@@ -99,10 +99,12 @@ static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, stru
|
||||
|
||||
service_dn = ldb_dn_new(tmp_ctx, ldb_ctx, "CN=Directory Service,CN=Windows NT,CN=Services");
|
||||
if ( ! ldb_dn_add_base(service_dn, ldb_get_config_basedn(ldb_ctx))) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
return DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
|
||||
}
|
||||
service_dn_str = ldb_dn_alloc_linearized(tmp_ctx, service_dn);
|
||||
if ( ! service_dn_str) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
return DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
|
||||
}
|
||||
|
||||
@@ -111,13 +113,15 @@ static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, stru
|
||||
|
||||
if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
|
||||
DEBUG(1, ("ldb_search: dn: %s not found: %s\n", service_dn_str, ldb_errstring(ldb_ctx)));
|
||||
+ talloc_free(tmp_ctx);
|
||||
return DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
|
||||
} else if (ret == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
DEBUG(1, ("ldb_search: dn: %s not found\n", service_dn_str));
|
||||
+ talloc_free(tmp_ctx);
|
||||
return DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
|
||||
} else if (res->count != 1) {
|
||||
- talloc_free(res);
|
||||
DEBUG(1, ("ldb_search: dn: %s not found\n", service_dn_str));
|
||||
+ talloc_free(tmp_ctx);
|
||||
return DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,176 @@
|
||||
From 5966f8c2d47ed0d6544d7ac242bcbe2c849b474e Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Mon, 4 Oct 2021 17:29:34 +0200
|
||||
Subject: [PATCH 103/266] CVE-2020-25717: s3:winbindd: make sure we default to
|
||||
r->out.authoritative = true
|
||||
|
||||
We need to make sure that temporary failures don't trigger a fallback
|
||||
to the local SAM that silently ignores the domain name part for users.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source3/winbindd/winbindd_dual_srv.c | 7 +++++++
|
||||
source3/winbindd/winbindd_irpc.c | 7 +++++++
|
||||
source3/winbindd/winbindd_pam.c | 15 +++++++++++----
|
||||
source3/winbindd/winbindd_pam_auth_crap.c | 9 ++++++++-
|
||||
source3/winbindd/winbindd_util.c | 7 +++++++
|
||||
5 files changed, 40 insertions(+), 4 deletions(-)
|
||||
|
||||
Conflict:{ --> unsigned char local_nt_response[24];
|
||||
delete a chunk from previos commit we don't introduce
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=5966f8c2d47ed0d6544d7ac242bcbe2c849b474e
|
||||
|
||||
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
|
||||
index 4a4894c2658..078fa77aed6 100644
|
||||
--- a/source3/winbindd/winbindd_dual_srv.c
|
||||
+++ b/source3/winbindd/winbindd_dual_srv.c
|
||||
@@ -940,6 +940,13 @@ NTSTATUS _winbind_SamLogon(struct pipes_struct *p,
|
||||
union netr_Validation *validation = NULL;
|
||||
bool interactive = false;
|
||||
|
||||
+ /*
|
||||
+ * Make sure we start with authoritative=true,
|
||||
+ * it will only set to false if we don't know the
|
||||
+ * domain.
|
||||
+ */
|
||||
+ r->out.authoritative = true;
|
||||
+
|
||||
domain = wb_child_domain();
|
||||
if (domain == NULL) {
|
||||
return NT_STATUS_REQUEST_NOT_ACCEPTED;
|
||||
diff --git a/source3/winbindd/winbindd_irpc.c b/source3/winbindd/winbindd_irpc.c
|
||||
index fda29c7e702..12f4554f9b6 100644
|
||||
--- a/source3/winbindd/winbindd_irpc.c
|
||||
+++ b/source3/winbindd/winbindd_irpc.c
|
||||
@@ -141,6 +141,13 @@ static NTSTATUS wb_irpc_SamLogon(struct irpc_message *msg,
|
||||
const char *target_domain_name = NULL;
|
||||
const char *account_name = NULL;
|
||||
|
||||
+ /*
|
||||
+ * Make sure we start with authoritative=true,
|
||||
+ * it will only set to false if we don't know the
|
||||
+ * domain.
|
||||
+ */
|
||||
+ req->out.authoritative = true;
|
||||
+
|
||||
switch (req->in.logon_level) {
|
||||
case NetlogonInteractiveInformation:
|
||||
case NetlogonServiceInformation:
|
||||
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
|
||||
index c49033b375d..59dd18e27b8 100644
|
||||
--- a/source3/winbindd/winbindd_pam.c
|
||||
+++ b/source3/winbindd/winbindd_pam.c
|
||||
@@ -1797,7 +1797,7 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(
|
||||
unsigned char local_nt_response[24];
|
||||
fstring name_namespace, name_domain, name_user;
|
||||
NTSTATUS result;
|
||||
- uint8_t authoritative = 0;
|
||||
+ uint8_t authoritative = 1;
|
||||
uint32_t flags = 0;
|
||||
uint16_t validation_level = 0;
|
||||
union netr_Validation *validation = NULL;
|
||||
@@ -2451,6 +2451,13 @@ done:
|
||||
result = NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Here we don't alter
|
||||
+ * state->response->data.auth.authoritative based
|
||||
+ * on the servers response
|
||||
+ * as we don't want a fallback to the local sam
|
||||
+ * for interactive PAM logons
|
||||
+ */
|
||||
set_auth_errors(state->response, result);
|
||||
|
||||
DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n",
|
||||
@@ -2665,7 +2672,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
|
||||
const char *name_domain = NULL;
|
||||
const char *workstation;
|
||||
uint64_t logon_id = 0;
|
||||
- uint8_t authoritative = 0;
|
||||
+ uint8_t authoritative = 1;
|
||||
uint32_t flags = 0;
|
||||
uint16_t validation_level;
|
||||
union netr_Validation *validation = NULL;
|
||||
@@ -2738,7 +2745,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
|
||||
&validation_level,
|
||||
&validation);
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
- state->response->data.auth.authoritative = authoritative;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -2792,6 +2797,8 @@ done:
|
||||
}
|
||||
|
||||
set_auth_errors(state->response, result);
|
||||
+ state->response->data.auth.authoritative = authoritative;
|
||||
+
|
||||
/*
|
||||
* Log the winbind pam authentication, the logon_id will tie this to
|
||||
* any of the logons invoked from this request.
|
||||
diff --git a/source3/winbindd/winbindd_pam_auth_crap.c b/source3/winbindd/winbindd_pam_auth_crap.c
|
||||
index b7912db43df..40cab81b5ea 100644
|
||||
--- a/source3/winbindd/winbindd_pam_auth_crap.c
|
||||
+++ b/source3/winbindd/winbindd_pam_auth_crap.c
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
struct winbindd_pam_auth_crap_state {
|
||||
struct winbindd_response *response;
|
||||
+ bool authoritative;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
@@ -45,7 +46,7 @@ struct tevent_req *winbindd_pam_auth_crap_send(
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
-
|
||||
+ state->authoritative = true;
|
||||
state->flags = request->flags;
|
||||
|
||||
if (state->flags & WBFLAG_PAM_AUTH_PAC) {
|
||||
@@ -124,6 +125,11 @@ struct tevent_req *winbindd_pam_auth_crap_send(
|
||||
|
||||
domain = find_auth_domain(request->flags, auth_domain);
|
||||
if (domain == NULL) {
|
||||
+ /*
|
||||
+ * We don't know the domain so
|
||||
+ * we're not authoritative
|
||||
+ */
|
||||
+ state->authoritative = false;
|
||||
tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
@@ -184,6 +190,7 @@ NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req,
|
||||
|
||||
if (tevent_req_is_nterror(req, &status)) {
|
||||
set_auth_errors(response, status);
|
||||
+ response->data.auth.authoritative = state->authoritative;
|
||||
return status;
|
||||
}
|
||||
|
||||
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
|
||||
index bec706f87de..ef197310fa0 100644
|
||||
--- a/source3/winbindd/winbindd_util.c
|
||||
+++ b/source3/winbindd/winbindd_util.c
|
||||
@@ -2092,6 +2092,13 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain)
|
||||
|
||||
void set_auth_errors(struct winbindd_response *resp, NTSTATUS result)
|
||||
{
|
||||
+ /*
|
||||
+ * Make sure we start with authoritative=true,
|
||||
+ * it will only set to false if we don't know the
|
||||
+ * domain.
|
||||
+ */
|
||||
+ resp->data.auth.authoritative = true;
|
||||
+
|
||||
resp->data.auth.nt_status = NT_STATUS_V(result);
|
||||
fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result));
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
From 50f5069a73ac689d3b5fb56fdc652aefb57d396a Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Thu, 28 Oct 2021 09:45:36 +1300
|
||||
Subject: [PATCH 146/266] CVE-2020-25722 s4/provision: add host/ SPNs at the
|
||||
start
|
||||
|
||||
There are two reasons for this. Firstly, leaving SPNs unclaimed is
|
||||
dangerous, as someone else could grab them first. Secondly, in some
|
||||
circumstances (self join) we try to add a DNS/ SPN a little bit later
|
||||
in provision. Under the rules we are introducing for CVE-2020-25722,
|
||||
this will make our later attempts to add HOST/ fail.
|
||||
|
||||
This causes a few errors in samba4.blackbox.dbcheck.* tests, which
|
||||
assert that revivified old domains match stored reference versions.
|
||||
Now they don't, because they have servicePrincipalNames.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/50f5069a73ac689d3b5fb56fdc652aefb57d396a
|
||||
---
|
||||
selftest/knownfail.d/cve-2020-25722-provision | 4 ++++
|
||||
source4/setup/provision_self_join.ldif | 9 +++++++--
|
||||
2 files changed, 11 insertions(+), 2 deletions(-)
|
||||
create mode 100644 selftest/knownfail.d/cve-2020-25722-provision
|
||||
|
||||
diff --git a/selftest/knownfail.d/cve-2020-25722-provision b/selftest/knownfail.d/cve-2020-25722-provision
|
||||
new file mode 100644
|
||||
index 00000000000..7fd4b4b3763
|
||||
--- /dev/null
|
||||
+++ b/selftest/knownfail.d/cve-2020-25722-provision
|
||||
@@ -0,0 +1,4 @@
|
||||
+samba4.blackbox.dbcheck.release-4-0-0
|
||||
+samba4.blackbox.dbcheck.release-4-0-0.quick
|
||||
+samba4.blackbox.upgradeprovision.release-4-0-0
|
||||
+samba4.blackbox.functionalprep.check_databases_same
|
||||
diff --git a/source4/setup/provision_self_join.ldif b/source4/setup/provision_self_join.ldif
|
||||
index f77ac5710ec..92bf4d9cf8f 100644
|
||||
--- a/source4/setup/provision_self_join.ldif
|
||||
+++ b/source4/setup/provision_self_join.ldif
|
||||
@@ -15,11 +15,16 @@ localPolicyFlags: 0
|
||||
operatingSystem: Samba
|
||||
operatingSystemVersion: ${SAMBA_VERSION_STRING}
|
||||
sAMAccountName: ${NETBIOSNAME}$
|
||||
-# The "servicePrincipalName" updates are now handled by the "samba_spnupdate"
|
||||
-# script
|
||||
userAccountControl: 532480
|
||||
clearTextPassword:: ${MACHINEPASS_B64}
|
||||
objectSid: ${DOMAINSID}-${DCRID}
|
||||
+# While some "servicePrincipalName" updates might be handled by the
|
||||
+# "samba_spnupdate" script, we need to get the basics in here before
|
||||
+# we add any others.
|
||||
+servicePrincipalName: HOST/${DNSNAME}
|
||||
+servicePrincipalName: HOST/${NETBIOSNAME}
|
||||
+servicePrincipalName: HOST/${DNSNAME}/${DNSNAME}
|
||||
+
|
||||
|
||||
dn: CN=RID Set,CN=${NETBIOSNAME},OU=Domain Controllers,${DOMAINDN}
|
||||
objectClass: rIDSet
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
From 66cd97e558cdb57bff2dfc2bf8734b0ee12f648e Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Mon, 4 Oct 2021 17:29:34 +0200
|
||||
Subject: [PATCH 104/266] CVE-2020-25717: s4:auth/ntlm: make sure
|
||||
auth_check_password() defaults to r->out.authoritative = true
|
||||
|
||||
We need to make sure that temporary failures don't trigger a fallback
|
||||
to the local SAM that silently ignores the domain name part for users.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source4/auth/ntlm/auth.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=66cd97e558cdb57bff2dfc2bf8734b0ee12f648e
|
||||
|
||||
diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
|
||||
index 1aa2e3b065f..e0c4436343c 100644
|
||||
--- a/source4/auth/ntlm/auth.c
|
||||
+++ b/source4/auth/ntlm/auth.c
|
||||
@@ -169,6 +169,11 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
|
||||
/*TODO: create a new event context here! */
|
||||
ev = auth_ctx->event_ctx;
|
||||
|
||||
+ /*
|
||||
+ * We are authoritative by default
|
||||
+ */
|
||||
+ *pauthoritative = 1;
|
||||
+
|
||||
subreq = auth_check_password_send(mem_ctx,
|
||||
ev,
|
||||
auth_ctx,
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
From 935997b92ebea5941a04c553934e203b33f1d7d7 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Fri, 22 Oct 2021 14:12:25 +1300
|
||||
Subject: [PATCH 151/266] CVE-2020-25722 s4/dsdb/samldb: add
|
||||
samldb_get_single_valued_attr() helper
|
||||
|
||||
This takes a string of logic out of samldb_unique_attr_check() that we
|
||||
are going to need in other places, and that would be very tedious to
|
||||
repeat.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/935997b92ebea5941a04c553934e203b33f1d7d7
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 49 +++++++++++++++++++++++++
|
||||
1 file changed, 49 insertions(+)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 6db7840b0c1..40dfab6390b 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -161,6 +161,55 @@ static int samldb_next_step(struct samldb_ctx *ac)
|
||||
}
|
||||
}
|
||||
|
||||
+static int samldb_get_single_valued_attr(struct ldb_context *ldb,
|
||||
+ struct samldb_ctx *ac,
|
||||
+ const char *attr,
|
||||
+ const char **value)
|
||||
+{
|
||||
+ /*
|
||||
+ * The steps we end up going through to get and check a single valued
|
||||
+ * attribute.
|
||||
+ */
|
||||
+ struct ldb_message_element *el = NULL;
|
||||
+
|
||||
+ *value = NULL;
|
||||
+
|
||||
+ el = dsdb_get_single_valued_attr(ac->msg, attr,
|
||||
+ ac->req->operation);
|
||||
+ if (el == NULL) {
|
||||
+ /* we are not affected */
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ if (el->num_values > 1) {
|
||||
+ ldb_asprintf_errstring(
|
||||
+ ldb,
|
||||
+ "samldb: %s has %u values, should be single-valued!",
|
||||
+ attr, el->num_values);
|
||||
+ return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
+ } else if (el->num_values == 0) {
|
||||
+ ldb_asprintf_errstring(
|
||||
+ ldb,
|
||||
+ "samldb: new value for %s "
|
||||
+ "not provided for mandatory, single-valued attribute!",
|
||||
+ attr);
|
||||
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if (el->values[0].length == 0) {
|
||||
+ ldb_asprintf_errstring(
|
||||
+ ldb,
|
||||
+ "samldb: %s is of zero length, should have a value!",
|
||||
+ attr);
|
||||
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
|
||||
+ }
|
||||
+
|
||||
+ *value = (char *)el->values[0].data;
|
||||
+
|
||||
+ return LDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
static int samldb_unique_attr_check(struct samldb_ctx *ac, const char *attr,
|
||||
const char *attr_conflict,
|
||||
struct ldb_dn *base_dn)
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,101 @@
|
||||
From b9d8f8025b7122cab64c37e5042866c66b556016 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Cabrero <scabrero@samba.org>
|
||||
Date: Tue, 28 Sep 2021 10:43:40 +0200
|
||||
Subject: [PATCH 113/266] CVE-2020-25717: loadparm: Add new parameter "min
|
||||
domain uid"
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
|
||||
|
||||
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
|
||||
[abartlet@samba.org Backported from master/4.15 due to
|
||||
conflicts with other new parameters]
|
||||
---
|
||||
docs-xml/smbdotconf/security/mindomainuid.xml | 17 +++++++++++++++++
|
||||
docs-xml/smbdotconf/winbind/idmapconfig.xml | 4 ++++
|
||||
lib/param/loadparm.c | 4 ++++
|
||||
source3/param/loadparm.c | 2 ++
|
||||
4 files changed, 27 insertions(+)
|
||||
create mode 100644 docs-xml/smbdotconf/security/mindomainuid.xml
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=b9d8f8025b7122cab64c37e5042866c66b556016
|
||||
|
||||
diff --git a/docs-xml/smbdotconf/security/mindomainuid.xml b/docs-xml/smbdotconf/security/mindomainuid.xml
|
||||
new file mode 100644
|
||||
index 00000000000..46ae795d730
|
||||
--- /dev/null
|
||||
+++ b/docs-xml/smbdotconf/security/mindomainuid.xml
|
||||
@@ -0,0 +1,17 @@
|
||||
+<samba:parameter name="min domain uid"
|
||||
+ type="integer"
|
||||
+ context="G"
|
||||
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
|
||||
+<description>
|
||||
+ <para>
|
||||
+ The integer parameter specifies the minimum uid allowed when mapping a
|
||||
+ local account to a domain account.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ Note that this option interacts with the configured <emphasis>idmap ranges</emphasis>!
|
||||
+ </para>
|
||||
+</description>
|
||||
+
|
||||
+<value type="default">1000</value>
|
||||
+</samba:parameter>
|
||||
diff --git a/docs-xml/smbdotconf/winbind/idmapconfig.xml b/docs-xml/smbdotconf/winbind/idmapconfig.xml
|
||||
index 1374040fb29..f70f11df757 100644
|
||||
--- a/docs-xml/smbdotconf/winbind/idmapconfig.xml
|
||||
+++ b/docs-xml/smbdotconf/winbind/idmapconfig.xml
|
||||
@@ -80,6 +80,9 @@
|
||||
authoritative for a unix ID to SID mapping, so it must be set
|
||||
for each individually configured domain and for the default
|
||||
configuration. The configured ranges must be mutually disjoint.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Note that the low value interacts with the <smbconfoption name="min domain uid"/> option!
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
@@ -115,4 +118,5 @@
|
||||
</programlisting>
|
||||
|
||||
</description>
|
||||
+<related>min domain uid</related>
|
||||
</samba:parameter>
|
||||
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
|
||||
index 006caabc092..d2f6e6241ad 100644
|
||||
--- a/lib/param/loadparm.c
|
||||
+++ b/lib/param/loadparm.c
|
||||
@@ -3079,6 +3079,10 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
|
||||
lpcfg_do_global_parameter(
|
||||
lp_ctx, "ldap max search request size", "256000");
|
||||
|
||||
+ lpcfg_do_global_parameter(lp_ctx,
|
||||
+ "min domain uid",
|
||||
+ "1000");
|
||||
+
|
||||
for (i = 0; parm_table[i].label; i++) {
|
||||
if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
|
||||
lp_ctx->flags[i] |= FLAG_DEFAULT;
|
||||
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
|
||||
index a3abaa2ec67..301e3622ed4 100644
|
||||
--- a/source3/param/loadparm.c
|
||||
+++ b/source3/param/loadparm.c
|
||||
@@ -960,6 +960,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
|
||||
Globals.ldap_max_authenticated_request_size = 16777216;
|
||||
Globals.ldap_max_search_request_size = 256000;
|
||||
|
||||
+ Globals.min_domain_uid = 1000;
|
||||
+
|
||||
/* Now put back the settings that were set with lp_set_cmdline() */
|
||||
apply_lp_set_cmdline();
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,279 @@
|
||||
From 4439ac7bb6e8fcb1610fa94923c3daaed3e4c958 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Fri, 22 Oct 2021 13:17:34 +1300
|
||||
Subject: [PATCH 153/266] CVE-2020-25722 s4/dsdb/samldb: check for clashes in
|
||||
UPNs/samaccountnames
|
||||
|
||||
We already know duplicate sAMAccountNames and UserPrincipalNames are bad,
|
||||
but we also have to check against the values these imply in each other.
|
||||
|
||||
For example, imagine users with SAM account names "Alice" and "Bob" in
|
||||
the realm "example.com". If they do not have explicit UPNs, by the logic
|
||||
of MS-ADTS 5.1.1.1.1 they use the implict UPNs "alice@example.com" and
|
||||
"bob@example.com", respectively. If Bob's UPN gets set to
|
||||
"alice@example.com", it will clash with Alice's implicit one.
|
||||
|
||||
Therefore we refuse to allow a UPN that implies an existing SAM account
|
||||
name and vice versa.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/4439ac7bb6e8fcb1610fa94923c3daaed3e4c958
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 206 +++++++++++++++++++++-
|
||||
1 files changed, 203 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index a03fc6eb07c..0cf00e2b19e 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -235,8 +235,9 @@ static int samldb_unique_attr_check(struct samldb_ctx *ac, const char *attr,
|
||||
return ldb_module_oom(ac->module);
|
||||
}
|
||||
|
||||
- /* Make sure that attr (eg) "sAMAccountName" is only used once */
|
||||
-
|
||||
+ /*
|
||||
+ * No other object should have the attribute with this value.
|
||||
+ */
|
||||
if (attr_conflict != NULL) {
|
||||
ret = dsdb_module_search(ac->module, ac, &res,
|
||||
base_dn,
|
||||
@@ -270,6 +271,193 @@ static int samldb_unique_attr_check(struct samldb_ctx *ac, const char *attr,
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
+
|
||||
+
|
||||
+static inline int samldb_sam_account_upn_clash_sub_search(
|
||||
+ struct samldb_ctx *ac,
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ struct ldb_dn *base_dn,
|
||||
+ const char *attr,
|
||||
+ const char *value,
|
||||
+ const char *err_msg
|
||||
+ )
|
||||
+{
|
||||
+ /*
|
||||
+ * A very specific helper function for samldb_sam_account_upn_clash(),
|
||||
+ * where we end up doing this same thing several times in a row.
|
||||
+ */
|
||||
+ const char * const no_attrs[] = { NULL };
|
||||
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
+ struct ldb_result *res = NULL;
|
||||
+ int ret;
|
||||
+ char *enc_value = ldb_binary_encode_string(ac, value);
|
||||
+ if (enc_value == NULL) {
|
||||
+ return ldb_module_oom(ac->module);
|
||||
+ }
|
||||
+ ret = dsdb_module_search(ac->module, mem_ctx, &res,
|
||||
+ base_dn,
|
||||
+ LDB_SCOPE_SUBTREE, no_attrs,
|
||||
+ DSDB_FLAG_NEXT_MODULE, ac->req,
|
||||
+ "(%s=%s)",
|
||||
+ attr, enc_value);
|
||||
+ talloc_free(enc_value);
|
||||
+
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ } else if (res->count > 1) {
|
||||
+ return ldb_operr(ldb);
|
||||
+ } else if (res->count == 1) {
|
||||
+ if (ldb_dn_compare(res->msgs[0]->dn, ac->msg->dn) != 0){
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "samldb: %s '%s' "
|
||||
+ "is already in use %s",
|
||||
+ attr, value, err_msg);
|
||||
+ /* different errors for different attrs */
|
||||
+ if (strcasecmp("userPrincipalName", attr) == 0) {
|
||||
+ return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
+ }
|
||||
+ return LDB_ERR_ENTRY_ALREADY_EXISTS;
|
||||
+ }
|
||||
+ }
|
||||
+ return LDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static int samldb_sam_account_upn_clash(struct samldb_ctx *ac)
|
||||
+{
|
||||
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
+ int ret;
|
||||
+ struct ldb_dn *base_dn = ldb_get_default_basedn(ldb);
|
||||
+ TALLOC_CTX *tmp_ctx = NULL;
|
||||
+ const char *real_sam = NULL;
|
||||
+ const char *real_upn = NULL;
|
||||
+ char *implied_sam = NULL;
|
||||
+ char *implied_upn = NULL;
|
||||
+ const char *realm = NULL;
|
||||
+
|
||||
+ ret = samldb_get_single_valued_attr(ldb, ac,
|
||||
+ "sAMAccountName",
|
||||
+ &real_sam);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ ret = samldb_get_single_valued_attr(ldb, ac,
|
||||
+ "userPrincipalName",
|
||||
+ &real_upn);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ if (real_upn == NULL && real_sam == NULL) {
|
||||
+ /* Not changing these things, so we're done */
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ tmp_ctx = talloc_new(ac);
|
||||
+ realm = samdb_dn_to_dns_domain(tmp_ctx, base_dn);
|
||||
+ if (realm == NULL) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ldb_operr(ldb);
|
||||
+ }
|
||||
+
|
||||
+ if (real_upn != NULL) {
|
||||
+ /*
|
||||
+ * note we take the last @ in the upn because the first (i.e.
|
||||
+ * sAMAccountName equivalent) part can contain @.
|
||||
+ *
|
||||
+ * It is also OK (per Windows) for a UPN to have zero @s.
|
||||
+ */
|
||||
+ char *at = NULL;
|
||||
+ char *upn_realm = NULL;
|
||||
+ implied_sam = talloc_strdup(tmp_ctx, real_upn);
|
||||
+ if (implied_sam == NULL) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ldb_module_oom(ac->module);
|
||||
+ }
|
||||
+
|
||||
+ at = strrchr(implied_sam, '@');
|
||||
+ if (at == NULL) {
|
||||
+ /*
|
||||
+ * there is no @ in this UPN, so we treat the whole
|
||||
+ * thing as a sAMAccountName for the purposes of a
|
||||
+ * clash.
|
||||
+ */
|
||||
+ DBG_INFO("samldb: userPrincipalName '%s' contains "
|
||||
+ "no '@' character\n", implied_sam);
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Now, this upn only implies a sAMAccountName if the
|
||||
+ * realm is our realm. So we need to compare the tail
|
||||
+ * of the upn to the realm.
|
||||
+ */
|
||||
+ *at = '\0';
|
||||
+ upn_realm = at + 1;
|
||||
+ if (strcasecmp(upn_realm, realm) != 0) {
|
||||
+ /* implied_sam is not the implied
|
||||
+ * sAMAccountName after all, because it is
|
||||
+ * from a different realm. */
|
||||
+ TALLOC_FREE(implied_sam);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (real_sam != NULL) {
|
||||
+ implied_upn = talloc_asprintf(tmp_ctx, "%s@%s",
|
||||
+ real_sam, realm);
|
||||
+ if (implied_upn == NULL) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ldb_module_oom(ac->module);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Now we have all of the actual and implied names, in which to search
|
||||
+ * for conflicts.
|
||||
+ */
|
||||
+ if (real_sam != NULL) {
|
||||
+ ret = samldb_sam_account_upn_clash_sub_search(
|
||||
+ ac, tmp_ctx, base_dn, "sAMAccountName",
|
||||
+ real_sam, "");
|
||||
+
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ if (implied_upn != NULL) {
|
||||
+ ret = samldb_sam_account_upn_clash_sub_search(
|
||||
+ ac, tmp_ctx, base_dn, "userPrincipalName", implied_upn,
|
||||
+ "(implied by sAMAccountName)");
|
||||
+
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ if (real_upn != NULL) {
|
||||
+ ret = samldb_sam_account_upn_clash_sub_search(
|
||||
+ ac, tmp_ctx, base_dn, "userPrincipalName",
|
||||
+ real_upn, "");
|
||||
+
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ if (implied_sam != NULL) {
|
||||
+ ret = samldb_sam_account_upn_clash_sub_search(
|
||||
+ ac, tmp_ctx, base_dn, "sAMAccountName", implied_sam,
|
||||
+ "(implied by userPrincipalName)");
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* This is run during an add or modify */
|
||||
static int samldb_sam_accountname_valid_check(struct samldb_ctx *ac)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -303,7 +491,11 @@ static int samldb_sam_accountname_valid_check(struct samldb_ctx *ac)
|
||||
} else if (ret == LDB_ERR_OBJECT_CLASS_VIOLATION) {
|
||||
ret = LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
+ ret = samldb_sam_account_upn_clash(ac);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
@@ -4175,7 +4367,6 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
-
|
||||
user_account_control
|
||||
= ldb_msg_find_attr_as_uint(res->msgs[0],
|
||||
"userAccountControl",
|
||||
@@ -4199,6 +4390,15 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
|
||||
}
|
||||
}
|
||||
|
||||
+ el = ldb_msg_find_element(ac->msg, "userPrincipalName");
|
||||
+ if (el != NULL) {
|
||||
+ ret = samldb_sam_account_upn_clash(ac);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ talloc_free(ac);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
el = ldb_msg_find_element(ac->msg, "ldapDisplayName");
|
||||
if (el != NULL) {
|
||||
ret = samldb_schema_ldapdisplayname_valid_check(ac);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
From ce47a81eb5f79dd3f54b300f6a9a7ccac9c1296a Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Cabrero <scabrero@samba.org>
|
||||
Date: Tue, 28 Sep 2021 10:45:11 +0200
|
||||
Subject: [PATCH 117/266] CVE-2020-25717: s3:auth: Check minimum domain uid
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
|
||||
|
||||
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
[abartlet@samba.org Removed knownfail on advice from metze]
|
||||
---
|
||||
source3/auth/auth_util.c | 16 ++++++++++++++++
|
||||
1 files changed, 16 insertions(+)
|
||||
delete mode 100644 selftest/knownfail.d/min_domain_uid
|
||||
|
||||
Conflict:delete a chunk which delete a file do not exist
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=ce47a81eb5f79dd3f54b300f6a9a7ccac9c1296a
|
||||
|
||||
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
|
||||
index 4686b29111e..4de4bc74374 100644
|
||||
--- a/source3/auth/auth_util.c
|
||||
+++ b/source3/auth/auth_util.c
|
||||
@@ -2103,6 +2103,22 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
+ } else if ((lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
|
||||
+ !is_myname(domain) && pwd->pw_uid < lp_min_domain_uid()) {
|
||||
+ /*
|
||||
+ * !is_myname(domain) because when smbd starts tries to setup
|
||||
+ * the guest user info, calling this function with nobody
|
||||
+ * username. Nobody is usually uid 65535 but it can be changed
|
||||
+ * to a regular user with 'guest account' parameter
|
||||
+ */
|
||||
+ nt_status = NT_STATUS_INVALID_TOKEN;
|
||||
+ DBG_NOTICE("Username '%s%s%s' is invalid on this system, "
|
||||
+ "it does not meet 'min domain uid' "
|
||||
+ "restriction (%u < %u): %s\n",
|
||||
+ nt_domain, lp_winbind_separator(), nt_username,
|
||||
+ pwd->pw_uid, lp_min_domain_uid(),
|
||||
+ nt_errstr(nt_status));
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
result = make_server_info(tmp_ctx);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,101 @@
|
||||
From 9be11622765c060971c4fcc2fba981f760f897d8 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Fri, 22 Oct 2021 15:27:25 +1300
|
||||
Subject: [PATCH 154/266] CVE-2020-25722 s4/dsdb/samldb: check sAMAccountName
|
||||
for illegal characters
|
||||
|
||||
This only for the real account name, not the account name implicit in
|
||||
a UPN. It doesn't matter if a UPN implies an illegal sAMAccountName,
|
||||
since that is not going to conflict with a real one.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/9be11622765c060971c4fcc2fba981f760f897d8
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 58 +++++++++++++++++++++++
|
||||
1 files changed, 58 insertions(+), 0 deletion(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 0cf00e2b19e..f420009376c 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -322,6 +322,59 @@ static inline int samldb_sam_account_upn_clash_sub_search(
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
+static int samaccountname_bad_chars_check(struct samldb_ctx *ac,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ /*
|
||||
+ * The rules here are based on
|
||||
+ *
|
||||
+ * https://social.technet.microsoft.com/wiki/contents/articles/11216.active-directory-requirements-for-creating-objects.aspx
|
||||
+ *
|
||||
+ * Windows considers UTF-8 sequences that map to "similar" characters
|
||||
+ * (e.g. 'a', 'ā') to be the same sAMAccountName, and we don't. Names
|
||||
+ * that are not valid UTF-8 *are* allowed.
|
||||
+ *
|
||||
+ * Additionally, Samba collapses multiple spaces, and Windows doesn't.
|
||||
+ */
|
||||
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0; name[i] != '\0'; i++) {
|
||||
+ uint8_t c = name[i];
|
||||
+ char *p = NULL;
|
||||
+ if (c < 32 || c == 127) {
|
||||
+ ldb_asprintf_errstring(
|
||||
+ ldb,
|
||||
+ "samldb: sAMAccountName contains invalid "
|
||||
+ "0x%.2x character\n", c);
|
||||
+ return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
+ }
|
||||
+ p = strchr("\"[]:;|=+*?<>/\\,", c);
|
||||
+ if (p != NULL) {
|
||||
+ ldb_asprintf_errstring(
|
||||
+ ldb,
|
||||
+ "samldb: sAMAccountName contains invalid "
|
||||
+ "'%c' character\n", c);
|
||||
+ return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (i == 0) {
|
||||
+ ldb_asprintf_errstring(
|
||||
+ ldb,
|
||||
+ "samldb: sAMAccountName is empty\n");
|
||||
+ return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
+ }
|
||||
+
|
||||
+ if (name[i - 1] == '.') {
|
||||
+ ldb_asprintf_errstring(
|
||||
+ ldb,
|
||||
+ "samldb: sAMAccountName ends with '.'");
|
||||
+ return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
+ }
|
||||
+ return LDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
static int samldb_sam_account_upn_clash(struct samldb_ctx *ac)
|
||||
{
|
||||
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
@@ -421,6 +474,11 @@ static int samldb_sam_account_upn_clash(struct samldb_ctx *ac)
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
+ ret = samaccountname_bad_chars_check(ac, real_sam);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+ }
|
||||
}
|
||||
if (implied_upn != NULL) {
|
||||
ret = samldb_sam_account_upn_clash_sub_search(
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
From 885fe6e31b107b3a6362cde0785e6d886888e0ec Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Fri, 8 Oct 2021 17:40:30 +0200
|
||||
Subject: [PATCH 118/266] CVE-2020-25717: s3:auth: we should not try to
|
||||
autocreate the guest account
|
||||
|
||||
We should avoid autocreation of users as much as possible.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source3/auth/user_krb5.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=885fe6e31b107b3a6362cde0785e6d886888e0ec
|
||||
|
||||
diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c
|
||||
index 8998f9c8f8a..074e8c7eb71 100644
|
||||
--- a/source3/auth/user_krb5.c
|
||||
+++ b/source3/auth/user_krb5.c
|
||||
@@ -155,7 +155,7 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
|
||||
if (!fuser) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
- pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true);
|
||||
+ pw = smb_getpwnam(mem_ctx, fuser, &unixuser, false);
|
||||
}
|
||||
|
||||
/* extra sanity check that the guest account is valid */
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,667 @@
|
||||
From b121b1920f996fc9c15ec40a63e7cf4dd7159161 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Fri, 22 Oct 2021 13:14:32 +1300
|
||||
Subject: [PATCH 155/266] CVE-2020-25722 s4/dsdb/samldb: check for SPN
|
||||
uniqueness, including aliases
|
||||
|
||||
Not only should it not be possible to add a servicePrincipalName that
|
||||
is already present in the domain, it should not be possible to add one
|
||||
that is implied by an entry in sPNMappings, unless the user is adding
|
||||
an alias to another SPN and has rights to alter that one.
|
||||
|
||||
For example, with the default sPNMappings, cifs/ is an alias pointing to
|
||||
host/, meaning if there is no cifs/example.com SPN, the host/example.com
|
||||
one will be used instead. A user can add the cifs/example.com SPN only
|
||||
if they can also change the host/example.com one (because adding the
|
||||
cifs/ effectively changes the host/). The reverse is refused in all cases,
|
||||
unless they happen to be on the same object. That is, if there is a
|
||||
cifs/example.com SPN, there is no way to add host/example.com elsewhere.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/b121b1920f996fc9c15ec40a63e7cf4dd7159161
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 588 +++++++++++++++++++++++-
|
||||
1 files changed, 585 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index f420009376c..f5141936a60 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -3383,6 +3383,546 @@ static int samldb_description_check(struct samldb_ctx *ac, bool *modified)
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
+#define SPN_ALIAS_NONE 0
|
||||
+#define SPN_ALIAS_LINK 1
|
||||
+#define SPN_ALIAS_TARGET 2
|
||||
+
|
||||
+static int find_spn_aliases(struct ldb_context *ldb,
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ const char *service_class,
|
||||
+ char ***aliases,
|
||||
+ size_t *n_aliases,
|
||||
+ int *direction)
|
||||
+{
|
||||
+ /*
|
||||
+ * If you change the way this works, you should also look at changing
|
||||
+ * LDB_lookup_spn_alias() in source4/dsdb/samdb/cracknames.c, which
|
||||
+ * does some of the same work.
|
||||
+ *
|
||||
+ * In particular, note that sPNMappings are resolved on a first come,
|
||||
+ * first served basis. For example, if we have
|
||||
+ *
|
||||
+ * host=ldap,cifs
|
||||
+ * foo=ldap
|
||||
+ * cifs=host,alerter
|
||||
+ *
|
||||
+ * then 'ldap', 'cifs', and 'host' will resolve to 'host', and
|
||||
+ * 'alerter' will resolve to 'cifs'.
|
||||
+ *
|
||||
+ * If this resolution method is made more complicated, then the
|
||||
+ * cracknames function should also be changed.
|
||||
+ */
|
||||
+ size_t i, j;
|
||||
+ int ret;
|
||||
+ bool ok;
|
||||
+ struct ldb_result *res = NULL;
|
||||
+ struct ldb_message_element *spnmappings = NULL;
|
||||
+ TALLOC_CTX *tmp_ctx = NULL;
|
||||
+ struct ldb_dn *service_dn = NULL;
|
||||
+
|
||||
+ const char *attrs[] = {
|
||||
+ "sPNMappings",
|
||||
+ NULL
|
||||
+ };
|
||||
+
|
||||
+ *direction = SPN_ALIAS_NONE;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(mem_ctx);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+
|
||||
+ service_dn = ldb_dn_new(
|
||||
+ tmp_ctx, ldb,
|
||||
+ "CN=Directory Service,CN=Windows NT,CN=Services");
|
||||
+ if (service_dn == NULL) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+
|
||||
+ ok = ldb_dn_add_base(service_dn, ldb_get_config_basedn(ldb));
|
||||
+ if (! ok) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_ERR_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ ret = ldb_search(ldb, tmp_ctx, &res, service_dn, LDB_SCOPE_BASE,
|
||||
+ attrs, "(objectClass=nTDSService)");
|
||||
+
|
||||
+ if (ret != LDB_SUCCESS || res->count != 1) {
|
||||
+ DBG_WARNING("sPNMappings not found.\n");
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ spnmappings = ldb_msg_find_element(res->msgs[0], "sPNMappings");
|
||||
+ if (spnmappings == NULL || spnmappings->num_values == 0) {
|
||||
+ DBG_WARNING("no sPNMappings attribute\n");
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_ERR_NO_SUCH_OBJECT;
|
||||
+ }
|
||||
+ *n_aliases = 0;
|
||||
+
|
||||
+ for (i = 0; i < spnmappings->num_values; i++) {
|
||||
+ char *p = NULL;
|
||||
+ char *mapping = talloc_strndup(
|
||||
+ tmp_ctx,
|
||||
+ (char *)spnmappings->values[i].data,
|
||||
+ spnmappings->values[i].length);
|
||||
+ if (mapping == NULL) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+
|
||||
+ p = strchr(mapping, '=');
|
||||
+ if (p == NULL) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_ERR_ALIAS_PROBLEM;
|
||||
+ }
|
||||
+ p[0] = '\0';
|
||||
+ p++;
|
||||
+
|
||||
+ if (strcasecmp(mapping, service_class) == 0) {
|
||||
+ /*
|
||||
+ * We need to return the reverse aliases for this one.
|
||||
+ *
|
||||
+ * typically, this means the service_class is "host"
|
||||
+ * and the mapping is "host=alerter,appmgmt,cisvc,..",
|
||||
+ * so we get "alerter", "appmgmt", etc in the list of
|
||||
+ * aliases.
|
||||
+ */
|
||||
+
|
||||
+ /* There is one more field than there are commas */
|
||||
+ size_t n = 1;
|
||||
+
|
||||
+ for (j = 0; p[j] != '\0'; j++) {
|
||||
+ if (p[j] == ',') {
|
||||
+ n++;
|
||||
+ p[j] = '\0';
|
||||
+ }
|
||||
+ }
|
||||
+ *aliases = talloc_array(mem_ctx, char*, n);
|
||||
+ if (*aliases == NULL) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+ *n_aliases = n;
|
||||
+ talloc_steal(mem_ctx, mapping);
|
||||
+ for (j = 0; j < n; j++) {
|
||||
+ (*aliases)[j] = p;
|
||||
+ p += strlen(p) + 1;
|
||||
+ }
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ *direction = SPN_ALIAS_LINK;
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+ /*
|
||||
+ * We need to look along the list to see if service_class is
|
||||
+ * there; if so, we return a list of one item (probably "host").
|
||||
+ */
|
||||
+ do {
|
||||
+ char *str = p;
|
||||
+ p = strchr(p, ',');
|
||||
+ if (p != NULL) {
|
||||
+ p[0] = '\0';
|
||||
+ p++;
|
||||
+ }
|
||||
+ if (strcasecmp(str, service_class) == 0) {
|
||||
+ *aliases = talloc_array(mem_ctx, char*, 1);
|
||||
+ if (*aliases == NULL) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+ *n_aliases = 1;
|
||||
+ (*aliases)[0] = mapping;
|
||||
+ talloc_steal(mem_ctx, mapping);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ *direction = SPN_ALIAS_TARGET;
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+ } while (p != NULL);
|
||||
+ }
|
||||
+ DBG_INFO("no sPNMappings alias for '%s'\n", service_class);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ *aliases = NULL;
|
||||
+ *n_aliases = 0;
|
||||
+ return LDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int get_spn_dn(struct ldb_context *ldb,
|
||||
+ TALLOC_CTX *tmp_ctx,
|
||||
+ const char *candidate,
|
||||
+ struct ldb_dn **dn)
|
||||
+{
|
||||
+ int ret;
|
||||
+ const char *empty_attrs[] = { NULL };
|
||||
+ struct ldb_message *msg = NULL;
|
||||
+ struct ldb_dn *base_dn = ldb_get_default_basedn(ldb);
|
||||
+
|
||||
+ const char *enc_candidate = NULL;
|
||||
+
|
||||
+ *dn = NULL;
|
||||
+
|
||||
+ enc_candidate = ldb_binary_encode_string(tmp_ctx, candidate);
|
||||
+ if (enc_candidate == NULL) {
|
||||
+ return ldb_operr(ldb);
|
||||
+ }
|
||||
+
|
||||
+ ret = dsdb_search_one(ldb,
|
||||
+ tmp_ctx,
|
||||
+ &msg,
|
||||
+ base_dn,
|
||||
+ LDB_SCOPE_SUBTREE,
|
||||
+ empty_attrs,
|
||||
+ 0,
|
||||
+ "(servicePrincipalName=%s)",
|
||||
+ enc_candidate);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ *dn = msg->dn;
|
||||
+ return LDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int check_spn_write_rights(struct ldb_context *ldb,
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ const char *spn,
|
||||
+ struct ldb_dn *dn)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct ldb_message *msg = NULL;
|
||||
+ struct ldb_message_element *del_el = NULL;
|
||||
+ struct ldb_message_element *add_el = NULL;
|
||||
+ struct ldb_val val = {
|
||||
+ .data = discard_const_p(uint8_t, spn),
|
||||
+ .length = strlen(spn)
|
||||
+ };
|
||||
+
|
||||
+ msg = ldb_msg_new(mem_ctx);
|
||||
+ if (msg == NULL) {
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+ msg->dn = dn;
|
||||
+
|
||||
+ ret = ldb_msg_add_empty(msg,
|
||||
+ "servicePrincipalName",
|
||||
+ LDB_FLAG_MOD_DELETE,
|
||||
+ &del_el);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ talloc_free(msg);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ del_el->values = talloc_array(msg->elements, struct ldb_val, 1);
|
||||
+ if (del_el->values == NULL) {
|
||||
+ talloc_free(msg);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ del_el->values[0] = val;
|
||||
+ del_el->num_values = 1;
|
||||
+
|
||||
+ ret = ldb_msg_add_empty(msg,
|
||||
+ "servicePrincipalName",
|
||||
+ LDB_FLAG_MOD_ADD,
|
||||
+ &add_el);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ talloc_free(msg);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ add_el->values = talloc_array(msg->elements, struct ldb_val, 1);
|
||||
+ if (add_el->values == NULL) {
|
||||
+ talloc_free(msg);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ add_el->values[0] = val;
|
||||
+ add_el->num_values = 1;
|
||||
+
|
||||
+ ret = ldb_modify(ldb, msg);
|
||||
+ if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
|
||||
+ DBG_ERR("hmm I think we're OK, but not sure\n");
|
||||
+ } else if (ret != LDB_SUCCESS) {
|
||||
+ DBG_ERR("SPN write rights check failed with %d\n", ret);
|
||||
+ talloc_free(msg);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ talloc_free(msg);
|
||||
+ return LDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int check_spn_alias_collision(struct ldb_context *ldb,
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ const char *spn,
|
||||
+ struct ldb_dn *target_dn)
|
||||
+{
|
||||
+ int ret;
|
||||
+ char *service_class = NULL;
|
||||
+ char *spn_tail = NULL;
|
||||
+ char *p = NULL;
|
||||
+ char **aliases = NULL;
|
||||
+ size_t n_aliases = 0;
|
||||
+ size_t i, len;
|
||||
+ TALLOC_CTX *tmp_ctx = NULL;
|
||||
+ const char *target_dnstr = ldb_dn_get_linearized(target_dn);
|
||||
+ int link_direction;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(mem_ctx);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * "dns/example.com/xxx" gives
|
||||
+ * service_class = "dns"
|
||||
+ * spn_tail = "example.com/xxx"
|
||||
+ */
|
||||
+ p = strchr(spn, '/');
|
||||
+ if (p == NULL) {
|
||||
+ /* bad SPN */
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ldb_error(ldb,
|
||||
+ LDB_ERR_OPERATIONS_ERROR,
|
||||
+ "malformed servicePrincipalName");
|
||||
+ }
|
||||
+ len = p - spn;
|
||||
+
|
||||
+ service_class = talloc_strndup(tmp_ctx, spn, len);
|
||||
+ if (service_class == NULL) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+ spn_tail = p + 1;
|
||||
+
|
||||
+ ret = find_spn_aliases(ldb,
|
||||
+ tmp_ctx,
|
||||
+ service_class,
|
||||
+ &aliases,
|
||||
+ &n_aliases,
|
||||
+ &link_direction);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * we have the list of aliases, and now we need to combined them with
|
||||
+ * spn_tail and see if we can find the SPN.
|
||||
+ */
|
||||
+ for (i = 0; i < n_aliases; i++) {
|
||||
+ struct ldb_dn *colliding_dn = NULL;
|
||||
+ const char *colliding_dnstr = NULL;
|
||||
+
|
||||
+ char *candidate = talloc_asprintf(tmp_ctx,
|
||||
+ "%s/%s",
|
||||
+ aliases[i],
|
||||
+ spn_tail);
|
||||
+ if (candidate == NULL) {
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+
|
||||
+ ret = get_spn_dn(ldb, tmp_ctx, candidate, &colliding_dn);
|
||||
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
+ DBG_DEBUG("SPN alias '%s' not found (good)\n",
|
||||
+ candidate);
|
||||
+ talloc_free(candidate);
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ DBG_ERR("SPN '%s' search error %d\n", candidate, ret);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ target_dnstr = ldb_dn_get_linearized(target_dn);
|
||||
+ /*
|
||||
+ * We have found an existing SPN that matches the alias. That
|
||||
+ * is OK only if it is on the object we are trying to add to,
|
||||
+ * or if the SPN on the other side is a more generic alias for
|
||||
+ * this one and we also have rights to modify it.
|
||||
+ *
|
||||
+ * That is, we can put "host/X" and "cifs/X" on the same
|
||||
+ * object, but not on different objects, unless we put the
|
||||
+ * host/X on first, and could also change that object when we
|
||||
+ * add cifs/X. It is forbidden to add the objects in the other
|
||||
+ * order.
|
||||
+ *
|
||||
+ * The rationale for this is that adding "cifs/X" effectively
|
||||
+ * changes "host/X" by diverting traffic. If "host/X" can be
|
||||
+ * added after "cifs/X", a sneaky person could get "cifs/X" in
|
||||
+ * first, making "host/X" have less effect than intended.
|
||||
+ *
|
||||
+ * Note: we also can't have "host/X" and "Host/X" on the same
|
||||
+ * object, but that is not relevant here.
|
||||
+ */
|
||||
+
|
||||
+ ret = ldb_dn_compare(colliding_dn, target_dn);
|
||||
+ if (ret != 0) {
|
||||
+ colliding_dnstr = ldb_dn_get_linearized(colliding_dn);
|
||||
+ DBG_ERR("trying to add SPN '%s' on '%s' when '%s' is "
|
||||
+ "on '%s'\n",
|
||||
+ spn,
|
||||
+ target_dnstr,
|
||||
+ candidate,
|
||||
+ colliding_dnstr);
|
||||
+
|
||||
+ if (link_direction == SPN_ALIAS_LINK) {
|
||||
+ /* we don't allow host/X if there is a
|
||||
+ * cifs/X */
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
+ }
|
||||
+ ret = check_spn_write_rights(ldb,
|
||||
+ tmp_ctx,
|
||||
+ candidate,
|
||||
+ colliding_dn);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ DBG_ERR("SPN '%s' is on '%s' so '%s' can't be "
|
||||
+ "added to '%s'\n",
|
||||
+ candidate,
|
||||
+ colliding_dnstr,
|
||||
+ spn,
|
||||
+ target_dnstr);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "samldb: spn[%s] would cause a conflict",
|
||||
+ spn);
|
||||
+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
||||
+ }
|
||||
+ } else {
|
||||
+ DBG_INFO("SPNs '%s' and '%s' alias both on '%s'\n",
|
||||
+ candidate, spn, target_dnstr);
|
||||
+ }
|
||||
+ talloc_free(candidate);
|
||||
+ }
|
||||
+
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static int check_spn_direct_collision(struct ldb_context *ldb,
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ const char *spn,
|
||||
+ struct ldb_dn *target_dn)
|
||||
+{
|
||||
+ int ret;
|
||||
+ TALLOC_CTX *tmp_ctx = NULL;
|
||||
+ struct ldb_dn *colliding_dn = NULL;
|
||||
+ const char *target_dnstr = NULL;
|
||||
+ const char *colliding_dnstr = NULL;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(mem_ctx);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+
|
||||
+ ret = get_spn_dn(ldb, tmp_ctx, spn, &colliding_dn);
|
||||
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
+ DBG_DEBUG("SPN '%s' not found (good)\n", spn);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ DBG_ERR("SPN '%s' search error %d\n", spn, ret);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ if (ret == LDB_ERR_COMPARE_TRUE) {
|
||||
+ /*
|
||||
+ * COMPARE_TRUE has special meaning here and we don't
|
||||
+ * want to return it by mistake.
|
||||
+ */
|
||||
+ ret = LDB_ERR_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+ return ret;
|
||||
+ }
|
||||
+ /*
|
||||
+ * We have found this exact SPN. This is mostly harmless (depend on
|
||||
+ * ADD vs REPLACE) when the spn is being put on the object that
|
||||
+ * already has, so we let it through to succeed or fail as some other
|
||||
+ * module sees fit.
|
||||
+ */
|
||||
+ target_dnstr = ldb_dn_get_linearized(target_dn);
|
||||
+ ret = ldb_dn_compare(colliding_dn, target_dn);
|
||||
+ if (ret != 0) {
|
||||
+ colliding_dnstr = ldb_dn_get_linearized(colliding_dn);
|
||||
+ DBG_ERR("SPN '%s' is on '%s' so it can't be "
|
||||
+ "added to '%s'\n",
|
||||
+ spn,
|
||||
+ colliding_dnstr,
|
||||
+ target_dnstr);
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "samldb: spn[%s] would cause a conflict",
|
||||
+ spn);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
+ }
|
||||
+
|
||||
+ DBG_INFO("SPN '%s' is already on '%s'\n",
|
||||
+ spn, target_dnstr);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_ERR_COMPARE_TRUE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Check that "servicePrincipalName" changes do not introduce a collision
|
||||
+ * globally. */
|
||||
+static int samldb_spn_uniqueness_check(struct samldb_ctx *ac,
|
||||
+ struct ldb_message_element *spn_el)
|
||||
+{
|
||||
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
+ int ret;
|
||||
+ const char *spn = NULL;
|
||||
+ size_t i;
|
||||
+ TALLOC_CTX *tmp_ctx = talloc_new(ac->msg);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ldb_oom(ldb);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < spn_el->num_values; i++) {
|
||||
+ spn = (char *)spn_el->values[i].data;
|
||||
+
|
||||
+ ret = check_spn_direct_collision(ldb,
|
||||
+ tmp_ctx,
|
||||
+ spn,
|
||||
+ ac->msg->dn);
|
||||
+ if (ret == LDB_ERR_COMPARE_TRUE) {
|
||||
+ DBG_INFO("SPN %s re-added to the same object\n", spn);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ DBG_ERR("SPN %s failed direct uniqueness check\n", spn);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = check_spn_alias_collision(ldb,
|
||||
+ tmp_ctx,
|
||||
+ spn,
|
||||
+ ac->msg->dn);
|
||||
+
|
||||
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
+ /* we have no sPNMappings, hence no aliases */
|
||||
+ break;
|
||||
+ }
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ DBG_ERR("SPN %s failed alias uniqueness check\n", spn);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ DBG_INFO("SPN %s seems to be unique\n", spn);
|
||||
+ }
|
||||
+
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
/* This trigger adapts the "servicePrincipalName" attributes if the
|
||||
* "dNSHostName" and/or "sAMAccountName" attribute change(s) */
|
||||
static int samldb_service_principal_names_change(struct samldb_ctx *ac)
|
||||
@@ -3498,8 +4038,14 @@ static int samldb_service_principal_names_change(struct samldb_ctx *ac)
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
- /* Potential "servicePrincipalName" changes in the same request have to
|
||||
- * be handled before the update (Windows behaviour). */
|
||||
+ /*
|
||||
+ * Potential "servicePrincipalName" changes in the same request have
|
||||
+ * to be handled before the update (Windows behaviour).
|
||||
+ *
|
||||
+ * We extract the SPN changes into a new message and run it through
|
||||
+ * the stack from this module, so that it subjects them to the SPN
|
||||
+ * checks we have here.
|
||||
+ */
|
||||
el = ldb_msg_find_element(ac->msg, "servicePrincipalName");
|
||||
if (el != NULL) {
|
||||
msg = ldb_msg_new(ac->msg);
|
||||
@@ -3521,7 +4067,7 @@ static int samldb_service_principal_names_change(struct samldb_ctx *ac)
|
||||
} while (el != NULL);
|
||||
|
||||
ret = dsdb_module_modify(ac->module, msg,
|
||||
- DSDB_FLAG_NEXT_MODULE, ac->req);
|
||||
+ DSDB_FLAG_OWN_MODULE, ac->req);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
@@ -4255,6 +4801,19 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req)
|
||||
return samldb_fill_object(ac);
|
||||
}
|
||||
|
||||
+
|
||||
+ el = ldb_msg_find_element(ac->msg, "servicePrincipalName");
|
||||
+ if ((el != NULL)) {
|
||||
+ /*
|
||||
+ * We need to check whether the SPN collides with an existing
|
||||
+ * one (anywhere) including via aliases.
|
||||
+ */
|
||||
+ ret = samldb_spn_uniqueness_check(ac, el);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (samdb_find_attribute(ldb, ac->msg,
|
||||
"objectclass", "subnet") != NULL) {
|
||||
ret = samldb_verify_subnet(ac, ac->msg->dn);
|
||||
@@ -4505,12 +5064,35 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
|
||||
el2 = ldb_msg_find_element(ac->msg, "sAMAccountName");
|
||||
if ((el != NULL) || (el2 != NULL)) {
|
||||
modified = true;
|
||||
+ /*
|
||||
+ * samldb_service_principal_names_change() might add SPN
|
||||
+ * changes to the request, so this must come before the SPN
|
||||
+ * uniqueness check below.
|
||||
+ *
|
||||
+ * Note we ALSO have to do the SPN uniqueness check inside
|
||||
+ * samldb_service_principal_names_change(), because it does a
|
||||
+ * subrequest to do requested SPN modifications *before* its
|
||||
+ * automatic ones are added.
|
||||
+ */
|
||||
ret = samldb_service_principal_names_change(ac);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
+ el = ldb_msg_find_element(ac->msg, "servicePrincipalName");
|
||||
+ if ((el != NULL)) {
|
||||
+ /*
|
||||
+ * We need to check whether the SPN collides with an existing
|
||||
+ * one (anywhere) including via aliases.
|
||||
+ */
|
||||
+ modified = true;
|
||||
+ ret = samldb_spn_uniqueness_check(ac, el);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
el = ldb_msg_find_element(ac->msg, "fSMORoleOwner");
|
||||
if (el != NULL) {
|
||||
ret = samldb_fsmo_role_owner_check(ac);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
From d079628a43f845522598be7efa0abf5e478549c6 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Fri, 8 Oct 2021 18:08:20 +0200
|
||||
Subject: [PATCH 119/266] CVE-2020-25717: s3:auth: no longer let
|
||||
check_account() autocreate local users
|
||||
|
||||
So far we autocreated local user accounts based on just the
|
||||
account_name (just ignoring any domain part).
|
||||
|
||||
This only happens via a possible 'add user script',
|
||||
which is not typically defined on domain members
|
||||
and on NT4 DCs local users already exist in the
|
||||
local passdb anyway.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source3/auth/auth_util.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=d079628a43f845522598be7efa0abf5e478549c6
|
||||
|
||||
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
|
||||
index 4de4bc74374..99b85d47a5f 100644
|
||||
--- a/source3/auth/auth_util.c
|
||||
+++ b/source3/auth/auth_util.c
|
||||
@@ -1898,7 +1898,7 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
- passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
|
||||
+ passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
|
||||
if (!passwd) {
|
||||
DEBUG(3, ("Failed to find authenticated user %s via "
|
||||
"getpwnam(), denying access.\n", dom_user));
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
From 3a4095aec5eb592d4968465930f7fd7e1435e19f Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Fri, 22 Oct 2021 16:03:18 +1300
|
||||
Subject: [PATCH 156/266] CVE-2020-25722 s4/dsdb/samldb: reject SPN with too
|
||||
few/many components
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/3a4095aec5eb592d4968465930f7fd7e1435e19f
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 41 +++++++++++++++++++++++++
|
||||
1 files changed, 41 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index f5141936a60..006658d2bce 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -3868,6 +3868,37 @@ static int check_spn_direct_collision(struct ldb_context *ldb,
|
||||
}
|
||||
|
||||
|
||||
+static int count_spn_components(struct ldb_val val)
|
||||
+{
|
||||
+ /*
|
||||
+ * a 3 part servicePrincipalName has two slashes, like
|
||||
+ * ldap/example.com/DomainDNSZones.example.com.
|
||||
+ *
|
||||
+ * In krb5_parse_name_flags() we don't count "\/" as a slash (i.e.
|
||||
+ * escaped by a backslash), but this is not the behaviour of Windows
|
||||
+ * on setting a servicePrincipalName -- slashes are counted regardless
|
||||
+ * of backslashes.
|
||||
+ *
|
||||
+ * Accordingly, here we ignore backslashes. This will reject
|
||||
+ * multi-slash SPNs that krb5_parse_name_flags() would accept, and
|
||||
+ * allow ones in the form "a\/b" that it won't parse.
|
||||
+ */
|
||||
+ size_t i;
|
||||
+ int slashes = 0;
|
||||
+ for (i = 0; i < val.length; i++) {
|
||||
+ char c = val.data[i];
|
||||
+ if (c == '/') {
|
||||
+ slashes++;
|
||||
+ if (slashes == 3) {
|
||||
+ /* at this point we don't care */
|
||||
+ return 4;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return slashes + 1;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Check that "servicePrincipalName" changes do not introduce a collision
|
||||
* globally. */
|
||||
static int samldb_spn_uniqueness_check(struct samldb_ctx *ac,
|
||||
@@ -3883,8 +3914,18 @@ static int samldb_spn_uniqueness_check(struct samldb_ctx *ac,
|
||||
}
|
||||
|
||||
for (i = 0; i < spn_el->num_values; i++) {
|
||||
+ int n_components;
|
||||
spn = (char *)spn_el->values[i].data;
|
||||
|
||||
+ n_components = count_spn_components(spn_el->values[i]);
|
||||
+ if (n_components > 3 || n_components < 2) {
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "samldb: spn[%s] invalid with %u components",
|
||||
+ spn, n_components);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
+ }
|
||||
+
|
||||
ret = check_spn_direct_collision(ldb,
|
||||
tmp_ctx,
|
||||
spn,
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,181 @@
|
||||
From 844faf2f0ac5d21d65f452fb6f4d1b19bb0a2be2 Mon Sep 17 00:00:00 2001
|
||||
From: Ralph Boehme <slow@samba.org>
|
||||
Date: Fri, 8 Oct 2021 12:33:16 +0200
|
||||
Subject: [PATCH 120/266] CVE-2020-25717: s3:auth: remove fallbacks in
|
||||
smb_getpwnam()
|
||||
|
||||
So far we tried getpwnam("DOMAIN\account") first and
|
||||
always did a fallback to getpwnam("account") completely
|
||||
ignoring the domain part, this just causes problems
|
||||
as we mix "DOMAIN1\account", "DOMAIN2\account",
|
||||
and "account"!
|
||||
|
||||
As we require a running winbindd for domain member setups
|
||||
we should no longer do a fallback to just "account" for
|
||||
users served by winbindd!
|
||||
|
||||
For users of the local SAM don't use this code path,
|
||||
as check_sam_security() doesn't call check_account().
|
||||
|
||||
The only case where smb_getpwnam("account") happens is
|
||||
when map_username() via ("username map [script]") mapped
|
||||
"DOMAIN\account" to something without '\', but that is
|
||||
explicitly desired by the admin.
|
||||
|
||||
Note: use 'git show -w'
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
|
||||
|
||||
Signed-off-by: Ralph Boehme <slow@samba.org>
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
selftest/knownfail.d/ktest | 26 +++++++++++++
|
||||
source3/auth/auth_util.c | 77 +++++++++++++++++++++-----------------
|
||||
2 files changed, 68 insertions(+), 35 deletions(-)
|
||||
create mode 100644 selftest/knownfail.d/ktest
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=844faf2f0ac5d21d65f452fb6f4d1b19bb0a2be2
|
||||
|
||||
diff --git a/selftest/knownfail.d/ktest b/selftest/knownfail.d/ktest
|
||||
new file mode 100644
|
||||
index 00000000000..809612ba0b9
|
||||
--- /dev/null
|
||||
+++ b/selftest/knownfail.d/ktest
|
||||
@@ -0,0 +1,26 @@
|
||||
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest
|
||||
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest
|
||||
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5...rpcclient.ktest:local
|
||||
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5...rpcclient.ktest:local
|
||||
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest
|
||||
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest
|
||||
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest
|
||||
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest
|
||||
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,packet...rpcclient.ktest:local
|
||||
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,packet...rpcclient.ktest:local
|
||||
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest
|
||||
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest
|
||||
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,sign...rpcclient.ktest:local
|
||||
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,sign...rpcclient.ktest:local
|
||||
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest
|
||||
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest
|
||||
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,seal...rpcclient.ktest:local
|
||||
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,seal...rpcclient.ktest:local
|
||||
+^samba3.blackbox.smbclient_krb5.old.ccache..smbclient.ktest:local
|
||||
+^samba3.blackbox.smbclient_krb5.new.ccache..smbclient.ktest:local
|
||||
+^samba3.blackbox.smbclient_large_file..krb5.smbclient.large.posix.write.read.ktest:local
|
||||
+^samba3.blackbox.smbclient_large_file..krb5.cmp.of.read.and.written.files.ktest:local
|
||||
+^samba3.blackbox.smbclient_krb5.old.ccache.--client-protection=encrypt.smbclient.ktest:local
|
||||
+^samba3.blackbox.smbclient_krb5.new.ccache.--client-protection=encrypt.smbclient.ktest:local
|
||||
+^samba3.blackbox.smbclient_large_file.--client-protection=encrypt.krb5.smbclient.large.posix.write.read.ktest:local
|
||||
+^samba3.blackbox.smbclient_large_file.--client-protection=encrypt.krb5.cmp.of.read.and.written.files.ktest:local
|
||||
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
|
||||
index 99b85d47a5f..d81313a0495 100644
|
||||
--- a/source3/auth/auth_util.c
|
||||
+++ b/source3/auth/auth_util.c
|
||||
@@ -1933,7 +1933,7 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
|
||||
{
|
||||
struct passwd *pw = NULL;
|
||||
char *p = NULL;
|
||||
- char *username = NULL;
|
||||
+ const char *username = NULL;
|
||||
|
||||
/* we only save a copy of the username it has been mangled
|
||||
by winbindd use default domain */
|
||||
@@ -1952,48 +1952,55 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
|
||||
/* code for a DOMAIN\user string */
|
||||
|
||||
if ( p ) {
|
||||
- pw = Get_Pwnam_alloc( mem_ctx, domuser );
|
||||
- if ( pw ) {
|
||||
- /* make sure we get the case of the username correct */
|
||||
- /* work around 'winbind use default domain = yes' */
|
||||
-
|
||||
- if ( lp_winbind_use_default_domain() &&
|
||||
- !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
|
||||
- char *domain;
|
||||
-
|
||||
- /* split the domain and username into 2 strings */
|
||||
- *p = '\0';
|
||||
- domain = username;
|
||||
-
|
||||
- *p_save_username = talloc_asprintf(mem_ctx,
|
||||
- "%s%c%s",
|
||||
- domain,
|
||||
- *lp_winbind_separator(),
|
||||
- pw->pw_name);
|
||||
- if (!*p_save_username) {
|
||||
- TALLOC_FREE(pw);
|
||||
- return NULL;
|
||||
- }
|
||||
- } else {
|
||||
- *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
|
||||
- }
|
||||
+ const char *domain = NULL;
|
||||
|
||||
- /* whew -- done! */
|
||||
- return pw;
|
||||
+ /* split the domain and username into 2 strings */
|
||||
+ *p = '\0';
|
||||
+ domain = username;
|
||||
+ p++;
|
||||
+ username = p;
|
||||
+
|
||||
+ if (strequal(domain, get_global_sam_name())) {
|
||||
+ /*
|
||||
+ * This typically don't happen
|
||||
+ * as check_sam_Security()
|
||||
+ * don't call make_server_info_info3()
|
||||
+ * and thus check_account().
|
||||
+ *
|
||||
+ * But we better keep this.
|
||||
+ */
|
||||
+ goto username_only;
|
||||
}
|
||||
|
||||
- /* setup for lookup of just the username */
|
||||
- /* remember that p and username are overlapping memory */
|
||||
-
|
||||
- p++;
|
||||
- username = talloc_strdup(mem_ctx, p);
|
||||
- if (!username) {
|
||||
+ pw = Get_Pwnam_alloc( mem_ctx, domuser );
|
||||
+ if (pw == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
+ /* make sure we get the case of the username correct */
|
||||
+ /* work around 'winbind use default domain = yes' */
|
||||
+
|
||||
+ if ( lp_winbind_use_default_domain() &&
|
||||
+ !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
|
||||
+ *p_save_username = talloc_asprintf(mem_ctx,
|
||||
+ "%s%c%s",
|
||||
+ domain,
|
||||
+ *lp_winbind_separator(),
|
||||
+ pw->pw_name);
|
||||
+ if (!*p_save_username) {
|
||||
+ TALLOC_FREE(pw);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ } else {
|
||||
+ *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
|
||||
+ }
|
||||
+
|
||||
+ /* whew -- done! */
|
||||
+ return pw;
|
||||
+
|
||||
}
|
||||
|
||||
/* just lookup a plain username */
|
||||
-
|
||||
+username_only:
|
||||
pw = Get_Pwnam_alloc(mem_ctx, username);
|
||||
|
||||
/* Create local user if requested but only if winbindd
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,178 @@
|
||||
From 208bbf8cfda200deaeddfad77e4b43d54e692ba5 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:09:21 +1300
|
||||
Subject: [PATCH 157/266] CVE-2020-25722 s4/dsdb modules: add
|
||||
dsdb_get_expected_new_values()
|
||||
|
||||
This function collects a superset of all the new values for the specified
|
||||
attribute that could result from an ldb add or modify message.
|
||||
|
||||
In most cases -- where there is a single add or modify -- the exact set
|
||||
of added values is returned, and this is done reasonably efficiently
|
||||
using the existing element. Where it gets complicated is when there are
|
||||
multiple elements for the same attribute in a message. Anything added
|
||||
before a replace or delete will be included in these results but may not
|
||||
end up in the database if the message runs its course. Examples:
|
||||
|
||||
sequence result
|
||||
1. ADD the element is returned (exact)
|
||||
2. REPLACE the element is returned (exact)
|
||||
3. ADD, ADD both elements are concatenated together (exact)
|
||||
4. ADD, REPLACE both elements are concatenated together (superset)
|
||||
5. REPLACE, ADD both elements are concatenated together (exact)
|
||||
6. ADD, DEL, ADD adds are concatenated together (superset)
|
||||
7. REPLACE, REPLACE both concatenated (superset)
|
||||
8. DEL, ADD last element is returned (exact)
|
||||
|
||||
Why this? In the past we have treated dsdb_get_single_valued_attr() as if
|
||||
it returned the complete set of possible database changes, when in fact it
|
||||
only returned the last non-delete. That is, it could have missed values
|
||||
in examples 3-7 above.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/208bbf8cfda200deaeddfad77e4b43d54e692ba5
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/util.c | 121 ++++++++++++++++++++++++++
|
||||
1 file changed, 121 insertions(+)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c
|
||||
index 9519ecfa928..da152e4d754 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/util.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/util.c
|
||||
@@ -1441,6 +1441,127 @@ void dsdb_req_chain_debug(struct ldb_request *req, int level)
|
||||
talloc_free(s);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Get all the values that *might* be added by an ldb message, as a composite
|
||||
+ * ldb element.
|
||||
+ *
|
||||
+ * This is useful when we need to check all the possible values against some
|
||||
+ * criteria.
|
||||
+ *
|
||||
+ * In cases where a modify message mixes multiple ADDs, DELETEs, and REPLACES,
|
||||
+ * the returned element might contain more values than would actually end up
|
||||
+ * in the database if the message was run to its conclusion.
|
||||
+ *
|
||||
+ * If the operation is not LDB_ADD or LDB_MODIFY, an operations error is
|
||||
+ * returned.
|
||||
+ *
|
||||
+ * The returned element might not be new, and should not be modified or freed
|
||||
+ * before the message is finished.
|
||||
+ */
|
||||
+
|
||||
+int dsdb_get_expected_new_values(TALLOC_CTX *mem_ctx,
|
||||
+ const struct ldb_message *msg,
|
||||
+ const char *attr_name,
|
||||
+ struct ldb_message_element **el,
|
||||
+ enum ldb_request_type operation)
|
||||
+{
|
||||
+ unsigned int i;
|
||||
+ unsigned int el_count = 0;
|
||||
+ unsigned int val_count = 0;
|
||||
+ struct ldb_val *v = NULL;
|
||||
+ struct ldb_message_element *_el = NULL;
|
||||
+ *el = NULL;
|
||||
+
|
||||
+ if (operation != LDB_ADD && operation != LDB_MODIFY) {
|
||||
+ DBG_ERR("inapplicable operation type: %d\n", operation);
|
||||
+ return LDB_ERR_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ /* count the adding or replacing elements */
|
||||
+ for (i = 0; i < msg->num_elements; i++) {
|
||||
+ if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) {
|
||||
+ unsigned int tmp;
|
||||
+ if ((operation == LDB_MODIFY) &&
|
||||
+ (LDB_FLAG_MOD_TYPE(msg->elements[i].flags)
|
||||
+ == LDB_FLAG_MOD_DELETE)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ el_count++;
|
||||
+ tmp = val_count + msg->elements[i].num_values;
|
||||
+ if (unlikely(tmp < val_count)) {
|
||||
+ DBG_ERR("too many values for one element!");
|
||||
+ return LDB_ERR_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+ val_count = tmp;
|
||||
+ }
|
||||
+ }
|
||||
+ if (el_count == 0) {
|
||||
+ /* nothing to see here */
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ if (el_count == 1 || val_count == 0) {
|
||||
+ /*
|
||||
+ * There is one effective element, which we can return as-is,
|
||||
+ * OR there are only elements with zero values -- any of which
|
||||
+ * will do.
|
||||
+ */
|
||||
+ for (i = 0; i < msg->num_elements; i++) {
|
||||
+ if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) {
|
||||
+ if ((operation == LDB_MODIFY) &&
|
||||
+ (LDB_FLAG_MOD_TYPE(msg->elements[i].flags)
|
||||
+ == LDB_FLAG_MOD_DELETE)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ *el = &msg->elements[i];
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ _el = talloc_zero(mem_ctx, struct ldb_message_element);
|
||||
+ if (_el == NULL) {
|
||||
+ return LDB_ERR_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+ _el->name = attr_name;
|
||||
+
|
||||
+ if (val_count == 0) {
|
||||
+ /*
|
||||
+ * Seems unlikely, but sometimes we might be adding zero
|
||||
+ * values in multiple separate elements. The talloc zero has
|
||||
+ * already set the expected values = NULL, num_values = 0.
|
||||
+ */
|
||||
+ *el = _el;
|
||||
+ return LDB_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ _el->values = talloc_array(_el, struct ldb_val, val_count);
|
||||
+ if (_el->values == NULL) {
|
||||
+ talloc_free(_el);
|
||||
+ return LDB_ERR_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+ _el->num_values = val_count;
|
||||
+
|
||||
+ v = _el->values;
|
||||
+
|
||||
+ for (i = 0; i < val_count; i++) {
|
||||
+ if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) {
|
||||
+ if ((operation == LDB_MODIFY) &&
|
||||
+ (LDB_FLAG_MOD_TYPE(msg->elements[i].flags)
|
||||
+ == LDB_FLAG_MOD_DELETE)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ memcpy(v,
|
||||
+ msg->elements[i].values,
|
||||
+ msg->elements[i].num_values);
|
||||
+ v += msg->elements[i].num_values;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *el = _el;
|
||||
+ return LDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Gets back a single-valued attribute by the rules of the DSDB triggers when
|
||||
* performing a modify operation.
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
From e8e0bea9b333315ec1ff9eb1d36d4e810ca95941 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Mon, 4 Oct 2021 18:03:55 +0200
|
||||
Subject: [PATCH 122/266] CVE-2020-25717: s3:auth: don't let create_local_token
|
||||
depend on !winbind_ping()
|
||||
|
||||
We always require a running winbindd on a domain member, so
|
||||
we should better fail a request instead of silently alter
|
||||
the behaviour, which results in a different unix token, just
|
||||
because winbindd might be restarted.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source3/auth/auth_util.c | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=e8e0bea9b333315ec1ff9eb1d36d4e810ca95941
|
||||
|
||||
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
|
||||
index d81313a0495..065b525500f 100644
|
||||
--- a/source3/auth/auth_util.c
|
||||
+++ b/source3/auth/auth_util.c
|
||||
@@ -576,13 +576,11 @@ NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
/*
|
||||
- * If winbind is not around, we can not make much use of the SIDs the
|
||||
- * domain controller provided us with. Likewise if the user name was
|
||||
- * mapped to some local unix user.
|
||||
+ * If the user name was mapped to some local unix user,
|
||||
+ * we can not make much use of the SIDs the
|
||||
+ * domain controller provided us with.
|
||||
*/
|
||||
-
|
||||
- if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
|
||||
- (server_info->nss_token)) {
|
||||
+ if (server_info->nss_token) {
|
||||
char *found_username = NULL;
|
||||
status = create_token_from_username(session_info,
|
||||
server_info->unix_name,
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
From 7913ec038f25b1778dfe545766266c70502e7c63 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:10:44 +1300
|
||||
Subject: [PATCH 158/266] CVE-2020-25722 s4/dsdb/samldb:
|
||||
samldb_get_single_valued_attr() check all values
|
||||
|
||||
using dsdb_get_expected_new_values().
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/7913ec038f25b1778dfe545766266c70502e7c63
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 006658d2bce..4bd40a5ef1f 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -171,11 +171,19 @@ static int samldb_get_single_valued_attr(struct ldb_context *ldb,
|
||||
* attribute.
|
||||
*/
|
||||
struct ldb_message_element *el = NULL;
|
||||
+ int ret;
|
||||
|
||||
*value = NULL;
|
||||
|
||||
- el = dsdb_get_single_valued_attr(ac->msg, attr,
|
||||
- ac->req->operation);
|
||||
+ ret = dsdb_get_expected_new_values(ac,
|
||||
+ ac->msg,
|
||||
+ attr,
|
||||
+ &el,
|
||||
+ ac->req->operation);
|
||||
+
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
if (el == NULL) {
|
||||
/* we are not affected */
|
||||
return LDB_SUCCESS;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
From eba5e1321830624e6e42d248616f651beb0d3b99 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Tue, 5 Oct 2021 18:11:57 +0200
|
||||
Subject: [PATCH 124/266] CVE-2020-25719 CVE-2020-25717: auth/gensec: always
|
||||
require a PAC in domain mode (DC or member)
|
||||
|
||||
AD domains always provide a PAC unless UF_NO_AUTH_DATA_REQUIRED is set
|
||||
on the service account, which can only be explicitly configured,
|
||||
but that's an invalid configuration!
|
||||
|
||||
We still try to support standalone servers in an MIT realm,
|
||||
as legacy setup.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
[jsutton@samba.org Removed knownfail entries]
|
||||
---
|
||||
auth/gensec/gensec_util.c | 27 +++++++++++++++++++++++----
|
||||
1 files changed, 23 insertions(+), 4 deletions(-)
|
||||
delete mode 100644 selftest/knownfail.d/no-pac
|
||||
|
||||
Conflict:delete a chunk which delete a file do not exist
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=eba5e1321830624e6e42d248616f651beb0d3b99
|
||||
|
||||
diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c
|
||||
index e185acc0c20..694661b53b5 100644
|
||||
--- a/auth/gensec/gensec_util.c
|
||||
+++ b/auth/gensec/gensec_util.c
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "auth/gensec/gensec_internal.h"
|
||||
#include "auth/common_auth.h"
|
||||
#include "../lib/util/asn1.h"
|
||||
+#include "param/param.h"
|
||||
+#include "libds/common/roles.h"
|
||||
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_AUTH
|
||||
@@ -46,10 +48,27 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx,
|
||||
session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
|
||||
|
||||
if (!pac_blob) {
|
||||
- if (gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) {
|
||||
- DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n",
|
||||
- principal_string));
|
||||
- return NT_STATUS_ACCESS_DENIED;
|
||||
+ enum server_role server_role =
|
||||
+ lpcfg_server_role(gensec_security->settings->lp_ctx);
|
||||
+
|
||||
+ /*
|
||||
+ * For any domain setup (DC or member) we require having
|
||||
+ * a PAC, as the service ticket comes from an AD DC,
|
||||
+ * which will always provide a PAC, unless
|
||||
+ * UF_NO_AUTH_DATA_REQUIRED is configured for our
|
||||
+ * account, but that's just an invalid configuration,
|
||||
+ * the admin configured for us!
|
||||
+ *
|
||||
+ * As a legacy case, we still allow kerberos tickets from an MIT
|
||||
+ * realm, but only in standalone mode. In that mode we'll only
|
||||
+ * ever accept a kerberos authentication with a keytab file
|
||||
+ * being explicitly configured via the 'keytab method' option.
|
||||
+ */
|
||||
+ if (server_role != ROLE_STANDALONE) {
|
||||
+ DBG_WARNING("Unable to find PAC in ticket from %s, "
|
||||
+ "failing to allow access\n",
|
||||
+ principal_string);
|
||||
+ return NT_STATUS_NO_IMPERSONATION_TOKEN;
|
||||
}
|
||||
DBG_NOTICE("Unable to find PAC for %s, resorting to local "
|
||||
"user lookup\n", principal_string);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
From 437465a90eff051762f347cb5537107f2234af01 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Fri, 22 Oct 2021 14:52:49 +1300
|
||||
Subject: [PATCH 159/266] CVE-2020-25722 s4/dsdb/samldb:
|
||||
samldb_sam_accountname_valid_check() check all values
|
||||
|
||||
Using dsdb_get_expected_new_values().
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/437465a90eff051762f347cb5537107f2234af01
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 4bd40a5ef1f..5d3e0f9771c 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -530,8 +530,17 @@ static int samldb_sam_accountname_valid_check(struct samldb_ctx *ac)
|
||||
bool is_admin;
|
||||
struct security_token *user_token = NULL;
|
||||
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
- struct ldb_message_element *el = dsdb_get_single_valued_attr(ac->msg, "samAccountName",
|
||||
- ac->req->operation);
|
||||
+ struct ldb_message_element *el = NULL;
|
||||
+
|
||||
+ ret = dsdb_get_expected_new_values(ac,
|
||||
+ ac->msg,
|
||||
+ "samAccountName",
|
||||
+ &el,
|
||||
+ ac->req->operation);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (el == NULL || el->num_values == 0) {
|
||||
ldb_asprintf_errstring(ldb,
|
||||
"%08X: samldb: 'samAccountName' can't be deleted/empty!",
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
From 9f73360e17d1e519d25cb4b60d7506fca9fd02fe Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Tue, 21 Sep 2021 12:27:28 +0200
|
||||
Subject: [PATCH 126/266] CVE-2020-25717: s3:ntlm_auth: fix memory leaks in
|
||||
ntlm_auth_generate_session_info_pac()
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source3/utils/ntlm_auth.c | 18 ++++++++++++------
|
||||
1 file changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=9f73360e17d1e519d25cb4b60d7506fca9fd02fe
|
||||
|
||||
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
|
||||
index 1d22a48c57c..e6efdfcec5c 100644
|
||||
--- a/source3/utils/ntlm_auth.c
|
||||
+++ b/source3/utils/ntlm_auth.c
|
||||
@@ -817,23 +817,27 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
|
||||
if (!p) {
|
||||
DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
|
||||
princ_name));
|
||||
- return NT_STATUS_LOGON_FAILURE;
|
||||
+ status = NT_STATUS_LOGON_FAILURE;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
user = talloc_strndup(mem_ctx, princ_name, p - princ_name);
|
||||
if (!user) {
|
||||
- return NT_STATUS_NO_MEMORY;
|
||||
+ status = NT_STATUS_NO_MEMORY;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
realm = talloc_strdup(talloc_tos(), p + 1);
|
||||
if (!realm) {
|
||||
- return NT_STATUS_NO_MEMORY;
|
||||
+ status = NT_STATUS_NO_MEMORY;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
if (!strequal(realm, lp_realm())) {
|
||||
DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm));
|
||||
if (!lp_allow_trusted_domains()) {
|
||||
- return NT_STATUS_LOGON_FAILURE;
|
||||
+ status = NT_STATUS_LOGON_FAILURE;
|
||||
+ goto done;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -841,7 +845,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
|
||||
domain = talloc_strdup(mem_ctx,
|
||||
logon_info->info3.base.logon_domain.string);
|
||||
if (!domain) {
|
||||
- return NT_STATUS_NO_MEMORY;
|
||||
+ status = NT_STATUS_NO_MEMORY;
|
||||
+ goto done;
|
||||
}
|
||||
DEBUG(10, ("Domain is [%s] (using PAC)\n", domain));
|
||||
} else {
|
||||
@@ -871,7 +876,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
|
||||
domain = talloc_strdup(mem_ctx, realm);
|
||||
}
|
||||
if (!domain) {
|
||||
- return NT_STATUS_NO_MEMORY;
|
||||
+ status = NT_STATUS_NO_MEMORY;
|
||||
+ goto done;
|
||||
}
|
||||
DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain));
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From 466620563bdbb31858e82462cdc0ae62605c9206 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:12:49 +1300
|
||||
Subject: [PATCH 160/266] CVE-2020-25722 s4/dsdb/samldb:
|
||||
samldb_schema_add_handle_linkid() checks all values
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/466620563bdbb31858e82462cdc0ae62605c9206
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 5d3e0f9771c..39533266aeb 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -739,8 +739,15 @@ static int samldb_schema_add_handle_linkid(struct samldb_ctx *ac)
|
||||
schema = dsdb_get_schema(ldb, ac);
|
||||
schema_dn = ldb_get_schema_basedn(ldb);
|
||||
|
||||
- el = dsdb_get_single_valued_attr(ac->msg, "linkID",
|
||||
- ac->req->operation);
|
||||
+ ret = dsdb_get_expected_new_values(ac,
|
||||
+ ac->msg,
|
||||
+ "linkID",
|
||||
+ &el,
|
||||
+ ac->req->operation);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (el == NULL) {
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,145 @@
|
||||
From 131d5ceb9deaaa1d8dd478a9b2e2556133c511aa Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Tue, 21 Sep 2021 12:44:01 +0200
|
||||
Subject: [PATCH 127/266] CVE-2020-25717: s3:ntlm_auth: let
|
||||
ntlm_auth_generate_session_info_pac() base the name on the PAC LOGON_INFO
|
||||
only
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source3/utils/ntlm_auth.c | 91 ++++++++++++---------------------------
|
||||
1 file changed, 28 insertions(+), 63 deletions(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=131d5ceb9deaaa1d8dd478a9b2e2556133c511aa
|
||||
|
||||
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
|
||||
index e6efdfcec5c..5541c58350b 100644
|
||||
--- a/source3/utils/ntlm_auth.c
|
||||
+++ b/source3/utils/ntlm_auth.c
|
||||
@@ -789,10 +789,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
|
||||
struct PAC_LOGON_INFO *logon_info = NULL;
|
||||
char *unixuser;
|
||||
NTSTATUS status;
|
||||
- char *domain = NULL;
|
||||
- char *realm = NULL;
|
||||
- char *user = NULL;
|
||||
- char *p;
|
||||
+ const char *domain = "";
|
||||
+ const char *user = "";
|
||||
|
||||
tmp_ctx = talloc_new(mem_ctx);
|
||||
if (!tmp_ctx) {
|
||||
@@ -809,79 +807,46 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto done;
|
||||
}
|
||||
- }
|
||||
-
|
||||
- DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
|
||||
-
|
||||
- p = strchr_m(princ_name, '@');
|
||||
- if (!p) {
|
||||
- DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
|
||||
- princ_name));
|
||||
- status = NT_STATUS_LOGON_FAILURE;
|
||||
+ } else {
|
||||
+ status = NT_STATUS_ACCESS_DENIED;
|
||||
+ DBG_WARNING("Kerberos ticket for[%s] has no PAC: %s\n",
|
||||
+ princ_name, nt_errstr(status));
|
||||
goto done;
|
||||
}
|
||||
|
||||
- user = talloc_strndup(mem_ctx, princ_name, p - princ_name);
|
||||
- if (!user) {
|
||||
- status = NT_STATUS_NO_MEMORY;
|
||||
- goto done;
|
||||
+ if (logon_info->info3.base.account_name.string != NULL) {
|
||||
+ user = logon_info->info3.base.account_name.string;
|
||||
+ } else {
|
||||
+ user = "";
|
||||
+ }
|
||||
+ if (logon_info->info3.base.logon_domain.string != NULL) {
|
||||
+ domain = logon_info->info3.base.logon_domain.string;
|
||||
+ } else {
|
||||
+ domain = "";
|
||||
}
|
||||
|
||||
- realm = talloc_strdup(talloc_tos(), p + 1);
|
||||
- if (!realm) {
|
||||
- status = NT_STATUS_NO_MEMORY;
|
||||
+ if (strlen(user) == 0 || strlen(domain) == 0) {
|
||||
+ status = NT_STATUS_ACCESS_DENIED;
|
||||
+ DBG_WARNING("Kerberos ticket for[%s] has invalid "
|
||||
+ "account_name[%s]/logon_domain[%s]: %s\n",
|
||||
+ princ_name,
|
||||
+ logon_info->info3.base.account_name.string,
|
||||
+ logon_info->info3.base.logon_domain.string,
|
||||
+ nt_errstr(status));
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if (!strequal(realm, lp_realm())) {
|
||||
- DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm));
|
||||
+ DBG_NOTICE("Kerberos ticket principal name is [%s] "
|
||||
+ "account_name[%s]/logon_domain[%s]\n",
|
||||
+ princ_name, user, domain);
|
||||
+
|
||||
+ if (!strequal(domain, lp_workgroup())) {
|
||||
if (!lp_allow_trusted_domains()) {
|
||||
status = NT_STATUS_LOGON_FAILURE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
- if (logon_info && logon_info->info3.base.logon_domain.string) {
|
||||
- domain = talloc_strdup(mem_ctx,
|
||||
- logon_info->info3.base.logon_domain.string);
|
||||
- if (!domain) {
|
||||
- status = NT_STATUS_NO_MEMORY;
|
||||
- goto done;
|
||||
- }
|
||||
- DEBUG(10, ("Domain is [%s] (using PAC)\n", domain));
|
||||
- } else {
|
||||
-
|
||||
- /* If we have winbind running, we can (and must) shorten the
|
||||
- username by using the short netbios name. Otherwise we will
|
||||
- have inconsistent user names. With Kerberos, we get the
|
||||
- fully qualified realm, with ntlmssp we get the short
|
||||
- name. And even w2k3 does use ntlmssp if you for example
|
||||
- connect to an ip address. */
|
||||
-
|
||||
- wbcErr wbc_status;
|
||||
- struct wbcDomainInfo *info = NULL;
|
||||
-
|
||||
- DEBUG(10, ("Mapping [%s] to short name using winbindd\n",
|
||||
- realm));
|
||||
-
|
||||
- wbc_status = wbcDomainInfo(realm, &info);
|
||||
-
|
||||
- if (WBC_ERROR_IS_OK(wbc_status)) {
|
||||
- domain = talloc_strdup(mem_ctx,
|
||||
- info->short_name);
|
||||
- wbcFreeMemory(info);
|
||||
- } else {
|
||||
- DEBUG(3, ("Could not find short name: %s\n",
|
||||
- wbcErrorString(wbc_status)));
|
||||
- domain = talloc_strdup(mem_ctx, realm);
|
||||
- }
|
||||
- if (!domain) {
|
||||
- status = NT_STATUS_NO_MEMORY;
|
||||
- goto done;
|
||||
- }
|
||||
- DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain));
|
||||
- }
|
||||
-
|
||||
unixuser = talloc_asprintf(tmp_ctx, "%s%c%s", domain, winbind_separator(), user);
|
||||
if (!unixuser) {
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From 57f7b13f70d6a5802fd31f06f71cfd65347781af Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:13:35 +1300
|
||||
Subject: [PATCH 161/266] CVE-2020-25722 s4/dsdb/samldb:
|
||||
samldb_schema_add_handle_mapiid() checks all values
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/57f7b13f70d6a5802fd31f06f71cfd65347781af
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 39533266aeb..5b2c2fc29aa 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -907,8 +907,15 @@ static int samldb_schema_add_handle_mapiid(struct samldb_ctx *ac)
|
||||
schema = dsdb_get_schema(ldb, ac);
|
||||
schema_dn = ldb_get_schema_basedn(ldb);
|
||||
|
||||
- el = dsdb_get_single_valued_attr(ac->msg, "mAPIID",
|
||||
- ac->req->operation);
|
||||
+ ret = dsdb_get_expected_new_values(ac,
|
||||
+ ac->msg,
|
||||
+ "mAPIID",
|
||||
+ &el,
|
||||
+ ac->req->operation);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (el == NULL) {
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From 18e4c639dfca246d198f2407d39ac5b85bb747f9 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:14:05 +1300
|
||||
Subject: [PATCH 162/266] CVE-2020-25722 s4/dsdb/samldb:
|
||||
samldb_prim_group_change() checks all values
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/18e4c639dfca246d198f2407d39ac5b85bb747f9
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 5b2c2fc29aa..ba56cf8826e 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -2121,8 +2121,15 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
|
||||
int ret;
|
||||
const char * const noattrs[] = { NULL };
|
||||
|
||||
- el = dsdb_get_single_valued_attr(ac->msg, "primaryGroupID",
|
||||
- ac->req->operation);
|
||||
+ ret = dsdb_get_expected_new_values(ac,
|
||||
+ ac->msg,
|
||||
+ "primaryGroupID",
|
||||
+ &el,
|
||||
+ ac->req->operation);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (el == NULL) {
|
||||
/* we are not affected */
|
||||
return LDB_SUCCESS;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
From dc4b1e39ce1f2201a2d6ae2d4cffef2448f69a62 Mon Sep 17 00:00:00 2001
|
||||
From: Ralph Boehme <slow@samba.org>
|
||||
Date: Sat, 18 Jan 2020 08:06:45 +0100
|
||||
Subject: [PATCH] s3/auth: use set_current_user_info() in
|
||||
auth3_generate_session_info_pac()
|
||||
|
||||
This delays reloading config slightly, but I don't see how could affect
|
||||
observable behaviour other then log messages coming from the functions in
|
||||
between the different locations for lp_load_with_shares() like
|
||||
make_session_info_krb5() are sent to a different logfile if "log file" uses %U.
|
||||
|
||||
Signed-off-by: Ralph Boehme <slow@samba.org>
|
||||
Reviewed-by: Andreas Schneider <asn@samba.org>
|
||||
---
|
||||
source3/auth/auth_generic.c | 14 ++++++++------
|
||||
1 file changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/samba-team/samba/commit/dc4b1e39ce1f2201a2d6ae2d4cffef2448f69a62
|
||||
|
||||
diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
|
||||
index 9243a0ba02d3..0e9500ac08d1 100644
|
||||
--- a/source3/auth/auth_generic.c
|
||||
+++ b/source3/auth/auth_generic.c
|
||||
@@ -159,12 +159,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
- /* setup the string used by %U */
|
||||
- sub_set_smb_name(username);
|
||||
-
|
||||
- /* reload services so that the new %U is taken into account */
|
||||
- lp_load_with_shares(get_dyn_CONFIGFILE());
|
||||
-
|
||||
status = make_session_info_krb5(mem_ctx,
|
||||
ntuser, ntdomain, username, pw,
|
||||
info3_copy, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
|
||||
@@ -176,6 +170,14 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ /* setup the string used by %U */
|
||||
+ set_current_user_info((*session_info)->unix_info->sanitized_username,
|
||||
+ (*session_info)->unix_info->unix_name,
|
||||
+ (*session_info)->info->domain_name);
|
||||
+
|
||||
+ /* reload services so that the new %U is taken into account */
|
||||
+ lp_load_with_shares(get_dyn_CONFIGFILE());
|
||||
+
|
||||
DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
|
||||
ntuser, ntdomain, rhost));
|
||||
|
||||
@ -0,0 +1,319 @@
|
||||
From a152f36b0576737e647dbe5f1954039668123c1f Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Mon, 4 Oct 2021 19:42:20 +0200
|
||||
Subject: [PATCH 128/266] CVE-2020-25717: s3:auth: let
|
||||
auth3_generate_session_info_pac() delegate everything to
|
||||
make_server_info_wbcAuthUserInfo()
|
||||
|
||||
This consolidates the code paths used for NTLMSSP and Kerberos!
|
||||
|
||||
I checked what we were already doing for NTLMSSP, which is this:
|
||||
|
||||
a) source3/auth/auth_winbind.c calls wbcAuthenticateUserEx()
|
||||
b) as a domain member we require a valid response from winbindd,
|
||||
otherwise we'll return NT_STATUS_NO_LOGON_SERVERS
|
||||
c) we call make_server_info_wbcAuthUserInfo(), which internally
|
||||
calls make_server_info_info3()
|
||||
d) auth_check_ntlm_password() calls
|
||||
smb_pam_accountcheck(unix_username, rhost), where rhost
|
||||
is only an ipv4 or ipv6 address (without reverse dns lookup)
|
||||
e) from auth3_check_password_send/auth3_check_password_recv()
|
||||
server_returned_info will be passed to auth3_generate_session_info(),
|
||||
triggered by gensec_session_info(), which means we'll call into
|
||||
create_local_token() in order to transform auth_serversupplied_info
|
||||
into auth_session_info.
|
||||
|
||||
For Kerberos gensec_session_info() will call
|
||||
auth3_generate_session_info_pac() via the gensec_generate_session_info_pac()
|
||||
helper function. The current logic is this:
|
||||
|
||||
a) gensec_generate_session_info_pac() is the function that
|
||||
evaluates the 'gensec:require_pac', which defaulted to 'no'
|
||||
before.
|
||||
b) auth3_generate_session_info_pac() called
|
||||
wbcAuthenticateUserEx() in order to pass the PAC blob
|
||||
to winbindd, but only to prime its cache, e.g. netsamlogon cache
|
||||
and others. Most failures were just ignored.
|
||||
c) If the PAC blob is available, it extracted the PAC_LOGON_INFO
|
||||
from it.
|
||||
d) Then we called the horrible get_user_from_kerberos_info() function:
|
||||
- It uses a first part of the tickets principal name (before the @)
|
||||
as username and combines that with the 'logon_info->base.logon_domain'
|
||||
if the logon_info (PAC) is present.
|
||||
- As a fallback without a PAC it's tries to ask winbindd for a mapping
|
||||
from realm to netbios domain name.
|
||||
- Finally is falls back to using the realm as netbios domain name
|
||||
With this information is builds 'userdomain+winbind_separator+useraccount'
|
||||
and calls map_username() followed by smb_getpwnam() with create=true,
|
||||
Note this is similar to the make_server_info_info3() => check_account()
|
||||
=> smb_getpwnam() logic under 3.
|
||||
- It also calls smb_pam_accountcheck(), but may pass the reverse DNS lookup name
|
||||
instead of the ip address as rhost.
|
||||
- It does some MAP_TO_GUEST_ON_BAD_UID logic and auto creates the
|
||||
guest account.
|
||||
e) We called create_info3_from_pac_logon_info()
|
||||
f) make_session_info_krb5() calls gets called and triggers this:
|
||||
- If get_user_from_kerberos_info() mapped to guest, it calls
|
||||
make_server_info_guest()
|
||||
- If create_info3_from_pac_logon_info() created a info3 from logon_info,
|
||||
it calls make_server_info_info3()
|
||||
- Without a PAC it tries pdb_getsampwnam()/make_server_info_sam() with
|
||||
a fallback to make_server_info_pw()
|
||||
From there it calls create_local_token()
|
||||
|
||||
I tried to change auth3_generate_session_info_pac() to behave similar
|
||||
to auth_winbind.c together with auth3_generate_session_info() as
|
||||
a domain member, as we now rely on a PAC:
|
||||
|
||||
a) As domain member we require a PAC and always call wbcAuthenticateUserEx()
|
||||
and require a valid response!
|
||||
b) we call make_server_info_wbcAuthUserInfo(), which internally
|
||||
calls make_server_info_info3(). Note make_server_info_info3()
|
||||
handles MAP_TO_GUEST_ON_BAD_UID and make_server_info_guest()
|
||||
internally.
|
||||
c) Similar to auth_check_ntlm_password() we now call
|
||||
smb_pam_accountcheck(unix_username, rhost), where rhost
|
||||
is only an ipv4 or ipv6 address (without reverse dns lookup)
|
||||
d) From there it calls create_local_token()
|
||||
|
||||
As standalone server (in an MIT realm) we continue
|
||||
with the already existing code logic, which works without a PAC:
|
||||
a) we keep smb_getpwnam() with create=true logic as it
|
||||
also requires an explicit 'add user script' option.
|
||||
b) In the following commits we assert that there's
|
||||
actually no PAC in this mode, which means we can
|
||||
remove unused and confusing code.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14646
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
---
|
||||
source3/auth/auth_generic.c | 137 ++++++++++++++++++++++++++++--------
|
||||
1 file changed, 109 insertions(+), 28 deletions(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=a152f36b0576737e647dbe5f1954039668123c1f
|
||||
|
||||
diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
|
||||
index 86585ad690c..450c358beeb 100644
|
||||
--- a/source3/auth/auth_generic.c
|
||||
+++ b/source3/auth/auth_generic.c
|
||||
@@ -46,6 +46,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
|
||||
uint32_t session_info_flags,
|
||||
struct auth_session_info **session_info)
|
||||
{
|
||||
+ enum server_role server_role = lp_server_role();
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
struct PAC_LOGON_INFO *logon_info = NULL;
|
||||
struct netr_SamInfo3 *info3_copy = NULL;
|
||||
@@ -54,39 +55,59 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
|
||||
char *ntuser;
|
||||
char *ntdomain;
|
||||
char *username;
|
||||
- char *rhost;
|
||||
+ const char *rhost;
|
||||
struct passwd *pw;
|
||||
NTSTATUS status;
|
||||
- int rc;
|
||||
|
||||
tmp_ctx = talloc_new(mem_ctx);
|
||||
if (!tmp_ctx) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
- if (pac_blob) {
|
||||
-#ifdef HAVE_KRB5
|
||||
+ if (tsocket_address_is_inet(remote_address, "ip")) {
|
||||
+ rhost = tsocket_address_inet_addr_string(
|
||||
+ remote_address, tmp_ctx);
|
||||
+ if (rhost == NULL) {
|
||||
+ status = NT_STATUS_NO_MEMORY;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ } else {
|
||||
+ rhost = "127.0.0.1";
|
||||
+ }
|
||||
+
|
||||
+ if (server_role != ROLE_STANDALONE) {
|
||||
struct wbcAuthUserParams params = {};
|
||||
struct wbcAuthUserInfo *info = NULL;
|
||||
struct wbcAuthErrorInfo *err = NULL;
|
||||
+ struct auth_serversupplied_info *server_info = NULL;
|
||||
+ char *original_user_name = NULL;
|
||||
+ char *p = NULL;
|
||||
wbcErr wbc_err;
|
||||
|
||||
+ if (pac_blob == NULL) {
|
||||
+ /*
|
||||
+ * This should already be catched at the main
|
||||
+ * gensec layer, but better check twice
|
||||
+ */
|
||||
+ status = NT_STATUS_INTERNAL_ERROR;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Let winbind decode the PAC.
|
||||
* This will also store the user
|
||||
* data in the netsamlogon cache.
|
||||
*
|
||||
- * We need to do this *before* we
|
||||
- * call get_user_from_kerberos_info()
|
||||
- * as that does a user lookup that
|
||||
- * expects info in the netsamlogon cache.
|
||||
- *
|
||||
- * See BUG: https://bugzilla.samba.org/show_bug.cgi?id=11259
|
||||
+ * This used to be a cache prime
|
||||
+ * optimization, but now we delegate
|
||||
+ * all logic to winbindd, as we require
|
||||
+ * winbindd as domain member anyway.
|
||||
*/
|
||||
params.level = WBC_AUTH_USER_LEVEL_PAC;
|
||||
params.password.pac.data = pac_blob->data;
|
||||
params.password.pac.length = pac_blob->length;
|
||||
|
||||
+ /* we are contacting the privileged pipe */
|
||||
become_root();
|
||||
wbc_err = wbcAuthenticateUserEx(¶ms, &info, &err);
|
||||
unbecome_root();
|
||||
@@ -99,18 +120,90 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
|
||||
*/
|
||||
|
||||
switch (wbc_err) {
|
||||
- case WBC_ERR_WINBIND_NOT_AVAILABLE:
|
||||
case WBC_ERR_SUCCESS:
|
||||
break;
|
||||
+ case WBC_ERR_WINBIND_NOT_AVAILABLE:
|
||||
+ status = NT_STATUS_NO_LOGON_SERVERS;
|
||||
+ DBG_ERR("winbindd not running - "
|
||||
+ "but required as domain member: %s\n",
|
||||
+ nt_errstr(status));
|
||||
+ goto done;
|
||||
case WBC_ERR_AUTH_ERROR:
|
||||
status = NT_STATUS(err->nt_status);
|
||||
wbcFreeMemory(err);
|
||||
goto done;
|
||||
+ case WBC_ERR_NO_MEMORY:
|
||||
+ status = NT_STATUS_NO_MEMORY;
|
||||
+ goto done;
|
||||
default:
|
||||
status = NT_STATUS_LOGON_FAILURE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ status = make_server_info_wbcAuthUserInfo(tmp_ctx,
|
||||
+ info->account_name,
|
||||
+ info->domain_name,
|
||||
+ info, &server_info);
|
||||
+ if (!NT_STATUS_IS_OK(status)) {
|
||||
+ DEBUG(10, ("make_server_info_wbcAuthUserInfo failed: %s\n",
|
||||
+ nt_errstr(status)));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* We skip doing this step if the caller asked us not to */
|
||||
+ if (!(server_info->guest)) {
|
||||
+ const char *unix_username = server_info->unix_name;
|
||||
+
|
||||
+ /* We might not be root if we are an RPC call */
|
||||
+ become_root();
|
||||
+ status = smb_pam_accountcheck(unix_username, rhost);
|
||||
+ unbecome_root();
|
||||
+
|
||||
+ if (!NT_STATUS_IS_OK(status)) {
|
||||
+ DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] "
|
||||
+ "FAILED with error %s\n",
|
||||
+ unix_username, nt_errstr(status)));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] "
|
||||
+ "succeeded\n", unix_username));
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
|
||||
+
|
||||
+ p = strchr_m(princ_name, '@');
|
||||
+ if (!p) {
|
||||
+ DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
|
||||
+ princ_name));
|
||||
+ status = NT_STATUS_LOGON_FAILURE;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ original_user_name = talloc_strndup(tmp_ctx, princ_name, p - princ_name);
|
||||
+ if (original_user_name == NULL) {
|
||||
+ status = NT_STATUS_NO_MEMORY;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ status = create_local_token(mem_ctx,
|
||||
+ server_info,
|
||||
+ NULL,
|
||||
+ original_user_name,
|
||||
+ session_info);
|
||||
+ if (!NT_STATUS_IS_OK(status)) {
|
||||
+ DEBUG(10, ("create_local_token failed: %s\n",
|
||||
+ nt_errstr(status)));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ goto session_info_ready;
|
||||
+ }
|
||||
+
|
||||
+ /* This is the standalone legacy code path */
|
||||
+
|
||||
+ if (pac_blob != NULL) {
|
||||
+#ifdef HAVE_KRB5
|
||||
status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL,
|
||||
NULL, NULL, 0, &logon_info);
|
||||
#else
|
||||
@@ -121,22 +214,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
- rc = get_remote_hostname(remote_address,
|
||||
- &rhost,
|
||||
- tmp_ctx);
|
||||
- if (rc < 0) {
|
||||
- status = NT_STATUS_NO_MEMORY;
|
||||
- goto done;
|
||||
- }
|
||||
- if (strequal(rhost, "UNKNOWN")) {
|
||||
- rhost = tsocket_address_inet_addr_string(remote_address,
|
||||
- tmp_ctx);
|
||||
- if (rhost == NULL) {
|
||||
- status = NT_STATUS_NO_MEMORY;
|
||||
- goto done;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
status = get_user_from_kerberos_info(tmp_ctx, rhost,
|
||||
princ_name, logon_info,
|
||||
&is_mapped, &is_guest,
|
||||
@@ -170,6 +247,8 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+session_info_ready:
|
||||
+
|
||||
/* setup the string used by %U */
|
||||
set_current_user_info((*session_info)->unix_info->sanitized_username,
|
||||
(*session_info)->unix_info->unix_name,
|
||||
@@ -179,7 +258,9 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
|
||||
lp_load_with_shares(get_dyn_CONFIGFILE());
|
||||
|
||||
DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
|
||||
- ntuser, ntdomain, rhost));
|
||||
+ (*session_info)->info->account_name,
|
||||
+ (*session_info)->info->domain_name,
|
||||
+ rhost));
|
||||
|
||||
status = NT_STATUS_OK;
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
From 2991eedefc19367b57313b72a3b741eae74d049c Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:15:00 +1300
|
||||
Subject: [PATCH 163/266] CVE-2020-25722 s4/dsdb/samldb:
|
||||
samldb_user_account_control_change() checks all values
|
||||
|
||||
There is another call to dsdb_get_expected_new_values() in this function
|
||||
that we change in the next commit.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/2991eedefc19367b57313b72a3b741eae74d049c
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index ba56cf8826e..b84ef4c26d5 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -2807,8 +2807,15 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
|
||||
bool old_is_critical = false;
|
||||
bool new_is_critical = false;
|
||||
|
||||
- el = dsdb_get_single_valued_attr(ac->msg, "userAccountControl",
|
||||
- ac->req->operation);
|
||||
+ ret = dsdb_get_expected_new_values(ac,
|
||||
+ ac->msg,
|
||||
+ "userAccountControl",
|
||||
+ &el,
|
||||
+ ac->req->operation);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (el == NULL || el->num_values == 0) {
|
||||
ldb_asprintf_errstring(ldb,
|
||||
"%08X: samldb: 'userAccountControl' can't be deleted!",
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
From 9f807fdd8d1a148891d389820c329f44f9ffe965 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Tue, 5 Oct 2021 18:12:49 +0200
|
||||
Subject: [PATCH 130/266] CVE-2020-25717: s3:auth: let
|
||||
auth3_generate_session_info_pac() reject a PAC in standalone mode
|
||||
|
||||
We should be strict in standalone mode, that we only support MIT realms
|
||||
without a PAC in order to keep the code sane.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
---
|
||||
source3/auth/auth_generic.c | 29 +++++++++--------------------
|
||||
1 file changed, 9 insertions(+), 20 deletions(-)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=9f807fdd8d1a148891d389820c329f44f9ffe965
|
||||
|
||||
diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
|
||||
index 450c358beeb..7d00cfa95c7 100644
|
||||
--- a/source3/auth/auth_generic.c
|
||||
+++ b/source3/auth/auth_generic.c
|
||||
@@ -48,8 +48,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
|
||||
{
|
||||
enum server_role server_role = lp_server_role();
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
- struct PAC_LOGON_INFO *logon_info = NULL;
|
||||
- struct netr_SamInfo3 *info3_copy = NULL;
|
||||
bool is_mapped;
|
||||
bool is_guest;
|
||||
char *ntuser;
|
||||
@@ -203,19 +201,20 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
|
||||
/* This is the standalone legacy code path */
|
||||
|
||||
if (pac_blob != NULL) {
|
||||
-#ifdef HAVE_KRB5
|
||||
- status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL,
|
||||
- NULL, NULL, 0, &logon_info);
|
||||
-#else
|
||||
- status = NT_STATUS_ACCESS_DENIED;
|
||||
-#endif
|
||||
+ /*
|
||||
+ * In standalone mode we don't expect a PAC!
|
||||
+ * we only support MIT realms
|
||||
+ */
|
||||
+ status = NT_STATUS_BAD_TOKEN_TYPE;
|
||||
+ DBG_WARNING("Unexpected PAC for [%s] in standalone mode - %s\n",
|
||||
+ princ_name, nt_errstr(status));
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
status = get_user_from_kerberos_info(tmp_ctx, rhost,
|
||||
- princ_name, logon_info,
|
||||
+ princ_name, NULL,
|
||||
&is_mapped, &is_guest,
|
||||
&ntuser, &ntdomain,
|
||||
&username, &pw);
|
||||
@@ -226,19 +225,9 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- /* Get the info3 from the PAC data if we have it */
|
||||
- if (logon_info) {
|
||||
- status = create_info3_from_pac_logon_info(tmp_ctx,
|
||||
- logon_info,
|
||||
- &info3_copy);
|
||||
- if (!NT_STATUS_IS_OK(status)) {
|
||||
- goto done;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
status = make_session_info_krb5(mem_ctx,
|
||||
ntuser, ntdomain, username, pw,
|
||||
- info3_copy, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
|
||||
+ NULL, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
|
||||
session_info);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
From 96fbfe0edd6307c6cd3c17cabb3473c5775ee656 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:15:43 +1300
|
||||
Subject: [PATCH 164/266] CVE-2020-25722 s4/dsdb/samldb
|
||||
_user_account_control_change() always add final value
|
||||
|
||||
dsdb_get_single_valued_attr() was finding the last non-delete element for
|
||||
userAccountControl and changing its value to the computed value.
|
||||
Unfortunately, the last non-delete element might not be the last element,
|
||||
and a subsequent delete might remove it.
|
||||
|
||||
Instead we just add a replace on the end.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/96fbfe0edd6307c6cd3c17cabb3473c5775ee656
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index b84ef4c26d5..1410e5bc5e6 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -3008,9 +3008,12 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
|
||||
return ldb_module_oom(ac->module);
|
||||
}
|
||||
|
||||
- /* Overwrite "userAccountControl" correctly */
|
||||
- el = dsdb_get_single_valued_attr(ac->msg, "userAccountControl",
|
||||
- ac->req->operation);
|
||||
+ ret = ldb_msg_add_empty(ac->msg,
|
||||
+ "userAccountControl",
|
||||
+ LDB_FLAG_MOD_REPLACE,
|
||||
+ &el);
|
||||
+ el->values = talloc(ac->msg, struct ldb_val);
|
||||
+ el->num_values = 1;
|
||||
el->values[0].data = (uint8_t *) tempstr;
|
||||
el->values[0].length = strlen(tempstr);
|
||||
} else {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From 63de509875b5c3426d288a1aad73e5a67bd345f4 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:16:34 +1300
|
||||
Subject: [PATCH 165/266] CVE-2020-25722 s4/dsdb/samldb:
|
||||
samldb_pwd_last_set_change() checks all values
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/63de509875b5c3426d288a1aad73e5a67bd345f4
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 1410e5bc5e6..8e93df221f5 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -3102,8 +3102,15 @@ static int samldb_pwd_last_set_change(struct samldb_ctx *ac)
|
||||
NULL
|
||||
};
|
||||
|
||||
- el = dsdb_get_single_valued_attr(ac->msg, "pwdLastSet",
|
||||
- ac->req->operation);
|
||||
+ ret = dsdb_get_expected_new_values(ac,
|
||||
+ ac->msg,
|
||||
+ "pwdLastSet",
|
||||
+ &el,
|
||||
+ ac->req->operation);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (el == NULL || el->num_values == 0) {
|
||||
ldb_asprintf_errstring(ldb,
|
||||
"%08X: samldb: 'pwdLastSet' can't be deleted!",
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From 1deb16de4d1823a653f86be009ab4f9c74c8df7e Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:17:31 +1300
|
||||
Subject: [PATCH 166/266] CVE-2020-25722 s4/dsdb/samldb: samldb_lockout_time()
|
||||
checks all values
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/1deb16de4d1823a653f86be009ab4f9c74c8df7e
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 8e93df221f5..48eb88f728b 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -3164,8 +3164,15 @@ static int samldb_lockout_time(struct samldb_ctx *ac)
|
||||
struct ldb_message *tmp_msg;
|
||||
int ret;
|
||||
|
||||
- el = dsdb_get_single_valued_attr(ac->msg, "lockoutTime",
|
||||
- ac->req->operation);
|
||||
+ ret = dsdb_get_expected_new_values(ac,
|
||||
+ ac->msg,
|
||||
+ "lockoutTime",
|
||||
+ &el,
|
||||
+ ac->req->operation);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (el == NULL || el->num_values == 0) {
|
||||
ldb_asprintf_errstring(ldb,
|
||||
"%08X: samldb: 'lockoutTime' can't be deleted!",
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From 485db903ed2bac1470e00948574b97bd9548cae4 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:17:50 +1300
|
||||
Subject: [PATCH 167/266] CVE-2020-25722 s4/dsdb/samldb:
|
||||
samldb_group_type_change() checks all values
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/485db903ed2bac1470e00948574b97bd9548cae4
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 48eb88f728b..391437d759d 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -3221,8 +3221,15 @@ static int samldb_group_type_change(struct samldb_ctx *ac)
|
||||
struct ldb_result *res;
|
||||
const char * const attrs[] = { "groupType", NULL };
|
||||
|
||||
- el = dsdb_get_single_valued_attr(ac->msg, "groupType",
|
||||
- ac->req->operation);
|
||||
+ ret = dsdb_get_expected_new_values(ac,
|
||||
+ ac->msg,
|
||||
+ "groupType",
|
||||
+ &el,
|
||||
+ ac->req->operation);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (el == NULL) {
|
||||
/* we are not affected */
|
||||
return LDB_SUCCESS;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
From fdd25972d26455c1b1254de3d1697786ae0678a3 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:18:10 +1300
|
||||
Subject: [PATCH 168/266] CVE-2020-25722 s4/dsdb/samldb:
|
||||
samldb_service_principal_names_change checks values
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/fdd25972d26455c1b1254de3d1697786ae0678a3
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 20 ++++++++++++++++----
|
||||
1 file changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 391437d759d..80ca1e3afc0 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -4047,10 +4047,22 @@ static int samldb_service_principal_names_change(struct samldb_ctx *ac)
|
||||
unsigned int i, j;
|
||||
int ret;
|
||||
|
||||
- el = dsdb_get_single_valued_attr(ac->msg, "dNSHostName",
|
||||
- ac->req->operation);
|
||||
- el2 = dsdb_get_single_valued_attr(ac->msg, "sAMAccountName",
|
||||
- ac->req->operation);
|
||||
+ ret = dsdb_get_expected_new_values(ac,
|
||||
+ ac->msg,
|
||||
+ "dNSHostName",
|
||||
+ &el,
|
||||
+ ac->req->operation);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ ret = dsdb_get_expected_new_values(ac,
|
||||
+ ac->msg,
|
||||
+ "sAMAccountName",
|
||||
+ &el2,
|
||||
+ ac->req->operation);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
if ((el == NULL) && (el2 == NULL)) {
|
||||
/* we are not affected */
|
||||
return LDB_SUCCESS;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From 3f413fb5813c979c7bdcc15ec4b059dbd533f4d1 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:18:21 +1300
|
||||
Subject: [PATCH 169/266] CVE-2020-25722 s4/dsdb/samldb:
|
||||
samldb_fsmo_role_owner_check checks values
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/3f413fb5813c979c7bdcc15ec4b059dbd533f4d1
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 80ca1e3afc0..d75277b3853 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -4302,9 +4302,15 @@ static int samldb_fsmo_role_owner_check(struct samldb_ctx *ac)
|
||||
struct ldb_dn *res_dn;
|
||||
struct ldb_result *res;
|
||||
int ret;
|
||||
+ ret = dsdb_get_expected_new_values(ac,
|
||||
+ ac->msg,
|
||||
+ "fSMORoleOwner",
|
||||
+ &el,
|
||||
+ ac->req->operation);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
- el = dsdb_get_single_valued_attr(ac->msg, "fSMORoleOwner",
|
||||
- ac->req->operation);
|
||||
if (el == NULL) {
|
||||
/* we are not affected */
|
||||
return LDB_SUCCESS;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
From 2a57c6e2f6a11698054afb2d9b173e5627eabb89 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Thu, 21 Oct 2021 12:52:07 +1300
|
||||
Subject: [PATCH 170/266] CVE-2020-25722 s4/dsdb/samldb:
|
||||
samldb_fsmo_role_owner_check() wants one value
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/2a57c6e2f6a11698054afb2d9b173e5627eabb89
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 17 ++++++++++++-----
|
||||
1 file changed, 12 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index d75277b3853..810365ca030 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -4315,6 +4315,9 @@ static int samldb_fsmo_role_owner_check(struct samldb_ctx *ac)
|
||||
/* we are not affected */
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
+ if (el->num_values != 1) {
|
||||
+ goto choose_error_code;
|
||||
+ }
|
||||
|
||||
/* Create a temporary message for fetching the "fSMORoleOwner" */
|
||||
tmp_msg = ldb_msg_new(ac->msg);
|
||||
@@ -4331,11 +4334,7 @@ static int samldb_fsmo_role_owner_check(struct samldb_ctx *ac)
|
||||
if (res_dn == NULL) {
|
||||
ldb_set_errstring(ldb,
|
||||
"samldb: 'fSMORoleOwner' attributes have to reference 'nTDSDSA' entries!");
|
||||
- if (ac->req->operation == LDB_ADD) {
|
||||
- return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
- } else {
|
||||
- return LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
- }
|
||||
+ goto choose_error_code;
|
||||
}
|
||||
|
||||
/* Fetched DN has to reference a "nTDSDSA" entry */
|
||||
@@ -4355,6 +4354,14 @@ static int samldb_fsmo_role_owner_check(struct samldb_ctx *ac)
|
||||
talloc_free(res);
|
||||
|
||||
return LDB_SUCCESS;
|
||||
+
|
||||
+choose_error_code:
|
||||
+ /* this is just how it is */
|
||||
+ if (ac->req->operation == LDB_ADD) {
|
||||
+ return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
+ } else {
|
||||
+ return LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
From b8424fad4234fa422436b5a704c017bd9d7e3913 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:19:42 +1300
|
||||
Subject: [PATCH 171/266] CVE-2020-25722 s4/dsdb/pwd_hash: password_hash_bypass
|
||||
gets all values
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/b8424fad4234fa422436b5a704c017bd9d7e3913
|
||||
|
||||
---
|
||||
.../dsdb/samdb/ldb_modules/password_hash.c | 30 ++++++++++++-------
|
||||
1 file changed, 20 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
|
||||
index bb437a3b982..5f033f9622b 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
|
||||
@@ -201,6 +201,7 @@ static int password_hash_bypass(struct ldb_module *module, struct ldb_request *r
|
||||
struct ldb_message_element *nthe;
|
||||
struct ldb_message_element *lmhe;
|
||||
struct ldb_message_element *sce;
|
||||
+ int ret;
|
||||
|
||||
switch (request->operation) {
|
||||
case LDB_ADD:
|
||||
@@ -214,17 +215,26 @@ static int password_hash_bypass(struct ldb_module *module, struct ldb_request *r
|
||||
}
|
||||
|
||||
/* nobody must touch password histories and 'supplementalCredentials' */
|
||||
- nte = dsdb_get_single_valued_attr(msg, "unicodePwd",
|
||||
- request->operation);
|
||||
- lme = dsdb_get_single_valued_attr(msg, "dBCSPwd",
|
||||
- request->operation);
|
||||
- nthe = dsdb_get_single_valued_attr(msg, "ntPwdHistory",
|
||||
- request->operation);
|
||||
- lmhe = dsdb_get_single_valued_attr(msg, "lmPwdHistory",
|
||||
- request->operation);
|
||||
- sce = dsdb_get_single_valued_attr(msg, "supplementalCredentials",
|
||||
- request->operation);
|
||||
|
||||
+#define GET_VALUES(el, attr) do { \
|
||||
+ ret = dsdb_get_expected_new_values(request, \
|
||||
+ msg, \
|
||||
+ attr, \
|
||||
+ &el, \
|
||||
+ request->operation); \
|
||||
+ \
|
||||
+ if (ret != LDB_SUCCESS) { \
|
||||
+ return ret; \
|
||||
+ } \
|
||||
+} while(0)
|
||||
+
|
||||
+ GET_VALUES(nte, "unicodePwd");
|
||||
+ GET_VALUES(lme, "dBCSPwd");
|
||||
+ GET_VALUES(nthe, "ntPwdHistory");
|
||||
+ GET_VALUES(lmhe, "lmPwdHistory");
|
||||
+ GET_VALUES(sce, "supplementalCredentials");
|
||||
+
|
||||
+#undef GET_VALUES
|
||||
#define CHECK_HASH_ELEMENT(e, min, max) do {\
|
||||
if (e && e->num_values) { \
|
||||
unsigned int _count; \
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
From bed2ea1d378f31e3d071a7a5d4c80cd9cc1c9894 Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Date: Wed, 20 Oct 2021 17:20:54 +1300
|
||||
Subject: [PATCH 172/266] CVE-2020-25722 s4/dsdb/pwd_hash: rework pwdLastSet
|
||||
bypass
|
||||
|
||||
This tightens the logic a bit, in that a message with trailing DELETE
|
||||
elements is no longer accepted when the bypass flag is set. In any case
|
||||
this is an unlikely scenario as this is an internal flag set by a private
|
||||
control in pdb_samba_dsdb_replace_by_sam().
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14876
|
||||
|
||||
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/bed2ea1d378f31e3d071a7a5d4c80cd9cc1c9894
|
||||
|
||||
---
|
||||
.../dsdb/samdb/ldb_modules/password_hash.c | 28 ++++++++++++-------
|
||||
1 file changed, 18 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
|
||||
index 5f033f9622b..9fa2e36ba90 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
|
||||
@@ -2227,23 +2227,31 @@ static int setup_last_set_field(struct setup_password_fields_io *io)
|
||||
}
|
||||
|
||||
if (io->ac->pwd_last_set_bypass) {
|
||||
- struct ldb_message_element *el1 = NULL;
|
||||
- struct ldb_message_element *el2 = NULL;
|
||||
-
|
||||
+ struct ldb_message_element *el = NULL;
|
||||
+ size_t i;
|
||||
+ size_t count = 0;
|
||||
+ /*
|
||||
+ * This is a message from pdb_samba_dsdb_replace_by_sam()
|
||||
+ *
|
||||
+ * We want to ensure there is only one pwdLastSet element, and
|
||||
+ * it isn't deleting.
|
||||
+ */
|
||||
if (msg == NULL) {
|
||||
return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
|
||||
- el1 = dsdb_get_single_valued_attr(msg, "pwdLastSet",
|
||||
- io->ac->req->operation);
|
||||
- if (el1 == NULL) {
|
||||
- return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
+ for (i = 0; i < msg->num_elements; i++) {
|
||||
+ if (ldb_attr_cmp(msg->elements[i].name,
|
||||
+ "pwdLastSet") == 0) {
|
||||
+ count++;
|
||||
+ el = &msg->elements[i];
|
||||
+ }
|
||||
}
|
||||
- el2 = ldb_msg_find_element(msg, "pwdLastSet");
|
||||
- if (el2 == NULL) {
|
||||
+ if (count != 1) {
|
||||
return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
- if (el1 != el2) {
|
||||
+
|
||||
+ if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
|
||||
return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,90 @@
|
||||
From 8513fe9e30a65060fc8908f42756e44550176d7f Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Wed, 20 Oct 2021 11:36:58 +1300
|
||||
Subject: [PATCH 228/266] CVE-2020-25722 Ensure the structural objectclass
|
||||
cannot be changed
|
||||
|
||||
If the structural objectclass is allowed to change, then the restrictions
|
||||
locking an object to remaining a user or computer will not be enforcable.
|
||||
|
||||
Likewise other LDAP inheritance rules, which allow only certain
|
||||
child objects can be bypassed, which can in turn allow creation of
|
||||
(unprivileged) users where only DNS objects were expected.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14889
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/8513fe9e30a65060fc8908f42756e44550176d7f
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/objectclass.c | 36 +++++++++++++++++++
|
||||
1 files changed, 36 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
|
||||
index 36ab76e19fc..d8feff0262c 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
|
||||
@@ -811,6 +811,7 @@ static int objectclass_do_mod(struct oc_context *ac)
|
||||
struct ldb_message_element *oc_el_entry, *oc_el_change;
|
||||
struct ldb_val *vals;
|
||||
struct ldb_message *msg;
|
||||
+ const struct dsdb_class *current_structural_objectclass;
|
||||
const struct dsdb_class *objectclass;
|
||||
unsigned int i, j, k;
|
||||
bool found;
|
||||
@@ -830,6 +831,22 @@ static int objectclass_do_mod(struct oc_context *ac)
|
||||
return ldb_operr(ldb);
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Get the current new top-most structural object class
|
||||
+ *
|
||||
+ * We must not allow this to change
|
||||
+ */
|
||||
+
|
||||
+ current_structural_objectclass
|
||||
+ = dsdb_get_last_structural_class(ac->schema,
|
||||
+ oc_el_entry);
|
||||
+ if (current_structural_objectclass == NULL) {
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "objectclass: cannot find current structural objectclass on %s!",
|
||||
+ ldb_dn_get_linearized(ac->search_res->message->dn));
|
||||
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
|
||||
+ }
|
||||
+
|
||||
/* use a new message structure */
|
||||
msg = ldb_msg_new(ac);
|
||||
if (msg == NULL) {
|
||||
@@ -939,6 +956,25 @@ static int objectclass_do_mod(struct oc_context *ac)
|
||||
return LDB_ERR_OBJECT_CLASS_VIOLATION;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Has (so far, we re-check for each and every
|
||||
+ * "objectclass" in the message) the structural
|
||||
+ * objectclass changed?
|
||||
+ */
|
||||
+
|
||||
+ if (objectclass != current_structural_objectclass) {
|
||||
+ const char *dn
|
||||
+ = ldb_dn_get_linearized(ac->search_res->message->dn);
|
||||
+ ldb_asprintf_errstring(ldb,
|
||||
+ "objectclass: not permitted "
|
||||
+ "to change the structural "
|
||||
+ "objectClass on %s [%s] => [%s]!",
|
||||
+ dn,
|
||||
+ current_structural_objectclass->lDAPDisplayName,
|
||||
+ objectclass->lDAPDisplayName);
|
||||
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
|
||||
+ }
|
||||
+
|
||||
/* Check for unrelated objectclasses */
|
||||
ret = check_unrelated_objectclasses(ac->module, ac->schema,
|
||||
objectclass,
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
From b6ab45da636118da83443516eee7d314f19b4e22 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Bartlett <abartlet@samba.org>
|
||||
Date: Mon, 4 Oct 2021 15:18:34 +1300
|
||||
Subject: [PATCH 235/266] CVE-2020-25722 kdc: Do not honour a request for a
|
||||
3-part SPN (ending in our domain/realm) unless a DC
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14776
|
||||
|
||||
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/b6ab45da636118da83443516eee7d314f19b4e22
|
||||
|
||||
---
|
||||
source4/kdc/db-glue.c | 23 +++++++++++++++++++++++
|
||||
1 files changed, 23 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c
|
||||
index d55bf1663d4..0f19e8d1c93 100644
|
||||
--- a/source4/kdc/db-glue.c
|
||||
+++ b/source4/kdc/db-glue.c
|
||||
@@ -968,6 +968,29 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
|
||||
entry_ex->entry.flags.server = 0;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * We restrict a 3-part SPN ending in my domain/realm to full
|
||||
+ * domain controllers.
|
||||
+ *
|
||||
+ * This avoids any cases where (eg) a demoted DC still has
|
||||
+ * these more restricted SPNs.
|
||||
+ */
|
||||
+ if (krb5_princ_size(context, principal) > 2) {
|
||||
+ char *third_part
|
||||
+ = smb_krb5_principal_get_comp_string(mem_ctx,
|
||||
+ context,
|
||||
+ principal,
|
||||
+ 2);
|
||||
+ bool is_our_realm =
|
||||
+ lpcfg_is_my_domain_or_realm(lp_ctx,
|
||||
+ third_part);
|
||||
+ bool is_dc = userAccountControl &
|
||||
+ (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT);
|
||||
+ if (is_our_realm && !is_dc) {
|
||||
+ entry_ex->entry.flags.server = 0;
|
||||
+ }
|
||||
+ }
|
||||
/*
|
||||
* To give the correct type of error to the client, we must
|
||||
* not just return the entry without .server set, we must
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
From 3ed16e74292058d059ae951317ca8d3b7f1f5d0e Mon Sep 17 00:00:00 2001
|
||||
From: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
Date: Tue, 2 Nov 2021 21:00:00 +1300
|
||||
Subject: [PATCH 244/266] CVE-2020-25722 selftest: Ensure check for duplicate
|
||||
servicePrincipalNames is not bypassed for an add operation
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14564
|
||||
|
||||
If one of the objectClass checks passed, samldb_add() could return
|
||||
through one of the samldb_fill_*() functions and skip the
|
||||
servicePrincipalName uniqueness checking.
|
||||
|
||||
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||||
|
||||
Conflict:remove test
|
||||
Reference:https://gitlab.com/samba-team/samba/-/commit/3ed16e74292058d059ae951317ca8d3b7f1f5d0e
|
||||
|
||||
---
|
||||
source4/dsdb/samdb/ldb_modules/samldb.c | 25 ++++++++++++-------------
|
||||
1 files changed, 12 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
index 810365ca030..f0227411ccd 100644
|
||||
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
||||
@@ -4838,6 +4838,18 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req)
|
||||
}
|
||||
}
|
||||
|
||||
+ el = ldb_msg_find_element(ac->msg, "servicePrincipalName");
|
||||
+ if ((el != NULL)) {
|
||||
+ /*
|
||||
+ * We need to check whether the SPN collides with an existing
|
||||
+ * one (anywhere) including via aliases.
|
||||
+ */
|
||||
+ ret = samldb_spn_uniqueness_check(ac, el);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (samdb_find_attribute(ldb, ac->msg,
|
||||
"objectclass", "user") != NULL) {
|
||||
ac->type = SAMLDB_TYPE_USER;
|
||||
@@ -4936,19 +4948,6 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req)
|
||||
return samldb_fill_object(ac);
|
||||
}
|
||||
|
||||
-
|
||||
- el = ldb_msg_find_element(ac->msg, "servicePrincipalName");
|
||||
- if ((el != NULL)) {
|
||||
- /*
|
||||
- * We need to check whether the SPN collides with an existing
|
||||
- * one (anywhere) including via aliases.
|
||||
- */
|
||||
- ret = samldb_spn_uniqueness_check(ac, el);
|
||||
- if (ret != LDB_SUCCESS) {
|
||||
- return ret;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
if (samdb_find_attribute(ldb, ac->msg,
|
||||
"objectclass", "subnet") != NULL) {
|
||||
ret = samldb_verify_subnet(ac, ac->msg->dn);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
From 33d4d482718fca10030b5a569f17cb1a2637fc8a Mon Sep 17 00:00:00 2001
|
||||
From: Volker Lendecke <vl@samba.org>
|
||||
Date: Fri, 3 Jan 2020 12:42:03 +0100
|
||||
Subject: [PATCH 2619/6935] winbind: Fix CID 1456624 Uninitialized scalar
|
||||
variable
|
||||
|
||||
Coverity does not get that for (rc!=0) gnutls_error_to_ntstatus()
|
||||
never returns NT_STATUS_OK
|
||||
|
||||
Signed-off-by: Volker Lendecke <vl@samba.org>
|
||||
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||
Conflict: NA
|
||||
Reference: https://git.samba.org/?p=samba.git;a=patch;h=33d4d482718fca10030b5a569f17cb1a2637fc8a
|
||||
---
|
||||
source3/winbindd/winbindd_pam.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
|
||||
index 1552eb3ce52..a1c6efe6662 100644
|
||||
--- a/source3/winbindd/winbindd_pam.c
|
||||
+++ b/source3/winbindd/winbindd_pam.c
|
||||
@@ -1738,7 +1738,7 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(
|
||||
NTSTATUS result;
|
||||
uint8_t authoritative = 0;
|
||||
uint32_t flags = 0;
|
||||
- uint16_t validation_level;
|
||||
+ uint16_t validation_level = 0;
|
||||
union netr_Validation *validation = NULL;
|
||||
struct netr_SamBaseInfo *base_info = NULL;
|
||||
bool ok;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
97
samba.spec
97
samba.spec
@ -49,7 +49,7 @@
|
||||
|
||||
Name: samba
|
||||
Version: 4.11.12
|
||||
Release: 6
|
||||
Release: 7
|
||||
|
||||
Summary: A suite for Linux to interoperate with Windows
|
||||
License: GPLv3+ and LGPLv3+
|
||||
@ -80,6 +80,95 @@ Patch10: backport-CVE-2020-14318.patch
|
||||
Patch11: backport-CVE-2020-14323.patch
|
||||
Patch12: backport-CVE-2021-3671.patch
|
||||
|
||||
Patch6062: backport-winbind-Fix-CID-1456624-Uninitialized-scalar-variabl.patch
|
||||
|
||||
Patch6157: backport-0001-CVE-2020-25717-winbindd-add-generic-wb_parent_idmap_.patch
|
||||
Patch6158: backport-0002-CVE-2020-25717-wb_xids2sids-make-use-of-the-new-wb_p.patch
|
||||
Patch6159: backport-0003-CVE-2020-25717-wb_sids2xids-call-wb_parent_idmap_set.patch
|
||||
Patch6160: backport-0004-CVE-2020-25717-winbindd-defer-the-setup_child-from-i.patch
|
||||
Patch6161: backport-0005-CVE-2020-25717-wb_sids2xids-build-state-idmap_doms-b.patch
|
||||
Patch6162: backport-0006-CVE-2020-25717-winbindd-allow-idmap-backends-to-mark.patch
|
||||
Patch6163: backport-0007-CVE-2020-25717-s3-idmap_hash-reliable-return-ID_TYPE.patch
|
||||
Patch6164: backport-0008-CVE-2020-25717-winbindd-call-wb_parent_idmap_setup_s.patch
|
||||
Patch6165: backport-0009-CVE-2020-25717-winbind-ensure-wb_parent_idmap_setup_.patch
|
||||
Patch6166: backport-0010-CVE-2020-25717-auth_sam-use-pdb_get_domain_info-to-l.patch
|
||||
Patch6167: backport-0011-CVE-2020-25717-s3-winbindd-make-sure-we-default-to-r.patch
|
||||
Patch6168: backport-0012-CVE-2020-25717-s4-auth-ntlm-make-sure-auth_check_pas.patch
|
||||
Patch6169: backport-0013-CVE-2020-25717-loadparm-Add-new-parameter-min-domain.patch
|
||||
Patch6170: backport-0014-CVE-2020-25717-s3-auth-Check-minimum-domain-uid.patch
|
||||
Patch6171: backport-0015-CVE-2020-25717-s3-auth-we-should-not-try-to-autocrea.patch
|
||||
Patch6172: backport-0016-CVE-2020-25717-s3-auth-no-longer-let-check_account-a.patch
|
||||
Patch6173: backport-0017-CVE-2020-25717-s3-auth-remove-fallbacks-in-smb_getpw.patch
|
||||
Patch6174: backport-0018-CVE-2020-25717-s3-auth-don-t-let-create_local_token-.patch
|
||||
Patch6175: backport-0019-CVE-2020-25719-CVE-2020-25717-auth-gensec-always-req.patch
|
||||
Patch6176: backport-0020-CVE-2020-25717-s3-ntlm_auth-fix-memory-leaks-in-ntlm.patch
|
||||
Patch6177: backport-0021-CVE-2020-25717-s3-ntlm_auth-let-ntlm_auth_generate_s.patch
|
||||
Patch6178: backport-0022-use-set_current_user_info-in-auth3_generate_session_info_p.patch
|
||||
Patch6179: backport-0023-CVE-2020-25717-s3-auth-let-auth3_generate_session_in.patch
|
||||
Patch6180: backport-0024-CVE-2020-25717-s3-auth-let-auth3_generate_session_in.patch
|
||||
Patch6181: backport-0000-CVE-2020-25721-krb5pac-Add-new-buffers-for-samAccoun.patch
|
||||
Patch6182: backport-0000-CVE-2020-25719-mit-samba-Make-ks_get_principal-inter.patch
|
||||
Patch6183: backport-0001-CVE-2020-25719-mit-samba-Add-ks_free_principal.patch
|
||||
Patch6184: backport-0002-CVE-2020-25719-sign-and-verify-PAC-with-ticket-principal.patch
|
||||
Patch6185: backport-0003-CVE-2020-25719-mit-samba-If-we-use-client_princ-alwa.patch
|
||||
Patch6186: backport-0004-CVE-2020-25719-mit-samba-Add-mit_samba_princ_needs_p.patch
|
||||
Patch6187: backport-0005-CVE-2020-25719-mit-samba-Rework-PAC-handling-in-kdb_.patch
|
||||
Patch6188: backport-0001-CVE-2020-25721-auth-Fill-in-the-new-HAS_SAM_NAME_AND.patch
|
||||
Patch6189: backport-0000-CVE-2016-2124-s4-libcli-sesssetup-don-t-fallback-to-.patch
|
||||
Patch6190: backport-0001-CVE-2016-2124-s3-libsmb-don-t-fallback-to-non-spnego.patch
|
||||
Patch6191: backport-0001-CVE-2020-25722-dsdb-Move-krbtgt-password-setup-after.patch
|
||||
Patch6192: backport-0002-CVE-2020-25722-dsdb-Restrict-the-setting-of-privileg.patch
|
||||
Patch6193: backport-0003-CVE-2020-25722-dsdb-objectclass-computer-becomes-UF_.patch
|
||||
Patch6194: backport-0004-CVE-2020-25722-dsdb-Prohibit-mismatch-between-UF_-ac.patch
|
||||
Patch6195: backport-0005-CVE-2020-25722-dsdb-Add-restrictions-on-computer-acc.patch
|
||||
Patch6196: backport-0006-CVE-2020-25722-samdb-Fill-in-isCriticalSystemObject-.patch
|
||||
Patch6197: backport-0007-CVE-2020-25722-s4-acl-Make-sure-Control-Access-Right.patch
|
||||
Patch6198: backport-0008-CVE-2020-25722-Check-all-elements-in-acl_check_spn-n.patch
|
||||
Patch6199: backport-0009-CVE-2020-25722-Check-for-all-errors-from-acl_check_e.patch
|
||||
Patch6200: backport-0010-CVE-2020-25722-s4-dsdb-cracknames-always-free-tmp_ct.patch
|
||||
Patch6201: backport-0011-CVE-2020-25722-s4-provision-add-host-SPNs-at-the-sta.patch
|
||||
Patch6202: backport-0012-CVE-2020-25722-s4-dsdb-samldb-add-samldb_get_single_.patch
|
||||
Patch6203: backport-0013-CVE-2020-25722-s4-dsdb-samldb-check-for-clashes-in-U.patch
|
||||
Patch6204: backport-0014-CVE-2020-25722-s4-dsdb-samldb-check-sAMAccountName-f.patch
|
||||
Patch6205: backport-0015-CVE-2020-25722-s4-dsdb-samldb-check-for-SPN-uniquene.patch
|
||||
Patch6206: backport-0016-CVE-2020-25722-s4-dsdb-samldb-reject-SPN-with-too-fe.patch
|
||||
Patch6207: backport-0017-CVE-2020-25722-s4-dsdb-modules-add-dsdb_get_expected.patch
|
||||
Patch6208: backport-0018-CVE-2020-25722-s4-dsdb-samldb-samldb_get_single_valu.patch
|
||||
Patch6209: backport-0019-CVE-2020-25722-s4-dsdb-samldb-samldb_sam_accountname.patch
|
||||
Patch6210: backport-0020-CVE-2020-25722-s4-dsdb-samldb-samldb_schema_add_hand.patch
|
||||
Patch6211: backport-0021-CVE-2020-25722-s4-dsdb-samldb-samldb_schema_add_hand.patch
|
||||
Patch6212: backport-0022-CVE-2020-25722-s4-dsdb-samldb-samldb_prim_group_chan.patch
|
||||
Patch6213: backport-0023-CVE-2020-25722-s4-dsdb-samldb-samldb_user_account_co.patch
|
||||
Patch6214: backport-0024-CVE-2020-25722-s4-dsdb-samldb-_user_account_control_.patch
|
||||
Patch6215: backport-0025-CVE-2020-25722-s4-dsdb-samldb-samldb_pwd_last_set_ch.patch
|
||||
Patch6216: backport-0026-CVE-2020-25722-s4-dsdb-samldb-samldb_lockout_time-ch.patch
|
||||
Patch6217: backport-0027-CVE-2020-25722-s4-dsdb-samldb-samldb_group_type_chan.patch
|
||||
Patch6218: backport-0028-CVE-2020-25722-s4-dsdb-samldb-samldb_service_princip.patch
|
||||
Patch6219: backport-0029-CVE-2020-25722-s4-dsdb-samldb-samldb_fsmo_role_owner.patch
|
||||
Patch6220: backport-0030-CVE-2020-25722-s4-dsdb-samldb-samldb_fsmo_role_owner.patch
|
||||
Patch6221: backport-0031-CVE-2020-25722-s4-dsdb-pwd_hash-password_hash_bypass.patch
|
||||
Patch6222: backport-0032-CVE-2020-25722-s4-dsdb-pwd_hash-rework-pwdLastSet-by.patch
|
||||
Patch6223: backport-0033-CVE-2020-25722-Ensure-the-structural-objectclass-can.patch
|
||||
Patch6224: backport-0034-CVE-2020-25722-kdc-Do-not-honour-a-request-for-a-3-p.patch
|
||||
Patch6225: backport-0035-CVE-2020-25722-selftest-Ensure-check-for-duplicate-s.patch
|
||||
Patch6226: backport-0000-CVE-2020-25718-simplify.patch
|
||||
Patch6227: backport-0001-CVE-2020-25718-trailing-chunk-must-match.patch
|
||||
Patch6228: backport-0002-CVE-2020-25718-fix-ldb_comparison_fold.patch
|
||||
Patch6229: backport-0003-CVE-2020-25718-catch-potential-overflow-error.patch
|
||||
Patch6230: backport-0005-CVE-2020-25718-Fix-Message-items-for-a.patch
|
||||
Patch6231: backport-0006-CVE-2020-25718-Change-sid-list.patch
|
||||
Patch6232: backport-0007-CVE-2020-25718-Obtain-the-user.patch
|
||||
Patch6233: backport-0008-CVE-2020-25718-Put-msDS-KrbTgtLinkBL-put-RODC-reveal-never-reveal.patch
|
||||
Patch6234: backport-0009-CVE-2020-25718-Put-msDS-KrbTgtLinkBL.patch
|
||||
Patch6235: backport-0010-CVE-2020-25718-Confirm-that-the-RODC.patch
|
||||
Patch6236: backport-0000-CVE-2021-3738-s4-torture-drsuapi-maintain-priv-admin.patch
|
||||
Patch6237: backport-0001-CVE-2021-3738-s4-rpc_server-common-provide-assoc_gro.patch
|
||||
Patch6238: backport-0002-CVE-2021-3738-s4-rpc_server-drsuapi-make-use-of-asso.patch
|
||||
Patch6239: backport-0003-CVE-2021-3738-s4-rpc_server-dnsserver-make-use-of-dc.patch
|
||||
Patch6240: backport-0004-CVE-2021-3738-s4-rpc_server-lsa-make-use-of-dcesrv_s.patch
|
||||
Patch6241: backport-0005-CVE-2021-3738-s4-rpc_server-netlogon-make-use-of-dce.patch
|
||||
Patch6242: backport-0006-CVE-2021-3738-s4-rpc_server-samr-make-use-of-dcesrv_.patch
|
||||
|
||||
BuildRequires: avahi-devel cups-devel dbus-devel docbook-style-xsl e2fsprogs-devel gawk gnupg2 gnutls-devel >= 3.4.7 gpgme-devel
|
||||
BuildRequires: jansson-devel krb5-devel >= %{required_mit_krb5} libacl-devel libaio-devel libarchive-devel libattr-devel
|
||||
BuildRequires: libcap-devel libcmocka-devel libnsl2-devel libtirpc-devel libuuid-devel libxslt lmdb ncurses-devel openldap-devel
|
||||
@ -3066,6 +3155,12 @@ fi
|
||||
%{_mandir}/man*
|
||||
|
||||
%changelog
|
||||
* Thu Dec 09 2021 xihaochen <xihaochen@huawei.com> - 4.11.12-7
|
||||
- Type:cves
|
||||
- ID:CVE-2020-25717,CVE-2020-25718,CVE-2020-25719,CVE-2020-25721,CVE-2020-25722,CVE-2016-2124,CVE-2021-3738
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2020-25717,CVE-2020-25718,CVE-2020-25719,CVE-2020-25721,CVE-2020-25722,CVE-2016-2124,CVE-2021-3738
|
||||
|
||||
* Mon Oct 25 2021 gaihuiying <gaihuiying1@huawei.com> - 4.11.12-6
|
||||
- Type:cves
|
||||
- ID:CVE-2021-3671
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user