Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Samba utility functions
4 :
5 : Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008-2010
6 :
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.
11 :
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.
16 :
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/>.
19 : */
20 : #include <Python.h>
21 : #include "py3compat.h"
22 : #include "libcli/security/sddl.h"
23 : #include "libcli/security/security.h"
24 :
25 :
26 : /* Set up in py_mod_security_patch() */
27 : static PyObject *PyExc_SDDLValueError = NULL;
28 :
29 :
30 29476 : static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods)
31 : {
32 764 : PyObject *dict;
33 764 : int i;
34 29476 : if (type->tp_dict == NULL)
35 0 : type->tp_dict = PyDict_New();
36 29476 : dict = type->tp_dict;
37 162118 : for (i = 0; methods[i].ml_name; i++) {
38 3438 : PyObject *descr;
39 132642 : if (methods[i].ml_flags & METH_CLASS)
40 7369 : descr = PyCFunction_New(&methods[i], (PyObject *)type);
41 : else
42 125273 : descr = PyDescr_NewMethod(type, &methods[i]);
43 132642 : PyDict_SetItemString(dict, methods[i].ml_name,
44 : descr);
45 132642 : Py_CLEAR(descr);
46 : }
47 29476 : }
48 :
49 8619 : static PyObject *py_dom_sid_split(PyObject *py_self, PyObject *args)
50 : {
51 8619 : struct dom_sid *self = pytalloc_get_ptr(py_self);
52 71 : struct dom_sid *domain_sid;
53 71 : TALLOC_CTX *mem_ctx;
54 71 : uint32_t rid;
55 71 : NTSTATUS status;
56 71 : PyObject *py_domain_sid;
57 :
58 8619 : mem_ctx = talloc_new(NULL);
59 8619 : if (mem_ctx == NULL) {
60 0 : PyErr_NoMemory();
61 0 : return NULL;
62 : }
63 :
64 8619 : status = dom_sid_split_rid(mem_ctx, self, &domain_sid, &rid);
65 8619 : if (!NT_STATUS_IS_OK(status)) {
66 0 : PyErr_SetString(PyExc_RuntimeError, "dom_sid_split_rid failed");
67 0 : talloc_free(mem_ctx);
68 0 : return NULL;
69 : }
70 :
71 8619 : py_domain_sid = pytalloc_steal(&dom_sid_Type, domain_sid);
72 8619 : talloc_free(mem_ctx);
73 8619 : return Py_BuildValue("(OI)", py_domain_sid, rid);
74 : }
75 :
76 4693 : static PyObject *py_dom_sid_richcmp(PyObject *py_self, PyObject *py_other, int op)
77 : {
78 4693 : struct dom_sid *self = pytalloc_get_ptr(py_self), *other;
79 121 : int val;
80 :
81 4693 : other = pytalloc_get_ptr(py_other);
82 4693 : if (other == NULL) {
83 0 : Py_INCREF(Py_NotImplemented);
84 0 : return Py_NotImplemented;
85 : }
86 :
87 4693 : val = dom_sid_compare(self, other);
88 :
89 4693 : switch (op) {
90 4453 : case Py_EQ: if (val == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
91 240 : case Py_NE: if (val != 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
92 0 : case Py_LT: if (val < 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
93 0 : case Py_GT: if (val > 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
94 0 : case Py_LE: if (val <= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
95 0 : case Py_GE: if (val >= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
96 : }
97 0 : Py_INCREF(Py_NotImplemented);
98 0 : return Py_NotImplemented;
99 : }
100 :
101 63014 : static PyObject *py_dom_sid_str(PyObject *py_self)
102 : {
103 63014 : struct dom_sid *self = pytalloc_get_ptr(py_self);
104 1572 : struct dom_sid_buf buf;
105 63014 : PyObject *ret = PyUnicode_FromString(dom_sid_str_buf(self, &buf));
106 63014 : return ret;
107 : }
108 :
109 1 : static PyObject *py_dom_sid_repr(PyObject *py_self)
110 : {
111 1 : struct dom_sid *self = pytalloc_get_ptr(py_self);
112 1 : struct dom_sid_buf buf;
113 1 : PyObject *ret = PyUnicode_FromFormat(
114 : "dom_sid('%s')", dom_sid_str_buf(self, &buf));
115 1 : return ret;
116 : }
117 :
118 122903 : static int py_dom_sid_init(PyObject *self, PyObject *args, PyObject *kwargs)
119 : {
120 122903 : char *str = NULL;
121 122903 : struct dom_sid *sid = pytalloc_get_ptr(self);
122 122903 : const char *kwnames[] = { "str", NULL };
123 :
124 122903 : if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &str))
125 0 : return -1;
126 :
127 122903 : if (str != NULL && !dom_sid_parse(str, sid)) {
128 6721 : PyErr_Format(PyExc_ValueError,
129 : "Unable to parse string: '%s'", str);
130 6721 : return -1;
131 : }
132 :
133 49072 : return 0;
134 : }
135 :
136 : static PyMethodDef py_dom_sid_extra_methods[] = {
137 : { "split", (PyCFunction)py_dom_sid_split, METH_NOARGS,
138 : "S.split() -> (domain_sid, rid)\n"
139 : "Split a domain sid" },
140 : {0}
141 : };
142 :
143 :
144 7369 : static void py_dom_sid_patch(PyTypeObject *type)
145 : {
146 7369 : type->tp_init = py_dom_sid_init;
147 7369 : type->tp_str = py_dom_sid_str;
148 7369 : type->tp_repr = py_dom_sid_repr;
149 7369 : type->tp_richcompare = py_dom_sid_richcmp;
150 7369 : PyType_AddMethods(type, py_dom_sid_extra_methods);
151 7178 : }
152 :
153 : #define PY_DOM_SID_PATCH py_dom_sid_patch
154 :
155 7335 : static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args)
156 : {
157 7335 : struct security_descriptor *desc = pytalloc_get_ptr(self);
158 1495 : NTSTATUS status;
159 1495 : struct security_ace *ace;
160 1495 : PyObject *py_ace;
161 7335 : Py_ssize_t idx = -1;
162 :
163 7335 : if (!PyArg_ParseTuple(args, "O|n", &py_ace, &idx))
164 0 : return NULL;
165 :
166 7335 : ace = pytalloc_get_ptr(py_ace);
167 7335 : status = security_descriptor_sacl_insert(desc, ace, idx);
168 7335 : PyErr_NTSTATUS_IS_ERR_RAISE(status);
169 7335 : Py_RETURN_NONE;
170 : }
171 :
172 861842 : static PyObject *py_descriptor_dacl_add(PyObject *self, PyObject *args)
173 : {
174 861842 : struct security_descriptor *desc = pytalloc_get_ptr(self);
175 144092 : NTSTATUS status;
176 144092 : struct security_ace *ace;
177 144092 : PyObject *py_ace;
178 861842 : Py_ssize_t idx = -1;
179 :
180 861842 : if (!PyArg_ParseTuple(args, "O|n", &py_ace, &idx))
181 0 : return NULL;
182 :
183 861842 : ace = pytalloc_get_ptr(py_ace);
184 :
185 861842 : status = security_descriptor_dacl_insert(desc, ace, idx);
186 861842 : PyErr_NTSTATUS_IS_ERR_RAISE(status);
187 861842 : Py_RETURN_NONE;
188 : }
189 :
190 0 : static PyObject *py_descriptor_dacl_del(PyObject *self, PyObject *args)
191 : {
192 0 : struct security_descriptor *desc = pytalloc_get_ptr(self);
193 0 : NTSTATUS status;
194 0 : struct dom_sid *sid;
195 0 : PyObject *py_sid;
196 :
197 0 : if (!PyArg_ParseTuple(args, "O", &py_sid))
198 0 : return NULL;
199 :
200 0 : sid = pytalloc_get_ptr(py_sid);
201 0 : status = security_descriptor_dacl_del(desc, sid);
202 0 : PyErr_NTSTATUS_IS_ERR_RAISE(status);
203 0 : Py_RETURN_NONE;
204 : }
205 :
206 0 : static PyObject *py_descriptor_sacl_del(PyObject *self, PyObject *args)
207 : {
208 0 : struct security_descriptor *desc = pytalloc_get_ptr(self);
209 0 : NTSTATUS status;
210 0 : struct dom_sid *sid;
211 0 : PyObject *py_sid;
212 :
213 0 : if (!PyArg_ParseTuple(args, "O", &py_sid))
214 0 : return NULL;
215 :
216 0 : sid = pytalloc_get_ptr(py_sid);
217 0 : status = security_descriptor_sacl_del(desc, sid);
218 0 : PyErr_NTSTATUS_IS_ERR_RAISE(status);
219 0 : Py_RETURN_NONE;
220 : }
221 :
222 110779 : static PyObject *py_descriptor_dacl_del_ace(PyObject *self, PyObject *args)
223 : {
224 110779 : struct security_descriptor *desc = pytalloc_get_ptr(self);
225 594 : NTSTATUS status;
226 110779 : struct security_ace *ace = NULL;
227 110779 : PyObject *py_ace = Py_None;
228 :
229 110779 : if (!PyArg_ParseTuple(args, "O!", &security_ace_Type, &py_ace))
230 0 : return NULL;
231 :
232 110779 : if (!PyObject_TypeCheck(py_ace, &security_ace_Type)) {
233 0 : PyErr_SetString(PyExc_TypeError,
234 : "expected security.security_ace "
235 : "for first argument to .dacl_del_ace");
236 0 : return NULL;
237 : }
238 :
239 110779 : ace = pytalloc_get_ptr(py_ace);
240 110779 : status = security_descriptor_dacl_del_ace(desc, ace);
241 110779 : PyErr_NTSTATUS_IS_ERR_RAISE(status);
242 110770 : Py_RETURN_NONE;
243 : }
244 :
245 0 : static PyObject *py_descriptor_sacl_del_ace(PyObject *self, PyObject *args)
246 : {
247 0 : struct security_descriptor *desc = pytalloc_get_ptr(self);
248 0 : NTSTATUS status;
249 0 : struct security_ace *ace = NULL;
250 0 : PyObject *py_ace = Py_None;
251 :
252 0 : if (!PyArg_ParseTuple(args, "O!", &security_ace_Type, &py_ace))
253 0 : return NULL;
254 :
255 0 : if (!PyObject_TypeCheck(py_ace, &security_ace_Type)) {
256 0 : PyErr_SetString(PyExc_TypeError,
257 : "expected security.security_ace "
258 : "for first argument to .sacl_del_ace");
259 0 : return NULL;
260 : }
261 :
262 0 : ace = pytalloc_get_ptr(py_ace);
263 0 : status = security_descriptor_sacl_del_ace(desc, ace);
264 0 : PyErr_NTSTATUS_IS_ERR_RAISE(status);
265 0 : Py_RETURN_NONE;
266 : }
267 :
268 1025139 : static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
269 : {
270 1025139 : return pytalloc_steal(self, security_descriptor_initialise(NULL));
271 : }
272 :
273 49450 : static PyObject *py_descriptor_from_sddl(PyObject *self, PyObject *args)
274 : {
275 10076 : struct security_descriptor *secdesc;
276 10076 : char *sddl;
277 10076 : PyObject *py_sid;
278 10076 : struct dom_sid *sid;
279 49450 : const char *err_msg = NULL;
280 49450 : size_t err_msg_offset = 0;
281 :
282 49450 : if (!PyArg_ParseTuple(args, "sO!", &sddl, &dom_sid_Type, &py_sid))
283 0 : return NULL;
284 :
285 49448 : if (!PyObject_TypeCheck(py_sid, &dom_sid_Type)) {
286 0 : PyErr_SetString(PyExc_TypeError,
287 : "expected security.dom_sid "
288 : "for second argument to .from_sddl");
289 0 : return NULL;
290 : }
291 :
292 49448 : sid = pytalloc_get_ptr(py_sid);
293 :
294 49448 : secdesc = sddl_decode_err_msg(NULL, sddl, sid,
295 : &err_msg, &err_msg_offset);
296 49448 : if (secdesc == NULL) {
297 214 : PyObject *exc = NULL;
298 214 : if (err_msg == NULL) {
299 197 : err_msg = "unknown error";
300 : }
301 : /*
302 : * Some notes about this exception value:
303 : *
304 : * We don't want to add the offset first, so as not to
305 : * confuse those who are used to the integer error
306 : * code coming first.
307 : *
308 : * The errant sddl is added so that the exception can
309 : * be caught some distance away from the call and we
310 : * still know what the messages refer to.
311 : */
312 214 : exc = Py_BuildValue("(s, s, i, s)",
313 : "Unable to parse SDDL",
314 : err_msg,
315 : err_msg_offset,
316 : sddl);
317 214 : if (exc == NULL) {
318 : /* an exception was set by Py_BuildValue() */
319 0 : return NULL;
320 : }
321 214 : PyErr_SetObject(PyExc_SDDLValueError, exc);
322 214 : Py_DECREF(exc);
323 214 : return NULL;
324 : }
325 :
326 49234 : return pytalloc_steal((PyTypeObject *)self, secdesc);
327 : }
328 :
329 77504 : static PyObject *py_descriptor_as_sddl(PyObject *self, PyObject *args)
330 : {
331 944 : struct dom_sid *sid;
332 77504 : PyObject *py_sid = Py_None;
333 77504 : struct security_descriptor *desc = pytalloc_get_ptr(self);
334 944 : char *text;
335 944 : PyObject *ret;
336 :
337 77504 : if (!PyArg_ParseTuple(args, "|O!", &dom_sid_Type, &py_sid))
338 0 : return NULL;
339 :
340 77503 : if (py_sid != Py_None)
341 75837 : sid = pytalloc_get_ptr(py_sid);
342 : else
343 1624 : sid = NULL;
344 :
345 77503 : text = sddl_encode(NULL, desc, sid);
346 77503 : if (text == NULL) {
347 0 : PyErr_SetString(PyExc_ValueError, "Unable to encode SDDL");
348 0 : return NULL;
349 : }
350 :
351 77503 : ret = PyUnicode_FromString(text);
352 :
353 77503 : talloc_free(text);
354 :
355 77503 : return ret;
356 : }
357 :
358 : static PyMethodDef py_descriptor_extra_methods[] = {
359 : { "sacl_add", (PyCFunction)py_descriptor_sacl_add, METH_VARARGS,
360 : "S.sacl_add(ace) -> None\n"
361 : "Add a security ace to this security descriptor" },
362 : { "dacl_add", (PyCFunction)py_descriptor_dacl_add, METH_VARARGS,
363 : NULL },
364 : { "dacl_del", (PyCFunction)py_descriptor_dacl_del, METH_VARARGS,
365 : NULL },
366 : { "sacl_del", (PyCFunction)py_descriptor_sacl_del, METH_VARARGS,
367 : NULL },
368 : { "dacl_del_ace", (PyCFunction)py_descriptor_dacl_del_ace, METH_VARARGS,
369 : NULL },
370 : { "sacl_del_ace", (PyCFunction)py_descriptor_sacl_del_ace, METH_VARARGS,
371 : NULL },
372 : { "from_sddl", (PyCFunction)py_descriptor_from_sddl, METH_VARARGS|METH_CLASS,
373 : NULL },
374 : { "as_sddl", (PyCFunction)py_descriptor_as_sddl, METH_VARARGS,
375 : NULL },
376 : {0}
377 : };
378 :
379 7828 : static PyObject *py_descriptor_richcmp(
380 : PyObject *py_self, PyObject *py_other, int op)
381 : {
382 7828 : struct security_descriptor *self = pytalloc_get_ptr(py_self);
383 7828 : struct security_descriptor *other = pytalloc_get_ptr(py_other);
384 7828 : bool eq;
385 :
386 7828 : if (other == NULL) {
387 0 : Py_INCREF(Py_NotImplemented);
388 0 : return Py_NotImplemented;
389 : }
390 :
391 7828 : eq = security_descriptor_equal(self, other);
392 :
393 7828 : switch(op) {
394 143 : case Py_EQ:
395 143 : if (eq) {
396 143 : Py_RETURN_TRUE;
397 : } else {
398 0 : Py_RETURN_FALSE;
399 : }
400 7685 : break;
401 7685 : case Py_NE:
402 7685 : if (eq) {
403 7568 : Py_RETURN_FALSE;
404 : } else {
405 117 : Py_RETURN_TRUE;
406 : }
407 0 : break;
408 0 : default:
409 0 : break;
410 : }
411 :
412 0 : Py_RETURN_NOTIMPLEMENTED;
413 : }
414 :
415 7369 : static void py_descriptor_patch(PyTypeObject *type)
416 : {
417 7369 : type->tp_new = py_descriptor_new;
418 7369 : type->tp_richcompare = py_descriptor_richcmp;
419 7369 : PyType_AddMethods(type, py_descriptor_extra_methods);
420 7178 : }
421 :
422 : #define PY_DESCRIPTOR_PATCH py_descriptor_patch
423 :
424 0 : static PyObject *py_token_is_sid(PyObject *self, PyObject *args)
425 : {
426 0 : PyObject *py_sid;
427 0 : struct dom_sid *sid;
428 0 : struct security_token *token = pytalloc_get_ptr(self);
429 0 : if (!PyArg_ParseTuple(args, "O", &py_sid))
430 0 : return NULL;
431 :
432 0 : sid = pytalloc_get_ptr(py_sid);
433 :
434 0 : return PyBool_FromLong(security_token_is_sid(token, sid));
435 : }
436 :
437 0 : static PyObject *py_token_has_sid(PyObject *self, PyObject *args)
438 : {
439 0 : PyObject *py_sid;
440 0 : struct dom_sid *sid;
441 0 : struct security_token *token = pytalloc_get_ptr(self);
442 0 : if (!PyArg_ParseTuple(args, "O", &py_sid))
443 0 : return NULL;
444 :
445 0 : sid = pytalloc_get_ptr(py_sid);
446 :
447 0 : return PyBool_FromLong(security_token_has_sid(token, sid));
448 : }
449 :
450 3 : static PyObject *py_token_is_anonymous(PyObject *self,
451 : PyObject *Py_UNUSED(ignored))
452 : {
453 3 : struct security_token *token = pytalloc_get_ptr(self);
454 :
455 3 : return PyBool_FromLong(security_token_is_anonymous(token));
456 : }
457 :
458 27 : static PyObject *py_token_is_system(PyObject *self,
459 : PyObject *Py_UNUSED(ignored))
460 : {
461 27 : struct security_token *token = pytalloc_get_ptr(self);
462 :
463 27 : return PyBool_FromLong(security_token_is_system(token));
464 : }
465 :
466 2 : static PyObject *py_token_has_builtin_administrators(PyObject *self,
467 : PyObject *Py_UNUSED(ignored))
468 : {
469 2 : struct security_token *token = pytalloc_get_ptr(self);
470 :
471 2 : return PyBool_FromLong(security_token_has_builtin_administrators(token));
472 : }
473 :
474 1 : static PyObject *py_token_has_nt_authenticated_users(PyObject *self,
475 : PyObject *Py_UNUSED(ignored))
476 : {
477 1 : struct security_token *token = pytalloc_get_ptr(self);
478 :
479 1 : return PyBool_FromLong(security_token_has_nt_authenticated_users(token));
480 : }
481 :
482 3 : static PyObject *py_token_has_privilege(PyObject *self, PyObject *args)
483 : {
484 3 : int priv;
485 3 : struct security_token *token = pytalloc_get_ptr(self);
486 :
487 3 : if (!PyArg_ParseTuple(args, "i", &priv))
488 0 : return NULL;
489 :
490 3 : return PyBool_FromLong(security_token_has_privilege(token, priv));
491 : }
492 :
493 1 : static PyObject *py_token_set_privilege(PyObject *self, PyObject *args)
494 : {
495 1 : int priv;
496 1 : struct security_token *token = pytalloc_get_ptr(self);
497 :
498 1 : if (!PyArg_ParseTuple(args, "i", &priv))
499 0 : return NULL;
500 :
501 1 : security_token_set_privilege(token, priv);
502 1 : Py_RETURN_NONE;
503 : }
504 :
505 54 : static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
506 : {
507 54 : int evaluate_claims = CLAIMS_EVALUATION_INVALID_STATE;
508 54 : const char *kwnames[] = { "evaluate_claims", NULL };
509 :
510 54 : if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
511 : discard_const_p(char *, kwnames),
512 : &evaluate_claims)) {
513 0 : return NULL;
514 : }
515 :
516 54 : return pytalloc_steal(self, security_token_initialise(NULL, evaluate_claims));
517 : }
518 :
519 : static PyMethodDef py_token_extra_methods[] = {
520 : { "is_sid", (PyCFunction)py_token_is_sid, METH_VARARGS,
521 : "S.is_sid(sid) -> bool\n"
522 : "Check whether this token is of the specified SID." },
523 : { "has_sid", (PyCFunction)py_token_has_sid, METH_VARARGS,
524 : NULL },
525 : { "is_anonymous", (PyCFunction)py_token_is_anonymous, METH_NOARGS,
526 : "S.is_anonymous() -> bool\n"
527 : "Check whether this is an anonymous token." },
528 : { "is_system", (PyCFunction)py_token_is_system, METH_NOARGS,
529 : NULL },
530 : { "has_builtin_administrators", (PyCFunction)py_token_has_builtin_administrators, METH_NOARGS,
531 : NULL },
532 : { "has_nt_authenticated_users", (PyCFunction)py_token_has_nt_authenticated_users, METH_NOARGS,
533 : NULL },
534 : { "has_privilege", (PyCFunction)py_token_has_privilege, METH_VARARGS,
535 : NULL },
536 : { "set_privilege", (PyCFunction)py_token_set_privilege, METH_VARARGS,
537 : NULL },
538 : {0}
539 : };
540 :
541 : #define PY_TOKEN_PATCH py_token_patch
542 7369 : static void py_token_patch(PyTypeObject *type)
543 : {
544 7369 : type->tp_new = py_token_new;
545 7369 : PyType_AddMethods(type, py_token_extra_methods);
546 7178 : }
547 :
548 1 : static PyObject *py_privilege_name(PyObject *self, PyObject *args)
549 : {
550 1 : int priv;
551 1 : const char *name = NULL;
552 1 : if (!PyArg_ParseTuple(args, "i", &priv)) {
553 0 : return NULL;
554 : }
555 1 : name = sec_privilege_name(priv);
556 1 : if (name == NULL) {
557 0 : PyErr_Format(PyExc_ValueError,
558 : "Invalid privilege LUID: %d", priv);
559 0 : return NULL;
560 : }
561 :
562 1 : return PyUnicode_FromString(name);
563 : }
564 :
565 1 : static PyObject *py_privilege_id(PyObject *self, PyObject *args)
566 : {
567 1 : char *name;
568 :
569 1 : if (!PyArg_ParseTuple(args, "s", &name))
570 0 : return NULL;
571 :
572 1 : return PyLong_FromLong(sec_privilege_id(name));
573 : }
574 :
575 143 : static PyObject *py_random_sid(PyObject *self,
576 : PyObject *Py_UNUSED(ignored))
577 : {
578 19 : struct dom_sid *sid;
579 19 : PyObject *ret;
580 143 : char *str = talloc_asprintf(
581 : NULL,
582 : "S-1-5-21-%"PRIu32"-%"PRIu32"-%"PRIu32,
583 : generate_random(),
584 : generate_random(),
585 : generate_random());
586 :
587 143 : sid = dom_sid_parse_talloc(NULL, str);
588 143 : talloc_free(str);
589 143 : ret = pytalloc_steal(&dom_sid_Type, sid);
590 143 : return ret;
591 : }
592 :
593 : static PyMethodDef py_mod_security_extra_methods[] = {
594 : { "random_sid", (PyCFunction)py_random_sid, METH_NOARGS, NULL },
595 : { "privilege_id", (PyCFunction)py_privilege_id, METH_VARARGS, NULL },
596 : { "privilege_name", (PyCFunction)py_privilege_name, METH_VARARGS, NULL },
597 : {0}
598 : };
599 :
600 7369 : static bool py_mod_security_patch(PyObject *m)
601 : {
602 191 : int ret;
603 191 : int i;
604 29476 : for (i = 0; py_mod_security_extra_methods[i].ml_name; i++) {
605 22107 : PyObject *descr = PyCFunction_New(&py_mod_security_extra_methods[i], NULL);
606 22107 : ret = PyModule_AddObject(m, py_mod_security_extra_methods[i].ml_name,
607 : descr);
608 22107 : if (ret != 0) {
609 0 : return false;
610 : }
611 : }
612 : /*
613 : * I wanted to make this a subclass of ValueError, but it
614 : * seems there isn't an easy way to do that using the API.
615 : * (c.f. SimpleExtendsException in cpython:Objects/exceptions.c)
616 : */
617 7369 : PyExc_SDDLValueError = PyErr_NewException("security.SDDLValueError",
618 : NULL, NULL);
619 :
620 7369 : if (PyExc_SDDLValueError == NULL) {
621 0 : return false;
622 : }
623 7369 : ret = PyModule_AddObject(m, "SDDLValueError", PyExc_SDDLValueError);
624 7369 : if (ret != 0) {
625 0 : return false;
626 : }
627 7178 : return true;
628 : }
629 :
630 : #define PY_MOD_SECURITY_PATCH(m) \
631 : do { \
632 : bool _ok = py_mod_security_patch(m); \
633 : if (! _ok) { \
634 : Py_XDECREF(m); \
635 : return NULL; \
636 : } \
637 : } while(0)
638 :
639 159954 : static PyObject *py_security_ace_equal(PyObject *py_self, PyObject *py_other, int op)
640 : {
641 159954 : struct security_ace *self = pytalloc_get_ptr(py_self);
642 159954 : struct security_ace *other = NULL;
643 14702 : bool eq;
644 :
645 159954 : if (!PyObject_TypeCheck(py_other, &security_ace_Type)) {
646 0 : eq = false;
647 : } else {
648 159954 : other = pytalloc_get_ptr(py_other);
649 159954 : eq = security_ace_equal(self, other);
650 : }
651 :
652 159954 : switch(op) {
653 159952 : case Py_EQ:
654 159952 : if (eq) {
655 1453 : Py_RETURN_TRUE;
656 : } else {
657 158499 : Py_RETURN_FALSE;
658 : }
659 2 : break;
660 2 : case Py_NE:
661 2 : if (eq) {
662 0 : Py_RETURN_FALSE;
663 : } else {
664 2 : Py_RETURN_TRUE;
665 : }
666 0 : break;
667 0 : default:
668 0 : break;
669 : }
670 :
671 0 : Py_RETURN_NOTIMPLEMENTED;
672 : }
673 :
674 13 : static PyObject *py_security_ace_as_sddl(PyObject *self, PyObject *args)
675 : {
676 13 : struct security_ace *ace = pytalloc_get_ptr(self);
677 13 : PyObject *py_sid = Py_None;
678 13 : struct dom_sid *sid = NULL;
679 13 : char *text = NULL;
680 13 : PyObject *ret = Py_None;
681 :
682 13 : if (!PyArg_ParseTuple(args, "O!", &dom_sid_Type, &py_sid))
683 0 : return NULL;
684 :
685 13 : if (!PyObject_TypeCheck(py_sid, &dom_sid_Type)) {
686 0 : PyErr_SetString(PyExc_TypeError,
687 : "expected security.dom_sid "
688 : "for second argument to .sddl_encode_ace");
689 0 : return NULL;
690 : }
691 :
692 13 : sid = pytalloc_get_ptr(py_sid);
693 :
694 13 : text = sddl_encode_ace(NULL, ace, sid);
695 13 : if (text == NULL) {
696 0 : return NULL;
697 : }
698 13 : ret = PyUnicode_FromString(text);
699 13 : talloc_free(text);
700 :
701 13 : return ret;
702 : }
703 :
704 : static PyMethodDef py_security_ace_extra_methods[] = {
705 : { "as_sddl", (PyCFunction)py_security_ace_as_sddl, METH_VARARGS, NULL },
706 : {0}
707 : };
708 :
709 : #define PY_ACE_PATCH py_security_ace_patch
710 :
711 7369 : static void py_security_ace_patch(PyTypeObject *type)
712 : {
713 7369 : type->tp_richcompare = py_security_ace_equal;
714 7369 : PyType_AddMethods(type, py_security_ace_extra_methods);
715 7178 : }
|