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:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user