libcli/security: add sddl_decode_err_msg()
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Thu, 26 Oct 2023 03:55:33 +0000 (16:55 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 1 Nov 2023 20:10:45 +0000 (20:10 +0000)
This will return an error message, if it can, along with an indicative
position.

For conditional ACEs the message might be accurate, and the position
fine-grained. For example, you might be able to construct the message
like this:

D:(XA;;CC;;;S-1-2-3;(@User.Title == !(@User.Title)))
                                    ^
 16: unexpected operator

For non-conditional ACEs, the position typically points to the beginning
of the ACE, like this:

D:(D;OICI;GA;;;BG)(D;OICI;GA;;;AN)(A; OICI; GRGWGX;;;AU)
                                  ^
 unknown error

Here the error is in the spaces either side of " OICI; ", but the pointer
points to the beginning of the ACE.

The old sddl_decode() function becomes a wrapper around the new function,
which inherits the guts of the old function.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
libcli/security/sddl.c
libcli/security/sddl.h

index 04cc577d2c8da6861339bb9d975bf85a28bc0756..9bd8d805c3306dba3e7cf059c4906979663f8c4d 100644 (file)
@@ -810,10 +810,14 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd,
 }
 
 /*
-  decode a security descriptor in SDDL format
-*/
-struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl,
-                                       const struct dom_sid *domain_sid)
+ * Decode a security descriptor in SDDL format, catching compilation
+ * error messages, if any.
+ *
+ * The message will be a direct talloc child of mem_ctx or NULL.
+ */
+struct security_descriptor *sddl_decode_err_msg(TALLOC_CTX *mem_ctx, const char *sddl,
+                                               const struct dom_sid *domain_sid,
+                                               const char **msg, size_t *msg_offset)
 {
        struct sddl_transition_state state = {
                /*
@@ -877,6 +881,26 @@ failed:
        return NULL;
 }
 
+
+/*
+  decode a security descriptor in SDDL format
+*/
+struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl,
+                                       const struct dom_sid *domain_sid)
+{
+       const char *msg = NULL;
+       size_t msg_offset = 0;
+       struct security_descriptor *sd = sddl_decode_err_msg(mem_ctx, sddl, domain_sid,
+                                                            &msg, &msg_offset);
+       DBG_NOTICE("could not decode '%s'\n", sddl);
+       if (msg != NULL) {
+               DBG_NOTICE("                  %*c\n", (int)msg_offset, '^');
+               DBG_NOTICE("error '%s'\n", msg);
+               talloc_free(discard_const(msg));
+       }
+       return sd;
+}
+
 /*
   turn a set of flags into a string
 */
index 824b7032546147837f492015e5c76d3083ba873f..c4dc72d834d5b31b735c37802865f388d3b10903 100644 (file)
@@ -25,6 +25,9 @@
 
 struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl,
                                        const struct dom_sid *domain_sid);
+struct security_descriptor *sddl_decode_err_msg(TALLOC_CTX *mem_ctx, const char *sddl,
+                                               const struct dom_sid *domain_sid,
+                                               const char **msg, size_t *msg_offset);
 char *sddl_encode(TALLOC_CTX *mem_ctx, const struct security_descriptor *sd,
                  const struct dom_sid *domain_sid);
 char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace,