mirror of
https://git.code.sf.net/p/ntfs-3g/ntfs-3g.git
synced 2024-11-27 03:53:48 +08:00
Simplified interfaces for checking permissions
This commit is contained in:
parent
bae437d845
commit
c5c51ec1fe
@ -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
|
||||
|
@ -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,
|
||||
|
336
src/ntfs-3g.c
336
src/ntfs-3g.c
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user