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:
haochenstar 2021-12-08 14:11:27 +08:00 committed by openeuler-sync-bot
parent 30f926a987
commit 8378df4821
88 changed files with 10556 additions and 1 deletions

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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));

View File

@ -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(&params, &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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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