#include "includes.h"
BOOL sec_ace_object(uint8 type)
{
if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
return True;
}
return False;
}
void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src)
{
ace_dest->type = ace_src->type;
ace_dest->flags = ace_src->flags;
ace_dest->size = ace_src->size;
ace_dest->info.mask = ace_src->info.mask;
ace_dest->obj_flags = ace_src->obj_flags;
memcpy(&ace_dest->obj_guid, &ace_src->obj_guid, sizeof(struct uuid));
memcpy(&ace_dest->inh_guid, &ace_src->inh_guid, sizeof(struct uuid));
sid_copy(&ace_dest->trustee, &ace_src->trustee);
}
void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
{
t->type = type;
t->flags = flag;
t->size = sid_size(sid) + 8;
t->info = mask;
ZERO_STRUCTP(&t->trustee);
sid_copy(&t->trustee, sid);
}
NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, unsigned *num, DOM_SID *sid, uint32 mask)
{
unsigned int i = 0;
if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
*num += 1;
if((new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0)
return NT_STATUS_NO_MEMORY;
for (i = 0; i < *num - 1; i ++)
sec_ace_copy(&(*new)[i], &old[i]);
(*new)[i].type = 0;
(*new)[i].flags = 0;
(*new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid);
(*new)[i].info.mask = mask;
sid_copy(&(*new)[i].trustee, sid);
return NT_STATUS_OK;
}
NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask)
{
unsigned int i = 0;
if (!ace || !sid) return NT_STATUS_INVALID_PARAMETER;
for (i = 0; i < num; i ++) {
if (sid_compare(&ace[i].trustee, sid) == 0) {
ace[i].info.mask = mask;
return NT_STATUS_OK;
}
}
return NT_STATUS_NOT_FOUND;
}
NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, uint32 *num, DOM_SID *sid)
{
unsigned int i = 0;
unsigned int n_del = 0;
if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
if((new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0)
return NT_STATUS_NO_MEMORY;
for (i = 0; i < *num; i ++) {
if (sid_compare(&old[i].trustee, sid) != 0)
sec_ace_copy(&(*new)[i], &old[i]);
else
n_del ++;
}
if (n_del == 0)
return NT_STATUS_NOT_FOUND;
else {
*num -= n_del;
return NT_STATUS_OK;
}
}
BOOL sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
{
if (!s1 && !s2) return True;
if (s1->type != s2->type || s1->flags != s2->flags ||
s1->info.mask != s2->info.mask) {
return False;
}
if (!sid_equal(&s1->trustee, &s2->trustee)) {
return False;
}
return True;
}
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;
}
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;
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;
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;
}
void dacl_sort_into_canonical_order(SEC_ACE *srclist, unsigned int num_aces)
{
unsigned int i;
if (!srclist || num_aces == 0)
return;
qsort( srclist, num_aces, sizeof(srclist[0]), QSORT_CAST nt_ace_inherit_comp);
for (i = 0; i < num_aces; i++ ) {
SEC_ACE *curr_ace = &srclist[i];
if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE)
break;
}
if (i)
qsort( srclist, i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
if (num_aces - i)
qsort( &srclist[i], num_aces - i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
}
BOOL token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace)
{
size_t i;
for (i = 0; i < token->num_sids; i++) {
if (sid_equal(&ace->trustee, &token->user_sids[i]))
return True;
}
return False;
}