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