Better permission handling, add chmod/chown
This commit is contained in:
@@ -22,3 +22,6 @@ int sys_access(const char *path, int mode);
|
||||
|
||||
// TODO: const struct termios *termp, const struct winsize *winp
|
||||
int sys_openpty(int *master, int *slave);
|
||||
|
||||
int sys_chmod(const char *path, mode_t mode);
|
||||
int sys_chown(const char *path, uid_t uid, gid_t gid);
|
||||
|
||||
@@ -45,6 +45,8 @@ struct vnode_operations {
|
||||
|
||||
int (*stat) (struct vnode *at, struct stat *st);
|
||||
int (*access) (struct vnode *node, uid_t *uid, gid_t *gid, mode_t *mode);
|
||||
int (*chmod) (struct vnode *node, mode_t mode);
|
||||
int (*chown) (struct vnode *node, uid_t uid, gid_t gid);
|
||||
|
||||
int (*readlink) (struct vnode *at, char *buf, size_t lim);
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ int vfs_readdir(struct vfs_ioctx *ctx, struct ofile *fd, struct dirent *ent);
|
||||
int vfs_unlink(struct vfs_ioctx *ctx, const char *path);
|
||||
int vfs_rmdir(struct vfs_ioctx *ctx, const char *path);
|
||||
int vfs_mkdir(struct vfs_ioctx *ctx, const char *path, mode_t mode);
|
||||
int vfs_chmod(struct vfs_ioctx *ctx, const char *path, mode_t mode);
|
||||
int vfs_chown(struct vfs_ioctx *ctx, const char *path, uid_t uid, gid_t gid);
|
||||
|
||||
int vfs_access(struct vfs_ioctx *ctx, const char *path, int accmode);
|
||||
int vfs_stat(struct vfs_ioctx *ctx, const char *path, struct stat *st);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#define SYSCALL_NR_CREAT 85
|
||||
#define SYSCALL_NR_UNLINK 87
|
||||
#define SYSCALL_NR_READDIR 89
|
||||
#define SYSCALL_NR_CHMOD 90
|
||||
#define SYSCALL_NR_CHOWN 92
|
||||
|
||||
#define SYSCALL_NR_BRK 12
|
||||
#define SYSCALL_NR_NANOSLEEP 35
|
||||
|
||||
@@ -185,3 +185,18 @@ int sys_openpty(int *master, int *slave) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int sys_chmod(const char *path, mode_t mode) {
|
||||
struct thread *thr = get_cpu()->thread;
|
||||
_assert(thr);
|
||||
_assert(path);
|
||||
|
||||
return vfs_chmod(&thr->ioctx, path, mode);
|
||||
}
|
||||
|
||||
int sys_chown(const char *path, uid_t uid, gid_t gid) {
|
||||
struct thread *thr = get_cpu()->thread;
|
||||
_assert(thr);
|
||||
_assert(path);
|
||||
|
||||
return vfs_chown(&thr->ioctx, path, uid, gid);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ const void *amd64_syscall_jmp_table[256] = {
|
||||
[SYSCALL_NR_MKDIR] = sys_mkdir,
|
||||
[SYSCALL_NR_CREAT] = sys_creat,
|
||||
[SYSCALL_NR_RMDIR] = sys_rmdir,
|
||||
[SYSCALL_NR_CHMOD] = sys_chmod,
|
||||
[SYSCALL_NR_CHOWN] = sys_chown,
|
||||
|
||||
// Process
|
||||
[SYSCALL_NR_EXIT] = sys_exit,
|
||||
|
||||
@@ -74,6 +74,7 @@ static ssize_t tty_read(struct chrdev *tty, void *buf, size_t pos, size_t lim) {
|
||||
memcpy((char *) buf + p, ibuf, rd);
|
||||
|
||||
rem -= rd;
|
||||
p += rd;
|
||||
}
|
||||
|
||||
return p;
|
||||
|
||||
+26
-27
@@ -30,8 +30,8 @@ static int ext2_vnode_truncate(struct vnode *vn, size_t length);
|
||||
static ssize_t ext2_vnode_readdir(struct ofile *fd, struct dirent *ent);
|
||||
//static void ext2_vnode_destroy(vnode_t *vn);
|
||||
static int ext2_vnode_stat(struct vnode *vn, struct stat *st);
|
||||
//static int ext2_vnode_chmod(vnode_t *vn, mode_t mode);
|
||||
//static int ext2_vnode_chown(vnode_t *vn, uid_t uid, gid_t gid);
|
||||
static int ext2_vnode_chmod(struct vnode *vn, mode_t mode);
|
||||
static int ext2_vnode_chown(struct vnode *vn, uid_t uid, gid_t gid);
|
||||
static int ext2_vnode_unlink(struct vnode *vn);
|
||||
//static int ext2_vnode_access(vnode_t *vn, uid_t *uid, gid_t *gid, mode_t *mode);
|
||||
static int ext2_vnode_readlink(struct vnode *vn, char *dst, size_t lim);
|
||||
@@ -48,8 +48,8 @@ struct vnode_operations ext2_vnode_ops = {
|
||||
.readlink = ext2_vnode_readlink,
|
||||
// .symlink = ext2_vnode_symlink,
|
||||
//
|
||||
// .chmod = ext2_vnode_chmod,
|
||||
// .chown = ext2_vnode_chown,
|
||||
.chmod = ext2_vnode_chmod,
|
||||
.chown = ext2_vnode_chown,
|
||||
.stat = ext2_vnode_stat,
|
||||
.unlink = ext2_vnode_unlink,
|
||||
// .access = ext2_vnode_access,
|
||||
@@ -427,7 +427,6 @@ static ssize_t ext2_vnode_write(struct ofile *fd, const void *buf, size_t count)
|
||||
}
|
||||
}
|
||||
|
||||
kinfo("Wrote %u bytes\n", written);
|
||||
return written;
|
||||
}
|
||||
|
||||
@@ -585,28 +584,28 @@ static int ext2_vnode_stat(struct vnode *vn, struct stat *st) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//static int ext2_vnode_chmod(vnode_t *vn, mode_t mode) {
|
||||
// _assert(vn && vn->fs && vn->fs_data);
|
||||
// struct ext2_inode *inode = (struct ext2_inode *) vn->fs_data;
|
||||
//
|
||||
// // Update only access mode
|
||||
// inode->type_perm &= ~0x1FF;
|
||||
// inode->type_perm |= mode & 0x1FF;
|
||||
//
|
||||
// // Write the inode back
|
||||
// return ext2_write_inode(vn->fs, inode, vn->fs_number);
|
||||
//}
|
||||
//
|
||||
//static int ext2_vnode_chown(vnode_t *vn, uid_t uid, gid_t gid) {
|
||||
// _assert(vn && vn->fs && vn->fs_data);
|
||||
// struct ext2_inode *inode = (struct ext2_inode *) vn->fs_data;
|
||||
//
|
||||
// inode->gid = gid;
|
||||
// inode->uid = uid;
|
||||
//
|
||||
// // Write the inode back
|
||||
// return ext2_write_inode(vn->fs, inode, vn->fs_number);
|
||||
//}
|
||||
static int ext2_vnode_chmod(struct vnode *vn, mode_t mode) {
|
||||
_assert(vn && vn->fs && vn->fs_data);
|
||||
struct ext2_inode *inode = (struct ext2_inode *) vn->fs_data;
|
||||
|
||||
// Update only access mode
|
||||
inode->type_perm &= ~0x1FF;
|
||||
inode->type_perm |= mode & 0x1FF;
|
||||
|
||||
// Write the inode back
|
||||
return ext2_write_inode(vn->fs, inode, vn->ino);
|
||||
}
|
||||
|
||||
static int ext2_vnode_chown(struct vnode *vn, uid_t uid, gid_t gid) {
|
||||
_assert(vn && vn->fs && vn->fs_data);
|
||||
struct ext2_inode *inode = (struct ext2_inode *) vn->fs_data;
|
||||
|
||||
inode->gid = gid;
|
||||
inode->uid = uid;
|
||||
|
||||
// Write the inode back
|
||||
return ext2_write_inode(vn->fs, inode, vn->ino);
|
||||
}
|
||||
|
||||
static int ext2_vnode_unlink(struct vnode *node) {
|
||||
_assert(node);
|
||||
|
||||
@@ -28,12 +28,17 @@ static int tarfs_vnode_open(struct ofile *of, int opt);
|
||||
static int tarfs_vnode_stat(struct vnode *node, struct stat *st);
|
||||
static ssize_t tarfs_vnode_read(struct ofile *fd, void *buf, size_t count);
|
||||
static off_t tarfs_vnode_lseek(struct ofile *fd, off_t off, int whence);
|
||||
// Nodes can be chmod/chown'd
|
||||
static int tarfs_vnode_chmod(struct vnode *node, mode_t mode);
|
||||
static int tarfs_vnode_chown(struct vnode *node, uid_t uid, gid_t gid);
|
||||
|
||||
static struct vnode_operations _tarfs_vnode_op = {
|
||||
.stat = tarfs_vnode_stat,
|
||||
.read = tarfs_vnode_read,
|
||||
.open = tarfs_vnode_open,
|
||||
.lseek = tarfs_vnode_lseek,
|
||||
.chmod = tarfs_vnode_chmod,
|
||||
.chown = tarfs_vnode_chown,
|
||||
};
|
||||
|
||||
static ssize_t tarfs_octal(const char *buf, size_t lim) {
|
||||
@@ -313,6 +318,14 @@ static off_t tarfs_vnode_lseek(struct ofile *fd, off_t offset, int whence) {
|
||||
return fd->pos;
|
||||
}
|
||||
|
||||
static int tarfs_vnode_chmod(struct vnode *node, mode_t mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tarfs_vnode_chown(struct vnode *node, uid_t uid, gid_t gid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void tarfs_init(void) {
|
||||
|
||||
@@ -545,3 +545,60 @@ off_t vfs_lseek(struct vfs_ioctx *ctx, struct ofile *fd, off_t offset, int whenc
|
||||
|
||||
return node->op->lseek(fd, offset, whence);
|
||||
}
|
||||
|
||||
int vfs_chmod(struct vfs_ioctx *ctx, const char *path, mode_t mode) {
|
||||
_assert(ctx);
|
||||
_assert(path);
|
||||
struct vnode *node;
|
||||
int res;
|
||||
|
||||
mode &= 0x1FF;
|
||||
|
||||
if ((res = vfs_find(ctx, ctx->cwd_vnode, path, &node)) != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// Only root or file owner can do that
|
||||
if (ctx->uid != 0 && ctx->uid != node->uid) {
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (!node->op || !node->op->chmod) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((res = node->op->chmod(node, mode)) != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
node->mode = mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vfs_chown(struct vfs_ioctx *ctx, const char *path, uid_t uid, gid_t gid) {
|
||||
struct vnode *node;
|
||||
int res;
|
||||
|
||||
if ((res = vfs_find(ctx, ctx->cwd_vnode, path, &node)) != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// Only root can chown
|
||||
if (ctx->uid != 0) {
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (!node->op || !node->op->chown) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((res = node->op->chown(node, uid, gid)) != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
node->uid = uid;
|
||||
node->gid = gid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user