summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--setcifsacl.c129
-rw-r--r--setcifsacl.rst.in20
2 files changed, 145 insertions, 4 deletions
diff --git a/setcifsacl.c b/setcifsacl.c
index db9cf2c..0c49e06 100644
--- a/setcifsacl.c
+++ b/setcifsacl.c
@@ -61,7 +61,8 @@ enum setcifsacl_actions {
ActSetAcl,
ActSetOwner,
ActSetGroup,
- ActSetSacl
+ ActSetSacl,
+ ActAddReorder
};
static void *plugin_handle;
@@ -483,6 +484,87 @@ alloc_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd **npntsd,
return 0;
}
+static struct cifs_ace **
+build_reorder_aces(struct cifs_ace **facesptr, int numfaces)
+{
+ struct cifs_ace *pace, **allowedacesptr, **deniedacesptr,
+ **allowedinhacesptr, **deniedinhacesptr, **reorderacesptr;
+ int i, numallowedaces, numdeniedaces,
+ numallowedinhaces, numdeniedinhaces, numreorderaces;
+
+ allowedacesptr = calloc(numfaces, sizeof(struct cifs_aces *));
+ deniedacesptr = calloc(numfaces, sizeof(struct cifs_aces *));
+ allowedinhacesptr = calloc(numfaces, sizeof(struct cifs_aces *));
+ deniedinhacesptr = calloc(numfaces, sizeof(struct cifs_aces *));
+ reorderacesptr = calloc(numfaces, sizeof(struct cifs_aces *));
+
+ numallowedaces = 0;
+ numdeniedaces = 0;
+ numallowedinhaces = 0;
+ numdeniedinhaces = 0;
+ numreorderaces = 0;
+
+ for (i = 0; i < numfaces; i++) {
+ pace = facesptr[i];
+ if ((pace->type == ACCESS_DENIED) || (pace->type == ACCESS_DENIED_OBJECT)) {
+ if (!(pace->flags & INHERITED_ACE_FLAG)) {
+ deniedacesptr[numdeniedaces] = malloc(sizeof(struct cifs_ace));
+ memcpy(deniedacesptr[numdeniedaces], pace, sizeof(struct cifs_ace));
+ numdeniedaces++;
+ } else {
+ deniedinhacesptr[numdeniedinhaces] = malloc(sizeof(struct cifs_ace));
+ memcpy(deniedinhacesptr[numdeniedinhaces], pace, sizeof(struct cifs_ace));
+ numdeniedinhaces++;
+ }
+ } else if ((pace->type == ACCESS_ALLOWED) || (pace->type == ACCESS_ALLOWED_OBJECT)) {
+ if (!(pace->flags & INHERITED_ACE_FLAG)) {
+ allowedacesptr[numallowedaces] = malloc(sizeof(struct cifs_ace));
+ memcpy(allowedacesptr[numallowedaces], pace, sizeof(struct cifs_ace));
+ numallowedaces++;
+ } else {
+ allowedinhacesptr[numallowedinhaces] = malloc(sizeof(struct cifs_ace));
+ memcpy(allowedinhacesptr[numallowedinhaces], pace, sizeof(struct cifs_ace));
+ numallowedinhaces++;
+ }
+ }
+ }
+
+ for (i = 0; i < numdeniedaces; i++) {
+ reorderacesptr[numreorderaces] = malloc(sizeof(struct cifs_ace));
+ memcpy(reorderacesptr[numreorderaces], deniedacesptr[i], sizeof(struct cifs_ace));
+ numreorderaces++;
+ free(deniedacesptr[i]);
+ }
+
+ for (i = 0; i < numallowedaces; i++) {
+ reorderacesptr[numreorderaces] = malloc(sizeof(struct cifs_ace));
+ memcpy(reorderacesptr[numreorderaces], allowedacesptr[i], sizeof(struct cifs_ace));
+ numreorderaces++;
+ free(allowedacesptr[i]);
+ }
+
+ for (i = 0; i < numdeniedinhaces; i++) {
+ reorderacesptr[numreorderaces] = malloc(sizeof(struct cifs_ace));
+ memcpy(reorderacesptr[numreorderaces], deniedinhacesptr[i], sizeof(struct cifs_ace));
+ numreorderaces++;
+ free(deniedinhacesptr[i]);
+ }
+
+ for (i = 0; i < numallowedinhaces; i++) {
+ reorderacesptr[numreorderaces] = malloc(sizeof(struct cifs_ace));
+ memcpy(reorderacesptr[numreorderaces], allowedinhacesptr[i], sizeof(struct cifs_ace));
+ numreorderaces++;
+ free(allowedinhacesptr[i]);
+ }
+
+ free(deniedacesptr);
+ free(allowedacesptr);
+ free(deniedinhacesptr);
+ free(allowedinhacesptr);
+
+ return reorderacesptr;
+}
+
static int
ace_set(struct cifs_ntsd *pntsd, struct cifs_ntsd **npntsd, ssize_t *bufsize,
struct cifs_ace **cacesptr, int numcaces, ace_kinds ace_kind)
@@ -540,6 +622,35 @@ ace_add(struct cifs_ntsd *pntsd, struct cifs_ntsd **npntsd, ssize_t *bufsize,
}
static int
+ace_add_reorder(struct cifs_ntsd *pntsd, struct cifs_ntsd **npntsd, ssize_t *bufsize,
+ struct cifs_ace **facesptr, int numfaces,
+ struct cifs_ace **cacesptr, int numcaces,
+ ace_kinds ace_kind)
+{
+ struct cifs_ace **reorderacesptr, **totalacesptr;
+ int i, rc, numaces;
+
+ numaces = numfaces + numcaces;
+ totalacesptr = calloc(numaces, sizeof(struct cifs_aces *));
+
+ for (i = 0; i < numfaces; i++) {
+ totalacesptr[i] = facesptr[i];
+ }
+
+ for (i = numfaces; i < numaces; i++) {
+ totalacesptr[i] = cacesptr[i - numfaces];
+ }
+
+ reorderacesptr = build_reorder_aces(totalacesptr, numaces);
+ rc = ace_add(pntsd, npntsd, bufsize, reorderacesptr,
+ numaces, cacesptr, 0, ace_kind);
+
+ free(totalacesptr);
+ free(reorderacesptr);
+ return rc;
+}
+
+static int
ace_modify(struct cifs_ntsd *pntsd, struct cifs_ntsd **npntsd, ssize_t *bufsize,
struct cifs_ace **facesptr, int numfaces,
struct cifs_ace **cacesptr, int numcaces,
@@ -1140,6 +1251,10 @@ setacl_action(struct cifs_ntsd *pntsd, struct cifs_ntsd **npntsd,
rc = ace_set(pntsd, npntsd, bufsize, cacesptr, numcaces,
ace_kind);
break;
+ case ActAddReorder:
+ rc = ace_add_reorder(pntsd, npntsd, bufsize, facesptr,
+ numfaces, cacesptr, numcaces, ace_kind);
+ break;
default:
fprintf(stderr, "%s: Invalid action: %d\n", __func__, maction);
break;
@@ -1165,6 +1280,10 @@ setcifsacl_usage(const char *prog)
fprintf(stderr,
"\tsetcifsacl -a \"ACL:Administrator:ALLOWED/0x0/FULL\" <file_name>\n");
fprintf(stderr, "\n");
+ fprintf(stderr, "\t-A Add ACE(s) and reorder, separated by a comma, to an ACL\n");
+ fprintf(stderr,
+ "\tsetcifsacl -A \"ACL:Administrator:ALLOWED/0x0/FULL\" <file_name>\n");
+ fprintf(stderr, "\n");
fprintf(stderr,
"\t-D Delete ACE(s), separated by a comma, from an ACL\n");
fprintf(stderr,
@@ -1204,7 +1323,7 @@ main(const int argc, char *const argv[])
char *attrname = ATTRNAME_ACL;
ace_kinds ace_kind = ACE_KIND_DACL;
- while ((c = getopt(argc, argv, "hvD:M:a:S:o:g:U")) != -1) {
+ while ((c = getopt(argc, argv, "hvD:M:a:A:S:o:g:U")) != -1) {
switch (c) {
case 'U':
ace_kind = ACE_KIND_SACL;
@@ -1222,6 +1341,10 @@ main(const int argc, char *const argv[])
maction = ActAdd;
ace_list = optarg;
break;
+ case 'A':
+ maction = ActAddReorder;
+ ace_list = optarg;
+ break;
case 'S':
maction = ActSetAcl;
ace_list = optarg;
@@ -1374,7 +1497,7 @@ cifsacl:
numfaces = get_numfaces((struct cifs_ntsd *)attrval, attrlen,
&aclptr, ace_kind);
- if (!numfaces && maction != ActAdd) {
+ if (!numfaces && (maction != ActAdd || maction != ActAddReorder)) {
/* if we are not adding aces */
fprintf(stderr, "%s: Empty DACL\n", __func__);
goto setcifsacl_facenum_ret;
diff --git a/setcifsacl.rst.in b/setcifsacl.rst.in
index 51b5973..e7762b8 100644
--- a/setcifsacl.rst.in
+++ b/setcifsacl.rst.in
@@ -11,7 +11,7 @@ Userspace helper to alter components of a security descriptor for Common Interne
SYNOPSIS
********
- setcifsacl [-v|-U|-a|-D|-M|-S|-o|-g] "{one or more ACEs or a SID}" {file system object}
+ setcifsacl [-v|-U|-a|-A|-D|-M|-S|-o|-g] "{one or more ACEs or a SID}" {file system object}
***********
DESCRIPTION
@@ -46,6 +46,12 @@ OPTIONS
Add one or more ACEs to an ACL of a security descriptor. An ACE is
added even if the same ACE exists in the ACL.
+-A
+ Add one or more ACEs to the ACL of a security descriptor, while maintaining
+ the preferred order of the ACEs.
+ The preferred order of ACEs are described in the following documentation:
+ https://docs.microsoft.com/en-us/windows/win32/secauthz/order-of-aces-in-a-dacl
+
-D
Delete one or more ACEs from an ACL of a security descriptor. Entire
ACE has to match in an existing ACL for the listed ACEs to be deleted.
@@ -100,6 +106,18 @@ Add an ACE
setcifsacl -U -a "ACL:CIFSTESTDOM\\user1:AUDIT/SA/D" <file_name>
+Add an ACE and reorder ACL
+==========================
+
+ setcifsacl -A "ACL:CIFSTESTDOM\user3:ALLOWED/OI/FULL" <file_name>
+ setcifsacl -A "ACL:CIFSTESTDOM\user2:DENIED/0x1/D" <file_name>
+ setcifsacl -A "ACL:CIFSTESTDOM\user1:ALLOWED/OI|CI|NI/D" <file_name>
+
+ After setting above mentioned ACEs, below is output of getcifsacl:
+ ACL:CIFSTESTDOM\user2:DENIED/0x1/D
+ ACL:CIFSTESTDOM\user3:ALLOWED/OI/FULL
+ ACL:CIFSTESTDOM\user1:ALLOWED/OI|CI|NI/D
+
Delete an ACE
=============