From 55a0d6606c76463296188582c52821a7607ade7b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 2 Aug 2012 13:35:24 +1000 Subject: s3-pysmbd: Add set_nt_acl() function based on parts of vfstest This will allow us to set the full NT ACL on a file, using the VFS layer, during provision of the AD DC. Andrew Bartlett --- source3/smbd/pysmbd.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) (limited to 'source3/smbd') diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c index 5badb3a744..6478319756 100644 --- a/source3/smbd/pysmbd.c +++ b/source3/smbd/pysmbd.c @@ -4,6 +4,8 @@ Copyright (C) Jeremy Allison 1994-2009. Copyright (C) Andreas Gruenbacher 2002. Copyright (C) Simo Sorce 2009. + Copyright (C) Simo Sorce 2002 + Copyright (C) Eric Lorimer 2002 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 @@ -23,6 +25,9 @@ #include "smbd/smbd.h" #include #include "libcli/util/pyerrors.h" +#include "librpc/rpc/pyrpc_util.h" +#include +#include "system/filesys.h" extern const struct generic_mapping file_generic_mapping; @@ -66,6 +71,83 @@ static NTSTATUS set_sys_acl_no_snum(const char *fname, return status; } +static NTSTATUS set_nt_acl_no_snum(const char *fname, + uint32 security_info_sent, const struct security_descriptor *sd) +{ + TALLOC_CTX *frame = talloc_stackframe(); + connection_struct *conn; + NTSTATUS status = NT_STATUS_OK; + files_struct *fsp; + struct smb_filename *smb_fname = NULL; + int flags; + + conn = talloc_zero(frame, connection_struct); + if (conn == NULL) { + DEBUG(0, ("talloc failed\n")); + return NT_STATUS_NO_MEMORY; + } + + if (!(conn->params = talloc(conn, struct share_params))) { + DEBUG(0,("get_nt_acl_no_snum: talloc() failed!\n")); + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + + conn->params->service = -1; + + set_conn_connectpath(conn, "/"); + + smbd_vfs_init(conn); + + fsp = talloc(frame, struct files_struct); + if (fsp == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + fsp->fh = talloc(fsp, struct fd_handle); + if (fsp->fh == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + fsp->conn = conn; + + status = create_synthetic_smb_fname_split(fsp, fname, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + fsp->fsp_name = smb_fname; + +#ifdef O_DIRECTORY + flags = O_RDONLY|O_DIRECTORY; +#else + /* POSIX allows us to open a directory with O_RDONLY. */ + flags = O_RDONLY; +#endif + + fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, 00400); + if (fsp->fh->fd == -1 && errno == EISDIR) { + fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, O_RDWR, 00400); + } + if (fsp->fh->fd == -1) { + printf("open: error=%d (%s)\n", errno, strerror(errno)); + TALLOC_FREE(frame); + return NT_STATUS_UNSUCCESSFUL; + } + + status = SMB_VFS_FSET_NT_ACL( fsp, security_info_sent, sd); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("set_nt_acl_no_snum: fset_nt_acl returned %s.\n", nt_errstr(status))); + } + + conn_free(conn); + TALLOC_FREE(frame); + + return status; +} + static SMB_ACL_T make_simple_acl(uid_t uid, gid_t gid) { @@ -195,6 +277,32 @@ static PyObject *py_smbd_have_posix_acls(PyObject *self, PyObject *args) #endif } +/* + set a simple ACL on a file, as a test + */ +static PyObject *py_smbd_set_nt_acl(PyObject *self, PyObject *args) +{ + NTSTATUS status; + char *fname; + int security_info_sent; + PyObject *py_sd; + struct security_descriptor *sd; + + if (!PyArg_ParseTuple(args, "siO", &fname, &security_info_sent, &py_sd)) + return NULL; + + if (!py_check_dcerpc_type(py_sd, "samba.dcerpc.security", "descriptor")) { + return NULL; + } + + sd = pytalloc_get_type(py_sd, struct security_descriptor); + + status = set_nt_acl_no_snum(fname, security_info_sent, sd); + PyErr_NTSTATUS_IS_ERR_RAISE(status); + + Py_RETURN_NONE; +} + static PyMethodDef py_smbd_methods[] = { { "have_posix_acls", (PyCFunction)py_smbd_have_posix_acls, METH_VARARGS, @@ -202,6 +310,9 @@ static PyMethodDef py_smbd_methods[] = { { "set_simple_acl", (PyCFunction)py_smbd_set_simple_acl, METH_VARARGS, NULL }, + { "set_nt_acl", + (PyCFunction)py_smbd_set_nt_acl, METH_VARARGS, + NULL }, { NULL } }; -- cgit