2013-02-27 17:03:03 -08:00
/*
* linux / fs / hfsplus / xattr_trusted . c
*
* Vyacheslav Dubeyko < slava @ dubeyko . com >
*
* Handler for storing security labels as extended attributes .
*/
# include <linux/security.h>
# include "hfsplus_fs.h"
# include "xattr.h"
2013-09-11 14:24:30 -07:00
# include "acl.h"
2013-02-27 17:03:03 -08:00
static int hfsplus_security_getxattr ( struct dentry * dentry , const char * name ,
void * buffer , size_t size , int type )
{
char xattr_name [ HFSPLUS_ATTR_MAX_STRLEN + 1 ] = { 0 } ;
size_t len = strlen ( name ) ;
if ( ! strcmp ( name , " " ) )
return - EINVAL ;
if ( len + XATTR_SECURITY_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN )
return - EOPNOTSUPP ;
strcpy ( xattr_name , XATTR_SECURITY_PREFIX ) ;
strcpy ( xattr_name + XATTR_SECURITY_PREFIX_LEN , name ) ;
return hfsplus_getxattr ( dentry , xattr_name , buffer , size ) ;
}
static int hfsplus_security_setxattr ( struct dentry * dentry , const char * name ,
const void * buffer , size_t size , int flags , int type )
{
char xattr_name [ HFSPLUS_ATTR_MAX_STRLEN + 1 ] = { 0 } ;
size_t len = strlen ( name ) ;
if ( ! strcmp ( name , " " ) )
return - EINVAL ;
if ( len + XATTR_SECURITY_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN )
return - EOPNOTSUPP ;
strcpy ( xattr_name , XATTR_SECURITY_PREFIX ) ;
strcpy ( xattr_name + XATTR_SECURITY_PREFIX_LEN , name ) ;
return hfsplus_setxattr ( dentry , xattr_name , buffer , size , flags ) ;
}
static size_t hfsplus_security_listxattr ( struct dentry * dentry , char * list ,
size_t list_size , const char * name , size_t name_len , int type )
{
/*
* This method is not used .
* It is used hfsplus_listxattr ( ) instead of generic_listxattr ( ) .
*/
return - EOPNOTSUPP ;
}
static int hfsplus_initxattrs ( struct inode * inode ,
const struct xattr * xattr_array ,
void * fs_info )
{
const struct xattr * xattr ;
char xattr_name [ HFSPLUS_ATTR_MAX_STRLEN + 1 ] = { 0 } ;
size_t xattr_name_len ;
int err = 0 ;
for ( xattr = xattr_array ; xattr - > name ! = NULL ; xattr + + ) {
xattr_name_len = strlen ( xattr - > name ) ;
if ( xattr_name_len = = 0 )
continue ;
if ( xattr_name_len + XATTR_SECURITY_PREFIX_LEN >
HFSPLUS_ATTR_MAX_STRLEN )
return - EOPNOTSUPP ;
strcpy ( xattr_name , XATTR_SECURITY_PREFIX ) ;
strcpy ( xattr_name +
XATTR_SECURITY_PREFIX_LEN , xattr - > name ) ;
memset ( xattr_name +
XATTR_SECURITY_PREFIX_LEN + xattr_name_len , 0 , 1 ) ;
err = __hfsplus_setxattr ( inode , xattr_name ,
xattr - > value , xattr - > value_len , 0 ) ;
if ( err )
break ;
}
return err ;
}
int hfsplus_init_security ( struct inode * inode , struct inode * dir ,
const struct qstr * qstr )
{
return security_inode_init_security ( inode , dir , qstr ,
& hfsplus_initxattrs , NULL ) ;
}
2013-09-11 14:24:30 -07:00
int hfsplus_init_inode_security ( struct inode * inode ,
struct inode * dir ,
const struct qstr * qstr )
{
int err ;
err = hfsplus_init_posix_acl ( inode , dir ) ;
if ( ! err )
err = hfsplus_init_security ( inode , dir , qstr ) ;
return err ;
}
2013-02-27 17:03:03 -08:00
const struct xattr_handler hfsplus_xattr_security_handler = {
. prefix = XATTR_SECURITY_PREFIX ,
. list = hfsplus_security_listxattr ,
. get = hfsplus_security_getxattr ,
. set = hfsplus_security_setxattr ,
} ;