posix-acl: implementation of POSIX ACL as a translator

Signed-off-by: Anand Avati <avati@gluster.com>

BUG: 2815 (Server-enforced ACLs)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2815
This commit is contained in:
Anand Avati 2011-07-01 17:18:10 +00:00
parent 6433214452
commit 04ed499a8e
10 changed files with 2145 additions and 1 deletions

View File

@ -105,6 +105,9 @@ AC_CONFIG_FILES([Makefile
xlators/encryption/Makefile
xlators/encryption/rot-13/Makefile
xlators/encryption/rot-13/src/Makefile
xlators/system/Makefile
xlators/system/posix-acl/Makefile
xlators/system/posix-acl/src/Makefile
cli/Makefile
cli/src/Makefile
doc/Makefile

View File

@ -1,3 +1,3 @@
SUBDIRS = cluster storage protocol performance debug features encryption mount nfs mgmt
SUBDIRS = cluster storage protocol performance debug features encryption mount nfs mgmt system
CLEANFILES =

View File

@ -4598,6 +4598,12 @@ init (xlator_t *this)
}
}
op_ret = sys_lgetxattr (dir_data->data, "system.posix_acl_access",
NULL, 0);
if ((op_ret < 0) && (errno == ENOTSUP))
gf_log (this->name, GF_LOG_WARNING,
"Posix access control list is not supported.");
_private = GF_CALLOC (1, sizeof (*_private),
gf_posix_mt_posix_private);
if (!_private) {

View File

@ -0,0 +1 @@
SUBDIRS = posix-acl

View File

@ -0,0 +1 @@
SUBDIRS = src

View File

@ -0,0 +1,13 @@
xlator_LTLIBRARIES = posix-acl.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/system
posix_acl_la_LDFLAGS = -module -avoidversion
posix_acl_la_SOURCES = posix-acl.c posix-acl-xattr.c
posix_acl_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
noinst_HEADERS = posix-acl.h posix-acl-xattr.h
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\
-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)\
-L$(xlatordir)/
CLEANFILES =

View File

