summaryrefslogtreecommitdiff
path: root/source3/modules/vfs_acl_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/modules/vfs_acl_common.c')
-rw-r--r--source3/modules/vfs_acl_common.c99
1 files changed, 48 insertions, 51 deletions
diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c
index 6e11ffc275..ea41fbb8e9 100644
--- a/source3/modules/vfs_acl_common.c
+++ b/source3/modules/vfs_acl_common.c
@@ -484,14 +484,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
psd);
}
-static NTSTATUS check_parent_acl_common(vfs_handle_struct *handle,
+static NTSTATUS get_parent_acl_common(vfs_handle_struct *handle,
const char *path,
- uint32_t access_mask,
struct security_descriptor **pp_parent_desc)
{
char *parent_name = NULL;
- struct security_descriptor *parent_desc = NULL;
- uint32_t access_granted = 0;
NTSTATUS status;
if (!parent_dirname(talloc_tos(), path, &parent_name, NULL)) {
@@ -504,15 +501,31 @@ static NTSTATUS check_parent_acl_common(vfs_handle_struct *handle,
(SECINFO_OWNER |
SECINFO_GROUP |
SECINFO_DACL),
- &parent_desc);
+ pp_parent_desc);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10,("check_parent_acl_common: get_nt_acl_internal "
+ DEBUG(10,("get_parent_acl_common: get_nt_acl_internal "
"on directory %s for "
"path %s returned %s\n",
parent_name,
path,
nt_errstr(status) ));
+ }
+ return status;
+}
+
+static NTSTATUS check_parent_acl_common(vfs_handle_struct *handle,
+ const char *path,
+ uint32_t access_mask,
+ struct security_descriptor **pp_parent_desc)
+{
+ char *parent_name = NULL;
+ struct security_descriptor *parent_desc = NULL;
+ uint32_t access_granted = 0;
+ NTSTATUS status;
+
+ status = get_parent_acl_common(handle, path, &parent_desc);
+ if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (pp_parent_desc) {
@@ -536,11 +549,6 @@ static NTSTATUS check_parent_acl_common(vfs_handle_struct *handle,
return NT_STATUS_OK;
}
-static void free_sd_common(void **ptr)
-{
- TALLOC_FREE(*ptr);
-}
-
/*********************************************************************
Check ACL on open. For new files inherit from parent directory.
*********************************************************************/
@@ -553,7 +561,6 @@ static int open_acl_common(vfs_handle_struct *handle,
{
uint32_t access_granted = 0;
struct security_descriptor *pdesc = NULL;
- struct security_descriptor *parent_desc = NULL;
bool file_existed = true;
char *fname = NULL;
NTSTATUS status;
@@ -599,29 +606,28 @@ static int open_acl_common(vfs_handle_struct *handle,
* Check the parent directory ACL will allow this.
*/
if (flags & O_CREAT) {
- struct security_descriptor *psd = NULL;
+ struct security_descriptor *parent_desc = NULL;
+ struct security_descriptor **pp_psd = NULL;
status = check_parent_acl_common(handle, fname,
SEC_DIR_ADD_FILE, &parent_desc);
if (!NT_STATUS_IS_OK(status)) {
goto err;
}
- /* Cache the parent security descriptor for
- * later use. We do have an fsp here, but to
- * keep the code consistent with the directory
- * case which doesn't, use the handle. */
- /* Attach this to the conn, move from talloc_tos(). */
- psd = (struct security_descriptor *)talloc_move(handle->conn,
- &parent_desc);
+ /* Cache the parent security descriptor for
+ * later use. */
- if (!psd) {
+ pp_psd = VFS_ADD_FSP_EXTENSION(handle,
+ fsp,
+ struct security_descriptor *,
+ NULL);
+ if (!pp_psd) {
status = NT_STATUS_NO_MEMORY;
goto err;
}
- status = NT_STATUS_NO_MEMORY;
- SMB_VFS_HANDLE_SET_DATA(handle, psd, free_sd_common,
- struct security_descriptor *, goto err);
+
+ *pp_psd = parent_desc;
status = NT_STATUS_OK;
}
}
@@ -648,30 +654,13 @@ static int mkdir_acl_common(vfs_handle_struct *handle, const char *path, mode_t
ret = vfs_stat_smb_fname(handle->conn, path, &sbuf);
if (ret == -1 && errno == ENOENT) {
- struct security_descriptor *parent_desc = NULL;
- struct security_descriptor *psd = NULL;
-
/* We're creating a new directory. */
status = check_parent_acl_common(handle, path,
- SEC_DIR_ADD_SUBDIR, &parent_desc);
+ SEC_DIR_ADD_SUBDIR, NULL);
if (!NT_STATUS_IS_OK(status)) {
errno = map_errno_from_nt_status(status);
return -1;
}
-
- /* Cache the parent security descriptor for
- * later use. We don't have an fsp here so
- * use the handle. */
-
- /* Attach this to the conn, move from talloc_tos(). */
- psd = (struct security_descriptor *)talloc_move(handle->conn,
- &parent_desc);
-
- if (!psd) {
- return -1;
- }
- SMB_VFS_HANDLE_SET_DATA(handle, psd, free_sd_common,
- struct security_descriptor *, return -1);
}
return SMB_VFS_NEXT_MKDIR(handle, path, mode);
@@ -916,6 +905,7 @@ static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle,
files_struct *fsp = NULL;
int info;
struct security_descriptor *parent_sd = NULL;
+ struct security_descriptor **pp_parent_sd = NULL;
status = SMB_VFS_NEXT_CREATE_FILE(handle,
req,
@@ -960,13 +950,19 @@ static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle,
goto out;
}
-
- /* We must have a cached parent sd in this case.
- * attached to the handle. */
-
- SMB_VFS_HANDLE_GET_DATA(handle, parent_sd,
- struct security_descriptor,
- goto err);
+ /* See if we have a cached parent sd, if so, use it. */
+ pp_parent_sd = (struct security_descriptor **)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+ if (!pp_parent_sd) {
+ /* Must be a directory, fetch again (sigh). */
+ status = get_parent_acl_common(handle,
+ fsp->fsp_name->base_name,
+ &parent_sd);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+ } else {
+ parent_sd = *pp_parent_sd;
+ }
if (!parent_sd) {
goto err;
@@ -984,8 +980,9 @@ static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle,
out:
- /* Ensure we never leave attached data around. */
- SMB_VFS_HANDLE_FREE_DATA(handle);
+ if (fsp) {
+ VFS_REMOVE_FSP_EXTENSION(handle, fsp);
+ }
if (NT_STATUS_IS_OK(status) && pinfo) {
*pinfo = info;