diff --git a/src/add-ons/kernel/file_systems/xfs/Inode.cpp b/src/add-ons/kernel/file_systems/xfs/Inode.cpp index ed2cd0752d..ec2e9d9831 100644 --- a/src/add-ons/kernel/file_systems/xfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/xfs/Inode.cpp @@ -181,6 +181,18 @@ Inode::HasFileTypeField() const } +status_t +Inode::CheckPermissions(int accessMode) const +{ + // you never have write access to a read-only volume + if ((accessMode & W_OK) != 0 && fVolume->IsReadOnly()) + return B_READ_ONLY_DEVICE; + + return check_access_permissions(accessMode, Mode(), + (uint32)fNode->GroupId(), (uint32)fNode->UserId()); +} + + status_t Inode::GetFromDisk() { diff --git a/src/add-ons/kernel/file_systems/xfs/Inode.h b/src/add-ons/kernel/file_systems/xfs/Inode.h index 51f6a97daa..648db9db25 100644 --- a/src/add-ons/kernel/file_systems/xfs/Inode.h +++ b/src/add-ons/kernel/file_systems/xfs/Inode.h @@ -189,6 +189,7 @@ public: void GetAccessTime(struct timespec& timestamp) const { fNode->GetAccessTime(timestamp); } + status_t CheckPermissions(int accessMode) const; uint32 UserId() const { return fNode->UserId(); } uint32 GroupId() const { return fNode->GroupId(); } bool HasFileTypeField() const; diff --git a/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp index b149edcebf..5b7558806b 100644 --- a/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp @@ -211,14 +211,16 @@ xfs_lookup(fs_volume *_volume, fs_vnode *_directory, const char *name, if (!directory->IsDirectory()) return B_NOT_A_DIRECTORY; - //TODO: pretend everything is accessible. We should actually checking - //for permission here. + status_t status = directory->CheckPermissions(X_OK); + if (status < B_OK) + return status; + DirectoryIterator* iterator = new(std::nothrow) DirectoryIterator(directory); if (iterator == NULL) return B_NO_MEMORY; - status_t status = iterator->Init(); + status = iterator->Init(); if (status != B_OK) { delete iterator; return status; @@ -308,9 +310,8 @@ xfs_free_cookie(fs_volume *_volume, fs_vnode *_node, void *_cookie) static status_t xfs_access(fs_volume *_volume, fs_vnode *_node, int accessMode) { - //TODO: pretend everything is accessible. We should actually checking - //for permission here. - return B_OK; + Inode* inode = (Inode*)_node->private_node; + return inode->CheckPermissions(accessMode); } @@ -353,6 +354,10 @@ xfs_open_dir(fs_volume * /*_volume*/, fs_vnode *_node, void **_cookie) Inode* inode = (Inode*)_node->private_node; TRACE("XFS_OPEN_DIR: (%ld)\n", inode->ID()); + status_t status = inode->CheckPermissions(R_OK); + if (status < B_OK) + return status; + if (!inode->IsDirectory()) return B_NOT_A_DIRECTORY; @@ -361,7 +366,7 @@ xfs_open_dir(fs_volume * /*_volume*/, fs_vnode *_node, void **_cookie) delete iterator; return B_NO_MEMORY; } - status_t status = iterator->Init(); + status = iterator->Init(); *_cookie = iterator; return status; }