@ -0,0 +1,190 @@
/*
Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS 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
Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include "posix-acl.h"
#include "posix-acl-xattr.h"
int
posix_ace_cmp (const void *val1, const void *val2)
{
const struct posix_ace *ace1 = NULL;
const struct posix_ace *ace2 = NULL;
int ret = 0;
ace1 = val1;
ace2 = val2;
ret = (ace1->tag - ace2->tag);
if (!ret)
ret = (ace1->id - ace2->id);
return ret;
}
void
posix_acl_normalize (xlator_t *this, struct posix_acl *acl)
{
qsort (acl->entries, acl->count, sizeof (struct posix_ace *),
posix_ace_cmp);
}
struct posix_acl *
posix_acl_from_xattr (xlator_t *this, const char *xattr_buf, int xattr_size)
{
struct posix_acl_xattr_header *header = NULL;
struct posix_acl_xattr_entry *entry = NULL;
struct posix_acl *acl = NULL;
struct posix_ace *ace = NULL;
int size = 0;
int count = 0;
int i = 0;
size = xattr_size;
if (size < sizeof (*header))
return NULL;
size -= sizeof (*header);
if (size % sizeof (*entry))
return NULL;
count = size / sizeof (*entry);
header = (struct posix_acl_xattr_header *) (xattr_buf);
entry = (struct posix_acl_xattr_entry *) (header + 1);
if (header->version != htole32 (POSIX_ACL_VERSION))
return NULL;
acl = posix_acl_new (this, count);
if (!acl)
return NULL;
ace = acl->entries;
for (i = 0; i < count; i++) {
ace->tag = letoh16 (entry->tag);
ace->perm = letoh16 (entry->perm);
switch (ace->tag) {
case POSIX_ACL_USER_OBJ:
case POSIX_ACL_GROUP_OBJ:
case POSIX_ACL_MASK:
case POSIX_ACL_OTHER:
ace->id = POSIX_ACL_UNDEFINED_ID;
break;
case POSIX_ACL_GROUP:
case POSIX_ACL_USER:
ace->id = letoh32 (entry->id);
break;
default:
goto err;
}
ace++;
entry++;
}
posix_acl_normalize (this, acl);
return acl;
err:
posix_acl_destroy (this, acl);
return NULL;
}
int
posix_acl_to_xattr (xlator_t *this, struct posix_acl *acl, char *xattr_buf,
int xattr_size)
{
int size = 0;
struct posix_acl_xattr_header *header = NULL;
struct posix_acl_xattr_entry *entry = NULL;
struct posix_ace *ace = NULL;
int i = 0;
size = sizeof (*header) + (acl->count * sizeof (*entry));
if (xattr_size < size)
return size;
header = (struct posix_acl_xattr_header *) (xattr_buf);
entry = (struct posix_acl_xattr_entry *) (header + 1);
ace = acl->entries;
header->version = htole32 (POSIX_ACL_VERSION);
for (i = 0; i < acl->count; i++) {
entry->tag = htole16 (ace->tag);
entry->perm = htole16 (ace->perm);
switch (ace->tag) {
case POSIX_ACL_USER:
case POSIX_ACL_GROUP:
entry->id = htole32 (ace->id);
break;
default:
entry->id = POSIX_ACL_UNDEFINED_ID;
break;
}
ace++;
entry++;
}
return 0;
}
int
posix_acl_matches_xattr (xlator_t *this, struct posix_acl *acl, const char *buf,
int size)
{
struct posix_acl *acl2 = NULL;
int ret = 1;
acl2 = posix_acl_from_xattr (this, buf, size);
if (!acl2)
return 0;
if (acl->count != acl2->count) {
ret = 0;
goto out;
}
if (memcmp (acl->entries, acl2->entries,
(acl->count * sizeof (struct posix_ace))))
ret = 0;
out:
posix_acl_destroy (this, acl2);
return ret;
}

View File

@ -0,0 +1,52 @@
/*
Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS 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
Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
#ifndef _POSIX_ACL_XATTR_H
#define _POSIX_ACL_XATTR_H
#include <stdint.h>
#include "common-utils.h"
#include "posix-acl.h"
#define POSIX_ACL_ACCESS_XATTR "system.posix_acl_access"
#define POSIX_ACL_DEFAULT_XATTR "system.posix_acl_default"
#define POSIX_ACL_VERSION 2
struct posix_acl_xattr_entry {
uint16_t tag;
uint16_t perm;
uint32_t id;
};
struct posix_acl_xattr_header {
uint32_t version;
struct posix_acl_xattr_entry entries[0];
};
struct posix_acl *posix_acl_from_xattr (xlator_t *this, const char *buf, int size);
int posix_acl_to_xattr (xlator_t *this, struct posix_acl *acl, char *buf, int size);
int posix_acl_matches_xattr (xlator_t *this, struct posix_acl *acl, const char *buf, int size);
#endif /* !_POSIX_ACL_XATTR_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,86 @@
/*
Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS 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
Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
#ifndef _POSIX_ACL_H
#define _POSIX_ACL_H
#include <stdint.h>
#include "xlator.h"
#include "common-utils.h"
#include "byte-order.h"
#define POSIX_ACL_READ (0x04)
#define POSIX_ACL_WRITE (0x02)
#define POSIX_ACL_EXECUTE (0x01)
#define POSIX_ACL_UNDEFINED_TAG (0x00)
#define POSIX_ACL_USER_OBJ (0x01)
#define POSIX_ACL_USER (0x02)
#define POSIX_ACL_GROUP_OBJ (0x04)
#define POSIX_ACL_GROUP (0x08)
#define POSIX_ACL_MASK (0x10)
#define POSIX_ACL_OTHER (0x20)
#define POSIX_ACL_UNDEFINED_ID ((id_t)-1)
struct posix_ace {
uint16_t tag;
uint16_t perm;
uint32_t id;
};
struct posix_acl {
int refcnt;
int count;
struct posix_ace entries[0];
};
struct posix_acl_ctx {
uid_t uid;
gid_t gid;
mode_t perm;
struct posix_acl *acl_access;
struct posix_acl *acl_default;
};
struct posix_acl_conf {
gf_lock_t acl_lock;
struct posix_acl *minimal_acl;
};
struct posix_acl *posix_acl_new (xlator_t *this, int entry_count);
struct posix_acl *posix_acl_ref (xlator_t *this, struct posix_acl *acl);
void posix_acl_unref (xlator_t *this, struct posix_acl *acl);
void posix_acl_destroy (xlator_t *this, struct posix_acl *acl);
struct posix_acl_ctx *posix_acl_ctx_get (inode_t *inode, xlator_t *this);
int posix_acl_get (inode_t *inode, xlator_t *this,
struct posix_acl **acl_access_p,
struct posix_acl **acl_default_p);
int posix_acl_set (inode_t *inode, xlator_t *this, struct posix_acl *acl_access,
struct posix_acl *acl_default);
#endif /* !_POSIX_ACL_H */