]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
libcli/security: access_check handles CALLBACK_OBJECT types
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Mon, 25 Sep 2023 01:36:59 +0000 (14:36 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 26 Sep 2023 23:45:36 +0000 (23:45 +0000)
These are like an object type if the callback (i.e. condtional ACE
conditions) succeeds, otherwise they are ignored.

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

index 5b0594e3f78278178827b9823a6d5dc2e38228f6..a974edf81379d54e7b8bca72b9a4a9454ab21f6e 100644 (file)
@@ -681,8 +681,8 @@ static NTSTATUS check_object_specific_access(const struct security_ace *ace,
                }
        }
 
-       if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
-
+       if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
+           ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT) {
                /* apply the access rights to this node, and any children */
                object_tree_modify_access(node, ace->access_mask);
 
@@ -853,6 +853,62 @@ NTSTATUS sec_access_check_ds_implicit_owner(const struct security_descriptor *sd
                                return NT_STATUS_OK;
                        }
                        break;
+               case SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT:
+               {
+                       /*
+                        * if the callback says ALLOW, we treat this as a
+                        * SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT.
+                        *
+                        * Otherwise we act as if this ACE does not exist.
+                        */
+                       enum ace_callback_result allow =
+                               check_callback_ace_allow(ace, token, sd);
+                       if (allow == ACE_CALLBACK_INVALID) {
+                               return NT_STATUS_INVALID_ACE_CONDITION;
+                       }
+                       if (allow != ACE_CALLBACK_ALLOW) {
+                               break;
+                       }
+
+                       status = check_object_specific_access(ace, tree,
+                                                             &grant_access);
+
+                       if (!NT_STATUS_IS_OK(status)) {
+                               return status;
+                       }
+
+                       if (grant_access) {
+                               return NT_STATUS_OK;
+                       }
+                       break;
+               }
+               case SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT:
+               {
+                       /*
+                        * ACCESS_DENIED_OBJECT ACEs can't grant access --
+                        * they either don't match the object and slide
+                        * harmlessly past or they return
+                        * NT_STATUS_ACCESS_DENIED.
+                        *
+                        * ACCESS_DENIED_CALLBACK_OBJECT ACEs add another way
+                        * of not applying, and another way of failing.
+                        */
+                       enum ace_callback_result deny =
+                               check_callback_ace_deny(ace, token, sd);
+                       if (deny == ACE_CALLBACK_INVALID) {
+                               return NT_STATUS_INVALID_ACE_CONDITION;
+                       }
+                       if (deny != ACE_CALLBACK_DENY) {
+                               break;
+                       }
+                       status = check_object_specific_access(ace, tree,
+                                                             &grant_access);
+
+                       if (!NT_STATUS_IS_OK(status)) {
+                               return status;
+                       }
+                       break;
+               }
                default:        /* Other ACE types not handled/supported */
                        break;
                }