[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Mon Mar 20 10:54:01 UTC 2023
The branch, master has been updated
via f3fad5a189f libcli/security: prepare sddl machine/forest_sid handling
via bd327f7d7a0 libcli/security: simplify sddl_encode_sid()
via 8f4aced3653 libcli/security: simplify rid-based SDDL sid strings
via 7d466a913f2 libcli/security: introduce struct sddl_transition_state
from 3e2eb1b0236 s4:kdc: Add client claims blob if it is present
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit f3fad5a189f73615360510ac61266c9fffa58edc
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Jan 14 11:02:10 2016 +0100
libcli/security: prepare sddl machine/forest_sid handling
In future we need to pass in 3 sids to sddl_encode()
Once we pass in a machine_sid from the caller we need to
have a test on a Windows member if the .machine_rid values
really belong to the local machine sid.
At least [MS-DTYP] 2.4.2.4 Well-Known SID Structures
pretents "LA" and "LG" are relative to the local machine sid.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Mon Mar 20 10:53:41 UTC 2023 on atb-devel-224
commit bd327f7d7a0d5f3377129ceb7f74e9dcf40587f3
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Mar 25 14:23:45 2022 +0100
libcli/security: simplify sddl_encode_sid()
We should walk the sid_codes array just once.
This makes further changes easier...
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
commit 8f4aced365381cae70fa33f9f0641f33ab3db1fb
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Mar 25 13:28:48 2022 +0100
libcli/security: simplify rid-based SDDL sid strings
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
commit 7d466a913f2c0038b30424403a7355db849fee7a
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Apr 30 19:49:12 2020 +0200
libcli/security: introduce struct sddl_transition_state
In future we'll need more than 'domain_sid' in order
to do the correct transition of SDDL to/from security_descriptor.
In the end we most likely add an
sddl_transition_{create,encode,decode}() api in order
to allow the caller to create an sddl_transition_state
once and then pass it to multiple calls to encode/decode.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
-----------------------------------------------------------------------
Summary of changes:
libcli/security/sddl.c | 186 +++++++++++++++++++++++++++++++++----------------
1 file changed, 127 insertions(+), 59 deletions(-)
Changeset truncated at 500 lines:
diff --git a/libcli/security/sddl.c b/libcli/security/sddl.c
index 076f040cfb8..dad5ce8f413 100644
--- a/libcli/security/sddl.c
+++ b/libcli/security/sddl.c
@@ -25,6 +25,12 @@
#include "librpc/gen_ndr/ndr_misc.h"
#include "system/locale.h"
+struct sddl_transition_state {
+ const struct dom_sid *machine_sid;
+ const struct dom_sid *domain_sid;
+ const struct dom_sid *forest_sid;
+};
+
struct flag_map {
const char *name;
uint32_t flag;
@@ -87,7 +93,9 @@ static bool sddl_map_flags(const struct flag_map *map, const char *str,
static const struct {
const char *code;
const char *sid;
- uint32_t rid;
+ uint32_t machine_rid;
+ uint32_t domain_rid;
+ uint32_t forest_rid;
} sid_codes[] = {
{ .code = "WD", .sid = SID_WORLD },
@@ -147,28 +155,28 @@ static const struct {
{ .code = "AS", .sid = SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY },
{ .code = "SS", .sid = SID_SERVICE_ASSERTED_IDENTITY },
- { .code = "RO", .sid = NULL, .rid = DOMAIN_RID_ENTERPRISE_READONLY_DCS },
+ { .code = "RO", .forest_rid = DOMAIN_RID_ENTERPRISE_READONLY_DCS },
- { .code = "LA", .sid = NULL, .rid = DOMAIN_RID_ADMINISTRATOR },
- { .code = "LG", .sid = NULL, .rid = DOMAIN_RID_GUEST },
+ { .code = "LA", .machine_rid = DOMAIN_RID_ADMINISTRATOR },
+ { .code = "LG", .machine_rid = DOMAIN_RID_GUEST },
- { .code = "DA", .sid = NULL, .rid = DOMAIN_RID_ADMINS },
- { .code = "DU", .sid = NULL, .rid = DOMAIN_RID_USERS },
- { .code = "DG", .sid = NULL, .rid = DOMAIN_RID_GUESTS },
- { .code = "DC", .sid = NULL, .rid = DOMAIN_RID_DOMAIN_MEMBERS },
- { .code = "DD", .sid = NULL, .rid = DOMAIN_RID_DCS },
- { .code = "CA", .sid = NULL, .rid = DOMAIN_RID_CERT_ADMINS },
- { .code = "SA", .sid = NULL, .rid = DOMAIN_RID_SCHEMA_ADMINS },
- { .code = "EA", .sid = NULL, .rid = DOMAIN_RID_ENTERPRISE_ADMINS },
- { .code = "PA", .sid = NULL, .rid = DOMAIN_RID_POLICY_ADMINS },
+ { .code = "DA", .domain_rid = DOMAIN_RID_ADMINS },
+ { .code = "DU", .domain_rid = DOMAIN_RID_USERS },
+ { .code = "DG", .domain_rid = DOMAIN_RID_GUESTS },
+ { .code = "DC", .domain_rid = DOMAIN_RID_DOMAIN_MEMBERS },
+ { .code = "DD", .domain_rid = DOMAIN_RID_DCS },
+ { .code = "CA", .domain_rid = DOMAIN_RID_CERT_ADMINS },
+ { .code = "SA", .forest_rid = DOMAIN_RID_SCHEMA_ADMINS },
+ { .code = "EA", .forest_rid = DOMAIN_RID_ENTERPRISE_ADMINS },
+ { .code = "PA", .domain_rid = DOMAIN_RID_POLICY_ADMINS },
- { .code = "CN", .sid = NULL, .rid = DOMAIN_RID_CLONEABLE_CONTROLLERS },
+ { .code = "CN", .domain_rid = DOMAIN_RID_CLONEABLE_CONTROLLERS },
- { .code = "AP", .sid = NULL, .rid = DOMAIN_RID_PROTECTED_USERS },
- { .code = "KA", .sid = NULL, .rid = DOMAIN_RID_KEY_ADMINS },
- { .code = "EK", .sid = NULL, .rid = DOMAIN_RID_ENTERPRISE_KEY_ADMINS },
+ { .code = "AP", .domain_rid = DOMAIN_RID_PROTECTED_USERS },
+ { .code = "KA", .domain_rid = DOMAIN_RID_KEY_ADMINS },
+ { .code = "EK", .forest_rid = DOMAIN_RID_ENTERPRISE_KEY_ADMINS },
- { .code = "RS", .sid = NULL, .rid = DOMAIN_RID_RAS_SERVERS }
+ { .code = "RS", .domain_rid = DOMAIN_RID_RAS_SERVERS }
};
/*
@@ -176,7 +184,7 @@ static const struct {
It can either be a special 2 letter code, or in S-* format
*/
static struct dom_sid *sddl_decode_sid(TALLOC_CTX *mem_ctx, const char **sddlp,
- const struct dom_sid *domain_sid)
+ struct sddl_transition_state *state)
{
const char *sddl = (*sddlp);
size_t i;
@@ -207,8 +215,20 @@ static struct dom_sid *sddl_decode_sid(TALLOC_CTX *mem_ctx, const char **sddlp,
(*sddlp) += 2;
- if (sid_codes[i].sid == NULL) {
- return dom_sid_add_rid(mem_ctx, domain_sid, sid_codes[i].rid);
+
+ if (sid_codes[i].machine_rid != 0) {
+ return dom_sid_add_rid(mem_ctx, state->machine_sid,
+ sid_codes[i].machine_rid);
+ }
+
+ if (sid_codes[i].domain_rid != 0) {
+ return dom_sid_add_rid(mem_ctx, state->domain_sid,
+ sid_codes[i].domain_rid);
+ }
+
+ if (sid_codes[i].forest_rid != 0) {
+ return dom_sid_add_rid(mem_ctx, state->forest_sid,
+ sid_codes[i].forest_rid);
}
return dom_sid_parse_talloc(mem_ctx, sid_codes[i].sid);
@@ -305,7 +325,7 @@ static bool sddl_decode_access(const char *str, uint32_t *pmask)
note that this routine modifies the string
*/
static bool sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char *str,
- const struct dom_sid *domain_sid)
+ struct sddl_transition_state *state)
{
const char *tok[6];
const char *s;
@@ -366,7 +386,7 @@ static bool sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char
/* trustee */
s = tok[5];
- sid = sddl_decode_sid(mem_ctx, &s, domain_sid);
+ sid = sddl_decode_sid(mem_ctx, &s, state);
if (sid == NULL) {
return false;
}
@@ -388,7 +408,7 @@ static const struct flag_map acl_flags[] = {
*/
static struct security_acl *sddl_decode_acl(struct security_descriptor *sd,
const char **sddlp, uint32_t *flags,
- const struct dom_sid *domain_sid)
+ struct sddl_transition_state *state)
{
const char *sddl = *sddlp;
struct security_acl *acl;
@@ -428,7 +448,7 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd,
return NULL;
}
if (!sddl_decode_ace(acl->aces, &acl->aces[acl->num_aces],
- astr, domain_sid)) {
+ astr, state)) {
talloc_free(acl);
return NULL;
}
@@ -457,6 +477,16 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd,
struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl,
const struct dom_sid *domain_sid)
{
+ struct sddl_transition_state state = {
+ /*
+ * TODO: verify .machine_rid values really belong to
+ * to the machine_sid on a member, once
+ * we pass machine_sid from the caller...
+ */
+ .machine_sid = domain_sid,
+ .domain_sid = domain_sid,
+ .forest_sid = domain_sid,
+ };
struct security_descriptor *sd;
sd = talloc_zero(mem_ctx, struct security_descriptor);
@@ -472,13 +502,13 @@ struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl,
switch (c) {
case 'D':
if (sd->dacl != NULL) goto failed;
- sd->dacl = sddl_decode_acl(sd, &sddl, &flags, domain_sid);
+ sd->dacl = sddl_decode_acl(sd, &sddl, &flags, &state);
if (sd->dacl == NULL) goto failed;
sd->type |= flags | SEC_DESC_DACL_PRESENT;
break;
case 'S':
if (sd->sacl != NULL) goto failed;
- sd->sacl = sddl_decode_acl(sd, &sddl, &flags, domain_sid);
+ sd->sacl = sddl_decode_acl(sd, &sddl, &flags, &state);
if (sd->sacl == NULL) goto failed;
/* this relies on the SEC_DESC_SACL_* flags being
1 bit shifted from the SEC_DESC_DACL_* flags */
@@ -486,12 +516,12 @@ struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl,
break;
case 'O':
if (sd->owner_sid != NULL) goto failed;
- sd->owner_sid = sddl_decode_sid(sd, &sddl, domain_sid);
+ sd->owner_sid = sddl_decode_sid(sd, &sddl, &state);
if (sd->owner_sid == NULL) goto failed;
break;
case 'G':
if (sd->group_sid != NULL) goto failed;
- sd->group_sid = sddl_decode_sid(sd, &sddl, domain_sid);
+ sd->group_sid = sddl_decode_sid(sd, &sddl, &state);
if (sd->group_sid == NULL) goto failed;
break;
}
@@ -547,45 +577,57 @@ failed:
encode a sid in SDDL format
*/
static char *sddl_encode_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
- const struct dom_sid *domain_sid)
+ struct sddl_transition_state *state)
{
+ bool in_machine = dom_sid_in_domain(state->machine_sid, sid);
+ bool in_domain = dom_sid_in_domain(state->domain_sid, sid);
+ bool in_forest = dom_sid_in_domain(state->forest_sid, sid);
+ struct dom_sid_buf buf;
+ const char *sidstr = dom_sid_str_buf(sid, &buf);
+ uint32_t rid = 0;
size_t i;
- char *sidstr;
- sidstr = dom_sid_string(mem_ctx, sid);
- if (sidstr == NULL) return NULL;
+ if (sid->num_auths > 1) {
+ rid = sid->sub_auths[sid->num_auths-1];
+ }
+
+ for (i=0;i<ARRAY_SIZE(sid_codes);i++) {
+ /* seen if its a well known sid */
+ if (sid_codes[i].sid != NULL) {
+ int cmp;
+
+ cmp = strcmp(sidstr, sid_codes[i].sid);
+ if (cmp != 0) {
+ continue;
+ }
- /* seen if its a well known sid */
- for (i=0;sid_codes[i].sid;i++) {
- if (strcmp(sidstr, sid_codes[i].sid) == 0) {
- talloc_free(sidstr);
return talloc_strdup(mem_ctx, sid_codes[i].code);
}
- }
- /* or a well known rid in our domain */
- if (dom_sid_in_domain(domain_sid, sid)) {
- uint32_t rid = sid->sub_auths[sid->num_auths-1];
- for (;i<ARRAY_SIZE(sid_codes);i++) {
- if (rid == sid_codes[i].rid) {
- talloc_free(sidstr);
- return talloc_strdup(mem_ctx, sid_codes[i].code);
- }
+ if (rid == 0) {
+ continue;
}
- }
- talloc_free(sidstr);
+ if (in_machine && sid_codes[i].machine_rid == rid) {
+ return talloc_strdup(mem_ctx, sid_codes[i].code);
+ }
+ if (in_domain && sid_codes[i].domain_rid == rid) {
+ return talloc_strdup(mem_ctx, sid_codes[i].code);
+ }
+ if (in_forest && sid_codes[i].forest_rid == rid) {
+ return talloc_strdup(mem_ctx, sid_codes[i].code);
+ }
+ }
- /* TODO: encode well known sids as two letter codes */
- return dom_sid_string(mem_ctx, sid);
+ return talloc_strdup(mem_ctx, sidstr);
}
/*
encode an ACE in SDDL format
*/
-char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace,
- const struct dom_sid *domain_sid)
+static char *sddl_transition_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace,
+ struct sddl_transition_state *state)
{
char *sddl = NULL;
TALLOC_CTX *tmp_ctx;
@@ -639,7 +681,7 @@ char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace,
}
}
- sddl_trustee = sddl_encode_sid(tmp_ctx, &ace->trustee, domain_sid);
+ sddl_trustee = sddl_encode_sid(tmp_ctx, &ace->trustee, state);
if (sddl_trustee == NULL) {
goto failed;
}
@@ -653,11 +695,27 @@ failed:
return sddl;
}
+char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace,
+ const struct dom_sid *domain_sid)
+{
+ struct sddl_transition_state state = {
+ /*
+ * TODO: verify .machine_rid values really belong to
+ * to the machine_sid on a member, once
+ * we pass machine_sid from the caller...
+ */
+ .machine_sid = domain_sid,
+ .domain_sid = domain_sid,
+ .forest_sid = domain_sid,
+ };
+ return sddl_transition_encode_ace(mem_ctx, ace, &state);
+}
+
/*
encode an ACL in SDDL format
*/
static char *sddl_encode_acl(TALLOC_CTX *mem_ctx, const struct security_acl *acl,
- uint32_t flags, const struct dom_sid *domain_sid)
+ uint32_t flags, struct sddl_transition_state *state)
{
char *sddl;
uint32_t i;
@@ -668,7 +726,7 @@ static char *sddl_encode_acl(TALLOC_CTX *mem_ctx, const struct security_acl *acl
/* now the ACEs, encoded in braces */
for (i=0;i<acl->num_aces;i++) {
- char *ace = sddl_encode_ace(sddl, &acl->aces[i], domain_sid);
+ char *ace = sddl_transition_encode_ace(sddl, &acl->aces[i], state);
if (ace == NULL) goto failed;
sddl = talloc_asprintf_append_buffer(sddl, "(%s)", ace);
if (sddl == NULL) goto failed;
@@ -689,6 +747,16 @@ failed:
char *sddl_encode(TALLOC_CTX *mem_ctx, const struct security_descriptor *sd,
const struct dom_sid *domain_sid)
{
+ struct sddl_transition_state state = {
+ /*
+ * TODO: verify .machine_rid values really belong to
+ * to the machine_sid on a member, once
+ * we pass machine_sid from the caller...
+ */
+ .machine_sid = domain_sid,
+ .domain_sid = domain_sid,
+ .forest_sid = domain_sid,
+ };
char *sddl;
TALLOC_CTX *tmp_ctx;
@@ -699,28 +767,28 @@ char *sddl_encode(TALLOC_CTX *mem_ctx, const struct security_descriptor *sd,
tmp_ctx = talloc_new(mem_ctx);
if (sd->owner_sid != NULL) {
- char *sid = sddl_encode_sid(tmp_ctx, sd->owner_sid, domain_sid);
+ char *sid = sddl_encode_sid(tmp_ctx, sd->owner_sid, &state);
if (sid == NULL) goto failed;
sddl = talloc_asprintf_append_buffer(sddl, "O:%s", sid);
if (sddl == NULL) goto failed;
}
if (sd->group_sid != NULL) {
- char *sid = sddl_encode_sid(tmp_ctx, sd->group_sid, domain_sid);
+ char *sid = sddl_encode_sid(tmp_ctx, sd->group_sid, &state);
if (sid == NULL) goto failed;
sddl = talloc_asprintf_append_buffer(sddl, "G:%s", sid);
if (sddl == NULL) goto failed;
}
if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl != NULL) {
- char *acl = sddl_encode_acl(tmp_ctx, sd->dacl, sd->type, domain_sid);
+ char *acl = sddl_encode_acl(tmp_ctx, sd->dacl, sd->type, &state);
if (acl == NULL) goto failed;
sddl = talloc_asprintf_append_buffer(sddl, "D:%s", acl);
if (sddl == NULL) goto failed;
}
if ((sd->type & SEC_DESC_SACL_PRESENT) && sd->sacl != NULL) {
- char *acl = sddl_encode_acl(tmp_ctx, sd->sacl, sd->type>>1, domain_sid);
+ char *acl = sddl_encode_acl(tmp_ctx, sd->sacl, sd->type>>1, &state);
if (acl == NULL) goto failed;
sddl = talloc_asprintf_append_buffer(sddl, "S:%s", acl);
if (sddl == NULL) goto failed;
--
Samba Shared Repository
More information about the samba-cvs
mailing list