setcifsacl - fix adding ACE when owner sid in unexpected location
diff mbox series

Message ID CAH2r5mufwdyGa0vs2=7cNDLbUXz3nVNvnQfcUOTbm7+6GPnNmQ@mail.gmail.com
State New
Headers show
Series
  • setcifsacl - fix adding ACE when owner sid in unexpected location
Related show

Commit Message

Steve French March 2, 2019, 5:13 a.m. UTC
Patch to fix setcifsacl when owner/group owner are at end instead of
beginning. Seems to work (see below).

$ setcifsacl -a "ACL:Administrator:ALLOWED/0x0/FULL" /mnt/file1
main: setxattr error: Invalid argument
$ getcifsacl /mnt/file1
REVISION:0x1
CONTROL:0x8404
OWNER:NT Authority\SYSTEM
GROUP:NT Authority\SYSTEM
ACL:NT Authority\SYSTEM:ALLOWED/I/FULL
ACL:BUILTIN\Administrators:ALLOWED/I/FULL
ACL:S-1-5-21-859164523-2028333235-149708467-500:ALLOWED/I/FULL
$ ./setcifsacl -a "ACL:Administrator:ALLOWED/0x0/FULL" /mnt/file1
$ getcifsacl /mnt/file1
REVISION:0x1
CONTROL:0x8004
OWNER:NT Authority\SYSTEM
GROUP:NT Authority\SYSTEM
ACL:NT Authority\SYSTEM:ALLOWED/I/FULL
ACL:BUILTIN\Administrators:ALLOWED/I/FULL
ACL:S-1-5-21-859164523-2028333235-149708467-500:ALLOWED/I/FULL
ACL:\administrator:ALLOWED/0x0/FULL

Comments

Pavel Shilovsky March 9, 2019, 12:38 a.m. UTC | #1
пт, 1 мар. 2019 г. в 21:14, Steve French <smfrench@gmail.com>:
>
> Patch to fix setcifsacl when owner/group owner are at end instead of
> beginning. Seems to work (see below).
>
> $ setcifsacl -a "ACL:Administrator:ALLOWED/0x0/FULL" /mnt/file1
> main: setxattr error: Invalid argument
> $ getcifsacl /mnt/file1
> REVISION:0x1
> CONTROL:0x8404
> OWNER:NT Authority\SYSTEM
> GROUP:NT Authority\SYSTEM
> ACL:NT Authority\SYSTEM:ALLOWED/I/FULL
> ACL:BUILTIN\Administrators:ALLOWED/I/FULL
> ACL:S-1-5-21-859164523-2028333235-149708467-500:ALLOWED/I/FULL
> $ ./setcifsacl -a "ACL:Administrator:ALLOWED/0x0/FULL" /mnt/file1
> $ getcifsacl /mnt/file1
> REVISION:0x1
> CONTROL:0x8004
> OWNER:NT Authority\SYSTEM
> GROUP:NT Authority\SYSTEM
> ACL:NT Authority\SYSTEM:ALLOWED/I/FULL
> ACL:BUILTIN\Administrators:ALLOWED/I/FULL
> ACL:S-1-5-21-859164523-2028333235-149708467-500:ALLOWED/I/FULL
> ACL:\administrator:ALLOWED/0x0/FULL


merged, thanks.
--
Best regards,
Pavel Shilovsky

Patch
diff mbox series

From 74314f24af13d708f39d68ca0a800301ce33d17a Mon Sep 17 00:00:00 2001
From: Steve French <stfrench@microsoft.com>
Date: Fri, 1 Mar 2019 23:11:25 -0600
Subject: [PATCH] setcifsacl: fix problem in setting ACL when server returns
 owner information at end instead of beginning

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>
---
 setcifsacl.c | 29 ++++++++++++++++++++++++-----
 1 file 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;
 
-- 
2.17.1