Factor out privilege checking code into se_file_access_check() which takes a bool...
authorJeremy Allison <jra@samba.org>
Mon, 27 Aug 2012 22:41:18 +0000 (15:41 -0700)
committerJeremy Allison <jra@samba.org>
Sat, 1 Sep 2012 03:29:13 +0000 (20:29 -0700)
libcli/security/access_check.c
libcli/security/access_check.h

index 7f08cb5ed851329e85c5095da1c6aa30cc8da19e..9153dad49960a57294265c7c36a95e02ac05757c 100644 (file)
@@ -274,16 +274,6 @@ NTSTATUS se_access_check(const struct security_descriptor *sd,
                }
        }
 
-       /* TODO: remove this, as it is file server specific */
-       if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
-           security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
-               bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
-       }
-       if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
-           security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
-               bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
-       }
-
        if ((bits_remaining & SEC_STD_WRITE_OWNER) &&
             security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
                bits_remaining &= ~(SEC_STD_WRITE_OWNER);
@@ -298,6 +288,82 @@ done:
        return NT_STATUS_OK;
 }
 
+/*
+  The main entry point for access checking FOR THE FILE SERVER ONLY !
+  If returning ACCESS_DENIED this function returns the denied bits in
+  the uint32_t pointed to by the access_granted pointer.
+*/
+NTSTATUS se_file_access_check(const struct security_descriptor *sd,
+                         const struct security_token *token,
+                         bool priv_open_requested,
+                         uint32_t access_desired,
+                         uint32_t *access_granted)
+{
+       uint32_t bits_remaining;
+       NTSTATUS status;
+
+       if (!priv_open_requested) {
+               /* Fall back to generic se_access_check(). */
+               return se_access_check(sd,
+                               token,
+                               access_desired,
+                               access_granted);
+       }
+
+       /*
+        * We need to handle the maximum allowed flag
+        * outside of se_access_check(), as we need to
+        * add in the access allowed by the privileges
+        * as well.
+        */
+
+       if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
+               uint32_t orig_access_desired = access_desired;
+
+               access_desired |= access_check_max_allowed(sd, token);
+               access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
+
+               if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
+                       access_desired |= SEC_RIGHTS_PRIV_BACKUP;
+               }
+
+               if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
+                       access_desired |= SEC_RIGHTS_PRIV_RESTORE;
+               }
+
+               DEBUG(10,("se_file_access_check: MAX desired = 0x%x "
+                       "mapped to 0x%x\n",
+                       orig_access_desired,
+                       access_desired));
+       }
+
+       status = se_access_check(sd,
+                               token,
+                               access_desired,
+                               access_granted);
+
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+               return status;
+       }
+
+       bits_remaining = *access_granted;
+
+       /* Check if we should override with privileges. */
+       if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
+           security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
+               bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
+       }
+       if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
+           security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
+               bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
+       }
+       if (bits_remaining != 0) {
+               *access_granted = bits_remaining;
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       return NT_STATUS_OK;
+}
 
 static const struct GUID *get_ace_object_type(struct security_ace *ace)
 {
index dccc117cd5b0983adfde6b3d931f930df56d4825..84b2e5fee99b1c29dbdb9b7c5a2195f0963c00ed 100644 (file)
@@ -54,6 +54,17 @@ NTSTATUS se_access_check(const struct security_descriptor *sd,
                         uint32_t access_desired,
                         uint32_t *access_granted);
 
+/*
+  The main entry point for access checking FOR THE FILE SERVER ONLY !
+  If returning ACCESS_DENIED this function returns the denied bits in
+  the uint32_t pointed to by the access_granted pointer.
+*/
+NTSTATUS se_file_access_check(const struct security_descriptor *sd,
+                        const struct security_token *token,
+                        bool priv_open_requested,
+                        uint32_t access_desired,
+                        uint32_t *access_granted);
+
 /* modified access check for the purposes of DS security
  * Lots of code duplication, it will ve united in just one
  * function eventually */