py_talloc_import now uses a steal, so this free is incorrect
[kai/samba.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 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_import(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, &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_import((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", &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_import(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_import(&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