summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix/pvfs_acl.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2006-10-09 11:13:49 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:20:52 -0500
commit2338e978322510d5b6def6edac40a868e4945d2e (patch)
treef040d75a6ba906d6bfebce3ad35dd19ee588d0db /source4/ntvfs/posix/pvfs_acl.c
parent0019163d85fce2e83cd3e6193479b59e88d37d98 (diff)
downloadsamba-2338e978322510d5b6def6edac40a868e4945d2e.tar.gz
samba-2338e978322510d5b6def6edac40a868e4945d2e.tar.bz2
samba-2338e978322510d5b6def6edac40a868e4945d2e.zip
r19199: split out the xattr NTACL code into a separate part of the posix
backend, allowing other ACL backends to be added. The xattr backend is still the default backend (This used to be commit 90f044e63b12d32228310c7529382198bd7e6dfe)
Diffstat (limited to 'source4/ntvfs/posix/pvfs_acl.c')
-rw-r--r--source4/ntvfs/posix/pvfs_acl.c108
1 files changed, 68 insertions, 40 deletions
diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c
index 62ef196977..1a3fc184de 100644
--- a/source4/ntvfs/posix/pvfs_acl.c
+++ b/source4/ntvfs/posix/pvfs_acl.c
@@ -27,6 +27,60 @@
#include "libcli/security/security.h"
+/* the list of currently registered ACL backends */
+static struct pvfs_acl_backend {
+ const struct pvfs_acl_ops *ops;
+} *backends = NULL;
+static int num_backends;
+
+/*
+ register a pvfs acl backend.
+
+ The 'name' can be later used by other backends to find the operations
+ structure for this backend.
+*/
+_PUBLIC_ NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops)
+{
+ struct pvfs_acl_ops *new_ops;
+
+ if (pvfs_acl_backend_byname(ops->name) != NULL) {
+ DEBUG(0,("pvfs acl backend '%s' already registered\n", ops->name));
+ return NT_STATUS_OBJECT_NAME_COLLISION;
+ }
+
+ backends = talloc_realloc(talloc_autofree_context(), backends, struct pvfs_acl_backend, num_backends+1);
+ NT_STATUS_HAVE_NO_MEMORY(backends);
+
+ new_ops = talloc_memdup(backends, ops, sizeof(*ops));
+ new_ops->name = talloc_strdup(new_ops, ops->name);
+
+ backends[num_backends].ops = new_ops;
+
+ num_backends++;
+
+ DEBUG(3,("NTVFS backend '%s' registered\n", ops->name));
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ return the operations structure for a named backend
+*/
+_PUBLIC_ const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
+{
+ int i;
+
+ for (i=0;i<num_backends;i++) {
+ if (strcmp(backends[i].ops->name, name) == 0) {
+ return backends[i].ops;
+ }
+ }
+
+ return NULL;
+}
+
+
/*
map a single access_mask from generic to specific bits for files/dirs
*/
@@ -67,17 +121,18 @@ static void pvfs_translate_generic_bits(struct security_acl *acl)
static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
struct ntvfs_request *req,
struct pvfs_filename *name, int fd,
- struct xattr_NTACL *acl)
+ struct security_descriptor **psd)
{
struct security_descriptor *sd;
NTSTATUS status;
struct security_ace ace;
mode_t mode;
- sd = security_descriptor_initialise(req);
- if (sd == NULL) {
+ *psd = security_descriptor_initialise(req);
+ if (*psd == NULL) {
return NT_STATUS_NO_MEMORY;
}
+ sd = *psd;
status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid);
if (!NT_STATUS_IS_OK(status)) {
@@ -154,9 +209,6 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
ace.access_mask = SEC_RIGHTS_FILE_ALL;
security_descriptor_dacl_add(sd, &ace);
- acl->version = 1;
- acl->info.sd = sd;
-
return NT_STATUS_OK;
}
@@ -190,36 +242,24 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
uint32_t access_mask,
union smb_setfileinfo *info)
{
- struct xattr_NTACL *acl;
uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
struct security_descriptor *new_sd, *sd, orig_sd;
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_NOT_FOUND;
uid_t old_uid = -1;
gid_t old_gid = -1;
uid_t new_uid = -1;
gid_t new_gid = -1;
- acl = talloc(req, struct xattr_NTACL);
- if (acl == NULL) {
- return NT_STATUS_NO_MEMORY;
+ if (pvfs->acl_ops != NULL) {
+ status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
}
-
- 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);
+ status = pvfs_default_acl(pvfs, req, name, fd, &sd);
}
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- switch (acl->version) {
- case 1:
- sd = acl->info.sd;
- break;
- default:
- return NT_STATUS_INVALID_ACL;
- }
-
new_sd = info->set_secdesc.in.sd;
orig_sd = *sd;
@@ -286,8 +326,8 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
/* we avoid saving if the sd is the same. This means when clients
copy files and end up copying the default sd that we don't
needlessly use xattrs */
- if (!security_descriptor_equal(sd, &orig_sd)) {
- status = pvfs_acl_save(pvfs, name, fd, acl);
+ if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
+ status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
}
return status;
@@ -302,31 +342,19 @@ NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs,
struct pvfs_filename *name, int fd,
union smb_fileinfo *info)
{
- struct xattr_NTACL *acl;
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_NOT_FOUND;
struct security_descriptor *sd;
- acl = talloc(req, struct xattr_NTACL);
- if (acl == NULL) {
- return NT_STATUS_NO_MEMORY;
+ if (pvfs->acl_ops) {
+ status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
}
-
- 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);
+ status = pvfs_default_acl(pvfs, req, name, fd, &sd);
}
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- switch (acl->version) {
- case 1:
- sd = acl->info.sd;
- break;
- default:
- return NT_STATUS_INVALID_ACL;
- }
-
normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
info->query_secdesc.out.sd = sd;