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 <me...@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 <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>
    Reviewed-by: Joseph Sutton <josephsut...@catalyst.net.nz>
    
    Autobuild-User(master): Stefan Metzmacher <me...@samba.org>
    Autobuild-Date(master): Mon Mar 20 10:53:41 UTC 2023 on atb-devel-224

commit bd327f7d7a0d5f3377129ceb7f74e9dcf40587f3
Author: Stefan Metzmacher <me...@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 <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>
    Reviewed-by: Joseph Sutton <josephsut...@catalyst.net.nz>

commit 8f4aced365381cae70fa33f9f0641f33ab3db1fb
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Mar 25 13:28:48 2022 +0100

    libcli/security: simplify rid-based SDDL sid strings
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>
    Reviewed-by: Joseph Sutton <josephsut...@catalyst.net.nz>

commit 7d466a913f2c0038b30424403a7355db849fee7a
Author: Stefan Metzmacher <me...@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 <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>
    Reviewed-by: Joseph Sutton <josephsut...@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

Reply via email to