vfs/{b|btr|package|b}fs/ext2/exfat: common access check.
* Added VFS helper function check_access_permissions() that combines several partially correct versions to the one true version (tm). * All but BFS (since recently) missed the S_IXOTH for root on directories, and all but packagefs missed proper group handling.
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2010, Haiku Inc. All Rights Reserved.
|
* Copyright 2004-2014, Haiku Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _FS_INTERFACE_H
|
#ifndef _FS_INTERFACE_H
|
||||||
#define _FS_INTERFACE_H
|
#define _FS_INTERFACE_H
|
||||||
|
|
||||||
|
|
||||||
/*! File System Interface Layer Definition */
|
/*! File System Interface Layer Definition */
|
||||||
|
|
||||||
|
|
||||||
@@ -330,6 +331,8 @@ extern status_t unremove_vnode(fs_volume* volume, ino_t vnodeID);
|
|||||||
extern status_t get_vnode_removed(fs_volume* volume, ino_t vnodeID,
|
extern status_t get_vnode_removed(fs_volume* volume, ino_t vnodeID,
|
||||||
bool* _removed);
|
bool* _removed);
|
||||||
extern fs_volume* volume_for_vnode(fs_vnode* vnode);
|
extern fs_volume* volume_for_vnode(fs_vnode* vnode);
|
||||||
|
extern status_t check_access_permissions(int accessMode, mode_t mode,
|
||||||
|
gid_t nodeGroupID, uid_t nodeUserID);
|
||||||
|
|
||||||
extern status_t read_pages(int fd, off_t pos, const struct iovec* vecs,
|
extern status_t read_pages(int fd, off_t pos, const struct iovec* vecs,
|
||||||
size_t count, size_t* _numBytes);
|
size_t count, size_t* _numBytes);
|
||||||
|
|||||||
@@ -506,37 +506,8 @@ Inode::CheckPermissions(int accessMode) const
|
|||||||
if ((accessMode & W_OK) != 0 && fVolume->IsReadOnly())
|
if ((accessMode & W_OK) != 0 && fVolume->IsReadOnly())
|
||||||
return B_READ_ONLY_DEVICE;
|
return B_READ_ONLY_DEVICE;
|
||||||
|
|
||||||
// get node permissions
|
return check_access_permissions(accessMode, Mode(), (gid_t)fNode.GroupID(),
|
||||||
mode_t mode = Mode();
|
(uid_t)fNode.UserID());
|
||||||
int userPermissions = (mode & S_IRWXU) >> 6;
|
|
||||||
int groupPermissions = (mode & S_IRWXG) >> 3;
|
|
||||||
int otherPermissions = mode & S_IRWXO;
|
|
||||||
|
|
||||||
// get the node permissions for this uid/gid
|
|
||||||
int permissions = 0;
|
|
||||||
uid_t uid = geteuid();
|
|
||||||
gid_t gid = getegid();
|
|
||||||
|
|
||||||
if (uid == 0) {
|
|
||||||
// user is root
|
|
||||||
// root has always read/write permission, but at least one of the
|
|
||||||
// X bits must be set for execute permission
|
|
||||||
permissions = userPermissions | groupPermissions | otherPermissions
|
|
||||||
| R_OK | W_OK;
|
|
||||||
if (IsDirectory())
|
|
||||||
permissions |= X_OK;
|
|
||||||
} else if (uid == (uid_t)fNode.UserID()) {
|
|
||||||
// user is node owner
|
|
||||||
permissions = userPermissions;
|
|
||||||
} else if (gid == (gid_t)fNode.GroupID()) {
|
|
||||||
// user is in owning group
|
|
||||||
permissions = groupPermissions;
|
|
||||||
} else {
|
|
||||||
// user is one of the others
|
|
||||||
permissions = otherPermissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (accessMode & ~permissions) == 0 ? B_OK : B_NOT_ALLOWED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
||||||
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2008-2014, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Copyright 2005-2007, Ingo Weinhold, bonefish@cs.tu-berlin.de.
|
* Copyright 2005-2007, Ingo Weinhold, bonefish@cs.tu-berlin.de.
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -104,35 +104,8 @@ Inode::CheckPermissions(int accessMode) const
|
|||||||
if ((accessMode & W_OK) != 0 && fVolume->IsReadOnly())
|
if ((accessMode & W_OK) != 0 && fVolume->IsReadOnly())
|
||||||
return B_READ_ONLY_DEVICE;
|
return B_READ_ONLY_DEVICE;
|
||||||
|
|
||||||
// get node permissions
|
return check_access_permissions(accessMode, Mode(), (gid_t)fNode.GroupID(),
|
||||||
mode_t mode = Mode();
|
(uid_t)fNode.UserID());
|
||||||
int userPermissions = (mode & S_IRWXU) >> 6;
|
|
||||||
int groupPermissions = (mode & S_IRWXG) >> 3;
|
|
||||||
int otherPermissions = mode & S_IRWXO;
|
|
||||||
|
|
||||||
// get the node permissions for this uid/gid
|
|
||||||
int permissions = 0;
|
|
||||||
uid_t uid = geteuid();
|
|
||||||
gid_t gid = getegid();
|
|
||||||
|
|
||||||
if (uid == 0) {
|
|
||||||
// user is root
|
|
||||||
// root has always read/write permission, but at least one of the
|
|
||||||
// X bits must be set for execute permission
|
|
||||||
permissions = userPermissions | groupPermissions | otherPermissions
|
|
||||||
| R_OK | W_OK;
|
|
||||||
} else if (uid == (uid_t)fNode.UserID()) {
|
|
||||||
// user is node owner
|
|
||||||
permissions = userPermissions;
|
|
||||||
} else if (gid == (gid_t)fNode.GroupID()) {
|
|
||||||
// user is in owning group
|
|
||||||
permissions = groupPermissions;
|
|
||||||
} else {
|
|
||||||
// user is one of the others
|
|
||||||
permissions = otherPermissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (accessMode & ~permissions) == 0 ? B_OK : B_NOT_ALLOWED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -162,12 +135,12 @@ Inode::FindBlock(off_t pos, off_t& physical, off_t *_length)
|
|||||||
logical = diff + extent_data->disk_offset;
|
logical = diff + extent_data->disk_offset;
|
||||||
else
|
else
|
||||||
panic("unknown extent type; %d\n", extent_data->Type());
|
panic("unknown extent type; %d\n", extent_data->Type());
|
||||||
status = fVolume->FindBlock(logical, physical);
|
status = fVolume->FindBlock(logical, physical);
|
||||||
if (_length != NULL)
|
if (_length != NULL)
|
||||||
*_length = extent_data->Size() - diff;
|
*_length = extent_data->Size() - diff;
|
||||||
TRACE("Inode::FindBlock(%" B_PRIdINO ") %" B_PRIdOFF " physical %"
|
TRACE("Inode::FindBlock(%" B_PRIdINO ") %" B_PRIdOFF " physical %"
|
||||||
B_PRIdOFF "\n", ID(), pos, physical);
|
B_PRIdOFF "\n", ID(), pos, physical);
|
||||||
|
|
||||||
free(extent_data);
|
free(extent_data);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -180,7 +153,7 @@ Inode::ReadAt(off_t pos, uint8* buffer, size_t* _length)
|
|||||||
|
|
||||||
// set/check boundaries for pos/length
|
// set/check boundaries for pos/length
|
||||||
if (pos < 0) {
|
if (pos < 0) {
|
||||||
ERROR("inode %" B_PRIdINO ": ReadAt failed(pos %" B_PRIdOFF
|
ERROR("inode %" B_PRIdINO ": ReadAt failed(pos %" B_PRIdOFF
|
||||||
", length %lu)\n", ID(), pos, length);
|
", length %lu)\n", ID(), pos, length);
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
@@ -212,7 +185,7 @@ Inode::ReadAt(off_t pos, uint8* buffer, size_t* _length)
|
|||||||
uint8 compression = extent_data->Compression();
|
uint8 compression = extent_data->Compression();
|
||||||
if (FileCache() != NULL
|
if (FileCache() != NULL
|
||||||
&& extent_data->Type() == BTRFS_EXTENT_DATA_REGULAR) {
|
&& extent_data->Type() == BTRFS_EXTENT_DATA_REGULAR) {
|
||||||
TRACE("inode %" B_PRIdINO ": ReadAt cache (pos %" B_PRIdOFF ", length %lu)\n",
|
TRACE("inode %" B_PRIdINO ": ReadAt cache (pos %" B_PRIdOFF ", length %lu)\n",
|
||||||
ID(), pos, length);
|
ID(), pos, length);
|
||||||
free(extent_data);
|
free(extent_data);
|
||||||
if (compression == BTRFS_EXTENT_COMPRESS_NONE)
|
if (compression == BTRFS_EXTENT_COMPRESS_NONE)
|
||||||
@@ -313,7 +286,7 @@ Inode::ReadAt(off_t pos, uint8* buffer, size_t* _length)
|
|||||||
panic("unknown extent compression; %d\n", compression);
|
panic("unknown extent compression; %d\n", compression);
|
||||||
free(extent_data);
|
free(extent_data);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -336,7 +309,7 @@ Inode::FindParent(ino_t *id)
|
|||||||
*id = search_key.Offset();
|
*id = search_key.Offset();
|
||||||
TRACE("Inode::FindParent() for %" B_PRIdINO ": %" B_PRIdINO "\n", fID,
|
TRACE("Inode::FindParent() for %" B_PRIdINO ": %" B_PRIdINO "\n", fID,
|
||||||
*id);
|
*id);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
||||||
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2008-2014, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -157,36 +157,8 @@ Inode::CheckPermissions(int accessMode) const
|
|||||||
if ((accessMode & W_OK) != 0 && fVolume->IsReadOnly())
|
if ((accessMode & W_OK) != 0 && fVolume->IsReadOnly())
|
||||||
return B_READ_ONLY_DEVICE;
|
return B_READ_ONLY_DEVICE;
|
||||||
|
|
||||||
// get node permissions
|
return check_access_permissions(accessMode, Mode(), (gid_t)GroupID(),
|
||||||
mode_t mode = Mode();
|
(uid_t)UserID());
|
||||||
int userPermissions = (mode & S_IRWXU) >> 6;
|
|
||||||
int groupPermissions = (mode & S_IRWXG) >> 3;
|
|
||||||
int otherPermissions = mode & S_IRWXO;
|
|
||||||
|
|
||||||
// get the node permissions for this uid/gid
|
|
||||||
int permissions = 0;
|
|
||||||
uid_t uid = geteuid();
|
|
||||||
gid_t gid = getegid();
|
|
||||||
|
|
||||||
if (uid == 0) {
|
|
||||||
// user is root
|
|
||||||
// root has always read/write permission, but at least one of the
|
|
||||||
// X bits must be set for execute permission
|
|
||||||
permissions = userPermissions | groupPermissions | otherPermissions
|
|
||||||
| R_OK | W_OK;
|
|
||||||
} else if (uid == (uid_t)UserID()) {
|
|
||||||
// user is node owner
|
|
||||||
permissions = userPermissions;
|
|
||||||
} else if (gid == (gid_t)GroupID()) {
|
|
||||||
// user is in owning group
|
|
||||||
permissions = groupPermissions;
|
|
||||||
} else {
|
|
||||||
// user is one of the others
|
|
||||||
permissions = otherPermissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (accessMode & ~permissions) == 0 ? B_OK : B_NOT_ALLOWED;
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -217,7 +189,7 @@ Inode::ReadAt(off_t pos, uint8* buffer, size_t* _length)
|
|||||||
return B_NO_ERROR;
|
return B_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return file_cache_read(FileCache(), NULL, pos, buffer, _length);
|
return file_cache_read(FileCache(), NULL, pos, buffer, _length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
||||||
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2008-2014, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -186,35 +186,8 @@ Inode::CheckPermissions(int accessMode) const
|
|||||||
if ((accessMode & W_OK) != 0 && fVolume->IsReadOnly())
|
if ((accessMode & W_OK) != 0 && fVolume->IsReadOnly())
|
||||||
return B_READ_ONLY_DEVICE;
|
return B_READ_ONLY_DEVICE;
|
||||||
|
|
||||||
// get node permissions
|
return check_access_permissions(accessMode, Mode(), (gid_t)fNode.GroupID(),
|
||||||
mode_t mode = Mode();
|
(uid_t)fNode.UserID());
|
||||||
int userPermissions = (mode & S_IRWXU) >> 6;
|
|
||||||
int groupPermissions = (mode & S_IRWXG) >> 3;
|
|
||||||
int otherPermissions = mode & S_IRWXO;
|
|
||||||
|
|
||||||
// get the node permissions for this uid/gid
|
|
||||||
int permissions = 0;
|
|
||||||
uid_t uid = geteuid();
|
|
||||||
gid_t gid = getegid();
|
|
||||||
|
|
||||||
if (uid == 0) {
|
|
||||||
// user is root
|
|
||||||
// root has always read/write permission, but at least one of the
|
|
||||||
// X bits must be set for execute permission
|
|
||||||
permissions = userPermissions | groupPermissions | otherPermissions
|
|
||||||
| R_OK | W_OK;
|
|
||||||
} else if (uid == (uid_t)fNode.UserID()) {
|
|
||||||
// user is node owner
|
|
||||||
permissions = userPermissions;
|
|
||||||
} else if (gid == (gid_t)fNode.GroupID()) {
|
|
||||||
// user is in owning group
|
|
||||||
permissions = groupPermissions;
|
|
||||||
} else {
|
|
||||||
// user is one of the others
|
|
||||||
permissions = otherPermissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (accessMode & ~permissions) == 0 ? B_OK : B_NOT_ALLOWED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,20 +36,6 @@ static const uint32 kOptimalIOSize = 64 * 1024;
|
|||||||
// #pragma mark - helper functions
|
// #pragma mark - helper functions
|
||||||
|
|
||||||
|
|
||||||
static bool
|
|
||||||
is_user_in_group(gid_t gid)
|
|
||||||
{
|
|
||||||
gid_t groups[NGROUPS_MAX];
|
|
||||||
int groupCount = getgroups(NGROUPS_MAX, groups);
|
|
||||||
for (int i = 0; i < groupCount; i++) {
|
|
||||||
if (gid == groups[i])
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (gid == getegid());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
check_access(Node* node, int mode)
|
check_access(Node* node, int mode)
|
||||||
{
|
{
|
||||||
@@ -57,33 +43,8 @@ check_access(Node* node, int mode)
|
|||||||
if (mode & W_OK)
|
if (mode & W_OK)
|
||||||
return B_READ_ONLY_DEVICE;
|
return B_READ_ONLY_DEVICE;
|
||||||
|
|
||||||
// get node permissions
|
return check_access_permissions(mode, node->Mode(), node->GroupID(),
|
||||||
int userPermissions = (node->Mode() & S_IRWXU) >> 6;
|
node->UserID());
|
||||||
int groupPermissions = (node->Mode() & S_IRWXG) >> 3;
|
|
||||||
int otherPermissions = node->Mode() & S_IRWXO;
|
|
||||||
|
|
||||||
// get the permissions for this uid/gid
|
|
||||||
int permissions = 0;
|
|
||||||
uid_t uid = geteuid();
|
|
||||||
|
|
||||||
if (uid == 0) {
|
|
||||||
// user is root
|
|
||||||
// root has always read/write permission, but at least one of the
|
|
||||||
// X bits must be set for execute permission
|
|
||||||
permissions = userPermissions | groupPermissions | otherPermissions
|
|
||||||
| S_IROTH | S_IWOTH;
|
|
||||||
} else if (uid == node->UserID()) {
|
|
||||||
// user is node owner
|
|
||||||
permissions = userPermissions;
|
|
||||||
} else if (is_user_in_group(node->GroupID())) {
|
|
||||||
// user is in owning group
|
|
||||||
permissions = groupPermissions;
|
|
||||||
} else {
|
|
||||||
// user is one of the others
|
|
||||||
permissions = otherPermissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (mode & ~permissions) == 0 ? B_OK : B_NOT_ALLOWED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,9 +54,6 @@ extern fs_volume_ops gReiserFSVolumeOps;
|
|||||||
extern fs_vnode_ops gReiserFSVnodeOps;
|
extern fs_vnode_ops gReiserFSVnodeOps;
|
||||||
|
|
||||||
|
|
||||||
inline static bool is_user_in_group(gid_t gid);
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - FS
|
// #pragma mark - FS
|
||||||
|
|
||||||
|
|
||||||
@@ -307,41 +304,19 @@ static status_t
|
|||||||
reiserfs_access(fs_volume *fs, fs_vnode *_node, int mode)
|
reiserfs_access(fs_volume *fs, fs_vnode *_node, int mode)
|
||||||
{
|
{
|
||||||
TOUCH(fs);
|
TOUCH(fs);
|
||||||
// FUNCTION_START();
|
|
||||||
// Volume *volume = (Volume*)fs->private_volume;
|
|
||||||
VNode *node = (VNode*)_node->private_node;
|
VNode *node = (VNode*)_node->private_node;
|
||||||
FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(),
|
FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(),
|
||||||
node->GetObjectID()));
|
node->GetObjectID()));
|
||||||
|
|
||||||
// write access requested?
|
// write access requested?
|
||||||
if (mode & W_OK)
|
if (mode & W_OK)
|
||||||
return B_READ_ONLY_DEVICE;
|
return B_READ_ONLY_DEVICE;
|
||||||
|
|
||||||
// get node permissions
|
// get node permissions
|
||||||
StatData *statData = node->GetStatData();
|
StatData *statData = node->GetStatData();
|
||||||
int userPermissions = (statData->GetMode() & S_IRWXU) >> 6;
|
|
||||||
int groupPermissions = (statData->GetMode() & S_IRWXG) >> 3;
|
return check_access_permissions(mode, statData->GetMode(),
|
||||||
int otherPermissions = statData->GetMode() & S_IRWXO;
|
statData->GetGID(), statData->GetUID());
|
||||||
// get the permissions for this uid/gid
|
|
||||||
int permissions = 0;
|
|
||||||
uid_t uid = geteuid();
|
|
||||||
// user is root
|
|
||||||
if (uid == 0) {
|
|
||||||
// root has always read/write permission, but at least one of the
|
|
||||||
// X bits must be set for execute permission
|
|
||||||
permissions = userPermissions | groupPermissions | otherPermissions
|
|
||||||
| S_IROTH | S_IWOTH;
|
|
||||||
// user is node owner
|
|
||||||
} else if (uid == statData->GetUID())
|
|
||||||
permissions = userPermissions;
|
|
||||||
// user is in owning group
|
|
||||||
else if (is_user_in_group(statData->GetGID()))
|
|
||||||
permissions = groupPermissions;
|
|
||||||
// user is one of the others
|
|
||||||
else
|
|
||||||
permissions = otherPermissions;
|
|
||||||
// do the check
|
|
||||||
if (mode & ~permissions)
|
|
||||||
return B_NOT_ALLOWED;
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reiserfs_read_stat
|
// reiserfs_read_stat
|
||||||
@@ -465,23 +440,7 @@ reiserfs_read(fs_volume *fs, fs_vnode *_node, void *cookie, off_t pos,
|
|||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// is_user_in_group
|
|
||||||
inline static bool
|
|
||||||
is_user_in_group(gid_t gid)
|
|
||||||
{
|
|
||||||
// Either I miss something, or we don't have getgroups() in the kernel. :-(
|
|
||||||
/*
|
|
||||||
gid_t groups[NGROUPS_MAX];
|
|
||||||
int groupCount = getgroups(NGROUPS_MAX, groups);
|
|
||||||
for (int i = 0; i < groupCount; i++) {
|
|
||||||
if (gid == groups[i])
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return (gid == getegid());
|
|
||||||
}
|
|
||||||
|
|
||||||
// DirectoryCookie
|
|
||||||
class DirectoryCookie : public DirEntryIterator {
|
class DirectoryCookie : public DirEntryIterator {
|
||||||
public:
|
public:
|
||||||
DirectoryCookie(Tree *tree, uint32 dirID, uint32 objectID,
|
DirectoryCookie(Tree *tree, uint32 dirID, uint32 objectID,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
* Copyright 2005-2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
* Copyright 2002-2011, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2002-2014, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||||
@@ -3591,6 +3591,23 @@ common_file_io_vec_pages(struct vnode* vnode, void* cookie,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_user_in_group(gid_t gid)
|
||||||
|
{
|
||||||
|
if (gid == getegid())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
gid_t groups[NGROUPS_MAX];
|
||||||
|
int groupCount = getgroups(NGROUPS_MAX, groups);
|
||||||
|
for (int i = 0; i < groupCount; i++) {
|
||||||
|
if (gid == groups[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - public API for file systems
|
// #pragma mark - public API for file systems
|
||||||
|
|
||||||
|
|
||||||
@@ -3876,6 +3893,42 @@ volume_for_vnode(fs_vnode* _vnode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" status_t
|
||||||
|
check_access_permissions(int accessMode, mode_t mode, gid_t nodeGroupID,
|
||||||
|
uid_t nodeUserID)
|
||||||
|
{
|
||||||
|
// get node permissions
|
||||||
|
int userPermissions = (mode & S_IRWXU) >> 6;
|
||||||
|
int groupPermissions = (mode & S_IRWXG) >> 3;
|
||||||
|
int otherPermissions = mode & S_IRWXO;
|
||||||
|
|
||||||
|
// get the node permissions for this uid/gid
|
||||||
|
int permissions = 0;
|
||||||
|
uid_t uid = geteuid();
|
||||||
|
|
||||||
|
if (uid == 0) {
|
||||||
|
// user is root
|
||||||
|
// root has always read/write permission, but at least one of the
|
||||||
|
// X bits must be set for execute permission
|
||||||
|
permissions = userPermissions | groupPermissions | otherPermissions
|
||||||
|
| S_IROTH | S_IWOTH;
|
||||||
|
if (S_ISDIR(mode))
|
||||||
|
permissions |= S_IXOTH;
|
||||||
|
} else if (uid == nodeUserID) {
|
||||||
|
// user is node owner
|
||||||
|
permissions = userPermissions;
|
||||||
|
} else if (is_user_in_group(nodeGroupID)) {
|
||||||
|
// user is in owning group
|
||||||
|
permissions = groupPermissions;
|
||||||
|
} else {
|
||||||
|
// user is one of the others
|
||||||
|
permissions = otherPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (accessMode & ~permissions) == 0 ? B_OK : B_NOT_ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
extern "C" status_t
|
extern "C" status_t
|
||||||
read_pages(int fd, off_t pos, const iovec* vecs, size_t count,
|
read_pages(int fd, off_t pos, const iovec* vecs, size_t count,
|
||||||
|
|||||||
Reference in New Issue
Block a user