Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Kick samba a little bit into understanding NFSv4 ACL's
Browse files Browse the repository at this point in the history
Ticket: #23566
  • Loading branch information
John Hixson committed May 20, 2017
1 parent e694a55 commit 1c7542f
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 10 deletions.
24 changes: 15 additions & 9 deletions python/samba/provision/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1533,19 +1533,22 @@ def setsysvolacl(samdb, netlogon, sysvol, uid, gid, domainsid, dnsdomain,
s3conf = s3param.get_context()
s3conf.load(lp.configfile)

file = tempfile.NamedTemporaryFile(dir=os.path.abspath(sysvol))
sysvol_dir = os.path.abspath(sysvol)
if smbd.has_posix_acls(sysvol_dir):
set_simple_acl = smbd.set_simple_acl
elif smbd.has_nfsv4_acls(sysvol_dir):
set_simple_acl = smbd.set_simple_nfsv4_acl

file = tempfile.NamedTemporaryFile(dir=sysvol_dir)
try:
try:
smbd.set_simple_acl(file.name, 0755, gid)
set_simple_acl(file.name, 0755, gid)
except OSError:
if not smbd.have_posix_acls():
# This clue is only strictly correct for RPM and
# Debian-like Linux systems, but hopefully other users
# will get enough clue from it.
raise ProvisioningError("Samba was compiled without the posix ACL support that s3fs requires. "
print "OSERROR OCCURED AFTER SETTING ACL"
if not smbd.have_posix_acls() and not smbd.have_nfsv4_acls():
raise ProvisioningError("Samba was compiled without the ACL support that s3fs requires. "
"Try installing libacl1-dev or libacl-devel, then re-run configure and make.")

raise ProvisioningError("Your filesystem or build does not support posix ACLs, which s3fs requires. "
raise ProvisioningError("Your filesystem or build does not support ACLs, which s3fs requires. "
"Try the mounting the filesystem with the 'acl' option.")
try:
smbd.chown(file.name, uid, gid)
Expand Down Expand Up @@ -1798,6 +1801,9 @@ def provision_fill(samdb, secrets_ldb, logger, names, paths,
samdb.transaction_commit()

if serverrole == "active directory domain controller":
if smbd.have_nfsv4_acls() and smbd.has_nfsv4_acls(targetdir):
smbd.set_nfsv4_defaults()

# Continue setting up sysvol for GPO. This appears to require being
# outside a transaction.
if not skip_sysvolacl:
Expand Down
10 changes: 10 additions & 0 deletions source3/lib/sysacls.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@
#include "modules/vfs_hpuxacl.h"
#endif

/*
* NFSv4 ACL's should be understood and a first class citizen. Work
* needs to be done in librpc/idl/smb_acl.idl for this to occur.
*/
#if defined(HAVE_LIBSUNACL) && defined(FREEBSD)
#if 0
#include "modules/nfs4_acls.h"
#endif
#endif

#undef DBGC_CLASS
#define DBGC_CLASS DBGC_ACLS

Expand Down
7 changes: 7 additions & 0 deletions source3/param/loadparm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2706,6 +2706,13 @@ static void init_locals(void)
} else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
} else {
/*
* This should only set dfs_samba4 and leave acl_xattr
* to be set later (or zfsacl). The only reason the decision
* can't be made here to load acl_xattr or zfsacl is
* that we don't have access to what the target
* directory is.
*/
lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
}
}
Expand Down
156 changes: 155 additions & 1 deletion source3/smbd/pysmbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,18 @@ static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode)
return acl;
}

static SMB_ACL_T make_simple_nfsv4_acl(gid_t gid, mode_t chmod_mode)
{
/*
* This function needs to create an NFSv4 ACL. Currently, the only way
* to do so is to use the operating system interface, or to use the
* functions in source3/modules/nfs4_acls.c. These seems ugly and
* hacky. NFSv4 ACL's should be a first class citizen and
* librpc/idl/smb_acl.idl should be modified accordingly.
*/
return NULL;
}

/*
set a simple ACL on a file, as a test
*/
Expand Down Expand Up @@ -353,6 +365,53 @@ static PyObject *py_smbd_set_simple_acl(PyObject *self, PyObject *args, PyObject
}

ret = set_sys_acl_conn(fname, SMB_ACL_TYPE_ACCESS, acl, conn);

TALLOC_FREE(acl);

if (ret != 0) {
TALLOC_FREE(frame);
errno = ret;
return PyErr_SetFromErrno(PyExc_OSError);
}

TALLOC_FREE(frame);

Py_RETURN_NONE;
}

