Commit 8520eeaa authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  cifs: fix parsing of hostname in dfs referrals
  cifs: display fsc in /proc/mounts
  cifs: enable fscache iff fsc mount option is used explicitly
  cifs: allow fsc mount option only if CONFIG_CIFS_FSCACHE is set
  cifs: Handle extended attribute name cifs_acl to generate cifs acl blob (try #4)
  cifs: Misc. cleanup in cifsacl handling [try #4]
  cifs: trivial comment fix for cifs_invalidate_mapping
  [CIFS] fs/cifs/Kconfig: CIFS depends on CRYPTO_HMAC
  cifs: don't take extra tlink reference in initiate_cifs_search
  cifs: Percolate error up to the caller during get/set acls [try #4]
  cifs: fix another memleak, in cifs_root_iget
  cifs: fix potential use-after-free in cifs_oplock_break_put
parents fb82155d ba038648
...@@ -4,6 +4,7 @@ config CIFS ...@@ -4,6 +4,7 @@ config CIFS
select NLS select NLS
select CRYPTO select CRYPTO
select CRYPTO_MD5 select CRYPTO_MD5
select CRYPTO_HMAC
select CRYPTO_ARC4 select CRYPTO_ARC4
help help
This is the client VFS module for the Common Internet File System This is the client VFS module for the Common Internet File System
...@@ -143,6 +144,13 @@ config CIFS_FSCACHE ...@@ -143,6 +144,13 @@ config CIFS_FSCACHE
to be cached locally on disk through the general filesystem cache to be cached locally on disk through the general filesystem cache
manager. If unsure, say N. manager. If unsure, say N.
config CIFS_ACL
bool "Provide CIFS ACL support (EXPERIMENTAL)"
depends on EXPERIMENTAL && CIFS_XATTR
help
Allows to fetch CIFS/NTFS ACL from the server. The DACL blob
is handed over to the application/caller.
config CIFS_EXPERIMENTAL config CIFS_EXPERIMENTAL
bool "CIFS Experimental Features (EXPERIMENTAL)" bool "CIFS Experimental Features (EXPERIMENTAL)"
depends on CIFS && EXPERIMENTAL depends on CIFS && EXPERIMENTAL
......
...@@ -560,7 +560,7 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, ...@@ -560,7 +560,7 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) if (IS_ERR(tlink))
return NULL; return ERR_CAST(tlink);
xid = GetXid(); xid = GetXid();
rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen); rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
...@@ -568,7 +568,9 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, ...@@ -568,7 +568,9 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
cifs_put_tlink(tlink); cifs_put_tlink(tlink);
cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen); cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
if (rc)
return ERR_PTR(rc);
return pntsd; return pntsd;
} }
...@@ -583,7 +585,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, ...@@ -583,7 +585,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) if (IS_ERR(tlink))
return NULL; return ERR_CAST(tlink);
tcon = tlink_tcon(tlink); tcon = tlink_tcon(tlink);
xid = GetXid(); xid = GetXid();
...@@ -591,23 +593,22 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, ...@@ -591,23 +593,22 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0, rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
&fid, &oplock, NULL, cifs_sb->local_nls, &fid, &oplock, NULL, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc) { if (!rc) {
cERROR(1, "Unable to open file to get ACL");
goto out;
}
rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen); rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
CIFSSMBClose(xid, tcon, fid); CIFSSMBClose(xid, tcon, fid);
out: }
cifs_put_tlink(tlink); cifs_put_tlink(tlink);
FreeXid(xid); FreeXid(xid);
cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
if (rc)
return ERR_PTR(rc);
return pntsd; return pntsd;
} }
/* Retrieve an ACL from the server */ /* Retrieve an ACL from the server */
static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
struct inode *inode, const char *path, struct inode *inode, const char *path,
u32 *pacllen) u32 *pacllen)
{ {
...@@ -695,7 +696,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, ...@@ -695,7 +696,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
} }
/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
void int
cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
struct inode *inode, const char *path, const __u16 *pfid) struct inode *inode, const char *path, const __u16 *pfid)
{ {
...@@ -711,17 +712,21 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, ...@@ -711,17 +712,21 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen); pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
if (pntsd) if (IS_ERR(pntsd)) {
rc = PTR_ERR(pntsd);
cERROR(1, "%s: error %d getting sec desc", __func__, rc);
} else {
rc = parse_sec_desc(pntsd, acllen, fattr); rc = parse_sec_desc(pntsd, acllen, fattr);
kfree(pntsd);
if (rc) if (rc)
cFYI(1, "parse sec desc failed rc = %d", rc); cERROR(1, "parse sec desc failed rc = %d", rc);
}
kfree(pntsd); return rc;
return;
} }
/* Convert mode bits to an ACL so we can update the ACL on the server */ /* Convert mode bits to an ACL so we can update the ACL on the server */
int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode)
{ {
int rc = 0; int rc = 0;
__u32 secdesclen = 0; __u32 secdesclen = 0;
...@@ -736,7 +741,10 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) ...@@ -736,7 +741,10 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
/* Add three ACEs for owner, group, everyone getting rid of /* Add three ACEs for owner, group, everyone getting rid of
other ACEs as chmod disables ACEs and set the security descriptor */ other ACEs as chmod disables ACEs and set the security descriptor */
if (pntsd) { if (IS_ERR(pntsd)) {
rc = PTR_ERR(pntsd);
cERROR(1, "%s: error %d getting sec desc", __func__, rc);
} else {
/* allocate memory for the smb header, /* allocate memory for the smb header,
set security descriptor request security descriptor set security descriptor request security descriptor
parameters, and secuirty descriptor itself */ parameters, and secuirty descriptor itself */
......
...@@ -458,6 +458,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) ...@@ -458,6 +458,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
seq_printf(s, ",acl"); seq_printf(s, ",acl");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
seq_printf(s, ",mfsymlinks"); seq_printf(s, ",mfsymlinks");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE)
seq_printf(s, ",fsc");
seq_printf(s, ",rsize=%d", cifs_sb->rsize); seq_printf(s, ",rsize=%d", cifs_sb->rsize);
seq_printf(s, ",wsize=%d", cifs_sb->wsize); seq_printf(s, ",wsize=%d", cifs_sb->wsize);
......
...@@ -130,10 +130,12 @@ extern int cifs_get_file_info_unix(struct file *filp); ...@@ -130,10 +130,12 @@ extern int cifs_get_file_info_unix(struct file *filp);
extern int cifs_get_inode_info_unix(struct inode **pinode, extern int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path, const unsigned char *search_path,
struct super_block *sb, int xid); struct super_block *sb, int xid);
extern void cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
struct cifs_fattr *fattr, struct inode *inode, struct cifs_fattr *fattr, struct inode *inode,
const char *path, const __u16 *pfid); const char *path, const __u16 *pfid);
extern int mode_to_acl(struct inode *inode, const char *path, __u64); extern int mode_to_cifs_acl(struct inode *inode, const char *path, __u64);
extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
const char *, u32 *);
extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
const char *); const char *);
......
...@@ -1352,6 +1352,11 @@ cifs_parse_mount_options(char *options, const char *devname, ...@@ -1352,6 +1352,11 @@ cifs_parse_mount_options(char *options, const char *devname,
"supported. Instead set " "supported. Instead set "
"/proc/fs/cifs/LookupCacheEnabled to 0\n"); "/proc/fs/cifs/LookupCacheEnabled to 0\n");
} else if (strnicmp(data, "fsc", 3) == 0) { } else if (strnicmp(data, "fsc", 3) == 0) {
#ifndef CONFIG_CIFS_FSCACHE
cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE"
"kernel config option set");
return 1;
#endif
vol->fsc = true; vol->fsc = true;
} else if (strnicmp(data, "mfsymlinks", 10) == 0) { } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
vol->mfsymlinks = true; vol->mfsymlinks = true;
......
...@@ -66,7 +66,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) ...@@ -66,7 +66,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
/* Search for server name delimiter */ /* Search for server name delimiter */
sep = memchr(hostname, '\\', len); sep = memchr(hostname, '\\', len);
if (sep) if (sep)
len = sep - unc; len = sep - hostname;
else else
cFYI(1, "%s: probably server name is whole unc: %s", cFYI(1, "%s: probably server name is whole unc: %s",
__func__, unc); __func__, unc);
......
...@@ -2271,8 +2271,10 @@ void cifs_oplock_break_get(struct cifsFileInfo *cfile) ...@@ -2271,8 +2271,10 @@ void cifs_oplock_break_get(struct cifsFileInfo *cfile)
void cifs_oplock_break_put(struct cifsFileInfo *cfile) void cifs_oplock_break_put(struct cifsFileInfo *cfile)
{ {
struct super_block *sb = cfile->dentry->d_sb;
cifsFileInfo_put(cfile); cifsFileInfo_put(cfile);
cifs_sb_deactive(cfile->dentry->d_sb); cifs_sb_deactive(sb);
} }
const struct address_space_operations cifs_addr_ops = { const struct address_space_operations cifs_addr_ops = {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* fs/cifs/fscache.c - CIFS filesystem cache interface * fs/cifs/fscache.c - CIFS filesystem cache interface
* *
* Copyright (c) 2010 Novell, Inc. * Copyright (c) 2010 Novell, Inc.
* Author(s): Suresh Jayaraman (sjayaraman@suse.de> * Author(s): Suresh Jayaraman <sjayaraman@suse.de>
* *
* This library is free software; you can redistribute it and/or modify * This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published * it under the terms of the GNU Lesser General Public License as published
...@@ -67,10 +67,12 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode) ...@@ -67,10 +67,12 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
if (cifsi->fscache) if (cifsi->fscache)
return; return;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) {
cifsi->fscache = fscache_acquire_cookie(tcon->fscache, cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
&cifs_fscache_inode_object_def, cifsi); &cifs_fscache_inode_object_def, cifsi);
cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache, cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache,
cifsi->fscache); cifsi->fscache);
}
} }
void cifs_fscache_release_inode_cookie(struct inode *inode) void cifs_fscache_release_inode_cookie(struct inode *inode)
...@@ -101,10 +103,8 @@ void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp) ...@@ -101,10 +103,8 @@ void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
{ {
if ((filp->f_flags & O_ACCMODE) != O_RDONLY) if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
cifs_fscache_disable_inode_cookie(inode); cifs_fscache_disable_inode_cookie(inode);
else { else
cifs_fscache_enable_inode_cookie(inode); cifs_fscache_enable_inode_cookie(inode);
cFYI(1, "CIFS: fscache inode cookie set");
}
} }
void cifs_fscache_reset_inode_cookie(struct inode *inode) void cifs_fscache_reset_inode_cookie(struct inode *inode)
......
...@@ -689,8 +689,13 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -689,8 +689,13 @@ int cifs_get_inode_info(struct inode **pinode,
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
/* fill in 0777 bits from ACL */ /* fill in 0777 bits from ACL */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
cFYI(1, "Getting mode bits from ACL"); rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid); pfid);
if (rc) {
cFYI(1, "%s: Getting ACL failed with error: %d",
__func__, rc);
goto cgii_exit;
}
} }
#endif #endif
...@@ -881,8 +886,10 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) ...@@ -881,8 +886,10 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
rc = cifs_get_inode_info(&inode, full_path, NULL, sb, rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
xid, NULL); xid, NULL);
if (!inode) if (!inode) {
return ERR_PTR(rc); inode = ERR_PTR(rc);
goto out;
}
#ifdef CONFIG_CIFS_FSCACHE #ifdef CONFIG_CIFS_FSCACHE
/* populate tcon->resource_id */ /* populate tcon->resource_id */
...@@ -898,13 +905,11 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) ...@@ -898,13 +905,11 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
inode->i_uid = cifs_sb->mnt_uid; inode->i_uid = cifs_sb->mnt_uid;
inode->i_gid = cifs_sb->mnt_gid; inode->i_gid = cifs_sb->mnt_gid;
} else if (rc) { } else if (rc) {
kfree(full_path);
_FreeXid(xid);
iget_failed(inode); iget_failed(inode);
return ERR_PTR(rc); inode = ERR_PTR(rc);
} }
out:
kfree(full_path); kfree(full_path);
/* can not call macro FreeXid here since in a void func /* can not call macro FreeXid here since in a void func
* TODO: This is no longer true * TODO: This is no longer true
...@@ -1670,7 +1675,9 @@ cifs_inode_needs_reval(struct inode *inode) ...@@ -1670,7 +1675,9 @@ cifs_inode_needs_reval(struct inode *inode)
return false; return false;
} }
/* check invalid_mapping flag and zap the cache if it's set */ /*
* Zap the cache. Called when invalid_mapping flag is set.
*/
static void static void
cifs_invalidate_mapping(struct inode *inode) cifs_invalidate_mapping(struct inode *inode)
{ {
...@@ -2115,9 +2122,14 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) ...@@ -2115,9 +2122,14 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
if (attrs->ia_valid & ATTR_MODE) { if (attrs->ia_valid & ATTR_MODE) {
rc = 0; rc = 0;
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
rc = mode_to_acl(inode, full_path, mode); rc = mode_to_cifs_acl(inode, full_path, mode);
else if (rc) {
cFYI(1, "%s: Setting ACL failed with error: %d",
__func__, rc);
goto cifs_setattr_exit;
}
} else
#endif #endif
if (((mode & S_IWUGO) == 0) && if (((mode & S_IWUGO) == 0) &&
(cifsInode->cifsAttrs & ATTR_READONLY) == 0) { (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
......
...@@ -226,26 +226,29 @@ static int initiate_cifs_search(const int xid, struct file *file) ...@@ -226,26 +226,29 @@ static int initiate_cifs_search(const int xid, struct file *file)
char *full_path = NULL; char *full_path = NULL;
struct cifsFileInfo *cifsFile; struct cifsFileInfo *cifsFile;
struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
struct tcon_link *tlink; struct tcon_link *tlink = NULL;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
if (file->private_data == NULL) {
tlink = cifs_sb_tlink(cifs_sb); tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) if (IS_ERR(tlink))
return PTR_ERR(tlink); return PTR_ERR(tlink);
pTcon = tlink_tcon(tlink);
if (file->private_data == NULL) cifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
file->private_data = if (cifsFile == NULL) {
kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
if (file->private_data == NULL) {
rc = -ENOMEM; rc = -ENOMEM;
goto error_exit; goto error_exit;
} }
file->private_data = cifsFile;
cifsFile->tlink = cifs_get_tlink(tlink);
pTcon = tlink_tcon(tlink);
} else {
cifsFile = file->private_data; cifsFile = file->private_data;
pTcon = tlink_tcon(cifsFile->tlink);
}
cifsFile->invalidHandle = true; cifsFile->invalidHandle = true;
cifsFile->srch_inf.endOfSearch = false; cifsFile->srch_inf.endOfSearch = false;
cifsFile->tlink = cifs_get_tlink(tlink);
full_path = build_path_from_dentry(file->f_path.dentry); full_path = build_path_from_dentry(file->f_path.dentry);
if (full_path == NULL) { if (full_path == NULL) {
......
...@@ -30,10 +30,11 @@ ...@@ -30,10 +30,11 @@
#define MAX_EA_VALUE_SIZE 65535 #define MAX_EA_VALUE_SIZE 65535
#define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib" #define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
#define CIFS_XATTR_CIFS_ACL "system.cifs_acl"
#define CIFS_XATTR_USER_PREFIX "user." #define CIFS_XATTR_USER_PREFIX "user."
#define CIFS_XATTR_SYSTEM_PREFIX "system." #define CIFS_XATTR_SYSTEM_PREFIX "system."
#define CIFS_XATTR_OS2_PREFIX "os2." #define CIFS_XATTR_OS2_PREFIX "os2."
#define CIFS_XATTR_SECURITY_PREFIX ".security" #define CIFS_XATTR_SECURITY_PREFIX "security."
#define CIFS_XATTR_TRUSTED_PREFIX "trusted." #define CIFS_XATTR_TRUSTED_PREFIX "trusted."
#define XATTR_TRUSTED_PREFIX_LEN 8 #define XATTR_TRUSTED_PREFIX_LEN 8
#define XATTR_SECURITY_PREFIX_LEN 9 #define XATTR_SECURITY_PREFIX_LEN 9
...@@ -277,29 +278,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, ...@@ -277,29 +278,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
cifs_sb->local_nls, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR); CIFS_MOUNT_MAP_SPECIAL_CHR);
#ifdef CONFIG_CIFS_EXPERIMENTAL
else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
__u16 fid;
int oplock = 0;
struct cifs_ntsd *pacl = NULL;
__u32 buflen = 0;
if (experimEnabled)
rc = CIFSSMBOpen(xid, pTcon, full_path,
FILE_OPEN, GENERIC_READ, 0, &fid,
&oplock, NULL, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
/* else rc is EOPNOTSUPP from above */
if (rc == 0) {
rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &pacl,
&buflen);
CIFSSMBClose(xid, pTcon, fid);
}
}
#endif /* EXPERIMENTAL */
#else #else
cFYI(1, "query POSIX ACL not supported yet"); cFYI(1, "Query POSIX ACL not supported yet");
#endif /* CONFIG_CIFS_POSIX */ #endif /* CONFIG_CIFS_POSIX */
} else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT, } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
...@@ -311,8 +291,33 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, ...@@ -311,8 +291,33 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
cifs_sb->mnt_cifs_flags & cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR); CIFS_MOUNT_MAP_SPECIAL_CHR);
#else #else
cFYI(1, "query POSIX default ACL not supported yet"); cFYI(1, "Query POSIX default ACL not supported yet");
#endif #endif /* CONFIG_CIFS_POSIX */
} else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
#ifdef CONFIG_CIFS_ACL
u32 acllen;
struct cifs_ntsd *pacl;
pacl = get_cifs_acl(cifs_sb, direntry->d_inode,
full_path, &acllen);
if (IS_ERR(pacl)) {
rc = PTR_ERR(pacl);
cERROR(1, "%s: error %zd getting sec desc",
__func__, rc);
} else {
if (ea_value) {
if (acllen > buf_size)
acllen = -ERANGE;
else
memcpy(ea_value, pacl, acllen);
}
rc = acllen;
kfree(pacl);
}
#else
cFYI(1, "Query CIFS ACL not supported yet");
#endif /* CONFIG_CIFS_ACL */
} else if (strncmp(ea_name, } else if (strncmp(ea_name,
CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) { CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
cFYI(1, "Trusted xattr namespace not supported yet"); cFYI(1, "Trusted xattr namespace not supported yet");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment