1 | /*
|
---|
2 | Unix SMB/CIFS implementation.
|
---|
3 | Samba utility functions
|
---|
4 | Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
|
---|
5 |
|
---|
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.
|
---|
10 |
|
---|
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.
|
---|
15 |
|
---|
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/>.
|
---|
18 | */
|
---|
19 | #include <Python.h>
|
---|
20 | #include "libcli/security/security.h"
|
---|
21 |
|
---|
22 | #ifndef Py_RETURN_NONE
|
---|
23 | #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
|
---|
24 | #endif
|
---|
25 |
|
---|
26 | static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods)
|
---|
27 | {
|
---|
28 | PyObject *dict;
|
---|
29 | int i;
|
---|
30 | if (type->tp_dict == NULL)
|
---|
31 | type->tp_dict = PyDict_New();
|
---|
32 | dict = type->tp_dict;
|
---|
33 | for (i = 0; methods[i].ml_name; i++) {
|
---|
34 | PyObject *descr;
|
---|
35 | if (methods[i].ml_flags & METH_CLASS)
|
---|
36 | descr = PyCFunction_New(&methods[i], (PyObject *)type);
|
---|
37 | else
|
---|
38 | descr = PyDescr_NewMethod(type, &methods[i]);
|
---|
39 | PyDict_SetItemString(dict, methods[i].ml_name,
|
---|
40 | descr);
|
---|
41 | }
|
---|
42 | }
|
---|
43 |
|
---|
44 | static PyObject *py_dom_sid_split(PyObject *py_self, PyObject *args)
|
---|
45 | {
|
---|
46 | struct dom_sid *self = py_talloc_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;
|
---|
52 |
|
---|
53 | mem_ctx = talloc_new(NULL);
|
---|
54 | if (mem_ctx == NULL) {
|
---|
55 | PyErr_NoMemory();
|
---|
56 | return NULL;
|
---|
57 | }
|
---|
58 |
|
---|
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;
|
---|
64 | }
|
---|
65 |
|
---|
66 | py_domain_sid = py_talloc_steal(&dom_sid_Type, domain_sid);
|
---|
67 | talloc_free(mem_ctx);
|
---|
68 | return Py_BuildValue("(OI)", py_domain_sid, rid);
|
---|
69 | }
|
---|
70 |
|
---|
71 | static int py_dom_sid_cmp(PyObject *py_self, PyObject *py_other)
|
---|
72 | {
|
---|
73 | struct dom_sid *self = py_talloc_get_ptr(py_self), *other;
|
---|
74 | other = py_talloc_get_ptr(py_other);
|
---|
75 | if (other == NULL)
|
---|
76 | return -1;
|
---|
77 |
|
---|
78 | return dom_sid_compare(self, other);
|
---|
79 | }
|
---|
80 |
|
---|
81 | static PyObject *py_dom_sid_str(PyObject *py_self)
|
---|
82 | {
|
---|
83 | struct dom_sid *self = py_talloc_get_ptr(py_self);
|
---|
84 | char *str = dom_sid_string(NULL, self);
|
---|
85 | PyObject *ret = PyString_FromString(str);
|
---|
86 | talloc_free(str);
|
---|
87 | return ret;
|
---|
88 | }
|
---|
89 |
|
---|
90 | static PyObject *py_dom_sid_repr(PyObject *py_self)
|
---|
91 | {
|
---|
92 | struct dom_sid *self = py_talloc_get_ptr(py_self);
|
---|
93 | char *str = dom_sid_string(NULL, self);
|
---|
94 | PyObject *ret = PyString_FromFormat("dom_sid('%s')", str);
|
---|
95 | talloc_free(str);
|
---|
96 | return ret;
|
---|
97 | }
|
---|
98 |
|
---|
99 | static int py_dom_sid_init(PyObject *self, PyObject *args, PyObject *kwargs)
|
---|
100 | {
|
---|
101 | char *str = NULL;
|
---|
102 | struct dom_sid *sid = py_talloc_get_ptr(self);
|
---|
103 | const char *kwnames[] = { "str", NULL };
|
---|
104 |
|
---|
105 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &str))
|
---|
106 | return -1;
|
---|
107 |
|
---|
108 | if (str != NULL && !dom_sid_parse(str, sid)) {
|
---|
109 | PyErr_SetString(PyExc_TypeError, "Unable to parse string");
|
---|
110 | return -1;
|
---|
111 | }
|
---|
112 |
|
---|
113 | return 0;
|
---|
114 | }
|
---|
115 |
|
---|
116 | static PyMethodDef py_dom_sid_extra_methods[] = {
|
---|
117 | { "split", (PyCFunction)py_dom_sid_split, METH_NOARGS,
|
---|
118 | "S.split() -> (domain_sid, rid)\n"
|
---|
119 | "Split a domain sid" },
|
---|
120 | { NULL }
|
---|
121 | };
|
---|
122 |
|
---|
123 |
|
---|
124 | static void py_dom_sid_patch(PyTypeObject *type)
|
---|
125 | {
|
---|
126 | type->tp_init = py_dom_sid_init;
|
---|
127 | type->tp_str = py_dom_sid_str;
|
---|
128 | type->tp_repr = py_dom_sid_repr;
|
---|
129 | type->tp_compare = py_dom_sid_cmp;
|
---|
130 | PyType_AddMethods(type, py_dom_sid_extra_methods);
|
---|
131 | }
|
---|
132 |
|
---|
133 | #define PY_DOM_SID_PATCH py_dom_sid_patch
|
---|
134 |
|
---|
135 | static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args)
|
---|
136 | {
|
---|
137 | struct security_descriptor *desc = py_talloc_get_ptr(self);
|
---|
138 | NTSTATUS status;
|
---|
139 | struct security_ace *ace;
|
---|
140 | PyObject *py_ace;
|
---|
141 |
|
---|
142 | if (!PyArg_ParseTuple(args, "O", &py_ace))
|
---|
143 | return NULL;
|
---|
144 |
|
---|
145 | ace = py_talloc_get_ptr(py_ace);
|
---|
146 | status = security_descriptor_sacl_add(desc, ace);
|
---|
147 | PyErr_NTSTATUS_IS_ERR_RAISE(status);
|
---|
148 | Py_RETURN_NONE;
|
---|
149 | }
|
---|
150 |
|
---|
151 | static PyObject *py_descriptor_dacl_add(PyObject *self, PyObject *args)
|
---|
152 | {
|
---|
153 | struct security_descriptor *desc = py_talloc_get_ptr(self);
|
---|
154 | NTSTATUS status;
|
---|
155 | struct security_ace *ace;
|
---|
156 | PyObject *py_ace;
|
---|
157 |
|
---|
158 | if (!PyArg_ParseTuple(args, "O", &py_ace))
|
---|
159 | return NULL;
|
---|
160 |
|
---|
161 | ace = py_talloc_get_ptr(py_ace);
|
---|
162 |
|
---|
163 | status = security_descriptor_dacl_add(desc, ace);
|
---|
164 | PyErr_NTSTATUS_IS_ERR_RAISE(status);
|
---|
165 | Py_RETURN_NONE;
|
---|
166 | }
|
---|
167 |
|
---|
168 | static PyObject *py_descriptor_dacl_del(PyObject *self, PyObject *args)
|
---|
169 | {
|
---|
170 | struct security_descriptor *desc = py_talloc_get_ptr(self);
|
---|
171 | NTSTATUS status;
|
---|
172 | struct dom_sid *sid;
|
---|
173 | PyObject *py_sid;
|
---|
174 |
|
---|
175 | if (!PyArg_ParseTuple(args, "O", &py_sid))
|
---|
176 | return NULL;
|
---|
177 |
|
---|
178 | sid = py_talloc_get_ptr(py_sid);
|
---|
179 | status = security_descriptor_dacl_del(desc, sid);
|
---|
180 | PyErr_NTSTATUS_IS_ERR_RAISE(status);
|
---|
181 | Py_RETURN_NONE;
|
---|
182 | }
|
---|
183 |
|
---|
184 | static PyObject *py_descriptor_sacl_del(PyObject *self, PyObject *args)
|
---|
185 | {
|
---|
186 | struct security_descriptor *desc = py_talloc_get_ptr(self);
|
---|
187 | NTSTATUS status;
|
---|
188 | struct dom_sid *sid;
|
---|
189 | PyObject *py_sid;
|
---|
190 |
|
---|
191 | if (!PyArg_ParseTuple(args, "O", &py_sid))
|
---|
192 | return NULL;
|
---|
193 |
|
---|
194 | sid = py_talloc_get_ptr(py_sid);
|
---|
195 | status = security_descriptor_sacl_del(desc, sid);
|
---|
196 | PyErr_NTSTATUS_IS_ERR_RAISE(status);
|
---|
197 | Py_RETURN_NONE;
|
---|
198 | }
|
---|
199 |
|
---|
200 | static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
|
---|
201 | {
|
---|
202 | return py_talloc_steal(self, security_descriptor_initialise(NULL));
|
---|
203 | }
|
---|
204 |
|
---|
205 | static PyObject *py_descriptor_from_sddl(PyObject *self, PyObject *args)
|
---|
206 | {
|
---|
207 | struct security_descriptor *secdesc;
|
---|
208 | char *sddl;
|
---|
209 | PyObject *py_sid;
|
---|
210 | struct dom_sid *sid;
|
---|
211 |
|
---|
212 | if (!PyArg_ParseTuple(args, "sO!", &sddl, &dom_sid_Type, &py_sid))
|
---|
213 | return NULL;
|
---|
214 |
|
---|
215 | sid = py_talloc_get_ptr(py_sid);
|
---|
216 |
|
---|
217 | secdesc = sddl_decode(NULL, sddl, sid);
|
---|
218 | if (secdesc == NULL) {
|
---|
219 | PyErr_SetString(PyExc_TypeError, "Unable to parse SDDL");
|
---|
220 | return NULL;
|
---|
221 | }
|
---|
222 |
|
---|
223 | return py_talloc_steal((PyTypeObject *)self, secdesc);
|
---|
224 | }
|
---|
225 |
|
---|
226 | static PyObject *py_descriptor_as_sddl(PyObject *self, PyObject *args)
|
---|
227 | {
|
---|
228 | struct dom_sid *sid;
|
---|
229 | PyObject *py_sid = Py_None;
|
---|
230 | struct security_descriptor *desc = py_talloc_get_ptr(self);
|
---|
231 | char *text;
|
---|
232 | PyObject *ret;
|
---|
233 |
|
---|
234 | if (!PyArg_ParseTuple(args, "|O!", &dom_sid_Type, &py_sid))
|
---|
235 | return NULL;
|
---|
236 |
|
---|
237 | if (py_sid != Py_None)
|
---|
238 | sid = py_talloc_get_ptr(py_sid);
|
---|
239 | else
|
---|
240 | sid = NULL;
|
---|
241 |
|
---|
242 | text = sddl_encode(NULL, desc, sid);
|
---|
243 |
|
---|
244 | ret = PyString_FromString(text);
|
---|
245 |
|
---|
246 | talloc_free(text);
|
---|
247 |
|
---|
248 | return ret;
|
---|
249 | }
|
---|
250 |
|
---|
251 | static PyMethodDef py_descriptor_extra_methods[] = {
|
---|
252 | { "sacl_add", (PyCFunction)py_descriptor_sacl_add, METH_VARARGS,
|
---|
253 | "S.sacl_add(ace) -> None\n"
|
---|
254 | "Add a security ace to this security descriptor" },
|
---|
255 | { "dacl_add", (PyCFunction)py_descriptor_dacl_add, METH_VARARGS,
|
---|
256 | NULL },
|
---|
257 | { "dacl_del", (PyCFunction)py_descriptor_dacl_del, METH_VARARGS,
|
---|
258 | NULL },
|
---|
259 | { "sacl_del", (PyCFunction)py_descriptor_sacl_del, METH_VARARGS,
|
---|
260 | NULL },
|
---|
261 | { "from_sddl", (PyCFunction)py_descriptor_from_sddl, METH_VARARGS|METH_CLASS,
|
---|
262 | NULL },
|
---|
263 | { "as_sddl", (PyCFunction)py_descriptor_as_sddl, METH_VARARGS,
|
---|
264 | NULL },
|
---|
265 | { NULL }
|
---|
266 | };
|
---|
267 |
|
---|
268 | static void py_descriptor_patch(PyTypeObject *type)
|
---|
269 | {
|
---|
270 | type->tp_new = py_descriptor_new;
|
---|
271 | PyType_AddMethods(type, py_descriptor_extra_methods);
|
---|
272 | }
|
---|
273 |
|
---|
274 | #define PY_DESCRIPTOR_PATCH py_descriptor_patch
|
---|
275 |
|
---|
276 | static PyObject *py_token_is_sid(PyObject *self, PyObject *args)
|
---|
277 | {
|
---|
278 | PyObject *py_sid;
|
---|
279 | struct dom_sid *sid;
|
---|
280 | struct security_token *token = py_talloc_get_ptr(self);
|
---|
281 | if (!PyArg_ParseTuple(args, "O", &py_sid))
|
---|
282 | return NULL;
|
---|
283 |
|
---|
284 | sid = py_talloc_get_ptr(py_sid);
|
---|
285 |
|
---|
286 | return PyBool_FromLong(security_token_is_sid(token, sid));
|
---|
287 | }
|
---|
288 |
|
---|
289 | static PyObject *py_token_has_sid(PyObject *self, PyObject *args)
|
---|
290 | {
|
---|
291 | PyObject *py_sid;
|
---|
292 | struct dom_sid *sid;
|
---|
293 | struct security_token *token = py_talloc_get_ptr(self);
|
---|
294 | if (!PyArg_ParseTuple(args, "O", &py_sid))
|
---|
295 | return NULL;
|
---|
296 |
|
---|
297 | sid = py_talloc_get_ptr(py_sid);
|
---|
298 |
|
---|
299 | return PyBool_FromLong(security_token_has_sid(token, sid));
|
---|
300 | }
|
---|
301 |
|
---|
302 | static PyObject *py_token_is_anonymous(PyObject *self)
|
---|
303 | {
|
---|
304 | struct security_token *token = py_talloc_get_ptr(self);
|
---|
305 |
|
---|
306 | return PyBool_FromLong(security_token_is_anonymous(token));
|
---|
307 | }
|
---|
308 |
|
---|
309 | static PyObject *py_token_is_system(PyObject *self)
|
---|
310 | {
|
---|
311 | struct security_token *token = py_talloc_get_ptr(self);
|
---|
312 |
|
---|
313 | return PyBool_FromLong(security_token_is_system(token));
|
---|
314 | }
|
---|
315 |
|
---|
316 | static PyObject *py_token_has_builtin_administrators(PyObject *self)
|
---|
317 | {
|
---|
318 | struct security_token *token = py_talloc_get_ptr(self);
|
---|
319 |
|
---|
320 | return PyBool_FromLong(security_token_has_builtin_administrators(token));
|
---|
321 | }
|
---|
322 |
|
---|
323 | static PyObject *py_token_has_nt_authenticated_users(PyObject *self)
|
---|
324 | {
|
---|
325 | struct security_token *token = py_talloc_get_ptr(self);
|
---|
326 |
|
---|
327 | return PyBool_FromLong(security_token_has_nt_authenticated_users(token));
|
---|
328 | }
|
---|
329 |
|
---|
330 | static PyObject *py_token_has_privilege(PyObject *self, PyObject *args)
|
---|
331 | {
|
---|
332 | int priv;
|
---|
333 | struct security_token *token = py_talloc_get_ptr(self);
|
---|
334 |
|
---|
335 | if (!PyArg_ParseTuple(args, "i", &priv))
|
---|
336 | return NULL;
|
---|
337 |
|
---|
338 | return PyBool_FromLong(security_token_has_privilege(token, priv));
|
---|
339 | }
|
---|
340 |
|
---|
341 | static PyObject *py_token_set_privilege(PyObject *self, PyObject *args)
|
---|
342 | {
|
---|
343 | int priv;
|
---|
344 | struct security_token *token = py_talloc_get_ptr(self);
|
---|
345 |
|
---|
346 | if (!PyArg_ParseTuple(args, "i", &priv))
|
---|
347 | return NULL;
|
---|
348 |
|
---|
349 | security_token_set_privilege(token, priv);
|
---|
350 | Py_RETURN_NONE;
|
---|
351 | }
|
---|
352 |
|
---|
353 | static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
|
---|
354 | {
|
---|
355 | return py_talloc_steal(self, security_token_initialise(NULL));
|
---|
356 | }
|
---|
357 |
|
---|
358 | static PyMethodDef py_token_extra_methods[] = {
|
---|
359 | { "is_sid", (PyCFunction)py_token_is_sid, METH_VARARGS,
|
---|
360 | "S.is_sid(sid) -> bool\n"
|
---|
361 | "Check whether this token is of the specified SID." },
|
---|
362 | { "has_sid", (PyCFunction)py_token_has_sid, METH_VARARGS,
|
---|
363 | NULL },
|
---|
364 | { "is_anonymous", (PyCFunction)py_token_is_anonymous, METH_NOARGS,
|
---|
365 | "S.is_anonymus() -> bool\n"
|
---|
366 | "Check whether this is an anonymous token." },
|
---|
367 | { "is_system", (PyCFunction)py_token_is_system, METH_NOARGS,
|
---|
368 | NULL },
|
---|
369 | { "has_builtin_administrators", (PyCFunction)py_token_has_builtin_administrators, METH_NOARGS,
|
---|
370 | NULL },
|
---|
371 | { "has_nt_authenticated_users", (PyCFunction)py_token_has_nt_authenticated_users, METH_NOARGS,
|
---|
372 | NULL },
|
---|
373 | { "has_privilege", (PyCFunction)py_token_has_privilege, METH_VARARGS,
|
---|
374 | NULL },
|
---|
375 | { "set_privilege", (PyCFunction)py_token_set_privilege, METH_VARARGS,
|
---|
376 | NULL },
|
---|
377 | { NULL }
|
---|
378 | };
|
---|
379 |
|
---|
380 | #define PY_TOKEN_PATCH py_token_patch
|
---|
381 | static void py_token_patch(PyTypeObject *type)
|
---|
382 | {
|
---|
383 | type->tp_new = py_token_new;
|
---|
384 | PyType_AddMethods(type, py_token_extra_methods);
|
---|
385 | }
|
---|
386 |
|
---|
387 | static PyObject *py_privilege_name(PyObject *self, PyObject *args)
|
---|
388 | {
|
---|
389 | int priv;
|
---|
390 | if (!PyArg_ParseTuple(args, "i", &priv))
|
---|
391 | return NULL;
|
---|
392 |
|
---|
393 | return PyString_FromString(sec_privilege_name(priv));
|
---|
394 | }
|
---|
395 |
|
---|
396 | static PyObject *py_privilege_id(PyObject *self, PyObject *args)
|
---|
397 | {
|
---|
398 | char *name;
|
---|
399 |
|
---|
400 | if (!PyArg_ParseTuple(args, "s", &name))
|
---|
401 | return NULL;
|
---|
402 |
|
---|
403 | return PyInt_FromLong(sec_privilege_id(name));
|
---|
404 | }
|
---|
405 |
|
---|
406 | static PyObject *py_random_sid(PyObject *self)
|
---|
407 | {
|
---|
408 | struct dom_sid *sid;
|
---|
409 | PyObject *ret;
|
---|
410 | char *str = talloc_asprintf(NULL, "S-1-5-21-%u-%u-%u",
|
---|
411 | (unsigned)generate_random(),
|
---|
412 | (unsigned)generate_random(),
|
---|
413 | (unsigned)generate_random());
|
---|
414 |
|
---|
415 | sid = dom_sid_parse_talloc(NULL, str);
|
---|
416 | talloc_free(str);
|
---|
417 | ret = py_talloc_steal(&dom_sid_Type, sid);
|
---|
418 | return ret;
|
---|
419 | }
|
---|
420 |
|
---|
421 | static PyMethodDef py_mod_security_extra_methods[] = {
|
---|
422 | { "random_sid", (PyCFunction)py_random_sid, METH_NOARGS, NULL },
|
---|
423 | { "privilege_id", (PyCFunction)py_privilege_id, METH_VARARGS, NULL },
|
---|
424 | { "privilege_name", (PyCFunction)py_privilege_name, METH_VARARGS, NULL },
|
---|
425 | { NULL }
|
---|
426 | };
|
---|
427 |
|
---|
428 | static void py_mod_security_patch(PyObject *m)
|
---|
429 | {
|
---|
430 | int i;
|
---|
431 | for (i = 0; py_mod_security_extra_methods[i].ml_name; i++) {
|
---|
432 | PyObject *descr = PyCFunction_New(&py_mod_security_extra_methods[i], NULL);
|
---|
433 | PyModule_AddObject(m, py_mod_security_extra_methods[i].ml_name,
|
---|
434 | descr);
|
---|
435 | }
|
---|
436 | }
|
---|
437 |
|
---|
438 | #define PY_MOD_SECURITY_PATCH py_mod_security_patch
|
---|