Simplified interfaces for checking permissions

This commit is contained in:
jpandre 2009-12-14 17:23:12 +00:00
parent bae437d845
commit c5c51ec1fe
3 changed files with 349 additions and 194 deletions

View File

@ -240,26 +240,24 @@ extern le32 ntfs_security_hash(const SECURITY_DESCRIPTOR_RELATIVE *sd,
int ntfs_build_mapping(struct SECURITY_CONTEXT *scx, const char *usermap_path);
int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode *ni, struct stat*);
int ntfs_set_mode(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode *ni, mode_t mode);
BOOL ntfs_allowed_as_owner(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode *ni);
int ntfs_allowed_access(struct SECURITY_CONTEXT *scx, const char *path,
ntfs_inode *ni, struct stat*);
int ntfs_set_mode(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, mode_t mode);
BOOL ntfs_allowed_as_owner(struct SECURITY_CONTEXT *scx, ntfs_inode *ni);
int ntfs_allowed_access(struct SECURITY_CONTEXT *scx,
ntfs_inode *ni, int accesstype);
BOOL ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
BOOL old_ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
const char *path, int accesstype);
#if POSIXACLS
le32 ntfs_alloc_securid(struct SECURITY_CONTEXT *scx,
uid_t uid, gid_t gid, const char *dir_path,
ntfs_inode *dir_ni, mode_t mode, BOOL isdir);
uid_t uid, gid_t gid, ntfs_inode *dir_ni,
mode_t mode, BOOL isdir);
#else
le32 ntfs_alloc_securid(struct SECURITY_CONTEXT *scx,
uid_t uid, gid_t gid, mode_t mode, BOOL isdir);
#endif
int ntfs_set_owner(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode *ni, uid_t uid, gid_t gid);
int ntfs_set_owner(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
uid_t uid, gid_t gid);
#if POSIXACLS
int ntfs_set_owner_mode(struct SECURITY_CONTEXT *scx,
ntfs_inode *ni, uid_t uid, gid_t gid,
@ -269,7 +267,7 @@ int ntfs_set_owner_mode(struct SECURITY_CONTEXT *scx,
ntfs_inode *ni, uid_t uid, gid_t gid, mode_t mode);
#endif
le32 ntfs_inherited_id(struct SECURITY_CONTEXT *scx,
const char *dir_path, ntfs_inode *dir_ni, BOOL fordir);
ntfs_inode *dir_ni, BOOL fordir);
int ntfs_open_secure(ntfs_volume *vol);
void ntfs_close_secure(struct SECURITY_CONTEXT *scx);
@ -277,28 +275,25 @@ void ntfs_close_secure(struct SECURITY_CONTEXT *scx);
int ntfs_set_inherited_posix(struct SECURITY_CONTEXT *scx,
ntfs_inode *ni, uid_t uid, gid_t gid,
const char *dir_path, ntfs_inode *dir_ni, mode_t mode);
int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, const char *path,
const char *name, char *value, size_t size,
ntfs_inode *ni);
int ntfs_set_posix_acl(struct SECURITY_CONTEXT *scx, const char *path,
ntfs_inode *dir_ni, mode_t mode);
int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
const char *name, char *value, size_t size);
int ntfs_set_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
const char *name, const char *value, size_t size,
int flags, ntfs_inode *ni);
int ntfs_remove_posix_acl(struct SECURITY_CONTEXT *scx, const char *path,
const char *name, ntfs_inode *ni);
int flags);
int ntfs_remove_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
const char *name);
#endif
int ntfs_get_ntfs_acl(struct SECURITY_CONTEXT *scx, const char *path,
const char *name, char *value, size_t size,
ntfs_inode *ni);
int ntfs_set_ntfs_acl(struct SECURITY_CONTEXT *scx, const char *path,
const char *name, const char *value, size_t size,
int flags, ntfs_inode *ni);
int ntfs_get_ntfs_attrib(const char *path,
char *value, size_t size, ntfs_inode *ni);
int ntfs_set_ntfs_attrib(const char *path,
const char *value, size_t size, int flags,
ntfs_inode *ni);
int ntfs_get_ntfs_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
char *value, size_t size);
int ntfs_set_ntfs_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
const char *value, size_t size, int flags);
int ntfs_get_ntfs_attrib(ntfs_inode *ni, char *value, size_t size);
int ntfs_set_ntfs_attrib(ntfs_inode *ni,
const char *value, size_t size, int flags);
/*
* Security API for direct access to security descriptors

View File

@ -1105,7 +1105,7 @@ static int update_secur_descr(ntfs_volume *vol,
* -1 if there is a problem
*/
static int upgrade_secur_desc(ntfs_volume *vol, const char *path,
static int upgrade_secur_desc(ntfs_volume *vol,
const char *attr, ntfs_inode *ni)
{
int attrsz;
@ -1116,11 +1116,11 @@ static int upgrade_secur_desc(ntfs_volume *vol, const char *path,
/*
* upgrade requires NTFS format v3.x
* also refuse upgrading for special files
* whose number is less than FILE_first_user
*/
if ((vol->major_ver >= 3)
&& (path[0] == '/')
&& (path[1] != '$') && (path[1] != '\0')) {
&& (ni->mft_no < FILE_first_user)) {
attrsz = ntfs_attr_size(attr);
securid = setsecurityattr(vol,
(const SECURITY_DESCRIPTOR_RELATIVE*)attr,
@ -1788,8 +1788,7 @@ static char *retrievesecurityattr(ntfs_volume *vol, SII_INDEX_KEY id)
* The returned descriptor is dynamically allocated and has to be freed
*/
static char *getsecurityattr(ntfs_volume *vol,
const char *path, ntfs_inode *ni)
static char *getsecurityattr(ntfs_volume *vol, ntfs_inode *ni)
{
SII_INDEX_KEY securid;
char *securattr;
@ -1815,8 +1814,8 @@ static char *getsecurityattr(ntfs_volume *vol,
securattr = ntfs_attr_readall(ni, AT_SECURITY_DESCRIPTOR,
AT_UNNAMED, 0, &readallsz);
if (securattr && !ntfs_valid_descr(securattr, readallsz)) {
ntfs_log_error("Bad security descriptor for %s\n",
path);
ntfs_log_error("Bad security descriptor for inode %lld\n",
(long long)ni->mft_no);
free(securattr);
securattr = (char*)NULL;
}
@ -1830,7 +1829,8 @@ static char *getsecurityattr(ntfs_volume *vol,
* minimum rights, so that a real descriptor can
* be created by chown or chmod
*/
ntfs_log_error("No security descriptor found for %s\n",path);
ntfs_log_error("No security descriptor found for inode %lld\n",
(long long)ni->mft_no);
securattr = ntfs_build_descr(0, 0, adminsid, adminsid);
}
return (securattr);
@ -1968,7 +1968,7 @@ static int access_check_posix(struct SECURITY_CONTEXT *scx,
*/
static int ntfs_get_perm(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode * ni, mode_t request)
ntfs_inode * ni, mode_t request)
{
const SECURITY_DESCRIPTOR_RELATIVE *phead;
const struct CACHED_PERMISSIONS *cached;
@ -1994,7 +1994,7 @@ static int ntfs_get_perm(struct SECURITY_CONTEXT *scx,
perm = 0; /* default to no permission */
isdir = (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
!= const_cpu_to_le16(0);
securattr = getsecurityattr(scx->vol, path, ni);
securattr = getsecurityattr(scx->vol, ni);
if (securattr) {
phead = (const SECURITY_DESCRIPTOR_RELATIVE*)
securattr;
@ -2034,7 +2034,7 @@ static int ntfs_get_perm(struct SECURITY_CONTEXT *scx,
&& (perm >= 0)
&& (scx->vol->secure_flags
& (1 << SECURITY_ADDSECURIDS))) {
upgrade_secur_desc(scx->vol, path,
upgrade_secur_desc(scx->vol,
securattr, ni);
/*
* fetch owner and group for cacheing
@ -2068,9 +2068,8 @@ static int ntfs_get_perm(struct SECURITY_CONTEXT *scx,
* the caller is expected to issue a new call
*/
int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, const char *path,
const char *name, char *value, size_t size,
ntfs_inode *ni)
int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
const char *name, char *value, size_t size)
{
const SECURITY_DESCRIPTOR_RELATIVE *phead;
struct POSIX_SECURITY *pxdesc;
@ -2093,7 +2092,7 @@ int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, const char *path,
if (cached)
pxdesc = cached->pxdesc;
else {
securattr = getsecurityattr(scx->vol, path, ni);
securattr = getsecurityattr(scx->vol, ni);
isdir = (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
!= const_cpu_to_le16(0);
if (securattr) {
@ -2124,7 +2123,7 @@ int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, const char *path,
&& (scx->vol->secure_flags
& (1 << SECURITY_ADDSECURIDS))) {
upgrade_secur_desc(scx->vol,
path, securattr, ni);
securattr, ni);
}
#if OWNERFROMACL
uid = ntfs_find_user(scx->mapping[MAPUSERS],usid);
@ -2202,13 +2201,10 @@ int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, const char *path,
* Do no use as mode of the file
*
* returns -1 if there is a problem
*
* This is only used for checking creation of DOS file names
*/
static int ntfs_get_perm(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode *ni,
mode_t request __attribute__((unused)))
ntfs_inode *ni, mode_t request)
{
const SECURITY_DESCRIPTOR_RELATIVE *phead;
const struct CACHED_PERMISSIONS *cached;
@ -2233,7 +2229,7 @@ static int ntfs_get_perm(struct SECURITY_CONTEXT *scx,
perm = 0; /* default to no permission */
isdir = (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
!= const_cpu_to_le16(0);
securattr = getsecurityattr(scx->vol, path, ni);
securattr = getsecurityattr(scx->vol, ni);
if (securattr) {
phead = (const SECURITY_DESCRIPTOR_RELATIVE*)
securattr;
@ -2265,7 +2261,7 @@ static int ntfs_get_perm(struct SECURITY_CONTEXT *scx,
&& (perm >= 0)
&& (scx->vol->secure_flags
& (1 << SECURITY_ADDSECURIDS))) {
upgrade_secur_desc(scx->vol, path,
upgrade_secur_desc(scx->vol,
securattr, ni);
/*
* fetch owner and group for cacheing
@ -2321,15 +2317,14 @@ static int ntfs_get_perm(struct SECURITY_CONTEXT *scx,
* the caller is expected to issue a new call
*/
int ntfs_get_ntfs_acl(struct SECURITY_CONTEXT *scx, const char *path,
const char *name __attribute__((unused)),
char *value, size_t size, ntfs_inode *ni)
int ntfs_get_ntfs_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
char *value, size_t size)
{
char *securattr;
size_t outsize;
outsize = 0; /* default to no data and no error */
securattr = getsecurityattr(scx->vol, path, ni);
securattr = getsecurityattr(scx->vol, ni);
if (securattr) {
outsize = ntfs_attr_size(securattr);
if (outsize <= size) {
@ -2346,8 +2341,7 @@ int ntfs_get_ntfs_acl(struct SECURITY_CONTEXT *scx, const char *path,
*/
int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode * ni,
struct stat *stbuf)
ntfs_inode * ni, struct stat *stbuf)
{
const SECURITY_DESCRIPTOR_RELATIVE *phead;
char *securattr;
@ -2374,7 +2368,7 @@ int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx,
perm = -1; /* default to error */
isdir = (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
!= const_cpu_to_le16(0);
securattr = getsecurityattr(scx->vol, path, ni);
securattr = getsecurityattr(scx->vol, ni);
if (securattr) {
phead =
(const SECURITY_DESCRIPTOR_RELATIVE*)
@ -2410,7 +2404,7 @@ int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx,
&& (scx->vol->secure_flags
& (1 << SECURITY_ADDSECURIDS))) {
upgrade_secur_desc(scx->vol,
path, securattr, ni);
securattr, ni);
}
#if OWNERFROMACL
stbuf->st_uid = ntfs_find_user(scx->mapping[MAPUSERS],usid);
@ -2451,8 +2445,7 @@ int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx,
*/
static struct POSIX_SECURITY *inherit_posix(struct SECURITY_CONTEXT *scx,
const char *dir_path, ntfs_inode *dir_ni,
mode_t mode, BOOL isdir)
ntfs_inode *dir_ni, mode_t mode, BOOL isdir)
{
const struct CACHED_PERMISSIONS *cached;
const SECURITY_DESCRIPTOR_RELATIVE *phead;
@ -2476,7 +2469,7 @@ static struct POSIX_SECURITY *inherit_posix(struct SECURITY_CONTEXT *scx,
scx->umask,isdir);
}
} else {
securattr = getsecurityattr(scx->vol, dir_path, dir_ni);
securattr = getsecurityattr(scx->vol, dir_ni);
if (securattr) {
phead = (const SECURITY_DESCRIPTOR_RELATIVE*)
securattr;
@ -2506,7 +2499,7 @@ static struct POSIX_SECURITY *inherit_posix(struct SECURITY_CONTEXT *scx,
if (!test_nino_flag(dir_ni, v3_Extensions)
&& (scx->vol->secure_flags
& (1 << SECURITY_ADDSECURIDS))) {
upgrade_secur_desc(scx->vol, dir_path,
upgrade_secur_desc(scx->vol,
securattr, dir_ni);
/*
* fetch owner and group for cacheing
@ -2534,8 +2527,8 @@ static struct POSIX_SECURITY *inherit_posix(struct SECURITY_CONTEXT *scx,
*/
le32 ntfs_alloc_securid(struct SECURITY_CONTEXT *scx,
uid_t uid, gid_t gid, const char *dir_path,
ntfs_inode *dir_ni, mode_t mode, BOOL isdir)
uid_t uid, gid_t gid, ntfs_inode *dir_ni,
mode_t mode, BOOL isdir)
{
#if !FORCE_FORMAT_v1x
const struct CACHED_SECURID *cached;
@ -2554,7 +2547,7 @@ le32 ntfs_alloc_securid(struct SECURITY_CONTEXT *scx,
#if !FORCE_FORMAT_v1x
pxdesc = inherit_posix(scx, dir_path, dir_ni, mode, isdir);
pxdesc = inherit_posix(scx, dir_ni, mode, isdir);
if (pxdesc) {
/* check whether target securid is known in cache */
@ -2617,7 +2610,7 @@ le32 ntfs_alloc_securid(struct SECURITY_CONTEXT *scx,
int ntfs_set_inherited_posix(struct SECURITY_CONTEXT *scx,
ntfs_inode *ni, uid_t uid, gid_t gid,
const char *dir_path, ntfs_inode *dir_ni, mode_t mode)
ntfs_inode *dir_ni, mode_t mode)
{
struct POSIX_SECURITY *pxdesc;
char *newattr;
@ -2630,7 +2623,7 @@ int ntfs_set_inherited_posix(struct SECURITY_CONTEXT *scx,
res = -1;
isdir = (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) != const_cpu_to_le16(0);
pxdesc = inherit_posix(scx, dir_path, dir_ni, mode, isdir);
pxdesc = inherit_posix(scx, dir_ni, mode, isdir);
if (pxdesc) {
usid = ntfs_find_usid(scx->mapping[MAPUSERS],uid,(SID*)&defusid);
gsid = ntfs_find_gsid(scx->mapping[MAPGROUPS],gid,(SID*)&defgsid);
@ -2882,8 +2875,7 @@ int ntfs_set_owner_mode(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
* if not, errno tells why
*/
BOOL ntfs_allowed_as_owner(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode *ni)
BOOL ntfs_allowed_as_owner(struct SECURITY_CONTEXT *scx, ntfs_inode *ni)
{
const struct CACHED_PERMISSIONS *cached;
char *oldattr;
@ -2909,7 +2901,7 @@ BOOL ntfs_allowed_as_owner(struct SECURITY_CONTEXT *scx,
uid = cached->uid;
gotowner = TRUE;
} else {
oldattr = getsecurityattr(scx->vol,path, ni);
oldattr = getsecurityattr(scx->vol, ni);
if (oldattr) {
#if OWNERFROMACL
usid = ntfs_acl_owner(oldattr);
@ -2949,9 +2941,9 @@ BOOL ntfs_allowed_as_owner(struct SECURITY_CONTEXT *scx,
* Returns 0, or -1 if there is a problem which errno describes
*/
int ntfs_set_posix_acl(struct SECURITY_CONTEXT *scx, const char *path,
int ntfs_set_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
const char *name, const char *value, size_t size,
int flags, ntfs_inode *ni)
int flags)
{
const SECURITY_DESCRIPTOR_RELATIVE *phead;
const struct CACHED_PERMISSIONS *cached;
@ -2991,7 +2983,7 @@ int ntfs_set_posix_acl(struct SECURITY_CONTEXT *scx, const char *path,
(const struct POSIX_ACL*)value,count,deflt);
}
} else {
oldattr = getsecurityattr(scx->vol,path, ni);
oldattr = getsecurityattr(scx->vol, ni);
if (oldattr) {
phead = (const SECURITY_DESCRIPTOR_RELATIVE*)oldattr;
#if OWNERFROMACL
@ -3052,11 +3044,11 @@ int ntfs_set_posix_acl(struct SECURITY_CONTEXT *scx, const char *path,
* Returns 0, or -1 if there is a problem which errno describes
*/
int ntfs_remove_posix_acl(struct SECURITY_CONTEXT *scx, const char *path,
const char *name, ntfs_inode *ni)
int ntfs_remove_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
const char *name)
{
return (ntfs_set_posix_acl(scx, path, name,
(const char*)NULL, 0, 0, ni));
return (ntfs_set_posix_acl(scx, ni, name,
(const char*)NULL, 0, 0));
}
#endif
@ -3067,11 +3059,8 @@ int ntfs_remove_posix_acl(struct SECURITY_CONTEXT *scx, const char *path,
* Returns 0, or -1 if there is a problem
*/
int ntfs_set_ntfs_acl(struct SECURITY_CONTEXT *scx,
const char *path __attribute__((unused)),
const char *name __attribute__((unused)),
const char *value, size_t size, int flags,
ntfs_inode *ni)
int ntfs_set_ntfs_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
const char *value, size_t size, int flags)
{
char *attr;
int res;
@ -3130,8 +3119,7 @@ int ntfs_set_ntfs_acl(struct SECURITY_CONTEXT *scx,
* -1 on failure, with errno = EIO
*/
int ntfs_set_mode(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode *ni, mode_t mode)
int ntfs_set_mode(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, mode_t mode)
{
const SECURITY_DESCRIPTOR_RELATIVE *phead;
const struct CACHED_PERMISSIONS *cached;
@ -3172,7 +3160,7 @@ int ntfs_set_mode(struct SECURITY_CONTEXT *scx,
newpxdesc = (struct POSIX_SECURITY*)NULL;
#endif
} else {
oldattr = getsecurityattr(scx->vol,path, ni);
oldattr = getsecurityattr(scx->vol, ni);
if (oldattr) {
phead = (const SECURITY_DESCRIPTOR_RELATIVE*)oldattr;
#if OWNERFROMACL
@ -3319,7 +3307,7 @@ int ntfs_sd_add_everyone(ntfs_inode *ni)
*/
int ntfs_allowed_access(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode *ni,
ntfs_inode *ni,
int accesstype) /* access type required (S_Ixxx values) */
{
int perm;
@ -3327,10 +3315,6 @@ int ntfs_allowed_access(struct SECURITY_CONTEXT *scx,
int allow;
struct stat stbuf;
#if POSIXACLS
/* shortcut, use only if Posix ACLs in use */
if (scx->vol->secure_flags & (1 << SECURITY_DEFAULT)) return (1);
#endif
/*
* Always allow for root unless execution is requested.
* (was checked by fuse until kernel 2.6.29)
@ -3342,7 +3326,7 @@ int ntfs_allowed_access(struct SECURITY_CONTEXT *scx,
|| (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY))))
allow = 1;
else {
perm = ntfs_get_perm(scx, path, ni, accesstype);
perm = ntfs_get_perm(scx, ni, accesstype);
if (perm >= 0) {
res = EACCES;
switch (accesstype) {
@ -3369,7 +3353,7 @@ int ntfs_allowed_access(struct SECURITY_CONTEXT *scx,
break;
case S_IWRITE + S_IEXEC + S_ISVTX:
if (perm & S_ISVTX) {
if ((ntfs_get_owner_mode(scx,path,ni,&stbuf) >= 0)
if ((ntfs_get_owner_mode(scx,ni,&stbuf) >= 0)
&& (stbuf.st_uid == scx->uid))
allow = 1;
else
@ -3391,6 +3375,8 @@ int ntfs_allowed_access(struct SECURITY_CONTEXT *scx,
return (allow);
}
#if 0 /* not needed any more */
/*
* Check whether user can access the parent directory
* of a file in a specific way
@ -3403,7 +3389,7 @@ int ntfs_allowed_access(struct SECURITY_CONTEXT *scx,
* This is used for Posix ACL and checking creation of DOS file names
*/
BOOL ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
BOOL old_ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
const char *path, int accesstype)
{
int allow;
@ -3413,10 +3399,6 @@ BOOL ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
ntfs_inode *dir_ni;
struct stat stbuf;
#if POSIXACLS
/* shortcut, use only if Posix ACLs in use */
if (scx->vol->secure_flags & (1 << SECURITY_DEFAULT)) return (TRUE);
#endif
allow = 0;
dirpath = strdup(path);
if (dirpath) {
@ -3426,7 +3408,7 @@ BOOL ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
*name = 0;
dir_ni = ntfs_pathname_to_inode(scx->vol, NULL, dirpath);
if (dir_ni) {
allow = ntfs_allowed_access(scx,dirpath,
allow = ntfs_allowed_access(scx,
dir_ni, accesstype);
ntfs_inode_close(dir_ni);
/*
@ -3439,7 +3421,7 @@ BOOL ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
path);
allow = FALSE;
if (ni) {
allow = (ntfs_get_owner_mode(scx,path,ni,&stbuf) >= 0)
allow = (ntfs_get_owner_mode(scx,ni,&stbuf) >= 0)
&& (stbuf.st_uid == scx->uid);
ntfs_inode_close(ni);
}
@ -3450,14 +3432,16 @@ BOOL ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
return (allow); /* errno is set if not allowed */
}
#endif
/*
* Define a new owner/group to a file
*
* returns zero if successful
*/
int ntfs_set_owner(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode *ni, uid_t uid, gid_t gid)
int ntfs_set_owner(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
uid_t uid, gid_t gid)
{
const SECURITY_DESCRIPTOR_RELATIVE *phead;
const struct CACHED_PERMISSIONS *cached;
@ -3492,7 +3476,7 @@ int ntfs_set_owner(struct SECURITY_CONTEXT *scx,
fileuid = 0;
filegid = 0;
mode = 0;
oldattr = getsecurityattr(scx->vol, path, ni);
oldattr = getsecurityattr(scx->vol, ni);
if (oldattr) {
isdir = (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
!= const_cpu_to_le16(0);
@ -3709,7 +3693,7 @@ static le32 build_inherited_id(struct SECURITY_CONTEXT *scx,
*/
le32 ntfs_inherited_id(struct SECURITY_CONTEXT *scx,
const char *dir_path, ntfs_inode *dir_ni, BOOL fordir)
ntfs_inode *dir_ni, BOOL fordir)
{
struct CACHED_PERMISSIONS *cached;
char *parentattr;
@ -3732,7 +3716,7 @@ le32 ntfs_inherited_id(struct SECURITY_CONTEXT *scx,
* Note : if parent directory has no id, it is not cacheable
*/
if (!securid) {
parentattr = getsecurityattr(scx->vol, dir_path, dir_ni);
parentattr = getsecurityattr(scx->vol, dir_ni);
if (parentattr) {
securid = build_inherited_id(scx,
parentattr, fordir);
@ -3933,7 +3917,7 @@ static int ntfs_default_mapping(struct SECURITY_CONTEXT *scx)
res = -1;
ni = ntfs_pathname_to_inode(scx->vol, NULL, "/.");
if (ni) {
securattr = getsecurityattr(scx->vol,"/.",ni);
securattr = getsecurityattr(scx->vol, ni);
if (securattr) {
phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr;
usid = (SID*)&securattr[le32_to_cpu(phead->owner)];
@ -4039,8 +4023,7 @@ int ntfs_build_mapping(struct SECURITY_CONTEXT *scx, const char *usermap_path)
* The attribute is returned according to cpu endianness
*/
int ntfs_get_ntfs_attrib(const char *path __attribute__((unused)),
char *value, size_t size, ntfs_inode *ni)
int ntfs_get_ntfs_attrib(ntfs_inode *ni, char *value, size_t size)
{
u32 attrib;
size_t outsize;
@ -4072,9 +4055,8 @@ int ntfs_get_ntfs_attrib(const char *path __attribute__((unused)),
* Returns 0, or -1 if there is a problem
*/
int ntfs_set_ntfs_attrib(const char *path __attribute__((unused)),
const char *value, size_t size, int flags,
ntfs_inode *ni)
int ntfs_set_ntfs_attrib(ntfs_inode *ni,
const char *value, size_t size, int flags)
{
u32 attrib;
le32 settable;
@ -4526,7 +4508,7 @@ int ntfs_get_file_security(struct SECURITY_API *scapi,
if (scapi && (scapi->magic == MAGIC_API)) {
ni = ntfs_pathname_to_inode(scapi->security.vol, NULL, path);
if (ni) {
attr = getsecurityattr(scapi->security.vol, path, ni);
attr = getsecurityattr(scapi->security.vol, ni);
if (attr) {
if (feedsecurityattr(attr,selection,
buf,buflen,psize)) {
@ -4595,7 +4577,7 @@ int ntfs_set_file_security(struct SECURITY_API *scapi,
NULL, path);
if (ni) {
oldattr = getsecurityattr(scapi->security.vol,
path, ni);
ni);
if (oldattr) {
if (mergesecurityattr(
scapi->security.vol,

View File

@ -102,6 +102,15 @@
#include "logging.h"
#include "misc.h"
/* sometimes the kernel cannot check access */
#define ntfs_real_allowed_access(scx, ni, type) ntfs_allowed_access(scx, ni, type)
#if POSIXACLS
/* short-circuit if PERMS checked by kernel and ACLs by fs */
#define ntfs_allowed_access(scx, ni, type) \
((scx)->vol->secure_flags & (1 << SECURITY_DEFAULT) \
? 1 : ntfs_allowed_access(scx, ni, type))
#endif
#define set_archive(ni) (ni)->flags |= FILE_ATTR_ARCHIVE
typedef enum {
@ -293,6 +302,127 @@ static BOOL ntfs_fuse_fill_security_context(struct SECURITY_CONTEXT *scx)
return (ctx->security.mapping[MAPUSERS] != (struct MAPPING*)NULL);
}
#if POSIXACLS
/*
* Check access to parent directory
*
* directory and file inodes are only opened when not fed in,
* they *HAVE TO* be fed in when already open, however
* file inode is only useful when S_ISVTX is requested
*
* returns 1 if allowed,
* 0 if not allowed or some error occurred (errno tells why)
*/
static int ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode *dir_ni,
ntfs_inode *ni, mode_t accesstype)
{
int allowed;
ntfs_inode *ni2;
ntfs_inode *dir_ni2;
char *dirpath;
char *name;
struct stat stbuf;
#if POSIXACLS
/* short-circuit if PERMS checked by kernel and ACLs by fs */
if (scx->vol->secure_flags & (1 << SECURITY_DEFAULT))
allowed = 1;
else
#endif
if (dir_ni)
allowed = ntfs_real_allowed_access(scx, dir_ni,
accesstype);
else {
allowed = 0;
dirpath = strdup(path);
if (dirpath) {
/* the root of file system is seen as a parent of itself */
/* is that correct ? */
name = strrchr(dirpath, '/');
*name = 0;
dir_ni2 = ntfs_pathname_to_inode(scx->vol,
NULL, dirpath);
if (dir_ni2) {
allowed = ntfs_real_allowed_access(scx,
dir_ni2, accesstype);
if (ntfs_inode_close(dir_ni2))
allowed = 0;
}
free(dirpath);
}
}
/*
* for a not-owned sticky directory, have to
* check whether file itself is owned
*/
if ((accesstype == (S_IWRITE + S_IEXEC + S_ISVTX))
&& (allowed == 2)) {
if (ni)
ni2 = ni;
else
ni2 = ntfs_pathname_to_inode(scx->vol, NULL,
path);
allowed = 0;
if (ni2) {
allowed = (ntfs_get_owner_mode(scx,ni2,&stbuf)
>= 0)
&& (stbuf.st_uid == scx->uid);
if (!ni)
ntfs_inode_close(ni2);
}
}
return (allowed);
}
#endif
/*
* Check access to parent directory
*
* for non-standard cases where access control cannot be checked by kernel
*
* no known situations where S_ISVTX is requested
*
* returns 1 if allowed,
* 0 if not allowed or some error occurred (errno tells why)
*/
static int ntfs_allowed_real_dir_access(struct SECURITY_CONTEXT *scx,
const char *path, ntfs_inode *dir_ni,
mode_t accesstype)
{
int allowed;
ntfs_inode *dir_ni2;
char *dirpath;
char *name;
if (dir_ni)
allowed = ntfs_real_allowed_access(scx, dir_ni, accesstype);
else {
allowed = 0;
dirpath = strdup(path);
if (dirpath) {
/* the root of file system is seen as a parent of itself */
/* is that correct ? */
name = strrchr(dirpath, '/');
*name = 0;
dir_ni2 = ntfs_pathname_to_inode(scx->vol, NULL,
dirpath);
if (dir_ni2) {
allowed = ntfs_real_allowed_access(scx,
dir_ni2, accesstype);
if (ntfs_inode_close(dir_ni2))
allowed = 0;
}
free(dirpath);
}
}
return (allowed);
}
/**
* ntfs_fuse_statfs - return information about mounted NTFS volume
* @path: ignored (but fuse requires it)
@ -544,9 +674,11 @@ static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf)
* make sure the parent directory is searchable
*/
if (withusermapping
&& !ntfs_allowed_dir_access(&security,path,S_IEXEC)) {
res = -EACCES;
goto exit;
&& !ntfs_allowed_dir_access(&security,path,
(!strcmp(org_path,"/") ? ni : (ntfs_inode*)NULL),
ni, S_IEXEC)) {
res = -EACCES;
goto exit;
}
#endif
if (((ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
@ -686,7 +818,7 @@ static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf)
stbuf->st_mode |= (0777 & ~ctx->fmask);
}
if (withusermapping) {
if (ntfs_get_owner_mode(&security,path,ni,stbuf) < 0)
if (ntfs_get_owner_mode(&security,ni,stbuf) < 0)
set_fuse_error(&res);
} else {
stbuf->st_uid = ctx->uid;
@ -882,10 +1014,17 @@ static int ntfs_fuse_opendir(const char *path,
accesstype = S_IWRITE | S_IREAD;
else
accesstype = S_IREAD;
/* directory must be searchable */
if (!ntfs_allowed_dir_access(&security,path,S_IEXEC)
/* check whether requested access is allowed */
|| !ntfs_allowed_access(&security,path,ni,accesstype))
/*
* directory must be searchable
* and requested access be allowed
*/
if (!strcmp(path,"/")
? !ntfs_allowed_dir_access(&security,
path, ni, ni, accesstype | S_IEXEC)
: !ntfs_allowed_dir_access(&security, path,
(ntfs_inode*)NULL, ni, S_IEXEC)
|| !ntfs_allowed_access(&security,
ni,accesstype))
res = -EACCES;
}
if (ntfs_inode_close(ni))
@ -954,12 +1093,14 @@ static int ntfs_fuse_open(const char *org_path,
accesstype = S_IWRITE | S_IREAD;
else
accesstype = S_IREAD;
/* JPA directory must be searchable */
/*
* directory must be searchable
* and requested access allowed
*/
if (!ntfs_allowed_dir_access(&security,
path,S_IEXEC)
/* JPA check whether requested access is allowed */
path,(ntfs_inode*)NULL,ni,S_IEXEC)
|| !ntfs_allowed_access(&security,
path,ni,accesstype))
ni,accesstype))
res = -EACCES;
}
#endif
@ -1188,9 +1329,10 @@ static int ntfs_fuse_trunc(const char *org_path, off_t size,
* or cannot write to file (already checked for ftruncate())
*/
if (ntfs_fuse_fill_security_context(&security)
&& (!ntfs_allowed_dir_access(&security, path, S_IEXEC)
&& (!ntfs_allowed_dir_access(&security, path,
(ntfs_inode*)NULL, ni, S_IEXEC)
|| (chkwrite
&& !ntfs_allowed_access(&security, path, ni, S_IWRITE)))) {
&& !ntfs_allowed_access(&security, ni, S_IWRITE)))) {
errno = EACCES;
goto exit;
}
@ -1265,13 +1407,14 @@ static int ntfs_fuse_chmod(const char *path,
} else {
#if POSIXACLS
/* parent directory must be executable */
if (ntfs_allowed_dir_access(&security,path,S_IEXEC)) {
if (ntfs_allowed_dir_access(&security,path,
(ntfs_inode*)NULL,(ntfs_inode*)NULL,S_IEXEC)) {
#endif
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
if (!ni)
res = -errno;
else {
if (ntfs_set_mode(&security,path,ni,mode))
if (ntfs_set_mode(&security,ni,mode))
res = -errno;
else
ntfs_fuse_update_times(ni, NTFS_UPDATE_CTIME);
@ -1307,14 +1450,15 @@ static int ntfs_fuse_chown(const char *path, uid_t uid, gid_t gid)
#if POSIXACLS
/* parent directory must be executable */
if (ntfs_allowed_dir_access(&security,path,S_IEXEC)) {
if (ntfs_allowed_dir_access(&security,path,
(ntfs_inode*)NULL,(ntfs_inode*)NULL,S_IEXEC)) {
#endif
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
if (!ni)
res = -errno;
else {
if (ntfs_set_owner(&security,
path,ni,uid,gid))
ni,uid,gid))
res = -errno;
else
ntfs_fuse_update_times(ni, NTFS_UPDATE_CTIME);
@ -1349,8 +1493,9 @@ static int ntfs_fuse_access(const char *path, int type)
else
res = -EOPNOTSUPP;
} else {
/* parent directory must be readable */
if (ntfs_allowed_dir_access(&security,path,S_IEXEC)) {
/* parent directory must be seachable */
if (ntfs_allowed_dir_access(&security,path,(ntfs_inode*)NULL,
(ntfs_inode*)NULL,S_IEXEC)) {
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
if (!ni) {
res = -errno;
@ -1361,7 +1506,7 @@ static int ntfs_fuse_access(const char *path, int type)
if (type & W_OK) mode += S_IWRITE;
if (type & R_OK) mode += S_IREAD;
if (!ntfs_allowed_access(&security,
path, ni, mode))
ni, mode))
res = -errno;
}
if (ntfs_inode_close(ni))
@ -1419,7 +1564,7 @@ static int ntfs_fuse_create(const char *org_path, mode_t typemode, dev_t dev,
#if POSIXACLS
/* make sure parent directory is writeable and executable */
if (!ntfs_fuse_fill_security_context(&security)
|| ntfs_allowed_access(&security,dir_path,
|| ntfs_allowed_access(&security,
dir_ni,S_IWRITE + S_IEXEC)) {
#else
ntfs_fuse_fill_security_context(&security);
@ -1438,13 +1583,13 @@ static int ntfs_fuse_create(const char *org_path, mode_t typemode, dev_t dev,
securid = 0;
else
if (ctx->inherit)
securid = ntfs_inherited_id(&security, dir_path,
securid = ntfs_inherited_id(&security,
dir_ni, S_ISDIR(type));
else
#if POSIXACLS
securid = ntfs_alloc_securid(&security,
security.uid, security.gid,
dir_path, dir_ni, perm, S_ISDIR(type));
dir_ni, perm, S_ISDIR(type));
#else
securid = ntfs_alloc_securid(&security,
security.uid, security.gid,
@ -1482,7 +1627,7 @@ static int ntfs_fuse_create(const char *org_path, mode_t typemode, dev_t dev,
if (!securid
&& ntfs_set_inherited_posix(&security, ni,
security.uid, security.gid,
dir_path, dir_ni, perm) < 0)
dir_ni, perm) < 0)
set_fuse_error(&res);
#else
if (!securid
@ -1630,6 +1775,7 @@ static int ntfs_fuse_link(const char *old_path, const char *new_path)
char *path;
int res = 0, uname_len;
#if POSIXACLS
BOOL samedir;
struct SECURITY_CONTEXT security;
#endif
@ -1664,10 +1810,13 @@ static int ntfs_fuse_link(const char *old_path, const char *new_path)
}
#if POSIXACLS
samedir = !strncmp(old_path, path, strlen(path))
&& (old_path[strlen(path)] == '/');
/* JPA make sure the parent directories are writeable */
if (ntfs_fuse_fill_security_context(&security)
&& (!ntfs_allowed_dir_access(&security,old_path,S_IWRITE + S_IEXEC)
|| !ntfs_allowed_access(&security,path,dir_ni,S_IWRITE + S_IEXEC)))
&& ((!samedir && !ntfs_allowed_dir_access(&security,old_path,
(ntfs_inode*)NULL,ni,S_IWRITE + S_IEXEC))
|| !ntfs_allowed_access(&security,dir_ni,S_IWRITE + S_IEXEC)))
res = -EACCES;
else
#endif
@ -1734,7 +1883,7 @@ static int ntfs_fuse_rm(const char *org_path)
#if POSIXACLS
/* JPA deny unlinking if directory is not writable and executable */
if (!ntfs_fuse_fill_security_context(&security)
|| ntfs_allowed_dir_access(&security, org_path,
|| ntfs_allowed_dir_access(&security, org_path, dir_ni, ni,
S_IEXEC + S_IWRITE + S_ISVTX)) {
#endif
if (ntfs_delete(ctx->vol, org_path, ni, dir_ni,
@ -1797,8 +1946,10 @@ static int ntfs_fuse_unlink(const char *org_path)
*/
if (!ntfs_fuse_fill_security_context(&security)
|| ntfs_allowed_dir_access(&security, path,
(ntfs_inode*)NULL, (ntfs_inode*)NULL,
S_IEXEC + S_IWRITE + S_ISVTX))
res = ntfs_fuse_rm_stream(path, stream_name, stream_name_len);
res = ntfs_fuse_rm_stream(path, stream_name,
stream_name_len);
else
res = -errno;
#else
@ -1890,6 +2041,7 @@ static int ntfs_fuse_rename_existing_dest(const char *old_path, const char *new_
*/
if (!ntfs_fuse_fill_security_context(&security)
|| ntfs_allowed_dir_access(&security, new_path,
(ntfs_inode*)NULL, (ntfs_inode*)NULL,
S_IEXEC + S_IWRITE + S_ISVTX))
ret = ntfs_fuse_safe_rename(old_path, new_path, tmp);
else
@ -2003,17 +2155,19 @@ static int ntfs_fuse_utime(const char *path, struct utimbuf *buf)
if (ntfs_fuse_is_named_data_stream(path))
return -EINVAL; /* n/a for named data streams. */
#if POSIXACLS
/* parent directory must be executable */
/* parent directory must be executable */
if (ntfs_fuse_fill_security_context(&security)
&& !ntfs_allowed_dir_access(&security,path,S_IEXEC)) {
&& !ntfs_allowed_dir_access(&security,path,
(ntfs_inode*)NULL,(ntfs_inode*)NULL,S_IEXEC)) {
return (-errno);
}
#endif
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
if (!ni)
return -errno;
#if POSIXACLS
ownerok = ntfs_allowed_as_owner(&security, path, ni);
ownerok = ntfs_allowed_as_owner(&security, ni);
if (buf) {
/*
* fuse never calls with a NULL buf and we do not
@ -2023,7 +2177,7 @@ static int ntfs_fuse_utime(const char *path, struct utimbuf *buf)
*/
writeok = !ownerok
&& (buf->actime == buf->modtime)
&& ntfs_allowed_access(&security, path, ni, S_IWRITE);
&& ntfs_allowed_access(&security, ni, S_IWRITE);
/* Must be owner */
if (!ownerok && !writeok)
res = (buf->actime == buf->modtime ? -EACCES : -EPERM);
@ -2035,7 +2189,7 @@ static int ntfs_fuse_utime(const char *path, struct utimbuf *buf)
} else {
/* Must be owner or have write access */
writeok = !ownerok
&& ntfs_allowed_access(&security, path, ni, S_IWRITE);
&& ntfs_allowed_access(&security, ni, S_IWRITE);
if (!ownerok && !writeok)
res = -EACCES;
else
@ -2205,8 +2359,15 @@ static ntfs_inode *ntfs_check_access_xattr(struct SECURITY_CONTEXT *security,
acctype = S_IEXEC | S_IWRITE;
else
acctype = S_IEXEC;
if (ntfs_allowed_dir_access(security,path,acctype)) {
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
if ((attr == XATTR_NTFS_DOS_NAME)
&& !strcmp(path,"/"))
/* forbid getting/setting names on root */
errno = EPERM;
else
if (ntfs_allowed_real_dir_access(security, path,
(ntfs_inode*)NULL ,acctype)) {
ni = ntfs_pathname_to_inode(ctx->vol,
NULL, path);
}
}
}
@ -2317,7 +2478,8 @@ static int ntfs_fuse_listxattr(const char *path, char *list, size_t size)
#if POSIXACLS
/* parent directory must be executable */
if (ntfs_fuse_fill_security_context(&security)
&& !ntfs_allowed_dir_access(&security,path,S_IEXEC)) {
&& !ntfs_allowed_dir_access(&security,path,(ntfs_inode*)NULL,
(ntfs_inode*)NULL,S_IEXEC)) {
return (-errno);
}
#endif
@ -2326,7 +2488,7 @@ static int ntfs_fuse_listxattr(const char *path, char *list, size_t size)
return -errno;
#if POSIXACLS
/* file must be readable */
if (!ntfs_allowed_access(&security,path,ni,S_IREAD)) {
if (!ntfs_allowed_access(&security,ni,S_IREAD)) {
ret = -EACCES;
goto exit;
}
@ -2427,7 +2589,8 @@ static int ntfs_fuse_getxattr_windows(const char *path, const char *name,
#if POSIXACLS
/* parent directory must be executable */
if (ntfs_fuse_fill_security_context(&security)
&& !ntfs_allowed_dir_access(&security,path,S_IEXEC)) {
&& !ntfs_allowed_dir_access(&security,path,(ntfs_inode*)NULL,
(ntfs_inode*)NULL,S_IEXEC)) {
return (-errno);
}
#endif
@ -2435,7 +2598,7 @@ static int ntfs_fuse_getxattr_windows(const char *path, const char *name,
if (!ni)
return -errno;
#if POSIXACLS
if (!ntfs_allowed_access(&security,path,ni,S_IREAD)) {
if (!ntfs_allowed_access(&security,ni,S_IREAD)) {
ret = -errno;
goto exit;
}
@ -2509,9 +2672,9 @@ static int ntfs_fuse_getxattr(const char *path, const char *name,
* mode was selected for xattr (from the user's
* point of view, ACLs are not xattr)
*/
ni = ntfs_check_access_xattr(&security,path,attr,FALSE);
ni = ntfs_check_access_xattr(&security, path, attr, FALSE);
if (ni) {
if (ntfs_allowed_access(&security,path,ni,S_IREAD)) {
if (ntfs_allowed_access(&security,ni,S_IREAD)) {
/*
* the returned value is the needed
* size. If it is too small, no copy
@ -2520,17 +2683,17 @@ static int ntfs_fuse_getxattr(const char *path, const char *name,
*/
switch (attr) {
case XATTR_NTFS_ACL :
res = ntfs_get_ntfs_acl(&security,path,
name,value,size,ni);
res = ntfs_get_ntfs_acl(&security, ni,
value, size);
break;
case XATTR_POSIX_ACC :
case XATTR_POSIX_DEF :
res = ntfs_get_posix_acl(&security,path,
name,value,size,ni);
res = ntfs_get_posix_acl(&security, ni,
name, value, size);
break;
case XATTR_NTFS_ATTRIB :
res = ntfs_get_ntfs_attrib(path,
value,size,ni);
res = ntfs_get_ntfs_attrib(ni,
value, size);
break;
case XATTR_NTFS_EFSINFO :
if (ctx->efs_raw)
@ -2551,7 +2714,13 @@ static int ntfs_fuse_getxattr(const char *path, const char *name,
res = ntfs_inode_get_times(path,
value,size,ni);
break;
default : /* not possible */
default :
/*
* make sure applications do not see
* Posix ACL not consistent with mode
*/
errno = EOPNOTSUPP;
res = -errno;
break;
}
} else {
@ -2582,12 +2751,12 @@ static int ntfs_fuse_getxattr(const char *path, const char *name,
*/
switch (attr) {
case XATTR_NTFS_ACL :
res = ntfs_get_ntfs_acl(&security,path,
name,value,size,ni);
res = ntfs_get_ntfs_acl(&security, ni,
value, size);
break;
case XATTR_NTFS_ATTRIB :
res = ntfs_get_ntfs_attrib(path,
value,size,ni);
res = ntfs_get_ntfs_attrib(ni,
value, size);
break;
case XATTR_NTFS_EFSINFO :
if (ctx->efs_raw)
@ -2635,7 +2804,8 @@ static int ntfs_fuse_getxattr(const char *path, const char *name,
#if POSIXACLS
/* parent directory must be executable */
if (ntfs_fuse_fill_security_context(&security)
&& !ntfs_allowed_dir_access(&security,path,S_IEXEC)) {
&& !ntfs_allowed_dir_access(&security,path,(ntfs_inode*)NULL,
(ntfs_inode*)NULL,S_IEXEC)) {
return (-errno);
}
/* trusted only readable by root */
@ -2648,7 +2818,7 @@ static int ntfs_fuse_getxattr(const char *path, const char *name,
return -errno;
#if POSIXACLS
/* file must be readable */
if (!ntfs_allowed_access(&security, path, ni, S_IREAD)) {
if (!ntfs_allowed_access(&security, ni, S_IREAD)) {
res = -errno;
goto exit;
}
@ -2709,20 +2879,20 @@ static int ntfs_fuse_setxattr(const char *path, const char *name,
*/
ni = ntfs_check_access_xattr(&security,path,attr,TRUE);
if (ni) {
if (ntfs_allowed_as_owner(&security,path,ni)) {
if (ntfs_allowed_as_owner(&security,ni)) {
switch (attr) {
case XATTR_NTFS_ACL :
res = ntfs_set_ntfs_acl(&security,path,
name,value,size,flags,ni);
res = ntfs_set_ntfs_acl(&security, ni,
value, size, flags);
break;
case XATTR_POSIX_ACC :
case XATTR_POSIX_DEF :
res = ntfs_set_posix_acl(&security,path,
name,value,size,flags,ni);
res = ntfs_set_posix_acl(&security, ni,
name, value, size, flags);
break;
case XATTR_NTFS_ATTRIB :
res = ntfs_set_ntfs_attrib(path,
value,size,flags,ni);
res = ntfs_set_ntfs_attrib(ni,
value, size, flags);
break;
case XATTR_NTFS_EFSINFO :
if (ctx->efs_raw)
@ -2744,7 +2914,13 @@ static int ntfs_fuse_setxattr(const char *path, const char *name,
res = ntfs_inode_set_times(path,
value,size,flags,ni);
break;
default : /* not possible */
default :
/*
* make sure applications do not see
* Posix ACL not consistent with mode
*/
errno = EOPNOTSUPP;
res = -errno;
break;
}
if (res)
@ -2776,15 +2952,15 @@ static int ntfs_fuse_setxattr(const char *path, const char *name,
* if defined, only owner is allowed
*/
if (!ntfs_fuse_fill_security_context(&security)
|| ntfs_allowed_as_owner(&security,path,ni)) {
|| ntfs_allowed_as_owner(&security, ni)) {
switch (attr) {
case XATTR_NTFS_ACL :
res = ntfs_set_ntfs_acl(&security,path,
name,value,size,flags,ni);
res = ntfs_set_ntfs_acl(&security, ni,
value, size, flags);
break;
case XATTR_NTFS_ATTRIB :
res = ntfs_set_ntfs_attrib(path,
value,size,flags,ni);
res = ntfs_set_ntfs_attrib(ni,
value, size, flags);
break;
case XATTR_NTFS_EFSINFO :
if (ctx->efs_raw)
@ -2837,7 +3013,8 @@ static int ntfs_fuse_setxattr(const char *path, const char *name,
#if POSIXACLS
/* parent directory must be executable */
if (ntfs_fuse_fill_security_context(&security)
&& !ntfs_allowed_dir_access(&security,path,S_IEXEC)) {
&& !ntfs_allowed_dir_access(&security,path,(ntfs_inode*)NULL,
(ntfs_inode*)NULL,S_IEXEC)) {
return (-errno);
}
/* security and trusted only settable by root */
@ -2859,13 +3036,13 @@ static int ntfs_fuse_setxattr(const char *path, const char *name,
}
break;
case XATTRNS_SYSTEM :
if (!ntfs_allowed_as_owner(&security,path,ni)) {
if (!ntfs_allowed_as_owner(&security,ni)) {
res = -EACCES;
goto exit;
}
break;
default :
if (!ntfs_allowed_access(&security,path,ni,S_IWRITE)) {
if (!ntfs_allowed_access(&security,ni,S_IWRITE)) {
res = -EACCES;
goto exit;
}
@ -2968,9 +3145,9 @@ static int ntfs_fuse_removexattr(const char *path, const char *name)
case XATTR_POSIX_DEF :
ni = ntfs_check_access_xattr(&security,path,attr,TRUE);
if (ni) {
if (!ntfs_allowed_as_owner(&security,path,ni)
|| ntfs_remove_posix_acl(&security,path,
name,ni))
if (!ntfs_allowed_as_owner(&security, ni)
|| ntfs_remove_posix_acl(&security, ni,
name))
res = -errno;
if (ntfs_inode_close(ni))
set_fuse_error(&res);
@ -2980,7 +3157,7 @@ static int ntfs_fuse_removexattr(const char *path, const char *name)
case XATTR_NTFS_REPARSE_DATA :
ni = ntfs_check_access_xattr(&security,path,attr,TRUE);
if (ni) {
if (!ntfs_allowed_as_owner(&security,path,ni)
if (!ntfs_allowed_as_owner(&security, ni)
|| ntfs_remove_ntfs_reparse_data(path,ni))
res = -errno;
if (ntfs_inode_close(ni))
@ -3030,7 +3207,7 @@ static int ntfs_fuse_removexattr(const char *path, const char *name)
* if defined, only owner is allowed
*/
if ((ntfs_fuse_fill_security_context(&security)
&& !ntfs_allowed_as_owner(&security,path,ni))
&& !ntfs_allowed_as_owner(&security, ni))
|| ntfs_remove_ntfs_reparse_data(path,ni))
res = -errno;
if (ntfs_inode_close(ni))
@ -3068,7 +3245,8 @@ static int ntfs_fuse_removexattr(const char *path, const char *name)
#if POSIXACLS
/* parent directory must be executable */
if (ntfs_fuse_fill_security_context(&security)
&& !ntfs_allowed_dir_access(&security,path,S_IEXEC)) {
&& !ntfs_allowed_dir_access(&security,path,(ntfs_inode*)NULL,
(ntfs_inode*)NULL,S_IEXEC)) {
return (-errno);
}
/* security and trusted only settable by root */
@ -3090,13 +3268,13 @@ static int ntfs_fuse_removexattr(const char *path, const char *name)
}
break;
case XATTRNS_SYSTEM :
if (!ntfs_allowed_as_owner(&security,path,ni)) {
if (!ntfs_allowed_as_owner(&security,ni)) {
res = -EACCES;
goto exit;
}
break;
default :
if (!ntfs_allowed_access(&security,path,ni,S_IWRITE)) {
if (!ntfs_allowed_access(&security,ni,S_IWRITE)) {
res = -EACCES;
goto exit;
}