DCE/RPC(Python): Rename py_talloc_import to py_talloc_steal.
[ira/wip.git] / source4 / librpc / ndr / py_security.c
index a7cb0515cf9bc0cd307f75b85c1601a58e5653b9..8ab790d4701b95af3c227e39f799daf16b99b819 100644 (file)
    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 <Python.h>
 #include "libcli/security/security.h"
 
-static PyObject *py_dom_sid_eq(PyObject *self, PyObject *args)
-{
-       struct dom_sid *this = py_talloc_get_ptr(self), *other;
-       PyObject *py_other;
+#ifndef Py_RETURN_NONE
+#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
+#endif
 
-       if (!PyArg_ParseTuple(args, "O", &py_other)) 
-               return 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);
+       }
+}
 
-       other = py_talloc_get_type(py_other, struct dom_sid);
+static int py_dom_sid_cmp(PyObject *py_self, PyObject *py_other)
+{
+       struct dom_sid *self = py_talloc_get_ptr(py_self), *other;
+       other = py_talloc_get_ptr(py_other);
        if (other == NULL)
-               return Py_False;
+               return -1;
 
-       return dom_sid_equal(this, other)?Py_True:Py_False;
+       return dom_sid_compare(self, other);
 }
 
-static PyObject *py_dom_sid_str(PyObject *self)
+static PyObject *py_dom_sid_str(PyObject *py_self)
 {
-       struct dom_sid *this = py_talloc_get_ptr(self);
-       char *str = dom_sid_string(NULL, this);
+       struct dom_sid *self = py_talloc_get_ptr(py_self);
+       char *str = dom_sid_string(NULL, self);
        PyObject *ret = PyString_FromString(str);
        talloc_free(str);
        return ret;
 }
 
-static PyObject *py_dom_sid_repr(PyObject *self)
+static PyObject *py_dom_sid_repr(PyObject *py_self)
 {
-       struct dom_sid *this = py_talloc_get_ptr(self);
-       char *str = dom_sid_string(NULL, this);
+       struct dom_sid *self = py_talloc_get_ptr(py_self);
+       char *str = dom_sid_string(NULL, self);
        PyObject *ret = PyString_FromFormat("dom_sid('%s')", str);
        talloc_free(str);
        return ret;
 }
 
-#define PY_DOM_SID_REPR py_dom_sid_repr
-
-static PyObject *py_dom_sid_init(PyObject *self, PyObject *args)
+static int py_dom_sid_init(PyObject *self, PyObject *args, PyObject *kwargs)
 {
-       struct dom_sid *this = py_talloc_get_ptr(self);
-       char *str;
-       struct dom_sid *new_this;
+       char *str = NULL;
+       struct dom_sid *sid = py_talloc_get_ptr(self);
+       const char *kwnames[] = { "str", NULL };
 
-       if (!PyArg_ParseTuple(args, "|s", &str))
-               return NULL;
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &str))
+               return -1;
 
-       new_this = dom_sid_parse_talloc(NULL, str);
-       memcpy(this, new_this, sizeof(*new_this));
-       talloc_free(new_this);
-       return Py_None;
+       if (str != NULL && !dom_sid_parse(str, sid)) {
+               PyErr_SetString(PyExc_TypeError, "Unable to parse string");
+               return -1;
+       }
+
+       return 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_compare = py_dom_sid_cmp;
 }
 
-#define PY_DOM_SID_EXTRA_METHODS \
-       { "__eq__", (PyCFunction)py_dom_sid_eq, METH_VARARGS, "S.__eq__(x) -> S == x" }, \
-       { "__str__", (PyCFunction)py_dom_sid_str, METH_NOARGS, "S.__str__() -> str(S)" }, \
-       { "__init__", (PyCFunction)py_dom_sid_init, METH_VARARGS, "S.__init__(str=None)" },
+#define PY_DOM_SID_PATCH py_dom_sid_patch
 
 static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args)
 {
@@ -86,7 +109,7 @@ static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args)
        ace = py_talloc_get_ptr(py_ace);
        status = security_descriptor_sacl_add(desc, ace);
        PyErr_NTSTATUS_IS_ERR_RAISE(status);
-       return Py_None;
+       Py_RETURN_NONE;
 }
 
 static PyObject *py_descriptor_dacl_add(PyObject *self, PyObject *args)
@@ -103,7 +126,7 @@ static PyObject *py_descriptor_dacl_add(PyObject *self, PyObject *args)
 
        status = security_descriptor_dacl_add(desc, ace);
        PyErr_NTSTATUS_IS_ERR_RAISE(status);
-       return Py_None;
+       Py_RETURN_NONE;
 }
 
 static PyObject *py_descriptor_dacl_del(PyObject *self, PyObject *args)
@@ -119,7 +142,7 @@ static PyObject *py_descriptor_dacl_del(PyObject *self, PyObject *args)
        sid = py_talloc_get_ptr(py_sid);
        status = security_descriptor_dacl_del(desc, sid);
        PyErr_NTSTATUS_IS_ERR_RAISE(status);
-       return Py_None;
+       Py_RETURN_NONE;
 }
 
 static PyObject *py_descriptor_sacl_del(PyObject *self, PyObject *args)
@@ -135,39 +158,84 @@ static PyObject *py_descriptor_sacl_del(PyObject *self, PyObject *args)
        sid = py_talloc_get_ptr(py_sid);
        status = security_descriptor_sacl_del(desc, sid);
        PyErr_NTSTATUS_IS_ERR_RAISE(status);
-       return Py_None;
+       Py_RETURN_NONE;
+}
+
+static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
+{
+       return py_talloc_steal(self, security_descriptor_initialise(NULL));
 }
 
-static PyObject *py_descriptor_eq(PyObject *self, PyObject *args)
+static PyObject *py_descriptor_from_sddl(PyObject *self, PyObject *args)
 {
-       struct security_descriptor *desc1 = py_talloc_get_ptr(self), *desc2;
-       PyObject *py_other;
+       struct security_descriptor *secdesc;
+       char *sddl;
+       PyObject *py_sid;
+       struct dom_sid *sid;
 
-       if (!PyArg_ParseTuple(args, "O", &py_other))
+       if (!PyArg_ParseTuple(args, "sO", &sddl, &py_sid))
                return NULL;
 
-       desc2 = py_talloc_get_ptr(py_other);
+       sid = py_talloc_get_ptr(py_sid);
 
-       return PyBool_FromLong(security_descriptor_equal(desc1, desc2));
+       secdesc = sddl_decode(NULL, sddl, sid);
+       if (secdesc == NULL) {
+               PyErr_SetString(PyExc_TypeError, "Unable to parse SDDL");
+               return NULL;
+       }
+
+       return py_talloc_steal((PyTypeObject *)self, secdesc);
 }
 
-static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
+static PyObject *py_descriptor_as_sddl(PyObject *self, PyObject *args)
 {
-       return py_talloc_import(self, security_descriptor_initialise(NULL));
-}      
+       struct dom_sid *sid;
+       PyObject *py_sid = Py_None;
+       struct security_descriptor *desc = py_talloc_get_ptr(self);
+       char *text;
+       PyObject *ret;
+
+       if (!PyArg_ParseTuple(args, "|O", &py_sid))
+               return NULL;
+
+       if (py_sid != Py_None)
+               sid = py_talloc_get_ptr(py_sid);
+       else
+               sid = NULL;
 
-#define PY_SECURITY_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 }, \
-       { "__eq__", (PyCFunction)py_descriptor_eq, METH_VARARGS, \
+       text = sddl_encode(NULL, desc, sid);
+
+       ret = PyString_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 },
+       { "from_sddl", (PyCFunction)py_descriptor_from_sddl, METH_VARARGS|METH_CLASS, 
+               NULL },
+       { "as_sddl", (PyCFunction)py_descriptor_as_sddl, METH_VARARGS,
+               NULL },
+       { NULL }
+};
+
+static void py_descriptor_patch(PyTypeObject *type)
+{
+       type->tp_new = py_descriptor_new;
+       PyType_AddMethods(type, py_descriptor_extra_methods);
+}
+
+#define PY_DESCRIPTOR_PATCH py_descriptor_patch
 
 static PyObject *py_token_is_sid(PyObject *self, PyObject *args)
 {
@@ -243,33 +311,42 @@ static PyObject *py_token_set_privilege(PyObject *self, PyObject *args)
                return NULL;
 
        security_token_set_privilege(token, priv);
-       return Py_None;
+       Py_RETURN_NONE;
 }
 
 static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
 {
-       return py_talloc_import(self, security_token_initialise(NULL));
+       return py_talloc_steal(self, security_token_initialise(NULL));
 }      
 
-#define PY_SECURITY_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_anonymus() -> 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, \
+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_anonymus() -> 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 },
+       { NULL }
+};
+
+#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)
 {
@@ -301,7 +378,25 @@ static PyObject *py_random_sid(PyObject *self)
 
         sid = dom_sid_parse_talloc(NULL, str);
        talloc_free(str);
-       ret = py_talloc_import(&PyDomSidType, sid);
-       talloc_free(sid);
+       ret = py_talloc_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 },
+       { NULL }
+};
+
+static void py_mod_security_patch(PyObject *m)
+{
+       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);
+               PyModule_AddObject(m, py_mod_security_extra_methods[i].ml_name,
+                                  descr);
+       }
+}
+
+#define PY_MOD_SECURITY_PATCH py_mod_security_patch