diff options
-rw-r--r-- | fs/cifs/Kconfig | 7 | ||||
-rw-r--r-- | fs/cifs/cifsacl.c | 2 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 2 | ||||
-rw-r--r-- | fs/cifs/xattr.c | 55 |
4 files changed, 40 insertions, 26 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig index 3bdbfb026b6b..ee45648b0d1a 100644 --- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig | |||
@@ -144,6 +144,13 @@ config CIFS_FSCACHE | |||
144 | to be cached locally on disk through the general filesystem cache | 144 | to be cached locally on disk through the general filesystem cache |
145 | manager. If unsure, say N. | 145 | manager. If unsure, say N. |
146 | 146 | ||
147 | config CIFS_ACL | ||
148 | bool "Provide CIFS ACL support (EXPERIMENTAL)" | ||
149 | depends on EXPERIMENTAL && CIFS_XATTR | ||
150 | help | ||
151 | Allows to fetch CIFS/NTFS ACL from the server. The DACL blob | ||
152 | is handed over to the application/caller. | ||
153 | |||
147 | config CIFS_EXPERIMENTAL | 154 | config CIFS_EXPERIMENTAL |
148 | bool "CIFS Experimental Features (EXPERIMENTAL)" | 155 | bool "CIFS Experimental Features (EXPERIMENTAL)" |
149 | depends on CIFS && EXPERIMENTAL | 156 | depends on CIFS && EXPERIMENTAL |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index c15e3ee730c6..c6ebea088ac7 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -608,7 +608,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, | |||
608 | } | 608 | } |
609 | 609 | ||
610 | /* Retrieve an ACL from the server */ | 610 | /* Retrieve an ACL from the server */ |
611 | static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, | 611 | struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, |
612 | struct inode *inode, const char *path, | 612 | struct inode *inode, const char *path, |
613 | u32 *pacllen) | 613 | u32 *pacllen) |
614 | { | 614 | { |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index b498731852d4..db961dc4fd3d 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -134,6 +134,8 @@ extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, | |||
134 | struct cifs_fattr *fattr, struct inode *inode, | 134 | struct cifs_fattr *fattr, struct inode *inode, |
135 | const char *path, const __u16 *pfid); | 135 | const char *path, const __u16 *pfid); |
136 | extern int mode_to_cifs_acl(struct inode *inode, const char *path, __u64); | 136 | extern int mode_to_cifs_acl(struct inode *inode, const char *path, __u64); |
137 | extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, | ||
138 | const char *, u32 *); | ||
137 | 139 | ||
138 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, | 140 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, |
139 | const char *); | 141 | const char *); |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index a264b744bb41..eae2a1491608 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
@@ -30,10 +30,11 @@ | |||
30 | 30 | ||
31 | #define MAX_EA_VALUE_SIZE 65535 | 31 | #define MAX_EA_VALUE_SIZE 65535 |
32 | #define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib" | 32 | #define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib" |
33 | #define CIFS_XATTR_CIFS_ACL "system.cifs_acl" | ||
33 | #define CIFS_XATTR_USER_PREFIX "user." | 34 | #define CIFS_XATTR_USER_PREFIX "user." |
34 | #define CIFS_XATTR_SYSTEM_PREFIX "system." | 35 | #define CIFS_XATTR_SYSTEM_PREFIX "system." |
35 | #define CIFS_XATTR_OS2_PREFIX "os2." | 36 | #define CIFS_XATTR_OS2_PREFIX "os2." |
36 | #define CIFS_XATTR_SECURITY_PREFIX ".security" | 37 | #define CIFS_XATTR_SECURITY_PREFIX "security." |
37 | #define CIFS_XATTR_TRUSTED_PREFIX "trusted." | 38 | #define CIFS_XATTR_TRUSTED_PREFIX "trusted." |
38 | #define XATTR_TRUSTED_PREFIX_LEN 8 | 39 | #define XATTR_TRUSTED_PREFIX_LEN 8 |
39 | #define XATTR_SECURITY_PREFIX_LEN 9 | 40 | #define XATTR_SECURITY_PREFIX_LEN 9 |
@@ -277,29 +278,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
277 | cifs_sb->local_nls, | 278 | cifs_sb->local_nls, |
278 | cifs_sb->mnt_cifs_flags & | 279 | cifs_sb->mnt_cifs_flags & |
279 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 280 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
280 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
281 | else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | ||
282 | __u16 fid; | ||
283 | int oplock = 0; | ||
284 | struct cifs_ntsd *pacl = NULL; | ||
285 | __u32 buflen = 0; | ||
286 | if (experimEnabled) | ||
287 | rc = CIFSSMBOpen(xid, pTcon, full_path, | ||
288 | FILE_OPEN, GENERIC_READ, 0, &fid, | ||
289 | &oplock, NULL, cifs_sb->local_nls, | ||
290 | cifs_sb->mnt_cifs_flags & | ||
291 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
292 | /* else rc is EOPNOTSUPP from above */ | ||
293 | |||
294 | if (rc == 0) { | ||
295 | rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &pacl, | ||
296 | &buflen); | ||
297 | CIFSSMBClose(xid, pTcon, fid); | ||
298 | } | ||
299 | } | ||
300 | #endif /* EXPERIMENTAL */ | ||
301 | #else | 281 | #else |
302 | cFYI(1, "query POSIX ACL not supported yet"); | 282 | cFYI(1, "Query POSIX ACL not supported yet"); |
303 | #endif /* CONFIG_CIFS_POSIX */ | 283 | #endif /* CONFIG_CIFS_POSIX */ |
304 | } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT, | 284 | } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT, |
305 | strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { | 285 | strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { |
@@ -311,8 +291,33 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
311 | cifs_sb->mnt_cifs_flags & | 291 | cifs_sb->mnt_cifs_flags & |
312 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 292 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
313 | #else | 293 | #else |
314 | cFYI(1, "query POSIX default ACL not supported yet"); | 294 | cFYI(1, "Query POSIX default ACL not supported yet"); |
315 | #endif | 295 | #endif /* CONFIG_CIFS_POSIX */ |
296 | } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL, | ||
297 | strlen(CIFS_XATTR_CIFS_ACL)) == 0) { | ||
298 | #ifdef CONFIG_CIFS_ACL | ||
299 | u32 acllen; | ||
300 | struct cifs_ntsd *pacl; | ||
301 | |||
302 | pacl = get_cifs_acl(cifs_sb, direntry->d_inode, | ||
303 | full_path, &acllen); | ||
304 | if (IS_ERR(pacl)) { | ||
305 | rc = PTR_ERR(pacl); | ||
306 | cERROR(1, "%s: error %zd getting sec desc", | ||
307 | __func__, rc); | ||
308 | } else { | ||
309 | if (ea_value) { | ||
310 | if (acllen > buf_size) | ||
311 | acllen = -ERANGE; | ||
312 | else | ||
313 | memcpy(ea_value, pacl, acllen); | ||
314 | } | ||
315 | rc = acllen; | ||
316 | kfree(pacl); | ||
317 | } | ||
318 | #else | ||
319 | cFYI(1, "Query CIFS ACL not supported yet"); | ||
320 | #endif /* CONFIG_CIFS_ACL */ | ||
316 | } else if (strncmp(ea_name, | 321 | } else if (strncmp(ea_name, |
317 | CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) { | 322 | CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) { |
318 | cFYI(1, "Trusted xattr namespace not supported yet"); | 323 | cFYI(1, "Trusted xattr namespace not supported yet"); |