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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
return NULL;
}
- nacl->aces = talloc_memdup (nacl, oacl->aces, sizeof(struct security_ace) * oacl->num_aces);
+ nacl->aces = (struct security_ace *)talloc_memdup (nacl, oacl->aces, sizeof(struct security_ace) * oacl->num_aces);
if ((nacl->aces == NULL) && (oacl->num_aces > 0)) {
goto failed;
}
- /* remapping array in trustee dom_sid from old acl to new acl */
-
- for (i = 0; i < oacl->num_aces; i++) {
- nacl->aces[i].trustee.sub_auths =
- talloc_memdup(nacl->aces, nacl->aces[i].trustee.sub_auths,
- sizeof(uint32_t) * nacl->aces[i].trustee.num_auths);
-
- if ((nacl->aces[i].trustee.sub_auths == NULL) && (nacl->aces[i].trustee.num_auths > 0)) {
- goto failed;
- }
- }
-
nacl->revision = oacl->revision;
nacl->size = oacl->size;
nacl->num_aces = oacl->num_aces;
}
}
+ nsd->revision = osd->revision;
+ nsd->type = osd->type;
+
return nsd;
failed:
}
/*
- add an ACE to the DACL of a security_descriptor
+ add an ACE to an ACL of a security_descriptor
*/
-NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd,
- const struct security_ace *ace)
+
+static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd,
+ bool add_to_sacl,
+ const struct security_ace *ace)
{
- if (sd->dacl == NULL) {
- sd->dacl = talloc(sd, struct security_acl);
- if (sd->dacl == NULL) {
+ struct security_acl *acl = NULL;
+
+ if (add_to_sacl) {
+ acl = sd->sacl;
+ } else {
+ acl = sd->dacl;
+ }
+
+ if (acl == NULL) {
+ acl = talloc(sd, struct security_acl);
+ if (acl == NULL) {
return NT_STATUS_NO_MEMORY;
}
- sd->dacl->revision = SECURITY_ACL_REVISION_NT4;
- sd->dacl->size = 0;
- sd->dacl->num_aces = 0;
- sd->dacl->aces = NULL;
+ acl->revision = SECURITY_ACL_REVISION_NT4;
+ acl->size = 0;
+ acl->num_aces = 0;
+ acl->aces = NULL;
}
- sd->dacl->aces = talloc_realloc(sd->dacl, sd->dacl->aces,
- struct security_ace, sd->dacl->num_aces+1);
- if (sd->dacl->aces == NULL) {
+ acl->aces = talloc_realloc(acl, acl->aces,
+ struct security_ace, acl->num_aces+1);
+ if (acl->aces == NULL) {
return NT_STATUS_NO_MEMORY;
}
- sd->dacl->aces[sd->dacl->num_aces] = *ace;
- sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths =
- talloc_memdup(sd->dacl->aces,
- sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths,
- sizeof(uint32_t) *
- sd->dacl->aces[sd->dacl->num_aces].trustee.num_auths);
- if (sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
+ acl->aces[acl->num_aces] = *ace;
- switch (sd->dacl->aces[sd->dacl->num_aces].type) {
+ switch (acl->aces[acl->num_aces].type) {
case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
- sd->dacl->revision = SECURITY_ACL_REVISION_ADS;
+ acl->revision = SECURITY_ACL_REVISION_ADS;
break;
default:
break;
}
- sd->dacl->num_aces++;
+ acl->num_aces++;
- sd->type |= SEC_DESC_DACL_PRESENT;
+ if (add_to_sacl) {
+ sd->sacl = acl;
+ sd->type |= SEC_DESC_SACL_PRESENT;
+ } else {
+ sd->dacl = acl;
+ sd->type |= SEC_DESC_DACL_PRESENT;
+ }
return NT_STATUS_OK;
}
+/*
+ add an ACE to the SACL of a security_descriptor
+*/
+
+NTSTATUS security_descriptor_sacl_add(struct security_descriptor *sd,
+ const struct security_ace *ace)
+{
+ return security_descriptor_acl_add(sd, true, ace);
+}
+
+/*
+ add an ACE to the DACL of a security_descriptor
+*/
+
+NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd,
+ const struct security_ace *ace)
+{
+ return security_descriptor_acl_add(sd, false, ace);
+}
/*
- delete the ACE corresponding to the given trustee in the DACL of a security_descriptor
+ delete the ACE corresponding to the given trustee in an ACL of a
+ security_descriptor
*/
-NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd,
- struct dom_sid *trustee)
+
+static NTSTATUS security_descriptor_acl_del(struct security_descriptor *sd,
+ bool sacl_del,
+ const struct dom_sid *trustee)
{
int i;
bool found = false;
+ struct security_acl *acl = NULL;
- if (sd->dacl == NULL) {
+ if (sacl_del) {
+ acl = sd->sacl;
+ } else {
+ acl = sd->dacl;
+ }
+
+ if (acl == NULL) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
/* there can be multiple ace's for one trustee */
- for (i=0;i<sd->dacl->num_aces;i++) {
- if (dom_sid_equal(trustee, &sd->dacl->aces[i].trustee)) {
- memmove(&sd->dacl->aces[i], &sd->dacl->aces[i+1],
- sizeof(sd->dacl->aces[i]) * (sd->dacl->num_aces - (i+1)));
- sd->dacl->num_aces--;
- if (sd->dacl->num_aces == 0) {
- sd->dacl->aces = NULL;
+ for (i=0;i<acl->num_aces;i++) {
+ if (dom_sid_equal(trustee, &acl->aces[i].trustee)) {
+ memmove(&acl->aces[i], &acl->aces[i+1],
+ sizeof(acl->aces[i]) * (acl->num_aces - (i+1)));
+ acl->num_aces--;
+ if (acl->num_aces == 0) {
+ acl->aces = NULL;
}
found = true;
}
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- sd->dacl->revision = SECURITY_ACL_REVISION_NT4;
+ acl->revision = SECURITY_ACL_REVISION_NT4;
- for (i=0;i<sd->dacl->num_aces;i++) {
- switch (sd->dacl->aces[i].type) {
+ for (i=0;i<acl->num_aces;i++) {
+ switch (acl->aces[i].type) {
case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
- sd->dacl->revision = SECURITY_ACL_REVISION_ADS;
+ acl->revision = SECURITY_ACL_REVISION_ADS;
return NT_STATUS_OK;
default:
break; /* only for the switch statement */
return NT_STATUS_OK;
}
+/*
+ delete the ACE corresponding to the given trustee in the DACL of a
+ security_descriptor
+*/
+
+NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd,
+ const struct dom_sid *trustee)
+{
+ return security_descriptor_acl_del(sd, false, trustee);
+}
+
+/*
+ delete the ACE corresponding to the given trustee in the SACL of a
+ security_descriptor
+*/
+
+NTSTATUS security_descriptor_sacl_del(struct security_descriptor *sd,
+ const struct dom_sid *trustee)
+{
+ return security_descriptor_acl_del(sd, true, trustee);
+}
/*
compare two security ace structures
*/
-BOOL security_ace_equal(const struct security_ace *ace1,
+bool security_ace_equal(const struct security_ace *ace1,
const struct security_ace *ace2)
{
- if (ace1 == ace2) return True;
- if (!ace1 || !ace2) return False;
- if (ace1->type != ace2->type) return False;
- if (ace1->flags != ace2->flags) return False;
- if (ace1->access_mask != ace2->access_mask) return False;
- if (!dom_sid_equal(&ace1->trustee, &ace2->trustee)) return False;
-
- return True;
+ if (ace1 == ace2) return true;
+ if (!ace1 || !ace2) return false;
+ if (ace1->type != ace2->type) return false;
+ if (ace1->flags != ace2->flags) return false;
+ if (ace1->access_mask != ace2->access_mask) return false;
+ if (!dom_sid_equal(&ace1->trustee, &ace2->trustee)) return false;
+
+ return true;
}
/*
compare two security acl structures
*/
-BOOL security_acl_equal(const struct security_acl *acl1,
+bool security_acl_equal(const struct security_acl *acl1,
const struct security_acl *acl2)
{
int i;
- if (acl1 == acl2) return True;
- if (!acl1 || !acl2) return False;
- if (acl1->revision != acl2->revision) return False;
- if (acl1->num_aces != acl2->num_aces) return False;
+ if (acl1 == acl2) return true;
+ if (!acl1 || !acl2) return false;
+ if (acl1->revision != acl2->revision) return false;
+ if (acl1->num_aces != acl2->num_aces) return false;
for (i=0;i<acl1->num_aces;i++) {
- if (!security_ace_equal(&acl1->aces[i], &acl2->aces[i])) return False;
+ if (!security_ace_equal(&acl1->aces[i], &acl2->aces[i])) return false;
}
- return True;
+ return true;
}
/*
compare two security descriptors.
*/
-BOOL security_descriptor_equal(const struct security_descriptor *sd1,
+bool security_descriptor_equal(const struct security_descriptor *sd1,
const struct security_descriptor *sd2)
{
- if (sd1 == sd2) return True;
- if (!sd1 || !sd2) return False;
- if (sd1->revision != sd2->revision) return False;
- if (sd1->type != sd2->type) return False;
+ if (sd1 == sd2) return true;
+ if (!sd1 || !sd2) return false;
+ if (sd1->revision != sd2->revision) return false;
+ if (sd1->type != sd2->type) return false;
- if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return False;
- if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return False;
- if (!security_acl_equal(sd1->sacl, sd2->sacl)) return False;
- if (!security_acl_equal(sd1->dacl, sd2->dacl)) return False;
+ if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return false;
+ if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return false;
+ if (!security_acl_equal(sd1->sacl, sd2->sacl)) return false;
+ if (!security_acl_equal(sd1->dacl, sd2->dacl)) return false;
- return True;
+ return true;
}
/*
compare two security descriptors, but allow certain (missing) parts
to be masked out of the comparison
*/
-BOOL security_descriptor_mask_equal(const struct security_descriptor *sd1,
+bool security_descriptor_mask_equal(const struct security_descriptor *sd1,
const struct security_descriptor *sd2,
uint32_t mask)
{
- if (sd1 == sd2) return True;
- if (!sd1 || !sd2) return False;
- if (sd1->revision != sd2->revision) return False;
- if ((sd1->type & mask) != (sd2->type & mask)) return False;
+ if (sd1 == sd2) return true;
+ if (!sd1 || !sd2) return false;
+ if (sd1->revision != sd2->revision) return false;
+ if ((sd1->type & mask) != (sd2->type & mask)) return false;
- if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return False;
- if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return False;
- if ((mask & SEC_DESC_DACL_PRESENT) && !security_acl_equal(sd1->dacl, sd2->dacl)) return False;
- if ((mask & SEC_DESC_SACL_PRESENT) && !security_acl_equal(sd1->sacl, sd2->sacl)) return False;
+ if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return false;
+ if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return false;
+ if ((mask & SEC_DESC_DACL_PRESENT) && !security_acl_equal(sd1->dacl, sd2->dacl)) return false;
+ if ((mask & SEC_DESC_SACL_PRESENT) && !security_acl_equal(sd1->sacl, sd2->sacl)) return false;
- return True;
+ return true;
}
-/*
- create a security descriptor using string SIDs. This is used by the
- torture code to allow the easy creation of complex ACLs
- This is a varargs function. The list of DACL ACEs ends with a NULL sid.
-
- Each ACE contains a set of 4 parameters:
- SID, ACCESS_TYPE, MASK, FLAGS
-
- a typical call would be:
-
- sd = security_descriptor_create(mem_ctx,
- mysid,
- mygroup,
- SID_NT_AUTHENTICATED_USERS,
- SEC_ACE_TYPE_ACCESS_ALLOWED,
- SEC_FILE_ALL,
- SEC_ACE_FLAG_OBJECT_INHERIT,
- NULL);
- that would create a sd with one DACL ACE
-*/
-struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx,
- const char *owner_sid,
- const char *group_sid,
- ...)
+static struct security_descriptor *security_descriptor_appendv(struct security_descriptor *sd,
+ bool add_ace_to_sacl,
+ va_list ap)
{
- va_list ap;
- struct security_descriptor *sd;
const char *sidstr;
- sd = security_descriptor_initialise(mem_ctx);
- if (sd == NULL) return NULL;
-
- if (owner_sid) {
- sd->owner_sid = dom_sid_parse_talloc(sd, owner_sid);
- if (sd->owner_sid == NULL) {
- talloc_free(sd);
- return NULL;
- }
- }
- if (group_sid) {
- sd->group_sid = dom_sid_parse_talloc(sd, group_sid);
- if (sd->group_sid == NULL) {
- talloc_free(sd);
- return NULL;
- }
- }
-
- va_start(ap, group_sid);
while ((sidstr = va_arg(ap, const char *))) {
struct dom_sid *sid;
struct security_ace *ace = talloc(sd, struct security_ace);
if (ace == NULL) {
talloc_free(sd);
- va_end(ap);
return NULL;
}
ace->type = va_arg(ap, unsigned int);
ace->flags = va_arg(ap, unsigned int);
sid = dom_sid_parse_talloc(ace, sidstr);
if (sid == NULL) {
- va_end(ap);
talloc_free(sd);
return NULL;
}
ace->trustee = *sid;
- status = security_descriptor_dacl_add(sd, ace);
+ if (add_ace_to_sacl) {
+ status = security_descriptor_sacl_add(sd, ace);
+ } else {
+ status = security_descriptor_dacl_add(sd, ace);
+ }
/* TODO: check: would talloc_free(ace) here be correct? */
if (!NT_STATUS_IS_OK(status)) {
- va_end(ap);
talloc_free(sd);
return NULL;
}
}
+
+ return sd;
+}
+
+struct security_descriptor *security_descriptor_append(struct security_descriptor *sd,
+ ...)
+{
+ va_list ap;
+
+ va_start(ap, sd);
+ sd = security_descriptor_appendv(sd, false, ap);
+ va_end(ap);
+
+ return sd;
+}
+
+static struct security_descriptor *security_descriptor_createv(TALLOC_CTX *mem_ctx,
+ uint16_t sd_type,
+ const char *owner_sid,
+ const char *group_sid,
+ bool add_ace_to_sacl,
+ va_list ap)
+{
+ struct security_descriptor *sd;
+
+ sd = security_descriptor_initialise(mem_ctx);
+ if (sd == NULL) {
+ return NULL;
+ }
+
+ sd->type |= sd_type;
+
+ if (owner_sid) {
+ sd->owner_sid = dom_sid_parse_talloc(sd, owner_sid);
+ if (sd->owner_sid == NULL) {
+ talloc_free(sd);
+ return NULL;
+ }
+ }
+ if (group_sid) {
+ sd->group_sid = dom_sid_parse_talloc(sd, group_sid);
+ if (sd->group_sid == NULL) {
+ talloc_free(sd);
+ return NULL;
+ }
+ }
+
+ return security_descriptor_appendv(sd, add_ace_to_sacl, ap);
+}
+
+/*
+ create a security descriptor using string SIDs. This is used by the
+ torture code to allow the easy creation of complex ACLs
+ This is a varargs function. The list of DACL ACEs ends with a NULL sid.
+
+ Each ACE contains a set of 4 parameters:
+ SID, ACCESS_TYPE, MASK, FLAGS
+
+ a typical call would be:
+
+ sd = security_descriptor_dacl_create(mem_ctx,
+ sd_type_flags,
+ mysid,
+ mygroup,
+ SID_NT_AUTHENTICATED_USERS,
+ SEC_ACE_TYPE_ACCESS_ALLOWED,
+ SEC_FILE_ALL,
+ SEC_ACE_FLAG_OBJECT_INHERIT,
+ NULL);
+ that would create a sd with one DACL ACE
+*/
+
+struct security_descriptor *security_descriptor_dacl_create(TALLOC_CTX *mem_ctx,
+ uint16_t sd_type,
+ const char *owner_sid,
+ const char *group_sid,
+ ...)
+{
+ struct security_descriptor *sd = NULL;
+ va_list ap;
+ va_start(ap, group_sid);
+ sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid,
+ group_sid, false, ap);
+ va_end(ap);
+
+ return sd;
+}
+
+struct security_descriptor *security_descriptor_sacl_create(TALLOC_CTX *mem_ctx,
+ uint16_t sd_type,
+ const char *owner_sid,
+ const char *group_sid,
+ ...)
+{
+ struct security_descriptor *sd = NULL;
+ va_list ap;
+ va_start(ap, group_sid);
+ sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid,
+ group_sid, true, ap);
va_end(ap);
return sd;
}
+
+struct security_ace *security_ace_create(TALLOC_CTX *mem_ctx,
+ const char *sid_str,
+ enum security_ace_type type,
+ uint32_t access_mask,
+ uint8_t flags)
+
+{
+ struct dom_sid *sid;
+ struct security_ace *ace;
+
+ ace = talloc_zero(mem_ctx, struct security_ace);
+ if (ace == NULL) {
+ return NULL;
+ }
+
+ sid = dom_sid_parse_talloc(ace, sid_str);
+ if (sid == NULL) {
+ talloc_free(ace);
+ return NULL;
+ }
+
+ ace->trustee = *sid;
+ ace->type = type;
+ ace->access_mask = access_mask;
+ ace->flags = flags;
+
+ return ace;
+}