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