summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2003-10-06 01:24:48 +0000
committerSimo Sorce <idra@samba.org>2003-10-06 01:24:48 +0000
commit762e7e1dff89cc14b0130fc9a22038b0845630a2 (patch)
treeed8c7bd3664a7df46685260a3c94933c85c350b6 /source3/lib
parent9cfd26141cf9530f27e673bfae119d9879894dd4 (diff)
downloadsamba-762e7e1dff89cc14b0130fc9a22038b0845630a2.tar.gz
samba-762e7e1dff89cc14b0130fc9a22038b0845630a2.tar.bz2
samba-762e7e1dff89cc14b0130fc9a22038b0845630a2.zip
split some security related functions in their own files.
(no need to include all of smbd files to use some basic sec functions) also minor compile fixes (This used to be commit 66074d3b097d8cf2a231bf08c7f4db62da68189d)
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/privileges.c345
-rw-r--r--source3/lib/secace.c285
-rw-r--r--source3/lib/secacl.c118
-rw-r--r--source3/lib/secdesc.c522
-rw-r--r--source3/lib/talloc.c21
-rw-r--r--source3/lib/util_seaccess.c129
-rw-r--r--source3/lib/util_sid.c2
7 files changed, 1271 insertions, 151 deletions
diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c
new file mode 100644
index 0000000000..1c23d9e40e
--- /dev/null
+++ b/source3/lib/privileges.c
@@ -0,0 +1,345 @@
+/*
+ Unix SMB/CIFS implementation.
+ Privileges handling functions
+ Copyright (C) Jean François Micouleau 1998-2001
+ Copyright (C) Simo Sorce 2002-2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/* defines */
+
+#define ALLOC_CHECK(ptr, err, label, str) do { if ((ptr) == NULL) { DEBUG(0, ("%s: out of memory!\n", str)); err = NT_STATUS_NO_MEMORY; goto label; } } while(0)
+#define NTSTATUS_CHECK(err, label, str1, str2) do { if (!NT_STATUS_IS_OK(err)) { DEBUG(0, ("%s: %s failed!\n", str1, str2)); } } while(0)
+
+/****************************************************************************
+ Check if a user is a mapped group.
+
+ This function will check if the group SID is mapped onto a
+ system managed gid or onto a winbind manged sid.
+ In the first case it will be threated like a mapped group
+ and the backend should take the member list with a getgrgid
+ and ignore any user that have been possibly set into the group
+ object.
+
+ In the second case, the group is a fully SAM managed group
+ served back to the system through winbind. In this case the
+ members of a Local group are "unrolled" to cope with the fact
+ that unix cannot contain groups inside groups.
+ The backend MUST never call any getgr* / getpw* function or
+ loops with winbind may happen.
+ ****************************************************************************/
+
+#if 0
+NTSTATUS is_mapped_group(BOOL *mapped, const DOM_SID *sid)
+{
+ NTSTATUS result;
+ gid_t id;
+
+ /* look if mapping exist, do not make idmap alloc an uid if SID is not found */
+ result = idmap_get_gid_from_sid(&id, sid, False);
+ if (NT_STATUS_IS_OK(result)) {
+ *mapped = gid_is_in_winbind_range(id);
+ } else {
+ *mapped = False;
+ }
+
+ return result;
+}
+#endif
+
+/****************************************************************************
+ duplicate alloc luid_attr
+ ****************************************************************************/
+NTSTATUS dupalloc_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_la)
+{
+ NTSTATUS ret;
+
+ *new_la = (LUID_ATTR *)talloc(mem_ctx, sizeof(LUID_ATTR));
+ ALLOC_CHECK(new_la, ret, done, "dupalloc_luid_attr");
+
+ (*new_la)->luid.high = old_la->luid.high;
+ (*new_la)->luid.low = old_la->luid.low;
+ (*new_la)->attr = old_la->attr;
+
+ ret = NT_STATUS_OK;
+
+done:
+ return ret;
+}
+
+/****************************************************************************
+ initialise a privilege list
+ ****************************************************************************/
+NTSTATUS init_privilege(PRIVILEGE_SET **priv_set)
+{
+ NTSTATUS ret;
+ TALLOC_CTX *mem_ctx = talloc_init("privilege set");
+ ALLOC_CHECK(mem_ctx, ret, done, "init_privilege");
+
+ *priv_set = talloc_zero(mem_ctx, sizeof(PRIVILEGE_SET));
+ ALLOC_CHECK(*priv_set, ret, done, "init_privilege");
+
+ (*priv_set)->mem_ctx = mem_ctx;
+
+ ret = NT_STATUS_OK;
+
+done:
+ return ret;
+}
+
+NTSTATUS init_priv_with_ctx(TALLOC_CTX *mem_ctx, PRIVILEGE_SET **priv_set)
+{
+ NTSTATUS ret;
+
+ *priv_set = talloc_zero(mem_ctx, sizeof(PRIVILEGE_SET));
+ ALLOC_CHECK(*priv_set, ret, done, "init_privilege");
+
+ (*priv_set)->mem_ctx = mem_ctx;
+ (*priv_set)->ext_ctx = True;
+
+ ret = NT_STATUS_OK;
+
+done:
+ return ret;
+}
+
+void reset_privilege(PRIVILEGE_SET *priv_set)
+{
+ priv_set->count = 0;
+ priv_set->control = 0;
+ priv_set->set = NULL;
+}
+
+void destroy_privilege(PRIVILEGE_SET **priv_set)
+{
+ reset_privilege(*priv_set);
+ if (!((*priv_set)->ext_ctx))
+ /* mem_ctx is local, destroy it */
+ talloc_destroy((*priv_set)->mem_ctx);
+ *priv_set = NULL;
+}
+
+/****************************************************************************
+ add a privilege to a privilege array
+ ****************************************************************************/
+NTSTATUS add_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
+{
+ NTSTATUS ret;
+ LUID_ATTR *new_set;
+
+ /* check if the privilege is not already in the list */
+ if (NT_STATUS_IS_OK(check_priv_in_privilege(priv_set, set)))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ /* we can allocate memory to add the new privilege */
+
+ new_set = (LUID_ATTR *)talloc_realloc(priv_set->mem_ctx, priv_set->set, (priv_set->count + 1) * (sizeof(LUID_ATTR)));
+ ALLOC_CHECK(new_set, ret, done, "add_privilege");
+
+ new_set[priv_set->count].luid.high = set.luid.high;
+ new_set[priv_set->count].luid.low = set.luid.low;
+ new_set[priv_set->count].attr = set.attr;
+
+ priv_set->count++;
+ priv_set->set = new_set;
+
+ ret = NT_STATUS_OK;
+
+done:
+ return ret;
+}
+
+/****************************************************************************
+ add all the privileges to a privilege array
+ ****************************************************************************/
+NTSTATUS add_all_privilege(PRIVILEGE_SET *priv_set)
+{
+ NTSTATUS result = NT_STATUS_OK;
+ LUID_ATTR set;
+
+ set.attr = 0;
+ set.luid.high = 0;
+
+ /* TODO: set a proper list of privileges */
+ set.luid.low = SE_PRIV_ADD_USERS;
+ result = add_privilege(priv_set, set);
+ NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege");
+
+ set.luid.low = SE_PRIV_ADD_MACHINES;
+ result = add_privilege(priv_set, set);
+ NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege");
+
+ set.luid.low = SE_PRIV_PRINT_OPERATOR;
+ result = add_privilege(priv_set, set);
+ NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege");
+
+done:
+ return result;
+}
+
+/****************************************************************************
+ check if the privilege list is empty
+ ****************************************************************************/
+NTSTATUS check_empty_privilege(PRIVILEGE_SET *priv_set)
+{
+ if (!priv_set)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ if (priv_set->count == 0)
+ return NT_STATUS_OK;
+
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
+/****************************************************************************
+ check if the privilege is in the privilege list
+ ****************************************************************************/
+NTSTATUS check_priv_in_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
+{
+ int i;
+
+ if (!priv_set)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ /* if the list is empty, obviously we can't have it */
+ if (NT_STATUS_IS_OK(check_empty_privilege(priv_set)))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ for (i = 0; i < priv_set->count; i++) {
+ LUID_ATTR *cur_set;
+
+ cur_set = &priv_set->set[i];
+ /* check only the low and high part. Checking the attr field has no meaning */
+ if ( (cur_set->luid.low == set.luid.low) &&
+ (cur_set->luid.high == set.luid.high) ) {
+ return NT_STATUS_OK;
+ }
+ }
+
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
+/****************************************************************************
+ remove a privilege from a privilege array
+ ****************************************************************************/
+NTSTATUS remove_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
+{
+ NTSTATUS ret;
+ LUID_ATTR *new_set;
+ LUID_ATTR *old_set;
+ int i,j;
+
+ if (!priv_set)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ /* check if the privilege is in the list */
+ if (!NT_STATUS_IS_OK(check_priv_in_privilege(priv_set, set)))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ /* special case if it's the only privilege in the list */
+ if (priv_set->count == 1) {
+ reset_privilege(priv_set);
+ return NT_STATUS_OK;
+ }
+
+ /*
+ * the privilege is there, create a new list,
+ * and copy the other privileges
+ */
+
+ old_set = priv_set->set;
+
+ new_set = (LUID_ATTR *)talloc(priv_set->mem_ctx, (priv_set->count - 1) * (sizeof(LUID_ATTR)));
+ ALLOC_CHECK(new_set, ret, done, "remove_privilege");
+
+ for (i=0, j=0; i < priv_set->count; i++) {
+ if ( (old_set[i].luid.low == set.luid.low) &&
+ (old_set[i].luid.high == set.luid.high) ) {
+ continue;
+ }
+
+ new_set[j].luid.low = old_set[i].luid.low;
+ new_set[j].luid.high = old_set[i].luid.high;
+ new_set[j].attr = old_set[i].attr;
+
+ j++;
+ }
+
+ if (j != priv_set->count - 1) {
+ DEBUG(0,("remove_privilege: mismatch ! difference is not -1\n"));
+ DEBUGADD(0,("old count:%d, new count:%d\n", priv_set->count, j));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ /* ok everything is fine */
+
+ priv_set->count--;
+ priv_set->set = new_set;
+
+ ret = NT_STATUS_OK;
+
+done:
+ return ret;
+}
+
+/****************************************************************************
+ duplicates a privilege array
+ the new privilege set must be passed inited
+ (use init_privilege or init_priv_with_ctx)
+ ****************************************************************************/
+NTSTATUS dup_priv_set(PRIVILEGE_SET *new_priv_set, PRIVILEGE_SET *priv_set)
+{
+ NTSTATUS ret;
+ LUID_ATTR *new_set;
+ LUID_ATTR *old_set;
+ int i;
+
+ if (!new_priv_set || !priv_set)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ /* special case if there are no privileges in the list */
+ if (priv_set->count == 0) {
+ return NT_STATUS_OK;
+ }
+
+ /*
+ * create a new list,
+ * and copy the other privileges
+ */
+
+ old_set = priv_set->set;
+
+ new_set = (LUID_ATTR *)talloc(new_priv_set->mem_ctx, (priv_set->count - 1) * (sizeof(LUID_ATTR)));
+ ALLOC_CHECK(new_set, ret, done, "dup_priv_set");
+
+ for (i=0; i < priv_set->count; i++) {
+
+ new_set[i].luid.low = old_set[i].luid.low;
+ new_set[i].luid.high = old_set[i].luid.high;
+ new_set[i].attr = old_set[i].attr;
+ }
+
+ new_priv_set->count = priv_set->count;
+ new_priv_set->control = priv_set->control;
+ new_priv_set->set = new_set;
+
+ ret = NT_STATUS_OK;
+
+done:
+ return ret;
+}
diff --git a/source3/lib/secace.c b/source3/lib/secace.c
new file mode 100644
index 0000000000..6769f1288a
--- /dev/null
+++ b/source3/lib/secace.c
@@ -0,0 +1,285 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * SEC_ACE handling functions
+ * Copyright (C) Andrew Tridgell 1992-1998,
+ * Copyright (C) Jeremy R. Allison 1995-2003.
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ * Copyright (C) Paul Ashton 1997-1998.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+/*******************************************************************
+ Check if ACE has OBJECT type.
+********************************************************************/
+
+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;
+}
+
+/*******************************************************************
+ copy a SEC_ACE structure.
+********************************************************************/
+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, GUID_SIZE);
+ memcpy(&ace_dest->inh_guid, &ace_src->inh_guid, GUID_SIZE);
+ sid_copy(&ace_dest->trustee, &ace_src->trustee);
+}
+
+/*******************************************************************
+ Sets up a SEC_ACE structure.
+********************************************************************/
+
+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);
+}
+
+/*******************************************************************
+ adds new SID with its permissions to ACE list
+********************************************************************/
+
+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] = (SEC_ACE *) talloc_zero(ctx, (*num) * sizeof(SEC_ACE))) == 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;
+}
+
+/*******************************************************************
+ modify SID's permissions at ACL
+********************************************************************/
+
+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;
+}
+
+/*******************************************************************
+ delete SID from ACL
+********************************************************************/
+
+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] = (SEC_ACE *) talloc_zero(ctx, (*num) * sizeof(SEC_ACE))) == 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;
+ }
+}
+
+/*******************************************************************
+ Compares two SEC_ACE structures
+********************************************************************/
+
+BOOL sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
+{
+ /* Trivial case */
+
+ if (!s1 && !s2) return True;
+
+ /* Check top level stuff */
+
+ if (s1->type != s2->type || s1->flags != s2->flags ||
+ s1->info.mask != s2->info.mask) {
+ return False;
+ }
+
+ /* Check SID */
+
+ 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;
+}
+
+/*******************************************************************
+ Comparison function to apply the order explained below in a group.
+*******************************************************************/
+
+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);
+}
+
+/*******************************************************************
+ Check if this ACE has a SID in common with the token.
+********************************************************************/
+
+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;
+}
diff --git a/source3/lib/secacl.c b/source3/lib/secacl.c
new file mode 100644
index 0000000000..756685a821
--- /dev/null
+++ b/source3/lib/secacl.c
@@ -0,0 +1,118 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * SEC_ACL handling routines
+ * Copyright (C) Andrew Tridgell 1992-1998,
+ * Copyright (C) Jeremy R. Allison 1995-2003.
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ * Copyright (C) Paul Ashton 1997-1998.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+/*******************************************************************
+ Create a SEC_ACL structure.
+********************************************************************/
+
+SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *ace_list)
+{
+ SEC_ACL *dst;
+ int i;
+
+ if((dst = (SEC_ACL *)talloc_zero(ctx,sizeof(SEC_ACL))) == NULL)
+ return NULL;
+
+ dst->revision = revision;
+ dst->num_aces = num_aces;
+ dst->size = SEC_ACL_HEADER_SIZE;
+
+ /* Now we need to return a non-NULL address for the ace list even
+ if the number of aces required is zero. This is because there
+ is a distinct difference between a NULL ace and an ace with zero
+ entries in it. This is achieved by checking that num_aces is a
+ positive number. */
+
+ if ((num_aces) &&
+ ((dst->ace = (SEC_ACE *)talloc(ctx, sizeof(SEC_ACE) * num_aces))
+ == NULL)) {
+ return NULL;
+ }
+
+ for (i = 0; i < num_aces; i++) {
+ dst->ace[i] = ace_list[i]; /* Structure copy. */
+ dst->size += ace_list[i].size;
+ }
+
+ return dst;
+}
+
+/*******************************************************************
+ Duplicate a SEC_ACL structure.
+********************************************************************/
+
+SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src)
+{
+ if(src == NULL)
+ return NULL;
+
+ return make_sec_acl(ctx, src->revision, src->num_aces, src->ace);
+}
+
+/*******************************************************************
+ Compares two SEC_ACL structures
+********************************************************************/
+
+BOOL sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
+{
+ unsigned int i, j;
+
+ /* Trivial cases */
+
+ if (!s1 && !s2) return True;
+ if (!s1 || !s2) return False;
+
+ /* Check top level stuff */
+
+ if (s1->revision != s2->revision) {
+ DEBUG(10, ("sec_acl_equal(): revision differs (%d != %d)\n",
+ s1->revision, s2->revision));
+ return False;
+ }
+
+ if (s1->num_aces != s2->num_aces) {
+ DEBUG(10, ("sec_acl_equal(): num_aces differs (%d != %d)\n",
+ s1->revision, s2->revision));
+ return False;
+ }
+
+ /* The ACEs could be in any order so check each ACE in s1 against
+ each ACE in s2. */
+
+ for (i = 0; i < s1->num_aces; i++) {
+ BOOL found = False;
+
+ for (j = 0; j < s2->num_aces; j++) {
+ if (sec_ace_equal(&s1->ace[i], &s2->ace[j])) {
+ found = True;
+ break;
+ }
+ }
+
+ if (!found) return False;
+ }
+
+ return True;
+}
diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c
new file mode 100644
index 0000000000..411185dbfa
--- /dev/null
+++ b/source3/lib/secdesc.c
@@ -0,0 +1,522 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * SEC_DESC handling functions
+ * Copyright (C) Andrew Tridgell 1992-1998,
+ * Copyright (C) Jeremy R. Allison 1995-2003.
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ * Copyright (C) Paul Ashton 1997-1998.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+/*******************************************************************
+ Works out the linearization size of a SEC_DESC.
+********************************************************************/
+
+size_t sec_desc_size(SEC_DESC *psd)
+{
+ size_t offset;
+
+ if (!psd) return 0;
+
+ offset = SEC_DESC_HEADER_SIZE;
+
+ /* don't align */
+
+ if (psd->owner_sid != NULL)
+ offset += sid_size(psd->owner_sid);
+
+ if (psd->grp_sid != NULL)
+ offset += sid_size(psd->grp_sid);
+
+ if (psd->sacl != NULL)
+ offset += psd->sacl->size;
+
+ if (psd->dacl != NULL)
+ offset += psd->dacl->size;
+
+ return offset;
+}
+
+/*******************************************************************
+ Compares two SEC_DESC structures
+********************************************************************/
+
+BOOL sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
+{
+ /* Trivial case */
+
+ if (!s1 && !s2) {
+ goto done;
+ }
+
+ /* Check top level stuff */
+
+ if (s1->revision != s2->revision) {
+ DEBUG(10, ("sec_desc_equal(): revision differs (%d != %d)\n",
+ s1->revision, s2->revision));
+ return False;
+ }
+
+ if (s1->type!= s2->type) {
+ DEBUG(10, ("sec_desc_equal(): type differs (%d != %d)\n",
+ s1->type, s2->type));
+ return False;
+ }
+
+ /* Check owner and group */
+
+ if (!sid_equal(s1->owner_sid, s2->owner_sid)) {
+ fstring str1, str2;
+
+ sid_to_string(str1, s1->owner_sid);
+ sid_to_string(str2, s2->owner_sid);
+
+ DEBUG(10, ("sec_desc_equal(): owner differs (%s != %s)\n",
+ str1, str2));
+ return False;
+ }
+
+ if (!sid_equal(s1->grp_sid, s2->grp_sid)) {
+ fstring str1, str2;
+
+ sid_to_string(str1, s1->grp_sid);
+ sid_to_string(str2, s2->grp_sid);
+
+ DEBUG(10, ("sec_desc_equal(): group differs (%s != %s)\n",
+ str1, str2));
+ return False;
+ }
+
+ /* Check ACLs present in one but not the other */
+
+ if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
+ (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl)) {
+ DEBUG(10, ("sec_desc_equal(): dacl or sacl not present\n"));
+ return False;
+ }
+
+ /* Sigh - we have to do it the hard way by iterating over all
+ the ACEs in the ACLs */
+
+ if (!sec_acl_equal(s1->dacl, s2->dacl) ||
+ !sec_acl_equal(s1->sacl, s2->sacl)) {
+ DEBUG(10, ("sec_desc_equal(): dacl/sacl list not equal\n"));
+ return False;
+ }
+
+ done:
+ DEBUG(10, ("sec_desc_equal(): secdescs are identical\n"));
+ return True;
+}
+
+/*******************************************************************
+ Merge part of security descriptor old_sec in to the empty sections of
+ security descriptor new_sec.
+********************************************************************/
+
+SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BUF *old_sdb)
+{
+ DOM_SID *owner_sid, *group_sid;
+ SEC_DESC_BUF *return_sdb;
+ SEC_ACL *dacl, *sacl;
+ SEC_DESC *psd = NULL;
+ uint16 secdesc_type;
+ size_t secdesc_size;
+
+ /* Copy over owner and group sids. There seems to be no flag for
+ this so just check the pointer values. */
+
+ owner_sid = new_sdb->sec->owner_sid ? new_sdb->sec->owner_sid :
+ old_sdb->sec->owner_sid;
+
+ group_sid = new_sdb->sec->grp_sid ? new_sdb->sec->grp_sid :
+ old_sdb->sec->grp_sid;
+
+ secdesc_type = new_sdb->sec->type;
+
+ /* Ignore changes to the system ACL. This has the effect of making
+ changes through the security tab audit button not sticking.
+ Perhaps in future Samba could implement these settings somehow. */
+
+ sacl = NULL;
+ secdesc_type &= ~SEC_DESC_SACL_PRESENT;
+
+ /* Copy across discretionary ACL */
+
+ if (secdesc_type & SEC_DESC_DACL_PRESENT) {
+ dacl = new_sdb->sec->dacl;
+ } else {
+ dacl = old_sdb->sec->dacl;
+ }
+
+ /* Create new security descriptor from bits */
+
+ psd = make_sec_desc(ctx, new_sdb->sec->revision, secdesc_type,
+ owner_sid, group_sid, sacl, dacl, &secdesc_size);
+
+ return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);
+
+ return(return_sdb);
+}
+
+/*******************************************************************
+ Creates a SEC_DESC structure
+********************************************************************/
+
+SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, uint16 type,
+ DOM_SID *owner_sid, DOM_SID *grp_sid,
+ SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size)
+{
+ SEC_DESC *dst;
+ uint32 offset = 0;
+
+ *sd_size = 0;
+
+ if(( dst = (SEC_DESC *)talloc_zero(ctx, sizeof(SEC_DESC))) == NULL)
+ return NULL;
+
+ dst->revision = revision;
+ dst->type = type;
+
+ if (sacl)
+ dst->type |= SEC_DESC_SACL_PRESENT;
+ if (dacl)
+ dst->type |= SEC_DESC_DACL_PRESENT;
+
+ dst->off_owner_sid = 0;
+ dst->off_grp_sid = 0;
+ dst->off_sacl = 0;
+ dst->off_dacl = 0;
+
+ if(owner_sid && ((dst->owner_sid = sid_dup_talloc(ctx,owner_sid)) == NULL))
+ goto error_exit;
+
+ if(grp_sid && ((dst->grp_sid = sid_dup_talloc(ctx,grp_sid)) == NULL))
+ goto error_exit;
+
+ if(sacl && ((dst->sacl = dup_sec_acl(ctx, sacl)) == NULL))
+ goto error_exit;
+
+ if(dacl && ((dst->dacl = dup_sec_acl(ctx, dacl)) == NULL))
+ goto error_exit;
+
+ offset = SEC_DESC_HEADER_SIZE;
+
+ /*
+ * Work out the linearization sizes.
+ */
+
+ if (dst->sacl != NULL) {
+ dst->off_sacl = offset;
+ offset += dst->sacl->size;
+ }
+ if (dst->dacl != NULL) {
+ dst->off_dacl = offset;
+ offset += dst->dacl->size;
+ }
+
+ if (dst->owner_sid != NULL) {
+ dst->off_owner_sid = offset;
+ offset += sid_size(dst->owner_sid);
+ }
+
+ if (dst->grp_sid != NULL) {
+ dst->off_grp_sid = offset;
+ offset += sid_size(dst->grp_sid);
+ }
+
+ *sd_size = (size_t)offset;
+ return dst;
+
+error_exit:
+
+ *sd_size = 0;
+ return NULL;
+}
+
+/*******************************************************************
+ Duplicate a SEC_DESC structure.
+********************************************************************/
+
+SEC_DESC *dup_sec_desc(TALLOC_CTX *ctx, const SEC_DESC *src)
+{
+ size_t dummy;
+
+ if(src == NULL)
+ return NULL;
+
+ return make_sec_desc( ctx, src->revision, src->type,
+ src->owner_sid, src->grp_sid, src->sacl,
+ src->dacl, &dummy);
+}
+
+/*******************************************************************
+ Creates a SEC_DESC structure with typical defaults.
+********************************************************************/
+
+SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, DOM_SID *owner_sid, DOM_SID *grp_sid,
+ SEC_ACL *dacl, size_t *sd_size)
+{
+ return make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
+ owner_sid, grp_sid, NULL, dacl, sd_size);
+}
+
+/*******************************************************************
+ Creates a SEC_DESC_BUF structure.
+********************************************************************/
+
+SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc)
+{
+ SEC_DESC_BUF *dst;
+
+ if((dst = (SEC_DESC_BUF *)talloc_zero(ctx, sizeof(SEC_DESC_BUF))) == NULL)
+ return NULL;
+
+ /* max buffer size (allocated size) */
+ dst->max_len = (uint32)len;
+ dst->len = (uint32)len;
+
+ if(sec_desc && ((dst->sec = dup_sec_desc(ctx, sec_desc)) == NULL)) {
+ return NULL;
+ }
+
+ dst->ptr = 0x1;
+
+ return dst;
+}
+
+/*******************************************************************
+ Duplicates a SEC_DESC_BUF structure.
+********************************************************************/
+
+SEC_DESC_BUF *dup_sec_desc_buf(TALLOC_CTX *ctx, SEC_DESC_BUF *src)
+{
+ if(src == NULL)
+ return NULL;
+
+ return make_sec_desc_buf( ctx, src->len, src->sec);
+}
+
+/*******************************************************************
+ 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)
+{
+ SEC_DESC *sd = 0;
+ SEC_ACL *dacl = 0;
+ SEC_ACE *ace = 0;
+ NTSTATUS status;
+
+ *sd_size = 0;
+
+ 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);
+
+ if (!NT_STATUS_IS_OK(status))
+ return status;
+
+ if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->type, psd[0]->owner_sid,
+ psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ *psd = sd;
+ sd = 0;
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ 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;
+
+ status = sec_ace_mod_sid(sd->dacl->ace, sd->dacl->num_aces, sid, mask);
+
+ if (!NT_STATUS_IS_OK(status))
+ return status;
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ 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)
+{
+ SEC_DESC *sd = 0;
+ SEC_ACL *dacl = 0;
+ SEC_ACE *ace = 0;
+ NTSTATUS status;
+
+ *sd_size = 0;
+
+ 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);
+
+ if (!NT_STATUS_IS_OK(status))
+ return status;
+
+ if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->type, psd[0]->owner_sid,
+ psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ *psd = sd;
+ sd = 0;
+ return NT_STATUS_OK;
+}
+
+/* Create a child security descriptor using another security descriptor as
+ the parent container. This child object can either be a container or
+ non-container object. */
+
+SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
+ BOOL child_container)
+{
+ SEC_DESC_BUF *sdb;
+ SEC_DESC *sd;
+ SEC_ACL *new_dacl, *the_acl;
+ SEC_ACE *new_ace_list = NULL;
+ unsigned int new_ace_list_ndx = 0, i;
+ size_t size;
+
+ /* Currently we only process the dacl when creating the child. The
+ sacl should also be processed but this is left out as sacls are
+ not implemented in Samba at the moment.*/
+
+ the_acl = parent_ctr->dacl;
+
+ if (!(new_ace_list = talloc(ctx, sizeof(SEC_ACE) * the_acl->num_aces)))
+ return NULL;
+
+ for (i = 0; the_acl && i < the_acl->num_aces; i++) {
+ SEC_ACE *ace = &the_acl->ace[i];
+ SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
+ uint8 new_flags = 0;
+ BOOL inherit = False;
+ fstring sid_str;
+
+ /* The OBJECT_INHERIT_ACE flag causes the ACE to be
+ inherited by non-container children objects. Container
+ children objects will inherit it as an INHERIT_ONLY
+ ACE. */
+
+ if (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) {
+
+ if (!child_container) {
+ new_flags |= SEC_ACE_FLAG_OBJECT_INHERIT;
+ } else {
+ new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
+ }
+
+ inherit = True;
+ }
+
+ /* The CONAINER_INHERIT_ACE flag means all child container
+ objects will inherit and use the ACE. */
+
+ if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
+ if (!child_container) {
+ inherit = False;
+ } else {
+ new_flags |= SEC_ACE_FLAG_CONTAINER_INHERIT;
+ }
+ }
+
+ /* The INHERIT_ONLY_ACE is not used by the se_access_check()
+ function for the parent container, but is inherited by
+ all child objects as a normal ACE. */
+
+ if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
+ /* Move along, nothing to see here */
+ }
+
+ /* The SEC_ACE_FLAG_NO_PROPAGATE_INHERIT flag means the ACE
+ is inherited by child objects but not grandchildren
+ objects. We clear the object inherit and container
+ inherit flags in the inherited ACE. */
+
+ if (ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
+ new_flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT |
+ SEC_ACE_FLAG_CONTAINER_INHERIT);
+ }
+
+ /* Add ACE to ACE list */
+
+ if (!inherit)
+ continue;
+
+ init_sec_access(&new_ace->info, ace->info.mask);
+ init_sec_ace(new_ace, &ace->trustee, ace->type,
+ new_ace->info, new_flags);
+
+ sid_to_string(sid_str, &ace->trustee);
+
+ DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
+ " inherited as %s:%d/0x%02x/0x%08x\n", sid_str,
+ ace->type, ace->flags, ace->info.mask,
+ sid_str, new_ace->type, new_ace->flags,
+ new_ace->info.mask));
+
+ new_ace_list_ndx++;
+ }
+
+ /* Create child security descriptor to return */
+
+ new_dacl = make_sec_acl(ctx, ACL_REVISION, new_ace_list_ndx, new_ace_list);
+
+ /* Use the existing user and group sids. I don't think this is
+ correct. Perhaps the user and group should be passed in as
+ parameters by the caller? */
+
+ sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
+ parent_ctr->owner_sid,
+ parent_ctr->grp_sid,
+ parent_ctr->sacl,
+ new_dacl, &size);
+
+ sdb = make_sec_desc_buf(ctx, size, sd);
+
+ return sdb;
+}
+
+/*******************************************************************
+ Sets up a SEC_ACCESS structure.
+********************************************************************/
+
+void init_sec_access(SEC_ACCESS *t, uint32 mask)
+{
+ t->mask = mask;
+}
+
diff --git a/source3/lib/talloc.c b/source3/lib/talloc.c
index b6c8b2efdf..485dc28f31 100644
--- a/source3/lib/talloc.c
+++ b/source3/lib/talloc.c
@@ -54,27 +54,6 @@
#include "includes.h"
-struct talloc_chunk {
- struct talloc_chunk *next;
- size_t size;
- void *ptr;
-};
-
-
-struct talloc_ctx {
- struct talloc_chunk *list;
- size_t total_alloc_size;
-
- /** The name recorded for this pool, if any. Should describe
- * the purpose for which it was allocated. The string is
- * allocated within the pool. **/
- char *name;
-
- /** Pointer to the next allocate talloc pool, so that we can
- * summarize all talloc memory usage. **/
- struct talloc_ctx *next_ctx;
-};
-
/**
* Start of linked list of all talloc pools.
diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c
index 2482d582d2..cb0f46e2f9 100644
--- a/source3/lib/util_seaccess.c
+++ b/source3/lib/util_seaccess.c
@@ -23,22 +23,6 @@
extern DOM_SID global_sid_Builtin;
-/**********************************************************************************
- Check if this ACE has a SID in common with the token.
-**********************************************************************************/
-
-static 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;
-}
-
/*********************************************************************************
Check an ACE against a SID. We return the remaining needed permission
bits not yet granted. Zero means permission allowed (no more needed bits).
@@ -332,119 +316,6 @@ BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
return False;
}
-/* Create a child security descriptor using another security descriptor as
- the parent container. This child object can either be a container or
- non-container object. */
-
-SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
- BOOL child_container)
-{
- SEC_DESC_BUF *sdb;
- SEC_DESC *sd;
- SEC_ACL *new_dacl, *the_acl;
- SEC_ACE *new_ace_list = NULL;
- unsigned int new_ace_list_ndx = 0, i;
- size_t size;
-
- /* Currently we only process the dacl when creating the child. The
- sacl should also be processed but this is left out as sacls are
- not implemented in Samba at the moment.*/
-
- the_acl = parent_ctr->dacl;
-
- if (!(new_ace_list = talloc(ctx, sizeof(SEC_ACE) * the_acl->num_aces)))
- return NULL;
-
- for (i = 0; the_acl && i < the_acl->num_aces; i++) {
- SEC_ACE *ace = &the_acl->ace[i];
- SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
- uint8 new_flags = 0;
- BOOL inherit = False;
- fstring sid_str;
-
- /* The OBJECT_INHERIT_ACE flag causes the ACE to be
- inherited by non-container children objects. Container
- children objects will inherit it as an INHERIT_ONLY
- ACE. */
-
- if (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) {
-
- if (!child_container) {
- new_flags |= SEC_ACE_FLAG_OBJECT_INHERIT;
- } else {
- new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
- }
-
- inherit = True;
- }
-
- /* The CONAINER_INHERIT_ACE flag means all child container
- objects will inherit and use the ACE. */
-
- if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
- if (!child_container) {
- inherit = False;
- } else {
- new_flags |= SEC_ACE_FLAG_CONTAINER_INHERIT;
- }
- }
-
- /* The INHERIT_ONLY_ACE is not used by the se_access_check()
- function for the parent container, but is inherited by
- all child objects as a normal ACE. */
-
- if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
- /* Move along, nothing to see here */
- }
-
- /* The SEC_ACE_FLAG_NO_PROPAGATE_INHERIT flag means the ACE
- is inherited by child objects but not grandchildren
- objects. We clear the object inherit and container
- inherit flags in the inherited ACE. */
-
- if (ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
- new_flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT |
- SEC_ACE_FLAG_CONTAINER_INHERIT);
- }
-
- /* Add ACE to ACE list */
-
- if (!inherit)
- continue;
-
- init_sec_access(&new_ace->info, ace->info.mask);
- init_sec_ace(new_ace, &ace->trustee, ace->type,
- new_ace->info, new_flags);
-
- sid_to_string(sid_str, &ace->trustee);
-
- DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
- " inherited as %s:%d/0x%02x/0x%08x\n", sid_str,
- ace->type, ace->flags, ace->info.mask,
- sid_str, new_ace->type, new_ace->flags,
- new_ace->info.mask));
-
- new_ace_list_ndx++;
- }
-
- /* Create child security descriptor to return */
-
- new_dacl = make_sec_acl(ctx, ACL_REVISION, new_ace_list_ndx, new_ace_list);
-
- /* Use the existing user and group sids. I don't think this is
- correct. Perhaps the user and group should be passed in as
- parameters by the caller? */
-
- sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
- parent_ctr->owner_sid,
- parent_ctr->grp_sid,
- parent_ctr->sacl,
- new_dacl, &size);
-
- sdb = make_sec_desc_buf(ctx, size, sd);
-
- return sdb;
-}
/*******************************************************************
samr_make_sam_obj_sd
diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c
index fbb393770d..50bbb4c72c 100644
--- a/source3/lib/util_sid.c
+++ b/source3/lib/util_sid.c
@@ -638,7 +638,7 @@ void print_guid(GUID *guid)
Tallocs a duplicate SID.
********************************************************************/
-DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, DOM_SID *src)
+DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src)
{
DOM_SID *dst;