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