summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libcli/security/access_check.c86
-rw-r--r--libcli/security/access_check.h11
2 files changed, 87 insertions, 10 deletions
diff --git a/libcli/security/access_check.c b/libcli/security/access_check.c
index 7f08cb5ed8..9153dad499 100644
--- a/libcli/security/access_check.c
+++ b/libcli/security/access_check.c
@@ -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)
{
diff --git a/libcli/security/access_check.h b/libcli/security/access_check.h
index dccc117cd5..84b2e5fee9 100644
--- a/libcli/security/access_check.h
+++ b/libcli/security/access_check.h
@@ -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 */