Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • lts-team/packages/samba
  • thctlo/samba-lintianfix
  • arnaudr/samba
  • jrwren/samba
  • paride/samba
  • athos/samba
  • henrich/samba
  • cnotin/samba
  • mimi89999/samba
  • samba-team/samba
  • ahasenack/samba
  • jrtc27/samba
  • noel/samba
13 results
Show changes
Commits on Source (31)
......@@ -89,7 +89,7 @@ SAMBA_VERSION_PRE_RELEASE=
# e.g. SAMBA_VERSION_RC_RELEASE=1 #
# -> "3.0.0rc1" #
########################################################
SAMBA_VERSION_RC_RELEASE=1
SAMBA_VERSION_RC_RELEASE=2
########################################################
# To mark SVN snapshots this should be set to 'yes' #
......
Release Announcements
=====================
This is the first release candidate of Samba 4.20. This is *not*
This is the second release candidate of Samba 4.20. This is *not*
intended for production environments and is designed for testing
purposes only. Please report any defects via the Samba bug reporting
system at https://bugzilla.samba.org/.
......@@ -108,6 +108,90 @@ New options added are:
and all files/directories below.
- '--restore savefile' Restores the stored DACLS to files in directory
Samba-tool extensions for AD Claims, Authentication Policies and Silos
----------------------------------------------------------------------
samba-tool now allows users to be associated with claims. In the
Samba AD DC, claims derive from Active Directory attributes mapped
into specific names. These claims can be used in rules, which are
conditional ACEs in a security descriptor, that decide if a user is
restricted by an authentication policy.
samba-tool also allows the creation and management of authentication
policies, which are rules about where a user may authenticate from,
if NTLM is permitted, and what services a user may authenticate to.
Finally, support is added for the creation and management of
authentication silos, which are helpful in defining network boundaries
by grouping users and the services they connect to.
Please note: The command line syntax for these tools is not final, and
may change before the next release, as we gain user feedback. The
syntax will be locked in once Samba offers 2016 AD Functional Level as
a default.
AD DC support for Authentication Silos and Authentication Policies
------------------------------------------------------------------
The Samba AD DC now also honours any existing claims, authentication
policy and authentication silo configuration previously created (eg
from an import of a Microsoft AD), as well as new configurations
created with samba-tool. The use of Microsoft's Powershell based
client tools is not expected to work.
To use this feature, the functional level must be set to 2012_R2 or
later with:
ad dc functional level = 2016
in the smb.conf.
The smb.conf file on each DC must have 'ad dc functional level = 2016'
set to have the partially complete feature available. This will also,
at first startup, update the server's own AD entry with the configured
functional level.
For new domains, add these parameters to 'samba-tool provision'
--option="ad dc functional level = 2016" --function-level=2016
The second option, setting the overall domain functional level
indicates that all DCs should be at this functional level.
To raise the domain functional level of an existing domain, after
updating the smb.conf and restarting Samba run
samba-tool domain schemaupgrade --schema=2019
samba-tool domain functionalprep --function-level=2016
samba-tool domain level raise --domain-level=2016 --forest-level=2016
This support is still new, so is not enabled by default in this
release. The above instructions are set at 2016, which while not
complete, matches what our testing environment validates.
Conditional ACEs and Resource Attribute ACEs
--------------------------------------------
Ordinary Access Control Entries (ACEs) unconditionally allow or deny
access to a given user or group. Conditional ACEs have an additional
section that describes conditions under which the ACE applies. If the
conditional expression is true, the ACE works like an ordinary ACE,
otherwise it is ignored. The condition terms can refer to claims,
group memberships, and attributes on the object itself. These
attributes are described in Resource Attribute ACEs that occur in the
object's System Access Control List (SACL). Conditional ACEs are
described in Microsoft documentation.
Conditional ACE evaluation is controlled by the "acl claims
evaluation" smb.conf option. The default value is "AD DC only" which
enables them in AD DC settings. The other option is "never", which
disables them altogether. There is currently no option to enable them
on the file server (this is likely to change in future releases).
The Security Descriptor Definition Language has extensions for
conditional ACEs and resource attribute ACEs; these are now supported
by Samba.
REMOVED FEATURES
================
......@@ -127,6 +211,20 @@ smb.conf changes
Parameter Name Description Default
-------------- ----------- -------
smb3 unix extensions Per share -
acl claims evaluation new AD DC only
CHANGES SINCE 4.20.0rc1
=======================
o Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
* BUG 15574: Performance regression for NDR parsing of security descriptors.
o Anoop C S <anoopcs@samba.org>
* BUG 15565: Build and install man page for wspsearch client utility.
o Andreas Schneider <asn@samba.org>
* BUG 15558: samba-gpupdate logging doesn't work.
KNOWN ISSUES
......
samba (2:4.20.0~rc2+dfsg-1) experimental; urgency=medium
* new upstream release candidate (4.20.0-rc2)
Note: this is just release candidate, not a release yet!
* omit (for now) wspsearch.1
-- Michael Tokarev <mjt@tls.msk.ru> Thu, 15 Feb 2024 23:05:46 +0300
samba (2:4.20.0~rc1+dfsg-1) experimental; urgency=medium
* new upstream release candidate (4.20.0-rc1)
......
......@@ -4,3 +4,4 @@ usr/share/man/man7/traffic_learner.7
usr/share/samba/setup
# new experimental windows search client
usr/bin/wspsearch
usr/share/man/man1/wspsearch.1
......@@ -54,6 +54,7 @@ manpages='''
manpages/wbinfo.1
manpages/winbindd.8
manpages/samba-log-parser.1
manpages/wspsearch.1
'''
pam_winbind_manpages = '''
......
......@@ -715,7 +715,7 @@ interface security
[default][flag(NDR_REMAINING)] DATA_BLOB ignored;
} security_ace_coda;
typedef [public,gensize,nosize] struct {
typedef [public,gensize,nosize,nopush,nopull] struct {
security_ace_type type; /* SEC_ACE_TYPE_* */
security_ace_flags flags; /* SEC_ACE_FLAG_* */
[value(ndr_size_security_ace(r,ndr->flags))] uint16 size;
......
......@@ -367,7 +367,7 @@ enum ndr_compression_alg {
};
#define NDR_PULL_CHECK_FLAGS(ndr, ndr_flags) do { \
if ((ndr_flags) & ~(NDR_SCALARS|NDR_BUFFERS)) { \
if (unlikely((ndr_flags) & ~(NDR_SCALARS|NDR_BUFFERS))) { \
return ndr_pull_error(ndr, NDR_ERR_FLAGS, "Invalid pull struct ndr_flags 0x%"PRI_NDR_FLAGS_TYPE, ndr_flags); \
} \
} while (0)
......
......@@ -1453,6 +1453,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_DATA_BLOB(struct ndr_pull *ndr, ndr_flags_ty
} else {
NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &length));
}
if (length == 0) {
/* skip the talloc for an empty blob */
blob->data = NULL;
blob->length = 0;
return NDR_ERR_SUCCESS;
}
NDR_PULL_NEED_BYTES(ndr, length);
*blob = data_blob_talloc(ndr->current_mem_ctx, ndr->data+ndr->offset, length);
ndr->offset += length;
......
......@@ -64,7 +64,11 @@ size_t ndr_size_security_ace(const struct security_ace *ace, libndr_flags flags)
} else if (ace->type == SEC_ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE) {
ret += ndr_size_security_ace_coda(&ace->coda, ace->type, flags);
} else {
ret += ace->coda.ignored.length;
/*
* Normal ACEs have a coda.ignored blob that is always or
* almost always empty. We aren't going to push it (it is
* ignored), so we don't add that length to the size.
*/
}
/* round up to a multiple of 4 (MS-DTYP 2.4.4.1) */
ret = (ret + 3ULL) & ~3ULL;
......@@ -75,6 +79,107 @@ size_t ndr_size_security_ace(const struct security_ace *ace, libndr_flags flags)
return ret;
}
static inline enum ndr_err_code ndr_maybe_pull_security_ace_object_ctr(struct ndr_pull *ndr,
ndr_flags_type ndr_flags,
struct security_ace *r)
{
/*
* If this is not an object ACE (as is usually common),
* ndr_pull_security_ace_object_ctr() will do nothing.
*
* By avoiding calling the function in that case, we avoid some
* tallocing and ndr token busywork.
*/
bool is_object = sec_ace_object(r->type);
if (is_object) {
NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, is_object));
NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, ndr_flags, &r->object));
}
return NDR_ERR_SUCCESS;
}
_PUBLIC_ enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct security_ace *r)
{
NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
if (ndr_flags & NDR_SCALARS) {
ssize_t sub_size;
NDR_CHECK(ndr_pull_align(ndr, 5));
NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type));
NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask));
NDR_CHECK(ndr_maybe_pull_security_ace_object_ctr(ndr, NDR_SCALARS, r));
NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee));
sub_size = ndr_subcontext_size_of_ace_coda(r, r->size, ndr->flags);
if (!sec_ace_has_extra_blob(r->type) || sub_size == 0) {
r->coda.ignored.data = NULL;
r->coda.ignored.length = 0;
} else {
struct ndr_pull *_ndr_coda;
NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_coda, 0, sub_size));
NDR_CHECK(ndr_pull_set_switch_value(_ndr_coda, &r->coda, r->type));
NDR_CHECK(ndr_pull_security_ace_coda(_ndr_coda, NDR_SCALARS|NDR_BUFFERS, &r->coda));
NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_coda, 0, sub_size));
}
NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_maybe_pull_security_ace_object_ctr(ndr, NDR_BUFFERS, r));
}
return NDR_ERR_SUCCESS;
}
static inline enum ndr_err_code ndr_maybe_push_security_ace_object_ctr(struct ndr_push *ndr,
ndr_flags_type ndr_flags,
const struct security_ace *r)
{
/*
* ndr_push_security_ace_object_ctr() does nothing (except tallocing
* and ndr_token fiddling) unless the ACE is an object ACE, which is
* usually very unlikely.
*/
bool is_object = sec_ace_object(r->type);
if (is_object) {
NDR_CHECK(ndr_push_set_switch_value(ndr, &r->object, is_object));
NDR_CHECK(ndr_push_security_ace_object_ctr(ndr, ndr_flags, &r->object));
}
return NDR_ERR_SUCCESS;
}
_PUBLIC_ enum ndr_err_code ndr_push_security_ace(struct ndr_push *ndr, ndr_flags_type ndr_flags, const struct security_ace *r)
{
NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 5));
NDR_CHECK(ndr_push_security_ace_type(ndr, NDR_SCALARS, r->type));
NDR_CHECK(ndr_push_security_ace_flags(ndr, NDR_SCALARS, r->flags));
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, ndr_size_security_ace(r, ndr->flags)));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->access_mask));
NDR_CHECK(ndr_maybe_push_security_ace_object_ctr(ndr, NDR_SCALARS, r));
NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, &r->trustee));
if (sec_ace_has_extra_blob(r->type)) {
struct ndr_push *_ndr_coda;
size_t coda_size = ndr_subcontext_size_of_ace_coda(
r,
ndr_size_security_ace(r, ndr->flags),
ndr->flags);
NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_coda, 0, coda_size));
NDR_CHECK(ndr_push_set_switch_value(_ndr_coda, &r->coda, r->type));
NDR_CHECK(ndr_push_security_ace_coda(_ndr_coda, NDR_SCALARS|NDR_BUFFERS, &r->coda));
NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_coda, 0, coda_size));
}
NDR_CHECK(ndr_push_trailer_align(ndr, 5));
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_maybe_push_security_ace_object_ctr(ndr, NDR_BUFFERS, r));
}
return NDR_ERR_SUCCESS;
}
/*
* An ACE coda can't be bigger than the space allowed for by
* ace->size, so we need to check this from the context of the ACE.
......
......@@ -603,7 +603,8 @@ sub ParseSubcontextPullStart($$$$$)
$self->pidl("{");
$self->indent;
$self->pidl("struct ndr_pull *$subndr;");
$self->pidl("NDR_CHECK(ndr_pull_subcontext_start($ndr, &$subndr, $l->{HEADER_SIZE}, $subcontext_size));");
$self->pidl("ssize_t sub_size = $subcontext_size;");
$self->pidl("NDR_CHECK(ndr_pull_subcontext_start($ndr, &$subndr, $l->{HEADER_SIZE}, sub_size));");
if (defined $l->{COMPRESSION}) {
$subndr = $self->ParseCompressionPullStart($e, $l, $subndr, $env);
......@@ -622,7 +623,7 @@ sub ParseSubcontextPullEnd($$$$$)
$self->ParseCompressionPullEnd($e, $l, $subndr, $env);
}
$self->pidl("NDR_CHECK(ndr_pull_subcontext_end($ndr, $subndr, $l->{HEADER_SIZE}, $subcontext_size));");
$self->pidl("NDR_CHECK(ndr_pull_subcontext_end($ndr, $subndr, $l->{HEADER_SIZE}, sub_size));");
$self->deindent;
$self->pidl("}");
}
......
......@@ -23,9 +23,10 @@ import gettext
import random
import sys
logger = logging.getLogger()
logger = logging.getLogger("gp")
def logger_init(name, log_level):
logger = logging.getLogger(name)
logger.addHandler(logging.StreamHandler(sys.stdout))
logger.setLevel(logging.CRITICAL)
if log_level == 1:
......
......@@ -26,8 +26,8 @@ plantestsuite_loadlist("samba4.ldap.ad_dc_performance.python(ad_dc_ntvfs)",
'--workgroup=$DOMAIN',
'$LOADLIST', '$LISTOPT'])
plantestsuite_loadlist("samba4.ndr_pack_performance.python(ad_dc_ntvfs)",
"ad_dc_ntvfs",
plantestsuite_loadlist("samba4.ndr_pack_performance.python",
"none",
[python, os.path.join(samba4srcdir,
"dsdb/tests/python/ndr_pack_performance.py"),
'$SERVER', '-U"$USERNAME%$PASSWORD"',
......
......@@ -4,10 +4,7 @@ import optparse
import sys
sys.path.insert(0, 'bin/python')
import os
import samba
import samba.getopt as options
import random
import gzip
# We try to use the test infrastructure of Samba 4.3+, but if it
......@@ -16,45 +13,13 @@ import gzip
#
# Don't copy this horror into ordinary tests -- it is special for
# performance tests that want to apply to old versions.
try:
from samba.tests.subunitrun import SubunitOptions, TestProgram
ANCIENT_SAMBA = False
except ImportError:
ANCIENT_SAMBA = True
samba.ensure_external_module("testtools", "testtools")
samba.ensure_external_module("subunit", "subunit/python")
from subunit.run import SubunitTestRunner
import unittest
from samba.tests.subunitrun import TestProgram
from samba.ndr import ndr_pack, ndr_unpack
from samba.dcerpc import security
from samba.dcerpc import drsuapi
parser = optparse.OptionParser("ndr_pack_performance.py [options] <host>")
sambaopts = options.SambaOptions(parser)
parser.add_option_group(sambaopts)
parser.add_option_group(options.VersionOptions(parser))
if not ANCIENT_SAMBA:
subunitopts = SubunitOptions(parser)
parser.add_option_group(subunitopts)
# use command line creds if available
credopts = options.CredentialsOptions(parser)
parser.add_option_group(credopts)
opts, args = parser.parse_args()
if len(args) < 1:
parser.print_usage()
sys.exit(1)
host = args[0]
lp = sambaopts.get_loadparm()
creds = credopts.get_credentials(lp)
random.seed(1)
BIG_SD_SDDL = ''.join(
"""O:S-1-5-21-3328325300-3937145445-4190589019-512G:S-1-5-2
......@@ -130,6 +95,23 @@ IOID;RP;5f202010-79a5-11d0-9020-00c04fc2d4cf;bf967aba-0de6-11d0-a285-00aa0030
0aa003049e2;RU)(OA;CIIOID;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f608;bf967a86-0d
e6-11d0-a285-00aa003049e2;ED)""".split())
CONDITIONAL_ACE_SDDL = ('O:SYG:SYD:(XA;OICI;CR;;;WD;'
'(@USER.ad://ext/AuthenticationSilo == "siloname"))')
NON_OBJECT_SDDL = (
"O:S-1-5-21-2212615479-2695158682-2101375468-512"
"G:S-1-5-21-2212615479-2695158682-2101375468-513"
"D:P(A;OICI;FA;;;S-1-5-21-2212615479-2695158682-2101375468-512)"
"(A;OICI;FA;;;S-1-5-21-2212615479-2695158682-2101375468-519)"
"(A;OICIIO;FA;;;CO)"
"(A;OICI;FA;;;S-1-5-21-2212615479-2695158682-2101375468-512)"
"(A;OICI;FA;;;SY)"
"(A;OICI;0x1200a9;;;AU)"
"(A;OICI;0x1200a9;;;ED)")
# set SCALE = 100 for normal test, or 1 for testing the test.
SCALE = 100
......@@ -144,57 +126,82 @@ class UserTests(samba.tests.TestCase):
return f.read()
def get_desc(self, sddl):
dummy_sid = security.dom_sid("S-2-0-0")
dummy_sid = security.dom_sid("S-1-2-3")
return security.descriptor.from_sddl(sddl, dummy_sid)
def get_blob(self, sddl):
return ndr_pack(self.get_desc(sddl))
def test_00_00_do_nothing(self):
def test_00_00_do_nothing(self, cycles=10000):
# this gives us an idea of the overhead
pass
for i in range(SCALE * cycles):
pass
def _test_pack(self, unpacked, cycles=10000):
pack = unpacked.__ndr_pack__
for i in range(SCALE * cycles):
ndr_pack(unpacked)
pack()
def _test_unpack(self, blob, cycles=10000, cls=security.descriptor):
for i in range(SCALE * cycles):
ndr_unpack(cls, blob)
cls().__ndr_unpack__(blob)
def _test_pack_unpack(self, desc, cycles=5000, cls=security.descriptor):
blob2 = ndr_pack(desc)
for i in range(SCALE * cycles):
blob = ndr_pack(desc)
desc = ndr_unpack(cls, blob)
self.assertEqual(blob, blob2)
def test_pack_big_sd(self):
def test_pack_big_sd_with_object_aces(self):
unpacked = self.get_desc(BIG_SD_SDDL)
self._test_pack(unpacked)
def test_unpack_big_sd(self):
def test_unpack_big_sd_with_object_aces(self):
blob = self.get_blob(BIG_SD_SDDL)
self._test_unpack(blob)
def test_pack_unpack_big_sd(self):
def test_pack_unpack_big_sd_with_object_aces(self):
unpacked = self.get_desc(BIG_SD_SDDL)
self._test_pack_unpack(unpacked)
def test_pack_little_sd(self):
def test_pack_little_sd_with_object_aces(self):
unpacked = self.get_desc(LITTLE_SD_SDDL)
self._test_pack(unpacked)
def test_unpack_little_sd(self):
def test_unpack_little_sd_with_object_aces(self):
blob = self.get_blob(LITTLE_SD_SDDL)
self._test_unpack(blob)
def test_pack_unpack_little_sd(self):
def test_pack_unpack_little_sd_with_object_aces(self):
unpacked = self.get_desc(LITTLE_SD_SDDL)
self._test_pack_unpack(unpacked)
def test_pack_conditional_ace_sd(self):
unpacked = self.get_desc(CONDITIONAL_ACE_SDDL)
self._test_pack(unpacked)
def test_unpack_conditional_ace_sd(self):
blob = self.get_blob(CONDITIONAL_ACE_SDDL)
self._test_unpack(blob)
def test_pack_unpack_conditional_ace_sd(self):
unpacked = self.get_desc(CONDITIONAL_ACE_SDDL)
self._test_pack_unpack(unpacked)
def test_pack_non_object_sd(self):
unpacked = self.get_desc(NON_OBJECT_SDDL)
self._test_pack(unpacked)
def test_unpack_non_object_sd(self):
blob = self.get_blob(NON_OBJECT_SDDL)
self._test_unpack(blob)
def test_pack_unpack_non_object_sd(self):
unpacked = self.get_desc(NON_OBJECT_SDDL)
self._test_pack_unpack(unpacked)
def test_unpack_repl_sample(self):
blob = self.get_file_blob('testdata/replication-ndrpack-example.gz')
self._test_unpack(blob, cycles=20, cls=drsuapi.DsGetNCChangesCtr6)
......@@ -205,18 +212,4 @@ class UserTests(samba.tests.TestCase):
self._test_pack(desc, cycles=20)
if "://" not in host:
if os.path.isfile(host):
host = "tdb://%s" % host
else:
host = "ldap://%s" % host
if ANCIENT_SAMBA:
runner = SubunitTestRunner()
if not runner.run(unittest.TestLoader().loadTestsFromTestCase(
UserTests)).wasSuccessful():
sys.exit(1)
sys.exit(0)
else:
TestProgram(module=__name__, opts=subunitopts)
TestProgram(module=__name__)