summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/ntvfs/simple/vfs_simple.c52
1 files changed, 39 insertions, 13 deletions
diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c
index 18f6559510..4802c11d6a 100644
--- a/source4/ntvfs/simple/vfs_simple.c
+++ b/source4/ntvfs/simple/vfs_simple.c
@@ -33,6 +33,8 @@
#define O_DIRECTORY 0
#endif
+#define CHECK_READ_ONLY(req) do { if (lp_readonly(req->conn->service)) return NT_STATUS_ACCESS_DENIED; } while (0)
+
/*
connect to a share - used when a tree_connect operation comes
in. For a disk based backend we needs to ensure that the base
@@ -95,6 +97,8 @@ static NTSTATUS svfs_unlink(struct request_context *req, struct smb_unlink *unl)
{
char *unix_path;
+ CHECK_READ_ONLY(req);
+
unix_path = svfs_unix_path(req, unl->in.pattern);
/* ignoring wildcards ... */
@@ -274,39 +278,49 @@ static NTSTATUS svfs_open(struct request_context *req, union smb_open *io)
struct stat st;
int fd, flags;
struct svfs_file *f;
+ int create_flags, rdwr_flags;
if (io->generic.level != RAW_OPEN_GENERIC) {
return ntvfs_map_open(req, io);
}
+ if (lp_readonly(req->conn->service)) {
+ create_flags = 0;
+ rdwr_flags = O_RDONLY;
+ } else {
+ create_flags = O_CREAT;
+ rdwr_flags = O_RDWR;
+ }
+
unix_path = svfs_unix_path(req, io->ntcreatex.in.fname);
switch (io->generic.in.open_disposition) {
case NTCREATEX_DISP_SUPERSEDE:
- flags = O_RDWR | O_CREAT | O_TRUNC;
+ case NTCREATEX_DISP_OVERWRITE_IF:
+ flags = create_flags | O_TRUNC;
break;
case NTCREATEX_DISP_OPEN:
- flags = O_RDWR;
+ case NTCREATEX_DISP_OVERWRITE:
+ flags = 0;
break;
case NTCREATEX_DISP_CREATE:
- flags = O_RDWR | O_CREAT | O_EXCL;
+ flags = create_flags | O_EXCL;
break;
case NTCREATEX_DISP_OPEN_IF:
- flags = O_RDWR | O_CREAT;
- break;
- case NTCREATEX_DISP_OVERWRITE:
- flags = O_RDWR;
- break;
- case NTCREATEX_DISP_OVERWRITE_IF:
- flags = O_RDWR | O_CREAT | O_TRUNC;
+ flags = create_flags;
break;
default:
- flags = O_RDWR;
+ flags = 0;
break;
}
+
+ flags |= rdwr_flags;
if (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) {
flags = O_RDONLY | O_DIRECTORY;
+ if (lp_readonly(req->conn->service)) {
+ goto do_open;
+ }
switch (io->generic.in.open_disposition) {
case NTCREATEX_DISP_CREATE:
if (mkdir(unix_path, 0755) == -1) {
@@ -322,9 +336,9 @@ static NTSTATUS svfs_open(struct request_context *req, union smb_open *io)
break;
}
}
- DEBUG(9,("svfs_open: file %s flags=0x%x\n", unix_path, flags));
+
+do_open:
fd = open(unix_path, flags, 0644);
- DEBUG(9,("svfs_open: fd=%d errno=%d\n", fd, errno));
if (fd == -1) {
if (errno == 0)
errno = ENOENT;
@@ -367,6 +381,8 @@ static NTSTATUS svfs_mkdir(struct request_context *req, union smb_mkdir *md)
{
char *unix_path;
+ CHECK_READ_ONLY(req);
+
if (md->generic.level != RAW_MKDIR_MKDIR) {
return NT_STATUS_INVALID_LEVEL;
}
@@ -387,6 +403,8 @@ static NTSTATUS svfs_rmdir(struct request_context *req, struct smb_rmdir *rd)
{
char *unix_path;
+ CHECK_READ_ONLY(req);
+
unix_path = svfs_unix_path(req, rd->in.path);
if (rmdir(unix_path) == -1) {
@@ -403,6 +421,8 @@ static NTSTATUS svfs_rename(struct request_context *req, union smb_rename *ren)
{
char *unix_path1, *unix_path2;
+ CHECK_READ_ONLY(req);
+
if (ren->generic.level != RAW_RENAME_RENAME) {
return NT_STATUS_INVALID_LEVEL;
}
@@ -458,6 +478,8 @@ static NTSTATUS svfs_write(struct request_context *req, union smb_write *wr)
{
ssize_t ret;
+ CHECK_READ_ONLY(req);
+
switch (wr->generic.level) {
case RAW_WRITE_WRITEX:
ret = pwrite(wr->writex.in.fnum,
@@ -563,6 +585,8 @@ static NTSTATUS svfs_lock(struct request_context *req, union smb_lock *lck)
*/
static NTSTATUS svfs_setpathinfo(struct request_context *req, union smb_setfileinfo *st)
{
+ CHECK_READ_ONLY(req);
+
return NT_STATUS_NOT_SUPPORTED;
}
@@ -574,6 +598,8 @@ static NTSTATUS svfs_setfileinfo(struct request_context *req,
{
struct utimbuf unix_times;
int fd;
+
+ CHECK_READ_ONLY(req);
switch (info->generic.level) {
case RAW_SFILEINFO_END_OF_FILE_INFO: