summaryrefslogtreecommitdiffstats
path: root/source4/librpc/ndr
diff options
context:
space:
mode:
Diffstat (limited to 'source4/librpc/ndr')
-rw-r--r--source4/librpc/ndr/py_auth.c76
-rw-r--r--source4/librpc/ndr/py_lsa.c77
-rw-r--r--source4/librpc/ndr/py_misc.c165
-rw-r--r--source4/librpc/ndr/py_security.c743
-rw-r--r--source4/librpc/ndr/py_xattr.c100
5 files changed, 1161 insertions, 0 deletions
diff --git a/source4/librpc/ndr/py_auth.c b/source4/librpc/ndr/py_auth.c
new file mode 100644
index 0000000..8d233b3
--- /dev/null
+++ b/source4/librpc/ndr/py_auth.c
@@ -0,0 +1,76 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2011
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2011
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "lib/replace/system/python.h"
+#include "includes.h"
+#include "libcli/util/pyerrors.h"
+#include "pyauth.h"
+#include "auth/auth.h"
+#include "auth/credentials/pycredentials.h"
+#include "librpc/rpc/pyrpc_util.h"
+
+static void PyType_AddGetSet(PyTypeObject *type, PyGetSetDef *getset)
+{
+ PyObject *dict;
+ int i;
+ if (type->tp_dict == NULL)
+ type->tp_dict = PyDict_New();
+ dict = type->tp_dict;
+ for (i = 0; getset[i].name; i++) {
+ PyObject *descr;
+ descr = PyDescr_NewGetSet(type, &getset[i]);
+ PyDict_SetItemString(dict, getset[i].name,
+ descr);
+ Py_CLEAR(descr);
+ }
+}
+
+static PyObject *py_auth_session_get_credentials(PyObject *self, void *closure)
+{
+ struct auth_session_info *session = pytalloc_get_type(self, struct auth_session_info);
+ PyObject *py_credentials;
+ /* This is evil, as the credentials are not IDL structures */
+ py_credentials = py_return_ndr_struct("samba.credentials", "Credentials", session->credentials, session->credentials);
+ return py_credentials;
+}
+
+static int py_auth_session_set_credentials(PyObject *self, PyObject *value, void *closure)
+{
+ struct auth_session_info *session = pytalloc_get_type(self, struct auth_session_info);
+ session->credentials = talloc_reference(session, PyCredentials_AsCliCredentials(value));
+ return 0;
+}
+
+static PyGetSetDef py_auth_session_extra_getset[] = {
+ {
+ .name = discard_const_p(char, "credentials"),
+ .get = (getter)py_auth_session_get_credentials,
+ .set = (setter)py_auth_session_set_credentials,
+ },
+ { .name = NULL },
+};
+
+static void py_auth_session_info_patch(PyTypeObject *type)
+{
+ PyType_AddGetSet(type, py_auth_session_extra_getset);
+}
+
+#define PY_SESSION_INFO_PATCH py_auth_session_info_patch
+
diff --git a/source4/librpc/ndr/py_lsa.c b/source4/librpc/ndr/py_lsa.c
new file mode 100644
index 0000000..c5e221f
--- /dev/null
+++ b/source4/librpc/ndr/py_lsa.c
@@ -0,0 +1,77 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+
+ Copyright (C) Catalyst IT 2017
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+#include "lib/replace/system/python.h"
+#include "librpc/gen_ndr/lsa.h"
+
+static PyObject *py_lsa_String_str(PyObject *py_self)
+{
+ struct lsa_String *self = pytalloc_get_ptr(py_self);
+ PyObject *ret = NULL;
+ if (self->string == NULL) {
+ const char *empty = "";
+ ret = PyUnicode_FromString(empty);
+ } else {
+ ret = PyUnicode_FromString(self->string);
+ }
+ return ret;
+}
+
+static PyObject *py_lsa_String_repr(PyObject *py_self)
+{
+ struct lsa_String *self = pytalloc_get_ptr(py_self);
+ PyObject *ret = NULL;
+ if (self->string == NULL) {
+ const char *empty = "lsaString(None)";
+ ret = PyUnicode_FromString(empty);
+ } else {
+ ret = PyUnicode_FromFormat("lsaString('%s')", self->string);
+ }
+ return ret;
+}
+
+static int py_lsa_String_init(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ struct lsa_String *string = pytalloc_get_ptr(self);
+ const char *str = NULL;
+ const char *kwnames[] = { "str", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &str))
+ return -1;
+
+ string->string = talloc_strdup(string, str);
+
+ if (str != NULL && string->string == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static void py_lsa_String_patch(PyTypeObject *type)
+{
+ type->tp_init = py_lsa_String_init;
+ type->tp_str = py_lsa_String_str;
+ type->tp_repr = py_lsa_String_repr;
+}
+
+#define PY_STRING_PATCH py_lsa_String_patch
+
diff --git a/source4/librpc/ndr/py_misc.c b/source4/librpc/ndr/py_misc.c
new file mode 100644
index 0000000..16e2960
--- /dev/null
+++ b/source4/librpc/ndr/py_misc.c
@@ -0,0 +1,165 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+#include "lib/replace/system/python.h"
+#include "python/py3compat.h"
+#include "librpc/gen_ndr/misc.h"
+
+static PyObject *py_GUID_richcmp(PyObject *py_self, PyObject *py_other, int op)
+{
+ int ret;
+ struct GUID *self = pytalloc_get_ptr(py_self), *other;
+ other = pytalloc_get_ptr(py_other);
+ if (other == NULL) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ ret = GUID_compare(self, other);
+
+ switch (op) {
+ case Py_EQ: if (ret == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+ case Py_NE: if (ret != 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+ case Py_LT: if (ret < 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+ case Py_GT: if (ret > 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+ case Py_LE: if (ret <= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+ case Py_GE: if (ret >= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+static PyObject *py_GUID_str(PyObject *py_self)
+{
+ struct GUID *self = pytalloc_get_ptr(py_self);
+ struct GUID_txt_buf buf;
+ PyObject *ret = PyUnicode_FromString(GUID_buf_string(self, &buf));
+ return ret;
+}
+
+static PyObject *py_GUID_repr(PyObject *py_self)
+{
+ struct GUID *self = pytalloc_get_ptr(py_self);
+ struct GUID_txt_buf buf;
+ PyObject *ret = PyUnicode_FromFormat(
+ "GUID('%s')", GUID_buf_string(self, &buf));
+ return ret;
+}
+
+static int py_GUID_init(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ PyObject *str = NULL;
+ NTSTATUS status;
+ struct GUID *guid = pytalloc_get_ptr(self);
+ const char *kwnames[] = { "str", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", discard_const_p(char *, kwnames), &str))
+ return -1;
+
+ if (str != NULL) {
+ DATA_BLOB guid_val;
+ Py_ssize_t _size;
+
+ if (PyUnicode_Check(str)) {
+ guid_val.data =
+ discard_const_p(uint8_t,
+ PyUnicode_AsUTF8AndSize(str, &_size));
+ } else if (PyBytes_Check(str)) {
+ guid_val.data =
+ discard_const_p(uint8_t,
+ PyBytes_AsString(str));
+ _size = PyBytes_Size(str);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "Expected a string or bytes argument to GUID()");
+ return -1;
+ }
+ guid_val.length = _size;
+ status = GUID_from_data_blob(&guid_val, guid);
+ if (!NT_STATUS_IS_OK(status)) {
+ PyErr_SetNTSTATUS(status);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void py_GUID_patch(PyTypeObject *type)
+{
+ type->tp_init = py_GUID_init;
+ type->tp_str = py_GUID_str;
+ type->tp_repr = py_GUID_repr;
+ type->tp_richcompare = py_GUID_richcmp;
+}
+
+#define PY_GUID_PATCH py_GUID_patch
+
+static int py_policy_handle_init(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ char *str = NULL;
+ NTSTATUS status;
+ struct policy_handle *handle = pytalloc_get_ptr(self);
+ const char *kwnames[] = { "uuid", "type", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|sI", discard_const_p(char *, kwnames), &str, &handle->handle_type))
+ return -1;
+
+ if (str != NULL) {
+ status = GUID_from_string(str, &handle->uuid);
+ if (!NT_STATUS_IS_OK(status)) {
+ PyErr_SetNTSTATUS(status);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static PyObject *py_policy_handle_repr(PyObject *py_self)
+{
+ struct policy_handle *self = pytalloc_get_ptr(py_self);
+ struct GUID_txt_buf buf;
+ PyObject *ret = PyUnicode_FromFormat(
+ "policy_handle(%d, '%s')",
+ self->handle_type,
+ GUID_buf_string(&self->uuid, &buf));
+ return ret;
+}
+
+static PyObject *py_policy_handle_str(PyObject *py_self)
+{
+ struct policy_handle *self = pytalloc_get_ptr(py_self);
+ struct GUID_txt_buf buf;
+ PyObject *ret = PyUnicode_FromFormat(
+ "%d, %s",
+ self->handle_type,
+ GUID_buf_string(&self->uuid, &buf));
+ return ret;
+}
+
+static void py_policy_handle_patch(PyTypeObject *type)
+{
+ type->tp_init = py_policy_handle_init;
+ type->tp_repr = py_policy_handle_repr;
+ type->tp_str = py_policy_handle_str;
+}
+
+#define PY_POLICY_HANDLE_PATCH py_policy_handle_patch
+
diff --git a/source4/librpc/ndr/py_security.c b/source4/librpc/ndr/py_security.c
new file mode 100644
index 0000000..581f06e
--- /dev/null
+++ b/source4/librpc/ndr/py_security.c
@@ -0,0 +1,743 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008-2010
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+#include "lib/replace/system/python.h"
+#include "gen_ndr/conditional_ace.h"
+#include "py3compat.h"
+#include "libcli/security/sddl.h"
+#include "libcli/security/security.h"
+
+
+/* Set up in py_mod_security_patch() */
+static PyObject *PyExc_SDDLValueError = NULL;
+
+
+static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods)
+{
+ PyObject *dict;
+ int i;
+ if (type->tp_dict == NULL)
+ type->tp_dict = PyDict_New();
+ dict = type->tp_dict;
+ for (i = 0; methods[i].ml_name; i++) {
+ PyObject *descr;
+ if (methods[i].ml_flags & METH_CLASS)
+ descr = PyCFunction_New(&methods[i], (PyObject *)type);
+ else
+ descr = PyDescr_NewMethod(type, &methods[i]);
+ PyDict_SetItemString(dict, methods[i].ml_name,
+ descr);
+ Py_CLEAR(descr);
+ }
+}
+
+static PyObject *py_dom_sid_split(PyObject *py_self, PyObject *args)
+{
+ struct dom_sid *self = pytalloc_get_ptr(py_self);
+ struct dom_sid *domain_sid;
+ TALLOC_CTX *mem_ctx;
+ uint32_t rid;
+ NTSTATUS status;
+ PyObject *py_domain_sid;
+
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ status = dom_sid_split_rid(mem_ctx, self, &domain_sid, &rid);
+ if (!NT_STATUS_IS_OK(status)) {
+ PyErr_SetString(PyExc_RuntimeError, "dom_sid_split_rid failed");
+ talloc_free(mem_ctx);
+ return NULL;
+ }
+
+ py_domain_sid = pytalloc_steal(&dom_sid_Type, domain_sid);
+ talloc_free(mem_ctx);
+ return Py_BuildValue("(OI)", py_domain_sid, rid);
+}
+
+static PyObject *py_dom_sid_richcmp(PyObject *py_self, PyObject *py_other, int op)
+{
+ struct dom_sid *self = pytalloc_get_ptr(py_self), *other;
+ int val;
+
+ other = pytalloc_get_ptr(py_other);
+ if (other == NULL) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ val = dom_sid_compare(self, other);
+
+ switch (op) {
+ case Py_EQ: if (val == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+ case Py_NE: if (val != 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+ case Py_LT: if (val < 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+ case Py_GT: if (val > 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+ case Py_LE: if (val <= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+ case Py_GE: if (val >= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+static PyObject *py_dom_sid_str(PyObject *py_self)
+{
+ struct dom_sid *self = pytalloc_get_ptr(py_self);
+ struct dom_sid_buf buf;
+ PyObject *ret = PyUnicode_FromString(dom_sid_str_buf(self, &buf));
+ return ret;
+}
+
+static PyObject *py_dom_sid_repr(PyObject *py_self)
+{
+ struct dom_sid *self = pytalloc_get_ptr(py_self);
+ struct dom_sid_buf buf;
+ PyObject *ret = PyUnicode_FromFormat(
+ "dom_sid('%s')", dom_sid_str_buf(self, &buf));
+ return ret;
+}
+
+static int py_dom_sid_init(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ char *str = NULL;
+ struct dom_sid *sid = pytalloc_get_ptr(self);
+ const char *kwnames[] = { "str", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &str))
+ return -1;
+
+ if (str != NULL && !dom_sid_parse(str, sid)) {
+ PyErr_Format(PyExc_ValueError,
+ "Unable to parse string: '%s'", str);
+ return -1;
+ }
+
+ return 0;
+}
+
+static PyMethodDef py_dom_sid_extra_methods[] = {
+ { "split", (PyCFunction)py_dom_sid_split, METH_NOARGS,
+ "S.split() -> (domain_sid, rid)\n"
+ "Split a domain sid" },
+ {0}
+};
+
+
+static void py_dom_sid_patch(PyTypeObject *type)
+{
+ type->tp_init = py_dom_sid_init;
+ type->tp_str = py_dom_sid_str;
+ type->tp_repr = py_dom_sid_repr;
+ type->tp_richcompare = py_dom_sid_richcmp;
+ PyType_AddMethods(type, py_dom_sid_extra_methods);
+}
+
+#define PY_DOM_SID_PATCH py_dom_sid_patch
+
+static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args)
+{
+ struct security_descriptor *desc = pytalloc_get_ptr(self);
+ NTSTATUS status;
+ struct security_ace *ace;
+ PyObject *py_ace;
+ Py_ssize_t idx = -1;
+
+ if (!PyArg_ParseTuple(args, "O|n", &py_ace, &idx))
+ return NULL;
+
+ ace = pytalloc_get_ptr(py_ace);
+ status = security_descriptor_sacl_insert(desc, ace, idx);
+ PyErr_NTSTATUS_IS_ERR_RAISE(status);
+ Py_RETURN_NONE;
+}
+
+static PyObject *py_descriptor_dacl_add(PyObject *self, PyObject *args)
+{
+ struct security_descriptor *desc = pytalloc_get_ptr(self);
+ NTSTATUS status;
+ struct security_ace *ace;
+ PyObject *py_ace;
+ Py_ssize_t idx = -1;
+
+ if (!PyArg_ParseTuple(args, "O|n", &py_ace, &idx))
+ return NULL;
+
+ ace = pytalloc_get_ptr(py_ace);
+
+ status = security_descriptor_dacl_insert(desc, ace, idx);
+ PyErr_NTSTATUS_IS_ERR_RAISE(status);
+ Py_RETURN_NONE;
+}
+
+static PyObject *py_descriptor_dacl_del(PyObject *self, PyObject *args)
+{
+ struct security_descriptor *desc = pytalloc_get_ptr(self);
+ NTSTATUS status;
+ struct dom_sid *sid;
+ PyObject *py_sid;
+
+ if (!PyArg_ParseTuple(args, "O", &py_sid))
+ return NULL;
+
+ sid = pytalloc_get_ptr(py_sid);
+ status = security_descriptor_dacl_del(desc, sid);
+ PyErr_NTSTATUS_IS_ERR_RAISE(status);
+ Py_RETURN_NONE;
+}
+
+static PyObject *py_descriptor_sacl_del(PyObject *self, PyObject *args)
+{
+ struct security_descriptor *desc = pytalloc_get_ptr(self);
+ NTSTATUS status;
+ struct dom_sid *sid;
+ PyObject *py_sid;
+
+ if (!PyArg_ParseTuple(args, "O", &py_sid))
+ return NULL;
+
+ sid = pytalloc_get_ptr(py_sid);
+ status = security_descriptor_sacl_del(desc, sid);
+ PyErr_NTSTATUS_IS_ERR_RAISE(status);
+ Py_RETURN_NONE;
+}
+
+static PyObject *py_descriptor_dacl_del_ace(PyObject *self, PyObject *args)
+{
+ struct security_descriptor *desc = pytalloc_get_ptr(self);
+ NTSTATUS status;
+ struct security_ace *ace = NULL;
+ PyObject *py_ace = Py_None;
+
+ if (!PyArg_ParseTuple(args, "O!", &security_ace_Type, &py_ace))
+ return NULL;
+
+ if (!PyObject_TypeCheck(py_ace, &security_ace_Type)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected security.security_ace "
+ "for first argument to .dacl_del_ace");
+ return NULL;
+ }
+
+ ace = pytalloc_get_ptr(py_ace);
+ status = security_descriptor_dacl_del_ace(desc, ace);
+ PyErr_NTSTATUS_IS_ERR_RAISE(status);
+ Py_RETURN_NONE;
+}
+
+static PyObject *py_descriptor_sacl_del_ace(PyObject *self, PyObject *args)
+{
+ struct security_descriptor *desc = pytalloc_get_ptr(self);
+ NTSTATUS status;
+ struct security_ace *ace = NULL;
+ PyObject *py_ace = Py_None;
+
+ if (!PyArg_ParseTuple(args, "O!", &security_ace_Type, &py_ace))
+ return NULL;
+
+ if (!PyObject_TypeCheck(py_ace, &security_ace_Type)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected security.security_ace "
+ "for first argument to .sacl_del_ace");
+ return NULL;
+ }
+
+ ace = pytalloc_get_ptr(py_ace);
+ status = security_descriptor_sacl_del_ace(desc, ace);
+ PyErr_NTSTATUS_IS_ERR_RAISE(status);
+ Py_RETURN_NONE;
+}
+
+static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
+{
+ return pytalloc_steal(self, security_descriptor_initialise(NULL));
+}
+
+static PyObject *py_descriptor_from_sddl(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ static const char *kwnames[] = { "", "", "allow_device_in_sddl", NULL };
+ struct security_descriptor *secdesc;
+ char *sddl;
+ PyObject *py_sid;
+ int allow_device_in_sddl = 1;
+ struct dom_sid *sid;
+ const char *err_msg = NULL;
+ size_t err_msg_offset = 0;
+ enum ace_condition_flags ace_condition_flags = 0;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kwargs,
+ "sO!|$p",
+ discard_const_p(char *, kwnames),
+ &sddl,
+ &dom_sid_Type,
+ &py_sid,
+ &allow_device_in_sddl))
+ return NULL;
+
+ if (!PyObject_TypeCheck(py_sid, &dom_sid_Type)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected security.dom_sid "
+ "for second argument to .from_sddl");
+ return NULL;
+ }
+
+ sid = pytalloc_get_ptr(py_sid);
+
+ if (allow_device_in_sddl) {
+ ace_condition_flags |= ACE_CONDITION_FLAG_ALLOW_DEVICE;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ secdesc = sddl_decode_err_msg(tmp_ctx, sddl, sid,
+ ace_condition_flags,
+ &err_msg, &err_msg_offset);
+ if (secdesc == NULL) {
+ PyObject *exc = NULL;
+ if (err_msg == NULL) {
+ err_msg = "unknown error";
+ }
+ /*
+ * Some notes about this exception value:
+ *
+ * We don't want to add the offset first, so as not to
+ * confuse those who are used to the integer error
+ * code coming first.
+ *
+ * The errant sddl is added so that the exception can
+ * be caught some distance away from the call and we
+ * still know what the messages refer to.
+ */
+ exc = Py_BuildValue("(s, s, i, s)",
+ "Unable to parse SDDL",
+ err_msg,
+ err_msg_offset,
+ sddl);
+ if (exc == NULL) {
+ talloc_free(tmp_ctx);
+ /* an exception was set by Py_BuildValue() */
+ return NULL;
+ }
+ PyErr_SetObject(PyExc_SDDLValueError, exc);
+ Py_DECREF(exc);
+ talloc_free(tmp_ctx);
+ return NULL;
+ }
+
+ secdesc = talloc_steal(NULL, secdesc);
+ talloc_free(tmp_ctx);
+
+ return pytalloc_steal((PyTypeObject *)self, secdesc);
+}
+
+static PyObject *py_descriptor_as_sddl(PyObject *self, PyObject *args)
+{
+ struct dom_sid *sid;
+ PyObject *py_sid = Py_None;
+ struct security_descriptor *desc = pytalloc_get_ptr(self);
+ char *text;
+ PyObject *ret;
+
+ if (!PyArg_ParseTuple(args, "|O!", &dom_sid_Type, &py_sid))
+ return NULL;
+
+ if (py_sid != Py_None)
+ sid = pytalloc_get_ptr(py_sid);
+ else
+ sid = NULL;
+
+ text = sddl_encode(NULL, desc, sid);
+ if (text == NULL) {
+ PyErr_SetString(PyExc_ValueError, "Unable to encode SDDL");
+ return NULL;
+ }
+
+ ret = PyUnicode_FromString(text);
+
+ talloc_free(text);
+
+ return ret;
+}
+
+static PyMethodDef py_descriptor_extra_methods[] = {
+ { "sacl_add", (PyCFunction)py_descriptor_sacl_add, METH_VARARGS,
+ "S.sacl_add(ace) -> None\n"
+ "Add a security ace to this security descriptor" },
+ { "dacl_add", (PyCFunction)py_descriptor_dacl_add, METH_VARARGS,
+ NULL },
+ { "dacl_del", (PyCFunction)py_descriptor_dacl_del, METH_VARARGS,
+ NULL },
+ { "sacl_del", (PyCFunction)py_descriptor_sacl_del, METH_VARARGS,
+ NULL },
+ { "dacl_del_ace", (PyCFunction)py_descriptor_dacl_del_ace, METH_VARARGS,
+ NULL },
+ { "sacl_del_ace", (PyCFunction)py_descriptor_sacl_del_ace, METH_VARARGS,
+ NULL },
+ { "from_sddl", (PyCFunction)py_descriptor_from_sddl, METH_VARARGS|METH_KEYWORDS|METH_CLASS,
+ NULL },
+ { "as_sddl", (PyCFunction)py_descriptor_as_sddl, METH_VARARGS,
+ NULL },
+ {0}
+};
+
+static PyObject *py_descriptor_richcmp(
+ PyObject *py_self, PyObject *py_other, int op)
+{
+ struct security_descriptor *self = pytalloc_get_ptr(py_self);
+ struct security_descriptor *other = pytalloc_get_ptr(py_other);
+ bool eq;
+
+ if (other == NULL) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ eq = security_descriptor_equal(self, other);
+
+ switch(op) {
+ case Py_EQ:
+ if (eq) {
+ Py_RETURN_TRUE;
+ } else {
+ Py_RETURN_FALSE;
+ }
+ break;
+ case Py_NE:
+ if (eq) {
+ Py_RETURN_FALSE;
+ } else {
+ Py_RETURN_TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ Py_RETURN_NOTIMPLEMENTED;
+}
+
+static void py_descriptor_patch(PyTypeObject *type)
+{
+ type->tp_new = py_descriptor_new;
+ type->tp_richcompare = py_descriptor_richcmp;
+ PyType_AddMethods(type, py_descriptor_extra_methods);
+}
+
+#define PY_DESCRIPTOR_PATCH py_descriptor_patch
+
+static PyObject *py_token_is_sid(PyObject *self, PyObject *args)
+{
+ PyObject *py_sid;
+ struct dom_sid *sid;
+ struct security_token *token = pytalloc_get_ptr(self);
+ if (!PyArg_ParseTuple(args, "O", &py_sid))
+ return NULL;
+
+ sid = pytalloc_get_ptr(py_sid);
+
+ return PyBool_FromLong(security_token_is_sid(token, sid));
+}
+
+static PyObject *py_token_has_sid(PyObject *self, PyObject *args)
+{
+ PyObject *py_sid;
+ struct dom_sid *sid;
+ struct security_token *token = pytalloc_get_ptr(self);
+ if (!PyArg_ParseTuple(args, "O", &py_sid))
+ return NULL;
+
+ sid = pytalloc_get_ptr(py_sid);
+
+ return PyBool_FromLong(security_token_has_sid(token, sid));
+}
+
+static PyObject *py_token_is_anonymous(PyObject *self,
+ PyObject *Py_UNUSED(ignored))
+{
+ struct security_token *token = pytalloc_get_ptr(self);
+
+ return PyBool_FromLong(security_token_is_anonymous(token));
+}
+
+static PyObject *py_token_is_system(PyObject *self,
+ PyObject *Py_UNUSED(ignored))
+{
+ struct security_token *token = pytalloc_get_ptr(self);
+
+ return PyBool_FromLong(security_token_is_system(token));
+}
+
+static PyObject *py_token_has_builtin_administrators(PyObject *self,
+ PyObject *Py_UNUSED(ignored))
+{
+ struct security_token *token = pytalloc_get_ptr(self);
+
+ return PyBool_FromLong(security_token_has_builtin_administrators(token));
+}
+
+static PyObject *py_token_has_nt_authenticated_users(PyObject *self,
+ PyObject *Py_UNUSED(ignored))
+{
+ struct security_token *token = pytalloc_get_ptr(self);
+
+ return PyBool_FromLong(security_token_has_nt_authenticated_users(token));
+}
+
+static PyObject *py_token_has_privilege(PyObject *self, PyObject *args)
+{
+ int priv;
+ struct security_token *token = pytalloc_get_ptr(self);
+
+ if (!PyArg_ParseTuple(args, "i", &priv))
+ return NULL;
+
+ return PyBool_FromLong(security_token_has_privilege(token, priv));
+}
+
+static PyObject *py_token_set_privilege(PyObject *self, PyObject *args)
+{
+ int priv;
+ struct security_token *token = pytalloc_get_ptr(self);
+
+ if (!PyArg_ParseTuple(args, "i", &priv))
+ return NULL;
+
+ security_token_set_privilege(token, priv);
+ Py_RETURN_NONE;
+}
+
+static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
+{
+ int evaluate_claims = CLAIMS_EVALUATION_INVALID_STATE;
+ const char *kwnames[] = { "evaluate_claims", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
+ discard_const_p(char *, kwnames),
+ &evaluate_claims)) {
+ return NULL;
+ }
+
+ return pytalloc_steal(self, security_token_initialise(NULL, evaluate_claims));
+}
+
+static PyMethodDef py_token_extra_methods[] = {
+ { "is_sid", (PyCFunction)py_token_is_sid, METH_VARARGS,
+ "S.is_sid(sid) -> bool\n"
+ "Check whether this token is of the specified SID." },
+ { "has_sid", (PyCFunction)py_token_has_sid, METH_VARARGS,
+ NULL },
+ { "is_anonymous", (PyCFunction)py_token_is_anonymous, METH_NOARGS,
+ "S.is_anonymous() -> bool\n"
+ "Check whether this is an anonymous token." },
+ { "is_system", (PyCFunction)py_token_is_system, METH_NOARGS,
+ NULL },
+ { "has_builtin_administrators", (PyCFunction)py_token_has_builtin_administrators, METH_NOARGS,
+ NULL },
+ { "has_nt_authenticated_users", (PyCFunction)py_token_has_nt_authenticated_users, METH_NOARGS,
+ NULL },
+ { "has_privilege", (PyCFunction)py_token_has_privilege, METH_VARARGS,
+ NULL },
+ { "set_privilege", (PyCFunction)py_token_set_privilege, METH_VARARGS,
+ NULL },
+ {0}
+};
+
+#define PY_TOKEN_PATCH py_token_patch
+static void py_token_patch(PyTypeObject *type)
+{
+ type->tp_new = py_token_new;
+ PyType_AddMethods(type, py_token_extra_methods);
+}
+
+static PyObject *py_privilege_name(PyObject *self, PyObject *args)
+{
+ int priv;
+ const char *name = NULL;
+ if (!PyArg_ParseTuple(args, "i", &priv)) {
+ return NULL;
+ }
+ name = sec_privilege_name(priv);
+ if (name == NULL) {
+ PyErr_Format(PyExc_ValueError,
+ "Invalid privilege LUID: %d", priv);
+ return NULL;
+ }
+
+ return PyUnicode_FromString(name);
+}
+
+static PyObject *py_privilege_id(PyObject *self, PyObject *args)
+{
+ char *name;
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ return PyLong_FromLong(sec_privilege_id(name));
+}
+
+static PyObject *py_random_sid(PyObject *self,
+ PyObject *Py_UNUSED(ignored))
+{
+ struct dom_sid *sid;
+ PyObject *ret;
+ char *str = talloc_asprintf(
+ NULL,
+ "S-1-5-21-%"PRIu32"-%"PRIu32"-%"PRIu32,
+ generate_random(),
+ generate_random(),
+ generate_random());
+
+ sid = dom_sid_parse_talloc(NULL, str);
+ talloc_free(str);
+ ret = pytalloc_steal(&dom_sid_Type, sid);
+ return ret;
+}
+
+static PyMethodDef py_mod_security_extra_methods[] = {
+ { "random_sid", (PyCFunction)py_random_sid, METH_NOARGS, NULL },
+ { "privilege_id", (PyCFunction)py_privilege_id, METH_VARARGS, NULL },
+ { "privilege_name", (PyCFunction)py_privilege_name, METH_VARARGS, NULL },
+ {0}
+};
+
+static bool py_mod_security_patch(PyObject *m)
+{
+ int ret;
+ int i;
+ for (i = 0; py_mod_security_extra_methods[i].ml_name; i++) {
+ PyObject *descr = PyCFunction_New(&py_mod_security_extra_methods[i], NULL);
+ ret = PyModule_AddObject(m, py_mod_security_extra_methods[i].ml_name,
+ descr);
+ if (ret != 0) {
+ return false;
+ }
+ }
+ /*
+ * I wanted to make this a subclass of ValueError, but it
+ * seems there isn't an easy way to do that using the API.
+ * (c.f. SimpleExtendsException in cpython:Objects/exceptions.c)
+ */
+ PyExc_SDDLValueError = PyErr_NewException("security.SDDLValueError",
+ NULL, NULL);
+
+ if (PyExc_SDDLValueError == NULL) {
+ return false;
+ }
+ ret = PyModule_AddObject(m, "SDDLValueError", PyExc_SDDLValueError);
+ if (ret != 0) {
+ return false;
+ }
+ return true;
+}
+
+#define PY_MOD_SECURITY_PATCH(m) \
+ do { \
+ bool _ok = py_mod_security_patch(m); \
+ if (! _ok) { \
+ Py_XDECREF(m); \
+ return NULL; \
+ } \
+ } while(0)
+
+static PyObject *py_security_ace_equal(PyObject *py_self, PyObject *py_other, int op)
+{
+ struct security_ace *self = pytalloc_get_ptr(py_self);
+ struct security_ace *other = NULL;
+ bool eq;
+
+ if (!PyObject_TypeCheck(py_other, &security_ace_Type)) {
+ eq = false;
+ } else {
+ other = pytalloc_get_ptr(py_other);
+ eq = security_ace_equal(self, other);
+ }
+
+ switch(op) {
+ case Py_EQ:
+ if (eq) {
+ Py_RETURN_TRUE;
+ } else {
+ Py_RETURN_FALSE;
+ }
+ break;
+ case Py_NE:
+ if (eq) {
+ Py_RETURN_FALSE;
+ } else {
+ Py_RETURN_TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ Py_RETURN_NOTIMPLEMENTED;
+}
+
+static PyObject *py_security_ace_as_sddl(PyObject *self, PyObject *args)
+{
+ struct security_ace *ace = pytalloc_get_ptr(self);
+ PyObject *py_sid = Py_None;
+ struct dom_sid *sid = NULL;
+ char *text = NULL;
+ PyObject *ret = Py_None;
+
+ if (!PyArg_ParseTuple(args, "O!", &dom_sid_Type, &py_sid))
+ return NULL;
+
+ if (!PyObject_TypeCheck(py_sid, &dom_sid_Type)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected security.dom_sid "
+ "for second argument to .sddl_encode_ace");
+ return NULL;
+ }
+
+ sid = pytalloc_get_ptr(py_sid);
+
+ text = sddl_encode_ace(NULL, ace, sid);
+ if (text == NULL) {
+ return NULL;
+ }
+ ret = PyUnicode_FromString(text);
+ talloc_free(text);
+
+ return ret;
+}
+
+static PyMethodDef py_security_ace_extra_methods[] = {
+ { "as_sddl", (PyCFunction)py_security_ace_as_sddl, METH_VARARGS, NULL },
+ {0}
+};
+
+#define PY_ACE_PATCH py_security_ace_patch
+
+static void py_security_ace_patch(PyTypeObject *type)
+{
+ type->tp_richcompare = py_security_ace_equal;
+ PyType_AddMethods(type, py_security_ace_extra_methods);
+}
diff --git a/source4/librpc/ndr/py_xattr.c b/source4/librpc/ndr/py_xattr.c
new file mode 100644
index 0000000..523c1ab
--- /dev/null
+++ b/source4/librpc/ndr/py_xattr.c
@@ -0,0 +1,100 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Matthieu Patou <mat@matws.net> 2010
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "lib/replace/system/python.h"
+
+static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods)
+{
+ PyObject *dict;
+ int i;
+ if (type->tp_dict == NULL)
+ type->tp_dict = PyDict_New();
+ dict = type->tp_dict;
+ for (i = 0; methods[i].ml_name; i++) {
+ PyObject *descr;
+ if (methods[i].ml_flags & METH_CLASS)
+ descr = PyCFunction_New(&methods[i], (PyObject *)type);
+ else
+ descr = PyDescr_NewMethod(type, &methods[i]);
+ PyDict_SetItemString(dict, methods[i].ml_name,
+ descr);
+ Py_CLEAR(descr);
+ }
+}
+
+static void ntacl_print_debug_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
+
+static void ntacl_print_debug_helper(struct ndr_print *ndr, const char *format, ...)
+{
+ va_list ap;
+ char *s = NULL;
+ int i, ret;
+
+ va_start(ap, format);
+ ret = vasprintf(&s, format, ap);
+ va_end(ap);
+
+ if (ret == -1) {
+ return;
+ }
+
+ for (i=0;i<ndr->depth;i++) {
+ printf(" ");
+ }
+
+ printf("%s\n", s);
+ free(s);
+}
+
+static PyObject *py_ntacl_print(PyObject *self, PyObject *args)
+{
+ struct xattr_NTACL *ntacl = pytalloc_get_ptr(self);
+ struct ndr_print *pr;
+ TALLOC_CTX *mem_ctx;
+
+ mem_ctx = talloc_new(NULL);
+
+ pr = talloc_zero(mem_ctx, struct ndr_print);
+ if (!pr) {
+ PyErr_NoMemory();
+ talloc_free(mem_ctx);
+ return NULL;
+ }
+ pr->print = ntacl_print_debug_helper;
+ ndr_print_xattr_NTACL(pr, "file", ntacl);
+
+ talloc_free(mem_ctx);
+
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef py_ntacl_extra_methods[] = {
+ { "dump", (PyCFunction)py_ntacl_print, METH_NOARGS,
+ NULL },
+ {0}
+};
+
+static void py_xattr_NTACL_patch(PyTypeObject *type)
+{
+ PyType_AddMethods(type, py_ntacl_extra_methods);
+}
+
+#define PY_NTACL_PATCH py_xattr_NTACL_patch
+
+