summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve French <stfrench@microsoft.com>2019-03-01 23:11:25 -0600
committerPavel Shilovsky <pshilov@microsoft.com>2019-03-08 16:29:41 -0800
commit0feb1a80f3777f4c244b46958aa9f730de9e18b6 (patch)
tree02e8f8ff0b03c0391e2c3d3f5ae595819b0bcb6e
parent1191a6cafde1f6e39546cab26a5b90c3cca523fd (diff)
downloadcifs-utils-0feb1a80f3777f4c244b46958aa9f730de9e18b6.tar.gz
cifs-utils-0feb1a80f3777f4c244b46958aa9f730de9e18b6.tar.bz2
cifs-utils-0feb1a80f3777f4c244b46958aa9f730de9e18b6.zip
setcifsacl: fix adding ACE when owner sid in unexpected location
If owner information is after the ACEs instead of before (e.g. Azure servers) in the ACL query then we would get "invalid argument" returned on setcifsacl -a (adding an ACE). This fixes that. Signed-off-by: Steve French <stfrench@microsoft.com>
-rw-r--r--setcifsacl.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/setcifsacl.c b/setcifsacl.c
index ba34403..1b98c37 100644
--- a/setcifsacl.c
+++ b/setcifsacl.c
@@ -106,13 +106,32 @@ copy_sec_desc(const struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
/* copy owner sid */
owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + osidsoffset);
- nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + osidsoffset);
- size = copy_cifs_sid(nowner_sid_ptr, owner_sid_ptr);
- bufsize += size;
+ group_sid_ptr = (struct cifs_sid *)((char *)pntsd + gsidsoffset);
+ /*
+ * some servers like Azure return the owner and group SIDs at end rather
+ * than at the beginning of the ACL so don't want to overwrite the last ACEs
+ */
+ if (dacloffset <= osidsoffset) {
+ /* owners placed at end of ACL */
+ nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + dacloffset + size);
+ pnntsd->osidoffset = dacloffset + size;
+ size = copy_cifs_sid(nowner_sid_ptr, owner_sid_ptr);
+ bufsize += size;
+ /* put group SID after owner SID */
+ ngroup_sid_ptr = (struct cifs_sid *)((char *)nowner_sid_ptr + size);
+ pnntsd->gsidoffset = pnntsd->osidoffset + size;
+ } else {
+ /*
+ * Most servers put the owner information at the beginning,
+ * before the ACL
+ */
+ nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + osidsoffset);
+ size = copy_cifs_sid(nowner_sid_ptr, owner_sid_ptr);
+ bufsize += size;
+ ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + gsidsoffset);
+ }
/* copy group sid */
- group_sid_ptr = (struct cifs_sid *)((char *)pntsd + gsidsoffset);
- ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + gsidsoffset);
size = copy_cifs_sid(ngroup_sid_ptr, group_sid_ptr);
bufsize += size;