1
0
mirror of https://github.com/samba-team/samba.git synced 2025-11-26 04:23:49 +03:00

Finally ! Fixed the ACL ordering bug reported by jcmd. I realised we were

not sorting returned ACE's correctly w.r.t. W2K - implemented the correct
algorithm.
Jeremy.
This commit is contained in:
Jeremy Allison
-
parent 80df684b72
commit fa23a4158e
2 changed files with 125 additions and 27 deletions

View File

@@ -3,7 +3,7 @@
* Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998,
* Copyright (C) Jeremy R. Allison 1995-1998
* Copyright (C) Jeremy R. Allison 1995-2003.
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
* Copyright (C) Paul Ashton 1997-1998.
*
@@ -901,7 +901,7 @@ BOOL sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int
}
/*******************************************************************
adds new SID with its permissions to SEC_DESC
Add a new SID with its permissions to SEC_DESC.
********************************************************************/
NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32 mask, size_t *sd_size)
@@ -913,7 +913,8 @@ NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32
*sd_size = 0;
if (!ctx || !psd || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER;
if (!ctx || !psd || !sid || !sd_size)
return NT_STATUS_INVALID_PARAMETER;
status = sec_ace_add_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid, mask);
@@ -933,14 +934,15 @@ NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32
}
/*******************************************************************
modify SID's permissions at SEC_DESC
Modify a SID's permissions in a SEC_DESC.
********************************************************************/
NTSTATUS sec_desc_mod_sid(SEC_DESC *sd, DOM_SID *sid, uint32 mask)
{
NTSTATUS status;
if (!sd || !sid) return NT_STATUS_INVALID_PARAMETER;
if (!sd || !sid)
return NT_STATUS_INVALID_PARAMETER;
status = sec_ace_mod_sid(sd->dacl->ace, sd->dacl->num_aces, sid, mask);
@@ -951,7 +953,7 @@ NTSTATUS sec_desc_mod_sid(SEC_DESC *sd, DOM_SID *sid, uint32 mask)
}
/*******************************************************************
delete SID from SEC_DESC
Delete a SID from a SEC_DESC.
********************************************************************/
NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t *sd_size)
@@ -963,7 +965,8 @@ NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t
*sd_size = 0;
if (!ctx || !psd[0] || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER;
if (!ctx || !psd[0] || !sid || !sd_size)
return NT_STATUS_INVALID_PARAMETER;
status = sec_ace_del_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid);
@@ -981,3 +984,108 @@ NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t
sd = 0;
return NT_STATUS_OK;
}
/*******************************************************************
Comparison function to sort non-inherited first.
*******************************************************************/
static int nt_ace_inherit_comp( SEC_ACE *a1, SEC_ACE *a2)
{
int a1_inh = a1->flags & SEC_ACE_FLAG_INHERITED_ACE;
int a2_inh = a2->flags & SEC_ACE_FLAG_INHERITED_ACE;
if (a1_inh == a2_inh)
return 0;
if (!a1_inh && a2_inh)
return -1;
return 1;
}
/*******************************************************************
Comparison function to apply the order explained below in a group.
*******************************************************************/
static int nt_ace_canon_comp( SEC_ACE *a1, SEC_ACE *a2)
{
if ((a1->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
(a2->type != SEC_ACE_TYPE_ACCESS_DENIED))
return -1;
if ((a2->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
(a1->type != SEC_ACE_TYPE_ACCESS_DENIED))
return 1;
/* Both access denied or access allowed. */
/* 1. ACEs that apply to the object itself */
if (!(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY))
return -1;
else if (!(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY))
return 1;
/* 2. ACEs that apply to a subobject of the object, such as
* a property set or property. */
if (a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
!(a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
return -1;
else if (a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
!(a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
return 1;
return 0;
}
/*******************************************************************
Functions to convert a SEC_DESC ACE DACL list into canonical order.
JRA.
--- from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp
The following describes the preferred order:
To ensure that noninherited ACEs have precedence over inherited ACEs,
place all noninherited ACEs in a group before any inherited ACEs.
This ordering ensures, for example, that a noninherited access-denied ACE
is enforced regardless of any inherited ACE that allows access.
Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as the following shows:
1. Access-denied ACEs that apply to the object itself
2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property
3. Access-allowed ACEs that apply to the object itself
4. Access-allowed ACEs that apply to a subobject of the object"
********************************************************************/
void dacl_sort_into_canonical_order(SEC_ACE *srclist, unsigned int num_aces)
{
unsigned int i;
if (!srclist || num_aces == 0)
return;
/* Sort so that non-inherited ACE's come first. */
qsort( srclist, num_aces, sizeof(srclist[0]), QSORT_CAST nt_ace_inherit_comp);
/* Find the boundary between non-inherited ACEs. */
for (i = 0; i < num_aces; i++ ) {
SEC_ACE *curr_ace = &srclist[i];
if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE)
break;
}
/* i now points at entry number of the first inherited ACE. */
/* Sort the non-inherited ACEs. */
if (i)
qsort( srclist, i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
/* Now sort the inherited ACEs. */
if (num_aces - i)
qsort( &srclist[i], num_aces - i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
}