commit 4625b945cbf338dc5ba3cdbad20c575155b5be19 Author: Paul Fertser Date: Wed Oct 8 16:58:47 2008 +0400 Fixed ACL setting by smbcacls on w2k shares * The sorting order of ACEs was wrong; * SEC_DESC_DACL_AUTO_INHERIT_REQ must be set to preserve w2k inheritance (not sure what effect that has on nt4). Tested on a w2k3 share. Before the change windows clients complained about wrong ACEs order and objects in the affected container were created with SEC_ACE_FLAG_INHERITED_ACE unset (nt4 semantic afaik). This patch fixed the issues. diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index d488ce2..91c2187 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -506,6 +506,7 @@ static void sec_desc_print(struct cli_state *cli, FILE *f, SEC_DESC *sd) uint32 i; fprintf(f, "REVISION:%d\n", sd->revision); + fprintf(f, "CONTROL:0x%x\n", sd->type); /* Print owner and group sid */ @@ -604,7 +605,7 @@ static int owner_set(struct cli_state *cli, enum chown_mode change_mode, return EXIT_FAILED; } - sd = make_sec_desc(talloc_tos(),old->revision, old->type, + sd = make_sec_desc(talloc_tos(),old->revision, old->type | SEC_DESC_DACL_AUTO_INHERIT_REQ, (change_mode == REQUEST_CHOWN) ? &sid : NULL, (change_mode == REQUEST_CHGRP) ? &sid : NULL, NULL, NULL, &sd_size); @@ -626,16 +627,29 @@ static int owner_set(struct cli_state *cli, enum chown_mode change_mode, } -/* 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. */ +/* 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. At + http://technet.microsoft.com/en-us/library/cc781716.aspx the + canonical order is specified as "Explicit Deny, Explicit Allow, + Inherited ACEs unchanged" */ static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2) { if (sec_ace_equal(ace1, ace2)) return 0; + if ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) && + !(ace2->flags & SEC_ACE_FLAG_INHERITED_ACE)) + return 1; + if (!(ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) && + (ace2->flags & SEC_ACE_FLAG_INHERITED_ACE)) + return -1; + if ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) && + (ace2->flags & SEC_ACE_FLAG_INHERITED_ACE)) + return ace1 - ace2; + if (ace1->type != ace2->type) return ace2->type - ace1->type; @@ -791,7 +805,7 @@ static int cacl_set(struct cli_state *cli, char *filename, and W2K. JRA. */ - sd = make_sec_desc(talloc_tos(),old->revision, old->type, + sd = make_sec_desc(talloc_tos(),old->revision, old->type | SEC_DESC_DACL_AUTO_INHERIT_REQ, old->owner_sid, old->group_sid, NULL, old->dacl, &sd_size);