diff options
author | Derrell Lipman <derrell@samba.org> | 2007-08-15 17:40:26 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:29:50 -0500 |
commit | 415b7463a3b543f4c7a1eab83162d65918337045 (patch) | |
tree | f7762383f6d6b177d680535d8418ce5ca9c01f05 /source3 | |
parent | 3dd3c4cd013dadd1a1f57ac3e0750018dc5a0698 (diff) | |
download | samba-415b7463a3b543f4c7a1eab83162d65918337045.tar.gz samba-415b7463a3b543f4c7a1eab83162d65918337045.tar.bz2 samba-415b7463a3b543f4c7a1eab83162d65918337045.zip |
r24466: - Sort ACEs according to http://support.microsoft.com/kb/269175 so that
Windows Explorer doesn't complain about the order (and so that they get
interpreted properly).
Derrell
(This used to be commit 8f371e2ea97a3b58d1c7c3aa1368a0904295f681)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/libsmb/libsmbclient.c | 82 |
1 files changed, 72 insertions, 10 deletions
diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 8fd18bd99d..fcc7c65a3a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3732,32 +3732,94 @@ smbc_utimes_ctx(SMBCCTX *context, } -/* The MSDN is contradictory over the ordering of ACE entries in an ACL. - However NT4 gives a "The information may have been modified by a - computer running Windows NT 5.0" if denied ACEs do not appear before - allowed ACEs. */ +/* + * Sort ACEs according to the documentation at + * http://support.microsoft.com/kb/269175, at least as far as it defines the + * order. + */ static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2) { - if (sec_ace_equal(ace1, ace2)) + BOOL b1; + BOOL b2; + + /* If the ACEs are equal, we have nothing more to do. */ + if (sec_ace_equal(ace1, ace2)) { return 0; + } + + /* Inherited follow non-inherited */ + b1 = ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); + b2 = ((ace2->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* + * What shall we do with AUDITs and ALARMs? It's undefined. We'll + * sort them after DENY and ALLOW. + */ + b1 = (ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED && + ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && + ace1->type != SEC_ACE_TYPE_ACCESS_DENIED && + ace1->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + b2 = (ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED && + ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && + ace2->type != SEC_ACE_TYPE_ACCESS_DENIED && + ace2->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* Allowed ACEs follow denied ACEs */ + b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED || + ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); + b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED || + ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); + if (b1 != b2) { + return (b1 ? 1 : -1); + } - if (ace1->type != ace2->type) + /* + * ACEs applying to an entity's object follow those applying to the + * entity itself + */ + b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || + ace1->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || + ace2->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* + * If we get this far, the ACEs are similar as far as the + * characteristics we typically care about (those defined by the + * referenced MS document). We'll now sort by characteristics that + * just seems reasonable. + */ + + if (ace1->type != ace2->type) { return ace2->type - ace1->type; + } - if (sid_compare(&ace1->trustee, &ace2->trustee)) + if (sid_compare(&ace1->trustee, &ace2->trustee)) { return sid_compare(&ace1->trustee, &ace2->trustee); + } - if (ace1->flags != ace2->flags) + if (ace1->flags != ace2->flags) { return ace1->flags - ace2->flags; + } - if (ace1->access_mask != ace2->access_mask) + if (ace1->access_mask != ace2->access_mask) { return ace1->access_mask - ace2->access_mask; + } - if (ace1->size != ace2->size) + if (ace1->size != ace2->size) { return ace1->size - ace2->size; + } return memcmp(ace1, ace2, sizeof(SEC_ACE)); } |