summaryrefslogtreecommitdiff
path: root/setcifsacl.c
diff options
context:
space:
mode:
Diffstat (limited to 'setcifsacl.c')
-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;