mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-30 00:31:14 +00:00
Kernel+LibC+LibCore: Add lchown and fchownat functions
This modifies sys$chown to allow specifying whether or not to follow symlinks and in which directory. This was then used to implement lchown and fchownat in LibC and LibCore.
This commit is contained in:
parent
344cfa0db4
commit
63760603f3
Notes:
sideshowbarker
2024-07-17 21:50:39 +09:00
Author: https://github.com/circl-lastname 🔰 Commit: https://github.com/SerenityOS/serenity/commit/63760603f3a Pull-request: https://github.com/SerenityOS/serenity/pull/11522 Reviewed-by: https://github.com/ADKaster
|
@ -400,6 +400,8 @@ struct SC_chown_params {
|
|||
StringArgument path;
|
||||
u32 uid;
|
||||
u32 gid;
|
||||
int dirfd;
|
||||
int follow_symlinks;
|
||||
};
|
||||
|
||||
struct SC_mknod_params {
|
||||
|
|
|
@ -564,9 +564,9 @@ ErrorOr<void> VirtualFileSystem::chown(Custody& custody, UserID a_uid, GroupID a
|
|||
return inode.chown(new_uid, new_gid);
|
||||
}
|
||||
|
||||
ErrorOr<void> VirtualFileSystem::chown(StringView path, UserID a_uid, GroupID a_gid, Custody& base)
|
||||
ErrorOr<void> VirtualFileSystem::chown(StringView path, UserID a_uid, GroupID a_gid, Custody& base, int options)
|
||||
{
|
||||
auto custody = TRY(resolve_path(path, base));
|
||||
auto custody = TRY(resolve_path(path, base, nullptr, options));
|
||||
return chown(custody, a_uid, a_gid);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
ErrorOr<void> rmdir(StringView path, Custody& base);
|
||||
ErrorOr<void> chmod(StringView path, mode_t, Custody& base);
|
||||
ErrorOr<void> chmod(Custody&, mode_t);
|
||||
ErrorOr<void> chown(StringView path, UserID, GroupID, Custody& base);
|
||||
ErrorOr<void> chown(StringView path, UserID, GroupID, Custody& base, int options);
|
||||
ErrorOr<void> chown(Custody&, UserID, GroupID);
|
||||
ErrorOr<void> access(StringView path, int mode, Custody& base);
|
||||
ErrorOr<InodeMetadata> lookup_metadata(StringView path, Custody& base, int options = 0);
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/NonnullRefPtrVector.h>
|
||||
#include <Kernel/FileSystem/Custody.h>
|
||||
#include <Kernel/FileSystem/OpenFileDescription.h>
|
||||
#include <Kernel/Process.h>
|
||||
|
||||
|
@ -24,7 +26,18 @@ ErrorOr<FlatPtr> Process::sys$chown(Userspace<const Syscall::SC_chown_params*> u
|
|||
TRY(require_promise(Pledge::chown));
|
||||
auto params = TRY(copy_typed_from_user(user_params));
|
||||
auto path = TRY(get_syscall_path_argument(params.path));
|
||||
TRY(VirtualFileSystem::the().chown(path->view(), params.uid, params.gid, current_directory()));
|
||||
|
||||
RefPtr<Custody> base;
|
||||
if (params.dirfd == AT_FDCWD) {
|
||||
base = current_directory();
|
||||
} else {
|
||||
auto base_description = TRY(fds().open_file_description(params.dirfd));
|
||||
if (!base_description->custody())
|
||||
return EINVAL;
|
||||
base = base_description->custody();
|
||||
}
|
||||
|
||||
TRY(VirtualFileSystem::the().chown(path->view(), params.uid, params.gid, *base, params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,13 +38,24 @@ static __thread int s_cached_tid = 0;
|
|||
|
||||
static int s_cached_pid = 0;
|
||||
|
||||
int lchown(const char* pathname, uid_t uid, gid_t gid)
|
||||
{
|
||||
if (!pathname) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
Syscall::SC_chown_params params { { pathname, strlen(pathname) }, uid, gid, AT_FDCWD, false };
|
||||
int rc = syscall(SC_chown, ¶ms);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int chown(const char* pathname, uid_t uid, gid_t gid)
|
||||
{
|
||||
if (!pathname) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
Syscall::SC_chown_params params { { pathname, strlen(pathname) }, uid, gid };
|
||||
Syscall::SC_chown_params params { { pathname, strlen(pathname) }, uid, gid, AT_FDCWD, true };
|
||||
int rc = syscall(SC_chown, ¶ms);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
@ -55,6 +66,17 @@ int fchown(int fd, uid_t uid, gid_t gid)
|
|||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int fchownat(int fd, const char* pathname, uid_t uid, gid_t gid, int flags)
|
||||
{
|
||||
if (!pathname) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
Syscall::SC_chown_params params { { pathname, strlen(pathname) }, uid, gid, fd, !(flags & AT_SYMLINK_NOFOLLOW) };
|
||||
int rc = syscall(SC_chown, ¶ms);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
pid_t fork()
|
||||
{
|
||||
__pthread_fork_prepare();
|
||||
|
|
|
@ -104,8 +104,10 @@ int mknod(const char* pathname, mode_t, dev_t);
|
|||
long fpathconf(int fd, int name);
|
||||
long pathconf(const char* path, int name);
|
||||
char* getlogin();
|
||||
int lchown(const char* pathname, uid_t uid, gid_t gid);
|
||||
int chown(const char* pathname, uid_t, gid_t);
|
||||
int fchown(int fd, uid_t, gid_t);
|
||||
int fchownat(int fd, const char* pathname, uid_t uid, gid_t gid, int flags);
|
||||
int ftruncate(int fd, off_t length);
|
||||
int truncate(const char* path, off_t length);
|
||||
int mount(int source_fd, const char* target, const char* fs_type, int flags);
|
||||
|
|
|
@ -368,13 +368,13 @@ ErrorOr<void> fchmod(int fd, mode_t mode)
|
|||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> chown(StringView pathname, uid_t uid, gid_t gid)
|
||||
ErrorOr<void> lchown(StringView pathname, uid_t uid, gid_t gid)
|
||||
{
|
||||
if (!pathname.characters_without_null_termination())
|
||||
return Error::from_syscall("chown"sv, -EFAULT);
|
||||
|
||||
#ifdef __serenity__
|
||||
Syscall::SC_chown_params params = { { pathname.characters_without_null_termination(), pathname.length() }, uid, gid };
|
||||
Syscall::SC_chown_params params = { { pathname.characters_without_null_termination(), pathname.length() }, uid, gid, AT_FDCWD, false };
|
||||
int rc = syscall(SC_chown, ¶ms);
|
||||
HANDLE_SYSCALL_RETURN_VALUE("chown"sv, rc, {});
|
||||
#else
|
||||
|
@ -385,6 +385,23 @@ ErrorOr<void> chown(StringView pathname, uid_t uid, gid_t gid)
|
|||
#endif
|
||||
}
|
||||
|
||||
ErrorOr<void> chown(StringView pathname, uid_t uid, gid_t gid)
|
||||
{
|
||||
if (!pathname.characters_without_null_termination())
|
||||
return Error::from_syscall("chown"sv, -EFAULT);
|
||||
|
||||
#ifdef __serenity__
|
||||
Syscall::SC_chown_params params = { { pathname.characters_without_null_termination(), pathname.length() }, uid, gid, AT_FDCWD, true };
|
||||
int rc = syscall(SC_chown, ¶ms);
|
||||
HANDLE_SYSCALL_RETURN_VALUE("chown"sv, rc, {});
|
||||
#else
|
||||
String path = pathname;
|
||||
if (::lchown(path.characters(), uid, gid) < 0)
|
||||
return Error::from_syscall("lchown"sv, -errno);
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
ErrorOr<Optional<struct passwd>> getpwnam(StringView name)
|
||||
{
|
||||
::setpwent();
|
||||
|
|
|
@ -66,6 +66,7 @@ ErrorOr<void> ioctl(int fd, unsigned request, ...);
|
|||
ErrorOr<struct termios> tcgetattr(int fd);
|
||||
ErrorOr<void> tcsetattr(int fd, int optional_actions, struct termios const&);
|
||||
ErrorOr<void> chmod(StringView pathname, mode_t mode);
|
||||
ErrorOr<void> lchown(StringView pathname, uid_t uid, gid_t gid);
|
||||
ErrorOr<void> chown(StringView pathname, uid_t uid, gid_t gid);
|
||||
ErrorOr<Optional<struct passwd>> getpwnam(StringView name);
|
||||
ErrorOr<Optional<struct group>> getgrnam(StringView name);
|
||||
|
|
Loading…
Reference in a new issue