backupkey: Change expected error codes to match Windows 2008R2 and Windows 2012R2
[Samba.git] / source4 / librpc / ndr / py_security.c
blob47d8c9a313306e1eb61a150c504b8979f629b961
1 /*
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/>.
20 #include <Python.h>
21 #include "libcli/security/security.h"
23 static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods)
25 PyObject *dict;
26 int i;
27 if (type->tp_dict == NULL)
28 type->tp_dict = PyDict_New();
29 dict = type->tp_dict;
30 for (i = 0; methods[i].ml_name; i++) {
31 PyObject *descr;
32 if (methods[i].ml_flags & METH_CLASS)
33 descr = PyCFunction_New(&methods[i], (PyObject *)type);
34 else
35 descr = PyDescr_NewMethod(type, &methods[i]);
36 PyDict_SetItemString(dict, methods[i].ml_name,
37 descr);
41 static PyObject *py_dom_sid_split(PyObject *py_self, PyObject *args)
43 struct dom_sid *self = pytalloc_get_ptr(py_self);
44 struct dom_sid *domain_sid;
45 TALLOC_CTX *mem_ctx;
46 uint32_t rid;
47 NTSTATUS status;
48 PyObject *py_domain_sid;
50 mem_ctx = talloc_new(NULL);
51 if (mem_ctx == NULL) {
52 PyErr_NoMemory();
53 return NULL;
56 status = dom_sid_split_rid(mem_ctx, self, &domain_sid, &rid);
57 if (!NT_STATUS_IS_OK(status)) {
58 PyErr_SetString(PyExc_RuntimeError, "dom_sid_split_rid failed");
59 talloc_free(mem_ctx);
60 return NULL;
63 py_domain_sid = pytalloc_steal(&dom_sid_Type, domain_sid);
64 talloc_free(mem_ctx);
65 return Py_BuildValue("(OI)", py_domain_sid, rid);
68 static int py_dom_sid_cmp(PyObject *py_self, PyObject *py_other)
70 struct dom_sid *self = pytalloc_get_ptr(py_self), *other;
71 int val;
73 other = pytalloc_get_ptr(py_other);
74 if (other == NULL)
75 return -1;
77 val = dom_sid_compare(self, other);
78 if (val > 0) {
79 return 1;
80 } else if (val < 0) {
81 return -1;
83 return 0;
86 static PyObject *py_dom_sid_str(PyObject *py_self)
88 struct dom_sid *self = pytalloc_get_ptr(py_self);
89 char *str = dom_sid_string(NULL, self);
90 PyObject *ret = PyString_FromString(str);
91 talloc_free(str);
92 return ret;
95 static PyObject *py_dom_sid_repr(PyObject *py_self)
97 struct dom_sid *self = pytalloc_get_ptr(py_self);
98 char *str = dom_sid_string(NULL, self);
99 PyObject *ret = PyString_FromFormat("dom_sid('%s')", str);
100 talloc_free(str);
101 return ret;
104 static int py_dom_sid_init(PyObject *self, PyObject *args, PyObject *kwargs)
106 char *str = NULL;
107 struct dom_sid *sid = pytalloc_get_ptr(self);
108 const char *kwnames[] = { "str", NULL };
110 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &str))
111 return -1;
113 if (str != NULL && !dom_sid_parse(str, sid)) {
114 PyErr_SetString(PyExc_TypeError, "Unable to parse string");
115 return -1;
118 return 0;
121 static PyMethodDef py_dom_sid_extra_methods[] = {
122 { "split", (PyCFunction)py_dom_sid_split, METH_NOARGS,
123 "S.split() -> (domain_sid, rid)\n"
124 "Split a domain sid" },
125 { NULL }
129 static void py_dom_sid_patch(PyTypeObject *type)
131 type->tp_init = py_dom_sid_init;
132 type->tp_str = py_dom_sid_str;
133 type->tp_repr = py_dom_sid_repr;
134 type->tp_compare = py_dom_sid_cmp;
135 PyType_AddMethods(type, py_dom_sid_extra_methods);
138 #define PY_DOM_SID_PATCH py_dom_sid_patch
140 static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args)
142 struct security_descriptor *desc = pytalloc_get_ptr(self);
143 NTSTATUS status;
144 struct security_ace *ace;
145 PyObject *py_ace;
147 if (!PyArg_ParseTuple(args, "O", &py_ace))
148 return NULL;
150 ace = pytalloc_get_ptr(py_ace);
151 status = security_descriptor_sacl_add(desc, ace);
152 PyErr_NTSTATUS_IS_ERR_RAISE(status);
153 Py_RETURN_NONE;
156 static PyObject *py_descriptor_dacl_add(PyObject *self, PyObject *args)
158 struct security_descriptor *desc = pytalloc_get_ptr(self);
159 NTSTATUS status;
160 struct security_ace *ace;
161 PyObject *py_ace;
163 if (!PyArg_ParseTuple(args, "O", &py_ace))
164 return NULL;
166 ace = pytalloc_get_ptr(py_ace);
168 status = security_descriptor_dacl_add(desc, ace);
169 PyErr_NTSTATUS_IS_ERR_RAISE(status);
170 Py_RETURN_NONE;
173 static PyObject *py_descriptor_dacl_del(PyObject *self, PyObject *args)
175 struct security_descriptor *desc = pytalloc_get_ptr(self);
176 NTSTATUS status;
177 struct dom_sid *sid;
178 PyObject *py_sid;
180 if (!PyArg_ParseTuple(args, "O", &py_sid))
181 return NULL;
183 sid = pytalloc_get_ptr(py_sid);
184 status = security_descriptor_dacl_del(desc, sid);
185 PyErr_NTSTATUS_IS_ERR_RAISE(status);
186 Py_RETURN_NONE;
189 static PyObject *py_descriptor_sacl_del(PyObject *self, PyObject *args)
191 struct security_descriptor *desc = pytalloc_get_ptr(self);
192 NTSTATUS status;
193 struct dom_sid *sid;
194 PyObject *py_sid;
196 if (!PyArg_ParseTuple(args, "O", &py_sid))
197 return NULL;
199 sid = pytalloc_get_ptr(py_sid);
200 status = security_descriptor_sacl_del(desc, sid);
201 PyErr_NTSTATUS_IS_ERR_RAISE(status);
202 Py_RETURN_NONE;
205 static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
207 return pytalloc_steal(self, security_descriptor_initialise(NULL));
210 static PyObject *py_descriptor_from_sddl(PyObject *self, PyObject *args)
212 struct security_descriptor *secdesc;
213 char *sddl;
214 PyObject *py_sid;
215 struct dom_sid *sid;
217 if (!PyArg_ParseTuple(args, "sO!", &sddl, &dom_sid_Type, &py_sid))
218 return NULL;
220 sid = pytalloc_get_ptr(py_sid);
222 secdesc = sddl_decode(NULL, sddl, sid);
223 if (secdesc == NULL) {
224 PyErr_SetString(PyExc_TypeError, "Unable to parse SDDL");
225 return NULL;
228 return pytalloc_steal((PyTypeObject *)self, secdesc);
231 static PyObject *py_descriptor_as_sddl(PyObject *self, PyObject *args)
233 struct dom_sid *sid;
234 PyObject *py_sid = Py_None;
235 struct security_descriptor *desc = pytalloc_get_ptr(self);
236 char *text;
237 PyObject *ret;
239 if (!PyArg_ParseTuple(args, "|O!", &dom_sid_Type, &py_sid))
240 return NULL;
242 if (py_sid != Py_None)
243 sid = pytalloc_get_ptr(py_sid);
244 else
245 sid = NULL;
247 text = sddl_encode(NULL, desc, sid);
249 ret = PyString_FromString(text);
251 talloc_free(text);
253 return ret;
256 static PyMethodDef py_descriptor_extra_methods[] = {
257 { "sacl_add", (PyCFunction)py_descriptor_sacl_add, METH_VARARGS,
258 "S.sacl_add(ace) -> None\n"
259 "Add a security ace to this security descriptor" },
260 { "dacl_add", (PyCFunction)py_descriptor_dacl_add, METH_VARARGS,
261 NULL },
262 { "dacl_del", (PyCFunction)py_descriptor_dacl_del, METH_VARARGS,
263 NULL },
264 { "sacl_del", (PyCFunction)py_descriptor_sacl_del, METH_VARARGS,
265 NULL },
266 { "from_sddl", (PyCFunction)py_descriptor_from_sddl, METH_VARARGS|METH_CLASS,
267 NULL },
268 { "as_sddl", (PyCFunction)py_descriptor_as_sddl, METH_VARARGS,
269 NULL },
270 { NULL }
273 static void py_descriptor_patch(PyTypeObject *type)
275 type->tp_new = py_descriptor_new;
276 PyType_AddMethods(type, py_descriptor_extra_methods);
279 #define PY_DESCRIPTOR_PATCH py_descriptor_patch
281 static PyObject *py_token_is_sid(PyObject *self, PyObject *args)
283 PyObject *py_sid;
284 struct dom_sid *sid;
285 struct security_token *token = pytalloc_get_ptr(self);
286 if (!PyArg_ParseTuple(args, "O", &py_sid))
287 return NULL;
289 sid = pytalloc_get_ptr(py_sid);
291 return PyBool_FromLong(security_token_is_sid(token, sid));
294 static PyObject *py_token_has_sid(PyObject *self, PyObject *args)
296 PyObject *py_sid;
297 struct dom_sid *sid;
298 struct security_token *token = pytalloc_get_ptr(self);
299 if (!PyArg_ParseTuple(args, "O", &py_sid))
300 return NULL;
302 sid = pytalloc_get_ptr(py_sid);
304 return PyBool_FromLong(security_token_has_sid(token, sid));
307 static PyObject *py_token_is_anonymous(PyObject *self)
309 struct security_token *token = pytalloc_get_ptr(self);
311 return PyBool_FromLong(security_token_is_anonymous(token));
314 static PyObject *py_token_is_system(PyObject *self)
316 struct security_token *token = pytalloc_get_ptr(self);
318 return PyBool_FromLong(security_token_is_system(token));
321 static PyObject *py_token_has_builtin_administrators(PyObject *self)
323 struct security_token *token = pytalloc_get_ptr(self);
325 return PyBool_FromLong(security_token_has_builtin_administrators(token));
328 static PyObject *py_token_has_nt_authenticated_users(PyObject *self)
330 struct security_token *token = pytalloc_get_ptr(self);
332 return PyBool_FromLong(security_token_has_nt_authenticated_users(token));
335 static PyObject *py_token_has_privilege(PyObject *self, PyObject *args)
337 int priv;
338 struct security_token *token = pytalloc_get_ptr(self);
340 if (!PyArg_ParseTuple(args, "i", &priv))
341 return NULL;
343 return PyBool_FromLong(security_token_has_privilege(token, priv));
346 static PyObject *py_token_set_privilege(PyObject *self, PyObject *args)
348 int priv;
349 struct security_token *token = pytalloc_get_ptr(self);
351 if (!PyArg_ParseTuple(args, "i", &priv))
352 return NULL;
354 security_token_set_privilege(token, priv);
355 Py_RETURN_NONE;
358 static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
360 return pytalloc_steal(self, security_token_initialise(NULL));
363 static PyMethodDef py_token_extra_methods[] = {
364 { "is_sid", (PyCFunction)py_token_is_sid, METH_VARARGS,
365 "S.is_sid(sid) -> bool\n"
366 "Check whether this token is of the specified SID." },
367 { "has_sid", (PyCFunction)py_token_has_sid, METH_VARARGS,
368 NULL },
369 { "is_anonymous", (PyCFunction)py_token_is_anonymous, METH_NOARGS,
370 "S.is_anonymus() -> bool\n"
371 "Check whether this is an anonymous token." },
372 { "is_system", (PyCFunction)py_token_is_system, METH_NOARGS,
373 NULL },
374 { "has_builtin_administrators", (PyCFunction)py_token_has_builtin_administrators, METH_NOARGS,
375 NULL },
376 { "has_nt_authenticated_users", (PyCFunction)py_token_has_nt_authenticated_users, METH_NOARGS,
377 NULL },
378 { "has_privilege", (PyCFunction)py_token_has_privilege, METH_VARARGS,
379 NULL },
380 { "set_privilege", (PyCFunction)py_token_set_privilege, METH_VARARGS,
381 NULL },
382 { NULL }
385 #define PY_TOKEN_PATCH py_token_patch
386 static void py_token_patch(PyTypeObject *type)
388 type->tp_new = py_token_new;
389 PyType_AddMethods(type, py_token_extra_methods);
392 static PyObject *py_privilege_name(PyObject *self, PyObject *args)
394 int priv;
395 if (!PyArg_ParseTuple(args, "i", &priv))
396 return NULL;
398 return PyString_FromString(sec_privilege_name(priv));
401 static PyObject *py_privilege_id(PyObject *self, PyObject *args)
403 char *name;
405 if (!PyArg_ParseTuple(args, "s", &name))
406 return NULL;
408 return PyInt_FromLong(sec_privilege_id(name));
411 static PyObject *py_random_sid(PyObject *self)
413 struct dom_sid *sid;
414 PyObject *ret;
415 char *str = talloc_asprintf(NULL, "S-1-5-21-%u-%u-%u",
416 (unsigned)generate_random(),
417 (unsigned)generate_random(),
418 (unsigned)generate_random());
420 sid = dom_sid_parse_talloc(NULL, str);
421 talloc_free(str);
422 ret = pytalloc_steal(&dom_sid_Type, sid);
423 return ret;
426 static PyMethodDef py_mod_security_extra_methods[] = {
427 { "random_sid", (PyCFunction)py_random_sid, METH_NOARGS, NULL },
428 { "privilege_id", (PyCFunction)py_privilege_id, METH_VARARGS, NULL },
429 { "privilege_name", (PyCFunction)py_privilege_name, METH_VARARGS, NULL },
430 { NULL }
433 static void py_mod_security_patch(PyObject *m)
435 int i;
436 for (i = 0; py_mod_security_extra_methods[i].ml_name; i++) {
437 PyObject *descr = PyCFunction_New(&py_mod_security_extra_methods[i], NULL);
438 PyModule_AddObject(m, py_mod_security_extra_methods[i].ml_name,
439 descr);
443 #define PY_MOD_SECURITY_PATCH py_mod_security_patch