From 2b89e1a20a6c726e5c3219a944143f0beb7c5920 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 27 Aug 2012 15:41:18 -0700 Subject: [PATCH] Factor out privilege checking code into se_file_access_check() which takes a bool priv_open_requested parameter. --- libcli/security/access_check.c | 86 +++++++++++++++++++++++++++++++++++++----- libcli/security/access_check.h | 11 ++++++ 2 files changed, 87 insertions(+), 10 deletions(-) diff --git a/libcli/security/access_check.c b/libcli/security/access_check.c index 7f08cb5ed85..9153dad4996 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 dccc117cd5b..84b2e5fee99 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 */ -- 2.11.4.GIT