]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
libcli: Fix parsing access flags from multiple tables
authorVolker Lendecke <vl@samba.org>
Mon, 19 Apr 2021 14:00:27 +0000 (16:00 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 21 Apr 2021 00:04:36 +0000 (00:04 +0000)
We have to look at all available mappings for parsing sddl for each
special flag set. "GW" and "FX" come from two different tables, but
the previous code settled on one table and then expected both "GW" and
"FX" to come from that same table. Change the code to look at all
tables per special flag set.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Wed Apr 21 00:04:36 UTC 2021 on sn-devel-184

libcli/security/sddl.c
python/samba/tests/sddl.py

index 899fdbdddf1770061f56b6b3b8e491fe79c8e157..26049ec458a0ca3e809b714b5f2f293822e2be10 100644 (file)
@@ -234,6 +234,39 @@ static const struct flag_map decode_ace_access_mask[] = {
        { NULL, 0 },
 };
 
+static bool sddl_decode_access(const char *str, uint32_t *pmask)
+{
+       const char *str0 = str;
+       uint32_t mask = 0;
+       int cmp;
+
+       cmp = strncmp(str, "0x", 2);
+       if (cmp == 0) {
+               *pmask = strtol(str, NULL, 16);
+               return true;
+       }
+
+       while ((str[0] != '\0') && isupper(str[0])) {
+               uint32_t flags = 0;
+               size_t len = 0;
+               bool found;
+
+               found = sddl_map_flag(
+                       ace_access_mask, str, &len, &flags);
+               found |= sddl_map_flag(
+                       decode_ace_access_mask, str, &len, &flags);
+               if (!found) {
+                       DEBUG(1, ("Unknown flag - %s in %s\n", str, str0));
+                       return false;
+               }
+               mask |= flags;
+               str += len;
+       }
+
+       *pmask = mask;
+       return true;
+}
+
 /*
   decode an ACE
   return true on success, false on failure
@@ -247,6 +280,7 @@ static bool sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char
        int i;
        uint32_t v;
        struct dom_sid *sid;
+       bool ok;
 
        ZERO_STRUCTP(ace);
 
@@ -273,15 +307,9 @@ static bool sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char
        ace->flags = v;
        
        /* access mask */
-       if (strncmp(tok[2], "0x", 2) == 0) {
-               ace->access_mask = strtol(tok[2], NULL, 16);
-       } else {
-               if (!sddl_map_flags(ace_access_mask, tok[2], &v, NULL) &&
-                   !sddl_map_flags(
-                           decode_ace_access_mask, tok[2], &v, NULL)) {
-                       return false;
-               }
-               ace->access_mask = v;
+       ok = sddl_decode_access(tok[2], &ace->access_mask);
+       if (!ok) {
+               return false;
        }
 
        /* object */
index 9e1e1147a6a754d27be83b4b3e44d27465251e36..83df59719c887eefbb2b61bfd46a8a971ea48d0a 100644 (file)
@@ -182,5 +182,6 @@ class SddlDecodeEncode(TestCase):
     def test_multiflag(self):
         sid = security.dom_sid("S-1-2-3-4")
         raised = False
-        with self.assertRaises(Exception):
-            sd = security.descriptor.from_sddl("D:(A;;GWFX;;;DA)", sid)
+        sd = security.descriptor.from_sddl("D:(A;;GWFX;;;DA)", sid)
+        sddl = sd.as_sddl(sid)
+        self.assertEqual(sd, security.descriptor.from_sddl(sddl, sid))