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