2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "libcli/security/security.h"
22 #ifndef Py_RETURN_NONE
23 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
26 static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods)
30 if (type->tp_dict == NULL)
31 type->tp_dict = PyDict_New();
33 for (i = 0; methods[i].ml_name; i++) {
35 if (methods[i].ml_flags & METH_CLASS)
36 descr = PyCFunction_New(&methods[i], (PyObject *)type);
38 descr = PyDescr_NewMethod(type, &methods[i]);
39 PyDict_SetItemString(dict, methods[i].ml_name,
44 static int py_dom_sid_cmp(PyObject *py_self, PyObject *py_other)
46 struct dom_sid *self = py_talloc_get_ptr(py_self), *other;
47 other = py_talloc_get_ptr(py_other);
51 return dom_sid_compare(self, other);
54 static PyObject *py_dom_sid_str(PyObject *py_self)
56 struct dom_sid *self = py_talloc_get_ptr(py_self);
57 char *str = dom_sid_string(NULL, self);
58 PyObject *ret = PyString_FromString(str);
63 static PyObject *py_dom_sid_repr(PyObject *py_self)
65 struct dom_sid *self = py_talloc_get_ptr(py_self);
66 char *str = dom_sid_string(NULL, self);
67 PyObject *ret = PyString_FromFormat("dom_sid('%s')", str);
72 static int py_dom_sid_init(PyObject *self, PyObject *args, PyObject *kwargs)
75 struct dom_sid *sid = py_talloc_get_ptr(self);
76 const char *kwnames[] = { "str", NULL };
78 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &str))
81 if (str != NULL && !dom_sid_parse(str, sid)) {
82 PyErr_SetString(PyExc_TypeError, "Unable to parse string");
89 static void py_dom_sid_patch(PyTypeObject *type)
91 type->tp_init = py_dom_sid_init;
92 type->tp_str = py_dom_sid_str;
93 type->tp_repr = py_dom_sid_repr;
94 type->tp_compare = py_dom_sid_cmp;
97 #define PY_DOM_SID_PATCH py_dom_sid_patch
99 static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args)
101 struct security_descriptor *desc = py_talloc_get_ptr(self);
103 struct security_ace *ace;
106 if (!PyArg_ParseTuple(args, "O", &py_ace))
109 ace = py_talloc_get_ptr(py_ace);
110 status = security_descriptor_sacl_add(desc, ace);
111 PyErr_NTSTATUS_IS_ERR_RAISE(status);
115 static PyObject *py_descriptor_dacl_add(PyObject *self, PyObject *args)
117 struct security_descriptor *desc = py_talloc_get_ptr(self);
119 struct security_ace *ace;
122 if (!PyArg_ParseTuple(args, "O", &py_ace))
125 ace = py_talloc_get_ptr(py_ace);
127 status = security_descriptor_dacl_add(desc, ace);
128 PyErr_NTSTATUS_IS_ERR_RAISE(status);
132 static PyObject *py_descriptor_dacl_del(PyObject *self, PyObject *args)
134 struct security_descriptor *desc = py_talloc_get_ptr(self);
139 if (!PyArg_ParseTuple(args, "O", &py_sid))
142 sid = py_talloc_get_ptr(py_sid);
143 status = security_descriptor_dacl_del(desc, sid);
144 PyErr_NTSTATUS_IS_ERR_RAISE(status);
148 static PyObject *py_descriptor_sacl_del(PyObject *self, PyObject *args)
150 struct security_descriptor *desc = py_talloc_get_ptr(self);
155 if (!PyArg_ParseTuple(args, "O", &py_sid))
158 sid = py_talloc_get_ptr(py_sid);
159 status = security_descriptor_sacl_del(desc, sid);
160 PyErr_NTSTATUS_IS_ERR_RAISE(status);
164 static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
166 return py_talloc_import(self, security_descriptor_initialise(NULL));
169 static PyObject *py_descriptor_from_sddl(PyObject *self, PyObject *args)
171 struct security_descriptor *secdesc;
176 if (!PyArg_ParseTuple(args, "sO", &sddl, &py_sid))
179 sid = py_talloc_get_ptr(py_sid);
181 secdesc = sddl_decode(NULL, sddl, sid);
182 if (secdesc == NULL) {
183 PyErr_SetString(PyExc_TypeError, "Unable to parse SDDL");
187 return py_talloc_import((PyTypeObject *)self, secdesc);
190 static PyObject *py_descriptor_as_sddl(PyObject *self, PyObject *args)
193 PyObject *py_sid = Py_None;
194 struct security_descriptor *desc = py_talloc_get_ptr(self);
198 if (!PyArg_ParseTuple(args, "|O", &py_sid))
201 if (py_sid != Py_None)
202 sid = py_talloc_get_ptr(py_sid);
206 text = sddl_encode(NULL, desc, sid);
208 ret = PyString_FromString(text);
215 static PyMethodDef py_descriptor_extra_methods[] = {
216 { "sacl_add", (PyCFunction)py_descriptor_sacl_add, METH_VARARGS,
217 "S.sacl_add(ace) -> None\n"
218 "Add a security ace to this security descriptor" },
219 { "dacl_add", (PyCFunction)py_descriptor_dacl_add, METH_VARARGS,
221 { "dacl_del", (PyCFunction)py_descriptor_dacl_del, METH_VARARGS,
223 { "sacl_del", (PyCFunction)py_descriptor_sacl_del, METH_VARARGS,
225 { "from_sddl", (PyCFunction)py_descriptor_from_sddl, METH_VARARGS|METH_CLASS,
227 { "as_sddl", (PyCFunction)py_descriptor_as_sddl, METH_VARARGS,
232 static void py_descriptor_patch(PyTypeObject *type)
234 type->tp_new = py_descriptor_new;
235 PyType_AddMethods(type, py_descriptor_extra_methods);
238 #define PY_DESCRIPTOR_PATCH py_descriptor_patch
240 static PyObject *py_token_is_sid(PyObject *self, PyObject *args)
244 struct security_token *token = py_talloc_get_ptr(self);
245 if (!PyArg_ParseTuple(args, "O", &py_sid))
248 sid = py_talloc_get_ptr(py_sid);
250 return PyBool_FromLong(security_token_is_sid(token, sid));
253 static PyObject *py_token_has_sid(PyObject *self, PyObject *args)
257 struct security_token *token = py_talloc_get_ptr(self);
258 if (!PyArg_ParseTuple(args, "O", &py_sid))
261 sid = py_talloc_get_ptr(py_sid);
263 return PyBool_FromLong(security_token_has_sid(token, sid));
266 static PyObject *py_token_is_anonymous(PyObject *self)
268 struct security_token *token = py_talloc_get_ptr(self);
270 return PyBool_FromLong(security_token_is_anonymous(token));
273 static PyObject *py_token_is_system(PyObject *self)
275 struct security_token *token = py_talloc_get_ptr(self);
277 return PyBool_FromLong(security_token_is_system(token));
280 static PyObject *py_token_has_builtin_administrators(PyObject *self)
282 struct security_token *token = py_talloc_get_ptr(self);
284 return PyBool_FromLong(security_token_has_builtin_administrators(token));
287 static PyObject *py_token_has_nt_authenticated_users(PyObject *self)
289 struct security_token *token = py_talloc_get_ptr(self);
291 return PyBool_FromLong(security_token_has_nt_authenticated_users(token));
294 static PyObject *py_token_has_privilege(PyObject *self, PyObject *args)
297 struct security_token *token = py_talloc_get_ptr(self);
299 if (!PyArg_ParseTuple(args, "i", &priv))
302 return PyBool_FromLong(security_token_has_privilege(token, priv));
305 static PyObject *py_token_set_privilege(PyObject *self, PyObject *args)
308 struct security_token *token = py_talloc_get_ptr(self);
310 if (!PyArg_ParseTuple(args, "i", &priv))
313 security_token_set_privilege(token, priv);
317 static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
319 return py_talloc_import(self, security_token_initialise(NULL));
322 static PyMethodDef py_token_extra_methods[] = {
323 { "is_sid", (PyCFunction)py_token_is_sid, METH_VARARGS,
324 "S.is_sid(sid) -> bool\n"
325 "Check whether this token is of the specified SID." },
326 { "has_sid", (PyCFunction)py_token_has_sid, METH_VARARGS,
328 { "is_anonymous", (PyCFunction)py_token_is_anonymous, METH_NOARGS,
329 "S.is_anonymus() -> bool\n"
330 "Check whether this is an anonymous token." },
331 { "is_system", (PyCFunction)py_token_is_system, METH_NOARGS,
333 { "has_builtin_administrators", (PyCFunction)py_token_has_builtin_administrators, METH_NOARGS,
335 { "has_nt_authenticated_users", (PyCFunction)py_token_has_nt_authenticated_users, METH_NOARGS,
337 { "has_privilege", (PyCFunction)py_token_has_privilege, METH_VARARGS,
339 { "set_privilege", (PyCFunction)py_token_set_privilege, METH_VARARGS,
344 #define PY_TOKEN_PATCH py_token_patch
345 static void py_token_patch(PyTypeObject *type)
347 type->tp_new = py_token_new;
348 PyType_AddMethods(type, py_token_extra_methods);
351 static PyObject *py_privilege_name(PyObject *self, PyObject *args)
354 if (!PyArg_ParseTuple(args, "i", &priv))
357 return PyString_FromString(sec_privilege_name(priv));
360 static PyObject *py_privilege_id(PyObject *self, PyObject *args)
364 if (!PyArg_ParseTuple(args, "s", &name))
367 return PyInt_FromLong(sec_privilege_id(name));
370 static PyObject *py_random_sid(PyObject *self)
374 char *str = talloc_asprintf(NULL, "S-1-5-21-%u-%u-%u",
375 (unsigned)generate_random(),
376 (unsigned)generate_random(),
377 (unsigned)generate_random());
379 sid = dom_sid_parse_talloc(NULL, str);
381 ret = py_talloc_import(&dom_sid_Type, sid);
385 static PyMethodDef py_mod_security_extra_methods[] = {
386 { "random_sid", (PyCFunction)py_random_sid, METH_NOARGS, NULL },
387 { "privilege_id", (PyCFunction)py_privilege_id, METH_VARARGS, NULL },
388 { "privilege_name", (PyCFunction)py_privilege_name, METH_VARARGS, NULL },
392 static void py_mod_security_patch(PyObject *m)
395 for (i = 0; py_mod_security_extra_methods[i].ml_name; i++) {
396 PyObject *descr = PyCFunction_New(&py_mod_security_extra_methods[i], NULL);
397 PyModule_AddObject(m, py_mod_security_extra_methods[i].ml_name,
402 #define PY_MOD_SECURITY_PATCH py_mod_security_patch