summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix/pvfs_open.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-12-30 02:25:20 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:07:43 -0500
commitabe22d0351955adb1ad7c304d45b9539d202aadb (patch)
treec24b4533344f9a5b97019aa85abf77047bf16d42 /source4/ntvfs/posix/pvfs_open.c
parente20be5a6be8fc5da412623c0491cdf9362f1dc2d (diff)
downloadsamba-abe22d0351955adb1ad7c304d45b9539d202aadb.tar.gz
samba-abe22d0351955adb1ad7c304d45b9539d202aadb.tar.bz2
samba-abe22d0351955adb1ad7c304d45b9539d202aadb.zip
r4403: - added ACL inheritance in the pvfs backend. ACLs are now inherited on
file and directory creation via ntcreatex. pvfs now passes the inheritance test in RAW-ACLS - cleaned up the error handling a bit in pvfs_open() (This used to be commit f4dfb63d5395a365961a21388639809fcd3112d0)
Diffstat (limited to 'source4/ntvfs/posix/pvfs_open.c')
-rw-r--r--source4/ntvfs/posix/pvfs_open.c116
1 files changed, 73 insertions, 43 deletions
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 34052fc44a..1695d8e1d9 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -95,6 +95,43 @@ static int pvfs_dir_fnum_destructor(void *p)
return 0;
}
+/*
+ setup any EAs and the ACL on newly created files/directories
+*/
+static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs,
+ struct smbsrv_request *req,
+ struct pvfs_filename *name,
+ int fd, int fnum,
+ union smb_open *io)
+{
+ NTSTATUS status;
+
+ /* setup any EAs that were asked for */
+ if (io->ntcreatex.in.ea_list) {
+ status = pvfs_setfileinfo_ea_set(pvfs, name, fd,
+ io->ntcreatex.in.ea_list->num_eas,
+ io->ntcreatex.in.ea_list->eas);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+
+ /* setup an initial sec_desc if requested */
+ if (io->ntcreatex.in.sec_desc) {
+ union smb_setfileinfo set;
+
+ set.set_secdesc.file.fnum = fnum;
+ set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
+ set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc;
+
+ status = pvfs_acl_set(pvfs, req, name, fd, &set);
+ } else {
+ /* otherwise setup an inherited acl from the parent */
+ status = pvfs_acl_inherit(pvfs, req, name, fd);
+ }
+
+ return status;
+}
/*
open a directory
@@ -162,6 +199,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
/* check the security descriptor */
status = pvfs_access_check(pvfs, req, name, &access_mask);
if (!NT_STATUS_IS_OK(status)) {
+ idr_remove(pvfs->idtree_fnum, fnum);
return status;
}
}
@@ -200,6 +238,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
uint32_t attrib = io->generic.in.file_attr | FILE_ATTRIBUTE_DIRECTORY;
mode_t mode = pvfs_fileperms(pvfs, attrib);
if (mkdir(name->full_name, mode) == -1) {
+ idr_remove(pvfs->idtree_fnum, fnum);
return pvfs_map_errno(pvfs,errno);
}
@@ -207,14 +246,21 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto cleanup_delete;
}
+
+ status = pvfs_open_setup_eas_acl(pvfs, req, name, -1, fnum, io);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto cleanup_delete;
+ }
+
create_action = NTCREATEX_ACTION_CREATED;
} else {
create_action = NTCREATEX_ACTION_EXISTED;
}
if (!name->exists) {
+ idr_remove(pvfs->idtree_fnum, fnum);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
@@ -236,6 +282,11 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
io->generic.out.is_directory = 1;
return NT_STATUS_OK;
+
+cleanup_delete:
+ idr_remove(pvfs->idtree_fnum, fnum);
+ rmdir(name->full_name);
+ return status;
}
/*
@@ -462,53 +513,25 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
name->dos.attrib = attrib;
status = pvfs_dosattrib_save(pvfs, name, fd);
if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->idtree_fnum, fnum);
- close(fd);
- return status;
+ goto cleanup_delete;
}
- /* setup any EAs that were asked for */
- if (io->ntcreatex.in.ea_list) {
- status = pvfs_setfileinfo_ea_set(pvfs, name, fd,
- io->ntcreatex.in.ea_list->num_eas,
- io->ntcreatex.in.ea_list->eas);
- if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->idtree_fnum, fnum);
- close(fd);
- return status;
- }
- }
-
- /* setup an initial sec_desc is required */
- if (io->ntcreatex.in.sec_desc) {
- union smb_setfileinfo set;
-
- set.set_secdesc.file.fnum = fnum;
- set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
- set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc;
- status = pvfs_acl_set(pvfs, req, name, fd, &set);
- if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->idtree_fnum, fnum);
- close(fd);
- return status;
- }
+ status = pvfs_open_setup_eas_acl(pvfs, req, name, fd, fnum, io);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto cleanup_delete;
}
/* form the lock context used for byte range locking and
opendb locking */
status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->idtree_fnum, fnum);
- close(fd);
- return status;
+ goto cleanup_delete;
}
status = pvfs_brl_locking_key(name, f->handle, &f->handle->brl_locking_key);
if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->idtree_fnum, fnum);
- close(fd);
- return status;
+ goto cleanup_delete;
}
/* grab a lock on the open file record */
@@ -518,16 +541,17 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
name->full_name));
/* we were supposed to do a blocking lock, so something
is badly wrong! */
- idr_remove(pvfs->idtree_fnum, fnum);
- close(fd);
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto cleanup_delete;
}
status = odb_open_file(lck, f->handle, name->stream_id,
share_access, create_options, access_mask);
talloc_free(lck);
if (!NT_STATUS_IS_OK(status)) {
- /* bad news, we must have hit a race */
+ /* bad news, we must have hit a race - we don't delete the file
+ here as the most likely scenario is that someone else created
+ the file at the same time */
idr_remove(pvfs->idtree_fnum, fnum);
close(fd);
return status;
@@ -583,6 +607,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
talloc_steal(pvfs, f);
return NT_STATUS_OK;
+
+cleanup_delete:
+ idr_remove(pvfs->idtree_fnum, fnum);
+ close(fd);
+ unlink(name->full_name);
+ return status;
}
@@ -846,6 +876,10 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return pvfs_open_directory(pvfs, req, name, io);
}
+ /* FILE_ATTRIBUTE_DIRECTORY is ignored if the above test for directory
+ open doesn't match */
+ io->generic.in.file_attr &= ~FILE_ATTRIBUTE_DIRECTORY;
+
create_options = io->generic.in.create_options;
share_access = io->generic.in.share_access;
access_mask = io->generic.in.access_mask;
@@ -894,10 +928,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return NT_STATUS_INVALID_PARAMETER;
}
- if (io->generic.in.file_attr & FILE_ATTRIBUTE_DIRECTORY) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
/* handle creating a new file separately */
if (!name->exists) {
status = pvfs_create_file(pvfs, req, name, io);