1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +03:00

librpc/security.idl: adjust size calculations for upcoming ace types

Soon we will get Conditional ACEs and Resource Attribute ACES, each of
which have trailing bytes at the end of the ACE. Here's a diagram:

              ____      The ACE size field may indicate a size bigger
  .type      /    |     than the known parts, even when you take
  .flags    /     |     rounding to a multiple of four into account.
  .size  --'      |     This extra data is meaningful in some ACEs.
  .access_mask    |
  .trustee (sid) _|  <- known data ends here.
                  :
   "coda"      ___:  <- the trailing part, Zero size unless the size
                        field points beyond the end of the known data.
			Probably empty for ordinary ACE types.

Until now we have thrown away these extra bytes, because they have no
meaning in the ACE types we recognise. But with conditional and
resource attribute ACEs we need to catch and process these bytes, so
we add an extra field for that.

Thus we can drop the manually written ndr_pull_security_ace() that
discarded the trailing bytes, because we just allow it to be pulled
into an unused blob. In the very common case, the blob will be empty.

Microsoft does not use a common name across different ACE types to
describe this end-data -- "coda" is a Samba term.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Douglas Bagnall 2023-07-13 21:31:50 +12:00 committed by Andrew Bartlett
parent 47edd41bc9
commit c73034cf7c
5 changed files with 59 additions and 38 deletions

View File

@ -67,6 +67,8 @@ void init_sec_ace(struct security_ace *t, const struct dom_sid *sid, enum securi
t->access_mask = mask;
t->trustee = *sid;
t->coda.ignored.data = NULL;
t->coda.ignored.length = 0;
}
int nt_ace_inherit_comp(const struct security_ace *a1, const struct security_ace *a2)

View File

@ -25,6 +25,8 @@
bool sec_ace_object(uint8_t type);
void sec_ace_copy(struct security_ace *ace_dest, const struct security_ace *ace_src);
size_t ndr_subcontext_size_of_ace_coda(const struct security_ace *ace, size_t ace_size, int flags);
void init_sec_ace(struct security_ace *t, const struct dom_sid *sid, enum security_ace_type type,
uint32_t mask, uint8_t flag);
int nt_ace_inherit_comp( const struct security_ace *a1, const struct security_ace *a2);

View File

@ -31,6 +31,7 @@ cpp_quote("#define dom_sid0 dom_sid")
*/
uuid("cbf7d408-2d6c-11e2-ae5b-0b5692790e18"),
version(0.0),
helper("../libcli/security/security.h"),
pyhelper("librpc/ndr/py_security.c"),
pointer_default(unique)
]
@ -588,13 +589,18 @@ interface security
[default];
} security_ace_object_ctr;
typedef [public,nopull,gensize,nosize] struct {
typedef [public,nodiscriminant,gensize] union {
[default][flag(NDR_REMAINING)] DATA_BLOB ignored;
} security_ace_coda;
typedef [public,gensize,nosize] 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;
uint32 access_mask;
[switch_is(type)] security_ace_object_ctr object;
dom_sid trustee;
[switch_is(type), subcontext(0), subcontext_size(ndr_subcontext_size_of_ace_coda(r, size, ndr->flags))] security_ace_coda coda;
} security_ace;
typedef enum {

View File

@ -1,21 +1,21 @@
/*
/*
Unix SMB/CIFS implementation.
fast routines for getting the wire size of security objects
Copyright (C) Andrew Tridgell 2003
Copyright (C) Stefan Metzmacher 2006-2008
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
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@ -25,10 +25,14 @@
#include "librpc/gen_ndr/ndr_security.h"
#include "../libcli/security/security.h"
/*
return the wire size of a security_ace
*/
size_t ndr_size_security_ace(const struct security_ace *ace, int flags)
* Find the wire size of a security_ace that has no trailing coda.
* This is used in ndr_pull_security_ace() generated from security.idl
* to work out where the coda starts (and in ndr_size_security_ace()
* just below).
*/
static size_t ndr_size_security_ace_core(const struct security_ace *ace, int flags)
{
size_t ret;
@ -56,35 +60,41 @@ size_t ndr_size_security_ace(const struct security_ace *ace, int flags)
return ret;
}
enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, int ndr_flags, struct security_ace *r)
/*
return the wire size of a security_ace
*/
size_t ndr_size_security_ace(const struct security_ace *ace, int flags)
{
if (ndr_flags & NDR_SCALARS) {
uint32_t start_ofs = ndr->offset;
uint32_t size = 0;
uint32_t pad = 0;
NDR_CHECK(ndr_pull_align(ndr, 4));
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_pull_set_switch_value(ndr, &r->object, r->type));
NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_SCALARS, &r->object));
NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee));
size = ndr->offset - start_ofs;
if (r->size < size) {
return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,
"ndr_pull_security_ace: r->size %u < size %u",
(unsigned)r->size, size);
}
pad = r->size - size;
NDR_PULL_NEED_BYTES(ndr, pad);
ndr->offset += pad;
size_t ret = ndr_size_security_ace_core(ace, flags);
ret += ndr_size_security_ace_coda(&ace->coda, ace->type, flags);
return ret;
}
/*
* 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.
*
* Usually the coda also can't be any smaller than the remaining
* space, because it is defined as a blob consuming everything it can.
*
* This is only used to find the size for the coda subcontext in
* security.idl.
*/
size_t ndr_subcontext_size_of_ace_coda(const struct security_ace *ace,
size_t ace_size,
int flags)
{
size_t core_size;
if (ace_size == 0) {
return 0;
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type));
NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_BUFFERS, &r->object));
core_size = ndr_size_security_ace_core(ace, flags);
if (ace_size < core_size) {
return 0;
}
return NDR_ERR_SUCCESS;
return ace_size - core_size;
}
/*
@ -109,7 +119,7 @@ size_t ndr_size_security_descriptor(const struct security_descriptor *sd, int fl
{
size_t ret;
if (!sd) return 0;
ret = 20;
ret += ndr_size_dom_sid(sd->owner_sid, flags);
ret += ndr_size_dom_sid(sd->group_sid, flags);
@ -177,7 +187,7 @@ enum ndr_err_code ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct
NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &num_auths));
NDR_CHECK(ndr_pull_dom_sid(ndr, ndr_flags, sid));
if (sid->num_auths != num_auths) {
return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE,
return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE,
"Bad num_auths %u; should equal %u",
num_auths, sid->num_auths);
}
@ -248,8 +258,8 @@ enum ndr_err_code ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const
}
if (sid->num_auths > 5) {
return ndr_push_error(ndr, NDR_ERR_RANGE,
"dom_sid28 allows only up to 5 sub auth [%u]",
return ndr_push_error(ndr, NDR_ERR_RANGE,
"dom_sid28 allows only up to 5 sub auth [%u]",
sid->num_auths);
}

View File

@ -0,0 +1 @@
^samba.tests.blackbox.ndrdump.+.NdrDumpTests.test_ndrdump_xattr_NTACL