2005-04-17 02:20:36 +04:00
# include <linux/reiserfs_fs.h>
# include <linux/errno.h>
# include <linux/fs.h>
# include <linux/pagemap.h>
# include <linux/xattr.h>
# include <linux/reiserfs_xattr.h>
2009-03-30 22:02:41 +04:00
# include <linux/security.h>
2005-04-17 02:20:36 +04:00
# include <asm/uaccess.h>
static int
2009-11-13 12:52:56 +03:00
security_get ( struct dentry * dentry , const char * name , void * buffer , size_t size ,
int handler_flags )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
if ( strlen ( name ) < sizeof ( XATTR_SECURITY_PREFIX ) )
return - EINVAL ;
2005-04-17 02:20:36 +04:00
2009-11-13 12:52:56 +03:00
if ( IS_PRIVATE ( dentry - > d_inode ) )
2005-07-13 07:21:28 +04:00
return - EPERM ;
2005-04-17 02:20:36 +04:00
2009-11-13 12:52:56 +03:00
return reiserfs_xattr_get ( dentry - > d_inode , name , buffer , size ) ;
2005-04-17 02:20:36 +04:00
}
static int
2009-11-13 12:52:56 +03:00
security_set ( struct dentry * dentry , const char * name , const void * buffer ,
size_t size , int flags , int handler_flags )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
if ( strlen ( name ) < sizeof ( XATTR_SECURITY_PREFIX ) )
return - EINVAL ;
2005-04-17 02:20:36 +04:00
2009-11-13 12:52:56 +03:00
if ( IS_PRIVATE ( dentry - > d_inode ) )
2005-07-13 07:21:28 +04:00
return - EPERM ;
2005-04-17 02:20:36 +04:00
2009-11-13 12:52:56 +03:00
return reiserfs_xattr_set ( dentry - > d_inode , name , buffer , size , flags ) ;
2005-04-17 02:20:36 +04:00
}
2009-11-13 12:52:56 +03:00
static size_t security_list ( struct dentry * dentry , char * list , size_t list_len ,
const char * name , size_t namelen , int handler_flags )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:38 +04:00
const size_t len = namelen + 1 ;
2005-04-17 02:20:36 +04:00
2009-11-13 12:52:56 +03:00
if ( IS_PRIVATE ( dentry - > d_inode ) )
2005-07-13 07:21:28 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
2009-03-30 22:02:38 +04:00
if ( list & & len < = list_len ) {
memcpy ( list , name , namelen ) ;
list [ namelen ] = ' \0 ' ;
}
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
return len ;
2005-04-17 02:20:36 +04:00
}
2009-03-30 22:02:41 +04:00
/* Initializes the security context for a new inode and returns the number
* of blocks needed for the transaction . If successful , reiserfs_security
* must be released using reiserfs_security_free when the caller is done . */
int reiserfs_security_init ( struct inode * dir , struct inode * inode ,
struct reiserfs_security_handle * sec )
{
int blocks = 0 ;
2009-05-05 23:30:16 +04:00
int error ;
sec - > name = NULL ;
/* Don't add selinux attributes on xattrs - they'll never get used */
if ( IS_PRIVATE ( dir ) )
return 0 ;
error = security_inode_init_security ( inode , dir , & sec - > name ,
& sec - > value , & sec - > length ) ;
2009-03-30 22:02:41 +04:00
if ( error ) {
if ( error = = - EOPNOTSUPP )
error = 0 ;
sec - > name = NULL ;
sec - > value = NULL ;
sec - > length = 0 ;
return error ;
}
2010-03-23 23:35:38 +03:00
if ( sec - > length & & reiserfs_xattrs_initialized ( inode - > i_sb ) ) {
2009-03-30 22:02:41 +04:00
blocks = reiserfs_xattr_jcreate_nblocks ( inode ) +
reiserfs_xattr_nblocks ( inode , sec - > length ) ;
/* We don't want to count the directories twice if we have
* a default ACL . */
REISERFS_I ( inode ) - > i_flags | = i_has_xattr_dir ;
}
return blocks ;
}
int reiserfs_security_write ( struct reiserfs_transaction_handle * th ,
struct inode * inode ,
struct reiserfs_security_handle * sec )
{
int error ;
if ( strlen ( sec - > name ) < sizeof ( XATTR_SECURITY_PREFIX ) )
return - EINVAL ;
error = reiserfs_xattr_set_handle ( th , inode , sec - > name , sec - > value ,
sec - > length , XATTR_CREATE ) ;
if ( error = = - ENODATA | | error = = - EOPNOTSUPP )
error = 0 ;
return error ;
}
void reiserfs_security_free ( struct reiserfs_security_handle * sec )
{
kfree ( sec - > name ) ;
kfree ( sec - > value ) ;
sec - > name = NULL ;
sec - > value = NULL ;
}
2009-03-30 22:02:38 +04:00
struct xattr_handler reiserfs_xattr_security_handler = {
2005-04-17 02:20:36 +04:00
. prefix = XATTR_SECURITY_PREFIX ,
. get = security_get ,
. set = security_set ,
. list = security_list ,
} ;