diff options
-rw-r--r-- | setcifsacl.c | 129 | ||||
-rw-r--r-- | setcifsacl.rst.in | 20 |
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 ============= |