2 Unix SMB/CIFS implementation.
3 Samba utility functions
5 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008-2010
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "py3compat.h"
22 #include "libcli/security/security.h"
24 static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods)
28 if (type->tp_dict == NULL)
29 type->tp_dict = PyDict_New();
31 for (i = 0; methods[i].ml_name; i++) {
33 if (methods[i].ml_flags & METH_CLASS)
34 descr = PyCFunction_New(&methods[i], (PyObject *)type);
36 descr = PyDescr_NewMethod(type, &methods[i]);
37 PyDict_SetItemString(dict, methods[i].ml_name,
43 static PyObject *py_dom_sid_split(PyObject *py_self, PyObject *args)
45 struct dom_sid *self = pytalloc_get_ptr(py_self);
46 struct dom_sid *domain_sid;
50 PyObject *py_domain_sid;
52 mem_ctx = talloc_new(NULL);
53 if (mem_ctx == NULL) {
58 status = dom_sid_split_rid(mem_ctx, self, &domain_sid, &rid);
59 if (!NT_STATUS_IS_OK(status)) {
60 PyErr_SetString(PyExc_RuntimeError, "dom_sid_split_rid failed");
65 py_domain_sid = pytalloc_steal(&dom_sid_Type, domain_sid);
67 return Py_BuildValue("(OI)", py_domain_sid, rid);
70 #if PY_MAJOR_VERSION >= 3
71 static PyObject *py_dom_sid_richcmp(PyObject *py_self, PyObject *py_other, int op)
73 struct dom_sid *self = pytalloc_get_ptr(py_self), *other;
76 other = pytalloc_get_ptr(py_other);
78 Py_INCREF(Py_NotImplemented);
79 return Py_NotImplemented;
82 val = dom_sid_compare(self, other);
85 case Py_EQ: if (val == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
86 case Py_NE: if (val != 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
87 case Py_LT: if (val < 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
88 case Py_GT: if (val > 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
89 case Py_LE: if (val <= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
90 case Py_GE: if (val >= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
92 Py_INCREF(Py_NotImplemented);
93 return Py_NotImplemented;
96 static int py_dom_sid_cmp(PyObject *py_self, PyObject *py_other)
98 struct dom_sid *self = pytalloc_get_ptr(py_self), *other;
101 other = pytalloc_get_ptr(py_other);
105 val = dom_sid_compare(self, other);
108 } else if (val < 0) {
115 static PyObject *py_dom_sid_str(PyObject *py_self)
117 struct dom_sid *self = pytalloc_get_ptr(py_self);
118 struct dom_sid_buf buf;
119 PyObject *ret = PyUnicode_FromString(dom_sid_str_buf(self, &buf));
123 static PyObject *py_dom_sid_repr(PyObject *py_self)
125 struct dom_sid *self = pytalloc_get_ptr(py_self);
126 struct dom_sid_buf buf;
127 PyObject *ret = PyStr_FromFormat(
128 "dom_sid('%s')", dom_sid_str_buf(self, &buf));
132 static int py_dom_sid_init(PyObject *self, PyObject *args, PyObject *kwargs)
135 struct dom_sid *sid = pytalloc_get_ptr(self);
136 const char *kwnames[] = { "str", NULL };
138 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &str))
141 if (str != NULL && !dom_sid_parse(str, sid)) {
142 PyErr_SetString(PyExc_TypeError, "Unable to parse string");
149 static PyMethodDef py_dom_sid_extra_methods[] = {
150 { "split", (PyCFunction)py_dom_sid_split, METH_NOARGS,
151 "S.split() -> (domain_sid, rid)\n"
152 "Split a domain sid" },
157 static void py_dom_sid_patch(PyTypeObject *type)
159 type->tp_init = py_dom_sid_init;
160 type->tp_str = py_dom_sid_str;
161 type->tp_repr = py_dom_sid_repr;
162 #if PY_MAJOR_VERSION >= 3
163 type->tp_richcompare = py_dom_sid_richcmp;
165 type->tp_compare = py_dom_sid_cmp;
167 PyType_AddMethods(type, py_dom_sid_extra_methods);
170 #define PY_DOM_SID_PATCH py_dom_sid_patch
172 static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args)
174 struct security_descriptor *desc = pytalloc_get_ptr(self);
176 struct security_ace *ace;
179 if (!PyArg_ParseTuple(args, "O", &py_ace))
182 ace = pytalloc_get_ptr(py_ace);
183 status = security_descriptor_sacl_add(desc, ace);
184 PyErr_NTSTATUS_IS_ERR_RAISE(status);
188 static PyObject *py_descriptor_dacl_add(PyObject *self, PyObject *args)
190 struct security_descriptor *desc = pytalloc_get_ptr(self);
192 struct security_ace *ace;
195 if (!PyArg_ParseTuple(args, "O", &py_ace))
198 ace = pytalloc_get_ptr(py_ace);
200 status = security_descriptor_dacl_add(desc, ace);
201 PyErr_NTSTATUS_IS_ERR_RAISE(status);
205 static PyObject *py_descriptor_dacl_del(PyObject *self, PyObject *args)
207 struct security_descriptor *desc = pytalloc_get_ptr(self);
212 if (!PyArg_ParseTuple(args, "O", &py_sid))
215 sid = pytalloc_get_ptr(py_sid);
216 status = security_descriptor_dacl_del(desc, sid);
217 PyErr_NTSTATUS_IS_ERR_RAISE(status);
221 static PyObject *py_descriptor_sacl_del(PyObject *self, PyObject *args)
223 struct security_descriptor *desc = pytalloc_get_ptr(self);
228 if (!PyArg_ParseTuple(args, "O", &py_sid))
231 sid = pytalloc_get_ptr(py_sid);
232 status = security_descriptor_sacl_del(desc, sid);
233 PyErr_NTSTATUS_IS_ERR_RAISE(status);
237 static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
239 return pytalloc_steal(self, security_descriptor_initialise(NULL));
242 static PyObject *py_descriptor_from_sddl(PyObject *self, PyObject *args)
244 struct security_descriptor *secdesc;
249 if (!PyArg_ParseTuple(args, "sO!", &sddl, &dom_sid_Type, &py_sid))
252 if (!PyObject_TypeCheck(py_sid, &dom_sid_Type)) {
253 PyErr_SetString(PyExc_TypeError,
254 "expected security.dom_sid "
255 "for second argument to .from_sddl");
259 sid = pytalloc_get_ptr(py_sid);
261 secdesc = sddl_decode(NULL, sddl, sid);
262 if (secdesc == NULL) {
263 PyErr_SetString(PyExc_TypeError, "Unable to parse SDDL");
267 return pytalloc_steal((PyTypeObject *)self, secdesc);
270 static PyObject *py_descriptor_as_sddl(PyObject *self, PyObject *args)
273 PyObject *py_sid = Py_None;
274 struct security_descriptor *desc = pytalloc_get_ptr(self);
278 if (!PyArg_ParseTuple(args, "|O!", &dom_sid_Type, &py_sid))
281 if (py_sid != Py_None)
282 sid = pytalloc_get_ptr(py_sid);
286 text = sddl_encode(NULL, desc, sid);
288 ret = PyUnicode_FromString(text);
295 static PyMethodDef py_descriptor_extra_methods[] = {
296 { "sacl_add", (PyCFunction)py_descriptor_sacl_add, METH_VARARGS,
297 "S.sacl_add(ace) -> None\n"
298 "Add a security ace to this security descriptor" },
299 { "dacl_add", (PyCFunction)py_descriptor_dacl_add, METH_VARARGS,
301 { "dacl_del", (PyCFunction)py_descriptor_dacl_del, METH_VARARGS,
303 { "sacl_del", (PyCFunction)py_descriptor_sacl_del, METH_VARARGS,
305 { "from_sddl", (PyCFunction)py_descriptor_from_sddl, METH_VARARGS|METH_CLASS,
307 { "as_sddl", (PyCFunction)py_descriptor_as_sddl, METH_VARARGS,
312 static void py_descriptor_patch(PyTypeObject *type)
314 type->tp_new = py_descriptor_new;
315 PyType_AddMethods(type, py_descriptor_extra_methods);
318 #define PY_DESCRIPTOR_PATCH py_descriptor_patch
320 static PyObject *py_token_is_sid(PyObject *self, PyObject *args)
324 struct security_token *token = pytalloc_get_ptr(self);
325 if (!PyArg_ParseTuple(args, "O", &py_sid))
328 sid = pytalloc_get_ptr(py_sid);
330 return PyBool_FromLong(security_token_is_sid(token, sid));
333 static PyObject *py_token_has_sid(PyObject *self, PyObject *args)
337 struct security_token *token = pytalloc_get_ptr(self);
338 if (!PyArg_ParseTuple(args, "O", &py_sid))
341 sid = pytalloc_get_ptr(py_sid);
343 return PyBool_FromLong(security_token_has_sid(token, sid));
346 static PyObject *py_token_is_anonymous(PyObject *self,
347 PyObject *Py_UNUSED(ignored))
349 struct security_token *token = pytalloc_get_ptr(self);
351 return PyBool_FromLong(security_token_is_anonymous(token));
354 static PyObject *py_token_is_system(PyObject *self,
355 PyObject *Py_UNUSED(ignored))
357 struct security_token *token = pytalloc_get_ptr(self);
359 return PyBool_FromLong(security_token_is_system(token));
362 static PyObject *py_token_has_builtin_administrators(PyObject *self,
363 PyObject *Py_UNUSED(ignored))
365 struct security_token *token = pytalloc_get_ptr(self);
367 return PyBool_FromLong(security_token_has_builtin_administrators(token));
370 static PyObject *py_token_has_nt_authenticated_users(PyObject *self,
371 PyObject *Py_UNUSED(ignored))
373 struct security_token *token = pytalloc_get_ptr(self);
375 return PyBool_FromLong(security_token_has_nt_authenticated_users(token));
378 static PyObject *py_token_has_privilege(PyObject *self, PyObject *args)
381 struct security_token *token = pytalloc_get_ptr(self);
383 if (!PyArg_ParseTuple(args, "i", &priv))
386 return PyBool_FromLong(security_token_has_privilege(token, priv));
389 static PyObject *py_token_set_privilege(PyObject *self, PyObject *args)
392 struct security_token *token = pytalloc_get_ptr(self);
394 if (!PyArg_ParseTuple(args, "i", &priv))
397 security_token_set_privilege(token, priv);
401 static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
403 return pytalloc_steal(self, security_token_initialise(NULL));
406 static PyMethodDef py_token_extra_methods[] = {
407 { "is_sid", (PyCFunction)py_token_is_sid, METH_VARARGS,
408 "S.is_sid(sid) -> bool\n"
409 "Check whether this token is of the specified SID." },
410 { "has_sid", (PyCFunction)py_token_has_sid, METH_VARARGS,
412 { "is_anonymous", (PyCFunction)py_token_is_anonymous, METH_NOARGS,
413 "S.is_anonymus() -> bool\n"
414 "Check whether this is an anonymous token." },
415 { "is_system", (PyCFunction)py_token_is_system, METH_NOARGS,
417 { "has_builtin_administrators", (PyCFunction)py_token_has_builtin_administrators, METH_NOARGS,
419 { "has_nt_authenticated_users", (PyCFunction)py_token_has_nt_authenticated_users, METH_NOARGS,
421 { "has_privilege", (PyCFunction)py_token_has_privilege, METH_VARARGS,
423 { "set_privilege", (PyCFunction)py_token_set_privilege, METH_VARARGS,
428 #define PY_TOKEN_PATCH py_token_patch
429 static void py_token_patch(PyTypeObject *type)
431 type->tp_new = py_token_new;
432 PyType_AddMethods(type, py_token_extra_methods);
435 static PyObject *py_privilege_name(PyObject *self, PyObject *args)
438 if (!PyArg_ParseTuple(args, "i", &priv))
441 return PyUnicode_FromString(sec_privilege_name(priv));
444 static PyObject *py_privilege_id(PyObject *self, PyObject *args)
448 if (!PyArg_ParseTuple(args, "s", &name))
451 return PyInt_FromLong(sec_privilege_id(name));
454 static PyObject *py_random_sid(PyObject *self,
455 PyObject *Py_UNUSED(ignored))
459 char *str = talloc_asprintf(NULL, "S-1-5-21-%u-%u-%u",
460 (unsigned)generate_random(),
461 (unsigned)generate_random(),
462 (unsigned)generate_random());
464 sid = dom_sid_parse_talloc(NULL, str);
466 ret = pytalloc_steal(&dom_sid_Type, sid);
470 static PyMethodDef py_mod_security_extra_methods[] = {
471 { "random_sid", (PyCFunction)py_random_sid, METH_NOARGS, NULL },
472 { "privilege_id", (PyCFunction)py_privilege_id, METH_VARARGS, NULL },
473 { "privilege_name", (PyCFunction)py_privilege_name, METH_VARARGS, NULL },
477 static void py_mod_security_patch(PyObject *m)
480 for (i = 0; py_mod_security_extra_methods[i].ml_name; i++) {
481 PyObject *descr = PyCFunction_New(&py_mod_security_extra_methods[i], NULL);
482 PyModule_AddObject(m, py_mod_security_extra_methods[i].ml_name,
487 #define PY_MOD_SECURITY_PATCH py_mod_security_patch