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