diff options
author | Richard Sharpe <realrichardsharpe@gmail.com> | 2012-03-13 16:47:17 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2012-03-14 02:26:34 +0100 |
commit | 44590c1b70c0a24f853c02d5fcdb3c609401e2ca (patch) | |
tree | c6f8a6db7e6aff213cecb48394be3256dc69611a | |
parent | 0e376db8b8b3770b189fbd9b3874406bcafcfd32 (diff) | |
download | samba-44590c1b70c0a24f853c02d5fcdb3c609401e2ca.tar.gz samba-44590c1b70c0a24f853c02d5fcdb3c609401e2ca.tar.xz samba-44590c1b70c0a24f853c02d5fcdb3c609401e2ca.zip |
Fix bug #8795 - Samba does not handle the Owner Rights permissions at all
Signed-off-by: Jeremy Allison <jra@samba.org>
Autobuild-User: Jeremy Allison <jra@samba.org>
Autobuild-Date: Wed Mar 14 02:26:34 CET 2012 on sn-devel-104
-rw-r--r-- | libcli/security/access_check.c | 52 | ||||
-rw-r--r-- | libcli/security/dom_sid.h | 1 | ||||
-rw-r--r-- | libcli/security/util_sid.c | 2 |
3 files changed, 49 insertions, 6 deletions
diff --git a/libcli/security/access_check.c b/libcli/security/access_check.c index d9f6293a460..7f08cb5ed85 100644 --- a/libcli/security/access_check.c +++ b/libcli/security/access_check.c @@ -159,6 +159,16 @@ NTSTATUS se_access_check(const struct security_descriptor *sd, uint32_t i; uint32_t bits_remaining; uint32_t explicitly_denied_bits = 0; + /* + * Up until Windows Server 2008, owner always had these rights. Now + * we have to use Owner Rights perms if they are on the file. + * + * In addition we have to accumulate these bits and apply them + * correctly. See bug #8795 + */ + uint32_t owner_rights_allowed = 0; + uint32_t owner_rights_denied = 0; + bool owner_rights_default = true; *access_granted = access_desired; bits_remaining = access_desired; @@ -178,12 +188,6 @@ NTSTATUS se_access_check(const struct security_descriptor *sd, bits_remaining)); } - /* the owner always gets SEC_STD_WRITE_DAC and SEC_STD_READ_CONTROL */ - if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) && - security_token_has_sid(token, sd->owner_sid)) { - bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL); - } - /* a NULL dacl allows access */ if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) { *access_granted = access_desired; @@ -202,6 +206,26 @@ NTSTATUS se_access_check(const struct security_descriptor *sd, continue; } + /* + * We need the Owner Rights permissions to ensure we + * give or deny the correct permissions to the owner. Replace + * owner_rights with the perms here if it is present. + * + * We don't care if we are not the owner because that is taken + * care of below when we check if our token has the owner SID. + * + */ + if (dom_sid_equal(&ace->trustee, &global_sid_Owner_Rights)) { + if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) { + owner_rights_allowed |= ace->access_mask; + owner_rights_default = false; + } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) { + owner_rights_denied |= ace->access_mask; + owner_rights_default = false; + } + continue; + } + if (!security_token_has_sid(token, &ace->trustee)) { continue; } @@ -219,6 +243,22 @@ NTSTATUS se_access_check(const struct security_descriptor *sd, } } + /* The owner always gets owner rights as defined above. */ + if (security_token_has_sid(token, sd->owner_sid)) { + if (owner_rights_default) { + /* + * Just remove them, no need to check if they are + * there. + */ + bits_remaining &= ~(SEC_STD_WRITE_DAC | + SEC_STD_READ_CONTROL); + } else { + bits_remaining &= ~owner_rights_allowed; + bits_remaining |= owner_rights_denied; + } + } + + /* Explicitly denied bits always override */ bits_remaining |= explicitly_denied_bits; /* diff --git a/libcli/security/dom_sid.h b/libcli/security/dom_sid.h index df57bd1d9ee..c4a417b64a6 100644 --- a/libcli/security/dom_sid.h +++ b/libcli/security/dom_sid.h @@ -38,6 +38,7 @@ extern const struct dom_sid global_sid_Authenticated_Users; extern const struct dom_sid global_sid_Network; extern const struct dom_sid global_sid_Creator_Owner; extern const struct dom_sid global_sid_Creator_Group; +extern const struct dom_sid global_sid_Owner_Rights; extern const struct dom_sid global_sid_Anonymous; extern const struct dom_sid global_sid_Builtin; extern const struct dom_sid global_sid_Builtin_Administrators; diff --git a/libcli/security/util_sid.c b/libcli/security/util_sid.c index f87d3ebe796..9a24a4ab8fa 100644 --- a/libcli/security/util_sid.c +++ b/libcli/security/util_sid.c @@ -62,6 +62,8 @@ const struct dom_sid global_sid_Creator_Owner = /* Creator Owner */ { 1, 1, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; const struct dom_sid global_sid_Creator_Group = /* Creator Group */ { 1, 1, {0,0,0,0,0,3}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Owner_Rights = /* Owner Rights */ +{ 1, 1, {0,0,0,0,0,3}, {4,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; const struct dom_sid global_sid_Anonymous = /* Anonymous login */ { 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; const struct dom_sid global_sid_Enterprise_DCs = /* Enterprise DCs */ |