1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-16 10:24:59 +00:00

Add chown() syscall and a simple /bin/chown program.

This commit is contained in:
Andreas Kling 2019-02-27 12:32:53 +01:00
parent 711e2b2651
commit 1d2529b4a1
19 changed files with 130 additions and 5 deletions

View file

@ -300,6 +300,7 @@ KResult VFS::chmod(const String& path, mode_t mode, Inode& base)
if (inode->fs().is_readonly())
return KResult(-EROFS);
// FIXME: Superuser should always be allowed to chmod.
if (current->euid() != inode->metadata().uid)
return KResult(-EPERM);
@ -310,6 +311,37 @@ KResult VFS::chmod(const String& path, mode_t mode, Inode& base)
return inode->chmod(mode);
}
KResult VFS::chown(const String& path, uid_t a_uid, gid_t a_gid, Inode& base)
{
auto inode_or_error = resolve_path_to_inode(path, base);
if (inode_or_error.is_error())
return inode_or_error.error();
auto inode = inode_or_error.value();
if (inode->fs().is_readonly())
return KResult(-EROFS);
if (current->euid() != inode->metadata().uid && !current->is_superuser())
return KResult(-EPERM);
uid_t new_uid = inode->metadata().uid;
gid_t new_gid = inode->metadata().gid;
if (a_uid != (uid_t)-1) {
if (current->euid() != a_uid && !current->is_superuser())
return KResult(-EPERM);
new_uid = a_uid;
}
if (a_gid != (gid_t)-1) {
if (!current->in_group(a_gid) && !current->is_superuser())
return KResult(-EPERM);
new_gid = a_gid;
}
dbgprintf("VFS::chown(): inode %u:%u <- uid:%d, gid:%d\n", inode->fsid(), inode->index(), new_uid, new_gid);
return inode->chown(new_uid, new_gid);
}
KResultOr<RetainPtr<Inode>> VFS::resolve_path_to_inode(const String& path, Inode& base, RetainPtr<Inode>* parent_inode)
{
// FIXME: This won't work nicely across mount boundaries.