Merge branch 'master' of git://git.samba.org/samba
[kai/samba-autobuild/.git] / source4 / librpc / ndr / py_security.c
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