s3: smbd: Move check_fsp_open() and check_fsp() to smb1_reply.c
[Samba.git] / source4 / librpc / ndr / py_security.c
blobff3de775af6d289fe6fef18633653912172e54ea
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 "py3compat.h"
22 #include "libcli/security/sddl.h"
23 #include "libcli/security/security.h"
25 static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods)
27 PyObject *dict;
28 int i;
29 if (type->tp_dict == NULL)
30 type->tp_dict = PyDict_New();
31 dict = type->tp_dict;
32 for (i = 0; methods[i].ml_name; i++) {
33 PyObject *descr;
34 if (methods[i].ml_flags & METH_CLASS)
35 descr = PyCFunction_New(&methods[i], (PyObject *)type);
36 else
37 descr = PyDescr_NewMethod(type, &methods[i]);
38 PyDict_SetItemString(dict, methods[i].ml_name,
39 descr);
40 Py_CLEAR(descr);
44 static PyObject *py_dom_sid_split(PyObject *py_self, PyObject *args)
46 struct dom_sid *self = pytalloc_get_ptr(py_self);
47 struct dom_sid *domain_sid;
48 TALLOC_CTX *mem_ctx;
49 uint32_t rid;
50 NTSTATUS status;
51 PyObject *py_domain_sid;
53 mem_ctx = talloc_new(NULL);
54 if (mem_ctx == NULL) {
55 PyErr_NoMemory();
56 return NULL;
59 status = dom_sid_split_rid(mem_ctx, self, &domain_sid, &rid);
60 if (!NT_STATUS_IS_OK(status)) {
61 PyErr_SetString(PyExc_RuntimeError, "dom_sid_split_rid failed");
62 talloc_free(mem_ctx);
63 return NULL;
66 py_domain_sid = pytalloc_steal(&dom_sid_Type, domain_sid);
67 talloc_free(mem_ctx);
68 return Py_BuildValue("(OI)", py_domain_sid, rid);
71 #if PY_MAJOR_VERSION >= 3
72 static PyObject *py_dom_sid_richcmp(PyObject *py_self, PyObject *py_other, int op)
74 struct dom_sid *self = pytalloc_get_ptr(py_self), *other;
75 int val;
77 other = pytalloc_get_ptr(py_other);
78 if (other == NULL) {
79 Py_INCREF(Py_NotImplemented);
80 return Py_NotImplemented;
83 val = dom_sid_compare(self, other);
85 switch (op) {
86 case Py_EQ: if (val == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
87 case Py_NE: if (val != 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
88 case Py_LT: if (val < 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
89 case Py_GT: if (val > 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
90 case Py_LE: if (val <= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
91 case Py_GE: if (val >= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
93 Py_INCREF(Py_NotImplemented);
94 return Py_NotImplemented;
96 #else
97 static int py_dom_sid_cmp(PyObject *py_self, PyObject *py_other)
99 struct dom_sid *self = pytalloc_get_ptr(py_self), *other;
100 int val;
102 other = pytalloc_get_ptr(py_other);
103 if (other == NULL)
104 return -1;
106 val = dom_sid_compare(self, other);
107 if (val > 0) {
108 return 1;
109 } else if (val < 0) {
110 return -1;
112 return 0;
114 #endif
116 static PyObject *py_dom_sid_str(PyObject *py_self)
118 struct dom_sid *self = pytalloc_get_ptr(py_self);
119 struct dom_sid_buf buf;
120 PyObject *ret = PyUnicode_FromString(dom_sid_str_buf(self, &buf));
121 return ret;
124 static PyObject *py_dom_sid_repr(PyObject *py_self)
126 struct dom_sid *self = pytalloc_get_ptr(py_self);
127 struct dom_sid_buf buf;
128 PyObject *ret = PyUnicode_FromFormat(
129 "dom_sid('%s')", dom_sid_str_buf(self, &buf));
130 return ret;
133 static int py_dom_sid_init(PyObject *self, PyObject *args, PyObject *kwargs)
135 char *str = NULL;
136 struct dom_sid *sid = pytalloc_get_ptr(self);
137 const char *kwnames[] = { "str", NULL };
139 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &str))
140 return -1;
142 if (str != NULL && !dom_sid_parse(str, sid)) {
143 PyErr_SetString(PyExc_TypeError, "Unable to parse string");
144 return -1;
147 return 0;
150 static PyMethodDef py_dom_sid_extra_methods[] = {
151 { "split", (PyCFunction)py_dom_sid_split, METH_NOARGS,
152 "S.split() -> (domain_sid, rid)\n"
153 "Split a domain sid" },
158 static void py_dom_sid_patch(PyTypeObject *type)
160 type->tp_init = py_dom_sid_init;
161 type->tp_str = py_dom_sid_str;
162 type->tp_repr = py_dom_sid_repr;
163 #if PY_MAJOR_VERSION >= 3
164 type->tp_richcompare = py_dom_sid_richcmp;
165 #else
166 type->tp_compare = py_dom_sid_cmp;
167 #endif
168 PyType_AddMethods(type, py_dom_sid_extra_methods);
171 #define PY_DOM_SID_PATCH py_dom_sid_patch
173 static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args)
175 struct security_descriptor *desc = pytalloc_get_ptr(self);
176 NTSTATUS status;
177 struct security_ace *ace;
178 PyObject *py_ace;
180 if (!PyArg_ParseTuple(args, "O", &py_ace))
181 return NULL;
183 ace = pytalloc_get_ptr(py_ace);
184 status = security_descriptor_sacl_add(desc, ace);
185 PyErr_NTSTATUS_IS_ERR_RAISE(status);
186 Py_RETURN_NONE;
189 static PyObject *py_descriptor_dacl_add(PyObject *self, PyObject *args)
191 struct security_descriptor *desc = pytalloc_get_ptr(self);
192 NTSTATUS status;
193 struct security_ace *ace;
194 PyObject *py_ace;
196 if (!PyArg_ParseTuple(args, "O", &py_ace))
197 return NULL;
199 ace = pytalloc_get_ptr(py_ace);
201 status = security_descriptor_dacl_add(desc, ace);
202 PyErr_NTSTATUS_IS_ERR_RAISE(status);
203 Py_RETURN_NONE;
206 static PyObject *py_descriptor_dacl_del(PyObject *self, PyObject *args)
208 struct security_descriptor *desc = pytalloc_get_ptr(self);
209 NTSTATUS status;
210 struct dom_sid *sid;
211 PyObject *py_sid;
213 if (!PyArg_ParseTuple(args, "O", &py_sid))
214 return NULL;
216 sid = pytalloc_get_ptr(py_sid);
217 status = security_descriptor_dacl_del(desc, sid);
218 PyErr_NTSTATUS_IS_ERR_RAISE(status);
219 Py_RETURN_NONE;
222 static PyObject *py_descriptor_sacl_del(PyObject *self, PyObject *args)
224 struct security_descriptor *desc = pytalloc_get_ptr(self);
225 NTSTATUS status;
226 struct dom_sid *sid;
227 PyObject *py_sid;
229 if (!PyArg_ParseTuple(args, "O", &py_sid))
230 return NULL;
232 sid = pytalloc_get_ptr(py_sid);
233 status = security_descriptor_sacl_del(desc, sid);
234 PyErr_NTSTATUS_IS_ERR_RAISE(status);
235 Py_RETURN_NONE;
238 static PyObject *py_descriptor_dacl_del_ace(PyObject *self, PyObject *args)
240 struct security_descriptor *desc = pytalloc_get_ptr(self);
241 NTSTATUS status;
242 struct security_ace *ace = NULL;
243 PyObject *py_ace = Py_None;
245 if (!PyArg_ParseTuple(args, "O!", &security_ace_Type, &py_ace))
246 return NULL;
248 if (!PyObject_TypeCheck(py_ace, &security_ace_Type)) {
249 PyErr_SetString(PyExc_TypeError,
250 "expected security.security_ace "
251 "for first argument to .dacl_del_ace");
252 return NULL;
255 ace = pytalloc_get_ptr(py_ace);
256 status = security_descriptor_dacl_del_ace(desc, ace);
257 PyErr_NTSTATUS_IS_ERR_RAISE(status);
258 Py_RETURN_NONE;
261 static PyObject *py_descriptor_sacl_del_ace(PyObject *self, PyObject *args)
263 struct security_descriptor *desc = pytalloc_get_ptr(self);
264 NTSTATUS status;
265 struct security_ace *ace = NULL;
266 PyObject *py_ace = Py_None;
268 if (!PyArg_ParseTuple(args, "O!", &security_ace_Type, &py_ace))
269 return NULL;
271 if (!PyObject_TypeCheck(py_ace, &security_ace_Type)) {
272 PyErr_SetString(PyExc_TypeError,
273 "expected security.security_ace "
274 "for first argument to .sacl_del_ace");
275 return NULL;
278 ace = pytalloc_get_ptr(py_ace);
279 status = security_descriptor_sacl_del_ace(desc, ace);
280 PyErr_NTSTATUS_IS_ERR_RAISE(status);
281 Py_RETURN_NONE;
284 static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
286 return pytalloc_steal(self, security_descriptor_initialise(NULL));
289 static PyObject *py_descriptor_from_sddl(PyObject *self, PyObject *args)
291 struct security_descriptor *secdesc;
292 char *sddl;
293 PyObject *py_sid;
294 struct dom_sid *sid;
296 if (!PyArg_ParseTuple(args, "sO!", &sddl, &dom_sid_Type, &py_sid))
297 return NULL;
299 if (!PyObject_TypeCheck(py_sid, &dom_sid_Type)) {
300 PyErr_SetString(PyExc_TypeError,
301 "expected security.dom_sid "
302 "for second argument to .from_sddl");
303 return NULL;
306 sid = pytalloc_get_ptr(py_sid);
308 secdesc = sddl_decode(NULL, sddl, sid);
309 if (secdesc == NULL) {
310 PyErr_SetString(PyExc_TypeError, "Unable to parse SDDL");
311 return NULL;
314 return pytalloc_steal((PyTypeObject *)self, secdesc);
317 static PyObject *py_descriptor_as_sddl(PyObject *self, PyObject *args)
319 struct dom_sid *sid;
320 PyObject *py_sid = Py_None;
321 struct security_descriptor *desc = pytalloc_get_ptr(self);
322 char *text;
323 PyObject *ret;
325 if (!PyArg_ParseTuple(args, "|O!", &dom_sid_Type, &py_sid))
326 return NULL;
328 if (py_sid != Py_None)
329 sid = pytalloc_get_ptr(py_sid);
330 else
331 sid = NULL;
333 text = sddl_encode(NULL, desc, sid);
335 ret = PyUnicode_FromString(text);
337 talloc_free(text);
339 return ret;
342 static PyMethodDef py_descriptor_extra_methods[] = {
343 { "sacl_add", (PyCFunction)py_descriptor_sacl_add, METH_VARARGS,
344 "S.sacl_add(ace) -> None\n"
345 "Add a security ace to this security descriptor" },
346 { "dacl_add", (PyCFunction)py_descriptor_dacl_add, METH_VARARGS,
347 NULL },
348 { "dacl_del", (PyCFunction)py_descriptor_dacl_del, METH_VARARGS,
349 NULL },
350 { "sacl_del", (PyCFunction)py_descriptor_sacl_del, METH_VARARGS,
351 NULL },
352 { "dacl_del_ace", (PyCFunction)py_descriptor_dacl_del_ace, METH_VARARGS,
353 NULL },
354 { "sacl_del_ace", (PyCFunction)py_descriptor_sacl_del_ace, METH_VARARGS,
355 NULL },
356 { "from_sddl", (PyCFunction)py_descriptor_from_sddl, METH_VARARGS|METH_CLASS,
357 NULL },
358 { "as_sddl", (PyCFunction)py_descriptor_as_sddl, METH_VARARGS,
359 NULL },
363 static PyObject *py_descriptor_richcmp(
364 PyObject *py_self, PyObject *py_other, int op)
366 struct security_descriptor *self = pytalloc_get_ptr(py_self);
367 struct security_descriptor *other = pytalloc_get_ptr(py_other);
368 bool eq;
370 if (other == NULL) {
371 Py_INCREF(Py_NotImplemented);
372 return Py_NotImplemented;
375 eq = security_descriptor_equal(self, other);
377 switch(op) {
378 case Py_EQ:
379 if (eq) {
380 Py_RETURN_TRUE;
381 } else {
382 Py_RETURN_FALSE;
384 break;
385 case Py_NE:
386 if (eq) {
387 Py_RETURN_FALSE;
388 } else {
389 Py_RETURN_TRUE;
391 break;
392 default:
393 break;
396 Py_RETURN_NOTIMPLEMENTED;
399 static void py_descriptor_patch(PyTypeObject *type)
401 type->tp_new = py_descriptor_new;
402 type->tp_richcompare = py_descriptor_richcmp;
403 PyType_AddMethods(type, py_descriptor_extra_methods);
406 #define PY_DESCRIPTOR_PATCH py_descriptor_patch
408 static PyObject *py_token_is_sid(PyObject *self, PyObject *args)
410 PyObject *py_sid;
411 struct dom_sid *sid;
412 struct security_token *token = pytalloc_get_ptr(self);
413 if (!PyArg_ParseTuple(args, "O", &py_sid))
414 return NULL;
416 sid = pytalloc_get_ptr(py_sid);
418 return PyBool_FromLong(security_token_is_sid(token, sid));
421 static PyObject *py_token_has_sid(PyObject *self, PyObject *args)
423 PyObject *py_sid;
424 struct dom_sid *sid;
425 struct security_token *token = pytalloc_get_ptr(self);
426 if (!PyArg_ParseTuple(args, "O", &py_sid))
427 return NULL;
429 sid = pytalloc_get_ptr(py_sid);
431 return PyBool_FromLong(security_token_has_sid(token, sid));
434 static PyObject *py_token_is_anonymous(PyObject *self,
435 PyObject *Py_UNUSED(ignored))
437 struct security_token *token = pytalloc_get_ptr(self);
439 return PyBool_FromLong(security_token_is_anonymous(token));
442 static PyObject *py_token_is_system(PyObject *self,
443 PyObject *Py_UNUSED(ignored))
445 struct security_token *token = pytalloc_get_ptr(self);
447 return PyBool_FromLong(security_token_is_system(token));
450 static PyObject *py_token_has_builtin_administrators(PyObject *self,
451 PyObject *Py_UNUSED(ignored))
453 struct security_token *token = pytalloc_get_ptr(self);
455 return PyBool_FromLong(security_token_has_builtin_administrators(token));
458 static PyObject *py_token_has_nt_authenticated_users(PyObject *self,
459 PyObject *Py_UNUSED(ignored))
461 struct security_token *token = pytalloc_get_ptr(self);
463 return PyBool_FromLong(security_token_has_nt_authenticated_users(token));
466 static PyObject *py_token_has_privilege(PyObject *self, PyObject *args)
468 int priv;
469 struct security_token *token = pytalloc_get_ptr(self);
471 if (!PyArg_ParseTuple(args, "i", &priv))
472 return NULL;
474 return PyBool_FromLong(security_token_has_privilege(token, priv));
477 static PyObject *py_token_set_privilege(PyObject *self, PyObject *args)
479 int priv;
480 struct security_token *token = pytalloc_get_ptr(self);
482 if (!PyArg_ParseTuple(args, "i", &priv))
483 return NULL;
485 security_token_set_privilege(token, priv);
486 Py_RETURN_NONE;
489 static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
491 return pytalloc_steal(self, security_token_initialise(NULL));
494 static PyMethodDef py_token_extra_methods[] = {
495 { "is_sid", (PyCFunction)py_token_is_sid, METH_VARARGS,
496 "S.is_sid(sid) -> bool\n"
497 "Check whether this token is of the specified SID." },
498 { "has_sid", (PyCFunction)py_token_has_sid, METH_VARARGS,
499 NULL },
500 { "is_anonymous", (PyCFunction)py_token_is_anonymous, METH_NOARGS,
501 "S.is_anonymous() -> bool\n"
502 "Check whether this is an anonymous token." },
503 { "is_system", (PyCFunction)py_token_is_system, METH_NOARGS,
504 NULL },
505 { "has_builtin_administrators", (PyCFunction)py_token_has_builtin_administrators, METH_NOARGS,
506 NULL },
507 { "has_nt_authenticated_users", (PyCFunction)py_token_has_nt_authenticated_users, METH_NOARGS,
508 NULL },
509 { "has_privilege", (PyCFunction)py_token_has_privilege, METH_VARARGS,
510 NULL },
511 { "set_privilege", (PyCFunction)py_token_set_privilege, METH_VARARGS,
512 NULL },
516 #define PY_TOKEN_PATCH py_token_patch
517 static void py_token_patch(PyTypeObject *type)
519 type->tp_new = py_token_new;
520 PyType_AddMethods(type, py_token_extra_methods);
523 static PyObject *py_privilege_name(PyObject *self, PyObject *args)
525 int priv;
526 const char *name = NULL;
527 if (!PyArg_ParseTuple(args, "i", &priv)) {
528 return NULL;
530 name = sec_privilege_name(priv);
531 if (name == NULL) {
532 PyErr_Format(PyExc_ValueError,
533 "Invalid privilege LUID: %d", priv);
534 return NULL;
537 return PyUnicode_FromString(name);
540 static PyObject *py_privilege_id(PyObject *self, PyObject *args)
542 char *name;
544 if (!PyArg_ParseTuple(args, "s", &name))
545 return NULL;
547 return PyLong_FromLong(sec_privilege_id(name));
550 static PyObject *py_random_sid(PyObject *self,
551 PyObject *Py_UNUSED(ignored))
553 struct dom_sid *sid;
554 PyObject *ret;
555 char *str = talloc_asprintf(
556 NULL,
557 "S-1-5-21-%"PRIu32"-%"PRIu32"-%"PRIu32,
558 generate_random(),
559 generate_random(),
560 generate_random());
562 sid = dom_sid_parse_talloc(NULL, str);
563 talloc_free(str);
564 ret = pytalloc_steal(&dom_sid_Type, sid);
565 return ret;
568 static PyMethodDef py_mod_security_extra_methods[] = {
569 { "random_sid", (PyCFunction)py_random_sid, METH_NOARGS, NULL },
570 { "privilege_id", (PyCFunction)py_privilege_id, METH_VARARGS, NULL },
571 { "privilege_name", (PyCFunction)py_privilege_name, METH_VARARGS, NULL },
575 static void py_mod_security_patch(PyObject *m)
577 int i;
578 for (i = 0; py_mod_security_extra_methods[i].ml_name; i++) {
579 PyObject *descr = PyCFunction_New(&py_mod_security_extra_methods[i], NULL);
580 PyModule_AddObject(m, py_mod_security_extra_methods[i].ml_name,
581 descr);
585 #define PY_MOD_SECURITY_PATCH py_mod_security_patch
587 static PyObject *py_security_ace_equal(PyObject *py_self, PyObject *py_other, int op)
589 struct security_ace *self = pytalloc_get_ptr(py_self);
590 struct security_ace *other = NULL;
591 bool eq;
593 if (!PyObject_TypeCheck(py_other, &security_ace_Type)) {
594 eq = false;
595 } else {
596 other = pytalloc_get_ptr(py_other);
597 eq = security_ace_equal(self, other);
600 switch(op) {
601 case Py_EQ:
602 if (eq) {
603 Py_RETURN_TRUE;
604 } else {
605 Py_RETURN_FALSE;
607 break;
608 case Py_NE:
609 if (eq) {
610 Py_RETURN_FALSE;
611 } else {
612 Py_RETURN_TRUE;
614 break;
615 default:
616 break;
619 Py_RETURN_NOTIMPLEMENTED;
622 static PyObject *py_security_ace_as_sddl(PyObject *self, PyObject *args)
624 struct security_ace *ace = pytalloc_get_ptr(self);
625 PyObject *py_sid = Py_None;
626 struct dom_sid *sid = NULL;
627 char *text = NULL;
628 PyObject *ret = Py_None;
630 if (!PyArg_ParseTuple(args, "O!", &dom_sid_Type, &py_sid))
631 return NULL;
633 if (!PyObject_TypeCheck(py_sid, &dom_sid_Type)) {
634 PyErr_SetString(PyExc_TypeError,
635 "expected security.dom_sid "
636 "for second argument to .sddl_encode_ace");
637 return NULL;
640 sid = pytalloc_get_ptr(py_sid);
642 text = sddl_encode_ace(NULL, ace, sid);
643 if (text == NULL) {
644 return NULL;
646 ret = PyUnicode_FromString(text);
647 talloc_free(text);
649 return ret;
652 static PyMethodDef py_security_ace_extra_methods[] = {
653 { "as_sddl", (PyCFunction)py_security_ace_as_sddl, METH_VARARGS, NULL },
657 #define PY_ACE_PATCH py_security_ace_patch
659 static void py_security_ace_patch(PyTypeObject *type)
661 type->tp_richcompare = py_security_ace_equal;
662 PyType_AddMethods(type, py_security_ace_extra_methods);