summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix/pvfs_acl.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-11-18 03:31:35 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:05:57 -0500
commitbc7b4abc3a85e78a73d401345265b2c022f0f04d (patch)
tree198b8203af8003f3e08c351f27425236bfd38227 /source4/ntvfs/posix/pvfs_acl.c
parent3c25dfe78905984da1b18a7c136f954bfcdece42 (diff)
downloadsamba-bc7b4abc3a85e78a73d401345265b2c022f0f04d.tar.gz
samba-bc7b4abc3a85e78a73d401345265b2c022f0f04d.tar.bz2
samba-bc7b4abc3a85e78a73d401345265b2c022f0f04d.zip
r3832: added NT ACL query/set to the posix NTVFS backend. The default ACL is
based on the current nttoken, which is completely wrong, but works as a start. The ACL is stored in the xattr system.DosAcl, using a NDR encoded IDL union with a version number to allow for future expansion. pvfs does not yet check the ACL for file access. At the moment the ACL is just query/set. We also need to do some RPC work to allow the windows ACL editor to be used. At the moment is queries the ACL fine, but displays an error when it fails to map the SIDs via rpc. (This used to be commit 3a1f20d874ab2d8b2a2f2485b7a705847abf1263)
Diffstat (limited to 'source4/ntvfs/posix/pvfs_acl.c')
-rw-r--r--source4/ntvfs/posix/pvfs_acl.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c
new file mode 100644
index 0000000000..2885604311
--- /dev/null
+++ b/source4/ntvfs/posix/pvfs_acl.c
@@ -0,0 +1,193 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ POSIX NTVFS backend - ACL support
+
+ Copyright (C) Andrew Tridgell 2004
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "auth/auth.h"
+#include "system/filesys.h"
+#include "vfs_posix.h"
+#include "librpc/gen_ndr/ndr_xattr.h"
+
+
+/*
+ setup a default ACL for a file
+*/
+static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
+ struct smbsrv_request *req,
+ struct pvfs_filename *name, int fd,
+ struct xattr_DosAcl *acl)
+{
+ struct security_descriptor *sd;
+ struct nt_user_token *token = req->session->session_info->nt_user_token;
+ int i;
+
+ sd = security_descriptor_initialise(req);
+ if (sd == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* nasty hack to get a reasonable sec desc - should be based on posix uid/gid
+ and perms */
+ if (token->num_sids > 0) {
+ sd->owner_sid = token->user_sids[0];
+ }
+ if (token->num_sids > 1) {
+ sd->group_sid = token->user_sids[1];
+ }
+
+ for (i=0;i<token->num_sids;i++) {
+ struct security_ace ace;
+ NTSTATUS status;
+
+ ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
+ ace.flags = 0;
+ ace.access_mask = SEC_RIGHTS_FULL_CTRL | STD_RIGHT_ALL_ACCESS;
+ ace.trustee = *token->user_sids[i];
+
+ status = security_descriptor_dacl_add(sd, &ace);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+
+ acl->version = 1;
+ acl->info.sd = sd;
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ omit any security_descriptor elements not specified in the given
+ secinfo flags
+*/
+static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags)
+{
+ if (!(secinfo_flags & OWNER_SECURITY_INFORMATION)) {
+ sd->owner_sid = NULL;
+ }
+ if (!(secinfo_flags & GROUP_SECURITY_INFORMATION)) {
+ sd->group_sid = NULL;
+ }
+ if (!(secinfo_flags & DACL_SECURITY_INFORMATION)) {
+ sd->dacl = NULL;
+ }
+ if (!(secinfo_flags & SACL_SECURITY_INFORMATION)) {
+ sd->sacl = NULL;
+ }
+}
+
+/*
+ answer a setfileinfo for an ACL
+*/
+NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
+ struct smbsrv_request *req,
+ struct pvfs_filename *name, int fd,
+ union smb_setfileinfo *info)
+{
+ struct xattr_DosAcl *acl;
+ uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
+ struct security_descriptor *new_sd, *sd;
+ NTSTATUS status;
+
+ acl = talloc_p(req, struct xattr_DosAcl);
+ if (acl == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = pvfs_acl_load(pvfs, name, fd, acl);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ status = pvfs_default_acl(pvfs, req, name, fd, acl);
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ switch (acl->version) {
+ case 1:
+ sd = acl->info.sd;
+ break;
+ default:
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ new_sd = info->set_secdesc.in.sd;
+
+ /* only set the elements that have been specified */
+ if (secinfo_flags & OWNER_SECURITY_INFORMATION) {
+ sd->owner_sid = new_sd->owner_sid;
+ }
+ if (secinfo_flags & GROUP_SECURITY_INFORMATION) {
+ sd->group_sid = new_sd->group_sid;
+ }
+ if (secinfo_flags & DACL_SECURITY_INFORMATION) {
+ sd->dacl = new_sd->dacl;
+ }
+ if (secinfo_flags & SACL_SECURITY_INFORMATION) {
+ sd->sacl = new_sd->sacl;
+ }
+
+ status = pvfs_acl_save(pvfs, name, fd, acl);
+
+ return status;
+}
+
+
+/*
+ answer a fileinfo query for the ACL
+*/
+NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs,
+ struct smbsrv_request *req,
+ struct pvfs_filename *name, int fd,
+ union smb_fileinfo *info)
+{
+ struct xattr_DosAcl *acl;
+ NTSTATUS status;
+ struct security_descriptor *sd;
+
+ acl = talloc_p(req, struct xattr_DosAcl);
+ if (acl == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = pvfs_acl_load(pvfs, name, fd, acl);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ status = pvfs_default_acl(pvfs, req, name, fd, acl);
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ switch (acl->version) {
+ case 1:
+ sd = acl->info.sd;
+ break;
+ default:
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
+
+ info->query_secdesc.out.sd = sd;
+
+ return NT_STATUS_OK;
+}
+