diff --git a/Cargo.lock b/Cargo.lock index b42e20eddffee31519984ed943290525fb650915..0cc040753313db48d3153fd1c60a73dc9d34047e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,7 +66,7 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -75,7 +75,7 @@ version = "0.3.2" dependencies = [ "fuse 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -98,7 +98,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -130,7 +130,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" "checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" -"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509" +"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0" "checksum spin 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7e4deb3c2455c73779e6d3eebceae9599fc70957e54c69fe88f93aa48e62f432" "checksum thread-scoped 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bcbb6aa301e5d3b0b5ef639c9a9c7e2f1c944f177b460c04dc24c69b1fa2bd99" "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" diff --git a/src/mount/redox/resource.rs b/src/mount/redox/resource.rs index ebe16067b6077cd1980f23091d9b1ef4b35ad1c4..59b9a25e4eb35b4348df0b1703a4f094e02febd3 100644 --- a/src/mount/redox/resource.rs +++ b/src/mount/redox/resource.rs @@ -2,8 +2,8 @@ use std::cmp::{min, max}; use std::time::{SystemTime, UNIX_EPOCH}; use syscall::data::TimeSpec; -use syscall::error::{Error, Result, EBADF, EINVAL, EISDIR}; -use syscall::flag::{O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, F_GETFL, F_SETFL}; +use syscall::error::{Error, Result, EBADF, EINVAL, EISDIR, EPERM}; +use syscall::flag::{O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, F_GETFL, F_SETFL, MODE_PERM}; use syscall::{Stat, SEEK_SET, SEEK_CUR, SEEK_END}; use disk::Disk; @@ -14,6 +14,8 @@ pub trait Resource<D: Disk> { fn read(&mut self, buf: &mut [u8], fs: &mut FileSystem<D>) -> Result<usize>; fn write(&mut self, buf: &[u8], fs: &mut FileSystem<D>) -> Result<usize>; fn seek(&mut self, offset: usize, whence: usize, fs: &mut FileSystem<D>) -> Result<usize>; + fn fchmod(&mut self, mode: u16, fs: &mut FileSystem<D>) -> Result<usize>; + fn fchown(&mut self, uid: u32, gid: u32, fs: &mut FileSystem<D>) -> Result<usize>; fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<usize>; fn path(&self, buf: &mut [u8]) -> Result<usize>; fn stat(&self, _stat: &mut Stat, fs: &mut FileSystem<D>) -> Result<usize>; @@ -27,15 +29,17 @@ pub struct DirResource { block: u64, data: Option<Vec<u8>>, seek: usize, + uid: u32, } impl DirResource { - pub fn new(path: String, block: u64, data: Option<Vec<u8>>) -> DirResource { + pub fn new(path: String, block: u64, data: Option<Vec<u8>>, uid: u32) -> DirResource { DirResource { path: path, block: block, data: data, seek: 0, + uid: uid, } } } @@ -46,7 +50,8 @@ impl<D: Disk> Resource<D> for DirResource { path: self.path.clone(), block: self.block, data: self.data.clone(), - seek: self.seek + seek: self.seek, + uid: self.uid })) } @@ -77,6 +82,40 @@ impl<D: Disk> Resource<D> for DirResource { Ok(self.seek) } + fn fchmod(&mut self, mode: u16, fs: &mut FileSystem<D>) -> Result<usize> { + let mut node = fs.node(self.block)?; + + if node.1.uid == self.uid || self.uid == 0 { + node.1.mode = (node.1.mode & ! MODE_PERM) | (mode & MODE_PERM); + + fs.write_at(node.0, &node.1)?; + + Ok(0) + } else { + Err(Error::new(EPERM)) + } + } + + fn fchown(&mut self, uid: u32, gid: u32, fs: &mut FileSystem<D>) -> Result<usize> { + let mut node = fs.node(self.block)?; + + if node.1.uid == self.uid || self.uid == 0 { + if uid as i32 != -1 { + node.1.uid = uid; + } + + if gid as i32 != -1 { + node.1.gid = gid; + } + + fs.write_at(node.0, &node.1)?; + + Ok(0) + } else { + Err(Error::new(EPERM)) + } + } + fn fcntl(&mut self, _cmd: usize, _arg: usize) -> Result<usize> { Err(Error::new(EBADF)) } @@ -192,6 +231,40 @@ impl<D: Disk> Resource<D> for FileResource { Ok(self.seek as usize) } + fn fchmod(&mut self, mode: u16, fs: &mut FileSystem<D>) -> Result<usize> { + let mut node = fs.node(self.block)?; + + if node.1.uid == self.uid || self.uid == 0 { + node.1.mode = (node.1.mode & ! MODE_PERM) | (mode & MODE_PERM); + + fs.write_at(node.0, &node.1)?; + + Ok(0) + } else { + Err(Error::new(EPERM)) + } + } + + fn fchown(&mut self, uid: u32, gid: u32, fs: &mut FileSystem<D>) -> Result<usize> { + let mut node = fs.node(self.block)?; + + if node.1.uid == self.uid || self.uid == 0 { + if uid as i32 != -1 { + node.1.uid = uid; + } + + if gid as i32 != -1 { + node.1.gid = gid; + } + + fs.write_at(node.0, &node.1)?; + + Ok(0) + } else { + Err(Error::new(EPERM)) + } + } + fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<usize> { match cmd { F_GETFL => Ok(self.flags), @@ -265,7 +338,7 @@ impl<D: Disk> Resource<D> for FileResource { Ok(0) } } else { - Err(Error::new(EBADF)) + Err(Error::new(EPERM)) } } } diff --git a/src/mount/redox/scheme.rs b/src/mount/redox/scheme.rs index 1f4bdb442baa3c76107327ffaff85185b329236b..2407ff29bc7b4fe013b45f044f54ad0262cd7882 100644 --- a/src/mount/redox/scheme.rs +++ b/src/mount/redox/scheme.rs @@ -210,12 +210,12 @@ impl<D: Disk> Scheme for FileScheme<D> { } } - Box::new(DirResource::new(path.to_string(), node.0, Some(data))) + Box::new(DirResource::new(path.to_string(), node.0, Some(data), uid)) } else if flags & O_WRONLY == O_WRONLY { // println!("{:X} & {:X}: EISDIR {}", flags, O_DIRECTORY, path); return Err(Error::new(EISDIR)); } else { - Box::new(DirResource::new(path.to_string(), node.0, None)) + Box::new(DirResource::new(path.to_string(), node.0, None, uid)) } } else if node.1.is_symlink() && !(flags & O_STAT == O_STAT && flags & O_NOFOLLOW == O_NOFOLLOW) && flags & O_SYMLINK != O_SYMLINK { let mut resolve_nodes = Vec::new(); @@ -287,7 +287,7 @@ impl<D: Disk> Scheme for FileScheme<D> { fs.write_at(node.0, &node.1)?; if dir { - Box::new(DirResource::new(path.to_string(), node.0, None)) + Box::new(DirResource::new(path.to_string(), node.0, None, uid)) } else { let seek = if flags & O_APPEND == O_APPEND { fs.node_len(node.0)? @@ -466,6 +466,24 @@ impl<D: Disk> Scheme for FileScheme<D> { } } + fn fchmod(&self, id: usize, mode: u16) -> Result<usize> { + let mut files = self.files.lock(); + if let Some(file) = files.get_mut(&id) { + file.fchmod(mode, &mut self.fs.borrow_mut()) + } else { + Err(Error::new(EBADF)) + } + } + + fn fchown(&self, id: usize, uid: u32, gid: u32) -> Result<usize> { + let mut files = self.files.lock(); + if let Some(file) = files.get_mut(&id) { + file.fchown(uid, gid, &mut self.fs.borrow_mut()) + } else { + Err(Error::new(EBADF)) + } + } + fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> { let mut files = self.files.lock(); if let Some(file) = files.get_mut(&id) {