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; if (!parent_dirname(talloc_tos(), path, &parent_name, NULL)) { return NT_STATUS_NO_MEMORY; } status = get_nt_acl_internal(handle, NULL, parent_name, (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION), &parent_desc); if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("check_parent_acl_common: get_nt_acl_internal " "on directory %s for " "path %s returned %s\n", parent_name, path, nt_errstr(status) )); return status; } status = smb1_file_se_access_check(handle->conn, parent_desc, handle->conn->server_info->ptok, access_mask, &access_granted); if(!NT_STATUS_IS_OK(status)) { DEBUG(10,("check_parent_acl_common: access check " "on directory %s for " "path %s for mask 0x%x returned %s\n", parent_name, path, access_mask, nt_errstr(status) )); return status; } if (pp_parent_desc) { *pp_parent_desc = parent_desc; } return NT_STATUS_OK; }
static int open_acl_xattr(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode) { uint32_t access_granted = 0; struct security_descriptor *pdesc = NULL; bool file_existed = true; NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL, fname, (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION), &pdesc); if (NT_STATUS_IS_OK(status)) { /* See if we can access it. */ status = smb1_file_se_access_check(pdesc, handle->conn->server_info->ptok, fsp->access_mask, &access_granted); if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("open_acl_xattr: file %s open " "refused with error %s\n", fname, nt_errstr(status) )); errno = map_errno_from_nt_status(status); return -1; } } else if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) { file_existed = false; } DEBUG(10,("open_acl_xattr: get_nt_acl_attr_internal for " "file %s returned %s\n", fname, nt_errstr(status) )); fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); if (!file_existed && fsp->fh->fd != -1) { /* File was created. Inherit from parent directory. */ string_set(&fsp->fsp_name, fname); inherit_new_acl(handle, fname, fsp, false); } return fsp->fh->fd; }
static int open_acl_common(vfs_handle_struct *handle, struct smb_filename *smb_fname, files_struct *fsp, int flags, mode_t mode) { 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; if (fsp->base_fsp) { /* Stream open. Base filename open already did the ACL check. */ DEBUG(10,("open_acl_common: stream open on %s\n", fsp_str_dbg(fsp) )); return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode); } status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); if (!NT_STATUS_IS_OK(status)) { goto err; } status = get_nt_acl_internal(handle, NULL, fname, (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION), &pdesc); if (NT_STATUS_IS_OK(status)) { /* See if we can access it. */ status = smb1_file_se_access_check(handle->conn, pdesc, handle->conn->server_info->ptok, fsp->access_mask, &access_granted); if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("open_acl_xattr: %s open " "refused with error %s\n", fsp_str_dbg(fsp), nt_errstr(status) )); goto err; } } else if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) { file_existed = false; /* * If O_CREAT is true then we're trying to create a file. * Check the parent directory ACL will allow this. */ if (flags & O_CREAT) { struct security_descriptor *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); if (!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); status = NT_STATUS_OK; } } DEBUG(10,("open_acl_xattr: get_nt_acl_attr_internal for " "%s returned %s\n", fsp_str_dbg(fsp), nt_errstr(status) )); fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode); return fsp->fh->fd; err: errno = map_errno_from_nt_status(status); return -1; }