/*
set a simple NFSv4 ACL on a file, as a test
*/
static PyObject *py_smbd_set_simple_nfsv4_acl(PyObject *self, PyObject *args, PyObject *kwargs)
{
const char * const kwnames[] = { "fname", "mode", "gid", "service", NULL };
char *fname, *service = NULL;
int ret;
int mode, gid = -1;
SMB_ACL_T acl;
TALLOC_CTX *frame;
connection_struct *conn;

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|iz",
discard_const_p(char *, kwnames),
&fname, &mode, &gid, &service))
return NULL;

acl = make_simple_nfsv4_acl(gid, mode);

frame = talloc_stackframe();

conn = get_conn(frame, service);
if (!conn) {
return NULL;
}

/*
* SMB_ACL_TYPE_ACCESS -> ACL_TYPE_ACCESS -> Not valid for NFSv4 ACL
*/
//ret = set_sys_acl_conn(fname, SMB_ACL_TYPE_ACCESS, acl, conn);
ret = 0;

TALLOC_FREE(acl);

if (ret != 0) {
Expand Down Expand Up @@ -473,7 +532,7 @@ static PyObject *py_smbd_unlink(PyObject *self, PyObject *args, PyObject *kwargs
}

/*
check if we have ACL support
check if we have POSIX.1e ACL support
*/
static PyObject *py_smbd_have_posix_acls(PyObject *self)
{
Expand All @@ -484,6 +543,86 @@ static PyObject *py_smbd_have_posix_acls(PyObject *self)
#endif
}

static PyObject *py_smbd_has_posix_acls(PyObject *self, PyObject *args, PyObject *kwargs)
{
const char * const kwnames[] = { "path", NULL };
char *path = NULL;
TALLOC_CTX *frame;
struct statfs fs;
int ret = false;

frame = talloc_stackframe();

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|z",
discard_const_p(char *, kwnames), &path)) {
TALLOC_FREE(frame);
return NULL;
}

if (statfs(path, &fs) != 0) {
TALLOC_FREE(frame);
return NULL;
}

if (fs.f_flags & MNT_ACLS)
ret = true;

TALLOC_FREE(frame);
return PyBool_FromLong(ret);
}

/*
check if we have NFSv4 ACL support
*/
static PyObject *py_smbd_have_nfsv4_acls(PyObject *self)
{
#ifdef HAVE_LIBSUNACL
return PyBool_FromLong(true);
#else
return PyBool_FromLong(false);
#endif
}

static PyObject *py_smbd_has_nfsv4_acls(PyObject *self, PyObject *args, PyObject *kwargs)
{
const char * const kwnames[] = { "path", NULL };
char *path = NULL;
TALLOC_CTX *frame;
struct statfs fs;
int ret = false;

frame = talloc_stackframe();

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|z",
discard_const_p(char *, kwnames), &path)) {
TALLOC_FREE(frame);
return NULL;
}

if (statfs(path, &fs) != 0) {
TALLOC_FREE(frame);
return NULL;
}

if (fs.f_flags & MNT_NFS4ACLS)
ret = true;

TALLOC_FREE(frame);
return PyBool_FromLong(ret);
}


static PyObject *py_smbd_set_nfsv4_defaults(PyObject *self)
{
/*
* This should really be done in source3/param/loadparm.c
*/
#if defined(HAVE_LIBSUNACL) && defined(FREEBSD)
lp_do_parameter(-1, "vfs objects", "dfs_samba4 zfsacl");
#endif
Py_RETURN_NONE;
}

/*
set the NT ACL on a file
*/
Expand Down Expand Up @@ -661,9 +800,24 @@ static PyMethodDef py_smbd_methods[] = {
{ "have_posix_acls",
(PyCFunction)py_smbd_have_posix_acls, METH_NOARGS,
NULL },
{ "has_posix_acls",
(PyCFunction)py_smbd_has_posix_acls, METH_VARARGS|METH_KEYWORDS,
NULL },
{ "have_nfsv4_acls",
(PyCFunction)py_smbd_have_nfsv4_acls, METH_NOARGS,
NULL },
{ "has_nfsv4_acls",
(PyCFunction)py_smbd_has_nfsv4_acls, METH_VARARGS|METH_KEYWORDS,
NULL },
{ "set_nfsv4_defaults",
(PyCFunction)py_smbd_set_nfsv4_defaults, METH_NOARGS,
NULL },
{ "set_simple_acl",
(PyCFunction)py_smbd_set_simple_acl, METH_VARARGS|METH_KEYWORDS,
NULL },
{ "set_simple_nfsv4_acl",
(PyCFunction)py_smbd_set_simple_nfsv4_acl, METH_VARARGS|METH_KEYWORDS,
NULL },
{ "set_nt_acl",
(PyCFunction)py_smbd_set_nt_acl, METH_VARARGS|METH_KEYWORDS,
NULL },
Expand Down

0 comments on commit 1c7542f

Please sign in to comment.